diff --git a/.github/workflows/test-cmake-build.yml b/.github/workflows/test-cmake-build.yml deleted file mode 100644 index a869b931..00000000 --- a/.github/workflows/test-cmake-build.yml +++ /dev/null @@ -1,236 +0,0 @@ -name: Build and Run tests - -on: [push] - -env: - BUILD_TYPE: Release - CMAKE_VER: 3.16.2 - -jobs: - build_linux: - name: Build and package on Ubuntu - runs-on: ubuntu-latest - timeout-minutes: 3600 - steps: - - uses: actions/checkout@v2 - - name: Init submodules - shell: bash - run: | - auth_header="$(git config --local --get http.https://github.com/.extraheader)" - git submodule sync --recursive - git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 - - - name: Install a fresh CMake - run: | - wget --no-verbose https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Linux-x86_64.sh - chmod +x cmake-${CMAKE_VER}-Linux-x86_64.sh - mkdir ${{runner.workspace}}/cmake - sudo ./cmake-${CMAKE_VER}-Linux-x86_64.sh --skip-license --prefix=${{runner.workspace}}/cmake - sudo rm -f /usr/local/bin/cmake /usr/local/bin/cpack - sudo ln -s ${{runner.workspace}}/cmake/bin/cmake /usr/local/bin/cmake - sudo ln -s ${{runner.workspace}}/cmake/bin/cpack /usr/local/bin/cpack - - - name: Install linuxdeploy - uses: miurahr/install-linuxdeploy-action@v1.2.0 - with: - plugins: qt appimage - - - name: Install dependencies - run: | - sudo DEBIAN_FRONTEND=noninteractive apt-get update - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libfcitx-qt5-dev - - - name: Install Qt - uses: jurplel/install-qt-action@v2 - with: - version: 5.9.9 - target: desktop - modules: qtwebchannel qtwebengine qtsvg qtlocation qttools qttranslations - - - name: Create Build Directory - shell: bash - run: mkdir build - working-directory: ${{runner.workspace}} - - # install-qt-action exports Qt5_Dir environment variable - - name: Configure the Project - shell: bash - run: cmake -DQt5_DIR=${Qt5_Dir}/lib/cmake/Qt5/ ${GITHUB_WORKSPACE} - working-directory: ${{runner.workspace}}/build - - - name: Build the Project - run: cmake --build . --target bundle - working-directory: ${{runner.workspace}}/build - - - name: Collect artifacts - shell: bash - run: | - mkdir -p artifacts - mv *.bz2 *.xz *.deb *.rpm *.AppImage artifacts || /bin/true - working-directory: ${{runner.workspace}}/build - - - uses: actions/upload-artifact@v1 - with: - name: linux packages - path: ${{runner.workspace}}/build/artifacts - - build_macos: - name: Build and package on MacOS X - runs-on: macos-latest - timeout-minutes: 3600 - steps: - - uses: actions/checkout@v2 - - name: Init submodules - shell: bash - run: | - auth_header="$(git config --local --get http.https://github.com/.extraheader)" - git submodule sync --recursive - git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 - - - name: Install a fresh CMake - run: | - wget --no-verbose https://github.com/Kitware/CMake/releases/download/v${CMAKE_VER}/cmake-${CMAKE_VER}-Darwin-x86_64.tar.gz - tar xzf cmake-${CMAKE_VER}-Darwin-x86_64.tar.gz - sudo rm -f /usr/local/bin/cmake /usr/local/bin/cpack - sudo ln -s ${{runner.workspace}}/cmake-${CMAKE_VER}-Darwin-x86_64/CMake.app/Contents/bin/cmake /usr/local/bin/cmake - sudo ln -s ${{runner.workspace}}/cmake-${CMAKE_VER}-Darwin-x86_64/CMake.app/Contents/bin/cpack /usr/local/bin/cpack - working-directory: ${{runner.workspace}} - - - name: Install macdeployqtFix - uses: actions/checkout@v2 - with: - repository: aurelien-rainone/macdeployqtfix - path: macdeployqtfix - - - name: Install Qt - uses: jurplel/install-qt-action@v2 - with: - version: 5.9.9 - target: desktop - modules: qtwebchannel qtwebengine qtsvg qtlocation qttools qttranslations - - - name: Create Build Directory - run: mkdir build - working-directory: ${{runner.workspace}} - - # install-qt-action exports Qt5_Dir environment variable - - name: Configure the Project - run: cmake -DQt5_DIR=${Qt5_Dir}/lib/cmake/Qt5/ -DMACDEPLOYQTFIX_EXECUTABLE=${GITHUB_WORKSPACE}/macdeployqtfix/macdeployqtfix.py ${GITHUB_WORKSPACE} - working-directory: ${{runner.workspace}}/build - - - name: Build the Project - run: cmake --build . --target bundle - working-directory: ${{runner.workspace}}/build - - - name: Collect artifacts - shell: bash - run: | - mkdir -p artifacts - mv ./_CPack_Packages/Darwin/External/vnote-2.8.2-Darwin/Applications/VNote.dmg artifacts || (exit 0) - working-directory: ${{runner.workspace}}/build - - - uses: actions/upload-artifact@v1 - with: - name: mac osx packages - path: ${{runner.workspace}}/build/artifacts - - build_win64: - name: Build and package on Windows(64bit) - runs-on: windows-latest - timeout-minutes: 3600 - - steps: - - uses: actions/checkout@v2 - - name: Init submodules - shell: bash - run: | - auth_header="$(git config --local --get http.https://github.com/.extraheader)" - git submodule sync --recursive - git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 - - - name: Install Qt - uses: jurplel/install-qt-action@v2 - with: - version: 5.9.9 - target: desktop - arch: win64_msvc2017_64 - modules: qtwebchannel qtwebengine qtsvg qtlocation qttools qttranslations - - - name: Create Build Directory - shell: bash - run: mkdir build - working-directory: ${{runner.workspace}} - - # install-qt-action exports Qt5_Dir environment variable - - name: Configure the Project - shell: bash - run: cmake -G "Visual Studio 16 2019" -A x64 -DQt5_DIR=${Qt5_Dir}/lib/cmake/Qt5/ ${GITHUB_WORKSPACE} - working-directory: ${{runner.workspace}}/build - - - name: Build the Project(Windows) - if: runner.os == 'Windows' - run: cmake --build . --target bundle --config ${env:BUILD_TYPE} - working-directory: ${{runner.workspace}}/build - - - name: Collect artifacts - shell: bash - run: | - mkdir -p artifacts - mv *.zip *.exe *.nupkg artifacts || (exit 0) - working-directory: ${{runner.workspace}}/build - - - uses: actions/upload-artifact@v1 - with: - name: windows packages - path: "${{runner.workspace}}\\build\\artifacts" - - build_win32: - name: Build and package on Windows(32bit) - runs-on: windows-latest - timeout-minutes: 3600 - - steps: - - uses: actions/checkout@v2 - - name: Init submodules - shell: bash - run: | - auth_header="$(git config --local --get http.https://github.com/.extraheader)" - git submodule sync --recursive - git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 - - # Qt 5.9 only support msvc 2015 for win32 but gh-a run on msvc2019 - - name: Install Qt - uses: jurplel/install-qt-action@v2 - with: - version: 5.9.9 - target: desktop - arch: win32_msvc2015 - modules: qtwebchannel qtwebengine qtsvg qtlocation qttools qttranslations - - - name: Create Build Directory - shell: bash - run: mkdir build - working-directory: ${{runner.workspace}} - - # install-qt-action exports Qt5_Dir environment variable - - name: Configure the Project - shell: bash - run: cmake -G "Visual Studio 16 2019" -A Win32 -DQt5_DIR=${Qt5_Dir}/lib/cmake/Qt5/ ${GITHUB_WORKSPACE} - working-directory: ${{runner.workspace}}/build - - - name: Build the Project(Windows) - if: runner.os == 'Windows' - run: cmake --build . --target bundle --config ${env:BUILD_TYPE} - working-directory: ${{runner.workspace}}/build - - - name: Collect artifacts - shell: bash - run: | - mkdir -p artifacts - mv *.zip *.exe *.nupkg artifacts || (exit 0) - working-directory: ${{runner.workspace}}/build - - - uses: actions/upload-artifact@v1 - with: - name: win32 packages - path: "${{runner.workspace}}\\build\\artifacts" diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 4ce739d4..00000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -VNote.pro.user* -CMakeLists.txt.user -.DS_Store diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 970115b7..00000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "src/utils/marked"] - path = src/utils/marked - url = https://github.com/chjj/marked.git -[submodule "hoedown"] - path = hoedown - url = https://github.com/tamlok/hoedown.git diff --git a/.linux_bintray.json b/.linux_bintray.json deleted file mode 100644 index ab8358c4..00000000 --- a/.linux_bintray.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "package": { - "name": "vnote", - "repo": "vnote", - "subject": "tamlok", - "desc": "Continuous deployment by Travis-CI", - "website_url": "https://github.com/tamlok/vnote", - "issue_tracker_url": "https://github.com/tamlok/vnote/issues", - "vcs_url": "https://github.com/tamlok/vnote.git", - "github_use_tag_release_notes": false, - "github_release_notes_file": "", - "licenses": ["MIT"], - "labels": ["Markdown", "Note-Taking", "Office", "Utils", "Efficiency"], - "public_download_numbers": true, - "public_stats": true - }, - - "version": { - "name": "2.10", - "desc": "VNote Releases", - "released": "2020-09-05", - "vcs_tag": "2.10", - "gpgSign": false - }, - - "files": - [{"includePattern": "build/(VNote-.*\\.AppImage)", "uploadPattern": "$1", - "matrixParams": {"override": 1 }}], - - "publish": true -} diff --git a/.macos_bintray.json b/.macos_bintray.json deleted file mode 100644 index c460e449..00000000 --- a/.macos_bintray.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "package": { - "name": "vnote", - "repo": "vnote", - "subject": "tamlok", - "desc": "Continuous deployment by Travis-CI", - "website_url": "https://github.com/tamlok/vnote", - "issue_tracker_url": "https://github.com/tamlok/vnote/issues", - "vcs_url": "https://github.com/tamlok/vnote.git", - "github_use_tag_release_notes": false, - "github_release_notes_file": "", - "licenses": ["MIT"], - "labels": ["Markdown", "Note-Taking", "Office", "Utils", "Efficiency"], - "public_download_numbers": true, - "public_stats": true - }, - - "version": { - "name": "2.10", - "desc": "VNote Releases", - "released": "2020-09-05", - "vcs_tag": "2.10", - "gpgSign": false - }, - - "files": - [{"includePattern": "build/distrib/(VNote-.*\\.dmg)", "uploadPattern": "$1", - "matrixParams": {"override": 1 }}], - - "publish": true -} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3c88f4b1..00000000 --- a/.travis.yml +++ /dev/null @@ -1,61 +0,0 @@ -dist: trusty -sudo: required -git: - depth: 1 -language: cpp - -matrix: - include: - - os: osx - compiler: clang - osx_image: xcode9.4 - - os: linux - compiler: g++ - -branches: - only: - - master - -before_install: -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo apt-get -qq update ; fi -- export version="2.10" - -install: -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install p7zip-full ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install chrpath ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install openssl libssl-dev ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install libgl1-mesa-dev ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install tree ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo apt-get install -qq gcc-6; sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 100 ; fi -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then sudo apt-get install -qq g++-6; sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-6 100 ; fi - -before_script: -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then chmod +x .travis_linux.sh ; fi -- if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then chmod +x .travis_macos.sh ; fi - -script: -- if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then CXX="g++-6" CC="gcc-6" ./.travis_linux.sh ; fi -- if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then ./.travis_macos.sh ; fi - -deploy: - - provider: bintray - skip_cleanup: true - file: "./.linux_bintray.json" - user: tamlok - key: - secure: vADlrYSusARnHxK3NTT3r1r6I/lrxyEuFKLOO73KXl6rvDywrrDDi6YsFekL14/o3clZKLOC8LbvA+4BKPVSoGTO4Dpx/i51fXphf+mMFB3QXSGnbqHm4+2ZnhCl62vfVlFeOPBLDO0KUBI8DCP0I+QogOUickXv3zYx69z6AudSxgjY7nPoN5jGSPgyId4r3o8Shrj1Fk1WtN6qciKyPne57v+jmvRlJTkoEfYkvwTRNMBlmaKy8Vj/CSoIvB8TH8bv3rhHLrN4o1QCwePdaX9G7xlImSpXqgRgzQVU3SRFN2bYTj5DZc1aFyA7iNOhmwgCLAN6OrqXyyJCbyywNhylfgad2rQANcfXiZw9ywooKEYafLDRuiK2G6Pk8m+R6Ded9JBoX9MSz/ZDxxfk4NmLO991wS7IK5aFTQfHZz5W8Tmh1rCphFwlDI/Rxs7ExbXu7INA8IhoLpOSmLIA5lfdC4fD8rv8mjy5gfpMkWlP8XATfi2eMH9uGj89aJa6xp7Bc2mfW3M71YHtYP/pyE/7Bk5vVonP8Cq9rK6OruMIUYtNmXoJnpte20ecSXj9yw7oTR27dhSx3XuAKOXiNpIau0CPxtXA5cSm5X0OS1Lt8RWrms0jp9Ch2dgxlNMpr0soF9DmwekhfHnVoOLyFBWBMDwvkx5TWij9FNAAJb4= - dry-run: false - on: - condition: $TRAVIS_OS_NAME = linux - branch: master - - provider: bintray - skip_cleanup: true - file: "./.macos_bintray.json" - user: tamlok - key: - secure: vADlrYSusARnHxK3NTT3r1r6I/lrxyEuFKLOO73KXl6rvDywrrDDi6YsFekL14/o3clZKLOC8LbvA+4BKPVSoGTO4Dpx/i51fXphf+mMFB3QXSGnbqHm4+2ZnhCl62vfVlFeOPBLDO0KUBI8DCP0I+QogOUickXv3zYx69z6AudSxgjY7nPoN5jGSPgyId4r3o8Shrj1Fk1WtN6qciKyPne57v+jmvRlJTkoEfYkvwTRNMBlmaKy8Vj/CSoIvB8TH8bv3rhHLrN4o1QCwePdaX9G7xlImSpXqgRgzQVU3SRFN2bYTj5DZc1aFyA7iNOhmwgCLAN6OrqXyyJCbyywNhylfgad2rQANcfXiZw9ywooKEYafLDRuiK2G6Pk8m+R6Ded9JBoX9MSz/ZDxxfk4NmLO991wS7IK5aFTQfHZz5W8Tmh1rCphFwlDI/Rxs7ExbXu7INA8IhoLpOSmLIA5lfdC4fD8rv8mjy5gfpMkWlP8XATfi2eMH9uGj89aJa6xp7Bc2mfW3M71YHtYP/pyE/7Bk5vVonP8Cq9rK6OruMIUYtNmXoJnpte20ecSXj9yw7oTR27dhSx3XuAKOXiNpIau0CPxtXA5cSm5X0OS1Lt8RWrms0jp9Ch2dgxlNMpr0soF9DmwekhfHnVoOLyFBWBMDwvkx5TWij9FNAAJb4= - dry-run: false - on: - condition: $TRAVIS_OS_NAME = osx - branch: master diff --git a/.travis_linux.sh b/.travis_linux.sh deleted file mode 100644 index 3cfa7689..00000000 --- a/.travis_linux.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/bash -project_dir=$(pwd) - -# Complain when not in Travis environment -if [ -z ${TRAVIS_COMMIT+x} ]; then - echo "This script is intended to be used only in Travis CI environment." - echo "To build VNote from source, please see the [documentation](https://tamlok.github.io/vnote/en_us/#!docs/Developers/Build%20VNote.md)." - exit 1 -fi - -# Install qt5.9 -sudo add-apt-repository ppa:george-edison55/cmake-3.x -y -sudo add-apt-repository ppa:beineri/opt-qt597-trusty -y -sudo apt-get update -qq -sudo apt-get -y install qt59base qt59webengine qt59webchannel qt59svg qt59location qt59tools qt59translations -source /opt/qt*/bin/qt*-env.sh - -# Compile qt5ct -wget -c https://excellmedia.dl.sourceforge.net/project/qt5ct/qt5ct-0.37.tar.bz2 -tar xf qt5ct-0.*.tar.bz2 -cd qt5ct-0.*/ -QT_SELECT=5 qmake -make -j$(nproc) && sudo make install - -# Compile newer version fcitx-qt5 -sudo apt-get -y install fcitx-libs-dev libgl1-mesa-dev bison -sudo apt-get -y install cmake - -wget http://xkbcommon.org/download/libxkbcommon-0.5.0.tar.xz -tar xf libxkbcommon-0.5.0.tar.xz -cd libxkbcommon-0.5.0 -./configure -prefix=/usr -libdir=/usr/lib/x86_64-linux-gnu -disable-x11 -make -j$(nproc) && sudo make install - -git clone git://anongit.kde.org/extra-cmake-modules -cd extra-cmake-modules -mkdir build && cd build -cmake .. -make -j$(nproc) && sudo make install - -git clone https://github.com/fcitx/fcitx-qt5 -cd fcitx-qt5 -git checkout 1.0.5 -cmake . -make -j$(nproc) && sudo make install - -# Copy fcitx-qt5 files to qt -sudo cp /usr/local/lib/libFcitxQt5DBusAddons.so* /opt/qt*/lib/ -sudo cp /usr/local/lib/libFcitxQt5WidgetsAddons.so* /opt/qt*/lib/ - -tree /opt/qt59/lib/ - -cd ${project_dir} -mkdir build -cd build -qmake -v -qmake CONFIG+=release -spec linux-g++-64 ../VNote.pro -make -j$(nproc) - -# -# Pack AppImage using linuxdeployqt -# -mkdir dist -INSTALL_ROOT=${project_dir}/build/dist make install ; tree dist/ - -# Copy SVG module -mkdir -p ./dist/usr/plugins/iconengines -mkdir -p ./dist/usr/plugins/imageformats -mkdir -p ./dist/usr/plugins/platforminputcontexts -cp /opt/qt59/plugins/iconengines/* ./dist/usr/plugins/iconengines/ -cp /opt/qt59/plugins/imageformats/* ./dist/usr/plugins/imageformats/ -cp /opt/qt59/plugins/platforminputcontexts/* ./dist/usr/plugins/platforminputcontexts/ - -# Copy other project files -cp "${project_dir}/README.md" "dist/README.md" -cp "${project_dir}/LICENSE" "dist/LICENSE" -echo ${version} > ./dist/version -echo "${TRAVIS_COMMIT}" >> ./dist/version - -# Get linuxdeployqt tool -git clone https://github.com/tamlok/vnote-utils.git vnote-utils.git -cp vnote-utils.git/linuxdeployqt-continuous-x86_64.AppImage ./linuxdeployqt-continuous-x86_64.AppImage -# wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" -chmod a+x linuxdeployqt*.AppImage -unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH -./linuxdeployqt*.AppImage ./dist/usr/share/applications/*.desktop -bundle-non-qt-libs -exclude-libs=libnss3,libnssutil3 -extra-plugins=platformthemes/libqt5ct.so,styles/libqt5ct-style.so - -# Copy translations -cp /opt/qt59/translations/*_zh_CN.qm ./dist/usr/translations/ - -# Package it for the second time. -./linuxdeployqt*.AppImage ./dist/usr/share/applications/*.desktop -appimage -exclude-libs=libnss3,libnssutil3 -extra-plugins=platformthemes/libqt5ct.so,styles/libqt5ct-style.so - -tree dist/ - -ls -l *.AppImage - -mv VNote-*.AppImage VNote-${version}-x86_64.AppImage - -cd .. - -exit 0 diff --git a/.travis_macos.sh b/.travis_macos.sh deleted file mode 100644 index 88c963c9..00000000 --- a/.travis_macos.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash -project_dir=$(pwd) - -# Complain when not in Travis environment -if [ -z ${TRAVIS_COMMIT+x} ]; then - echo "This script is intended to be used only in Travis CI environment." - echo "To build VNote from source, please see the [documentation](https://tamlok.github.io/vnote/en_us/#!docs/Developers/Build%20VNote.md)." - exit 1 -fi - -brew update > /dev/null - -brew install gnu-getopt -export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" - -# Download Qt from Qt Installer -cd ${project_dir} -mkdir build -cd build - -export VERBOSE=1 -export QT_CI_PACKAGES="qt.qt5.598.clang_64,qt.qt5.598.qtwebengine" -export QT_CI_LOGIN="tamlok@qq.com" -export QT_CI_PASSWORD="TravisCI@VNote" - -git clone https://github.com/tamlok/qtci.git -source qtci/path.env - -install-qt 5.9.8 -source qt-5.9.8.env - -echo $PATH - -QTDIR="${project_dir}/build/Qt/5.9.8/clang_64" -LDFLAGS=-L$QTDIR/lib -CPPFLAGS=-I$QTDIR/include - -# Build your app -cd ${project_dir}/build -qmake -v -qmake CONFIG-=debug CONFIG+=release ../VNote.pro -make -j2 - -git clone https://github.com/aurelien-rainone/macdeployqtfix.git - -# Package DMG from build/src/VNote.app directory -cd src/ - -sed -i -e 's/com.yourcompany.VNote/com.tamlok.VNote/g' VNote.app/Contents/Info.plist -$QTDIR/bin/macdeployqt VNote.app -python ../macdeployqtfix/macdeployqtfix.py VNote.app/Contents/MacOS/VNote $QTDIR - -# Fix Helpers/QtWebEngineProcess.app -cd VNote.app/Contents/Frameworks/QtWebEngineCore.framework/Versions/5/Helpers -$QTDIR/bin/macdeployqt QtWebEngineProcess.app -python ${project_dir}/build/macdeployqtfix/macdeployqtfix.py QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess $QTDIR - -cd ${project_dir}/build -mkdir -p distrib/VNote -cd distrib/VNote -mv ../../src/VNote.app ./ -cp "${project_dir}/LICENSE" "LICENSE" -cp "${project_dir}/README.md" "README.md" -echo "${version}" > version -echo "${TRAVIS_COMMIT}" >> version - -ln -s /Applications ./Applications - -cd .. -hdiutil create -srcfolder ./VNote -format UDBZ ./VNote.dmg -mv VNote.dmg VNote-${version}-x64.dmg -cd .. - -exit 0 diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index ffebedaf..00000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -# Minimum requirement for CMake version. -# 3.13 or later for Linux and Mac OSX. -# it causes error for build with cmake 3.12 or earlier. -# 3.12 or later for Windows -# because Qt5.9 only support MSVC2017, -# and MSVC2017 is integrated with cmake 3.12. -cmake_policy(SET CMP0042 NEW) -cmake_minimum_required (VERSION 3.12) -project(VNote VERSION 2.8.2 - DESCRIPTION "VNote is a markdown note taking application" - HOMEPAGE_URL "https://tamlok.github.io/vnote" - LANGUAGES C CXX) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -## Qt5 configurations -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTORCC ON) - -# find Qt5 installation -find_package(Qt5 REQUIRED COMPONENTS Core Gui Network PrintSupport WebChannel WebEngine - WebEngineWidgets Positioning Svg Widgets LinguistTools - HINTS - "/opt/qt59/lib/cmake/Qt5/" - "c:/Qt/Qt5.9.8/5.9.8/msvc2017_64/lib/cmake/Qt5/" - "c:/Qt/Qt5.9.9/5.9.9/msvc2017_64/lib/cmake/Qt5/" - "/usr/local/Cellar/qt/5.9.8/clang_64/lib/cmake/Qt5/" - "/usr/local/Cellar/qt/5.9.9/clang_64/lib/cmake/Qt5/") - -## hoedown library -add_library(hoedown STATIC - hoedown/src/autolink.c hoedown/src/document.c hoedown/src/html.c hoedown/src/html_smartypants.c - hoedown/src/version.c hoedown/src/buffer.c hoedown/src/escape.c hoedown/src/html_blocks.c - hoedown/src/stack.c ) -target_link_libraries(hoedown PRIVATE Qt5::Core Qt5::Gui) - -## peg-highlight library -add_library(peg-highlight STATIC peg-highlight/pmh_parser.c peg-highlight/pmh_styleparser.c) -target_link_libraries(peg-highlight PRIVATE Qt5::Core Qt5::Gui) - -## project sources -add_subdirectory(src) - -include(${CMAKE_CURRENT_LIST_DIR}/Packaging.cmake) - -# vim: ts=2 sw=2 sts=2 et diff --git a/CMakeSettings.json b/CMakeSettings.json deleted file mode 100644 index a5e15d01..00000000 --- a/CMakeSettings.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "configurations": [ - { - "name": "x64-Debug", - "generator": "Ninja", - "configurationType": "RelWithDebInfo", - "inheritEnvironments": [ - "msvc_x64_x64" - ], - "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", - "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "-v", - "ctestCommandArgs": "" - } - ] -} \ No newline at end of file diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index fd008af1..00000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,9 +0,0 @@ -OS Version (操作系统): Windows, Linux, macOS - -VNote Version (Help - About VNote - Version: )(VNote版本): 2.2, d78e892d5cc etc.. - -Symptoms (表现): - - -How to Repro (如何复现): - diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 401b9948..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Le Tan - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Packaging.cmake b/Packaging.cmake deleted file mode 100644 index 7326f038..00000000 --- a/Packaging.cmake +++ /dev/null @@ -1,197 +0,0 @@ -find_package(Qt5Core REQUIRED) -get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) -get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) - -set(CPACK_PACKAGE_VENDOR "Le Tan") -set(CPACK_PACKAGE_NAME "vnote") -set(CPACK_PACKAGE_CONTACT "Le Tan ") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}") -set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md") -set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") -set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) -set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) -set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) - -set(CPACK_PACKAGE_INSTALL_DIRECTORY "vnote") -set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}") - -# set human names to executables -set(CPACK_PACKAGE_EXECUTABLES "VNote" "VNote") -set(CPACK_CREATE_DESKTOP_LINKS "VNote") -set(CPACK_STRIP_FILES TRUE) - -#------------------------------------------------------------------------------ -# include CPack, so we get target for packages -set(CPACK_OUTPUT_CONFIG_FILE "${CMAKE_BINARY_DIR}/BundleConfig.cmake") - -add_custom_target(bundle - COMMAND ${CMAKE_CPACK_COMMAND} "--config" "${CMAKE_BINARY_DIR}/BundleConfig.cmake" - COMMENT "Running CPACK. Please wait..." - DEPENDS VNote) -set(CPACK_GENERATOR) - -# Qt IFW packaging framework -set(CPACK_IFW_ROOT $ENV{HOME}/Qt/QtIFW-3.0.6/ CACHE PATH "Qt Installer Framework installation base path") -find_program(BINARYCREATOR_EXECUTABLE binarycreator HINTS "${_qt_bin_dir}" ${CPACK_IFW_ROOT}/bin) -if(BINARYCREATOR_EXECUTABLE) - list(APPEND CPACK_GENERATOR IFW) - message(STATUS " + Qt Installer Framework YES ") -else() - message(STATUS " + Qt Installer Framework NO ") -endif() - -if (WIN32 AND NOT UNIX) - #-------------------------------------------------------------------------- - # Windows specific - find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}" DOC "Path to the windeployqt utility") - list(APPEND CPACK_GENERATOR ZIP) - message(STATUS "Package generation - Windows") - message(STATUS " + ZIP YES ") - - set(PACKAGE_ICON "${CMAKE_SOURCE_DIR}/src/resources/icons/vnote.ico") - - # NSIS windows installer - find_program(NSIS_PATH nsis PATH_SUFFIXES nsis) - if(NSIS_PATH) - list(APPEND CPACK_GENERATOR NSIS) - message(STATUS " + NSIS YES ") - set(CPACK_NSIS_DISPLAY_NAME ${CPACK_PACKAGE_NAME}) - set(CPACK_NSIS_MUI_ICON "${PACKAGE_ICON}") - set(CPACK_NSIS_MUI_HEADERIMAGE_BITMAP "${PACKAGE_ICON}") - set(CPACK_NSIS_CONTACT "${CPACK_PACKAGE_CONTACT}") - set(CPACK_NSIS_MODIFY_PATH ON) - else() - message(STATUS " + NSIS NO ") - endif() - - # NuGet package - find_program(NUGET_EXECUTABLE nuget) - if(NUGET_EXECUTABLE) - list(APPEND CPACK_GENERATOR NuGET) - message(STATUS " + NuGET YES ") - set(CPACK_NUGET_PACKAGE_NAME "VNote") - else() - message(STATUS " + NuGET NO ") - endif() - - # Bundle Library Files - if(CMAKE_BUILD_TYPE_UPPER STREQUAL "DEBUG") - set(WINDEPLOYQT_ARGS --debug) - else() - set(WINDEPLOYQT_ARGS --release) - endif() - file(MAKE_DIRECTORY "${CPACK_PACKAGE_DIRECTORY}/_qtstaff") - add_custom_command(TARGET bundle PRE_BUILD - COMMAND "${CMAKE_COMMAND}" -E - env PATH="${_qt_bin_dir}" "${WINDEPLOYQT_EXECUTABLE}" - ${WINDEPLOYQT_ARGS} - --verbose 0 - --no-compiler-runtime - --no-angle - --no-opengl-sw - --dir "${CPACK_PACKAGE_DIRECTORY}/_qtstaff" - $ - COMMENT "Deploying Qt..." - ) - install(DIRECTORY "${CPACK_PACKAGE_DIRECTORY}/_qtstaff/" DESTINATION bin) - set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) - include(InstallRequiredSystemLibraries) - -elseif (APPLE) - #-------------------------------------------------------------------------- - # Apple specific - find_program(MACDEPLOYQT_EXECUTABLE macdeployqt HINTS "${_qt_bin_dir}" DOC "Path to the macdeployqt utility") - find_program(MACDEPLOYQTFIX_EXECUTABLE macdeployqtfix.py HINTS "${_qt_bin_dir}" DOC "Path to the macdeployqtfix utility") - find_package(Python2 REQUIRED COMPONENTS Interpreter) - message(STATUS "Package generation - Mac OS X") - set(CPACK_PACKAGE_ICON ${CMAKE_SOURCE_DIR}/resources/Icon.icns) - list(APPEND CPACK_GENERATOR External) - set(CPACK_EXTERNAL_ENABLE_STAGING ON) - set(CPACK_SET_DESTDIR ON) - message(STATUS " + macdeployqt -dmg YES ") - set(EXTERNAL_WORK "_CPack_Packages/Darwin/External/${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-Darwin") - set(APP_BUNDLE "${CPACK_PACKAGE_DIRECTORY}/${EXTERNAL_WORK}/${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app") - string(FIND "${Qt5_DIR}" "/cmake/Qt5" _STR_LOC) - string(SUBSTRING "${Qt5_DIR}" 0 ${_STR_LOC} _QT_LIB_ROOT) - file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/CPackExternal.cmake" - CONTENT "execute_process(COMMAND \"${MACDEPLOYQT_EXECUTABLE}\" \"${APP_BUNDLE}\" -always-overwrite -verbose=2 -libpath=${_QT_LIB_ROOT}) - execute_process(COMMAND ${Python2_EXECUTABLE} \"${MACDEPLOYQTFIX_EXECUTABLE}\" \"${APP_BUNDLE}/Contents/MacOS/VNote\" ${_QT_LIB_ROOT} -v) - execute_process(COMMAND \"${MACDEPLOYQT_EXECUTABLE}\" \"${APP_BUNDLE}/Contents/Frameworks/QtWebEngineCore.framework/Versions/5/Helpers/QtWebEngineProcess.app\" -verbose=2 -libpath=${_QT_LIB_ROOT}) - execute_process(COMMAND ${Python2_EXECUTABLE} \"${MACDEPLOYQTFIX_EXECUTABLE}\" \"${APP_BUNDLE}/Contents/Frameworks/QtWebEngineCore.framework/Versions/5/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess\" ${_QT_LIB_ROOT} -v) - execute_process(COMMAND \"${MACDEPLOYQT_EXECUTABLE}\" \"${APP_BUNDLE}\" -dmg -verbose=2 -always-overwrite -libpath=${_QT_LIB_ROOT})" - ) - set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_BINARY_DIR}/CPackExternal.cmake") - include(InstallRequiredSystemLibraries) - -else () - #----------------------------------------------------------------------------- - # Linux specific - list(APPEND CPACK_GENERATOR TBZ2 TXZ) - message(STATUS "Package generation - UNIX") - message(STATUS " + TBZ2 YES ") - message(STATUS " + TXZ YES ") - - find_program(RPMBUILD_PATH rpmbuild) - if(RPMBUILD_PATH) - message(STATUS " + RPM YES ") - set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") - set(CPACK_RPM_PACKAGE_LICENSE "MIT") - else() - message(STATUS " + RPM NO ") - endif() - - find_program(DEBUILD_PATH debuild) - if(DEBUILD_PATH) - list(APPEND CPACK_GENERATOR DEB) - message(STATUS " + DEB YES ") - # use default, that is an output of `dpkg --print-architecture` - #set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") - set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) - set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://tamlok.github.io/vnote") - if(Qt5_DIR STREQUAL "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/cmake/Qt5" ) - set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) - else() - set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) - set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5core5a, libqt5gui5, libqt5positioning5, libqt5webenginewidgets5") - endif() - set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "graphviz") - set(CPACK_DEBIAN_PACKAGE_SUGGESTS "libjs-mathjax") - set(CPACK_DEBIAN_PACKAGE_SECTION "utils") - endif() - - find_program(LINUXDEPLOY_EXECUTABLE linuxdeploy linuxdeploy-x86_64.AppImage HINTS "${_qt_bin_dir}") - if(LINUXDEPLOY_EXECUTABLE) - message(STATUS " + AppImage YES ") - find_path(NSS3_PLUGIN_PATH NAMES libsoftokn3.so PATHS /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} /usr/lib /usr/local/lib - PATH_SUFFIXES nss NO_DEFAULT_PATH) - set(CPACK_GENERATOR "External;${CPACK_GENERATOR}") - # run make DESTDIR= install before run package script - set(CPACK_EXTERNAL_ENABLE_STAGING ON) - set(CPACK_SET_DESTDIR ON) - set(_EXTERNAL_PACKDIR ${CPACK_PACKAGE_DIRECTORY}/_CPack_Packages/Linux/External/${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-Linux) - string(FIND "${Qt5_DIR}" "/cmake/Qt5" _STR_LOC) - string(SUBSTRING "${Qt5_DIR}" 0 ${_STR_LOC} _QT_LIB_ROOT) - set(_LINUXDEPLOY_ENV "QMAKE=${_qmake_executable}" "LD_LIBRARY_PATH=${_QT_LIB_ROOT}:$ENV{LD_LIBRARY_PATH}") - file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/CPackExternal.cmake" - CONTENT "execute_process(COMMAND ${CMAKE_COMMAND} -E env ${_LINUXDEPLOY_ENV} \"${LINUXDEPLOY_EXECUTABLE}\" --plugin qt --output appimage - -v1 - --appdir ${_EXTERNAL_PACKDIR} -e ${_EXTERNAL_PACKDIR}${CMAKE_INSTALL_PREFIX}/bin/VNote - --desktop-file ${_EXTERNAL_PACKDIR}${CMAKE_INSTALL_PREFIX}/share/applications/vnote.desktop - -i ${CMAKE_SOURCE_DIR}/src/resources/icons/16x16/vnote.png -i ${CMAKE_SOURCE_DIR}/src/resources/icons/32x32/vnote.png - -i ${CMAKE_SOURCE_DIR}/src/resources/icons/48x48/vnote.png -i ${CMAKE_SOURCE_DIR}/src/resources/icons/64x64/vnote.png - -i ${CMAKE_SOURCE_DIR}/src/resources/icons/128x128/vnote.png -i ${CMAKE_SOURCE_DIR}/src/resources/icons/256x256/vnote.png - -i ${CMAKE_SOURCE_DIR}/src/resources/icons/vnote.svg - -l ${NSS3_PLUGIN_PATH}/libfreebl3.so -l ${NSS3_PLUGIN_PATH}/libfreeblpriv3.so -l ${NSS3_PLUGIN_PATH}/libnssckbi.so - -l ${NSS3_PLUGIN_PATH}/libnssdbm3.so -l ${NSS3_PLUGIN_PATH}/libsoftokn3.so - WORKING_DIRECTORY ${CPACK_PACKAGE_DIRECTORY})" - ) - set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_BINARY_DIR}/CPackExternal.cmake") - else() - message(STATUS " + AppImage NO ") - endif() - - # set package icon - set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/src/resources/icons/vnote.png") -endif() - -include(CPack) diff --git a/README.md b/README.md deleted file mode 100644 index d76577f9..00000000 --- a/README.md +++ /dev/null @@ -1,227 +0,0 @@ -# VNote -[中文 Chinese](./README_zh.md) | [日本語 Japanese](./README_ja.md) - -**VNote is a note-taking application that knows programmers and Markdown better.** - -For more information, please visit [**VNote's Homepage**](https://tamlok.github.io/vnote). - -Check this [showcase screencast](https://www.youtube.com/watch?v=EFCmCFZKxJ4) to know what you could do with VNote! - -![VNote](screenshots/vnote.png) - -# Downloads -Users from China can download the latest release of VNote from [Tianyi Netdisk](https://cloud.189.cn/t/Av67NvmEJVBv). - -## Windows -### Official Zip -![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/tamlok/vnote?svg=true) - -- [Github releases](https://github.com/tamlok/vnote/releases) -- Latest builds on master: [ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -**NOT** supported in XP since QtWebEngineProcess used by VNote could not work in XP. - -### Scoop -VNote can be installed from `extras` bucket of Scoop. - -```shell -scoop bucket add extras -scoop install vnote -scoop update vnote -``` - -## Linux -### AppImage -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -There is an AppImage format standalone executable of VNote for major Linux distributions. **Any help for packaging and distribution on Linux is appreciated!** - -- [Github releases](https://github.com/tamlok/vnote/releases) -- Latest builds on master: [ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -### openSUSE -Currently `vnote` on openSUSE Tumbleweed can be installed from `home:opensuse_zh` project on OBS. You can execute the following command directly: - -```shell -sudo zypper ar https://download.opensuse.org/repositories/home:/opensuse_zh/openSUSE_Tumbleweed/ home:opensuse_zh -sudo zypper ref -sudo zypper in vnote -``` - -For other architectures, please search for `vnote` at [software.opensuse.org](https://software.opensuse.org). - -We don't support Leap 42 and below due to the Qt version. Please use AppImage or build it yourself. - -### Arch Linux -VNote on Arch Linux can be installed from the AUR as [vnote](https://aur.archlinux.org/packages/vnote-bin/): - -```shell -git clone https://aur.archlinux.org/vnote-bin.git -cd vnote-bin -makepkg -sic -``` - -There is also a development version that tracks the latest master [vnote-git](https://aur.archlinux.org/packages/vnote-git/). - -### NixOS -Thank @kuznero for packaging VNote in NixOS. It should be available in `unstable` and `unstable-small` channels. - -## MacOS -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -- [Github releases](https://github.com/tamlok/vnote/releases) -- Latest builds on master: [ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -You can also install VNote using homebrew, through the cask tap: - -```shell -brew cask install vnote -``` - -# Description -**VNote** is a Qt-based, free and open source note-taking application, focusing on Markdown. VNote is designed to provide a comfortable editing experience, especially for programmers. - -VNote is **NOT** just a simple editor for Markdown. By providing notes management, VNote makes taking notes in Markdown simpler and more pleasant. - -Utilizing Qt, VNote could run on **Linux**, **Windows**, and **macOS**. - -![VNote Main Interface](screenshots/_vnotemaini_1525154456_1561295841.png) - -# Supports -- [Github issues](https://github.com/tamlok/vnote/issues); -- Email: `tamlokveer at gmail.com`; -- [Slack](https://join.slack.com/t/vnote/shared_invite/enQtNDg2MzY0NDg3NzI4LTVhMzBlOTY0YzVhMmQyMTFmZDdhY2M3MDQxYTBjOTA2Y2IxOGRiZjg2NzdhMjkzYmUyY2VkMWJlZTNhMTQyODU); -- [Telegram](https://t.me/vnotex); -- WeChat Public Account: VNote笔记 (vnote_md); -![VNote WeChat](screenshots/vnote_md.jpg) - -# Highlights -- Powerful **full-text search**; -- **Universal Entry** to reach anything just by typing; -- Inserting images directly from clipboard; -- Syntax highlights of fenced code blocks in both **edit** and **read** mode; -- Powerful **In-Place Preview** for images, diagrams, and formulas; -- Side-by-side live preview for diagrams; -- Outline in both edit and read mode; -- Custom styles in both edit and read mode; -- **Vim** mode and a set of powerful shortcuts; -- Infinite levels of folders; -- Multiple tabs and splitting windows; -- [Mermaid](http://knsv.github.io/mermaid/), [Flowchart.js](http://flowchart.js.org/), [MathJax](https://www.mathjax.org/), [PlantUML](http://plantuml.com/), and [Graphviz](http://www.graphviz.org/); -- Supports HiDPI; -- Attachments of notes; -- Themes and dark mode; -- Rich and extensible export, such as HTML, PDF, PDF (All In One), and images; -- GitHub and WeChat image hosting; - -# Donate -You could help VNote's development in many ways. - -- Keep monitoring VNote and sending feedback for improvement. -- Spread and promote VNote to your friends. Popularity is a strong power to drive developers. -- Participate in the development of VNote and send PullRequest to make VNote perfect. -- Last, really appreciate your donate to VNote if you think VNote really helps you and you want to help VNote. - -**PayPal**: [PayPal.Me/vnotemd](https://www.paypal.me/vnotemd) - -**Alipay**: `tamlokveer@gmail.com` - - - -**WeChat** - - - -Thank [users who donated to VNote](https://github.com/tamlok/vnote/wiki/Donate-List)! - -# Why VNote -## Markdown Editor & Notes Management -VNote tries to be a powerful Markdown editor with notes management, or a note-taking application with pleasant Markdown support. If you are a fan of Markdown and enjoy writing Markdown notes for study, work, and life, VNote is the right tool for you. - -## Pleasant Markdown Experience -### Insights About Markdown -Markdown, as a simple mark language, unlike rich text, was born with a **gap between edit and read**. There are about three ways to handle this gap: - -1. As one extreme, some editors just treat Markdown as **plain text**. Users may lose themselves in the messy black characters. It is hard to keep track of the information of the note. -2. Most Markdown editors use two panels to **edit and preview Markdown notes simultaneously**. It makes things easier since users could see a pleasant typesetting and layout while editing the text. However, two panels may occupy the whole screen and users keep moving eyes left and right which will be a big distraction. -3. As another extreme, some editors convert the Markdown elements in place immediately after the typing, which makes editing Markdown just like editing rich text document in Word. - -Since most editors choose the second way to handle the gap, people always think of preview when it comes to Markdown. It may be a misunderstanding about Markdown. Designed as a simple mark language, Markdown is intended to help to keep track of the information of the text when editing and provide a beautiful typesetting when reading after being converted to HTML. - -### Tradeoff: VNote's Way -VNote tries to minimize the gap and provide the best-effort *WYSIWYG* for Markdown via tuned **syntax highlights** and some other features. By helping to keep track of the content, there is no need to preview or alter the text immediately after being typed. - -# Features -## Notebook-Based Notes Management -VNote uses **notebooks** to hold your notes. Like OneNote, a notebook can be hosted on any location on your system. A notebook is designed to represent one account. For example, you could have one notebook hosted on local file system and another notebook hosted on an OwnCloud server. This is really useful when notes require different levels of security. - -A notebook corresponds to a self-contained folder (called the *Root Folder* of the notebook) in the file system. You could copy the folder to another location (or on another computer) and import it into VNote. - -A notebook could have infinite levels of folders. VNote supports copying or moving folders or notes within or between notebooks. - -## Simple Notes Management -All your notes are managed by some plaintext configuration files and stored as plaintext files. You could access your notes without VNote. You could use external file synchronization services to synchronize your notes and import them on another machine. - -VNote supports both Markdown (suffix `md`) and rich text notes. - -## Syntax Highlight -VNote supports accurate syntax highlight for Markdown. Tuning the style of the highlight, VNote enables you to keep track of your document easily. - -VNote also supports **syntax highlight for fenced code blocks** in edit mode in Markdown, which is **superior** than almost all current Markdown editors. - -![Syntax Highlight](screenshots/_1513485266_1616037517.png) - -## In-Place Preview -VNote supports powerful **in-place preview** for images, diagrams, and formulas in edit mode. - -![In-Place Preview](screenshots/_inplacepre_1525155248_405615820.png) - -## Pleasant Image Experience -Just paste your image into the Markdown note, VNote will manage all other stuffs. VNote stores images in a specified folder in the same folder with the note. VNote will pop up a window to preview the image when you insert an image. Furthermore, VNote will delete the useless image files automatically after you remove the image links. - -## Universal Entry & Full-Text Search -VNote has powerful built-in full-text search with **Regular Expression** and **Fuzzy Search** support. The search could be executed within all notebooks, current notebook, or current folder, targeted at name or content. - -Like the `CtrlP` in Vim, VNote supports **Universal Entry** to reach anything by typing in a simple input. - -![Universal Entry](screenshots/_universale_1522894821_465772669.png) - -## Interactive Outline Viewer In Read & Edit Mode -VNote provides a user-friendly outline viewer for both edit and view mode. The outline viewer is a responsive item tree instead of a segment of HTML. - -## Powerful Shortcuts -VNote supports many pleasant and powerful shortcuts which facilitate your editing, including **Vim Mode**, **Captain Mode**, and **Navigation Mode** which enable you to work without the mouse. - -Please refer to the [shortcuts help](src/resources/docs/shortcuts_en.md) in the help menu for more details. - -## Highly Configurable -In VNote, almost everything is configurable, such as background color, font, and Markdown style. VNote uses a plaintext file to record all your configuration, so you could just copy that file to initialize a new VNote on another computer. - -# Dependencies -- [Qt 5.9](http://qt-project.org) (L-GPL v3) -- [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License) -- [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License) -- [Marked 0.5.1](https://github.com/markedjs/marked) (MIT License) -- [Highlight.js](https://github.com/isagalaev/highlight.js/) (BSD License) -- [Ionicons 2.0.1](https://github.com/driftyco/ionicons/) (MIT License) -- [markdown-it 8.3.1](https://github.com/markdown-it/markdown-it) (MIT License) -- [markdown-it-headinganchor 1.3.0](https://github.com/adam-p/markdown-it-headinganchor) (MIT License) -- [markdown-it-task-lists 1.4.0](https://github.com/revin/markdown-it-task-lists) (ISC License) -- [markdown-it-footnote](https://github.com/markdown-it/markdown-it-footnote) (MIT License) -- [markdown-it-sub](https://github.com/markdown-it/markdown-it-sub) (MIT License) -- [markdown-it-sup](https://github.com/markdown-it/markdown-it-sup) (MIT License) -- [markdown-it-front-matter](https://github.com/craigdmckenna/markdown-it-front-matter) (MIT License) -- [markdown-it-imsize](https://github.com/tatsy/markdown-it-imsize) (Unknown) (Thanks @Kinka for help) -- [markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji) (MIT License) -- [markdown-it-texmath](https://github.com/goessner/markdown-it-texmath) (MIT License) -- [markdown-it-container 2.0.0](https://github.com/markdown-it/markdown-it-container) (MIT License) -- [mermaid 7.0.0](https://github.com/knsv/mermaid) (MIT License) -- [MathJax](https://www.mathjax.org/) (Apache-2.0) -- [showdown](https://github.com/showdownjs/showdown) (MIT License) -- [flowchart.js](https://github.com/adrai/flowchart.js) (MIT License) -- [PlantUML](http://plantuml.com/) (MIT License) -- [dom-to-image](https://github.com/tsayen/dom-to-image) (MIT License) -- [turndown](https://github.com/domchristie/turndown) (MIT License) - -# License -VNote is licensed under the [MIT license](http://opensource.org/licenses/MIT). diff --git a/README_ja.md b/README_ja.md deleted file mode 100644 index 14ddf2b8..00000000 --- a/README_ja.md +++ /dev/null @@ -1,220 +0,0 @@ -# VNote -[中文 Chinese](./README_zh.md) | [英語 English](./README.md) - -**VNote は、プログラマとMarkdownをよく理解するノート作成アプリケーションです。** - -詳細情報は、[**VNoteのホームページ**](https://tamlok.github.io/vnote)に訪問してください。 - -![VNote](screenshots/vnote.png) - -# ダウンロード -## Windows -### Zipアーカイブ -![Windowsビルド・ステータス](https://ci.appveyor.com/api/projects/status/github/tamlok/vnote?svg=true) - -- [Githubリリース](https://github.com/tamlok/vnote/releases) -- 開発中の最新ビルド: [![ダウンロード](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg)](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -Windows XPはサポート**されません。** - -### Scoop -VNote can be installed from `extras` bucket of Scoop. - -```shell -scoop bucket add extras -scoop install vnote -scoop update vnote -``` - -## Linux -### AppImage -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -主要Linuxディストリビューションむけには、AppImageのVNoteスタンドアロン実行ファイルがあります。**Linuxのパッケージングと配布の支援を歓迎します!** - -- [Githubリリース](https://github.com/tamlok/vnote/releases) -- 開発中の最新ビルド: [![ダウンロード](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg)](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -### openSUSE -現在、OpenSUSE Tumbleweedの`vnote`は、OBS上の`home:openuse_zh`プロジェクトからインストールすることができます。次のコマンドを直接実行できます。 - -```shell -sudo zypper ar https://download.opensuse.org/repositories/home:/opensuse_zh/openSUSE_Tumbleweed/ home:opensuse_zh -sudo zypper ref -sudo zypper in vnote -``` - -その他のアーキテクチャについては、[software.opensuse.org](https://software.opensuse.org)で`vnote`を検索してください。 - -Qtバージョンの関係で、Leap 42およびそれ以下のバージョンをサポートしていません。AppImageを使ったり、自分でビルドしてください。 - -### Arch Linux -Arch Linux上のVNoteは、AURから[vnote](https://aur.archlinux.org/packages/vnote-bin/)のインストールができます。 - -```shell -git clone https://aur.archlinux.org/vnote-bin.git -cd vnote-bin -makepkg -sic -``` - -また、最新のマスター[vnote git](https://aur.archlinux.org/packages/vnote-git/)を追跡する開発バージョンもあります。 - -### NixOS -Thank @kuznero for packaging VNote in NixOS. It should be available in `unstable` and `unstable-small` channels. - -## MacOS -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -- [Githubリリース](https://github.com/tamlok/vnote/releases) -- 開発中の最新ビルド: [![ダウンロード](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg)](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -cask tapを通じ、homebrewをつかってVNoteをインストールすることもできます。 - -```shell -brew cask install vnote -``` - -# 説明 -**VNote**は、Qtベースの無料のオープンソースのノート作成アプリケーションで、Markdownに焦点を当てています。VNoteは、特にプログラマーにとって快適な編集エクスペリエンスを提供するように設計されています。 - -VNoteは、Markdownの単純なエディタ**ではありません**。ノート管理を提供することで、VNoteはマークダウンのノート作成をより簡単に、より楽しくすることができます。 - -Qtを使用し、VNoteは、**Linux**, **Windows**そして、**macOS**で利用できます。 - -![VNote主インタフェース](screenshots/_vnotemaini_1525154456_1561295841.png) - -# サポート -- [Github issues](https://github.com/tamlok/vnote/issues); -- Email: `tamlokveer at gmail.com`; -- [Slack](https://join.slack.com/t/vnote/shared_invite/enQtNDg2MzY0NDg3NzI4LTVhMzBlOTY0YzVhMmQyMTFmZDdhY2M3MDQxYTBjOTA2Y2IxOGRiZjg2NzdhMjkzYmUyY2VkMWJlZTNhMTQyODU); -- [Telegram](https://t.me/vnotex); - -# ハイライト -- 強力な**全文検索**; -- **ユニバーサルエントリ**は、入力するだけで何かに到達することができます。 -- 直接クリップボードから画像を挿入; -- **編集**と**読み込み**の両方で、フェンシングされたコードブロックの構文のハイライト表示; -- 編集モードでの画像、図、数式の強力な**その場プレビュー**; -- 図の横並びのライブプレビュー; -- 編集モードと読み込みモードの両方でアウトラインを作成; -- 編集モードと読み込みモードの両方でカスタムスタイル; -- **Vim**モードと協力なショートカットキー; -- 無限レベルのフォルダ; -- 複数のタブとウィンドウ分割; -- [Mermaid](http://knsv.github.io/mermaid/), [Flowchart.js](http://flowchart.js.org/), [MathJax](https://www.mathjax.org/), [PlantUML](http://plantuml.com/), and [Graphviz](http://www.graphviz.org/); -- HiDPIのサポート; -- ノートの添付ファイル; -- テーマとダーク・モード; -- HTML、PDF、PDF(All In One)、イメージなど、拡張性と拡張性に優れたエクスポート - -# 寄付 -VNoteの開発に、さまざまな方法で支援できます。 - -- VNoteの開発に注目し、改善のためにフィードバックを送信する -- VNoteを友達に広める。人気がひろまることは、開発者にとって大きなエネルギーになります。 -- VNoteの開発に参加し、VNoteを完全にするためにPullRequestを送信します。 -- VNoteが本当に役に立ち、VNoteを助けたいと思ったら、VNoteへの寄付を本当に感謝します。 - -**PayPal**: [PayPal.Me/vnotemd](https://www.paypal.me/vnotemd) - -**Alipay**: `tamlokveer@gmail.com` - - - -**WeChat** - - - -[VNoteヘ寄付されたユーザ](https://github.com/tamlok/vnote/wiki/Donate-List)に感謝いたします! - -# VNoteのわけ -## Markdown編集とノート管理 -VNoteは、ノート管理機能のついた協力なMarkdownエディタ、あるいは快適なMarkdownサポートつきのノート作成アプリケーションを目指しています。もしMarkdownのファンで、勉強や仕事、人生のためにMarkdownのノートを書くのなら、VNoteはあなたにとって正しいツールです。 - -## 快適なマークダウン体験 -### Markdownについての洞察 -Markdownは、リッチテキストとは異なり、編集と読み取りの間にある**ギャップ**を持って生まれた、シンプルなマークアップ言語です。このギャップを扱うには、3つの方法があります。 - -1. 一つの極端な例として、エディタの中には、Markdownを**プレーンテキスト**として扱うだけのものもある。ユーザーは、ごちゃごちゃした黒い文字で自分を失うことがあります。メモの情報を追跡するのは難しくなる。 -2. ほとんどのMarkdownエディターは、**編集とプレビューを同時に行うために、2つのパネルを使用します**。ユーザーはテキストの編集中に、楽しいタイプの設定とレイアウトを見ることができるので、より簡単になります。しかし、2つのパネルが画面全体を占め、ユーザは目を左右に動かすことになり、大きな混乱を招くことになりかねません。 -3. もう一つの極端な点として、編集の直後にMarkdown要素を変換するエディタもあり、Wordのリッチテキスト文書を編集するのと同じように、Markdownを編集することができます。 - -ほとんどのエディタは、ギャップを処理するための2番目の方法を選んでいるので、Markdownをつかうときは、常にプレビューを考えていることになります。これは、Markdownの誤解かもしれません。シンプルなマーク言語として設計されたMarkdownは、編集時にテキストの情報を記録し、HTMLに変換された後に美しいタイプの設定を提供することを目的としています。 - -### トレードオフ:VNoteの方法 -VNoteは、チューニングされた**構文ハイライト**とその他の機能によって、ギャップを最小限に抑えて、Markdownのためにベストエフォート*WYSIWYG*を提供します。コンテンツを追跡することを助けることにより、テキストを入力した直後にテキストをプレビューしたり変更する必要がなくなります。 - -# 機能 -## ノートブック・ベースのノート管理 -VNoteは、**ノートブック**を使用してノートを管理することができます。OneNoteと同様に、ノートブックはシステム上の任意の場所にホストすることができます。ノートブックは1つのアカウントを表すように設計されています。たとえば、ローカル・ファイルシステムで管理されているノートブックと、OwnCloudサーバ上に保存されている別のノートブックをもつことができます。これは、メモが異なるレベルのセキュリティを必要とする場合に、実際に役立ちます。 - -ノートブックは、ファイルシステム内の自己完結型フォルダ(ノートブックの*Rootフォルダ*と呼ばれます)に対応しています。フォルダを別の場所(または別のコンピュータ)にコピーして、VNoteにインポートすることができます。 - -ノートブックは、無限レベルのフォルダを持つことができます。VNoteでは、ノートブック内またはノートブック間でフォルダやノートをコピーまたは移動することができます。 - -## シンプルなノート管理 -すべてのメモは、平文の設定ファイルによって管理され、平文ファイルとして格納されます。ノートは、VNOTEなしでアクセスできます。外部のファイル同期サービスを使用して、ノートを同期させたり、別のマシンにインポートすることができます。 - -VNoteは、Markdown(拡張子`md`)とリッチテキストノートの両方をサポートしています。 - -## 構文ハイライト -VNoteでは、Markdownの正確な構文強調表示をサポートしています。ハイライトのスタイルを調整することで、VNoteを使用してドキュメントを簡単に追跡することができます。 - -また、VNoteは、**Fenceされたコードブロックに対する**構文ハイライトをサポートしています。これは、現在のあらゆるMarkdownエディタよりも**優れています**。 - -![Syntax Highlight](screenshots/_1513485266_1616037517.png) - -## インプレイスプレビュー -VNoteは、編集モードでのイメージ、図、数式の強力な**その場プレビュー**をサポートしています。 - -![その場プレビュー](screenshots/_inplacepre_1525155248_405615820.png) - -## 快適なイメージ体験 -画像をMarkdownに貼り付けするだけで、VNoteは他のすべてのものを管理することになります。VNoteは、同じフォルダ内の指定されたフォルダに、ノートとともに画像を格納します。VNoteは、画像を挿入するときに画像プレビューするウィンドウをポップアップ表示させます。また、VNoteは、画像リンクを削除した後に、自動的に画像ファイルを削除します。 - -## ユニバーサルエントリと全文検索 -VNote には、**正規表現**と**ファジー検索**サポートのある、強力な全文検索が組み込まれています。検索は、すべてのノートブック、現在のノートブック、または現在のフォルダ、名前またはコンテンツを対象に実行することができます。 - -VNoteは、Vimでの`Ctrl+P`のように、**ユニバーサルエントリ**機能をサポートし、シンプルな入力であらゆる機能へ到達できます。 - -![ユニバーサルエントリ](screenshots/_universale_1522894821_465772669.png) - -## 読み込み&編集モードのインタラクティブなアウトライン表示 -VNoteでは、編集モードと閲覧モードの両方でユーザフレンドリなアウトラインビューアが提供されています。アウトライン・ビューアは、HTMLのセグメントではなく、応答するアイテム・ツリーです。 - -## 強力なショートカット -VNoteは、Vim Mode**、**キャプテンモード**、、**ナビゲーションモード**など、編集を容易にする強力なショートカットをサポートしています。これにより、マウスを使用せずに作業を行うことができます。 - -詳細については、ヘルプメニューの[ショートカットヘルプ](src/resources/docs/shortcuts_en.md)を参照してください。 - -## 柔軟に調整可能 -VNoteでは、背景色、フォント、マークダウンなど、ほとんどすべてのものが調整可能です。VNoteは平文ファイルを使ってすべての構成を記録しますので、そのファイルをコピーすれば、別のコンピュータで新しいVNoteを初期化することができます。 - -# 依存関係 -- [Qt 5.9](http://qt-project.org) (L-GPL v3) -- [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License) -- [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License) -- [Marked 0.5.1](https://github.com/markedjs/marked) (MIT License) -- [Highlight.js](https://github.com/isagalaev/highlight.js/) (BSD License) -- [Ionicons 2.0.1](https://github.com/driftyco/ionicons/) (MIT License) -- [markdown-it 8.3.1](https://github.com/markdown-it/markdown-it) (MIT License) -- [markdown-it-headinganchor 1.3.0](https://github.com/adam-p/markdown-it-headinganchor) (MIT License) -- [markdown-it-task-lists 1.4.0](https://github.com/revin/markdown-it-task-lists) (ISC License) -- [markdown-it-footnote](https://github.com/markdown-it/markdown-it-footnote) (MIT License) -- [markdown-it-sub](https://github.com/markdown-it/markdown-it-sub) (MIT License) -- [markdown-it-sup](https://github.com/markdown-it/markdown-it-sup) (MIT License) -- [markdown-it-front-matter](https://github.com/craigdmckenna/markdown-it-front-matter) (MIT License) -- [markdown-it-imsize](https://github.com/tatsy/markdown-it-imsize) (Unknown) (Thanks @Kinka for help) -- [markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji) (MIT License) -- [markdown-it-texmath](https://github.com/goessner/markdown-it-texmath) (MIT License) -- [markdown-it-container 2.0.0](https://github.com/markdown-it/markdown-it-container) (MIT License) -- [mermaid 7.0.0](https://github.com/knsv/mermaid) (MIT License) -- [MathJax](https://www.mathjax.org/) (Apache-2.0) -- [showdown](https://github.com/showdownjs/showdown) (Unknown) -- [flowchart.js](https://github.com/adrai/flowchart.js) (MIT License) -- [PlantUML](http://plantuml.com/) (MIT License) -- [dom-to-image](https://github.com/tsayen/dom-to-image) (MIT License) -- [turndown](https://github.com/domchristie/turndown) (MIT License) - -# ライセンス -VNoteは、[MITライセンス](http://opensource.org/licenses/MIT)の下でライセンスされています。 diff --git a/README_zh.md b/README_zh.md deleted file mode 100644 index 52ccc7a0..00000000 --- a/README_zh.md +++ /dev/null @@ -1,228 +0,0 @@ -# VNote -[英文 English](./README.md) | [日本語 Japanese](./README_ja.md) - -**VNote 是一个更懂程序员和 Markdown 的笔记软件!** - -更多信息,请访问 [**VNote 主页**](https://tamlok.github.io/vnote) 。 - -观看[展示录屏](https://www.bilibili.com/video/av77455284) ! - -![VNote](screenshots/vnote.png) - -# 下载 -国内的用户可以尝试在[天翼云盘](https://cloud.189.cn/t/Av67NvmEJVBv)下载 VNote 的最新发行版本。 - -## Windows -### 官方压缩包 -![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/tamlok/vnote?svg=true) - -- [Github releases](https://github.com/tamlok/vnote/releases) -- master 分支的最新构建:[ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -VNote 不支持 **XP**,因为 QtWebEngineProcess 无法在 XP 上运行。 - -### Scoop -VNote 也可以通过 Scoop 的 `extras` 仓库进行安装。 - -```shell -scoop bucket add extras -scoop install vnote -scoop update vnote -``` - -## Linux -### AppImage -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -VNote 当前为主要 Linux 发行版提供了一个 AppImage 格式的独立可执行文件。希望了解 Linux 系统下打包发布的开发人员能提供这方面进一步的帮助! - -- [Github releases](https://github.com/tamlok/vnote/releases) -- master 分支的最新构建:[ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -### openSUSE -目前 openSUSE Tumbleweed 可以通过 OBS 上的 `home:opensuse_zh` 源直接安装。您可以直接执行以下命令: - -```shell -sudo zypper ar https://download.opensuse.org/repositories/home:/opensuse_zh/openSUSE_Tumbleweed/ home:opensuse_zh -sudo zypper ref -sudo zypper in vnote -``` - -其他架构请直接在 [software.opensuse.org](https://software.opensuse.org) 搜索 `vnote`。 - -由于 Leap 42 及以下版本的 Qt 版本过低,我们无法在 OBS 上进行打包。请使用 AppImage 或自行构建。 - -### Arch Linux -Arch Linux 可以通过 AUR 中的 [vnote-bin](https://aur.archlinux.org/packages/vnote-bin/) 进行安装: - -```shell -git clone https://aur.archlinux.org/vnote-bin.git -cd vnote-bin -makepkg -sic -``` - -AUR 也提供一个和最新 master 分支同步的开发版本 [vnote-git](https://aur.archlinux.org/packages/vnote-git/) 。 - -## MacOS -[![Build Status](https://travis-ci.org/tamlok/vnote.svg?branch=master)](https://travis-ci.org/tamlok/vnote) - -- [Github releases](https://github.com/tamlok/vnote/releases) -- master 分支的最新构建:[ ![Download](https://api.bintray.com/packages/tamlok/vnote/vnote/images/download.svg) ](https://bintray.com/tamlok/vnote/vnote/_latestVersion) - -也可以通过 homebrew cask 进行安装: - -```shell -brew cask install vnote -``` - -### NixOS -感谢 @kuznero 在 NixOS 上打包 VNote。您可以在 `unstable` 和 `unstable-small` 频道中找到 VNote。 - -# 简介 - -**VNote** 是一个基于 Qt 框架的、免费的开源笔记软件。VNote 专注于 Markdown 的编辑与阅读,以提供舒适的编辑体验为设计目标。 - -VNote 不是一个简单的 Markdown 编辑器。通过提供笔记管理功能,VNote 使得编写 Markdown 笔记更简单和舒适! - -得益于 Qt 框架,VNote 能够在主流操作系统上运行,包括 **Linux**, **Windows** 以及 **macOS** 。 - -![VNote Main Interface](screenshots/_vnotemaini_1525154456_1561295841.png) - -# 支持 -- [Github issues](https://github.com/tamlok/vnote/issues); -- 邮箱: `tamlokveer at gmail.com` ; -- [Slack](https://join.slack.com/t/vnote/shared_invite/enQtNDg2MzY0NDg3NzI4LTVhMzBlOTY0YzVhMmQyMTFmZDdhY2M3MDQxYTBjOTA2Y2IxOGRiZjg2NzdhMjkzYmUyY2VkMWJlZTNhMTQyODU); -- [Telegram](https://t.me/vnotex) ; -- 微信公众号: VNote笔记(vnote_md); -![VNote WeChat](screenshots/vnote_md.jpg) - -# 亮点 -- 强大的**全文搜索**; -- **通用入口**,通过按键操控一切; -- 直接从剪切板插入图片; -- 编辑和阅读模式下代码块的语法高亮; -- 强大的**原地预览**,包括图片、图表和公式; -- 针对图表的两边实时预览; -- 编辑和阅读模式下的大纲; -- 自定义编辑和阅读模式的样式; -- **Vim** 模式以及一系列强大的快捷键; -- 无限层级的文件夹; -- 多个标签页和窗口分割; -- [Mermaid](http://knsv.github.io/mermaid/)、 [Flowchart.js](http://flowchart.js.org/)、 [MathJax](https://www.mathjax.org/)、 [PlantUML](http://plantuml.com/) 和 [Graphviz](http://www.graphviz.org/); -- 支持高分辨率; -- 笔记附件; -- 主题以及深色模式; -- 丰富、可扩展的导出,包括 HTML、PDF、PDF(多合一)和图片; -- GitHub和微信图床; - -# 捐赠 -您可以通过很多途径帮助 VNote 的开发。 - -- 持续关注 VNote 并反馈。 -- 向您的朋友们推广和传播 VNote。普及度是驱动开发者的一股强大力量。 -- 参与到 VNote 的开发中,发送 Pull Request 来帮助 VNote 变得更完美。 -- 最后,如果您觉得 VNote 真的帮助到您并且想回馈 VNote,非常感谢您的捐赠。 - -**PayPal**: [PayPal.Me/vnotemd](https://www.paypal.me/vnotemd) - -**支付宝**: `tamlokveer@gmail.com` - - - -**微信** - - - -非常感谢[这些用户](https://github.com/tamlok/vnote/wiki/Donate-List)对 VNote 的捐赠! - -# 开发 VNote 的动机 -## Markdown 编辑器与笔记管理 -VNote 设计为带有笔记管理功能的 Markdown 编辑器,或者有良好 Markdown 支持的笔记软件。如果您喜欢 Markdown 并经常在学习、工作和生活中使用 Markdown 记录笔记,那么 VNote 就是一个适合您的工具。 - -## 舒适的 Markdown 体验 -### Markdown 的本质 -Markdown 作为一个简单标记语言,不像富文本,它的编辑和阅读有着与生俱来的隔阂。一般目前大概有三类方法来处理这个隔阂: - -1. 作为一个极端,一些编辑器只是将 Markdown 作为无格式的纯文本处理。用户很容易在密密麻麻的黑漆漆的一片文字中找不着方向。 -2. 大部分编辑器使用两个面板来同时编辑和预览 Markdown 笔记。从而,用户可以在编辑的同时看到优美的排版和布局。但是,两个面板基本会占据了整个屏幕,而用户的目光焦点左右频繁移动,往往也会使得用户无法专注编辑。 -3. 作为另一个极端,一些编辑器在用户输入文本后立即将 Markdown 的标记转换为 HTML 元素,使得编写 Markdown 如同在 Word 文档里面编写富文本一样。 - -由于几乎所有的编辑器都选择第二种方法来处理隔阂,一提到 Markdown 人们往往会想起预览。这可能是对 Markdown 的一个最大的误解了。设计为一个简单的标记语言,Markdown 的设计初衷就是为了在编辑的时候方便帮助跟踪文本的信息,而又能在阅读的时候被转换为 HTML 为发布提供美观的排版输出。所以,Markdown 本身就应该在编辑的时候能够方便地跟踪和掌控文本的信息和脉络,而不需要通过预览这种接近饮鸩止渴的方法来方便编辑。 - -### 折中:VNote 的方案 -VNote 尝试通过精心调配的**语法高亮**和其他一些特性,来最大程度地减小 Markdown 的这种割裂感,尽可能地提供一个*所见即所得*的编辑体验。用户在编辑的时候就能有效第把握内容脉络,也就没有必要进行预览或者强制更改文本为 HTML 元素了。 - -# 功能 -## 基于笔记本的管理 -VNote 使用 **笔记本** 来管理笔记。类似于 OneNote,一个笔记本可以保存在系统上的任意位置。一个笔记本对应于一个账户的概念。例如,您可以在本地文件系统上有一个笔记本,另外在某台 OwnCloud 服务器上保存另一个笔记本。当不同的笔记有不同的保密要求时,独立的笔记本就非常适用了。 - -一个笔记本对应于文件系统上的一个独立完整的文件夹(称为笔记本的 **根目录** )。您可以将该文件夹拷贝到其他位置(或者另一台计算机上),然后将其导入到 VNote 中。 - -VNote 支持一个笔记本中包含无限层级的文件夹。VNote 支持在笔记本内或笔记本间拷贝或剪切文件夹和笔记。 - -## 直观的笔记管理 -所有笔记被保存为纯文本而且通过纯文本的配置文件进行管理。即使没有 VNote,您也能方便访问您的数据。这样,您也可以使用第三方的文件同步服务来同步您的笔记,并在另一台计算机上导入到 VNote 中。 - -VNote 支持 Markdown 和富文本笔记,其中 Markdown 笔记必须以 `md` 为后缀名。 - -## 语法高亮 -VNote 支持精确的 Markdown 语法高亮。通过精心调试的高亮样式,VNote 使得您能够轻松跟踪和阅读您的文档。 - -VNote 还支持 Markdown 编辑模式中代码块的语法高亮。目前的 Markdown 编辑器中绝大部分都尚不支持该特性。 - -![Syntax Highlight](screenshots/_1513485266_1616037517.png) - -## 原地预览 -VNote 支持在编辑时原地预览图片、图表和公式。 - -![In-Place Preview](screenshots/_inplacepre_1525155248_405615820.png) - -## 良好的图片体验 -编辑时,支持像其他富文本编辑器一样直接粘贴插入图片,VNote 会帮您管理所插入的图片。VNote 将这些图片保存在和笔记同一目录下的一个指定目录中。插入图片时,VNote 会弹出一个窗口预览即将要插入的图片。另外,当您移除笔记中的图片链接时,VNote 会自动删除对应的图片文件。 - -## 通用入口和全文搜索 -VNote 内置强大的全文搜索,支持**正则表达式**和**模糊搜索**。搜索可以指定范围,包括全部笔记本、当前笔记本和当前文件夹,也可以指定目标,如名字或内容。 - -类似于 Vim 中的 `Ctrl+P`,VNote 支持**通用入口**,可以在一个输入框中进行搜索或跳转。 - -![Universal Entry](screenshots/_universale_1522894821_465772669.png) - -## 编辑和阅读模式中的交互式大纲视图 -VNote 为编辑和预览模式都提供了一个用户友好的大纲视图。该大纲视图是一个项目树,而不是简单地插入一段 HTML。 - -## 强大的快捷键 -VNote 提供很多快捷键,从而提供一个愉悦的编辑体验。其中包括 **Vim模式**、**舰长模式** 和 **导航模式**,它们能让您完全摆脱鼠标进行操作。 - -更多细节请参考帮助菜单中的[快捷键帮助](src/resources/docs/shortcuts_zh.md)。 - -## 高度可定制 -在 VNote 中,几乎一切都是可以定制的,例如背景颜色、字体以及 Markdown 样式等。VNote 使用一个纯文本文件来记录您的所有配置,因此通过拷贝该文件就能够很快地在另一台电脑上初始化一个新的 VNote。 - -# 依赖 -- [Qt 5.9](http://qt-project.org) (L-GPL v3) -- [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License) -- [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License) -- [Marked 0.5.1](https://github.com/markedjs/marked) (MIT License) -- [Highlight.js](https://github.com/isagalaev/highlight.js/) (BSD License) -- [Ionicons 2.0.1](https://github.com/driftyco/ionicons/) (MIT License) -- [markdown-it 8.3.1](https://github.com/markdown-it/markdown-it) (MIT License) -- [markdown-it-headinganchor 1.3.0](https://github.com/adam-p/markdown-it-headinganchor) (MIT License) -- [markdown-it-task-lists 1.4.0](https://github.com/revin/markdown-it-task-lists) (ISC License) -- [markdown-it-footnote](https://github.com/markdown-it/markdown-it-footnote) (MIT License) -- [markdown-it-sub](https://github.com/markdown-it/markdown-it-sub) (MIT License) -- [markdown-it-sup](https://github.com/markdown-it/markdown-it-sup) (MIT License) -- [markdown-it-front-matter](https://github.com/craigdmckenna/markdown-it-front-matter) (MIT License) -- [markdown-it-imsize](https://github.com/tatsy/markdown-it-imsize) (Unknown) (Thanks @Kinka for help) -- [markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji) (MIT License) -- [markdown-it-texmath](https://github.com/goessner/markdown-it-texmath) (MIT License) -- [markdown-it-container 2.0.0](https://github.com/markdown-it/markdown-it-container) (MIT License) -- [mermaid 7.0.0](https://github.com/knsv/mermaid) (MIT License) -- [MathJax](https://www.mathjax.org/) (Apache-2.0) -- [showdown](https://github.com/showdownjs/showdown) (Unknown) -- [flowchart.js](https://github.com/adrai/flowchart.js) (MIT License) -- [PlantUML](http://plantuml.com/) (MIT License) -- [dom-to-image](https://github.com/tsayen/dom-to-image) (MIT License) -- [turndown](https://github.com/domchristie/turndown) (MIT License) - -# 代码许可 -VNote 使用 [MIT 许可](http://opensource.org/licenses/MIT)。 diff --git a/VNote.pro b/VNote.pro deleted file mode 100644 index 4adc516d..00000000 --- a/VNote.pro +++ /dev/null @@ -1,15 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-10-01T11:03:59 -# -#------------------------------------------------- - -TEMPLATE = subdirs - -CONFIG += c++11 - -SUBDIRS = hoedown \ - peg-highlight \ - src - -src.depends = hoedown peg-highlight diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index f1ad78f6..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,78 +0,0 @@ -image: Visual Studio 2015 - -version: 2.10.{build} - -branches: - only: - - master - -environment: - COMPILER: msvc - VSVER: 14 - - matrix: - - QT: C:\Qt\5.9\msvc2015_64 - PLATFORM: amd64 - - QT: C:\Qt\5.9\msvc2015 - PLATFORM: x86 - -clone_depth: 1 - -# scripts that run after cloning repository -install: - - set PATH=%QT%\bin\;C:\Qt\Tools\QtCreator\bin\;C:\Qt\QtIFW2.0.1\bin\;%PATH% - - git submodule update --init --recursive - -# scripts that run before build -before_build: - - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %PLATFORM% - # After calling vcvarsall.bat, %PLATFORM% will be X64 or x86 - - qmake --version - - mkdir build - - cd build - - if "%PLATFORM%" EQU "X64" (qmake -r -spec win32-msvc CONFIG+=x86_64 CONFIG-=debug CONFIG+=release ../VNote.pro) - - if "%PLATFORM%" EQU "x86" (qmake -r -spec win32-msvc CONFIG+=Win32 CONFIG-=debug CONFIG+=release ../VNote.pro) - -# custom build scripts -build_script: - - nmake - -# scripts that run after build -after_build: - - set vnote_version=2.10 - # Clone OpenSSL DLLs - - git clone https://github.com/tamlok/openssl-utils.git openssl-utils.git - - mkdir distrib\VNote - - windeployqt.exe --dir .\distrib\VNote %APPVEYOR_BUILD_FOLDER%\build\src\release\VNote.exe - - copy "%APPVEYOR_BUILD_FOLDER%\build\src\release\VNote.exe" "distrib\VNote\VNote.exe" - - copy "%APPVEYOR_BUILD_FOLDER%\README.md" "distrib\VNote\README.md" - - copy "%APPVEYOR_BUILD_FOLDER%\LICENSE" "distrib\VNote\LICENSE.txt" - - echo %vnote_version% > "distrib\VNote\version.txt" - - echo %APPVEYOR_REPO_COMMIT% >> "distrib\VNote\version.txt" - - copy "distrib\VNote\VNote.exe" "distrib\VNote_win_%PLATFORM%.exe" - # Delete translations\qt_*.qm - - del /F /Q "distrib\VNote\translations\qt_*.qm" - # Copy OpenSSL DLLs - - if "%PLATFORM%" EQU "X64" (xcopy "openssl-utils.git\win64\*.dll" "distrib\VNote") - - if "%PLATFORM%" EQU "x86" (xcopy "openssl-utils.git\win32\*.dll" "distrib\VNote") - - cd distrib - - 7z a VNote_win_%PLATFORM%_portable_%vnote_version%.zip VNote - -artifacts: - - path: build\distrib\VNote_win_%PLATFORM%_portable_%vnote_version%.zip - name: portable - - path: build\distrib\VNote_win_%PLATFORM%.exe - name: exe_only - -deploy: - - provider: BinTray - username: tamlok - api_key: - secure: YJqzsVDlC2NYH2RgzbUMtjZWbSXOdWUiiENOIqImo31hOfeiB0MiVGmBLmKPAHEg - subject: tamlok - repo: vnote - package: vnote - version: 2.10 - publish: true - override: true - artifact: portable diff --git a/changes.md b/changes.md deleted file mode 100644 index 377c7c5d..00000000 --- a/changes.md +++ /dev/null @@ -1,404 +0,0 @@ -# Changes History -## v2.10 -- Add support for Git push/pull; (@musmus9405) -- Bug fixes; (@tootal, @hlyang1992) - -## v2.9.1 -- Fix start issue on macOS (no need to add `-m` option); - -## v2.9 -- Upgrade to MathJax v3; -- Support `e` command in Vim mode; (@gydeng) -- Fix start issue on macOS (no need to add `-m` option); - -## v2.8.2 -- Upgrade Mermaid.js; - -## v2.8.1 -- Fix PlantUML online resources; -- MacOS: support staying in tray; -- Add a configuration in Settings to control code block copy button; - -## v2.8 -- Add supports for image hosting, including service GitHub, Gitee, Wechat, and Tencent Cloud; (@fengwenhua) -- Support sorting notebooks in context menu; -- Add theme v_next; (@hzhu212); - -## v2.7.2 -- Use 5.9.8 on macOS; -- Call Java (PlantUML) directly on Win; - -## v2.7.1 -- Fix PlantUML command; -- Use 5.12.0 on macOS; -- Add config [web]/enable_code_block_copy_button for copy button in code block in read mode; - -## v2.7 -- Editor - - Fix smart table bugs; - - Fix improper leading line space on macOS; -- Fix bug which will open two tabs for the same file; -- Add copy button to copy code block in read mode; -- PluatUML: use shell to launch Java; -- Use qt 5.12.1 on macOS for better performance; -- Add theme `v_simple` provided by user LuoshuiTianyi; -- Support adding sibling folder in context menu; - -## v2.6 -- Version-specific user track; - -## v2.5 -- Do not open unknown type file when creating a new note; -- Support Right-To-Left text in edit mode (with Vim mode disabled); -- Remove credict information in export template; - -## v2.4 -- Bundle qt5ct in Linux for native look support; -- Use `Return` or `Enter` to confirm selection in macOS (besides `Cmd+O`); -- Support sync note list to current note automatically via config `global/sync_note_list_to_current_tab`; -- Add `Ctrl+E N` to view and edit current note's information; -- Fix Markdown highlighter to handle fenced code block without a leading empty line; -- Prompt for restart after changing theme; - -## v2.3 -- Add Japanese translations (thanks to @miurahr); -- Editor - - Bug fix of smart table; - - Allow to disable smart table; -- Update to Qt 5.9.7 in CI in Linux; -- Add user track logics for users counting; -- Add CMake build system; - - Support multiple packaging genration; - - QtIFW GUI installer - - Debian package - - RPM package - - AppImage - - Tar.gz package - - ZIP package - - Windows Nullsoft installer - - Windows NuGet package - - Mac OS X dmg package - - Support staic code checkers; - - clang-tidy - - crazy - - include-what-you-see - - Support modern IDEs; - - Microsoft Visual Studio 2017 - - JetBrains CLion - - QtCreator - - XCode - - VSCode - -## v2.2 -- Editor - - Support smart GFM table; - - support auto scrolling cursor into center; - - Support specifying font via settings to override style config; - - Guess image title from the file name; - - Support ~~~ as fenced code block marker; -- MathJax - - Support equation number; - - Support \begin and \end directly; - - Support $..$ in \text{} within $$...$$; -- NotebookPanel: support spliting file list out; -- Add openGL option in settings on Windows; -- Markdown-it - - Support alert text via markdown-it-container plugin; -- Support WaveDrom for digital timing diagram; - -## v2.1 -- UniversalEntry/Searcher: `Ctrl+B` to expand/collapse all items; -- Captain mode: support specifying keyboard layout mappings, such as Russian or French; -- Editor - - Support downloading images to local when Parse&Paste; - - Support scaling image when inserting image; - - Support Parse&Paste as table from Microsoft Excel; - - Support attach a file as attachment and insert as link by Drag&Drop; - - Support `Ctrl+Sfhit+V` to paste as plain text; - - Fix Unicode issue; -- Attachment - - Support copying file path; -- Support Drag&Drop to copy/move notes; -- Support MathJax euqation number in read mode; -- Fix blurry toolbar icon on macOS; -- Fix blurry renderring in read mode on Windows; - -## v2.0 -- Vim: support specifying leader key via "[editor]/vim_leader_key"; -- LivePreview - - Smart live preview for PlantUML (Live Preview Tunnel); - - Expand live preview area via `Ctrl+E U`; -- In-Place Preview: support in-place preview for online PlantUML; -- Captain: fix captain mode shortcuts in different keyboard layout (Windows only); -- Quick Access: specify a note for quick access via `Ctrl+Alt+I`; -- Magic Word: support `%att%` as the relative path of the attachment folder; -- Search: highlight matches of full-text search results in page in edit mode; -- Editor - - Allow inserting link or content when dropping files in; - - Support highlighting tabs; -- Support parsing HTML tables without head; -- Export: support outline panel in exported HTML files; - -## v1.22 -- Editor - - Support parsting HTML as converted Markdown text; - - Improve performance of in-place preview; - - Be aware of links, images, and in-place preview in edit mode (visit or copy); - - Support exporting and copying PlantUML and Graphviz diagram in edit mode; -- Support middle click to close a tab; -- Support searching files via multiple tags, such as "vnote && markdown"; - -## v1.21 -- Improve performance of editor (now could process 10K lines); -- Support `vnote` highlight in edit mode; -- Support **completion** in edit mode by `Ctrl+N/P`; -- Support building a notebook from external directory recursively; -- Update Flowchart.js to 1.11.3; - -## v1.20 -- More efficient and accurate Markdown parser and highlighter; -- MathJax: get rid of escaping; -- Draw background for **hrule** in edit mode; -- Support specifying the expanded level of outline; -- Support drag&drop a directory to Explorer to open it; -- `Ctrl+;` to insert inline code and `Ctrl+J/K` to scroll page in edit mode; -- Support YAML front matter in edit mode; -- Support searching Explorer root directory; - -## v1.19 -- Support tags for notes; -- UniversalEntry: support searching tags; -- WebView: click an image or diagram to view it in read mode; -- Add test buttons for PlantUML and Graphviz in settings dialog; -- CaptainMode: Y to focus to the edit area; - -## v1.18 -- Explorer: fix the crash when no root entry is set; -- New dark theme **v_detorte** from a Vim *detorte* theme; -- Support maximizing split or distributing splits; -- Refine styles and HiDPI support; - -## v1.17 -- Add **History** to browse history; -- Add **Explorer** to browse external files; -- Support view order in note list; -- Support relative path for notebook; -- UniversalEntry - - Fix input method issue on macOS; - - Add `j` for listing and searching History; -- Support customized zoom delta of editor; -- Add cache for in-place preview; -- Better support for hiDPI; -- Lazy initialization; -- Support stay-on-top; - -## v1.16 -- Markdown-it: supports specifying image size, emoji, and YAML metadata; -- Bug fixes; - -## v1.15 -- Support **PlantUML** and **Graphviz**; -- **In-Place Preview** for MathJax, PlantUML, Graphviz, and Flowchart.js; -- **Live Preview** for diagrams via `Ctrl+E I`; -- Restore cursor position when recovering pages at startup; -- UniversalEntry - - Ctrl+I to expand/collapse current item; - - Ctrl+L to go to current item's parent item; -- Markdown-it: aware of YAML format metadata in notes; -- Show hovered link in status line in read mode; -- Export: support embedding images as data URI into HTML pages; - -## v1.14 -- Support **Universal Entry** by `Ctrl+G`; -- Single click a note in note list to open it in a new tab by default; -- Translate `Ctrl` in default shortcuts to `Meta` on macOS; -- Do not copy files when import if they locate in current folder; - -## v1.13 -- Replace **v_white** theme with **v_native**, which behaves more like native applications; -- Support **full-text search**; - - Support `&&` and `||` logics (space-separated keywords are treated as AND); -- Enhanced export; - - Support MHTML format; - - Support All-In-One PDF via tool *wkhtmltopdf*; - - Support *pandoc* and random tool for custom export; -- Support **Word Count** information in both read and edit mode; -- Support SavePage action in read mode; -- Support *back reference* in replace text via `\1`, `\2`, and so on; -- Support sorting in Cart; -- Support sorting notes and folders via name or modification date; -- Support both `flow` and `flowchart` as the language of *flowchart.js* diagram; -- Add PasteAsBlockQuote menu action to paste text as block quote from clipboard; -- Add options for Markdown-it to support subscript and superscript; -- Better support for 4K display; - -## v1.12 -- Combine `EditNote` and `SaveExitNote` as `EditReadNote` (`Ctrl+T`); -- Support exporting notes as Markdown, HTML, and PDF; -- Support simple search in directory tree, file list, and outline; -- Support copying selected text as HTML in edit mode; -- Support copying text to Evernote, OneNote, Word, WeChat Public Account editor and so on; -- Support auto-save; -- Support fullscreen mode and hiding menu bar; -- Support `Ctrl+H/W/U` to delete text in most line edits; -- Support zooming in/out in edit mode; -- Support MathJax in fenced code block with language `mathjax` specified; -- More shortcuts; -- Add **Cart** to collect notes for further processing; -- Output built-in themes on start of VNote; -- `Esc` to exit edit mode when Vim mode is disabled; -- Support Vim command line for search in read mode; -- Support printing; -- Single click in file list to open file in current tab, double clicks to open in a new tab; - -## v1.11.1 -- Refine copy function in read mode. Better support for copying and pasting into OneNote or WeChat editor; -- Do not highlight code blocks without language specified by default; -- Refine themes and styles; -- Support foreground for selected/searched word in MDHL style; -- Support shortcuts for external programs; -- Support resetting VNote; -- Cover more scenarios for Chinese translations; - -## v1.11 -- Support themes; - - Three built-in mordern themes; - - One dark mode theme; -- Vim mode - - Support block cursor in Normal/Visual mode; - - `=` to auto-indent selected lines as the first line; -- Support custom external editors to open notes; -- Enable `Ctrl+C`/`Ctrl+V` in Vim mode to copy/paste; -- Support Flash Page to record ideas quickly; -- Support previewing inline images; - -## v1.10 -- Migrate to Qt 5.9.1; -- Support Compact mode in main window; -- Update icons; -- Support custom startup pages; -- Remove obsolete title marker when inserting new one; -- Support Magic Words; -- Vim mode - - Share registers among all tabs; - - Support `Ctrl+O` in Insert mode; -- Add "Code Block", "Insert Link", and "Insert Image" tool bar buttons; -- Support `Ctrl+Shift+T` to recover last closed tabs; -- Support view read-only files in edit mode; -- Refactor editor for speed; -- Support templates when creating notes; -- Support snippets; -- Support file change check; -- Support backup file (save changes automatically); - -## v1.9 -- Support attachments of notes. -- Add recycle bin to notebook to hold deleted files. -- Refine Vim mode: - - Support J and gJ to join line; - - Support S, {, and }; - - w to save note; - - Fix Y and D actions in Visual mode. -- Support AppImage package for Linux. -- More responsive and efficient syntax highlight and image preview. -- More pleasant line distance. -- More natural interaction of folder and note management. -- Support inserting note name as title. -- Support custom default mode to open a note. -- Support auto heading sequence. -- Support color column in fenced code block in edit mode. -- Support line number in code block in both read and edit mode. -- Support created time and modified time of notes, folders, and notebooks. -- Support custom Markdown-it options, such as auto line break. -- Confirm when cleaning up unused images. -- Support custom Mathjax location. -- Support custom style for code block highlights in read mode. -- Double click on a tab to close it. - -## v1.8 -- Support editing external files. VNote could open files from command line. -- Support drag-and-drop to open external files. -- Refine tab context menu. -- Support system tray icon. -- Refine Vim mode. -- Make all tool buttons always visible and smaller. -- Support custom file type suffix. -- Make the name of notebook/folder/note case-insensitive. -- Support links to internal notes in notes. - -## v1.7 -- ATTENTION: please add font-size option to the "editor" section of your custom MDHL style. -- Refine Vim mode (more functions, please refer to the shortcuts help). -- Support Find in Vim mode. -- Refine tab context menu. -- Support Flowchart.js for flowchart. -- Add toolbar for common text edit functions. -- Support line number (both absolute and relative) in edit mode. -- Support custom shortcuts. -- Support [[, ]], [], ][, [{, ]} to navigate through titles in both edit and read mode. -- Many minor bug fixes. - -## v1.6 -- Support simple but powerful **Vim mode**. -- Change the shortcut of ExitAndRead from `Ctrl+R` to `Ctrl+T`. -- Add a edit status indicator in the status bar. -- Dragging mouse with Ctrl and left button pressed to scroll in read and edit mode. -- Refine highlighting cursor line. -- Support subscript, superscript and footnote in markdown-it renderer. -- Refactor outline logics to not show extra [EMPTY] headers. -- Handle HTML comments correctly. -- Provide a default root folder when adding notebooks. -- Support check for updates. -- Redraw app icons. -- Many minor bug fixes. - -## v1.5 -- Support logging in release mode. -- Fix Chinese font matching in mdhl. -- Fix VimagePreviewer to support optional title. -- Refactor local image folder logics. -- Support custom local image folder for both notebook scope and global scope. -- Support constraining the width of images in read mode. -- Fix and refine default style. -- Centering the images and display the alt text as caption in read mode. -- Support exporting a single note as PDF file. -- Add "Open File Location" menu item in folder tree and note list. -- Support highlighting trailing space. - -## v1.4 -- Use `_vnote.json` as the config file. -- More user friendly messages. -- Delete notebook by deleting root directories one by one. -- Refactor image preview logics to support previewing all images in edit mode. -- Support constraining the width of previewed images to the edit window. -- bugfix. - -## v1.3 -- Support code block syntax highlight in edit mode. -- A more pleasant AutoIndent and AutoList. -- `Ctrl+` instead of `Ctrl+Alt+` to insert title. -- Support custom Markdown CSS styles and editor styles. - -## v1.2 -- Support **MathJax**. -- Fix a crash on macOS. -- Change default font family. -- Refine tab order. -- Better support for HiDPI. -- Support zoom in/out page when reading. -- Introduce **Captain Mode** and **Navigation Mode**. -- A more user friendly popup opened notes list. -- Support jumping to specified tab efficiently by num keys. -- Add shortcuts documentation. -- AutoList and AutoIndent. - -## v1.1 -- Refine messages and dialogs. Add Chinese translations. -- A new application icon. -- Support install target for Linux. -- Continuous build and deployment for Linux, macOS, and Windows. -- Support both X64 and x86 version of Windows. -- Add `.md` suffix automatically when creating a note. -- A more user friendly insert dialog. -- Support **Mermaid** diagram. -- Add **markdown-it** as the default renderer. Support task list. diff --git a/coc_update.cmd b/coc_update.cmd deleted file mode 100644 index db00ffad..00000000 --- a/coc_update.cmd +++ /dev/null @@ -1,35 +0,0 @@ -@echo off -rem Update .ccls project file for ccls LPS and compile_flags.txt for clangd - -if "%~1"=="" ( - echo missing argument: the location of Qt's include directory - EXIT /B 0 -) - -set qt_inc=%~1 -set qt_inc=%qt_inc:\=\\% - -( - echo clang - echo -fcxx-exceptions - echo -std=c++11 - echo -Isrc - echo -Isrc\\dialog - echo -Isrc\\utils - echo -Isrc\\widgets - echo -Ihoedown - echo -Ipeg-highlight - echo -I%qt_inc% - echo -I%qt_inc%\\QtCore - echo -I%qt_inc%\\QtWebEngineWidgets - echo -I%qt_inc%\\QtSvg - echo -I%qt_inc%\\QtPrintSupport - echo -I%qt_inc%\\QtWidgets - echo -I%qt_inc%\\QtWebEngineCore - echo -I%qt_inc%\\QtGui - echo -I%qt_inc%\\QtWebChannel - echo -I%qt_inc%\\QtNetwork - echo -I%qt_inc%\\QtTest -) > ".ccls" - -copy /Y .ccls compile_flags.txt diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index acfdfb07..00000000 --- a/debian/changelog +++ /dev/null @@ -1,6 +0,0 @@ -vnote (1.8-0ubuntu1) zesty; urgency=medium - - * Initial release - * Adjusted the Makefile to fix $(DESTDIR) problems. - - -- Le Tan Sun, 20 Aug 2017 09:32:22 +0800 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index ec635144..00000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/debian/control b/debian/control deleted file mode 100644 index 33e9e6c1..00000000 --- a/debian/control +++ /dev/null @@ -1,17 +0,0 @@ -Source: vnote -Section: editors -Priority: optional -Maintainer: Le Tan -Build-Depends: debhelper (>=9), qt5-default (>= 5.7.1), libqt5svg5-dev, qtwebengine5-dev, libqt5webchannel5-dev, qtpositioning5-dev -Standards-Version: 3.9.6 -Homepage: https://tamlok.github.io/vnote -Vcs-Browser: https://github.com/tamlok/vnote.git - -Package: vnote -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, libQt5WebEngineWidgets (>= 5.7.1), libQt5WebEngineCore, libQt5PrintSupport, libQt5Widgets, libQt5Gui, libQt5WebChannel, libQt5Network, libQt5Core -Suggests: libssl -Description: A Vim-inspired note-taking application for Markdown. - VNote is a cross-platform, free note-taking application, designed especially - for Markdown. VNote provides both simple note management and pleasant Markdown - edit experience. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 73f90572..00000000 --- a/debian/copyright +++ /dev/null @@ -1,7 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: vnote -Source: https://tamlok.github.io/vnote - -Files: * -Copyright: 2017 Le Tan -License: MIT License diff --git a/debian/rules b/debian/rules deleted file mode 100755 index fcd3d026..00000000 --- a/debian/rules +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/make -f -# See debhelper(7) (uncomment to enable) -# output every command that modifies files on the build system. -#export DH_VERBOSE = 1 - - -# see FEATURE AREAS in dpkg-buildflags(1) -#export DEB_BUILD_MAINT_OPTIONS = hardening=+all - -# see ENVIRONMENT in dpkg-buildflags(1) -# package maintainers to append CFLAGS -#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic -# package maintainers to append LDFLAGS -#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed - - -%: - dh $@ - - -# dh_make generated override targets -# This is example for Cmake (See https://bugs.debian.org/641051 ) -#override_dh_auto_configure: -# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) -override_dh_shlibdeps: - dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info - -export QT_SELECT=qt5 diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 163aaf8d..00000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/hoedown b/hoedown deleted file mode 160000 index e63d2160..00000000 --- a/hoedown +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e63d2160a7d9895defc253d933b58a83ac54f81a diff --git a/peg-highlight/peg-highlight.pro b/peg-highlight/peg-highlight.pro deleted file mode 100644 index a7672ba4..00000000 --- a/peg-highlight/peg-highlight.pro +++ /dev/null @@ -1,18 +0,0 @@ -# PEG-Markdown-Highlight -# Github: https://github.com/ali-rantakari/peg-markdown-highlight - -QT -= core gui - -TARGET = peg-highlight - -TEMPLATE = lib - -CONFIG += warn_off -CONFIG += staticlib - -SOURCES += pmh_parser.c \ - pmh_styleparser.c - -HEADERS += pmh_parser.h \ - pmh_styleparser.h \ - pmh_definitions.h diff --git a/peg-highlight/pmh_definitions.h b/peg-highlight/pmh_definitions.h deleted file mode 100755 index 4647103f..00000000 --- a/peg-highlight/pmh_definitions.h +++ /dev/null @@ -1,138 +0,0 @@ -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_definitions.h - */ - -#ifndef pmh_MARKDOWN_DEFINITIONS -#define pmh_MARKDOWN_DEFINITIONS - -/** \file -* \brief Global definitions for the parser. -*/ - - -/** -* \brief Element types. -* -* The first (documented) ones are language element types. -* -* The last (non-documented) ones are utility types used -* by the parser itself. -* -* \sa pmh_element -*/ -typedef enum -{ - pmh_LINK, /**< Explicit link */ - pmh_AUTO_LINK_URL, /**< Implicit URL link */ - pmh_AUTO_LINK_EMAIL, /**< Implicit email link */ - pmh_IMAGE, /**< Image definition */ - pmh_CODE, /**< Code (inline) */ - pmh_HTML, /**< HTML */ - pmh_HTML_ENTITY, /**< HTML special entity definition */ - pmh_EMPH, /**< Emphasized text */ - pmh_STRONG, /**< Strong text */ - pmh_LIST_BULLET, /**< Bullet for an unordered list item */ - pmh_LIST_ENUMERATOR, /**< Enumerator for an ordered list item */ - pmh_COMMENT, /**< (HTML) Comment */ - - // Code assumes that pmh_H1-6 are in order. - pmh_H1, /**< Header, level 1 */ - pmh_H2, /**< Header, level 2 */ - pmh_H3, /**< Header, level 3 */ - pmh_H4, /**< Header, level 4 */ - pmh_H5, /**< Header, level 5 */ - pmh_H6, /**< Header, level 6 */ - - pmh_BLOCKQUOTE, /**< Blockquote */ - pmh_VERBATIM, /**< Verbatim (e.g. block of code) */ - pmh_HTMLBLOCK, /**< Block of HTML */ - pmh_HRULE, /**< Horizontal rule */ - pmh_REFERENCE, /**< Reference */ - pmh_FENCEDCODEBLOCK, /**< Fenced code block */ - pmh_NOTE, /**< Note */ - pmh_STRIKE, /**< Strike-through */ - pmh_FRONTMATTER, /**< Front matter */ - pmh_DISPLAYFORMULA, /**< Math display formula */ - pmh_INLINEEQUATION, /**< Math inline equation */ - pmh_MARK, /**< HTML tag content */ - pmh_TABLE, /**< GFM table */ - pmh_TABLEHEADER, /**< GFM table header */ - pmh_TABLEBORDER, /**< GFM table border | */ - - // Utility types used by the parser itself: - - // List of pmh_RAW element lists, each to be processed separately from - // others (for each element in linked lists of this type, `children` points - // to a linked list of pmh_RAW elements): - pmh_RAW_LIST, /**< Internal to parser. Please ignore. */ - - // Span marker for positions in original input to be post-processed - // in a second parsing step: - pmh_RAW, /**< Internal to parser. Please ignore. */ - - // Additional text to be parsed along with spans in the original input - // (these may be added to linked lists of pmh_RAW elements): - pmh_EXTRA_TEXT, /**< Internal to parser. Please ignore. */ - - // Separates linked lists of pmh_RAW elements into parts to be processed - // separate from each other: - pmh_SEPARATOR, /**< Internal to parser. Please ignore. */ - - // Placeholder element used while parsing: - pmh_NO_TYPE, /**< Internal to parser. Please ignore. */ - - // Linked list of *all* elements created while parsing: - pmh_ALL /**< Internal to parser. Please ignore. */ -} pmh_element_type; - -/** -* \brief Number of types in pmh_element_type. -* \sa pmh_element_type -*/ -#define pmh_NUM_TYPES 39 - -/** -* \brief Number of *language element* types in pmh_element_type. -* \sa pmh_element_type -*/ -#define pmh_NUM_LANG_TYPES (pmh_NUM_TYPES - 6) - - -/** -* \brief A Language element occurrence. -*/ -struct pmh_Element -{ - pmh_element_type type; /**< \brief Type of element */ - unsigned long pos; /**< \brief Unicode code point offset marking the - beginning of this element in the - input. */ - unsigned long end; /**< \brief Unicode code point offset marking the - end of this element in the input. */ - struct pmh_Element *next; /**< \brief Next element in list */ - char *label; /**< \brief Label (for links and references) */ - char *address; /**< \brief Address (for links and references) */ -}; -typedef struct pmh_Element pmh_element; - -/** -* \brief Bitfield enumeration of supported Markdown extensions. -*/ -enum pmh_extensions -{ - pmh_EXT_NONE = 0, /**< No extensions */ - pmh_EXT_NOTES = (1 << 0), /**< Footnote syntax: - http://pandoc.org/README.html#footnotes */ - pmh_EXT_STRIKE = (1 << 1), /**< Strike-through syntax: - http://pandoc.org/README.html#strikeout */ - pmh_EXT_FRONTMATTER = (1 << 2), /**< YAML meta data */ - pmh_EXT_MATH = (1 << 3), /**< Math */ - pmh_EXT_MARK = (1 << 4), /**< HTML tag content */ - pmh_EXT_MATH_RAW = (1 << 5), /**< Math in format \begin and \end */ - pmh_EXT_TABLE = (1 << 6), /** GFM Table */ -}; - -#endif diff --git a/peg-highlight/pmh_parser.c b/peg-highlight/pmh_parser.c deleted file mode 100644 index 50050002..00000000 --- a/peg-highlight/pmh_parser.c +++ /dev/null @@ -1,7498 +0,0 @@ -/* A recursive-descent parser generated by greg 0.4.3 */ - -#include -#include -#include -struct _GREG; -#define YYRULECOUNT 268 - -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_grammar.leg - * - * This is a slightly adapted version of the PEG grammar from John MacFarlane's - * peg-markdown compiler. - */ - -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_parser_head.c - * - * Code to be inserted into the beginning of the parser code generated - * from the PEG grammar. - */ - -#include "pmh_parser.h" - -#ifndef pmh_DEBUG_OUTPUT -#define pmh_DEBUG_OUTPUT 0 -#endif - -#if pmh_DEBUG_OUTPUT -#define pmh_IF(x) if (x) -#define pmh_PRINTF(x, ...) fprintf(stderr, x, ##__VA_ARGS__) -#define pmh_PUTCHAR(x) putchar(x) -#else -#define pmh_IF(x) -#define pmh_PRINTF(x, ...) -#define pmh_PUTCHAR(x) -#endif - - - -// Alias strdup to _strdup on MSVC: -#ifdef _MSC_VER -#define strdup _strdup -#endif - - -char *strdup_or_null(char *s) -{ - return (s == NULL) ? NULL : strdup(s); -} - - -// Internal language element occurrence structure, containing -// both public and private members: -struct pmh_RealElement -{ - // "Public" members: - // (these must match what's defined in pmh_definitions.h) - // ----------------------------------------------- - pmh_element_type type; - unsigned long pos; - unsigned long end; - struct pmh_RealElement *next; - char *label; - char *address; - - // "Private" members for use by the parser itself: - // ----------------------------------------------- - - // next element in list of all elements: - struct pmh_RealElement *all_elems_next; - - // offset to text (for elements of type pmh_EXTRA_TEXT, used when the - // parser reads the value of 'text'): - int text_offset; - - // text content (for elements of type pmh_EXTRA_TEXT): - char *text; - - // children of element (for elements of type pmh_RAW_LIST) - struct pmh_RealElement *children; -}; -typedef struct pmh_RealElement pmh_realelement; - - - - -// Parser state data: -typedef struct -{ - /* The original, unmodified UTF-8 input: */ - char *original_input; - - /* The offsets of the bytes we have stripped from original_input: */ - unsigned long *strip_positions; - size_t strip_positions_len; - - /* Buffer of characters to be parsed: */ - char *charbuf; - - /* Linked list of {start, end} offset pairs determining which parts */ - /* of charbuf to actually parse: */ - pmh_realelement *current_elem; - pmh_realelement *elem_head; - - /* Current parsing offset within charbuf: */ - unsigned long offset; - - /* The extensions to use for parsing (bitfield */ - /* of enum pmh_extensions): */ - int extensions; - - /* Array of parsing result elements, indexed by type: */ - pmh_realelement **head_elems; - - /* Whether we are parsing only references: */ - bool parsing_only_references; - - /* List of reference elements: */ - pmh_realelement *references; -} parser_data; - -static parser_data *mk_parser_data(char *original_input, - unsigned long *strip_positions, - size_t strip_positions_len, - char *charbuf, - pmh_realelement *parsing_elems, - unsigned long offset, - int extensions, - pmh_realelement **head_elems, - pmh_realelement *references) -{ - parser_data *p_data = (parser_data *)malloc(sizeof(parser_data)); - p_data->extensions = extensions; - p_data->original_input = original_input; - p_data->strip_positions = strip_positions; - p_data->strip_positions_len = strip_positions_len; - p_data->charbuf = charbuf; - p_data->offset = offset; - p_data->elem_head = p_data->current_elem = parsing_elems; - p_data->references = references; - p_data->parsing_only_references = false; - if (head_elems != NULL) - p_data->head_elems = head_elems; - else { - p_data->head_elems = (pmh_realelement **) - malloc(sizeof(pmh_realelement *) * pmh_NUM_TYPES); - int i; - for (i = 0; i < pmh_NUM_TYPES; i++) - p_data->head_elems[i] = NULL; - } - return p_data; -} - - -// Forward declarations -static void parse_markdown(parser_data *p_data); -static void parse_references(parser_data *p_data); - - - - - -static char **get_element_type_names() -{ - static char **elem_type_names = NULL; - if (elem_type_names == NULL) - { - elem_type_names = (char **)malloc(sizeof(char*) * pmh_NUM_LANG_TYPES); - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - elem_type_names[i] = NULL; - elem_type_names[pmh_LINK] = "LINK"; - elem_type_names[pmh_AUTO_LINK_URL] = "AUTO_LINK_URL"; - elem_type_names[pmh_AUTO_LINK_EMAIL] = "AUTO_LINK_EMAIL"; - elem_type_names[pmh_IMAGE] = "IMAGE"; - elem_type_names[pmh_CODE] = "CODE"; - elem_type_names[pmh_HTML] = "HTML"; - elem_type_names[pmh_HTML_ENTITY] = "HTML_ENTITY"; - elem_type_names[pmh_EMPH] = "EMPH"; - elem_type_names[pmh_STRONG] = "STRONG"; - elem_type_names[pmh_LIST_BULLET] = "LIST_BULLET"; - elem_type_names[pmh_LIST_ENUMERATOR] = "LIST_ENUMERATOR"; - elem_type_names[pmh_COMMENT] = "COMMENT"; - elem_type_names[pmh_H1] = "H1"; - elem_type_names[pmh_H2] = "H2"; - elem_type_names[pmh_H3] = "H3"; - elem_type_names[pmh_H4] = "H4"; - elem_type_names[pmh_H5] = "H5"; - elem_type_names[pmh_H6] = "H6"; - elem_type_names[pmh_BLOCKQUOTE] = "BLOCKQUOTE"; - elem_type_names[pmh_VERBATIM] = "VERBATIM"; - elem_type_names[pmh_HTMLBLOCK] = "HTMLBLOCK"; - elem_type_names[pmh_HRULE] = "HRULE"; - elem_type_names[pmh_REFERENCE] = "REFERENCE"; - elem_type_names[pmh_FENCEDCODEBLOCK] = "FENCEDCODEBLOCK"; - elem_type_names[pmh_NOTE] = "NOTE"; - elem_type_names[pmh_STRIKE] = "STRIKE"; - elem_type_names[pmh_FRONTMATTER] = "FRONTMATTER"; - elem_type_names[pmh_DISPLAYFORMULA] = "DISPLAYFORMULA"; - elem_type_names[pmh_INLINEEQUATION] = "INLINEEQUATION"; - elem_type_names[pmh_MARK] = "MARK"; - elem_type_names[pmh_TABLE] = "TABLE"; - elem_type_names[pmh_TABLEHEADER] = "TABLEHEADER"; - elem_type_names[pmh_TABLEBORDER] = "TABLEBORDER"; - } - return elem_type_names; -} - -pmh_element_type pmh_element_type_from_name(char *name) -{ - char **elem_type_names = get_element_type_names(); - - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - { - char *i_name = elem_type_names[i]; - if (i_name == NULL) - continue; - if (strcmp(i_name, name) == 0) - return i; - } - - return pmh_NO_TYPE; -} - -char *pmh_element_name_from_type(pmh_element_type type) -{ - char **elem_type_names = get_element_type_names(); - char* ret = elem_type_names[type]; - if (ret == NULL) - return "unknown type"; - return ret; -} - - - - -/* -Remove pmh_RAW elements with zero length; return pointer -to new head. -*/ -static pmh_realelement *remove_zero_length_raw_spans(pmh_realelement *elem) -{ - pmh_realelement *head = elem; - pmh_realelement *parent = NULL; - pmh_realelement *c = head; - while (c != NULL) - { - if (c->type == pmh_RAW && c->pos >= c->end) - { - if (parent != NULL) - parent->next = c->next; - else - head = c->next; - parent = c; - c = c->next; - continue; - } - parent = c; - c = c->next; - } - return head; -} - -#if pmh_DEBUG_OUTPUT -/* -Print null-terminated string s.t. some characters are -represented by their corresponding espace sequences -*/ -static void print_str_literal_escapes(char *str) -{ - char *c = str; - pmh_PRINTF("'"); - while (*c != '\0') - { - if (*c == '\n') pmh_PRINTF("\\n"); - else if (*c == '\t') pmh_PRINTF("\\t"); - else putchar(*c); - c++; - } - pmh_PRINTF("'"); -} -#endif - -#if pmh_DEBUG_OUTPUT -/* -Print elements in a linked list of -pmh_RAW, pmh_SEPARATOR, pmh_EXTRA_TEXT elements -*/ -static void print_raw_spans_inline(pmh_realelement *elem) -{ - pmh_realelement *cur = elem; - while (cur != NULL) - { - if (cur->type == pmh_SEPARATOR) - pmh_PRINTF(" ", cur->pos); - else if (cur->type == pmh_EXTRA_TEXT) { - pmh_PRINTF("{pmh_ETEXT "); - print_str_literal_escapes(cur->text); - pmh_PRINTF("}"); - } - else - pmh_PRINTF("(%ld-%ld) ", cur->pos, cur->end); - cur = cur->next; - } -} -#endif - -/* -Perform postprocessing parsing runs for pmh_RAW_LIST elements in `elem`, -iteratively until no such elements exist. -*/ -static void process_raw_blocks(parser_data *p_data) -{ - pmh_PRINTF("--------process_raw_blocks---------\n"); - while (p_data->head_elems[pmh_RAW_LIST] != NULL) - { - pmh_PRINTF("new iteration.\n"); - pmh_realelement *cursor = p_data->head_elems[pmh_RAW_LIST]; - p_data->head_elems[pmh_RAW_LIST] = NULL; - while (cursor != NULL) - { - pmh_realelement *span_list = (pmh_realelement*)cursor->children; - - span_list = remove_zero_length_raw_spans(span_list); - - #if pmh_DEBUG_OUTPUT - pmh_PRINTF(" process: "); - print_raw_spans_inline(span_list); - pmh_PRINTF("\n"); - #endif - - while (span_list != NULL) - { - pmh_PRINTF("next: span_list: %ld-%ld\n", - span_list->pos, span_list->end); - - // Skip separators in the beginning, as well as - // separators after another separator: - if (span_list->type == pmh_SEPARATOR) { - span_list = span_list->next; - continue; - } - - // Store list of spans until next separator in subspan_list: - pmh_realelement *subspan_list = span_list; - pmh_realelement *previous = NULL; - while (span_list != NULL && span_list->type != pmh_SEPARATOR) { - previous = span_list; - span_list = span_list->next; - } - if (span_list != NULL && span_list->type == pmh_SEPARATOR) { - span_list = span_list->next; - previous->next = NULL; - } - - #if pmh_DEBUG_OUTPUT - pmh_PRINTF(" subspan process: "); - print_raw_spans_inline(subspan_list); - pmh_PRINTF("\n"); - #endif - - // Process subspan_list: - parser_data *raw_p_data = mk_parser_data( - p_data->original_input, - p_data->strip_positions, - p_data->strip_positions_len, - p_data->charbuf, - subspan_list, - subspan_list->pos, - p_data->extensions, - p_data->head_elems, - p_data->references - ); - parse_markdown(raw_p_data); - free(raw_p_data); - - pmh_PRINTF("parse over\n"); - } - - cursor = cursor->next; - } - } -} - - -#if pmh_DEBUG_OUTPUT -static void print_raw_blocks(char *text, pmh_realelement *elem[]) -{ - pmh_PRINTF("--------print_raw_blocks---------\n"); - pmh_PRINTF("block:\n"); - pmh_realelement *cursor = elem[pmh_RAW_LIST]; - while (cursor != NULL) - { - print_raw_spans_inline(cursor->children); - cursor = cursor->next; - } -} -#endif - - - - -/* Free all elements created while parsing */ -void pmh_free_elements(pmh_element **elems) -{ - pmh_realelement *cursor = (pmh_realelement*)elems[pmh_ALL]; - while (cursor != NULL) { - pmh_realelement *tofree = cursor; - cursor = cursor->all_elems_next; - if (tofree->text != NULL) - free(tofree->text); - if (tofree->label != NULL) - free(tofree->label); - if (tofree->address != NULL) - free(tofree->address); - free(tofree); - } - elems[pmh_ALL] = NULL; - - free(elems); -} - - - - - - -#define IS_CONTINUATION_BYTE(x) ((x & 0xC0) == 0x80) -#define HAS_UTF8_BOM(x) ( ((*x & 0xFF) == 0xEF)\ - && ((*(x+1) & 0xFF) == 0xBB)\ - && ((*(x+2) & 0xFF) == 0xBF) ) -#define ADD_STRIP_POS(x) \ - /* reallocate more space for the array, if needed: */ \ - if (strip_positions_size <= strip_positions_pos) { \ - size_t new_size = strip_positions_size * 2; \ - unsigned long *new_arr = (unsigned long *) \ - calloc(new_size, \ - sizeof(unsigned long)); \ - memcpy(new_arr, strip_positions, \ - (sizeof(unsigned long) * strip_positions_size)); \ - strip_positions_size = new_size; \ - free(strip_positions); \ - strip_positions = new_arr; \ - } \ - strip_positions[strip_positions_pos] = x; \ - strip_positions_pos++; - -/* -Copy `str` to `out`, while doing the following: - - remove UTF-8 continuation bytes - - remove possible UTF-8 BOM (byte order mark) - - append two newlines to the end (like peg-markdown does) - - keep track of which bytes we have stripped (in strip_positions) -*/ -static int strcpy_preformat(char *str, char **out, - unsigned long **out_strip_positions, - size_t *out_strip_positions_len) -{ - size_t strip_positions_size = 1024; - size_t strip_positions_pos = 0; - unsigned long *strip_positions = (unsigned long *) - calloc(strip_positions_size, - sizeof(unsigned long)); - - - // +2 in the following is due to the "\n\n" suffix: - char *new_str = (char *)malloc(sizeof(char) * strlen(str) + 1 + 2); - char *c = str; - int i = 0; - - if (HAS_UTF8_BOM(c)) { - c += 3; - ADD_STRIP_POS(0); - ADD_STRIP_POS(1); - ADD_STRIP_POS(2); - } - - while (*c != '\0') - { - if (!IS_CONTINUATION_BYTE(*c)) { - *(new_str+i) = *c, i++; - } else { - ADD_STRIP_POS((int)(c-str)); - } - c++; - } - - *(new_str+(i++)) = '\n'; - *(new_str+(i++)) = '\n'; - *(new_str+i) = '\0'; - - *out = new_str; - *out_strip_positions = strip_positions; - *out_strip_positions_len = strip_positions_pos; - return i; -} - - - -void pmh_markdown_to_elements(char *text, int extensions, - pmh_element **out_result[]) -{ - char *text_copy = NULL; - unsigned long *strip_positions = NULL; - size_t strip_positions_len = 0; - int text_copy_len = strcpy_preformat(text, &text_copy, &strip_positions, - &strip_positions_len); - - pmh_realelement *parsing_elem = (pmh_realelement *) - malloc(sizeof(pmh_realelement)); - parsing_elem->type = pmh_RAW; - parsing_elem->pos = 0; - parsing_elem->end = text_copy_len; - parsing_elem->next = NULL; - - parser_data *p_data = mk_parser_data( - text, - strip_positions, - strip_positions_len, - text_copy, - parsing_elem, - 0, - extensions, - NULL, - NULL - ); - pmh_realelement **result = p_data->head_elems; - - if (*text_copy != '\0') - { - // Get reference definitions into p_data->references - parse_references(p_data); - - // Reset parser state to beginning of input - p_data->offset = 0; - p_data->current_elem = p_data->elem_head; - - // Parse whole document - parse_markdown(p_data); - - #if pmh_DEBUG_OUTPUT - print_raw_blocks(text_copy, result); - #endif - - process_raw_blocks(p_data); - } - - free(strip_positions); - free(p_data); - free(parsing_elem); - free(text_copy); - - *out_result = (pmh_element**)result; -} - - - -/* -Mergesort linked list of elements (using comparison function `compare`), -return new head. (Adapted slightly from Simon Tatham's algorithm.) -*/ -static pmh_element *ll_mergesort(pmh_element *list, - int (*compare)(const pmh_element*, - const pmh_element*)) -{ - if (!list) - return NULL; - - pmh_element *out_head = list; - - /* Merge widths of doubling size until done */ - int merge_width = 1; - while (1) - { - pmh_element *l, *r; /* left & right segment pointers */ - pmh_element *tail = NULL; /* tail of sorted section */ - - l = out_head; - out_head = NULL; - - int merge_count = 0; - - while (l) - { - merge_count++; - - /* Position r, determine lsize & rsize */ - r = l; - int lsize = 0; - int i; - for (i = 0; i < merge_width; i++) { - lsize++; - r = r->next; - if (!r) - break; - } - int rsize = merge_width; - - /* Merge l & r */ - while (lsize > 0 || (rsize > 0 && r)) - { - bool get_from_left = false; - if (lsize == 0) get_from_left = false; - else if (rsize == 0 || !r) get_from_left = true; - else if (compare(l,r) <= 0) get_from_left = true; - - pmh_element *e; - if (get_from_left) { - e = l; l = l->next; lsize--; - } else { - e = r; r = r->next; rsize--; - } - - /* add the next pmh_element to the merged list */ - if (tail) - tail->next = e; - else - out_head = e; - tail = e; - } - - l = r; - } - tail->next = NULL; - - if (merge_count <= 1) - return out_head; - - merge_width *= 2; - } -} - -static int elem_compare_by_pos(const pmh_element *a, const pmh_element *b) -{ - return a->pos - b->pos; -} - -void pmh_sort_elements_by_pos(pmh_element *element_lists[]) -{ - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - element_lists[i] = ll_mergesort(element_lists[i], &elem_compare_by_pos); -} - - - - - - - - -/* return true if extension is selected */ -static bool extension(parser_data *p_data, int ext) -{ - return ((p_data->extensions & ext) != 0); -} - -/* return reference pmh_realelement for a given label */ -static pmh_realelement *get_reference(parser_data *p_data, char *label) -{ - if (!label) - return NULL; - - pmh_realelement *cursor = p_data->references; - while (cursor != NULL) - { - if (cursor->label && strcmp(label, cursor->label) == 0) - return cursor; - cursor = cursor->next; - } - return NULL; -} - - -/* cons an element/list onto a list, returning pointer to new head */ -static pmh_realelement *cons(pmh_realelement *elem, pmh_realelement *list) -{ - assert(elem != NULL); - - pmh_realelement *cur = elem; - while (cur->next != NULL) { - cur = cur->next; - } - cur->next = list; - - return elem; -} - - -/* reverse a list, returning pointer to new list */ -static pmh_realelement *reverse(pmh_realelement *list) -{ - pmh_realelement *new_head = NULL; - pmh_realelement *next = NULL; - while (list != NULL) { - next = list->next; - list->next = new_head; - new_head = list; - list = next; - } - return new_head; -} - - - -/* construct pmh_realelement */ -static pmh_realelement *mk_element(parser_data *p_data, pmh_element_type type, - long pos, long end) -{ - pmh_realelement *result = (pmh_realelement *)malloc(sizeof(pmh_realelement)); - memset(result, 0, sizeof(*result)); - result->type = type; - result->pos = pos; - result->end = end; - - pmh_realelement *old_all_elements_head = p_data->head_elems[pmh_ALL]; - p_data->head_elems[pmh_ALL] = result; - result->all_elems_next = old_all_elements_head; - - //pmh_PRINTF(" mk_element: %s [%ld - %ld]\n", pmh_element_name_from_type(type), pos, end); - - return result; -} - -static pmh_realelement *copy_element(parser_data *p_data, pmh_realelement *elem) -{ - pmh_realelement *result = mk_element(p_data, elem->type, elem->pos, elem->end); - result->label = strdup_or_null(elem->label); - result->text = strdup_or_null(elem->text); - result->address = strdup_or_null(elem->address); - return result; -} - -/* construct pmh_EXTRA_TEXT pmh_realelement */ -static pmh_realelement *mk_etext(parser_data *p_data, char *string) -{ - pmh_realelement *result; - assert(string != NULL); - result = mk_element(p_data, pmh_EXTRA_TEXT, 0,0); - result->text = strdup_or_null(string); - return result; -} - - -/* -Given an element where the offsets {pos, end} represent -locations in the *parsed text* (defined by the linked list of pmh_RAW and -pmh_EXTRA_TEXT elements in p_data->current_elem), fix these offsets to represent -corresponding offsets in the parse buffer (p_data->charbuf). Also split -the given pmh_realelement into multiple parts if its offsets span multiple -p_data->current_elem elements. Return the (list of) elements with real offsets. -*/ -static pmh_realelement *fix_offsets(parser_data *p_data, pmh_realelement *elem) -{ - if (elem->type == pmh_EXTRA_TEXT) - return mk_etext(p_data, elem->text); - - pmh_realelement *new_head = copy_element(p_data, elem); - - pmh_realelement *tail = new_head; - pmh_realelement *prev = NULL; - - bool found_start = false; - bool found_end = false; - bool tail_needs_pos = false; - unsigned long previous_end = 0; - unsigned long c = 0; - - pmh_realelement *cursor = p_data->elem_head; - while (cursor != NULL) - { - int thislen = (cursor->type == pmh_EXTRA_TEXT) - ? strlen(cursor->text) - : cursor->end - cursor->pos; - - if (tail_needs_pos && cursor->type != pmh_EXTRA_TEXT) { - tail->pos = cursor->pos; - tail_needs_pos = false; - } - - unsigned int this_pos = cursor->pos; - - if (!found_start && (c <= elem->pos && elem->pos <= c+thislen)) { - tail->pos = (cursor->type == pmh_EXTRA_TEXT) - ? previous_end - : cursor->pos + (elem->pos - c); - this_pos = tail->pos; - found_start = true; - } - - if (!found_end && (c <= elem->end && elem->end <= c+thislen)) { - tail->end = (cursor->type == pmh_EXTRA_TEXT) - ? previous_end - : cursor->pos + (elem->end - c); - found_end = true; - } - - if (found_start && found_end) - break; - - if (cursor->type != pmh_EXTRA_TEXT) - previous_end = cursor->end; - - if (found_start) { - pmh_realelement *new_elem = copy_element(p_data, tail); - new_elem->pos = this_pos; - new_elem->end = cursor->end; - new_elem->next = tail; - if (prev != NULL) - prev->next = new_elem; - if (new_head == tail) - new_head = new_elem; - prev = new_elem; - tail_needs_pos = true; - } - - c += thislen; - cursor = cursor->next; - } - - return new_head; -} - - - -/* Add an element to p_data->head_elems. */ -static void add(parser_data *p_data, pmh_realelement *elem) -{ - if (elem->type != pmh_RAW_LIST) - { - pmh_PRINTF(" add: %s [%ld - %ld]\n", - pmh_element_name_from_type(elem->type), elem->pos, elem->end); - elem = fix_offsets(p_data, elem); - pmh_PRINTF(" > %s [%ld - %ld]\n", - pmh_element_name_from_type(elem->type), elem->pos, elem->end); - } - else - { - pmh_PRINTF(" add: pmh_RAW_LIST "); - pmh_realelement *cursor = elem->children; - pmh_realelement *previous = NULL; - while (cursor != NULL) - { - pmh_realelement *next = cursor->next; - pmh_PRINTF("(%ld-%ld)>", cursor->pos, cursor->end); - pmh_realelement *new_cursor = fix_offsets(p_data, cursor); - if (previous != NULL) - previous->next = new_cursor; - else - elem->children = new_cursor; - pmh_PRINTF("(%ld-%ld)", new_cursor->pos, new_cursor->end); - while (new_cursor->next != NULL) { - new_cursor = new_cursor->next; - pmh_PRINTF("(%ld-%ld)", new_cursor->pos, new_cursor->end); - } - pmh_PRINTF(" "); - if (next != NULL) - new_cursor->next = next; - previous = new_cursor; - cursor = next; - } - pmh_PRINTF("\n"); - } - - if (p_data->head_elems[elem->type] == NULL) - p_data->head_elems[elem->type] = elem; - else - { - pmh_realelement *last = elem; - while (last->next != NULL) - last = last->next; - last->next = p_data->head_elems[elem->type]; - p_data->head_elems[elem->type] = elem; - } -} - - -// Given a range in the list of spans we use for parsing (pos, end), return -// a copy of the corresponding section in the original input, with all of -// the UTF-8 bytes intact: -static char *copy_input_span(parser_data *p_data, - unsigned long pos, unsigned long end) -{ - if (end <= pos) - return NULL; - - char *ret = NULL; - - // Adjust (pos,end) to match actual indexes in charbuf: - pmh_realelement *dummy = mk_element(p_data, pmh_NO_TYPE, pos, end); - pmh_realelement *fixed_dummies = fix_offsets(p_data, dummy); - pmh_realelement *cursor = fixed_dummies; - while (cursor != NULL) - { - if (cursor->end <= cursor->pos) - { - cursor = cursor->next; - continue; - } - - // Adjust cursor's span to take bytes stripped from the original - // input into account (i.e. match the corresponding span in - // p_data->original_input): - unsigned long adjusted_pos = cursor->pos; - unsigned long adjusted_end = cursor->end; - size_t i; - for (i = 0; i < p_data->strip_positions_len; i++) - { - unsigned long strip_position = p_data->strip_positions[i]; - if (strip_position <= adjusted_pos) - adjusted_pos++; - if (strip_position <= adjusted_end) - adjusted_end++; - else - break; - } - - // Copy span from original input: - size_t adjusted_len = adjusted_end - adjusted_pos; - char *str = (char *)malloc(sizeof(char)*adjusted_len + 1); - *str = '\0'; - strncat(str, (p_data->original_input + adjusted_pos), adjusted_len); - - if (ret == NULL) - ret = str; - else - { - // append str to ret: - char *new_ret = (char *)malloc(sizeof(char) - *(strlen(str) + strlen(ret)) + 1); - *new_ret = '\0'; - strcat(new_ret, ret); - strcat(new_ret, str); - free(ret); - free(str); - ret = new_ret; - } - - cursor = cursor->next; - } - - return ret; -} - - - - - -# define YYSTYPE pmh_realelement * -#ifdef __DEBUG__ -# define YY_DEBUG 1 -#endif - -#define YY_INPUT(buf, result, max_size)\ - yy_input_func(buf, &result, max_size, (parser_data *)G->data) - -static void yy_input_func(char *buf, int *result, int max_size, - parser_data *p_data) -{ - if (p_data->current_elem == NULL) - { - (*result) = 0; - return; - } - - if (p_data->current_elem->type == pmh_EXTRA_TEXT) - { - int yyc; - bool moreToRead = (p_data->current_elem->text - && *(p_data->current_elem->text - + p_data->current_elem->text_offset) != '\0'); - if (moreToRead) - { - yyc = *(p_data->current_elem->text + p_data->current_elem->text_offset++); - pmh_PRINTF("\e[47;30m"); pmh_PUTCHAR(yyc); pmh_PRINTF("\e[0m"); - pmh_IF(yyc == '\n') pmh_PRINTF("\e[47m \e[0m"); - } - else - { - yyc = EOF; - p_data->current_elem = p_data->current_elem->next; - pmh_PRINTF("\e[41m \e[0m"); - if (p_data->current_elem != NULL) - p_data->offset = p_data->current_elem->pos; - } - (*result) = (EOF == yyc) ? 0 : (*(buf) = yyc, 1); - return; - } - - *(buf) = *(p_data->charbuf + p_data->offset); - (*result) = (*buf != '\0'); - p_data->offset++; - - pmh_PRINTF("\e[43;30m"); pmh_PUTCHAR(*buf); pmh_PRINTF("\e[0m"); - pmh_IF(*buf == '\n') pmh_PRINTF("\e[42m \e[0m"); - - if (p_data->offset >= p_data->current_elem->end) - { - p_data->current_elem = p_data->current_elem->next; - pmh_PRINTF("\e[41m \e[0m"); - if (p_data->current_elem != NULL) - p_data->offset = p_data->current_elem->pos; - } -} - - - -#define elem(x) mk_element((parser_data *)G->data, x, thunk->begin, thunk->end) -#define elem_s(x) mk_element((parser_data *)G->data, x, s->pos, thunk->end) -#define mk_sep mk_element((parser_data *)G->data, pmh_SEPARATOR, 0,0) -#define mk_notype mk_element((parser_data *)G->data, pmh_NO_TYPE, 0,0) -#define etext(x) mk_etext((parser_data *)G->data, x) -#define ADD(x) add((parser_data *)G->data, x) -#define EXT(x) extension((parser_data *)G->data, x) -#define REF_EXISTS(x) reference_exists((parser_data *)G->data, x) -#define GET_REF(x) get_reference((parser_data *)G->data, x) -#define PARSING_REFERENCES ((parser_data *)G->data)->parsing_only_references -#define FREE_LABEL(l) { free(l->label); l->label = NULL; } -#define FREE_ADDRESS(l) { free(l->address); l->address = NULL; } - -// This gives us the text matched with < > as it appears in the original input: -#define COPY_YYTEXT_ORIG() copy_input_span((parser_data *)G->data, thunk->begin, thunk->end) - -// pos is the postition of next char to parse after matching one $ -// Do not allow $, digit, and \ before opening $ -bool inline_equation_predict_pre(char *buf, int pos) -{ - if (pos < 2) { - return true; - } - - unsigned char ch = buf[pos - 2]; - return ch != '$' && (ch < '0' || ch > '9') && ch != '\\'; -} - -// Do not allow \, space before ending $ -bool inline_equation_predict_post(char *buf, int pos) -{ - unsigned char ch = buf[pos - 2]; - return ch != '\\' && ch != ' ' && ch != '\t'; -} - -#define IEP_PRE inline_equation_predict_pre(G->buf, G->pos) -#define IEP_POST inline_equation_predict_post(G->buf, G->pos) - -// Do not allow whitespace before ending ~~ -bool strike_predict_post(char *buf, int pos) -{ - unsigned char ch = buf[pos - 1]; - return ch != '\n' && ch != '\r' && ch != ' ' && ch != '\t'; -} - -#define STRIKE_POST strike_predict_post(G->buf, G->pos) - -// Number of display formula raw opening -unsigned char nr_dfr = 0; - -bool start_dfr() -{ - nr_dfr = 1; - return true; -} - -bool inc_dfr() -{ - ++nr_dfr; - return true; -} - -bool dec_dfr() -{ - --nr_dfr; - return true; -} - -bool nested_dfr() -{ - return nr_dfr > 1; -} - - -#ifndef YY_ALLOC -#define YY_ALLOC(N, D) malloc(N) -#endif -#ifndef YY_CALLOC -#define YY_CALLOC(N, S, D) calloc(N, S) -#endif -#ifndef YY_REALLOC -#define YY_REALLOC(B, N, D) realloc(B, N) -#endif -#ifndef YY_FREE -#define YY_FREE free -#endif -#ifndef YY_LOCAL -#define YY_LOCAL(T) static T -#endif -#ifndef YY_ACTION -#define YY_ACTION(T) static T -#endif -#ifndef YY_RULE -#define YY_RULE(T) static T -#endif -#ifndef YY_PARSE -#define YY_PARSE(T) T -#endif -#ifndef YY_NAME -#define YY_NAME(N) yy##N -#endif -#ifndef YY_INPUT -#define YY_INPUT(buf, result, max_size) \ - { \ - int yyc= getchar(); \ - result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ - yyprintf((stderr, "<%c>", yyc)); \ - } -#endif -#ifndef YY_BEGIN -#define YY_BEGIN ( G->begin= G->pos, 1) -#endif -#ifndef YY_END -#define YY_END ( G->end= G->pos, 1) -#endif -#ifdef YY_DEBUG -# define yyprintf(args) fprintf args -#else -# define yyprintf(args) -#endif -#ifndef YYSTYPE -#define YYSTYPE int -#endif -#ifndef YY_XTYPE -#define YY_XTYPE void * -#endif -#ifndef YY_XVAR -#define YY_XVAR yyxvar -#endif - -#ifndef YY_STACK_SIZE -#define YY_STACK_SIZE 128 -#endif - -#ifndef YY_BUFFER_START_SIZE -#define YY_BUFFER_START_SIZE 1024 -#endif - -#ifndef YY_PART -#define yydata G->data -#define yy G->ss - -struct _yythunk; // forward declaration -typedef void (*yyaction)(struct _GREG *G, char *yytext, int yyleng, struct _yythunk *thunkpos, YY_XTYPE YY_XVAR); -typedef struct _yythunk { int begin, end; yyaction action; struct _yythunk *next; } yythunk; - -typedef struct _GREG { - char *buf; - int buflen; - int offset; - int pos; - int limit; - char *text; - int textlen; - int begin; - int end; - yythunk *thunks; - int thunkslen; - int thunkpos; - YYSTYPE ss; - YYSTYPE *val; - YYSTYPE *vals; - int valslen; - YY_XTYPE data; -} GREG; - -YY_LOCAL(int) yyrefill(GREG *G) -{ - int yyn; - while (G->buflen - G->pos < 512) - { - G->buflen *= 2; - G->buf= (char *)YY_REALLOC(G->buf, G->buflen, G->data); - } - YY_INPUT((G->buf + G->pos), yyn, (G->buflen - G->pos)); - if (!yyn) return 0; - G->limit += yyn; - return 1; -} - -YY_LOCAL(int) yymatchDot(GREG *G) -{ - if (G->pos >= G->limit && !yyrefill(G)) return 0; - ++G->pos; - return 1; -} - -YY_LOCAL(int) yymatchChar(GREG *G, int c) -{ - if (G->pos >= G->limit && !yyrefill(G)) return 0; - if ((unsigned char)G->buf[G->pos] == c) - { - ++G->pos; - yyprintf((stderr, " ok yymatchChar(%c) @ %s\n", c, G->buf+G->pos)); - return 1; - } - yyprintf((stderr, " fail yymatchChar(%c) @ %s\n", c, G->buf+G->pos)); - return 0; -} - -YY_LOCAL(int) yymatchString(GREG *G, char *s) -{ - int yysav= G->pos; - while (*s) - { - if (G->pos >= G->limit && !yyrefill(G)) return 0; - if (G->buf[G->pos] != *s) - { - G->pos= yysav; - return 0; - } - ++s; - ++G->pos; - } - return 1; -} - -YY_LOCAL(int) yymatchClass(GREG *G, unsigned char *bits) -{ - int c; - if (G->pos >= G->limit && !yyrefill(G)) return 0; - c= (unsigned char)G->buf[G->pos]; - if (bits[c >> 3] & (1 << (c & 7))) - { - ++G->pos; - yyprintf((stderr, " ok yymatchClass @ %s\n", G->buf+G->pos)); - return 1; - } - yyprintf((stderr, " fail yymatchClass @ %s\n", G->buf+G->pos)); - return 0; -} - -YY_LOCAL(void) yyDo(GREG *G, yyaction action, int begin, int end) -{ - while (G->thunkpos >= G->thunkslen) - { - G->thunkslen *= 2; - G->thunks= (yythunk *)YY_REALLOC(G->thunks, sizeof(yythunk) * G->thunkslen, G->data); - } - G->thunks[G->thunkpos].begin= begin; - G->thunks[G->thunkpos].end= end; - G->thunks[G->thunkpos].action= action; - ++G->thunkpos; -} - -YY_LOCAL(int) yyText(GREG *G, int begin, int end) -{ - int yyleng= end - begin; - if (yyleng <= 0) - yyleng= 0; - else - { - while (G->textlen < (yyleng + 1)) - { - G->textlen *= 2; - G->text= (char *)YY_REALLOC(G->text, G->textlen, G->data); - } - memcpy(G->text, G->buf + begin, yyleng); - } - G->text[yyleng]= '\0'; - return yyleng; -} - -YY_LOCAL(void) yyDone(GREG *G) -{ - int pos; - for (pos= 0; pos < G->thunkpos; ++pos) - { - yythunk *thunk= &G->thunks[pos]; - int yyleng= thunk->end ? yyText(G, thunk->begin, thunk->end) : thunk->begin; - yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, G->text)); - thunk->action(G, G->text, yyleng, thunk, G->data); - } - G->thunkpos= 0; -} - -YY_LOCAL(void) yyCommit(GREG *G) -{ - if ((G->limit -= G->pos)) - { - memmove(G->buf, G->buf + G->pos, G->limit); - } - G->offset += G->pos; - G->begin -= G->pos; - G->end -= G->pos; - G->pos= G->thunkpos= 0; -} - -YY_LOCAL(int) yyAccept(GREG *G, int tp0) -{ - if (tp0) - { - fprintf(stderr, "accept denied at %d\n", tp0); - return 0; - } - else - { - yyDone(G); - yyCommit(G); - } - return 1; -} - -YY_LOCAL(void) yyPush(GREG *G, char *text, int count, yythunk *thunk, YY_XTYPE YY_XVAR) { G->val += count; } -YY_LOCAL(void) yyPop(GREG *G, char *text, int count, yythunk *thunk, YY_XTYPE YY_XVAR) { G->val -= count; } -YY_LOCAL(void) yySet(GREG *G, char *text, int count, yythunk *thunk, YY_XTYPE YY_XVAR) { G->val[count]= G->ss; } - -#endif /* YY_PART */ - -#define YYACCEPT yyAccept(G, yythunkpos0) - -YY_RULE(int) yy_RawNoteBlock(GREG *G); /* 268 */ -YY_RULE(int) yy_RawNoteReference(GREG *G); /* 267 */ -YY_RULE(int) yy_AlphanumericAscii(GREG *G); /* 266 */ -YY_RULE(int) yy_Quoted(GREG *G); /* 265 */ -YY_RULE(int) yy_HtmlTag(GREG *G); /* 264 */ -YY_RULE(int) yy_MarkTagClose(GREG *G); /* 263 */ -YY_RULE(int) yy_MarkTagText(GREG *G); /* 262 */ -YY_RULE(int) yy_MarkTagOpen(GREG *G); /* 261 */ -YY_RULE(int) yy_Ticks5(GREG *G); /* 260 */ -YY_RULE(int) yy_Ticks4(GREG *G); /* 259 */ -YY_RULE(int) yy_Ticks3(GREG *G); /* 258 */ -YY_RULE(int) yy_Ticks2(GREG *G); /* 257 */ -YY_RULE(int) yy_Ticks1(GREG *G); /* 256 */ -YY_RULE(int) yy_SkipBlock(GREG *G); /* 255 */ -YY_RULE(int) yy_References(GREG *G); /* 254 */ -YY_RULE(int) yy_EmptyTitle(GREG *G); /* 253 */ -YY_RULE(int) yy_RefTitleParens(GREG *G); /* 252 */ -YY_RULE(int) yy_RefTitleDouble(GREG *G); /* 251 */ -YY_RULE(int) yy_RefTitleSingle(GREG *G); /* 250 */ -YY_RULE(int) yy_LabelInline(GREG *G); /* 249 */ -YY_RULE(int) yy_RefTitle(GREG *G); /* 248 */ -YY_RULE(int) yy_RefSrc(GREG *G); /* 247 */ -YY_RULE(int) yy_AutoLinkEmail(GREG *G); /* 246 */ -YY_RULE(int) yy_AutoLinkUrl(GREG *G); /* 245 */ -YY_RULE(int) yy_ImageSizeHeight(GREG *G); /* 244 */ -YY_RULE(int) yy_ImageSizeWidth(GREG *G); /* 243 */ -YY_RULE(int) yy_ImageSizeComplete(GREG *G); /* 242 */ -YY_RULE(int) yy_TitleDoubleExt(GREG *G); /* 241 */ -YY_RULE(int) yy_TitleSingleExt(GREG *G); /* 240 */ -YY_RULE(int) yy_TitleDouble(GREG *G); /* 239 */ -YY_RULE(int) yy_TitleSingle(GREG *G); /* 238 */ -YY_RULE(int) yy_SourceContents(GREG *G); /* 237 */ -YY_RULE(int) yy_ImageSize(GREG *G); /* 236 */ -YY_RULE(int) yy_TitleExt(GREG *G); /* 235 */ -YY_RULE(int) yy_Title(GREG *G); /* 234 */ -YY_RULE(int) yy_Source(GREG *G); /* 233 */ -YY_RULE(int) yy_Label(GREG *G); /* 232 */ -YY_RULE(int) yy_ReferenceLinkSingle(GREG *G); /* 231 */ -YY_RULE(int) yy_ReferenceLinkDouble(GREG *G); /* 230 */ -YY_RULE(int) yy_AutoLink(GREG *G); /* 229 */ -YY_RULE(int) yy_ReferenceLink(GREG *G); /* 228 */ -YY_RULE(int) yy_ExplicitLinkSize(GREG *G); /* 227 */ -YY_RULE(int) yy_ExplicitLink(GREG *G); /* 226 */ -YY_RULE(int) yy_StrongUl(GREG *G); /* 225 */ -YY_RULE(int) yy_StrongStar(GREG *G); /* 224 */ -YY_RULE(int) yy_Whitespace(GREG *G); /* 223 */ -YY_RULE(int) yy_EmphUl(GREG *G); /* 222 */ -YY_RULE(int) yy_EmphStar(GREG *G); /* 221 */ -YY_RULE(int) yy_StarLine(GREG *G); /* 220 */ -YY_RULE(int) yy_UlLine(GREG *G); /* 219 */ -YY_RULE(int) yy_SpecialChar(GREG *G); /* 218 */ -YY_RULE(int) yy_Eof(GREG *G); /* 217 */ -YY_RULE(int) yy_NormalEndline(GREG *G); /* 216 */ -YY_RULE(int) yy_TerminalEndline(GREG *G); /* 215 */ -YY_RULE(int) yy_LineBreak(GREG *G); /* 214 */ -YY_RULE(int) yy_CharEntity(GREG *G); /* 213 */ -YY_RULE(int) yy_DecEntity(GREG *G); /* 212 */ -YY_RULE(int) yy_HexEntity(GREG *G); /* 211 */ -YY_RULE(int) yy_ExtendedSpecialChar(GREG *G); /* 210 */ -YY_RULE(int) yy_Alphanumeric(GREG *G); /* 209 */ -YY_RULE(int) yy_NormalChar(GREG *G); /* 208 */ -YY_RULE(int) yy_Symbol(GREG *G); /* 207 */ -YY_RULE(int) yy_EscapedChar(GREG *G); /* 206 */ -YY_RULE(int) yy_Entity(GREG *G); /* 205 */ -YY_RULE(int) yy_RawHtml(GREG *G); /* 204 */ -YY_RULE(int) yy_Mark(GREG *G); /* 203 */ -YY_RULE(int) yy_Code(GREG *G); /* 202 */ -YY_RULE(int) yy_InlineNote(GREG *G); /* 201 */ -YY_RULE(int) yy_NoteReference(GREG *G); /* 200 */ -YY_RULE(int) yy_Link(GREG *G); /* 199 */ -YY_RULE(int) yy_Image(GREG *G); /* 198 */ -YY_RULE(int) yy_Strike(GREG *G); /* 197 */ -YY_RULE(int) yy_Emph(GREG *G); /* 196 */ -YY_RULE(int) yy_Strong(GREG *G); /* 195 */ -YY_RULE(int) yy_UlOrStarLine(GREG *G); /* 194 */ -YY_RULE(int) yy_Str(GREG *G); /* 193 */ -YY_RULE(int) yy_InStyleTags(GREG *G); /* 192 */ -YY_RULE(int) yy_StyleClose(GREG *G); /* 191 */ -YY_RULE(int) yy_StyleOpen(GREG *G); /* 190 */ -YY_RULE(int) yy_HtmlBlockType(GREG *G); /* 189 */ -YY_RULE(int) yy_HtmlBlockSelfClosing(GREG *G); /* 188 */ -YY_RULE(int) yy_HtmlComment(GREG *G); /* 187 */ -YY_RULE(int) yy_HtmlBlockInTags(GREG *G); /* 186 */ -YY_RULE(int) yy_HtmlBlockHead(GREG *G); /* 185 */ -YY_RULE(int) yy_HtmlBlockCloseHead(GREG *G); /* 184 */ -YY_RULE(int) yy_HtmlBlockOpenHead(GREG *G); /* 183 */ -YY_RULE(int) yy_HtmlBlockScript(GREG *G); /* 182 */ -YY_RULE(int) yy_HtmlBlockCloseScript(GREG *G); /* 181 */ -YY_RULE(int) yy_HtmlBlockOpenScript(GREG *G); /* 180 */ -YY_RULE(int) yy_HtmlBlockTr(GREG *G); /* 179 */ -YY_RULE(int) yy_HtmlBlockCloseTr(GREG *G); /* 178 */ -YY_RULE(int) yy_HtmlBlockOpenTr(GREG *G); /* 177 */ -YY_RULE(int) yy_HtmlBlockThead(GREG *G); /* 176 */ -YY_RULE(int) yy_HtmlBlockCloseThead(GREG *G); /* 175 */ -YY_RULE(int) yy_HtmlBlockOpenThead(GREG *G); /* 174 */ -YY_RULE(int) yy_HtmlBlockTh(GREG *G); /* 173 */ -YY_RULE(int) yy_HtmlBlockCloseTh(GREG *G); /* 172 */ -YY_RULE(int) yy_HtmlBlockOpenTh(GREG *G); /* 171 */ -YY_RULE(int) yy_HtmlBlockTfoot(GREG *G); /* 170 */ -YY_RULE(int) yy_HtmlBlockCloseTfoot(GREG *G); /* 169 */ -YY_RULE(int) yy_HtmlBlockOpenTfoot(GREG *G); /* 168 */ -YY_RULE(int) yy_HtmlBlockTd(GREG *G); /* 167 */ -YY_RULE(int) yy_HtmlBlockCloseTd(GREG *G); /* 166 */ -YY_RULE(int) yy_HtmlBlockOpenTd(GREG *G); /* 165 */ -YY_RULE(int) yy_HtmlBlockTbody(GREG *G); /* 164 */ -YY_RULE(int) yy_HtmlBlockCloseTbody(GREG *G); /* 163 */ -YY_RULE(int) yy_HtmlBlockOpenTbody(GREG *G); /* 162 */ -YY_RULE(int) yy_HtmlBlockLi(GREG *G); /* 161 */ -YY_RULE(int) yy_HtmlBlockCloseLi(GREG *G); /* 160 */ -YY_RULE(int) yy_HtmlBlockOpenLi(GREG *G); /* 159 */ -YY_RULE(int) yy_HtmlBlockFrameset(GREG *G); /* 158 */ -YY_RULE(int) yy_HtmlBlockCloseFrameset(GREG *G); /* 157 */ -YY_RULE(int) yy_HtmlBlockOpenFrameset(GREG *G); /* 156 */ -YY_RULE(int) yy_HtmlBlockDt(GREG *G); /* 155 */ -YY_RULE(int) yy_HtmlBlockCloseDt(GREG *G); /* 154 */ -YY_RULE(int) yy_HtmlBlockOpenDt(GREG *G); /* 153 */ -YY_RULE(int) yy_HtmlBlockDd(GREG *G); /* 152 */ -YY_RULE(int) yy_HtmlBlockCloseDd(GREG *G); /* 151 */ -YY_RULE(int) yy_HtmlBlockOpenDd(GREG *G); /* 150 */ -YY_RULE(int) yy_HtmlBlockUl(GREG *G); /* 149 */ -YY_RULE(int) yy_HtmlBlockCloseUl(GREG *G); /* 148 */ -YY_RULE(int) yy_HtmlBlockOpenUl(GREG *G); /* 147 */ -YY_RULE(int) yy_HtmlBlockTable(GREG *G); /* 146 */ -YY_RULE(int) yy_HtmlBlockCloseTable(GREG *G); /* 145 */ -YY_RULE(int) yy_HtmlBlockOpenTable(GREG *G); /* 144 */ -YY_RULE(int) yy_HtmlBlockPre(GREG *G); /* 143 */ -YY_RULE(int) yy_HtmlBlockClosePre(GREG *G); /* 142 */ -YY_RULE(int) yy_HtmlBlockOpenPre(GREG *G); /* 141 */ -YY_RULE(int) yy_HtmlBlockP(GREG *G); /* 140 */ -YY_RULE(int) yy_HtmlBlockCloseP(GREG *G); /* 139 */ -YY_RULE(int) yy_HtmlBlockOpenP(GREG *G); /* 138 */ -YY_RULE(int) yy_HtmlBlockOl(GREG *G); /* 137 */ -YY_RULE(int) yy_HtmlBlockCloseOl(GREG *G); /* 136 */ -YY_RULE(int) yy_HtmlBlockOpenOl(GREG *G); /* 135 */ -YY_RULE(int) yy_HtmlBlockNoscript(GREG *G); /* 134 */ -YY_RULE(int) yy_HtmlBlockCloseNoscript(GREG *G); /* 133 */ -YY_RULE(int) yy_HtmlBlockOpenNoscript(GREG *G); /* 132 */ -YY_RULE(int) yy_HtmlBlockNoframes(GREG *G); /* 131 */ -YY_RULE(int) yy_HtmlBlockCloseNoframes(GREG *G); /* 130 */ -YY_RULE(int) yy_HtmlBlockOpenNoframes(GREG *G); /* 129 */ -YY_RULE(int) yy_HtmlBlockMenu(GREG *G); /* 128 */ -YY_RULE(int) yy_HtmlBlockCloseMenu(GREG *G); /* 127 */ -YY_RULE(int) yy_HtmlBlockOpenMenu(GREG *G); /* 126 */ -YY_RULE(int) yy_HtmlBlockH6(GREG *G); /* 125 */ -YY_RULE(int) yy_HtmlBlockCloseH6(GREG *G); /* 124 */ -YY_RULE(int) yy_HtmlBlockOpenH6(GREG *G); /* 123 */ -YY_RULE(int) yy_HtmlBlockH5(GREG *G); /* 122 */ -YY_RULE(int) yy_HtmlBlockCloseH5(GREG *G); /* 121 */ -YY_RULE(int) yy_HtmlBlockOpenH5(GREG *G); /* 120 */ -YY_RULE(int) yy_HtmlBlockH4(GREG *G); /* 119 */ -YY_RULE(int) yy_HtmlBlockCloseH4(GREG *G); /* 118 */ -YY_RULE(int) yy_HtmlBlockOpenH4(GREG *G); /* 117 */ -YY_RULE(int) yy_HtmlBlockH3(GREG *G); /* 116 */ -YY_RULE(int) yy_HtmlBlockCloseH3(GREG *G); /* 115 */ -YY_RULE(int) yy_HtmlBlockOpenH3(GREG *G); /* 114 */ -YY_RULE(int) yy_HtmlBlockH2(GREG *G); /* 113 */ -YY_RULE(int) yy_HtmlBlockCloseH2(GREG *G); /* 112 */ -YY_RULE(int) yy_HtmlBlockOpenH2(GREG *G); /* 111 */ -YY_RULE(int) yy_HtmlBlockH1(GREG *G); /* 110 */ -YY_RULE(int) yy_HtmlBlockCloseH1(GREG *G); /* 109 */ -YY_RULE(int) yy_HtmlBlockOpenH1(GREG *G); /* 108 */ -YY_RULE(int) yy_HtmlBlockForm(GREG *G); /* 107 */ -YY_RULE(int) yy_HtmlBlockCloseForm(GREG *G); /* 106 */ -YY_RULE(int) yy_HtmlBlockOpenForm(GREG *G); /* 105 */ -YY_RULE(int) yy_HtmlBlockFieldset(GREG *G); /* 104 */ -YY_RULE(int) yy_HtmlBlockCloseFieldset(GREG *G); /* 103 */ -YY_RULE(int) yy_HtmlBlockOpenFieldset(GREG *G); /* 102 */ -YY_RULE(int) yy_HtmlBlockDl(GREG *G); /* 101 */ -YY_RULE(int) yy_HtmlBlockCloseDl(GREG *G); /* 100 */ -YY_RULE(int) yy_HtmlBlockOpenDl(GREG *G); /* 99 */ -YY_RULE(int) yy_HtmlBlockDiv(GREG *G); /* 98 */ -YY_RULE(int) yy_HtmlBlockCloseDiv(GREG *G); /* 97 */ -YY_RULE(int) yy_HtmlBlockOpenDiv(GREG *G); /* 96 */ -YY_RULE(int) yy_HtmlBlockDir(GREG *G); /* 95 */ -YY_RULE(int) yy_HtmlBlockCloseDir(GREG *G); /* 94 */ -YY_RULE(int) yy_HtmlBlockOpenDir(GREG *G); /* 93 */ -YY_RULE(int) yy_HtmlBlockCenter(GREG *G); /* 92 */ -YY_RULE(int) yy_HtmlBlockCloseCenter(GREG *G); /* 91 */ -YY_RULE(int) yy_HtmlBlockOpenCenter(GREG *G); /* 90 */ -YY_RULE(int) yy_HtmlBlockBlockquote(GREG *G); /* 89 */ -YY_RULE(int) yy_HtmlBlockCloseBlockquote(GREG *G); /* 88 */ -YY_RULE(int) yy_HtmlBlockOpenBlockquote(GREG *G); /* 87 */ -YY_RULE(int) yy_HtmlBlockAddress(GREG *G); /* 86 */ -YY_RULE(int) yy_HtmlBlockCloseAddress(GREG *G); /* 85 */ -YY_RULE(int) yy_HtmlAttribute(GREG *G); /* 84 */ -YY_RULE(int) yy_HtmlBlockOpenAddress(GREG *G); /* 83 */ -YY_RULE(int) yy_OptionallyIndentedLine(GREG *G); /* 82 */ -YY_RULE(int) yy_Indent(GREG *G); /* 81 */ -YY_RULE(int) yy_ListBlockLine(GREG *G); /* 80 */ -YY_RULE(int) yy_ListContinuationBlock(GREG *G); /* 79 */ -YY_RULE(int) yy_ListBlock(GREG *G); /* 78 */ -YY_RULE(int) yy_ListItem(GREG *G); /* 77 */ -YY_RULE(int) yy_Enumerator(GREG *G); /* 76 */ -YY_RULE(int) yy_ListItemTight(GREG *G); /* 75 */ -YY_RULE(int) yy_ListLoose(GREG *G); /* 74 */ -YY_RULE(int) yy_ListTight(GREG *G); /* 73 */ -YY_RULE(int) yy_Bullet(GREG *G); /* 72 */ -YY_RULE(int) yy_TableCell(GREG *G); /* 71 */ -YY_RULE(int) yy_TableBorder(GREG *G); /* 70 */ -YY_RULE(int) yy_TableLine(GREG *G); /* 69 */ -YY_RULE(int) yy_TableDelimiter(GREG *G); /* 68 */ -YY_RULE(int) yy_TableHeader(GREG *G); /* 67 */ -YY_RULE(int) yy_InlineEquationMultiple(GREG *G); /* 66 */ -YY_RULE(int) yy_InlineEquationSingle(GREG *G); /* 65 */ -YY_RULE(int) yy_InlineEquation(GREG *G); /* 64 */ -YY_RULE(int) yy_Nonspacechar(GREG *G); /* 63 */ -YY_RULE(int) yy_DisplayFormulaRawMark(GREG *G); /* 62 */ -YY_RULE(int) yy_DisplayFormulaRawEnd(GREG *G); /* 61 */ -YY_RULE(int) yy_Spnl(GREG *G); /* 60 */ -YY_RULE(int) yy_DisplayFormulaRawStart(GREG *G); /* 59 */ -YY_RULE(int) yy_FormulaNumber(GREG *G); /* 58 */ -YY_RULE(int) yy_DisplayFormulaRaw(GREG *G); /* 57 */ -YY_RULE(int) yy_DisplayFormulaDollar(GREG *G); /* 56 */ -YY_RULE(int) yy_FencedCodeBlockTidle(GREG *G); /* 55 */ -YY_RULE(int) yy_FencedCodeBlockTick(GREG *G); /* 54 */ -YY_RULE(int) yy_FencedCodeBlockEndTidle(GREG *G); /* 53 */ -YY_RULE(int) yy_FencedCodeBlockChunkTidle(GREG *G); /* 52 */ -YY_RULE(int) yy_FencedCodeBlockStartTidleLine(GREG *G); /* 51 */ -YY_RULE(int) yy_FencedCodeBlockStartTidle(GREG *G); /* 50 */ -YY_RULE(int) yy_Spacechar(GREG *G); /* 49 */ -YY_RULE(int) yy_FencedCodeBlockEndTick(GREG *G); /* 48 */ -YY_RULE(int) yy_FencedCodeBlockChunkTick(GREG *G); /* 47 */ -YY_RULE(int) yy_FencedCodeBlockStartTickLine(GREG *G); /* 46 */ -YY_RULE(int) yy_FencedCodeBlockStartTick(GREG *G); /* 45 */ -YY_RULE(int) yy_VerbatimChunk(GREG *G); /* 44 */ -YY_RULE(int) yy_IndentedLine(GREG *G); /* 43 */ -YY_RULE(int) yy_NonblankIndentedLine(GREG *G); /* 42 */ -YY_RULE(int) yy_Line(GREG *G); /* 41 */ -YY_RULE(int) yy_StartList(GREG *G); /* 40 */ -YY_RULE(int) yy_BlockQuoteRaw(GREG *G); /* 39 */ -YY_RULE(int) yy_Endline(GREG *G); /* 38 */ -YY_RULE(int) yy_RawLine(GREG *G); /* 37 */ -YY_RULE(int) yy_SetextBottom2(GREG *G); /* 36 */ -YY_RULE(int) yy_SetextBottom1(GREG *G); /* 35 */ -YY_RULE(int) yy_SetextHeading2(GREG *G); /* 34 */ -YY_RULE(int) yy_SetextHeading1(GREG *G); /* 33 */ -YY_RULE(int) yy_SetextHeading(GREG *G); /* 32 */ -YY_RULE(int) yy_Space(GREG *G); /* 31 */ -YY_RULE(int) yy_AtxHeading(GREG *G); /* 30 */ -YY_RULE(int) yy_AtxStart(GREG *G); /* 29 */ -YY_RULE(int) yy_Inline(GREG *G); /* 28 */ -YY_RULE(int) yy_Sp(GREG *G); /* 27 */ -YY_RULE(int) yy_AtxInline(GREG *G); /* 26 */ -YY_RULE(int) yy_Inlines(GREG *G); /* 25 */ -YY_RULE(int) yy_NonindentSpace(GREG *G); /* 24 */ -YY_RULE(int) yy_Plain(GREG *G); /* 23 */ -YY_RULE(int) yy_Para(GREG *G); /* 22 */ -YY_RULE(int) yy_StyleBlock(GREG *G); /* 21 */ -YY_RULE(int) yy_HtmlBlock(GREG *G); /* 20 */ -YY_RULE(int) yy_Table(GREG *G); /* 19 */ -YY_RULE(int) yy_BulletList(GREG *G); /* 18 */ -YY_RULE(int) yy_OrderedList(GREG *G); /* 17 */ -YY_RULE(int) yy_Heading(GREG *G); /* 16 */ -YY_RULE(int) yy_HorizontalRule(GREG *G); /* 15 */ -YY_RULE(int) yy_Reference(GREG *G); /* 14 */ -YY_RULE(int) yy_Note(GREG *G); /* 13 */ -YY_RULE(int) yy_DisplayFormula(GREG *G); /* 12 */ -YY_RULE(int) yy_FencedCodeBlock(GREG *G); /* 11 */ -YY_RULE(int) yy_Verbatim(GREG *G); /* 10 */ -YY_RULE(int) yy_BlockQuote(GREG *G); /* 9 */ -YY_RULE(int) yy_BlankLine(GREG *G); /* 8 */ -YY_RULE(int) yy_FrontMatterEndMark(GREG *G); /* 7 */ -YY_RULE(int) yy_FrontMatterBlock(GREG *G); /* 6 */ -YY_RULE(int) yy_Newline(GREG *G); /* 5 */ -YY_RULE(int) yy_LocMarker(GREG *G); /* 4 */ -YY_RULE(int) yy_Block(GREG *G); /* 3 */ -YY_RULE(int) yy_FrontMatter(GREG *G); /* 2 */ -YY_RULE(int) yy_Doc(GREG *G); /* 1 */ - -YY_ACTION(void) yy_1_InlineNote(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_InlineNote\n")); - ADD(elem_s(pmh_NOTE)); ; -#undef s -} -YY_ACTION(void) yy_1_Note(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Note\n")); - ADD(elem_s(pmh_NOTE)); ; -#undef s -} -YY_ACTION(void) yy_1_NoteReference(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_NoteReference\n")); - ADD(elem(pmh_NOTE)); ; -} -YY_ACTION(void) yy_1_RawLine(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_RawLine\n")); - yy = elem(pmh_RAW); ; -} -YY_ACTION(void) yy_1_Line(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Line\n")); - yy = mk_element((parser_data *)G->data, pmh_RAW, yy->pos, yy->end); ; -} -YY_ACTION(void) yy_1_StartList(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_StartList\n")); - yy = NULL; ; -} -YY_ACTION(void) yy_1_HtmlComment(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlComment\n")); - ADD(elem_s(pmh_COMMENT)); ; -#undef s -} -YY_ACTION(void) yy_1_RawHtml(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_RawHtml\n")); - ADD(elem_s(pmh_HTML)); ; -#undef s -} -YY_ACTION(void) yy_1_MarkTagClose(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_MarkTagClose\n")); - yy = elem_s(pmh_HTML); ; -#undef s -} -YY_ACTION(void) yy_1_MarkTagOpen(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_MarkTagOpen\n")); - yy = elem_s(pmh_HTML); ; -#undef s -} -YY_ACTION(void) yy_1_Mark(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define c G->val[-1] -#define o G->val[-2] - yyprintf((stderr, "do yy_1_Mark\n")); - - ADD(o); - ADD(mk_element((parser_data *)G->data, pmh_MARK, o->end, c->pos)); - ADD(c); - ; -#undef c -#undef o -} -YY_ACTION(void) yy_1_Code(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Code\n")); - ADD(elem_s(pmh_CODE)); ; -#undef s -} -YY_ACTION(void) yy_1_Ticks5(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks5\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_Ticks4(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks4\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_Ticks3(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks3\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_Ticks2(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks2\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_Ticks1(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Ticks1\n")); - yy = elem(pmh_NO_TYPE); ; -} -YY_ACTION(void) yy_1_RefSrc(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_RefSrc\n")); - yy = mk_notype; yy->address = COPY_YYTEXT_ORIG(); ; -} -YY_ACTION(void) yy_2_Label(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_2_Label\n")); - - s->pos = s->pos; - s->end = thunk->end; - yy = s; - ; -#undef s -} -YY_ACTION(void) yy_1_Label(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Label\n")); - s->label = COPY_YYTEXT_ORIG(); ; -#undef s -} -YY_ACTION(void) yy_1_Reference(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define r G->val[-1] -#define l G->val[-2] -#define s G->val[-3] - yyprintf((stderr, "do yy_1_Reference\n")); - - pmh_realelement *el = elem_s(pmh_REFERENCE); - el->label = strdup_or_null(l->label); - el->address = strdup_or_null(r->address); - ADD(el); - FREE_LABEL(l); - FREE_ADDRESS(r); - ; -#undef r -#undef l -#undef s -} -YY_ACTION(void) yy_3_AutoLinkEmail(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_3_AutoLinkEmail\n")); - - s->end = thunk->end; - ADD(s); - ; -#undef s -} -YY_ACTION(void) yy_2_AutoLinkEmail(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_2_AutoLinkEmail\n")); - s->address = COPY_YYTEXT_ORIG(); ; -#undef s -} -YY_ACTION(void) yy_1_AutoLinkEmail(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_AutoLinkEmail\n")); - s->type = pmh_AUTO_LINK_EMAIL; ; -#undef s -} -YY_ACTION(void) yy_3_AutoLinkUrl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_3_AutoLinkUrl\n")); - - s->end = thunk->end; - ADD(s); - ; -#undef s -} -YY_ACTION(void) yy_2_AutoLinkUrl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_2_AutoLinkUrl\n")); - s->address = COPY_YYTEXT_ORIG(); ; -#undef s -} -YY_ACTION(void) yy_1_AutoLinkUrl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_AutoLinkUrl\n")); - s->type = pmh_AUTO_LINK_URL; ; -#undef s -} -YY_ACTION(void) yy_3_Source(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_3_Source\n")); - yy->address = COPY_YYTEXT_ORIG(); ; -} -YY_ACTION(void) yy_2_Source(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_2_Source\n")); - yy->address = COPY_YYTEXT_ORIG(); ; -} -YY_ACTION(void) yy_1_Source(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Source\n")); - yy = mk_notype; ; -} -YY_ACTION(void) yy_1_ExplicitLinkSize(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define l G->val[-1] -#define s G->val[-2] - yyprintf((stderr, "do yy_1_ExplicitLinkSize\n")); - - yy = elem_s(pmh_LINK); - if (l->address != NULL) - yy->address = strdup_or_null(l->address); - FREE_LABEL(s); - FREE_ADDRESS(l); - ; -#undef l -#undef s -} -YY_ACTION(void) yy_1_ExplicitLink(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define l G->val[-1] -#define s G->val[-2] - yyprintf((stderr, "do yy_1_ExplicitLink\n")); - - yy = elem_s(pmh_LINK); - if (l->address != NULL) - yy->address = strdup_or_null(l->address); - FREE_LABEL(s); - FREE_ADDRESS(l); - ; -#undef l -#undef s -} -YY_ACTION(void) yy_1_ReferenceLinkSingle(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_ReferenceLinkSingle\n")); - - pmh_realelement *reference = GET_REF(s->label); - if (reference) { - yy = elem_s(pmh_LINK); - yy->label = strdup_or_null(s->label); - yy->address = strdup_or_null(reference->address); - } else - yy = NULL; - FREE_LABEL(s); - ; -#undef s -} -YY_ACTION(void) yy_1_ReferenceLinkDouble(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define l G->val[-1] -#define s G->val[-2] - yyprintf((stderr, "do yy_1_ReferenceLinkDouble\n")); - - pmh_realelement *reference = GET_REF(l->label); - if (reference) { - yy = elem_s(pmh_LINK); - yy->label = strdup_or_null(l->label); - yy->address = strdup_or_null(reference->address); - } else - yy = NULL; - FREE_LABEL(s); - FREE_LABEL(l); - ; -#undef l -#undef s -} -YY_ACTION(void) yy_1_Link(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Link\n")); - if (yy) ADD(yy); ; -} -YY_ACTION(void) yy_1_Image(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Image\n")); - - if (yy != NULL) { - yy->type = pmh_IMAGE; - yy->pos -= 1; - ADD(yy); - } - ; -} -YY_ACTION(void) yy_1_Strike(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Strike\n")); - ADD(elem_s(pmh_STRIKE)); ; -#undef s -} -YY_ACTION(void) yy_1_StrongUl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_StrongUl\n")); - ADD(elem_s(pmh_STRONG)); ; -#undef s -} -YY_ACTION(void) yy_1_StrongStar(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_StrongStar\n")); - ADD(elem_s(pmh_STRONG)); ; -#undef s -} -YY_ACTION(void) yy_1_EmphUl(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_EmphUl\n")); - ADD(elem_s(pmh_EMPH)); ; -#undef s -} -YY_ACTION(void) yy_1_EmphStar(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_EmphStar\n")); - ADD(elem_s(pmh_EMPH)); ; -#undef s -} -YY_ACTION(void) yy_1_Entity(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Entity\n")); - ADD(elem_s(pmh_HTML_ENTITY)); ; -#undef s -} -YY_ACTION(void) yy_1_StyleBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_StyleBlock\n")); - ADD(elem_s(pmh_HTMLBLOCK)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlock\n")); - ADD(elem_s(pmh_HTMLBLOCK)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH6(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH6\n")); - ADD(elem_s(pmh_H6)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH5(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH5\n")); - ADD(elem_s(pmh_H5)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH4(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH4\n")); - ADD(elem_s(pmh_H4)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH3(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH3\n")); - ADD(elem_s(pmh_H3)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH2(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH2\n")); - ADD(elem_s(pmh_H2)); ; -#undef s -} -YY_ACTION(void) yy_1_HtmlBlockH1(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_HtmlBlockH1\n")); - ADD(elem_s(pmh_H1)); ; -#undef s -} -YY_ACTION(void) yy_1_Enumerator(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Enumerator\n")); - ADD(elem(pmh_LIST_ENUMERATOR)); ; -} -YY_ACTION(void) yy_3_ListContinuationBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_ListContinuationBlock\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_2_ListContinuationBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListContinuationBlock\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_1_ListContinuationBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListContinuationBlock\n")); - if (*yytext == '\0') /* if strlen(yytext) == 0 */ - a = cons(elem(pmh_SEPARATOR), a); - else - a = cons(elem(pmh_RAW), a); - ; -#undef a -} -YY_ACTION(void) yy_3_ListBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_ListBlock\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_2_ListBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListBlock\n")); - a = cons(elem(pmh_RAW), a); ; -#undef a -} -YY_ACTION(void) yy_1_ListBlock(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListBlock\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_3_ListItemTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_ListItemTight\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_2_ListItemTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListItemTight\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_1_ListItemTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListItemTight\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_3_ListItem(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_ListItem\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_2_ListItem(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListItem\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_1_ListItem(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListItem\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_2_ListLoose(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define b G->val[-1] -#define a G->val[-2] - yyprintf((stderr, "do yy_2_ListLoose\n")); - pmh_realelement *cur = a; - while (cur != NULL) { - pmh_realelement *rawlist = mk_element((parser_data *)G->data, pmh_RAW_LIST, 0,0); - rawlist->children = reverse(cur->children); - ADD(rawlist); - cur = cur->next; - } - ; -#undef b -#undef a -} -YY_ACTION(void) yy_1_ListLoose(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define b G->val[-1] -#define a G->val[-2] - yyprintf((stderr, "do yy_1_ListLoose\n")); - b = cons(etext("\n\n"), b); /* In loose list, \n\n added to end of each element */ - pmh_realelement *el = mk_notype; - el->children = b; - a = cons(el, a); - ; -#undef b -#undef a -} -YY_ACTION(void) yy_2_ListTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_ListTight\n")); - pmh_realelement *cur = a; - while (cur != NULL) { - pmh_realelement *rawlist = mk_element((parser_data *)G->data, pmh_RAW_LIST, 0,0); - rawlist->children = reverse(cur->children); - ADD(rawlist); - cur = cur->next; - } - ; -#undef a -} -YY_ACTION(void) yy_1_ListTight(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_ListTight\n")); - pmh_realelement *el = mk_notype; - el->children = yy; - a = cons(el, a); - ; -#undef a -} -YY_ACTION(void) yy_1_Bullet(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_Bullet\n")); - ADD(elem(pmh_LIST_BULLET)); ; -} -YY_ACTION(void) yy_1_HorizontalRule(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_HorizontalRule\n")); - ADD(elem(pmh_HRULE)); ; -} -YY_ACTION(void) yy_1_TableBorder(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_TableBorder\n")); - ADD(elem(pmh_TABLEBORDER)); ; -} -YY_ACTION(void) yy_1_TableHeader(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_TableHeader\n")); - ADD(elem_s(pmh_TABLEHEADER)); ; -#undef s -} -YY_ACTION(void) yy_1_Table(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Table\n")); - ADD(elem_s(pmh_TABLE)); ; -#undef s -} -YY_ACTION(void) yy_1_InlineEquation(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_InlineEquation\n")); - ADD(elem(pmh_INLINEEQUATION)); ; -} -YY_ACTION(void) yy_1_DisplayFormulaRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_DisplayFormulaRaw\n")); - ADD(elem(pmh_DISPLAYFORMULA)); ; -} -YY_ACTION(void) yy_1_DisplayFormulaDollar(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_DisplayFormulaDollar\n")); - ADD(elem(pmh_DISPLAYFORMULA)); ; -} -YY_ACTION(void) yy_1_FencedCodeBlockTidle(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_FencedCodeBlockTidle\n")); - ADD(elem(pmh_FENCEDCODEBLOCK)); ; -} -YY_ACTION(void) yy_1_FencedCodeBlockTick(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_FencedCodeBlockTick\n")); - ADD(elem(pmh_FENCEDCODEBLOCK)); ; -} -YY_ACTION(void) yy_1_Verbatim(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_Verbatim\n")); - ADD(elem_s(pmh_VERBATIM)); ; -#undef s -} -YY_ACTION(void) yy_5_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_5_BlockQuoteRaw\n")); - yy = a; ; -#undef a -} -YY_ACTION(void) yy_4_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_4_BlockQuoteRaw\n")); - a = cons(etext("\n"), a); ; -#undef a -} -YY_ACTION(void) yy_3_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_3_BlockQuoteRaw\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_2_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_2_BlockQuoteRaw\n")); - a = cons(yy, a); ; -#undef a -} -YY_ACTION(void) yy_1_BlockQuoteRaw(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_BlockQuoteRaw\n")); - ADD(elem(pmh_BLOCKQUOTE)); ; -#undef a -} -YY_ACTION(void) yy_1_BlockQuote(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define a G->val[-1] - yyprintf((stderr, "do yy_1_BlockQuote\n")); - pmh_realelement *rawlist = mk_element((parser_data *)G->data, pmh_RAW_LIST, 0,0); - rawlist->children = reverse(a); - ADD(rawlist); - ; -#undef a -} -YY_ACTION(void) yy_1_SetextHeading2(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_SetextHeading2\n")); - ADD(elem_s(pmh_H2)); ; -#undef s -} -YY_ACTION(void) yy_1_SetextHeading1(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_SetextHeading1\n")); - ADD(elem_s(pmh_H1)); ; -#undef s -} -YY_ACTION(void) yy_1_AtxHeading(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_AtxHeading\n")); - ADD(elem_s(s->type)); ; -#undef s -} -YY_ACTION(void) yy_1_AtxStart(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_AtxStart\n")); - yy = elem((pmh_element_type)(pmh_H1 + (strlen(yytext) - 1))); ; -} -YY_ACTION(void) yy_1_FrontMatter(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ -#define s G->val[-1] - yyprintf((stderr, "do yy_1_FrontMatter\n")); - - ADD(elem(pmh_FRONTMATTER)); - ; -#undef s -} -YY_ACTION(void) yy_1_LocMarker(GREG *G, char *yytext, int yyleng, yythunk *thunk, YY_XTYPE YY_XVAR) -{ - yyprintf((stderr, "do yy_1_LocMarker\n")); - yy = elem(pmh_NO_TYPE); ; -} - -YY_RULE(int) yy_RawNoteBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RawNoteBlock")); - { int yypos4= G->pos, yythunkpos4= G->thunkpos; if (!yy_BlankLine(G)) { goto l4; } goto l1; - l4:; G->pos= yypos4; G->thunkpos= yythunkpos4; - } if (!yy_OptionallyIndentedLine(G)) { goto l1; } - l2:; - { int yypos3= G->pos, yythunkpos3= G->thunkpos; - { int yypos5= G->pos, yythunkpos5= G->thunkpos; if (!yy_BlankLine(G)) { goto l5; } goto l3; - l5:; G->pos= yypos5; G->thunkpos= yythunkpos5; - } if (!yy_OptionallyIndentedLine(G)) { goto l3; } goto l2; - l3:; G->pos= yypos3; G->thunkpos= yythunkpos3; - } - l6:; - { int yypos7= G->pos, yythunkpos7= G->thunkpos; if (!yy_BlankLine(G)) { goto l7; } goto l6; - l7:; G->pos= yypos7; G->thunkpos= yythunkpos7; - } - yyprintf((stderr, " ok %s @ %s\n", "RawNoteBlock", G->buf+G->pos)); - return 1; - l1:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RawNoteBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RawNoteReference(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RawNoteReference")); if (!yymatchString(G, "[^")) goto l8; - { int yypos11= G->pos, yythunkpos11= G->thunkpos; if (!yy_Newline(G)) { goto l11; } goto l8; - l11:; G->pos= yypos11; G->thunkpos= yythunkpos11; - } - { int yypos12= G->pos, yythunkpos12= G->thunkpos; if (!yymatchChar(G, ']')) goto l12; goto l8; - l12:; G->pos= yypos12; G->thunkpos= yythunkpos12; - } if (!yymatchDot(G)) goto l8; - l9:; - { int yypos10= G->pos, yythunkpos10= G->thunkpos; - { int yypos13= G->pos, yythunkpos13= G->thunkpos; if (!yy_Newline(G)) { goto l13; } goto l10; - l13:; G->pos= yypos13; G->thunkpos= yythunkpos13; - } - { int yypos14= G->pos, yythunkpos14= G->thunkpos; if (!yymatchChar(G, ']')) goto l14; goto l10; - l14:; G->pos= yypos14; G->thunkpos= yythunkpos14; - } if (!yymatchDot(G)) goto l10; goto l9; - l10:; G->pos= yypos10; G->thunkpos= yythunkpos10; - } if (!yymatchChar(G, ']')) goto l8; - yyprintf((stderr, " ok %s @ %s\n", "RawNoteReference", G->buf+G->pos)); - return 1; - l8:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RawNoteReference", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AlphanumericAscii(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "AlphanumericAscii")); if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l15; - yyprintf((stderr, " ok %s @ %s\n", "AlphanumericAscii", G->buf+G->pos)); - return 1; - l15:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AlphanumericAscii", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Quoted(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Quoted")); - { int yypos17= G->pos, yythunkpos17= G->thunkpos; if (!yymatchChar(G, '"')) goto l18; - l19:; - { int yypos20= G->pos, yythunkpos20= G->thunkpos; - { int yypos21= G->pos, yythunkpos21= G->thunkpos; if (!yymatchChar(G, '"')) goto l21; goto l20; - l21:; G->pos= yypos21; G->thunkpos= yythunkpos21; - } if (!yymatchDot(G)) goto l20; goto l19; - l20:; G->pos= yypos20; G->thunkpos= yythunkpos20; - } if (!yymatchChar(G, '"')) goto l18; goto l17; - l18:; G->pos= yypos17; G->thunkpos= yythunkpos17; if (!yymatchChar(G, '\'')) goto l16; - l22:; - { int yypos23= G->pos, yythunkpos23= G->thunkpos; - { int yypos24= G->pos, yythunkpos24= G->thunkpos; if (!yymatchChar(G, '\'')) goto l24; goto l23; - l24:; G->pos= yypos24; G->thunkpos= yythunkpos24; - } if (!yymatchDot(G)) goto l23; goto l22; - l23:; G->pos= yypos23; G->thunkpos= yythunkpos23; - } if (!yymatchChar(G, '\'')) goto l16; - } - l17:; - yyprintf((stderr, " ok %s @ %s\n", "Quoted", G->buf+G->pos)); - return 1; - l16:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Quoted", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlTag(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlTag")); if (!yymatchChar(G, '<')) goto l25; if (!yy_Spnl(G)) { goto l25; } - { int yypos26= G->pos, yythunkpos26= G->thunkpos; if (!yymatchChar(G, '/')) goto l26; goto l27; - l26:; G->pos= yypos26; G->thunkpos= yythunkpos26; - } - l27:; if (!yy_AlphanumericAscii(G)) { goto l25; } - l28:; - { int yypos29= G->pos, yythunkpos29= G->thunkpos; if (!yy_AlphanumericAscii(G)) { goto l29; } goto l28; - l29:; G->pos= yypos29; G->thunkpos= yythunkpos29; - } if (!yy_Spnl(G)) { goto l25; } - l30:; - { int yypos31= G->pos, yythunkpos31= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l31; } goto l30; - l31:; G->pos= yypos31; G->thunkpos= yythunkpos31; - } - { int yypos32= G->pos, yythunkpos32= G->thunkpos; if (!yymatchChar(G, '/')) goto l32; goto l33; - l32:; G->pos= yypos32; G->thunkpos= yythunkpos32; - } - l33:; if (!yy_Spnl(G)) { goto l25; } if (!yymatchChar(G, '>')) goto l25; - yyprintf((stderr, " ok %s @ %s\n", "HtmlTag", G->buf+G->pos)); - return 1; - l25:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlTag", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_MarkTagClose(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "MarkTagClose")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l34; if (!yy_LocMarker(G)) { goto l34; } yyDo(G, yySet, -1, 0); if (!yymatchChar(G, '<')) goto l34; if (!yy_Spnl(G)) { goto l34; } if (!yymatchChar(G, '/')) goto l34; - { int yypos35= G->pos, yythunkpos35= G->thunkpos; if (!yymatchString(G, "mark")) goto l36; goto l35; - l36:; G->pos= yypos35; G->thunkpos= yythunkpos35; if (!yymatchString(G, "MARK")) goto l34; - } - l35:; if (!yy_Spnl(G)) { goto l34; } if (!yymatchChar(G, '>')) goto l34; yyText(G, G->begin, G->end); if (!(YY_END)) goto l34; yyDo(G, yy_1_MarkTagClose, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "MarkTagClose", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l34:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "MarkTagClose", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_MarkTagText(GREG *G) -{ - yyprintf((stderr, "%s\n", "MarkTagText")); - l38:; - { int yypos39= G->pos, yythunkpos39= G->thunkpos; - { int yypos40= G->pos, yythunkpos40= G->thunkpos; if (!yy_MarkTagClose(G)) { goto l40; } goto l39; - l40:; G->pos= yypos40; G->thunkpos= yythunkpos40; - } - { int yypos41= G->pos, yythunkpos41= G->thunkpos; if (!yy_RawHtml(G)) { goto l42; } goto l41; - l42:; G->pos= yypos41; G->thunkpos= yythunkpos41; if (!yymatchDot(G)) goto l39; - } - l41:; goto l38; - l39:; G->pos= yypos39; G->thunkpos= yythunkpos39; - } - yyprintf((stderr, " ok %s @ %s\n", "MarkTagText", G->buf+G->pos)); - return 1; -} -YY_RULE(int) yy_MarkTagOpen(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "MarkTagOpen")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l43; if (!yy_LocMarker(G)) { goto l43; } yyDo(G, yySet, -1, 0); if (!yymatchChar(G, '<')) goto l43; if (!yy_Spnl(G)) { goto l43; } - { int yypos44= G->pos, yythunkpos44= G->thunkpos; if (!yymatchString(G, "mark")) goto l45; goto l44; - l45:; G->pos= yypos44; G->thunkpos= yythunkpos44; if (!yymatchString(G, "MARK")) goto l43; - } - l44:; if (!yy_Spnl(G)) { goto l43; } - l46:; - { int yypos47= G->pos, yythunkpos47= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l47; } goto l46; - l47:; G->pos= yypos47; G->thunkpos= yythunkpos47; - } if (!yymatchChar(G, '>')) goto l43; yyText(G, G->begin, G->end); if (!(YY_END)) goto l43; yyDo(G, yy_1_MarkTagOpen, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "MarkTagOpen", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l43:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "MarkTagOpen", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks5(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks5")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l48; if (!yymatchString(G, "`````")) goto l48; yyText(G, G->begin, G->end); if (!(YY_END)) goto l48; - { int yypos49= G->pos, yythunkpos49= G->thunkpos; if (!yymatchChar(G, '`')) goto l49; goto l48; - l49:; G->pos= yypos49; G->thunkpos= yythunkpos49; - } yyDo(G, yy_1_Ticks5, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks5", G->buf+G->pos)); - return 1; - l48:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks5", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks4(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks4")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l50; if (!yymatchString(G, "````")) goto l50; yyText(G, G->begin, G->end); if (!(YY_END)) goto l50; - { int yypos51= G->pos, yythunkpos51= G->thunkpos; if (!yymatchChar(G, '`')) goto l51; goto l50; - l51:; G->pos= yypos51; G->thunkpos= yythunkpos51; - } yyDo(G, yy_1_Ticks4, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks4", G->buf+G->pos)); - return 1; - l50:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks4", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks3(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks3")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l52; if (!yymatchString(G, "```")) goto l52; yyText(G, G->begin, G->end); if (!(YY_END)) goto l52; - { int yypos53= G->pos, yythunkpos53= G->thunkpos; if (!yymatchChar(G, '`')) goto l53; goto l52; - l53:; G->pos= yypos53; G->thunkpos= yythunkpos53; - } yyDo(G, yy_1_Ticks3, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks3", G->buf+G->pos)); - return 1; - l52:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks3", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks2")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l54; if (!yymatchString(G, "``")) goto l54; yyText(G, G->begin, G->end); if (!(YY_END)) goto l54; - { int yypos55= G->pos, yythunkpos55= G->thunkpos; if (!yymatchChar(G, '`')) goto l55; goto l54; - l55:; G->pos= yypos55; G->thunkpos= yythunkpos55; - } yyDo(G, yy_1_Ticks2, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks2", G->buf+G->pos)); - return 1; - l54:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Ticks1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Ticks1")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l56; if (!yymatchChar(G, '`')) goto l56; yyText(G, G->begin, G->end); if (!(YY_END)) goto l56; - { int yypos57= G->pos, yythunkpos57= G->thunkpos; if (!yymatchChar(G, '`')) goto l57; goto l56; - l57:; G->pos= yypos57; G->thunkpos= yythunkpos57; - } yyDo(G, yy_1_Ticks1, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Ticks1", G->buf+G->pos)); - return 1; - l56:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Ticks1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SkipBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SkipBlock")); - { int yypos59= G->pos, yythunkpos59= G->thunkpos; - { int yypos63= G->pos, yythunkpos63= G->thunkpos; if (!yy_BlankLine(G)) { goto l63; } goto l60; - l63:; G->pos= yypos63; G->thunkpos= yythunkpos63; - } if (!yy_RawLine(G)) { goto l60; } - l61:; - { int yypos62= G->pos, yythunkpos62= G->thunkpos; - { int yypos64= G->pos, yythunkpos64= G->thunkpos; if (!yy_BlankLine(G)) { goto l64; } goto l62; - l64:; G->pos= yypos64; G->thunkpos= yythunkpos64; - } if (!yy_RawLine(G)) { goto l62; } goto l61; - l62:; G->pos= yypos62; G->thunkpos= yythunkpos62; - } - l65:; - { int yypos66= G->pos, yythunkpos66= G->thunkpos; if (!yy_BlankLine(G)) { goto l66; } goto l65; - l66:; G->pos= yypos66; G->thunkpos= yythunkpos66; - } goto l59; - l60:; G->pos= yypos59; G->thunkpos= yythunkpos59; if (!yy_BlankLine(G)) { goto l58; } - l67:; - { int yypos68= G->pos, yythunkpos68= G->thunkpos; if (!yy_BlankLine(G)) { goto l68; } goto l67; - l68:; G->pos= yypos68; G->thunkpos= yythunkpos68; - } - } - l59:; - yyprintf((stderr, " ok %s @ %s\n", "SkipBlock", G->buf+G->pos)); - return 1; - l58:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SkipBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_References(GREG *G) -{ - yyprintf((stderr, "%s\n", "References")); - l70:; - { int yypos71= G->pos, yythunkpos71= G->thunkpos; - { int yypos72= G->pos, yythunkpos72= G->thunkpos; if (!yy_Reference(G)) { goto l73; } goto l72; - l73:; G->pos= yypos72; G->thunkpos= yythunkpos72; if (!yy_SkipBlock(G)) { goto l71; } - } - l72:; goto l70; - l71:; G->pos= yypos71; G->thunkpos= yythunkpos71; - } - yyprintf((stderr, " ok %s @ %s\n", "References", G->buf+G->pos)); - return 1; -} -YY_RULE(int) yy_EmptyTitle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "EmptyTitle")); if (!yymatchString(G, "")) goto l74; - yyprintf((stderr, " ok %s @ %s\n", "EmptyTitle", G->buf+G->pos)); - return 1; - l74:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "EmptyTitle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefTitleParens(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefTitleParens")); if (!yy_Spnl(G)) { goto l75; } if (!yymatchChar(G, '(')) goto l75; - l76:; - { int yypos77= G->pos, yythunkpos77= G->thunkpos; - { int yypos78= G->pos, yythunkpos78= G->thunkpos; - { int yypos79= G->pos, yythunkpos79= G->thunkpos; if (!yymatchChar(G, ')')) goto l80; if (!yy_Sp(G)) { goto l80; } if (!yy_Newline(G)) { goto l80; } goto l79; - l80:; G->pos= yypos79; G->thunkpos= yythunkpos79; if (!yy_Newline(G)) { goto l78; } - } - l79:; goto l77; - l78:; G->pos= yypos78; G->thunkpos= yythunkpos78; - } if (!yymatchDot(G)) goto l77; goto l76; - l77:; G->pos= yypos77; G->thunkpos= yythunkpos77; - } if (!yymatchChar(G, ')')) goto l75; - yyprintf((stderr, " ok %s @ %s\n", "RefTitleParens", G->buf+G->pos)); - return 1; - l75:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefTitleParens", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefTitleDouble(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefTitleDouble")); if (!yy_Spnl(G)) { goto l81; } if (!yymatchChar(G, '"')) goto l81; - l82:; - { int yypos83= G->pos, yythunkpos83= G->thunkpos; - { int yypos84= G->pos, yythunkpos84= G->thunkpos; - { int yypos85= G->pos, yythunkpos85= G->thunkpos; if (!yymatchChar(G, '"')) goto l86; if (!yy_Sp(G)) { goto l86; } if (!yy_Newline(G)) { goto l86; } goto l85; - l86:; G->pos= yypos85; G->thunkpos= yythunkpos85; if (!yy_Newline(G)) { goto l84; } - } - l85:; goto l83; - l84:; G->pos= yypos84; G->thunkpos= yythunkpos84; - } if (!yymatchDot(G)) goto l83; goto l82; - l83:; G->pos= yypos83; G->thunkpos= yythunkpos83; - } if (!yymatchChar(G, '"')) goto l81; - yyprintf((stderr, " ok %s @ %s\n", "RefTitleDouble", G->buf+G->pos)); - return 1; - l81:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefTitleDouble", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefTitleSingle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefTitleSingle")); if (!yy_Spnl(G)) { goto l87; } if (!yymatchChar(G, '\'')) goto l87; - l88:; - { int yypos89= G->pos, yythunkpos89= G->thunkpos; - { int yypos90= G->pos, yythunkpos90= G->thunkpos; - { int yypos91= G->pos, yythunkpos91= G->thunkpos; if (!yymatchChar(G, '\'')) goto l92; if (!yy_Sp(G)) { goto l92; } if (!yy_Newline(G)) { goto l92; } goto l91; - l92:; G->pos= yypos91; G->thunkpos= yythunkpos91; if (!yy_Newline(G)) { goto l90; } - } - l91:; goto l89; - l90:; G->pos= yypos90; G->thunkpos= yythunkpos90; - } if (!yymatchDot(G)) goto l89; goto l88; - l89:; G->pos= yypos89; G->thunkpos= yythunkpos89; - } if (!yymatchChar(G, '\'')) goto l87; - yyprintf((stderr, " ok %s @ %s\n", "RefTitleSingle", G->buf+G->pos)); - return 1; - l87:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefTitleSingle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_LabelInline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "LabelInline")); - { int yypos94= G->pos, yythunkpos94= G->thunkpos; if (!yy_Str(G)) { goto l95; } goto l94; - l95:; G->pos= yypos94; G->thunkpos= yythunkpos94; if (!yy_Endline(G)) { goto l96; } goto l94; - l96:; G->pos= yypos94; G->thunkpos= yythunkpos94; if (!yy_Space(G)) { goto l97; } goto l94; - l97:; G->pos= yypos94; G->thunkpos= yythunkpos94; if (!yy_RawHtml(G)) { goto l98; } goto l94; - l98:; G->pos= yypos94; G->thunkpos= yythunkpos94; if (!yy_Entity(G)) { goto l99; } goto l94; - l99:; G->pos= yypos94; G->thunkpos= yythunkpos94; if (!yy_EscapedChar(G)) { goto l100; } goto l94; - l100:; G->pos= yypos94; G->thunkpos= yythunkpos94; if (!yy_Symbol(G)) { goto l93; } - } - l94:; - yyprintf((stderr, " ok %s @ %s\n", "LabelInline", G->buf+G->pos)); - return 1; - l93:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "LabelInline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefTitle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefTitle")); - { int yypos102= G->pos, yythunkpos102= G->thunkpos; if (!yy_RefTitleSingle(G)) { goto l103; } goto l102; - l103:; G->pos= yypos102; G->thunkpos= yythunkpos102; if (!yy_RefTitleDouble(G)) { goto l104; } goto l102; - l104:; G->pos= yypos102; G->thunkpos= yythunkpos102; if (!yy_RefTitleParens(G)) { goto l105; } goto l102; - l105:; G->pos= yypos102; G->thunkpos= yythunkpos102; if (!yy_EmptyTitle(G)) { goto l101; } - } - l102:; - yyprintf((stderr, " ok %s @ %s\n", "RefTitle", G->buf+G->pos)); - return 1; - l101:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefTitle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RefSrc(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RefSrc")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l106; if (!yy_Nonspacechar(G)) { goto l106; } - l107:; - { int yypos108= G->pos, yythunkpos108= G->thunkpos; if (!yy_Nonspacechar(G)) { goto l108; } goto l107; - l108:; G->pos= yypos108; G->thunkpos= yythunkpos108; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l106; yyDo(G, yy_1_RefSrc, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "RefSrc", G->buf+G->pos)); - return 1; - l106:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RefSrc", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AutoLinkEmail(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "AutoLinkEmail")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l109; if (!yy_LocMarker(G)) { goto l109; } yyDo(G, yySet, -1, 0); yyDo(G, yy_1_AutoLinkEmail, G->begin, G->end); if (!yymatchChar(G, '<')) goto l109; - { int yypos110= G->pos, yythunkpos110= G->thunkpos; if (!yymatchString(G, "mailto:")) goto l110; goto l111; - l110:; G->pos= yypos110; G->thunkpos= yythunkpos110; - } - l111:; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l109; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\062\350\377\003\376\377\377\207\376\377\377\107\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l109; - l112:; - { int yypos113= G->pos, yythunkpos113= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\062\350\377\003\376\377\377\207\376\377\377\107\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l113; goto l112; - l113:; G->pos= yypos113; G->thunkpos= yythunkpos113; - } if (!yymatchChar(G, '@')) goto l109; - { int yypos116= G->pos, yythunkpos116= G->thunkpos; if (!yy_Newline(G)) { goto l116; } goto l109; - l116:; G->pos= yypos116; G->thunkpos= yythunkpos116; - } - { int yypos117= G->pos, yythunkpos117= G->thunkpos; if (!yymatchChar(G, '>')) goto l117; goto l109; - l117:; G->pos= yypos117; G->thunkpos= yythunkpos117; - } if (!yymatchDot(G)) goto l109; - l114:; - { int yypos115= G->pos, yythunkpos115= G->thunkpos; - { int yypos118= G->pos, yythunkpos118= G->thunkpos; if (!yy_Newline(G)) { goto l118; } goto l115; - l118:; G->pos= yypos118; G->thunkpos= yythunkpos118; - } - { int yypos119= G->pos, yythunkpos119= G->thunkpos; if (!yymatchChar(G, '>')) goto l119; goto l115; - l119:; G->pos= yypos119; G->thunkpos= yythunkpos119; - } if (!yymatchDot(G)) goto l115; goto l114; - l115:; G->pos= yypos115; G->thunkpos= yythunkpos115; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l109; yyDo(G, yy_2_AutoLinkEmail, G->begin, G->end); if (!yymatchChar(G, '>')) goto l109; yyText(G, G->begin, G->end); if (!(YY_END)) goto l109; yyDo(G, yy_3_AutoLinkEmail, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "AutoLinkEmail", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l109:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AutoLinkEmail", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AutoLinkUrl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "AutoLinkUrl")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l120; if (!yy_LocMarker(G)) { goto l120; } yyDo(G, yySet, -1, 0); yyDo(G, yy_1_AutoLinkUrl, G->begin, G->end); if (!yymatchChar(G, '<')) goto l120; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l120; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\000\000\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l120; - l121:; - { int yypos122= G->pos, yythunkpos122= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\000\000\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l122; goto l121; - l122:; G->pos= yypos122; G->thunkpos= yythunkpos122; - } if (!yymatchString(G, "://")) goto l120; - { int yypos125= G->pos, yythunkpos125= G->thunkpos; if (!yy_Newline(G)) { goto l125; } goto l120; - l125:; G->pos= yypos125; G->thunkpos= yythunkpos125; - } - { int yypos126= G->pos, yythunkpos126= G->thunkpos; if (!yymatchChar(G, '>')) goto l126; goto l120; - l126:; G->pos= yypos126; G->thunkpos= yythunkpos126; - } if (!yymatchDot(G)) goto l120; - l123:; - { int yypos124= G->pos, yythunkpos124= G->thunkpos; - { int yypos127= G->pos, yythunkpos127= G->thunkpos; if (!yy_Newline(G)) { goto l127; } goto l124; - l127:; G->pos= yypos127; G->thunkpos= yythunkpos127; - } - { int yypos128= G->pos, yythunkpos128= G->thunkpos; if (!yymatchChar(G, '>')) goto l128; goto l124; - l128:; G->pos= yypos128; G->thunkpos= yythunkpos128; - } if (!yymatchDot(G)) goto l124; goto l123; - l124:; G->pos= yypos124; G->thunkpos= yythunkpos124; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l120; yyDo(G, yy_2_AutoLinkUrl, G->begin, G->end); if (!yymatchChar(G, '>')) goto l120; yyText(G, G->begin, G->end); if (!(YY_END)) goto l120; yyDo(G, yy_3_AutoLinkUrl, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "AutoLinkUrl", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l120:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AutoLinkUrl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ImageSizeHeight(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ImageSizeHeight")); if (!yymatchString(G, "=x")) goto l129; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l129; - l130:; - { int yypos131= G->pos, yythunkpos131= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l131; goto l130; - l131:; G->pos= yypos131; G->thunkpos= yythunkpos131; - } - yyprintf((stderr, " ok %s @ %s\n", "ImageSizeHeight", G->buf+G->pos)); - return 1; - l129:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ImageSizeHeight", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ImageSizeWidth(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ImageSizeWidth")); if (!yymatchChar(G, '=')) goto l132; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l132; - l133:; - { int yypos134= G->pos, yythunkpos134= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l134; goto l133; - l134:; G->pos= yypos134; G->thunkpos= yythunkpos134; - } if (!yymatchChar(G, 'x')) goto l132; - yyprintf((stderr, " ok %s @ %s\n", "ImageSizeWidth", G->buf+G->pos)); - return 1; - l132:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ImageSizeWidth", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ImageSizeComplete(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ImageSizeComplete")); if (!yymatchChar(G, '=')) goto l135; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l135; - l136:; - { int yypos137= G->pos, yythunkpos137= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l137; goto l136; - l137:; G->pos= yypos137; G->thunkpos= yythunkpos137; - } if (!yymatchChar(G, 'x')) goto l135; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l135; - l138:; - { int yypos139= G->pos, yythunkpos139= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l139; goto l138; - l139:; G->pos= yypos139; G->thunkpos= yythunkpos139; - } - yyprintf((stderr, " ok %s @ %s\n", "ImageSizeComplete", G->buf+G->pos)); - return 1; - l135:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ImageSizeComplete", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TitleDoubleExt(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TitleDoubleExt")); if (!yymatchChar(G, '"')) goto l140; - l141:; - { int yypos142= G->pos, yythunkpos142= G->thunkpos; - { int yypos143= G->pos, yythunkpos143= G->thunkpos; - { int yypos144= G->pos, yythunkpos144= G->thunkpos; if (!yymatchChar(G, '"')) goto l145; goto l144; - l145:; G->pos= yypos144; G->thunkpos= yythunkpos144; if (!yy_Newline(G)) { goto l143; } - } - l144:; goto l142; - l143:; G->pos= yypos143; G->thunkpos= yythunkpos143; - } if (!yymatchDot(G)) goto l142; goto l141; - l142:; G->pos= yypos142; G->thunkpos= yythunkpos142; - } if (!yymatchChar(G, '"')) goto l140; - yyprintf((stderr, " ok %s @ %s\n", "TitleDoubleExt", G->buf+G->pos)); - return 1; - l140:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TitleDoubleExt", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TitleSingleExt(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TitleSingleExt")); if (!yymatchChar(G, '\'')) goto l146; - l147:; - { int yypos148= G->pos, yythunkpos148= G->thunkpos; - { int yypos149= G->pos, yythunkpos149= G->thunkpos; - { int yypos150= G->pos, yythunkpos150= G->thunkpos; if (!yymatchChar(G, '\'')) goto l151; goto l150; - l151:; G->pos= yypos150; G->thunkpos= yythunkpos150; if (!yy_Newline(G)) { goto l149; } - } - l150:; goto l148; - l149:; G->pos= yypos149; G->thunkpos= yythunkpos149; - } if (!yymatchDot(G)) goto l148; goto l147; - l148:; G->pos= yypos148; G->thunkpos= yythunkpos148; - } if (!yymatchChar(G, '\'')) goto l146; - yyprintf((stderr, " ok %s @ %s\n", "TitleSingleExt", G->buf+G->pos)); - return 1; - l146:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TitleSingleExt", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TitleDouble(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TitleDouble")); if (!yymatchChar(G, '"')) goto l152; - l153:; - { int yypos154= G->pos, yythunkpos154= G->thunkpos; - { int yypos155= G->pos, yythunkpos155= G->thunkpos; if (!yymatchChar(G, '"')) goto l155; if (!yy_Sp(G)) { goto l155; } - { int yypos156= G->pos, yythunkpos156= G->thunkpos; if (!yymatchChar(G, ')')) goto l157; goto l156; - l157:; G->pos= yypos156; G->thunkpos= yythunkpos156; if (!yy_Newline(G)) { goto l155; } - } - l156:; goto l154; - l155:; G->pos= yypos155; G->thunkpos= yythunkpos155; - } if (!yymatchDot(G)) goto l154; goto l153; - l154:; G->pos= yypos154; G->thunkpos= yythunkpos154; - } if (!yymatchChar(G, '"')) goto l152; - yyprintf((stderr, " ok %s @ %s\n", "TitleDouble", G->buf+G->pos)); - return 1; - l152:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TitleDouble", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TitleSingle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TitleSingle")); if (!yymatchChar(G, '\'')) goto l158; - l159:; - { int yypos160= G->pos, yythunkpos160= G->thunkpos; - { int yypos161= G->pos, yythunkpos161= G->thunkpos; if (!yymatchChar(G, '\'')) goto l161; if (!yy_Sp(G)) { goto l161; } - { int yypos162= G->pos, yythunkpos162= G->thunkpos; if (!yymatchChar(G, ')')) goto l163; goto l162; - l163:; G->pos= yypos162; G->thunkpos= yythunkpos162; if (!yy_Newline(G)) { goto l161; } - } - l162:; goto l160; - l161:; G->pos= yypos161; G->thunkpos= yythunkpos161; - } if (!yymatchDot(G)) goto l160; goto l159; - l160:; G->pos= yypos160; G->thunkpos= yythunkpos160; - } if (!yymatchChar(G, '\'')) goto l158; - yyprintf((stderr, " ok %s @ %s\n", "TitleSingle", G->buf+G->pos)); - return 1; - l158:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TitleSingle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SourceContents(GREG *G) -{ - yyprintf((stderr, "%s\n", "SourceContents")); - l165:; - { int yypos166= G->pos, yythunkpos166= G->thunkpos; - { int yypos167= G->pos, yythunkpos167= G->thunkpos; - { int yypos171= G->pos, yythunkpos171= G->thunkpos; if (!yymatchChar(G, '(')) goto l171; goto l168; - l171:; G->pos= yypos171; G->thunkpos= yythunkpos171; - } - { int yypos172= G->pos, yythunkpos172= G->thunkpos; if (!yymatchChar(G, ')')) goto l172; goto l168; - l172:; G->pos= yypos172; G->thunkpos= yythunkpos172; - } - { int yypos173= G->pos, yythunkpos173= G->thunkpos; if (!yymatchChar(G, '>')) goto l173; goto l168; - l173:; G->pos= yypos173; G->thunkpos= yythunkpos173; - } if (!yy_Nonspacechar(G)) { goto l168; } - l169:; - { int yypos170= G->pos, yythunkpos170= G->thunkpos; - { int yypos174= G->pos, yythunkpos174= G->thunkpos; if (!yymatchChar(G, '(')) goto l174; goto l170; - l174:; G->pos= yypos174; G->thunkpos= yythunkpos174; - } - { int yypos175= G->pos, yythunkpos175= G->thunkpos; if (!yymatchChar(G, ')')) goto l175; goto l170; - l175:; G->pos= yypos175; G->thunkpos= yythunkpos175; - } - { int yypos176= G->pos, yythunkpos176= G->thunkpos; if (!yymatchChar(G, '>')) goto l176; goto l170; - l176:; G->pos= yypos176; G->thunkpos= yythunkpos176; - } if (!yy_Nonspacechar(G)) { goto l170; } goto l169; - l170:; G->pos= yypos170; G->thunkpos= yythunkpos170; - } goto l167; - l168:; G->pos= yypos167; G->thunkpos= yythunkpos167; if (!yymatchChar(G, '(')) goto l166; if (!yy_SourceContents(G)) { goto l166; } if (!yymatchChar(G, ')')) goto l166; - } - l167:; goto l165; - l166:; G->pos= yypos166; G->thunkpos= yythunkpos166; - } - yyprintf((stderr, " ok %s @ %s\n", "SourceContents", G->buf+G->pos)); - return 1; -} -YY_RULE(int) yy_ImageSize(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ImageSize")); - { int yypos178= G->pos, yythunkpos178= G->thunkpos; if (!yy_ImageSizeComplete(G)) { goto l179; } goto l178; - l179:; G->pos= yypos178; G->thunkpos= yythunkpos178; if (!yy_ImageSizeWidth(G)) { goto l180; } goto l178; - l180:; G->pos= yypos178; G->thunkpos= yythunkpos178; if (!yy_ImageSizeHeight(G)) { goto l181; } goto l178; - l181:; G->pos= yypos178; G->thunkpos= yythunkpos178; if (!yymatchString(G, "")) goto l177; - } - l178:; - yyprintf((stderr, " ok %s @ %s\n", "ImageSize", G->buf+G->pos)); - return 1; - l177:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ImageSize", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TitleExt(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TitleExt")); - { int yypos183= G->pos, yythunkpos183= G->thunkpos; if (!yy_TitleSingleExt(G)) { goto l184; } goto l183; - l184:; G->pos= yypos183; G->thunkpos= yythunkpos183; if (!yy_TitleDoubleExt(G)) { goto l185; } goto l183; - l185:; G->pos= yypos183; G->thunkpos= yythunkpos183; if (!yymatchString(G, "")) goto l182; - } - l183:; - yyprintf((stderr, " ok %s @ %s\n", "TitleExt", G->buf+G->pos)); - return 1; - l182:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TitleExt", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Title(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Title")); - { int yypos187= G->pos, yythunkpos187= G->thunkpos; if (!yy_TitleSingle(G)) { goto l188; } goto l187; - l188:; G->pos= yypos187; G->thunkpos= yythunkpos187; if (!yy_TitleDouble(G)) { goto l189; } goto l187; - l189:; G->pos= yypos187; G->thunkpos= yythunkpos187; if (!yymatchString(G, "")) goto l186; - } - l187:; - yyprintf((stderr, " ok %s @ %s\n", "Title", G->buf+G->pos)); - return 1; - l186:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Title", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Source(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Source")); yyDo(G, yy_1_Source, G->begin, G->end); - { int yypos191= G->pos, yythunkpos191= G->thunkpos; if (!yymatchChar(G, '<')) goto l192; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l192; if (!yy_SourceContents(G)) { goto l192; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l192; yyDo(G, yy_2_Source, G->begin, G->end); if (!yymatchChar(G, '>')) goto l192; goto l191; - l192:; G->pos= yypos191; G->thunkpos= yythunkpos191; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l190; if (!yy_SourceContents(G)) { goto l190; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l190; yyDo(G, yy_3_Source, G->begin, G->end); - } - l191:; - yyprintf((stderr, " ok %s @ %s\n", "Source", G->buf+G->pos)); - return 1; - l190:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Source", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Label(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Label")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l193; if (!yy_LocMarker(G)) { goto l193; } yyDo(G, yySet, -1, 0); if (!yymatchChar(G, '[')) goto l193; - { int yypos194= G->pos, yythunkpos194= G->thunkpos; - { int yypos196= G->pos, yythunkpos196= G->thunkpos; if (!yymatchChar(G, '^')) goto l196; goto l195; - l196:; G->pos= yypos196; G->thunkpos= yythunkpos196; - } yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l195; goto l194; - l195:; G->pos= yypos194; G->thunkpos= yythunkpos194; - { int yypos197= G->pos, yythunkpos197= G->thunkpos; if (!yymatchDot(G)) goto l193; G->pos= yypos197; G->thunkpos= yythunkpos197; - } yyText(G, G->begin, G->end); if (!( !EXT(pmh_EXT_NOTES) )) goto l193; - } - l194:; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l193; - l198:; - { int yypos199= G->pos, yythunkpos199= G->thunkpos; - { int yypos200= G->pos, yythunkpos200= G->thunkpos; if (!yymatchChar(G, ']')) goto l200; goto l199; - l200:; G->pos= yypos200; G->thunkpos= yythunkpos200; - } - { int yypos201= G->pos, yythunkpos201= G->thunkpos; if (!yymatchChar(G, '[')) goto l201; goto l199; - l201:; G->pos= yypos201; G->thunkpos= yythunkpos201; - } if (!yy_LabelInline(G)) { goto l199; } goto l198; - l199:; G->pos= yypos199; G->thunkpos= yythunkpos199; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l193; yyDo(G, yy_1_Label, G->begin, G->end); if (!yymatchChar(G, ']')) goto l193; yyText(G, G->begin, G->end); if (!(YY_END)) goto l193; yyDo(G, yy_2_Label, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Label", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l193:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Label", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ReferenceLinkSingle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ReferenceLinkSingle")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l202; if (!yy_Label(G)) { goto l202; } yyDo(G, yySet, -1, 0); - { int yypos203= G->pos, yythunkpos203= G->thunkpos; if (!yy_Spnl(G)) { goto l203; } if (!yymatchString(G, "[]")) goto l203; goto l204; - l203:; G->pos= yypos203; G->thunkpos= yythunkpos203; - } - l204:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l202; yyDo(G, yy_1_ReferenceLinkSingle, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ReferenceLinkSingle", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l202:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ReferenceLinkSingle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ReferenceLinkDouble(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 2, 0); - yyprintf((stderr, "%s\n", "ReferenceLinkDouble")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l205; if (!yy_Label(G)) { goto l205; } yyDo(G, yySet, -2, 0); if (!yy_Spnl(G)) { goto l205; } - { int yypos206= G->pos, yythunkpos206= G->thunkpos; if (!yymatchString(G, "[]")) goto l206; goto l205; - l206:; G->pos= yypos206; G->thunkpos= yythunkpos206; - } if (!yy_Label(G)) { goto l205; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_END)) goto l205; yyDo(G, yy_1_ReferenceLinkDouble, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ReferenceLinkDouble", G->buf+G->pos)); yyDo(G, yyPop, 2, 0); - return 1; - l205:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ReferenceLinkDouble", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AutoLink(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "AutoLink")); - { int yypos208= G->pos, yythunkpos208= G->thunkpos; if (!yy_AutoLinkUrl(G)) { goto l209; } goto l208; - l209:; G->pos= yypos208; G->thunkpos= yythunkpos208; if (!yy_AutoLinkEmail(G)) { goto l207; } - } - l208:; - yyprintf((stderr, " ok %s @ %s\n", "AutoLink", G->buf+G->pos)); - return 1; - l207:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AutoLink", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ReferenceLink(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ReferenceLink")); - { int yypos211= G->pos, yythunkpos211= G->thunkpos; if (!yy_ReferenceLinkDouble(G)) { goto l212; } goto l211; - l212:; G->pos= yypos211; G->thunkpos= yythunkpos211; if (!yy_ReferenceLinkSingle(G)) { goto l210; } - } - l211:; - yyprintf((stderr, " ok %s @ %s\n", "ReferenceLink", G->buf+G->pos)); - return 1; - l210:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ReferenceLink", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ExplicitLinkSize(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 2, 0); - yyprintf((stderr, "%s\n", "ExplicitLinkSize")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l213; if (!yy_Label(G)) { goto l213; } yyDo(G, yySet, -2, 0); if (!yy_Spnl(G)) { goto l213; } if (!yymatchChar(G, '(')) goto l213; if (!yy_Sp(G)) { goto l213; } if (!yy_Source(G)) { goto l213; } yyDo(G, yySet, -1, 0); if (!yy_Spnl(G)) { goto l213; } if (!yy_TitleExt(G)) { goto l213; } if (!yy_Sp(G)) { goto l213; } if (!yy_ImageSize(G)) { goto l213; } if (!yy_Sp(G)) { goto l213; } if (!yymatchChar(G, ')')) goto l213; yyText(G, G->begin, G->end); if (!(YY_END)) goto l213; yyDo(G, yy_1_ExplicitLinkSize, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ExplicitLinkSize", G->buf+G->pos)); yyDo(G, yyPop, 2, 0); - return 1; - l213:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ExplicitLinkSize", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ExplicitLink(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 2, 0); - yyprintf((stderr, "%s\n", "ExplicitLink")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l214; if (!yy_Label(G)) { goto l214; } yyDo(G, yySet, -2, 0); if (!yy_Spnl(G)) { goto l214; } if (!yymatchChar(G, '(')) goto l214; if (!yy_Sp(G)) { goto l214; } if (!yy_Source(G)) { goto l214; } yyDo(G, yySet, -1, 0); if (!yy_Spnl(G)) { goto l214; } if (!yy_Title(G)) { goto l214; } if (!yy_Sp(G)) { goto l214; } if (!yymatchChar(G, ')')) goto l214; yyText(G, G->begin, G->end); if (!(YY_END)) goto l214; yyDo(G, yy_1_ExplicitLink, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ExplicitLink", G->buf+G->pos)); yyDo(G, yyPop, 2, 0); - return 1; - l214:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ExplicitLink", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StrongUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "StrongUl")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l215; if (!yy_LocMarker(G)) { goto l215; } yyDo(G, yySet, -1, 0); if (!yymatchString(G, "__")) goto l215; - { int yypos216= G->pos, yythunkpos216= G->thunkpos; if (!yy_Whitespace(G)) { goto l216; } goto l215; - l216:; G->pos= yypos216; G->thunkpos= yythunkpos216; - } - { int yypos219= G->pos, yythunkpos219= G->thunkpos; if (!yymatchString(G, "__")) goto l219; goto l215; - l219:; G->pos= yypos219; G->thunkpos= yythunkpos219; - } if (!yy_Inline(G)) { goto l215; } - l217:; - { int yypos218= G->pos, yythunkpos218= G->thunkpos; - { int yypos220= G->pos, yythunkpos220= G->thunkpos; if (!yymatchString(G, "__")) goto l220; goto l218; - l220:; G->pos= yypos220; G->thunkpos= yythunkpos220; - } if (!yy_Inline(G)) { goto l218; } goto l217; - l218:; G->pos= yypos218; G->thunkpos= yythunkpos218; - } if (!yymatchString(G, "__")) goto l215; yyText(G, G->begin, G->end); if (!(YY_END)) goto l215; yyDo(G, yy_1_StrongUl, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "StrongUl", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l215:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StrongUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StrongStar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "StrongStar")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l221; if (!yy_LocMarker(G)) { goto l221; } yyDo(G, yySet, -1, 0); if (!yymatchString(G, "**")) goto l221; - { int yypos222= G->pos, yythunkpos222= G->thunkpos; if (!yy_Whitespace(G)) { goto l222; } goto l221; - l222:; G->pos= yypos222; G->thunkpos= yythunkpos222; - } - { int yypos225= G->pos, yythunkpos225= G->thunkpos; if (!yymatchString(G, "**")) goto l225; goto l221; - l225:; G->pos= yypos225; G->thunkpos= yythunkpos225; - } if (!yy_Inline(G)) { goto l221; } - l223:; - { int yypos224= G->pos, yythunkpos224= G->thunkpos; - { int yypos226= G->pos, yythunkpos226= G->thunkpos; if (!yymatchString(G, "**")) goto l226; goto l224; - l226:; G->pos= yypos226; G->thunkpos= yythunkpos226; - } if (!yy_Inline(G)) { goto l224; } goto l223; - l224:; G->pos= yypos224; G->thunkpos= yythunkpos224; - } if (!yymatchString(G, "**")) goto l221; yyText(G, G->begin, G->end); if (!(YY_END)) goto l221; yyDo(G, yy_1_StrongStar, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "StrongStar", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l221:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StrongStar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Whitespace(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Whitespace")); - { int yypos228= G->pos, yythunkpos228= G->thunkpos; if (!yy_Spacechar(G)) { goto l229; } goto l228; - l229:; G->pos= yypos228; G->thunkpos= yythunkpos228; if (!yy_Newline(G)) { goto l227; } - } - l228:; - yyprintf((stderr, " ok %s @ %s\n", "Whitespace", G->buf+G->pos)); - return 1; - l227:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Whitespace", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_EmphUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "EmphUl")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l230; if (!yy_LocMarker(G)) { goto l230; } yyDo(G, yySet, -1, 0); if (!yymatchChar(G, '_')) goto l230; - { int yypos231= G->pos, yythunkpos231= G->thunkpos; if (!yy_Whitespace(G)) { goto l231; } goto l230; - l231:; G->pos= yypos231; G->thunkpos= yythunkpos231; - } - { int yypos234= G->pos, yythunkpos234= G->thunkpos; - { int yypos236= G->pos, yythunkpos236= G->thunkpos; if (!yymatchChar(G, '_')) goto l236; goto l235; - l236:; G->pos= yypos236; G->thunkpos= yythunkpos236; - } if (!yy_Inline(G)) { goto l235; } goto l234; - l235:; G->pos= yypos234; G->thunkpos= yythunkpos234; if (!yy_StrongUl(G)) { goto l230; } - } - l234:; - l232:; - { int yypos233= G->pos, yythunkpos233= G->thunkpos; - { int yypos237= G->pos, yythunkpos237= G->thunkpos; - { int yypos239= G->pos, yythunkpos239= G->thunkpos; if (!yymatchChar(G, '_')) goto l239; goto l238; - l239:; G->pos= yypos239; G->thunkpos= yythunkpos239; - } if (!yy_Inline(G)) { goto l238; } goto l237; - l238:; G->pos= yypos237; G->thunkpos= yythunkpos237; if (!yy_StrongUl(G)) { goto l233; } - } - l237:; goto l232; - l233:; G->pos= yypos233; G->thunkpos= yythunkpos233; - } if (!yymatchChar(G, '_')) goto l230; yyText(G, G->begin, G->end); if (!(YY_END)) goto l230; yyDo(G, yy_1_EmphUl, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "EmphUl", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l230:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "EmphUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_EmphStar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "EmphStar")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l240; if (!yy_LocMarker(G)) { goto l240; } yyDo(G, yySet, -1, 0); if (!yymatchChar(G, '*')) goto l240; - { int yypos241= G->pos, yythunkpos241= G->thunkpos; if (!yy_Whitespace(G)) { goto l241; } goto l240; - l241:; G->pos= yypos241; G->thunkpos= yythunkpos241; - } - { int yypos244= G->pos, yythunkpos244= G->thunkpos; - { int yypos246= G->pos, yythunkpos246= G->thunkpos; if (!yymatchChar(G, '*')) goto l246; goto l245; - l246:; G->pos= yypos246; G->thunkpos= yythunkpos246; - } if (!yy_Inline(G)) { goto l245; } goto l244; - l245:; G->pos= yypos244; G->thunkpos= yythunkpos244; if (!yy_StrongStar(G)) { goto l240; } - } - l244:; - l242:; - { int yypos243= G->pos, yythunkpos243= G->thunkpos; - { int yypos247= G->pos, yythunkpos247= G->thunkpos; - { int yypos249= G->pos, yythunkpos249= G->thunkpos; if (!yymatchChar(G, '*')) goto l249; goto l248; - l249:; G->pos= yypos249; G->thunkpos= yythunkpos249; - } if (!yy_Inline(G)) { goto l248; } goto l247; - l248:; G->pos= yypos247; G->thunkpos= yythunkpos247; if (!yy_StrongStar(G)) { goto l243; } - } - l247:; goto l242; - l243:; G->pos= yypos243; G->thunkpos= yythunkpos243; - } if (!yymatchChar(G, '*')) goto l240; yyText(G, G->begin, G->end); if (!(YY_END)) goto l240; yyDo(G, yy_1_EmphStar, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "EmphStar", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l240:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "EmphStar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StarLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "StarLine")); - { int yypos251= G->pos, yythunkpos251= G->thunkpos; if (!yymatchString(G, "****")) goto l252; - l253:; - { int yypos254= G->pos, yythunkpos254= G->thunkpos; if (!yymatchChar(G, '*')) goto l254; goto l253; - l254:; G->pos= yypos254; G->thunkpos= yythunkpos254; - } goto l251; - l252:; G->pos= yypos251; G->thunkpos= yythunkpos251; if (!yy_Spacechar(G)) { goto l250; } if (!yymatchChar(G, '*')) goto l250; - l255:; - { int yypos256= G->pos, yythunkpos256= G->thunkpos; if (!yymatchChar(G, '*')) goto l256; goto l255; - l256:; G->pos= yypos256; G->thunkpos= yythunkpos256; - } - { int yypos257= G->pos, yythunkpos257= G->thunkpos; if (!yy_Spacechar(G)) { goto l250; } G->pos= yypos257; G->thunkpos= yythunkpos257; - } - } - l251:; - yyprintf((stderr, " ok %s @ %s\n", "StarLine", G->buf+G->pos)); - return 1; - l250:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StarLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_UlLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "UlLine")); - { int yypos259= G->pos, yythunkpos259= G->thunkpos; if (!yymatchString(G, "____")) goto l260; - l261:; - { int yypos262= G->pos, yythunkpos262= G->thunkpos; if (!yymatchChar(G, '_')) goto l262; goto l261; - l262:; G->pos= yypos262; G->thunkpos= yythunkpos262; - } goto l259; - l260:; G->pos= yypos259; G->thunkpos= yythunkpos259; if (!yy_Spacechar(G)) { goto l258; } if (!yymatchChar(G, '_')) goto l258; - l263:; - { int yypos264= G->pos, yythunkpos264= G->thunkpos; if (!yymatchChar(G, '_')) goto l264; goto l263; - l264:; G->pos= yypos264; G->thunkpos= yythunkpos264; - } - { int yypos265= G->pos, yythunkpos265= G->thunkpos; if (!yy_Spacechar(G)) { goto l258; } G->pos= yypos265; G->thunkpos= yythunkpos265; - } - } - l259:; - yyprintf((stderr, " ok %s @ %s\n", "UlLine", G->buf+G->pos)); - return 1; - l258:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "UlLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SpecialChar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SpecialChar")); - { int yypos267= G->pos, yythunkpos267= G->thunkpos; if (!yymatchChar(G, '~')) goto l268; goto l267; - l268:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '*')) goto l269; goto l267; - l269:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '_')) goto l270; goto l267; - l270:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '`')) goto l271; goto l267; - l271:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '&')) goto l272; goto l267; - l272:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '[')) goto l273; goto l267; - l273:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, ']')) goto l274; goto l267; - l274:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '(')) goto l275; goto l267; - l275:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, ')')) goto l276; goto l267; - l276:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '<')) goto l277; goto l267; - l277:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '!')) goto l278; goto l267; - l278:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '#')) goto l279; goto l267; - l279:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '\\')) goto l280; goto l267; - l280:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '\'')) goto l281; goto l267; - l281:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yymatchChar(G, '"')) goto l282; goto l267; - l282:; G->pos= yypos267; G->thunkpos= yythunkpos267; if (!yy_ExtendedSpecialChar(G)) { goto l266; } - } - l267:; - yyprintf((stderr, " ok %s @ %s\n", "SpecialChar", G->buf+G->pos)); - return 1; - l266:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SpecialChar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Eof(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Eof")); - { int yypos284= G->pos, yythunkpos284= G->thunkpos; if (!yymatchDot(G)) goto l284; goto l283; - l284:; G->pos= yypos284; G->thunkpos= yythunkpos284; - } - yyprintf((stderr, " ok %s @ %s\n", "Eof", G->buf+G->pos)); - return 1; - l283:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Eof", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NormalEndline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NormalEndline")); if (!yy_Sp(G)) { goto l285; } if (!yy_Newline(G)) { goto l285; } - { int yypos286= G->pos, yythunkpos286= G->thunkpos; if (!yy_BlankLine(G)) { goto l286; } goto l285; - l286:; G->pos= yypos286; G->thunkpos= yythunkpos286; - } - { int yypos287= G->pos, yythunkpos287= G->thunkpos; if (!yymatchChar(G, '>')) goto l287; goto l285; - l287:; G->pos= yypos287; G->thunkpos= yythunkpos287; - } - { int yypos288= G->pos, yythunkpos288= G->thunkpos; if (!yy_AtxStart(G)) { goto l288; } goto l285; - l288:; G->pos= yypos288; G->thunkpos= yythunkpos288; - } - { int yypos289= G->pos, yythunkpos289= G->thunkpos; if (!yy_Line(G)) { goto l289; } - { int yypos290= G->pos, yythunkpos290= G->thunkpos; if (!yymatchChar(G, '=')) goto l291; - l292:; - { int yypos293= G->pos, yythunkpos293= G->thunkpos; if (!yymatchChar(G, '=')) goto l293; goto l292; - l293:; G->pos= yypos293; G->thunkpos= yythunkpos293; - } goto l290; - l291:; G->pos= yypos290; G->thunkpos= yythunkpos290; if (!yymatchChar(G, '-')) goto l289; - l294:; - { int yypos295= G->pos, yythunkpos295= G->thunkpos; if (!yymatchChar(G, '-')) goto l295; goto l294; - l295:; G->pos= yypos295; G->thunkpos= yythunkpos295; - } - } - l290:; if (!yy_Newline(G)) { goto l289; } goto l285; - l289:; G->pos= yypos289; G->thunkpos= yythunkpos289; - } - { int yypos296= G->pos, yythunkpos296= G->thunkpos; if (!yy_FencedCodeBlockStartTick(G)) { goto l296; } goto l285; - l296:; G->pos= yypos296; G->thunkpos= yythunkpos296; - } - { int yypos297= G->pos, yythunkpos297= G->thunkpos; if (!yy_FencedCodeBlockStartTidle(G)) { goto l297; } goto l285; - l297:; G->pos= yypos297; G->thunkpos= yythunkpos297; - } - yyprintf((stderr, " ok %s @ %s\n", "NormalEndline", G->buf+G->pos)); - return 1; - l285:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NormalEndline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TerminalEndline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TerminalEndline")); if (!yy_Sp(G)) { goto l298; } if (!yy_Newline(G)) { goto l298; } if (!yy_Eof(G)) { goto l298; } - yyprintf((stderr, " ok %s @ %s\n", "TerminalEndline", G->buf+G->pos)); - return 1; - l298:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TerminalEndline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_LineBreak(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "LineBreak")); if (!yymatchString(G, " ")) goto l299; if (!yy_NormalEndline(G)) { goto l299; } - yyprintf((stderr, " ok %s @ %s\n", "LineBreak", G->buf+G->pos)); - return 1; - l299:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "LineBreak", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_CharEntity(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "CharEntity")); if (!yymatchChar(G, '&')) goto l300; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l300; - l301:; - { int yypos302= G->pos, yythunkpos302= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l302; goto l301; - l302:; G->pos= yypos302; G->thunkpos= yythunkpos302; - } if (!yymatchChar(G, ';')) goto l300; - yyprintf((stderr, " ok %s @ %s\n", "CharEntity", G->buf+G->pos)); - return 1; - l300:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "CharEntity", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_DecEntity(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "DecEntity")); if (!yymatchChar(G, '&')) goto l303; if (!yymatchChar(G, '#')) goto l303; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l303; - l304:; - { int yypos305= G->pos, yythunkpos305= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l305; goto l304; - l305:; G->pos= yypos305; G->thunkpos= yythunkpos305; - } if (!yymatchChar(G, ';')) goto l303; - yyprintf((stderr, " ok %s @ %s\n", "DecEntity", G->buf+G->pos)); - return 1; - l303:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "DecEntity", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HexEntity(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HexEntity")); if (!yymatchChar(G, '&')) goto l306; if (!yymatchChar(G, '#')) goto l306; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l306; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l306; - l307:; - { int yypos308= G->pos, yythunkpos308= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l308; goto l307; - l308:; G->pos= yypos308; G->thunkpos= yythunkpos308; - } if (!yymatchChar(G, ';')) goto l306; - yyprintf((stderr, " ok %s @ %s\n", "HexEntity", G->buf+G->pos)); - return 1; - l306:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HexEntity", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ExtendedSpecialChar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ExtendedSpecialChar")); - { int yypos310= G->pos, yythunkpos310= G->thunkpos; yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l311; if (!yymatchChar(G, '^')) goto l311; goto l310; - l311:; G->pos= yypos310; G->thunkpos= yythunkpos310; yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_MATH) )) goto l312; if (!yymatchChar(G, '$')) goto l312; goto l310; - l312:; G->pos= yypos310; G->thunkpos= yythunkpos310; yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_TABLE) )) goto l309; if (!yymatchChar(G, '|')) goto l309; - } - l310:; - yyprintf((stderr, " ok %s @ %s\n", "ExtendedSpecialChar", G->buf+G->pos)); - return 1; - l309:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ExtendedSpecialChar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Alphanumeric(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Alphanumeric")); - { int yypos314= G->pos, yythunkpos314= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l315; goto l314; - l315:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\200")) goto l316; goto l314; - l316:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\201")) goto l317; goto l314; - l317:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\202")) goto l318; goto l314; - l318:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\203")) goto l319; goto l314; - l319:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\204")) goto l320; goto l314; - l320:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\205")) goto l321; goto l314; - l321:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\206")) goto l322; goto l314; - l322:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\207")) goto l323; goto l314; - l323:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\210")) goto l324; goto l314; - l324:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\211")) goto l325; goto l314; - l325:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\212")) goto l326; goto l314; - l326:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\213")) goto l327; goto l314; - l327:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\214")) goto l328; goto l314; - l328:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\215")) goto l329; goto l314; - l329:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\216")) goto l330; goto l314; - l330:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\217")) goto l331; goto l314; - l331:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\220")) goto l332; goto l314; - l332:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\221")) goto l333; goto l314; - l333:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\222")) goto l334; goto l314; - l334:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\223")) goto l335; goto l314; - l335:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\224")) goto l336; goto l314; - l336:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\225")) goto l337; goto l314; - l337:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\226")) goto l338; goto l314; - l338:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\227")) goto l339; goto l314; - l339:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\230")) goto l340; goto l314; - l340:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\231")) goto l341; goto l314; - l341:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\232")) goto l342; goto l314; - l342:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\233")) goto l343; goto l314; - l343:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\234")) goto l344; goto l314; - l344:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\235")) goto l345; goto l314; - l345:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\236")) goto l346; goto l314; - l346:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\237")) goto l347; goto l314; - l347:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\240")) goto l348; goto l314; - l348:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\241")) goto l349; goto l314; - l349:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\242")) goto l350; goto l314; - l350:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\243")) goto l351; goto l314; - l351:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\244")) goto l352; goto l314; - l352:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\245")) goto l353; goto l314; - l353:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\246")) goto l354; goto l314; - l354:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\247")) goto l355; goto l314; - l355:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\250")) goto l356; goto l314; - l356:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\251")) goto l357; goto l314; - l357:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\252")) goto l358; goto l314; - l358:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\253")) goto l359; goto l314; - l359:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\254")) goto l360; goto l314; - l360:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\255")) goto l361; goto l314; - l361:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\256")) goto l362; goto l314; - l362:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\257")) goto l363; goto l314; - l363:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\260")) goto l364; goto l314; - l364:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\261")) goto l365; goto l314; - l365:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\262")) goto l366; goto l314; - l366:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\263")) goto l367; goto l314; - l367:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\264")) goto l368; goto l314; - l368:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\265")) goto l369; goto l314; - l369:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\266")) goto l370; goto l314; - l370:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\267")) goto l371; goto l314; - l371:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\270")) goto l372; goto l314; - l372:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\271")) goto l373; goto l314; - l373:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\272")) goto l374; goto l314; - l374:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\273")) goto l375; goto l314; - l375:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\274")) goto l376; goto l314; - l376:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\275")) goto l377; goto l314; - l377:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\276")) goto l378; goto l314; - l378:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\277")) goto l379; goto l314; - l379:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\300")) goto l380; goto l314; - l380:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\301")) goto l381; goto l314; - l381:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\302")) goto l382; goto l314; - l382:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\303")) goto l383; goto l314; - l383:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\304")) goto l384; goto l314; - l384:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\305")) goto l385; goto l314; - l385:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\306")) goto l386; goto l314; - l386:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\307")) goto l387; goto l314; - l387:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\310")) goto l388; goto l314; - l388:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\311")) goto l389; goto l314; - l389:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\312")) goto l390; goto l314; - l390:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\313")) goto l391; goto l314; - l391:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\314")) goto l392; goto l314; - l392:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\315")) goto l393; goto l314; - l393:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\316")) goto l394; goto l314; - l394:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\317")) goto l395; goto l314; - l395:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\320")) goto l396; goto l314; - l396:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\321")) goto l397; goto l314; - l397:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\322")) goto l398; goto l314; - l398:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\323")) goto l399; goto l314; - l399:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\324")) goto l400; goto l314; - l400:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\325")) goto l401; goto l314; - l401:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\326")) goto l402; goto l314; - l402:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\327")) goto l403; goto l314; - l403:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\330")) goto l404; goto l314; - l404:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\331")) goto l405; goto l314; - l405:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\332")) goto l406; goto l314; - l406:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\333")) goto l407; goto l314; - l407:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\334")) goto l408; goto l314; - l408:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\335")) goto l409; goto l314; - l409:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\336")) goto l410; goto l314; - l410:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\337")) goto l411; goto l314; - l411:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\340")) goto l412; goto l314; - l412:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\341")) goto l413; goto l314; - l413:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\342")) goto l414; goto l314; - l414:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\343")) goto l415; goto l314; - l415:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\344")) goto l416; goto l314; - l416:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\345")) goto l417; goto l314; - l417:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\346")) goto l418; goto l314; - l418:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\347")) goto l419; goto l314; - l419:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\350")) goto l420; goto l314; - l420:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\351")) goto l421; goto l314; - l421:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\352")) goto l422; goto l314; - l422:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\353")) goto l423; goto l314; - l423:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\354")) goto l424; goto l314; - l424:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\355")) goto l425; goto l314; - l425:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\356")) goto l426; goto l314; - l426:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\357")) goto l427; goto l314; - l427:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\360")) goto l428; goto l314; - l428:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\361")) goto l429; goto l314; - l429:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\362")) goto l430; goto l314; - l430:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\363")) goto l431; goto l314; - l431:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\364")) goto l432; goto l314; - l432:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\365")) goto l433; goto l314; - l433:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\366")) goto l434; goto l314; - l434:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\367")) goto l435; goto l314; - l435:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\370")) goto l436; goto l314; - l436:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\371")) goto l437; goto l314; - l437:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\372")) goto l438; goto l314; - l438:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\373")) goto l439; goto l314; - l439:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\374")) goto l440; goto l314; - l440:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\375")) goto l441; goto l314; - l441:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\376")) goto l442; goto l314; - l442:; G->pos= yypos314; G->thunkpos= yythunkpos314; if (!yymatchString(G, "\377")) goto l313; - } - l314:; - yyprintf((stderr, " ok %s @ %s\n", "Alphanumeric", G->buf+G->pos)); - return 1; - l313:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Alphanumeric", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NormalChar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NormalChar")); - { int yypos444= G->pos, yythunkpos444= G->thunkpos; - { int yypos445= G->pos, yythunkpos445= G->thunkpos; if (!yy_SpecialChar(G)) { goto l446; } goto l445; - l446:; G->pos= yypos445; G->thunkpos= yythunkpos445; if (!yy_Spacechar(G)) { goto l447; } goto l445; - l447:; G->pos= yypos445; G->thunkpos= yythunkpos445; if (!yy_Newline(G)) { goto l444; } - } - l445:; goto l443; - l444:; G->pos= yypos444; G->thunkpos= yythunkpos444; - } if (!yymatchDot(G)) goto l443; - yyprintf((stderr, " ok %s @ %s\n", "NormalChar", G->buf+G->pos)); - return 1; - l443:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NormalChar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Symbol(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Symbol")); if (!yy_SpecialChar(G)) { goto l448; } - yyprintf((stderr, " ok %s @ %s\n", "Symbol", G->buf+G->pos)); - return 1; - l448:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Symbol", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_EscapedChar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "EscapedChar")); if (!yymatchChar(G, '\\')) goto l449; - { int yypos450= G->pos, yythunkpos450= G->thunkpos; if (!yy_Newline(G)) { goto l450; } goto l449; - l450:; G->pos= yypos450; G->thunkpos= yythunkpos450; - } - { int yypos451= G->pos, yythunkpos451= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\012\157\000\120\000\000\000\270\001\000\000\170\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l452; goto l451; - l452:; G->pos= yypos451; G->thunkpos= yythunkpos451; if (!yy_ExtendedSpecialChar(G)) { goto l449; } - } - l451:; - yyprintf((stderr, " ok %s @ %s\n", "EscapedChar", G->buf+G->pos)); - return 1; - l449:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "EscapedChar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Entity(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Entity")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l453; if (!yy_LocMarker(G)) { goto l453; } yyDo(G, yySet, -1, 0); - { int yypos454= G->pos, yythunkpos454= G->thunkpos; if (!yy_HexEntity(G)) { goto l455; } goto l454; - l455:; G->pos= yypos454; G->thunkpos= yythunkpos454; if (!yy_DecEntity(G)) { goto l456; } goto l454; - l456:; G->pos= yypos454; G->thunkpos= yythunkpos454; if (!yy_CharEntity(G)) { goto l453; } - } - l454:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l453; yyDo(G, yy_1_Entity, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Entity", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l453:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Entity", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RawHtml(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "RawHtml")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l457; if (!yy_LocMarker(G)) { goto l457; } yyDo(G, yySet, -1, 0); - { int yypos458= G->pos, yythunkpos458= G->thunkpos; if (!yy_HtmlComment(G)) { goto l459; } goto l458; - l459:; G->pos= yypos458; G->thunkpos= yythunkpos458; if (!yy_HtmlBlockScript(G)) { goto l460; } goto l458; - l460:; G->pos= yypos458; G->thunkpos= yythunkpos458; if (!yy_HtmlTag(G)) { goto l457; } - } - l458:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l457; yyDo(G, yy_1_RawHtml, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "RawHtml", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l457:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RawHtml", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Mark(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 2, 0); - yyprintf((stderr, "%s\n", "Mark")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_MARK) )) goto l461; if (!yy_MarkTagOpen(G)) { goto l461; } yyDo(G, yySet, -2, 0); if (!yy_MarkTagText(G)) { goto l461; } if (!yy_MarkTagClose(G)) { goto l461; } yyDo(G, yySet, -1, 0); yyDo(G, yy_1_Mark, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Mark", G->buf+G->pos)); yyDo(G, yyPop, 2, 0); - return 1; - l461:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Mark", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Code(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Code")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l462; - { int yypos463= G->pos, yythunkpos463= G->thunkpos; if (!yy_Ticks1(G)) { goto l464; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l464; } - { int yypos467= G->pos, yythunkpos467= G->thunkpos; - { int yypos471= G->pos, yythunkpos471= G->thunkpos; if (!yymatchChar(G, '`')) goto l471; goto l468; - l471:; G->pos= yypos471; G->thunkpos= yythunkpos471; - } if (!yy_Nonspacechar(G)) { goto l468; } - l469:; - { int yypos470= G->pos, yythunkpos470= G->thunkpos; - { int yypos472= G->pos, yythunkpos472= G->thunkpos; if (!yymatchChar(G, '`')) goto l472; goto l470; - l472:; G->pos= yypos472; G->thunkpos= yythunkpos472; - } if (!yy_Nonspacechar(G)) { goto l470; } goto l469; - l470:; G->pos= yypos470; G->thunkpos= yythunkpos470; - } goto l467; - l468:; G->pos= yypos467; G->thunkpos= yythunkpos467; - { int yypos474= G->pos, yythunkpos474= G->thunkpos; if (!yy_Ticks1(G)) { goto l474; } goto l473; - l474:; G->pos= yypos474; G->thunkpos= yythunkpos474; - } if (!yymatchChar(G, '`')) goto l473; - l475:; - { int yypos476= G->pos, yythunkpos476= G->thunkpos; if (!yymatchChar(G, '`')) goto l476; goto l475; - l476:; G->pos= yypos476; G->thunkpos= yythunkpos476; - } goto l467; - l473:; G->pos= yypos467; G->thunkpos= yythunkpos467; - { int yypos477= G->pos, yythunkpos477= G->thunkpos; if (!yy_Sp(G)) { goto l477; } if (!yy_Ticks1(G)) { goto l477; } goto l464; - l477:; G->pos= yypos477; G->thunkpos= yythunkpos477; - } - { int yypos478= G->pos, yythunkpos478= G->thunkpos; if (!yy_Spacechar(G)) { goto l479; } goto l478; - l479:; G->pos= yypos478; G->thunkpos= yythunkpos478; if (!yy_Newline(G)) { goto l464; } - { int yypos480= G->pos, yythunkpos480= G->thunkpos; if (!yy_BlankLine(G)) { goto l480; } goto l464; - l480:; G->pos= yypos480; G->thunkpos= yythunkpos480; - } - } - l478:; - } - l467:; - l465:; - { int yypos466= G->pos, yythunkpos466= G->thunkpos; - { int yypos481= G->pos, yythunkpos481= G->thunkpos; - { int yypos485= G->pos, yythunkpos485= G->thunkpos; if (!yymatchChar(G, '`')) goto l485; goto l482; - l485:; G->pos= yypos485; G->thunkpos= yythunkpos485; - } if (!yy_Nonspacechar(G)) { goto l482; } - l483:; - { int yypos484= G->pos, yythunkpos484= G->thunkpos; - { int yypos486= G->pos, yythunkpos486= G->thunkpos; if (!yymatchChar(G, '`')) goto l486; goto l484; - l486:; G->pos= yypos486; G->thunkpos= yythunkpos486; - } if (!yy_Nonspacechar(G)) { goto l484; } goto l483; - l484:; G->pos= yypos484; G->thunkpos= yythunkpos484; - } goto l481; - l482:; G->pos= yypos481; G->thunkpos= yythunkpos481; - { int yypos488= G->pos, yythunkpos488= G->thunkpos; if (!yy_Ticks1(G)) { goto l488; } goto l487; - l488:; G->pos= yypos488; G->thunkpos= yythunkpos488; - } if (!yymatchChar(G, '`')) goto l487; - l489:; - { int yypos490= G->pos, yythunkpos490= G->thunkpos; if (!yymatchChar(G, '`')) goto l490; goto l489; - l490:; G->pos= yypos490; G->thunkpos= yythunkpos490; - } goto l481; - l487:; G->pos= yypos481; G->thunkpos= yythunkpos481; - { int yypos491= G->pos, yythunkpos491= G->thunkpos; if (!yy_Sp(G)) { goto l491; } if (!yy_Ticks1(G)) { goto l491; } goto l466; - l491:; G->pos= yypos491; G->thunkpos= yythunkpos491; - } - { int yypos492= G->pos, yythunkpos492= G->thunkpos; if (!yy_Spacechar(G)) { goto l493; } goto l492; - l493:; G->pos= yypos492; G->thunkpos= yythunkpos492; if (!yy_Newline(G)) { goto l466; } - { int yypos494= G->pos, yythunkpos494= G->thunkpos; if (!yy_BlankLine(G)) { goto l494; } goto l466; - l494:; G->pos= yypos494; G->thunkpos= yythunkpos494; - } - } - l492:; - } - l481:; goto l465; - l466:; G->pos= yypos466; G->thunkpos= yythunkpos466; - } if (!yy_Sp(G)) { goto l464; } if (!yy_Ticks1(G)) { goto l464; } goto l463; - l464:; G->pos= yypos463; G->thunkpos= yythunkpos463; if (!yy_Ticks2(G)) { goto l495; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l495; } - { int yypos498= G->pos, yythunkpos498= G->thunkpos; - { int yypos502= G->pos, yythunkpos502= G->thunkpos; if (!yymatchChar(G, '`')) goto l502; goto l499; - l502:; G->pos= yypos502; G->thunkpos= yythunkpos502; - } if (!yy_Nonspacechar(G)) { goto l499; } - l500:; - { int yypos501= G->pos, yythunkpos501= G->thunkpos; - { int yypos503= G->pos, yythunkpos503= G->thunkpos; if (!yymatchChar(G, '`')) goto l503; goto l501; - l503:; G->pos= yypos503; G->thunkpos= yythunkpos503; - } if (!yy_Nonspacechar(G)) { goto l501; } goto l500; - l501:; G->pos= yypos501; G->thunkpos= yythunkpos501; - } goto l498; - l499:; G->pos= yypos498; G->thunkpos= yythunkpos498; - { int yypos505= G->pos, yythunkpos505= G->thunkpos; if (!yy_Ticks2(G)) { goto l505; } goto l504; - l505:; G->pos= yypos505; G->thunkpos= yythunkpos505; - } if (!yymatchChar(G, '`')) goto l504; - l506:; - { int yypos507= G->pos, yythunkpos507= G->thunkpos; if (!yymatchChar(G, '`')) goto l507; goto l506; - l507:; G->pos= yypos507; G->thunkpos= yythunkpos507; - } goto l498; - l504:; G->pos= yypos498; G->thunkpos= yythunkpos498; - { int yypos508= G->pos, yythunkpos508= G->thunkpos; if (!yy_Sp(G)) { goto l508; } if (!yy_Ticks2(G)) { goto l508; } goto l495; - l508:; G->pos= yypos508; G->thunkpos= yythunkpos508; - } - { int yypos509= G->pos, yythunkpos509= G->thunkpos; if (!yy_Spacechar(G)) { goto l510; } goto l509; - l510:; G->pos= yypos509; G->thunkpos= yythunkpos509; if (!yy_Newline(G)) { goto l495; } - { int yypos511= G->pos, yythunkpos511= G->thunkpos; if (!yy_BlankLine(G)) { goto l511; } goto l495; - l511:; G->pos= yypos511; G->thunkpos= yythunkpos511; - } - } - l509:; - } - l498:; - l496:; - { int yypos497= G->pos, yythunkpos497= G->thunkpos; - { int yypos512= G->pos, yythunkpos512= G->thunkpos; - { int yypos516= G->pos, yythunkpos516= G->thunkpos; if (!yymatchChar(G, '`')) goto l516; goto l513; - l516:; G->pos= yypos516; G->thunkpos= yythunkpos516; - } if (!yy_Nonspacechar(G)) { goto l513; } - l514:; - { int yypos515= G->pos, yythunkpos515= G->thunkpos; - { int yypos517= G->pos, yythunkpos517= G->thunkpos; if (!yymatchChar(G, '`')) goto l517; goto l515; - l517:; G->pos= yypos517; G->thunkpos= yythunkpos517; - } if (!yy_Nonspacechar(G)) { goto l515; } goto l514; - l515:; G->pos= yypos515; G->thunkpos= yythunkpos515; - } goto l512; - l513:; G->pos= yypos512; G->thunkpos= yythunkpos512; - { int yypos519= G->pos, yythunkpos519= G->thunkpos; if (!yy_Ticks2(G)) { goto l519; } goto l518; - l519:; G->pos= yypos519; G->thunkpos= yythunkpos519; - } if (!yymatchChar(G, '`')) goto l518; - l520:; - { int yypos521= G->pos, yythunkpos521= G->thunkpos; if (!yymatchChar(G, '`')) goto l521; goto l520; - l521:; G->pos= yypos521; G->thunkpos= yythunkpos521; - } goto l512; - l518:; G->pos= yypos512; G->thunkpos= yythunkpos512; - { int yypos522= G->pos, yythunkpos522= G->thunkpos; if (!yy_Sp(G)) { goto l522; } if (!yy_Ticks2(G)) { goto l522; } goto l497; - l522:; G->pos= yypos522; G->thunkpos= yythunkpos522; - } - { int yypos523= G->pos, yythunkpos523= G->thunkpos; if (!yy_Spacechar(G)) { goto l524; } goto l523; - l524:; G->pos= yypos523; G->thunkpos= yythunkpos523; if (!yy_Newline(G)) { goto l497; } - { int yypos525= G->pos, yythunkpos525= G->thunkpos; if (!yy_BlankLine(G)) { goto l525; } goto l497; - l525:; G->pos= yypos525; G->thunkpos= yythunkpos525; - } - } - l523:; - } - l512:; goto l496; - l497:; G->pos= yypos497; G->thunkpos= yythunkpos497; - } if (!yy_Sp(G)) { goto l495; } if (!yy_Ticks2(G)) { goto l495; } goto l463; - l495:; G->pos= yypos463; G->thunkpos= yythunkpos463; - { int yypos527= G->pos, yythunkpos527= G->thunkpos; if (!yy_FencedCodeBlockStartTickLine(G)) { goto l527; } goto l526; - l527:; G->pos= yypos527; G->thunkpos= yythunkpos527; - } if (!yy_Ticks3(G)) { goto l526; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l526; } - { int yypos530= G->pos, yythunkpos530= G->thunkpos; - { int yypos534= G->pos, yythunkpos534= G->thunkpos; if (!yymatchChar(G, '`')) goto l534; goto l531; - l534:; G->pos= yypos534; G->thunkpos= yythunkpos534; - } if (!yy_Nonspacechar(G)) { goto l531; } - l532:; - { int yypos533= G->pos, yythunkpos533= G->thunkpos; - { int yypos535= G->pos, yythunkpos535= G->thunkpos; if (!yymatchChar(G, '`')) goto l535; goto l533; - l535:; G->pos= yypos535; G->thunkpos= yythunkpos535; - } if (!yy_Nonspacechar(G)) { goto l533; } goto l532; - l533:; G->pos= yypos533; G->thunkpos= yythunkpos533; - } goto l530; - l531:; G->pos= yypos530; G->thunkpos= yythunkpos530; - { int yypos537= G->pos, yythunkpos537= G->thunkpos; if (!yy_Ticks3(G)) { goto l537; } goto l536; - l537:; G->pos= yypos537; G->thunkpos= yythunkpos537; - } if (!yymatchChar(G, '`')) goto l536; - l538:; - { int yypos539= G->pos, yythunkpos539= G->thunkpos; if (!yymatchChar(G, '`')) goto l539; goto l538; - l539:; G->pos= yypos539; G->thunkpos= yythunkpos539; - } goto l530; - l536:; G->pos= yypos530; G->thunkpos= yythunkpos530; - { int yypos540= G->pos, yythunkpos540= G->thunkpos; if (!yy_Sp(G)) { goto l540; } if (!yy_Ticks3(G)) { goto l540; } goto l526; - l540:; G->pos= yypos540; G->thunkpos= yythunkpos540; - } - { int yypos541= G->pos, yythunkpos541= G->thunkpos; if (!yy_Spacechar(G)) { goto l542; } goto l541; - l542:; G->pos= yypos541; G->thunkpos= yythunkpos541; if (!yy_Newline(G)) { goto l526; } - { int yypos543= G->pos, yythunkpos543= G->thunkpos; if (!yy_BlankLine(G)) { goto l543; } goto l526; - l543:; G->pos= yypos543; G->thunkpos= yythunkpos543; - } - } - l541:; - } - l530:; - l528:; - { int yypos529= G->pos, yythunkpos529= G->thunkpos; - { int yypos544= G->pos, yythunkpos544= G->thunkpos; - { int yypos548= G->pos, yythunkpos548= G->thunkpos; if (!yymatchChar(G, '`')) goto l548; goto l545; - l548:; G->pos= yypos548; G->thunkpos= yythunkpos548; - } if (!yy_Nonspacechar(G)) { goto l545; } - l546:; - { int yypos547= G->pos, yythunkpos547= G->thunkpos; - { int yypos549= G->pos, yythunkpos549= G->thunkpos; if (!yymatchChar(G, '`')) goto l549; goto l547; - l549:; G->pos= yypos549; G->thunkpos= yythunkpos549; - } if (!yy_Nonspacechar(G)) { goto l547; } goto l546; - l547:; G->pos= yypos547; G->thunkpos= yythunkpos547; - } goto l544; - l545:; G->pos= yypos544; G->thunkpos= yythunkpos544; - { int yypos551= G->pos, yythunkpos551= G->thunkpos; if (!yy_Ticks3(G)) { goto l551; } goto l550; - l551:; G->pos= yypos551; G->thunkpos= yythunkpos551; - } if (!yymatchChar(G, '`')) goto l550; - l552:; - { int yypos553= G->pos, yythunkpos553= G->thunkpos; if (!yymatchChar(G, '`')) goto l553; goto l552; - l553:; G->pos= yypos553; G->thunkpos= yythunkpos553; - } goto l544; - l550:; G->pos= yypos544; G->thunkpos= yythunkpos544; - { int yypos554= G->pos, yythunkpos554= G->thunkpos; if (!yy_Sp(G)) { goto l554; } if (!yy_Ticks3(G)) { goto l554; } goto l529; - l554:; G->pos= yypos554; G->thunkpos= yythunkpos554; - } - { int yypos555= G->pos, yythunkpos555= G->thunkpos; if (!yy_Spacechar(G)) { goto l556; } goto l555; - l556:; G->pos= yypos555; G->thunkpos= yythunkpos555; if (!yy_Newline(G)) { goto l529; } - { int yypos557= G->pos, yythunkpos557= G->thunkpos; if (!yy_BlankLine(G)) { goto l557; } goto l529; - l557:; G->pos= yypos557; G->thunkpos= yythunkpos557; - } - } - l555:; - } - l544:; goto l528; - l529:; G->pos= yypos529; G->thunkpos= yythunkpos529; - } if (!yy_Sp(G)) { goto l526; } if (!yy_Ticks3(G)) { goto l526; } goto l463; - l526:; G->pos= yypos463; G->thunkpos= yythunkpos463; if (!yy_Ticks4(G)) { goto l558; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l558; } - { int yypos561= G->pos, yythunkpos561= G->thunkpos; - { int yypos565= G->pos, yythunkpos565= G->thunkpos; if (!yymatchChar(G, '`')) goto l565; goto l562; - l565:; G->pos= yypos565; G->thunkpos= yythunkpos565; - } if (!yy_Nonspacechar(G)) { goto l562; } - l563:; - { int yypos564= G->pos, yythunkpos564= G->thunkpos; - { int yypos566= G->pos, yythunkpos566= G->thunkpos; if (!yymatchChar(G, '`')) goto l566; goto l564; - l566:; G->pos= yypos566; G->thunkpos= yythunkpos566; - } if (!yy_Nonspacechar(G)) { goto l564; } goto l563; - l564:; G->pos= yypos564; G->thunkpos= yythunkpos564; - } goto l561; - l562:; G->pos= yypos561; G->thunkpos= yythunkpos561; - { int yypos568= G->pos, yythunkpos568= G->thunkpos; if (!yy_Ticks4(G)) { goto l568; } goto l567; - l568:; G->pos= yypos568; G->thunkpos= yythunkpos568; - } if (!yymatchChar(G, '`')) goto l567; - l569:; - { int yypos570= G->pos, yythunkpos570= G->thunkpos; if (!yymatchChar(G, '`')) goto l570; goto l569; - l570:; G->pos= yypos570; G->thunkpos= yythunkpos570; - } goto l561; - l567:; G->pos= yypos561; G->thunkpos= yythunkpos561; - { int yypos571= G->pos, yythunkpos571= G->thunkpos; if (!yy_Sp(G)) { goto l571; } if (!yy_Ticks4(G)) { goto l571; } goto l558; - l571:; G->pos= yypos571; G->thunkpos= yythunkpos571; - } - { int yypos572= G->pos, yythunkpos572= G->thunkpos; if (!yy_Spacechar(G)) { goto l573; } goto l572; - l573:; G->pos= yypos572; G->thunkpos= yythunkpos572; if (!yy_Newline(G)) { goto l558; } - { int yypos574= G->pos, yythunkpos574= G->thunkpos; if (!yy_BlankLine(G)) { goto l574; } goto l558; - l574:; G->pos= yypos574; G->thunkpos= yythunkpos574; - } - } - l572:; - } - l561:; - l559:; - { int yypos560= G->pos, yythunkpos560= G->thunkpos; - { int yypos575= G->pos, yythunkpos575= G->thunkpos; - { int yypos579= G->pos, yythunkpos579= G->thunkpos; if (!yymatchChar(G, '`')) goto l579; goto l576; - l579:; G->pos= yypos579; G->thunkpos= yythunkpos579; - } if (!yy_Nonspacechar(G)) { goto l576; } - l577:; - { int yypos578= G->pos, yythunkpos578= G->thunkpos; - { int yypos580= G->pos, yythunkpos580= G->thunkpos; if (!yymatchChar(G, '`')) goto l580; goto l578; - l580:; G->pos= yypos580; G->thunkpos= yythunkpos580; - } if (!yy_Nonspacechar(G)) { goto l578; } goto l577; - l578:; G->pos= yypos578; G->thunkpos= yythunkpos578; - } goto l575; - l576:; G->pos= yypos575; G->thunkpos= yythunkpos575; - { int yypos582= G->pos, yythunkpos582= G->thunkpos; if (!yy_Ticks4(G)) { goto l582; } goto l581; - l582:; G->pos= yypos582; G->thunkpos= yythunkpos582; - } if (!yymatchChar(G, '`')) goto l581; - l583:; - { int yypos584= G->pos, yythunkpos584= G->thunkpos; if (!yymatchChar(G, '`')) goto l584; goto l583; - l584:; G->pos= yypos584; G->thunkpos= yythunkpos584; - } goto l575; - l581:; G->pos= yypos575; G->thunkpos= yythunkpos575; - { int yypos585= G->pos, yythunkpos585= G->thunkpos; if (!yy_Sp(G)) { goto l585; } if (!yy_Ticks4(G)) { goto l585; } goto l560; - l585:; G->pos= yypos585; G->thunkpos= yythunkpos585; - } - { int yypos586= G->pos, yythunkpos586= G->thunkpos; if (!yy_Spacechar(G)) { goto l587; } goto l586; - l587:; G->pos= yypos586; G->thunkpos= yythunkpos586; if (!yy_Newline(G)) { goto l560; } - { int yypos588= G->pos, yythunkpos588= G->thunkpos; if (!yy_BlankLine(G)) { goto l588; } goto l560; - l588:; G->pos= yypos588; G->thunkpos= yythunkpos588; - } - } - l586:; - } - l575:; goto l559; - l560:; G->pos= yypos560; G->thunkpos= yythunkpos560; - } if (!yy_Sp(G)) { goto l558; } if (!yy_Ticks4(G)) { goto l558; } goto l463; - l558:; G->pos= yypos463; G->thunkpos= yythunkpos463; if (!yy_Ticks5(G)) { goto l462; } yyDo(G, yySet, -1, 0); if (!yy_Sp(G)) { goto l462; } - { int yypos591= G->pos, yythunkpos591= G->thunkpos; - { int yypos595= G->pos, yythunkpos595= G->thunkpos; if (!yymatchChar(G, '`')) goto l595; goto l592; - l595:; G->pos= yypos595; G->thunkpos= yythunkpos595; - } if (!yy_Nonspacechar(G)) { goto l592; } - l593:; - { int yypos594= G->pos, yythunkpos594= G->thunkpos; - { int yypos596= G->pos, yythunkpos596= G->thunkpos; if (!yymatchChar(G, '`')) goto l596; goto l594; - l596:; G->pos= yypos596; G->thunkpos= yythunkpos596; - } if (!yy_Nonspacechar(G)) { goto l594; } goto l593; - l594:; G->pos= yypos594; G->thunkpos= yythunkpos594; - } goto l591; - l592:; G->pos= yypos591; G->thunkpos= yythunkpos591; - { int yypos598= G->pos, yythunkpos598= G->thunkpos; if (!yy_Ticks5(G)) { goto l598; } goto l597; - l598:; G->pos= yypos598; G->thunkpos= yythunkpos598; - } if (!yymatchChar(G, '`')) goto l597; - l599:; - { int yypos600= G->pos, yythunkpos600= G->thunkpos; if (!yymatchChar(G, '`')) goto l600; goto l599; - l600:; G->pos= yypos600; G->thunkpos= yythunkpos600; - } goto l591; - l597:; G->pos= yypos591; G->thunkpos= yythunkpos591; - { int yypos601= G->pos, yythunkpos601= G->thunkpos; if (!yy_Sp(G)) { goto l601; } if (!yy_Ticks5(G)) { goto l601; } goto l462; - l601:; G->pos= yypos601; G->thunkpos= yythunkpos601; - } - { int yypos602= G->pos, yythunkpos602= G->thunkpos; if (!yy_Spacechar(G)) { goto l603; } goto l602; - l603:; G->pos= yypos602; G->thunkpos= yythunkpos602; if (!yy_Newline(G)) { goto l462; } - { int yypos604= G->pos, yythunkpos604= G->thunkpos; if (!yy_BlankLine(G)) { goto l604; } goto l462; - l604:; G->pos= yypos604; G->thunkpos= yythunkpos604; - } - } - l602:; - } - l591:; - l589:; - { int yypos590= G->pos, yythunkpos590= G->thunkpos; - { int yypos605= G->pos, yythunkpos605= G->thunkpos; - { int yypos609= G->pos, yythunkpos609= G->thunkpos; if (!yymatchChar(G, '`')) goto l609; goto l606; - l609:; G->pos= yypos609; G->thunkpos= yythunkpos609; - } if (!yy_Nonspacechar(G)) { goto l606; } - l607:; - { int yypos608= G->pos, yythunkpos608= G->thunkpos; - { int yypos610= G->pos, yythunkpos610= G->thunkpos; if (!yymatchChar(G, '`')) goto l610; goto l608; - l610:; G->pos= yypos610; G->thunkpos= yythunkpos610; - } if (!yy_Nonspacechar(G)) { goto l608; } goto l607; - l608:; G->pos= yypos608; G->thunkpos= yythunkpos608; - } goto l605; - l606:; G->pos= yypos605; G->thunkpos= yythunkpos605; - { int yypos612= G->pos, yythunkpos612= G->thunkpos; if (!yy_Ticks5(G)) { goto l612; } goto l611; - l612:; G->pos= yypos612; G->thunkpos= yythunkpos612; - } if (!yymatchChar(G, '`')) goto l611; - l613:; - { int yypos614= G->pos, yythunkpos614= G->thunkpos; if (!yymatchChar(G, '`')) goto l614; goto l613; - l614:; G->pos= yypos614; G->thunkpos= yythunkpos614; - } goto l605; - l611:; G->pos= yypos605; G->thunkpos= yythunkpos605; - { int yypos615= G->pos, yythunkpos615= G->thunkpos; if (!yy_Sp(G)) { goto l615; } if (!yy_Ticks5(G)) { goto l615; } goto l590; - l615:; G->pos= yypos615; G->thunkpos= yythunkpos615; - } - { int yypos616= G->pos, yythunkpos616= G->thunkpos; if (!yy_Spacechar(G)) { goto l617; } goto l616; - l617:; G->pos= yypos616; G->thunkpos= yythunkpos616; if (!yy_Newline(G)) { goto l590; } - { int yypos618= G->pos, yythunkpos618= G->thunkpos; if (!yy_BlankLine(G)) { goto l618; } goto l590; - l618:; G->pos= yypos618; G->thunkpos= yythunkpos618; - } - } - l616:; - } - l605:; goto l589; - l590:; G->pos= yypos590; G->thunkpos= yythunkpos590; - } if (!yy_Sp(G)) { goto l462; } if (!yy_Ticks5(G)) { goto l462; } - } - l463:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l462; yyDo(G, yy_1_Code, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Code", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l462:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Code", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_InlineNote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "InlineNote")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l619; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l619; if (!yy_LocMarker(G)) { goto l619; } yyDo(G, yySet, -1, 0); if (!yymatchString(G, "^[")) goto l619; - { int yypos622= G->pos, yythunkpos622= G->thunkpos; if (!yymatchChar(G, ']')) goto l622; goto l619; - l622:; G->pos= yypos622; G->thunkpos= yythunkpos622; - } if (!yy_Inline(G)) { goto l619; } - l620:; - { int yypos621= G->pos, yythunkpos621= G->thunkpos; - { int yypos623= G->pos, yythunkpos623= G->thunkpos; if (!yymatchChar(G, ']')) goto l623; goto l621; - l623:; G->pos= yypos623; G->thunkpos= yythunkpos623; - } if (!yy_Inline(G)) { goto l621; } goto l620; - l621:; G->pos= yypos621; G->thunkpos= yythunkpos621; - } if (!yymatchChar(G, ']')) goto l619; yyText(G, G->begin, G->end); if (!(YY_END)) goto l619; yyDo(G, yy_1_InlineNote, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "InlineNote", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l619:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "InlineNote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NoteReference(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NoteReference")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l624; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l624; if (!yy_RawNoteReference(G)) { goto l624; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l624; yyDo(G, yy_1_NoteReference, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "NoteReference", G->buf+G->pos)); - return 1; - l624:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NoteReference", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Link(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Link")); - { int yypos626= G->pos, yythunkpos626= G->thunkpos; if (!yy_ExplicitLink(G)) { goto l627; } goto l626; - l627:; G->pos= yypos626; G->thunkpos= yythunkpos626; if (!yy_ReferenceLink(G)) { goto l628; } goto l626; - l628:; G->pos= yypos626; G->thunkpos= yythunkpos626; if (!yy_AutoLink(G)) { goto l625; } - } - l626:; yyDo(G, yy_1_Link, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Link", G->buf+G->pos)); - return 1; - l625:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Link", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Image(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Image")); if (!yymatchChar(G, '!')) goto l629; - { int yypos630= G->pos, yythunkpos630= G->thunkpos; if (!yy_ExplicitLink(G)) { goto l631; } goto l630; - l631:; G->pos= yypos630; G->thunkpos= yythunkpos630; if (!yy_ExplicitLinkSize(G)) { goto l632; } goto l630; - l632:; G->pos= yypos630; G->thunkpos= yythunkpos630; if (!yy_ReferenceLink(G)) { goto l629; } - } - l630:; yyDo(G, yy_1_Image, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Image", G->buf+G->pos)); - return 1; - l629:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Image", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Strike(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Strike")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_STRIKE) )) goto l633; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l633; if (!yy_LocMarker(G)) { goto l633; } yyDo(G, yySet, -1, 0); if (!yymatchString(G, "~~")) goto l633; - { int yypos634= G->pos, yythunkpos634= G->thunkpos; if (!yy_Whitespace(G)) { goto l634; } goto l633; - l634:; G->pos= yypos634; G->thunkpos= yythunkpos634; - } - { int yypos637= G->pos, yythunkpos637= G->thunkpos; if (!yymatchString(G, "~~")) goto l637; goto l633; - l637:; G->pos= yypos637; G->thunkpos= yythunkpos637; - } if (!yy_Inline(G)) { goto l633; } - l635:; - { int yypos636= G->pos, yythunkpos636= G->thunkpos; - { int yypos638= G->pos, yythunkpos638= G->thunkpos; if (!yymatchString(G, "~~")) goto l638; goto l636; - l638:; G->pos= yypos638; G->thunkpos= yythunkpos638; - } if (!yy_Inline(G)) { goto l636; } goto l635; - l636:; G->pos= yypos636; G->thunkpos= yythunkpos636; - } yyText(G, G->begin, G->end); if (!( STRIKE_POST )) goto l633; if (!yymatchString(G, "~~")) goto l633; yyText(G, G->begin, G->end); if (!(YY_END)) goto l633; yyDo(G, yy_1_Strike, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Strike", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l633:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Strike", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Emph(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Emph")); - { int yypos640= G->pos, yythunkpos640= G->thunkpos; if (!yy_EmphStar(G)) { goto l641; } goto l640; - l641:; G->pos= yypos640; G->thunkpos= yythunkpos640; if (!yy_EmphUl(G)) { goto l639; } - } - l640:; - yyprintf((stderr, " ok %s @ %s\n", "Emph", G->buf+G->pos)); - return 1; - l639:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Emph", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Strong(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Strong")); - { int yypos643= G->pos, yythunkpos643= G->thunkpos; if (!yy_StrongStar(G)) { goto l644; } goto l643; - l644:; G->pos= yypos643; G->thunkpos= yythunkpos643; if (!yy_StrongUl(G)) { goto l642; } - } - l643:; - yyprintf((stderr, " ok %s @ %s\n", "Strong", G->buf+G->pos)); - return 1; - l642:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Strong", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_UlOrStarLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "UlOrStarLine")); - { int yypos646= G->pos, yythunkpos646= G->thunkpos; if (!yy_UlLine(G)) { goto l647; } goto l646; - l647:; G->pos= yypos646; G->thunkpos= yythunkpos646; if (!yy_StarLine(G)) { goto l645; } - } - l646:; - yyprintf((stderr, " ok %s @ %s\n", "UlOrStarLine", G->buf+G->pos)); - return 1; - l645:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "UlOrStarLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Str(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Str")); if (!yy_NormalChar(G)) { goto l648; } - l649:; - { int yypos650= G->pos, yythunkpos650= G->thunkpos; - { int yypos651= G->pos, yythunkpos651= G->thunkpos; if (!yy_NormalChar(G)) { goto l652; } goto l651; - l652:; G->pos= yypos651; G->thunkpos= yythunkpos651; if (!yymatchChar(G, '_')) goto l650; - l653:; - { int yypos654= G->pos, yythunkpos654= G->thunkpos; if (!yymatchChar(G, '_')) goto l654; goto l653; - l654:; G->pos= yypos654; G->thunkpos= yythunkpos654; - } - { int yypos655= G->pos, yythunkpos655= G->thunkpos; if (!yy_Alphanumeric(G)) { goto l650; } G->pos= yypos655; G->thunkpos= yythunkpos655; - } - } - l651:; goto l649; - l650:; G->pos= yypos650; G->thunkpos= yythunkpos650; - } - yyprintf((stderr, " ok %s @ %s\n", "Str", G->buf+G->pos)); - return 1; - l648:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Str", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_InStyleTags(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "InStyleTags")); if (!yy_StyleOpen(G)) { goto l656; } - l657:; - { int yypos658= G->pos, yythunkpos658= G->thunkpos; - { int yypos659= G->pos, yythunkpos659= G->thunkpos; if (!yy_StyleClose(G)) { goto l659; } goto l658; - l659:; G->pos= yypos659; G->thunkpos= yythunkpos659; - } if (!yymatchDot(G)) goto l658; goto l657; - l658:; G->pos= yypos658; G->thunkpos= yythunkpos658; - } if (!yy_StyleClose(G)) { goto l656; } - yyprintf((stderr, " ok %s @ %s\n", "InStyleTags", G->buf+G->pos)); - return 1; - l656:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "InStyleTags", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StyleClose(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "StyleClose")); if (!yymatchChar(G, '<')) goto l660; if (!yy_Spnl(G)) { goto l660; } if (!yymatchChar(G, '/')) goto l660; - { int yypos661= G->pos, yythunkpos661= G->thunkpos; if (!yymatchString(G, "style")) goto l662; goto l661; - l662:; G->pos= yypos661; G->thunkpos= yythunkpos661; if (!yymatchString(G, "STYLE")) goto l660; - } - l661:; if (!yy_Spnl(G)) { goto l660; } if (!yymatchChar(G, '>')) goto l660; - yyprintf((stderr, " ok %s @ %s\n", "StyleClose", G->buf+G->pos)); - return 1; - l660:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StyleClose", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StyleOpen(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "StyleOpen")); if (!yymatchChar(G, '<')) goto l663; if (!yy_Spnl(G)) { goto l663; } - { int yypos664= G->pos, yythunkpos664= G->thunkpos; if (!yymatchString(G, "style")) goto l665; goto l664; - l665:; G->pos= yypos664; G->thunkpos= yythunkpos664; if (!yymatchString(G, "STYLE")) goto l663; - } - l664:; if (!yy_Spnl(G)) { goto l663; } - l666:; - { int yypos667= G->pos, yythunkpos667= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l667; } goto l666; - l667:; G->pos= yypos667; G->thunkpos= yythunkpos667; - } if (!yymatchChar(G, '>')) goto l663; - yyprintf((stderr, " ok %s @ %s\n", "StyleOpen", G->buf+G->pos)); - return 1; - l663:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StyleOpen", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockType(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockType")); - { int yypos669= G->pos, yythunkpos669= G->thunkpos; if (!yymatchString(G, "address")) goto l670; goto l669; - l670:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "blockquote")) goto l671; goto l669; - l671:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "center")) goto l672; goto l669; - l672:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "dir")) goto l673; goto l669; - l673:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "div")) goto l674; goto l669; - l674:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "dl")) goto l675; goto l669; - l675:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "fieldset")) goto l676; goto l669; - l676:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "form")) goto l677; goto l669; - l677:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "h1")) goto l678; goto l669; - l678:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "h2")) goto l679; goto l669; - l679:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "h3")) goto l680; goto l669; - l680:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "h4")) goto l681; goto l669; - l681:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "h5")) goto l682; goto l669; - l682:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "h6")) goto l683; goto l669; - l683:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "hr")) goto l684; goto l669; - l684:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "isindex")) goto l685; goto l669; - l685:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "menu")) goto l686; goto l669; - l686:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "noframes")) goto l687; goto l669; - l687:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "noscript")) goto l688; goto l669; - l688:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "ol")) goto l689; goto l669; - l689:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchChar(G, 'p')) goto l690; goto l669; - l690:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "pre")) goto l691; goto l669; - l691:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "table")) goto l692; goto l669; - l692:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "ul")) goto l693; goto l669; - l693:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "dd")) goto l694; goto l669; - l694:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "dt")) goto l695; goto l669; - l695:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "frameset")) goto l696; goto l669; - l696:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "li")) goto l697; goto l669; - l697:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "tbody")) goto l698; goto l669; - l698:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "td")) goto l699; goto l669; - l699:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "tfoot")) goto l700; goto l669; - l700:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "th")) goto l701; goto l669; - l701:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "thead")) goto l702; goto l669; - l702:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "tr")) goto l703; goto l669; - l703:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "script")) goto l704; goto l669; - l704:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "ADDRESS")) goto l705; goto l669; - l705:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "BLOCKQUOTE")) goto l706; goto l669; - l706:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "CENTER")) goto l707; goto l669; - l707:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "DIR")) goto l708; goto l669; - l708:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "DIV")) goto l709; goto l669; - l709:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "DL")) goto l710; goto l669; - l710:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "FIELDSET")) goto l711; goto l669; - l711:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "FORM")) goto l712; goto l669; - l712:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "H1")) goto l713; goto l669; - l713:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "H2")) goto l714; goto l669; - l714:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "H3")) goto l715; goto l669; - l715:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "H4")) goto l716; goto l669; - l716:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "H5")) goto l717; goto l669; - l717:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "H6")) goto l718; goto l669; - l718:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "HR")) goto l719; goto l669; - l719:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "ISINDEX")) goto l720; goto l669; - l720:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "MENU")) goto l721; goto l669; - l721:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "NOFRAMES")) goto l722; goto l669; - l722:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "NOSCRIPT")) goto l723; goto l669; - l723:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "OL")) goto l724; goto l669; - l724:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchChar(G, 'P')) goto l725; goto l669; - l725:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "PRE")) goto l726; goto l669; - l726:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "TABLE")) goto l727; goto l669; - l727:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "UL")) goto l728; goto l669; - l728:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "DD")) goto l729; goto l669; - l729:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "DT")) goto l730; goto l669; - l730:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "FRAMESET")) goto l731; goto l669; - l731:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "LI")) goto l732; goto l669; - l732:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "TBODY")) goto l733; goto l669; - l733:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "TD")) goto l734; goto l669; - l734:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "TFOOT")) goto l735; goto l669; - l735:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "TH")) goto l736; goto l669; - l736:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "THEAD")) goto l737; goto l669; - l737:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "TR")) goto l738; goto l669; - l738:; G->pos= yypos669; G->thunkpos= yythunkpos669; if (!yymatchString(G, "SCRIPT")) goto l668; - } - l669:; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockType", G->buf+G->pos)); - return 1; - l668:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockType", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockSelfClosing(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockSelfClosing")); if (!yymatchChar(G, '<')) goto l739; if (!yy_Spnl(G)) { goto l739; } if (!yy_HtmlBlockType(G)) { goto l739; } if (!yy_Spnl(G)) { goto l739; } - l740:; - { int yypos741= G->pos, yythunkpos741= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l741; } goto l740; - l741:; G->pos= yypos741; G->thunkpos= yythunkpos741; - } if (!yymatchChar(G, '/')) goto l739; if (!yy_Spnl(G)) { goto l739; } if (!yymatchChar(G, '>')) goto l739; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockSelfClosing", G->buf+G->pos)); - return 1; - l739:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockSelfClosing", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlComment(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlComment")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l742; if (!yy_LocMarker(G)) { goto l742; } yyDo(G, yySet, -1, 0); if (!yymatchString(G, "")) goto l745; goto l744; - l745:; G->pos= yypos745; G->thunkpos= yythunkpos745; - } if (!yymatchDot(G)) goto l744; goto l743; - l744:; G->pos= yypos744; G->thunkpos= yythunkpos744; - } if (!yymatchString(G, "-->")) goto l742; yyText(G, G->begin, G->end); if (!(YY_END)) goto l742; yyDo(G, yy_1_HtmlComment, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlComment", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l742:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlComment", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockInTags(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockInTags")); - { int yypos747= G->pos, yythunkpos747= G->thunkpos; if (!yy_HtmlBlockAddress(G)) { goto l748; } goto l747; - l748:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockBlockquote(G)) { goto l749; } goto l747; - l749:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockCenter(G)) { goto l750; } goto l747; - l750:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockDir(G)) { goto l751; } goto l747; - l751:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockDiv(G)) { goto l752; } goto l747; - l752:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockDl(G)) { goto l753; } goto l747; - l753:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockFieldset(G)) { goto l754; } goto l747; - l754:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockForm(G)) { goto l755; } goto l747; - l755:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockH1(G)) { goto l756; } goto l747; - l756:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockH2(G)) { goto l757; } goto l747; - l757:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockH3(G)) { goto l758; } goto l747; - l758:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockH4(G)) { goto l759; } goto l747; - l759:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockH5(G)) { goto l760; } goto l747; - l760:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockH6(G)) { goto l761; } goto l747; - l761:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockMenu(G)) { goto l762; } goto l747; - l762:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockNoframes(G)) { goto l763; } goto l747; - l763:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockNoscript(G)) { goto l764; } goto l747; - l764:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockOl(G)) { goto l765; } goto l747; - l765:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockP(G)) { goto l766; } goto l747; - l766:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockPre(G)) { goto l767; } goto l747; - l767:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockTable(G)) { goto l768; } goto l747; - l768:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockUl(G)) { goto l769; } goto l747; - l769:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockDd(G)) { goto l770; } goto l747; - l770:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockDt(G)) { goto l771; } goto l747; - l771:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockFrameset(G)) { goto l772; } goto l747; - l772:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockLi(G)) { goto l773; } goto l747; - l773:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockTbody(G)) { goto l774; } goto l747; - l774:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockTd(G)) { goto l775; } goto l747; - l775:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockTfoot(G)) { goto l776; } goto l747; - l776:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockTh(G)) { goto l777; } goto l747; - l777:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockThead(G)) { goto l778; } goto l747; - l778:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockTr(G)) { goto l779; } goto l747; - l779:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockScript(G)) { goto l780; } goto l747; - l780:; G->pos= yypos747; G->thunkpos= yythunkpos747; if (!yy_HtmlBlockHead(G)) { goto l746; } - } - l747:; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockInTags", G->buf+G->pos)); - return 1; - l746:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockInTags", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockHead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockHead")); if (!yy_HtmlBlockOpenHead(G)) { goto l781; } - l782:; - { int yypos783= G->pos, yythunkpos783= G->thunkpos; - { int yypos784= G->pos, yythunkpos784= G->thunkpos; if (!yy_HtmlBlockCloseHead(G)) { goto l784; } goto l783; - l784:; G->pos= yypos784; G->thunkpos= yythunkpos784; - } if (!yymatchDot(G)) goto l783; goto l782; - l783:; G->pos= yypos783; G->thunkpos= yythunkpos783; - } if (!yy_HtmlBlockCloseHead(G)) { goto l781; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockHead", G->buf+G->pos)); - return 1; - l781:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockHead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseHead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseHead")); if (!yymatchChar(G, '<')) goto l785; if (!yy_Spnl(G)) { goto l785; } if (!yymatchChar(G, '/')) goto l785; - { int yypos786= G->pos, yythunkpos786= G->thunkpos; if (!yymatchString(G, "head")) goto l787; goto l786; - l787:; G->pos= yypos786; G->thunkpos= yythunkpos786; if (!yymatchString(G, "HEAD")) goto l785; - } - l786:; if (!yy_Spnl(G)) { goto l785; } if (!yymatchChar(G, '>')) goto l785; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseHead", G->buf+G->pos)); - return 1; - l785:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseHead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenHead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenHead")); if (!yymatchChar(G, '<')) goto l788; if (!yy_Spnl(G)) { goto l788; } - { int yypos789= G->pos, yythunkpos789= G->thunkpos; if (!yymatchString(G, "head")) goto l790; goto l789; - l790:; G->pos= yypos789; G->thunkpos= yythunkpos789; if (!yymatchString(G, "HEAD")) goto l788; - } - l789:; if (!yy_Spnl(G)) { goto l788; } - l791:; - { int yypos792= G->pos, yythunkpos792= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l792; } goto l791; - l792:; G->pos= yypos792; G->thunkpos= yythunkpos792; - } if (!yymatchChar(G, '>')) goto l788; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenHead", G->buf+G->pos)); - return 1; - l788:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenHead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockScript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockScript")); if (!yy_HtmlBlockOpenScript(G)) { goto l793; } - l794:; - { int yypos795= G->pos, yythunkpos795= G->thunkpos; - { int yypos796= G->pos, yythunkpos796= G->thunkpos; if (!yy_HtmlBlockCloseScript(G)) { goto l796; } goto l795; - l796:; G->pos= yypos796; G->thunkpos= yythunkpos796; - } if (!yymatchDot(G)) goto l795; goto l794; - l795:; G->pos= yypos795; G->thunkpos= yythunkpos795; - } if (!yy_HtmlBlockCloseScript(G)) { goto l793; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockScript", G->buf+G->pos)); - return 1; - l793:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockScript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseScript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseScript")); if (!yymatchChar(G, '<')) goto l797; if (!yy_Spnl(G)) { goto l797; } if (!yymatchChar(G, '/')) goto l797; - { int yypos798= G->pos, yythunkpos798= G->thunkpos; if (!yymatchString(G, "script")) goto l799; goto l798; - l799:; G->pos= yypos798; G->thunkpos= yythunkpos798; if (!yymatchString(G, "SCRIPT")) goto l797; - } - l798:; if (!yy_Spnl(G)) { goto l797; } if (!yymatchChar(G, '>')) goto l797; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseScript", G->buf+G->pos)); - return 1; - l797:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseScript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenScript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenScript")); if (!yymatchChar(G, '<')) goto l800; if (!yy_Spnl(G)) { goto l800; } - { int yypos801= G->pos, yythunkpos801= G->thunkpos; if (!yymatchString(G, "script")) goto l802; goto l801; - l802:; G->pos= yypos801; G->thunkpos= yythunkpos801; if (!yymatchString(G, "SCRIPT")) goto l800; - } - l801:; if (!yy_Spnl(G)) { goto l800; } - l803:; - { int yypos804= G->pos, yythunkpos804= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l804; } goto l803; - l804:; G->pos= yypos804; G->thunkpos= yythunkpos804; - } if (!yymatchChar(G, '>')) goto l800; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenScript", G->buf+G->pos)); - return 1; - l800:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenScript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTr(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTr")); if (!yy_HtmlBlockOpenTr(G)) { goto l805; } - l806:; - { int yypos807= G->pos, yythunkpos807= G->thunkpos; - { int yypos808= G->pos, yythunkpos808= G->thunkpos; if (!yy_HtmlBlockTr(G)) { goto l809; } goto l808; - l809:; G->pos= yypos808; G->thunkpos= yythunkpos808; - { int yypos810= G->pos, yythunkpos810= G->thunkpos; if (!yy_HtmlBlockCloseTr(G)) { goto l810; } goto l807; - l810:; G->pos= yypos810; G->thunkpos= yythunkpos810; - } if (!yymatchDot(G)) goto l807; - } - l808:; goto l806; - l807:; G->pos= yypos807; G->thunkpos= yythunkpos807; - } if (!yy_HtmlBlockCloseTr(G)) { goto l805; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTr", G->buf+G->pos)); - return 1; - l805:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTr", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTr(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTr")); if (!yymatchChar(G, '<')) goto l811; if (!yy_Spnl(G)) { goto l811; } if (!yymatchChar(G, '/')) goto l811; - { int yypos812= G->pos, yythunkpos812= G->thunkpos; if (!yymatchString(G, "tr")) goto l813; goto l812; - l813:; G->pos= yypos812; G->thunkpos= yythunkpos812; if (!yymatchString(G, "TR")) goto l811; - } - l812:; if (!yy_Spnl(G)) { goto l811; } if (!yymatchChar(G, '>')) goto l811; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTr", G->buf+G->pos)); - return 1; - l811:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTr", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTr(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTr")); if (!yymatchChar(G, '<')) goto l814; if (!yy_Spnl(G)) { goto l814; } - { int yypos815= G->pos, yythunkpos815= G->thunkpos; if (!yymatchString(G, "tr")) goto l816; goto l815; - l816:; G->pos= yypos815; G->thunkpos= yythunkpos815; if (!yymatchString(G, "TR")) goto l814; - } - l815:; if (!yy_Spnl(G)) { goto l814; } - l817:; - { int yypos818= G->pos, yythunkpos818= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l818; } goto l817; - l818:; G->pos= yypos818; G->thunkpos= yythunkpos818; - } if (!yymatchChar(G, '>')) goto l814; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTr", G->buf+G->pos)); - return 1; - l814:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTr", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockThead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockThead")); if (!yy_HtmlBlockOpenThead(G)) { goto l819; } - l820:; - { int yypos821= G->pos, yythunkpos821= G->thunkpos; - { int yypos822= G->pos, yythunkpos822= G->thunkpos; if (!yy_HtmlBlockThead(G)) { goto l823; } goto l822; - l823:; G->pos= yypos822; G->thunkpos= yythunkpos822; - { int yypos824= G->pos, yythunkpos824= G->thunkpos; if (!yy_HtmlBlockCloseThead(G)) { goto l824; } goto l821; - l824:; G->pos= yypos824; G->thunkpos= yythunkpos824; - } if (!yymatchDot(G)) goto l821; - } - l822:; goto l820; - l821:; G->pos= yypos821; G->thunkpos= yythunkpos821; - } if (!yy_HtmlBlockCloseThead(G)) { goto l819; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockThead", G->buf+G->pos)); - return 1; - l819:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockThead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseThead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseThead")); if (!yymatchChar(G, '<')) goto l825; if (!yy_Spnl(G)) { goto l825; } if (!yymatchChar(G, '/')) goto l825; - { int yypos826= G->pos, yythunkpos826= G->thunkpos; if (!yymatchString(G, "thead")) goto l827; goto l826; - l827:; G->pos= yypos826; G->thunkpos= yythunkpos826; if (!yymatchString(G, "THEAD")) goto l825; - } - l826:; if (!yy_Spnl(G)) { goto l825; } if (!yymatchChar(G, '>')) goto l825; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseThead", G->buf+G->pos)); - return 1; - l825:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseThead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenThead(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenThead")); if (!yymatchChar(G, '<')) goto l828; if (!yy_Spnl(G)) { goto l828; } - { int yypos829= G->pos, yythunkpos829= G->thunkpos; if (!yymatchString(G, "thead")) goto l830; goto l829; - l830:; G->pos= yypos829; G->thunkpos= yythunkpos829; if (!yymatchString(G, "THEAD")) goto l828; - } - l829:; if (!yy_Spnl(G)) { goto l828; } - l831:; - { int yypos832= G->pos, yythunkpos832= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l832; } goto l831; - l832:; G->pos= yypos832; G->thunkpos= yythunkpos832; - } if (!yymatchChar(G, '>')) goto l828; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenThead", G->buf+G->pos)); - return 1; - l828:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenThead", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTh(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTh")); if (!yy_HtmlBlockOpenTh(G)) { goto l833; } - l834:; - { int yypos835= G->pos, yythunkpos835= G->thunkpos; - { int yypos836= G->pos, yythunkpos836= G->thunkpos; if (!yy_HtmlBlockTh(G)) { goto l837; } goto l836; - l837:; G->pos= yypos836; G->thunkpos= yythunkpos836; - { int yypos838= G->pos, yythunkpos838= G->thunkpos; if (!yy_HtmlBlockCloseTh(G)) { goto l838; } goto l835; - l838:; G->pos= yypos838; G->thunkpos= yythunkpos838; - } if (!yymatchDot(G)) goto l835; - } - l836:; goto l834; - l835:; G->pos= yypos835; G->thunkpos= yythunkpos835; - } if (!yy_HtmlBlockCloseTh(G)) { goto l833; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTh", G->buf+G->pos)); - return 1; - l833:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTh", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTh(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTh")); if (!yymatchChar(G, '<')) goto l839; if (!yy_Spnl(G)) { goto l839; } if (!yymatchChar(G, '/')) goto l839; - { int yypos840= G->pos, yythunkpos840= G->thunkpos; if (!yymatchString(G, "th")) goto l841; goto l840; - l841:; G->pos= yypos840; G->thunkpos= yythunkpos840; if (!yymatchString(G, "TH")) goto l839; - } - l840:; if (!yy_Spnl(G)) { goto l839; } if (!yymatchChar(G, '>')) goto l839; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTh", G->buf+G->pos)); - return 1; - l839:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTh", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTh(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTh")); if (!yymatchChar(G, '<')) goto l842; if (!yy_Spnl(G)) { goto l842; } - { int yypos843= G->pos, yythunkpos843= G->thunkpos; if (!yymatchString(G, "th")) goto l844; goto l843; - l844:; G->pos= yypos843; G->thunkpos= yythunkpos843; if (!yymatchString(G, "TH")) goto l842; - } - l843:; if (!yy_Spnl(G)) { goto l842; } - l845:; - { int yypos846= G->pos, yythunkpos846= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l846; } goto l845; - l846:; G->pos= yypos846; G->thunkpos= yythunkpos846; - } if (!yymatchChar(G, '>')) goto l842; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTh", G->buf+G->pos)); - return 1; - l842:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTh", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTfoot(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTfoot")); if (!yy_HtmlBlockOpenTfoot(G)) { goto l847; } - l848:; - { int yypos849= G->pos, yythunkpos849= G->thunkpos; - { int yypos850= G->pos, yythunkpos850= G->thunkpos; if (!yy_HtmlBlockTfoot(G)) { goto l851; } goto l850; - l851:; G->pos= yypos850; G->thunkpos= yythunkpos850; - { int yypos852= G->pos, yythunkpos852= G->thunkpos; if (!yy_HtmlBlockCloseTfoot(G)) { goto l852; } goto l849; - l852:; G->pos= yypos852; G->thunkpos= yythunkpos852; - } if (!yymatchDot(G)) goto l849; - } - l850:; goto l848; - l849:; G->pos= yypos849; G->thunkpos= yythunkpos849; - } if (!yy_HtmlBlockCloseTfoot(G)) { goto l847; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTfoot", G->buf+G->pos)); - return 1; - l847:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTfoot", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTfoot(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTfoot")); if (!yymatchChar(G, '<')) goto l853; if (!yy_Spnl(G)) { goto l853; } if (!yymatchChar(G, '/')) goto l853; - { int yypos854= G->pos, yythunkpos854= G->thunkpos; if (!yymatchString(G, "tfoot")) goto l855; goto l854; - l855:; G->pos= yypos854; G->thunkpos= yythunkpos854; if (!yymatchString(G, "TFOOT")) goto l853; - } - l854:; if (!yy_Spnl(G)) { goto l853; } if (!yymatchChar(G, '>')) goto l853; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTfoot", G->buf+G->pos)); - return 1; - l853:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTfoot", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTfoot(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTfoot")); if (!yymatchChar(G, '<')) goto l856; if (!yy_Spnl(G)) { goto l856; } - { int yypos857= G->pos, yythunkpos857= G->thunkpos; if (!yymatchString(G, "tfoot")) goto l858; goto l857; - l858:; G->pos= yypos857; G->thunkpos= yythunkpos857; if (!yymatchString(G, "TFOOT")) goto l856; - } - l857:; if (!yy_Spnl(G)) { goto l856; } - l859:; - { int yypos860= G->pos, yythunkpos860= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l860; } goto l859; - l860:; G->pos= yypos860; G->thunkpos= yythunkpos860; - } if (!yymatchChar(G, '>')) goto l856; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTfoot", G->buf+G->pos)); - return 1; - l856:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTfoot", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTd")); if (!yy_HtmlBlockOpenTd(G)) { goto l861; } - l862:; - { int yypos863= G->pos, yythunkpos863= G->thunkpos; - { int yypos864= G->pos, yythunkpos864= G->thunkpos; if (!yy_HtmlBlockTd(G)) { goto l865; } goto l864; - l865:; G->pos= yypos864; G->thunkpos= yythunkpos864; - { int yypos866= G->pos, yythunkpos866= G->thunkpos; if (!yy_HtmlBlockCloseTd(G)) { goto l866; } goto l863; - l866:; G->pos= yypos866; G->thunkpos= yythunkpos866; - } if (!yymatchDot(G)) goto l863; - } - l864:; goto l862; - l863:; G->pos= yypos863; G->thunkpos= yythunkpos863; - } if (!yy_HtmlBlockCloseTd(G)) { goto l861; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTd", G->buf+G->pos)); - return 1; - l861:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTd")); if (!yymatchChar(G, '<')) goto l867; if (!yy_Spnl(G)) { goto l867; } if (!yymatchChar(G, '/')) goto l867; - { int yypos868= G->pos, yythunkpos868= G->thunkpos; if (!yymatchString(G, "td")) goto l869; goto l868; - l869:; G->pos= yypos868; G->thunkpos= yythunkpos868; if (!yymatchString(G, "TD")) goto l867; - } - l868:; if (!yy_Spnl(G)) { goto l867; } if (!yymatchChar(G, '>')) goto l867; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTd", G->buf+G->pos)); - return 1; - l867:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTd")); if (!yymatchChar(G, '<')) goto l870; if (!yy_Spnl(G)) { goto l870; } - { int yypos871= G->pos, yythunkpos871= G->thunkpos; if (!yymatchString(G, "td")) goto l872; goto l871; - l872:; G->pos= yypos871; G->thunkpos= yythunkpos871; if (!yymatchString(G, "TD")) goto l870; - } - l871:; if (!yy_Spnl(G)) { goto l870; } - l873:; - { int yypos874= G->pos, yythunkpos874= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l874; } goto l873; - l874:; G->pos= yypos874; G->thunkpos= yythunkpos874; - } if (!yymatchChar(G, '>')) goto l870; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTd", G->buf+G->pos)); - return 1; - l870:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTbody(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTbody")); if (!yy_HtmlBlockOpenTbody(G)) { goto l875; } - l876:; - { int yypos877= G->pos, yythunkpos877= G->thunkpos; - { int yypos878= G->pos, yythunkpos878= G->thunkpos; if (!yy_HtmlBlockTbody(G)) { goto l879; } goto l878; - l879:; G->pos= yypos878; G->thunkpos= yythunkpos878; - { int yypos880= G->pos, yythunkpos880= G->thunkpos; if (!yy_HtmlBlockCloseTbody(G)) { goto l880; } goto l877; - l880:; G->pos= yypos880; G->thunkpos= yythunkpos880; - } if (!yymatchDot(G)) goto l877; - } - l878:; goto l876; - l877:; G->pos= yypos877; G->thunkpos= yythunkpos877; - } if (!yy_HtmlBlockCloseTbody(G)) { goto l875; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTbody", G->buf+G->pos)); - return 1; - l875:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTbody", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTbody(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTbody")); if (!yymatchChar(G, '<')) goto l881; if (!yy_Spnl(G)) { goto l881; } if (!yymatchChar(G, '/')) goto l881; - { int yypos882= G->pos, yythunkpos882= G->thunkpos; if (!yymatchString(G, "tbody")) goto l883; goto l882; - l883:; G->pos= yypos882; G->thunkpos= yythunkpos882; if (!yymatchString(G, "TBODY")) goto l881; - } - l882:; if (!yy_Spnl(G)) { goto l881; } if (!yymatchChar(G, '>')) goto l881; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTbody", G->buf+G->pos)); - return 1; - l881:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTbody", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTbody(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTbody")); if (!yymatchChar(G, '<')) goto l884; if (!yy_Spnl(G)) { goto l884; } - { int yypos885= G->pos, yythunkpos885= G->thunkpos; if (!yymatchString(G, "tbody")) goto l886; goto l885; - l886:; G->pos= yypos885; G->thunkpos= yythunkpos885; if (!yymatchString(G, "TBODY")) goto l884; - } - l885:; if (!yy_Spnl(G)) { goto l884; } - l887:; - { int yypos888= G->pos, yythunkpos888= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l888; } goto l887; - l888:; G->pos= yypos888; G->thunkpos= yythunkpos888; - } if (!yymatchChar(G, '>')) goto l884; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTbody", G->buf+G->pos)); - return 1; - l884:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTbody", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockLi(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockLi")); if (!yy_HtmlBlockOpenLi(G)) { goto l889; } - l890:; - { int yypos891= G->pos, yythunkpos891= G->thunkpos; - { int yypos892= G->pos, yythunkpos892= G->thunkpos; if (!yy_HtmlBlockLi(G)) { goto l893; } goto l892; - l893:; G->pos= yypos892; G->thunkpos= yythunkpos892; - { int yypos894= G->pos, yythunkpos894= G->thunkpos; if (!yy_HtmlBlockCloseLi(G)) { goto l894; } goto l891; - l894:; G->pos= yypos894; G->thunkpos= yythunkpos894; - } if (!yymatchDot(G)) goto l891; - } - l892:; goto l890; - l891:; G->pos= yypos891; G->thunkpos= yythunkpos891; - } if (!yy_HtmlBlockCloseLi(G)) { goto l889; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockLi", G->buf+G->pos)); - return 1; - l889:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockLi", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseLi(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseLi")); if (!yymatchChar(G, '<')) goto l895; if (!yy_Spnl(G)) { goto l895; } if (!yymatchChar(G, '/')) goto l895; - { int yypos896= G->pos, yythunkpos896= G->thunkpos; if (!yymatchString(G, "li")) goto l897; goto l896; - l897:; G->pos= yypos896; G->thunkpos= yythunkpos896; if (!yymatchString(G, "LI")) goto l895; - } - l896:; if (!yy_Spnl(G)) { goto l895; } if (!yymatchChar(G, '>')) goto l895; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseLi", G->buf+G->pos)); - return 1; - l895:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseLi", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenLi(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenLi")); if (!yymatchChar(G, '<')) goto l898; if (!yy_Spnl(G)) { goto l898; } - { int yypos899= G->pos, yythunkpos899= G->thunkpos; if (!yymatchString(G, "li")) goto l900; goto l899; - l900:; G->pos= yypos899; G->thunkpos= yythunkpos899; if (!yymatchString(G, "LI")) goto l898; - } - l899:; if (!yy_Spnl(G)) { goto l898; } - l901:; - { int yypos902= G->pos, yythunkpos902= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l902; } goto l901; - l902:; G->pos= yypos902; G->thunkpos= yythunkpos902; - } if (!yymatchChar(G, '>')) goto l898; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenLi", G->buf+G->pos)); - return 1; - l898:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenLi", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockFrameset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockFrameset")); if (!yy_HtmlBlockOpenFrameset(G)) { goto l903; } - l904:; - { int yypos905= G->pos, yythunkpos905= G->thunkpos; - { int yypos906= G->pos, yythunkpos906= G->thunkpos; if (!yy_HtmlBlockFrameset(G)) { goto l907; } goto l906; - l907:; G->pos= yypos906; G->thunkpos= yythunkpos906; - { int yypos908= G->pos, yythunkpos908= G->thunkpos; if (!yy_HtmlBlockCloseFrameset(G)) { goto l908; } goto l905; - l908:; G->pos= yypos908; G->thunkpos= yythunkpos908; - } if (!yymatchDot(G)) goto l905; - } - l906:; goto l904; - l905:; G->pos= yypos905; G->thunkpos= yythunkpos905; - } if (!yy_HtmlBlockCloseFrameset(G)) { goto l903; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockFrameset", G->buf+G->pos)); - return 1; - l903:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockFrameset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseFrameset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseFrameset")); if (!yymatchChar(G, '<')) goto l909; if (!yy_Spnl(G)) { goto l909; } if (!yymatchChar(G, '/')) goto l909; - { int yypos910= G->pos, yythunkpos910= G->thunkpos; if (!yymatchString(G, "frameset")) goto l911; goto l910; - l911:; G->pos= yypos910; G->thunkpos= yythunkpos910; if (!yymatchString(G, "FRAMESET")) goto l909; - } - l910:; if (!yy_Spnl(G)) { goto l909; } if (!yymatchChar(G, '>')) goto l909; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseFrameset", G->buf+G->pos)); - return 1; - l909:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseFrameset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenFrameset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenFrameset")); if (!yymatchChar(G, '<')) goto l912; if (!yy_Spnl(G)) { goto l912; } - { int yypos913= G->pos, yythunkpos913= G->thunkpos; if (!yymatchString(G, "frameset")) goto l914; goto l913; - l914:; G->pos= yypos913; G->thunkpos= yythunkpos913; if (!yymatchString(G, "FRAMESET")) goto l912; - } - l913:; if (!yy_Spnl(G)) { goto l912; } - l915:; - { int yypos916= G->pos, yythunkpos916= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l916; } goto l915; - l916:; G->pos= yypos916; G->thunkpos= yythunkpos916; - } if (!yymatchChar(G, '>')) goto l912; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenFrameset", G->buf+G->pos)); - return 1; - l912:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenFrameset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDt(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDt")); if (!yy_HtmlBlockOpenDt(G)) { goto l917; } - l918:; - { int yypos919= G->pos, yythunkpos919= G->thunkpos; - { int yypos920= G->pos, yythunkpos920= G->thunkpos; if (!yy_HtmlBlockDt(G)) { goto l921; } goto l920; - l921:; G->pos= yypos920; G->thunkpos= yythunkpos920; - { int yypos922= G->pos, yythunkpos922= G->thunkpos; if (!yy_HtmlBlockCloseDt(G)) { goto l922; } goto l919; - l922:; G->pos= yypos922; G->thunkpos= yythunkpos922; - } if (!yymatchDot(G)) goto l919; - } - l920:; goto l918; - l919:; G->pos= yypos919; G->thunkpos= yythunkpos919; - } if (!yy_HtmlBlockCloseDt(G)) { goto l917; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDt", G->buf+G->pos)); - return 1; - l917:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDt", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDt(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDt")); if (!yymatchChar(G, '<')) goto l923; if (!yy_Spnl(G)) { goto l923; } if (!yymatchChar(G, '/')) goto l923; - { int yypos924= G->pos, yythunkpos924= G->thunkpos; if (!yymatchString(G, "dt")) goto l925; goto l924; - l925:; G->pos= yypos924; G->thunkpos= yythunkpos924; if (!yymatchString(G, "DT")) goto l923; - } - l924:; if (!yy_Spnl(G)) { goto l923; } if (!yymatchChar(G, '>')) goto l923; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDt", G->buf+G->pos)); - return 1; - l923:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDt", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDt(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDt")); if (!yymatchChar(G, '<')) goto l926; if (!yy_Spnl(G)) { goto l926; } - { int yypos927= G->pos, yythunkpos927= G->thunkpos; if (!yymatchString(G, "dt")) goto l928; goto l927; - l928:; G->pos= yypos927; G->thunkpos= yythunkpos927; if (!yymatchString(G, "DT")) goto l926; - } - l927:; if (!yy_Spnl(G)) { goto l926; } - l929:; - { int yypos930= G->pos, yythunkpos930= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l930; } goto l929; - l930:; G->pos= yypos930; G->thunkpos= yythunkpos930; - } if (!yymatchChar(G, '>')) goto l926; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDt", G->buf+G->pos)); - return 1; - l926:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDt", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDd")); if (!yy_HtmlBlockOpenDd(G)) { goto l931; } - l932:; - { int yypos933= G->pos, yythunkpos933= G->thunkpos; - { int yypos934= G->pos, yythunkpos934= G->thunkpos; if (!yy_HtmlBlockDd(G)) { goto l935; } goto l934; - l935:; G->pos= yypos934; G->thunkpos= yythunkpos934; - { int yypos936= G->pos, yythunkpos936= G->thunkpos; if (!yy_HtmlBlockCloseDd(G)) { goto l936; } goto l933; - l936:; G->pos= yypos936; G->thunkpos= yythunkpos936; - } if (!yymatchDot(G)) goto l933; - } - l934:; goto l932; - l933:; G->pos= yypos933; G->thunkpos= yythunkpos933; - } if (!yy_HtmlBlockCloseDd(G)) { goto l931; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDd", G->buf+G->pos)); - return 1; - l931:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDd")); if (!yymatchChar(G, '<')) goto l937; if (!yy_Spnl(G)) { goto l937; } if (!yymatchChar(G, '/')) goto l937; - { int yypos938= G->pos, yythunkpos938= G->thunkpos; if (!yymatchString(G, "dd")) goto l939; goto l938; - l939:; G->pos= yypos938; G->thunkpos= yythunkpos938; if (!yymatchString(G, "DD")) goto l937; - } - l938:; if (!yy_Spnl(G)) { goto l937; } if (!yymatchChar(G, '>')) goto l937; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDd", G->buf+G->pos)); - return 1; - l937:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDd")); if (!yymatchChar(G, '<')) goto l940; if (!yy_Spnl(G)) { goto l940; } - { int yypos941= G->pos, yythunkpos941= G->thunkpos; if (!yymatchString(G, "dd")) goto l942; goto l941; - l942:; G->pos= yypos941; G->thunkpos= yythunkpos941; if (!yymatchString(G, "DD")) goto l940; - } - l941:; if (!yy_Spnl(G)) { goto l940; } - l943:; - { int yypos944= G->pos, yythunkpos944= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l944; } goto l943; - l944:; G->pos= yypos944; G->thunkpos= yythunkpos944; - } if (!yymatchChar(G, '>')) goto l940; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDd", G->buf+G->pos)); - return 1; - l940:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockUl")); if (!yy_HtmlBlockOpenUl(G)) { goto l945; } - l946:; - { int yypos947= G->pos, yythunkpos947= G->thunkpos; - { int yypos948= G->pos, yythunkpos948= G->thunkpos; if (!yy_HtmlBlockUl(G)) { goto l949; } goto l948; - l949:; G->pos= yypos948; G->thunkpos= yythunkpos948; - { int yypos950= G->pos, yythunkpos950= G->thunkpos; if (!yy_HtmlBlockCloseUl(G)) { goto l950; } goto l947; - l950:; G->pos= yypos950; G->thunkpos= yythunkpos950; - } if (!yymatchDot(G)) goto l947; - } - l948:; goto l946; - l947:; G->pos= yypos947; G->thunkpos= yythunkpos947; - } if (!yy_HtmlBlockCloseUl(G)) { goto l945; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockUl", G->buf+G->pos)); - return 1; - l945:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseUl")); if (!yymatchChar(G, '<')) goto l951; if (!yy_Spnl(G)) { goto l951; } if (!yymatchChar(G, '/')) goto l951; - { int yypos952= G->pos, yythunkpos952= G->thunkpos; if (!yymatchString(G, "ul")) goto l953; goto l952; - l953:; G->pos= yypos952; G->thunkpos= yythunkpos952; if (!yymatchString(G, "UL")) goto l951; - } - l952:; if (!yy_Spnl(G)) { goto l951; } if (!yymatchChar(G, '>')) goto l951; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseUl", G->buf+G->pos)); - return 1; - l951:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenUl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenUl")); if (!yymatchChar(G, '<')) goto l954; if (!yy_Spnl(G)) { goto l954; } - { int yypos955= G->pos, yythunkpos955= G->thunkpos; if (!yymatchString(G, "ul")) goto l956; goto l955; - l956:; G->pos= yypos955; G->thunkpos= yythunkpos955; if (!yymatchString(G, "UL")) goto l954; - } - l955:; if (!yy_Spnl(G)) { goto l954; } - l957:; - { int yypos958= G->pos, yythunkpos958= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l958; } goto l957; - l958:; G->pos= yypos958; G->thunkpos= yythunkpos958; - } if (!yymatchChar(G, '>')) goto l954; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenUl", G->buf+G->pos)); - return 1; - l954:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenUl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockTable(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockTable")); if (!yy_HtmlBlockOpenTable(G)) { goto l959; } - l960:; - { int yypos961= G->pos, yythunkpos961= G->thunkpos; - { int yypos962= G->pos, yythunkpos962= G->thunkpos; if (!yy_HtmlBlockTable(G)) { goto l963; } goto l962; - l963:; G->pos= yypos962; G->thunkpos= yythunkpos962; - { int yypos964= G->pos, yythunkpos964= G->thunkpos; if (!yy_HtmlBlockCloseTable(G)) { goto l964; } goto l961; - l964:; G->pos= yypos964; G->thunkpos= yythunkpos964; - } if (!yymatchDot(G)) goto l961; - } - l962:; goto l960; - l961:; G->pos= yypos961; G->thunkpos= yythunkpos961; - } if (!yy_HtmlBlockCloseTable(G)) { goto l959; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTable", G->buf+G->pos)); - return 1; - l959:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTable", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseTable(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseTable")); if (!yymatchChar(G, '<')) goto l965; if (!yy_Spnl(G)) { goto l965; } if (!yymatchChar(G, '/')) goto l965; - { int yypos966= G->pos, yythunkpos966= G->thunkpos; if (!yymatchString(G, "table")) goto l967; goto l966; - l967:; G->pos= yypos966; G->thunkpos= yythunkpos966; if (!yymatchString(G, "TABLE")) goto l965; - } - l966:; if (!yy_Spnl(G)) { goto l965; } if (!yymatchChar(G, '>')) goto l965; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTable", G->buf+G->pos)); - return 1; - l965:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTable", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenTable(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenTable")); if (!yymatchChar(G, '<')) goto l968; if (!yy_Spnl(G)) { goto l968; } - { int yypos969= G->pos, yythunkpos969= G->thunkpos; if (!yymatchString(G, "table")) goto l970; goto l969; - l970:; G->pos= yypos969; G->thunkpos= yythunkpos969; if (!yymatchString(G, "TABLE")) goto l968; - } - l969:; if (!yy_Spnl(G)) { goto l968; } - l971:; - { int yypos972= G->pos, yythunkpos972= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l972; } goto l971; - l972:; G->pos= yypos972; G->thunkpos= yythunkpos972; - } if (!yymatchChar(G, '>')) goto l968; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTable", G->buf+G->pos)); - return 1; - l968:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTable", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockPre(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockPre")); if (!yy_HtmlBlockOpenPre(G)) { goto l973; } - l974:; - { int yypos975= G->pos, yythunkpos975= G->thunkpos; - { int yypos976= G->pos, yythunkpos976= G->thunkpos; if (!yy_HtmlBlockPre(G)) { goto l977; } goto l976; - l977:; G->pos= yypos976; G->thunkpos= yythunkpos976; - { int yypos978= G->pos, yythunkpos978= G->thunkpos; if (!yy_HtmlBlockClosePre(G)) { goto l978; } goto l975; - l978:; G->pos= yypos978; G->thunkpos= yythunkpos978; - } if (!yymatchDot(G)) goto l975; - } - l976:; goto l974; - l975:; G->pos= yypos975; G->thunkpos= yythunkpos975; - } if (!yy_HtmlBlockClosePre(G)) { goto l973; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockPre", G->buf+G->pos)); - return 1; - l973:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockPre", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockClosePre(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockClosePre")); if (!yymatchChar(G, '<')) goto l979; if (!yy_Spnl(G)) { goto l979; } if (!yymatchChar(G, '/')) goto l979; - { int yypos980= G->pos, yythunkpos980= G->thunkpos; if (!yymatchString(G, "pre")) goto l981; goto l980; - l981:; G->pos= yypos980; G->thunkpos= yythunkpos980; if (!yymatchString(G, "PRE")) goto l979; - } - l980:; if (!yy_Spnl(G)) { goto l979; } if (!yymatchChar(G, '>')) goto l979; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockClosePre", G->buf+G->pos)); - return 1; - l979:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockClosePre", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenPre(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenPre")); if (!yymatchChar(G, '<')) goto l982; if (!yy_Spnl(G)) { goto l982; } - { int yypos983= G->pos, yythunkpos983= G->thunkpos; if (!yymatchString(G, "pre")) goto l984; goto l983; - l984:; G->pos= yypos983; G->thunkpos= yythunkpos983; if (!yymatchString(G, "PRE")) goto l982; - } - l983:; if (!yy_Spnl(G)) { goto l982; } - l985:; - { int yypos986= G->pos, yythunkpos986= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l986; } goto l985; - l986:; G->pos= yypos986; G->thunkpos= yythunkpos986; - } if (!yymatchChar(G, '>')) goto l982; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenPre", G->buf+G->pos)); - return 1; - l982:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenPre", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockP(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockP")); if (!yy_HtmlBlockOpenP(G)) { goto l987; } - l988:; - { int yypos989= G->pos, yythunkpos989= G->thunkpos; - { int yypos990= G->pos, yythunkpos990= G->thunkpos; if (!yy_HtmlBlockP(G)) { goto l991; } goto l990; - l991:; G->pos= yypos990; G->thunkpos= yythunkpos990; - { int yypos992= G->pos, yythunkpos992= G->thunkpos; if (!yy_HtmlBlockCloseP(G)) { goto l992; } goto l989; - l992:; G->pos= yypos992; G->thunkpos= yythunkpos992; - } if (!yymatchDot(G)) goto l989; - } - l990:; goto l988; - l989:; G->pos= yypos989; G->thunkpos= yythunkpos989; - } if (!yy_HtmlBlockCloseP(G)) { goto l987; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockP", G->buf+G->pos)); - return 1; - l987:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockP", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseP(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseP")); if (!yymatchChar(G, '<')) goto l993; if (!yy_Spnl(G)) { goto l993; } if (!yymatchChar(G, '/')) goto l993; - { int yypos994= G->pos, yythunkpos994= G->thunkpos; if (!yymatchChar(G, 'p')) goto l995; goto l994; - l995:; G->pos= yypos994; G->thunkpos= yythunkpos994; if (!yymatchChar(G, 'P')) goto l993; - } - l994:; if (!yy_Spnl(G)) { goto l993; } if (!yymatchChar(G, '>')) goto l993; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseP", G->buf+G->pos)); - return 1; - l993:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseP", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenP(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenP")); if (!yymatchChar(G, '<')) goto l996; if (!yy_Spnl(G)) { goto l996; } - { int yypos997= G->pos, yythunkpos997= G->thunkpos; if (!yymatchChar(G, 'p')) goto l998; goto l997; - l998:; G->pos= yypos997; G->thunkpos= yythunkpos997; if (!yymatchChar(G, 'P')) goto l996; - } - l997:; if (!yy_Spnl(G)) { goto l996; } - l999:; - { int yypos1000= G->pos, yythunkpos1000= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1000; } goto l999; - l1000:; G->pos= yypos1000; G->thunkpos= yythunkpos1000; - } if (!yymatchChar(G, '>')) goto l996; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenP", G->buf+G->pos)); - return 1; - l996:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenP", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOl")); if (!yy_HtmlBlockOpenOl(G)) { goto l1001; } - l1002:; - { int yypos1003= G->pos, yythunkpos1003= G->thunkpos; - { int yypos1004= G->pos, yythunkpos1004= G->thunkpos; if (!yy_HtmlBlockOl(G)) { goto l1005; } goto l1004; - l1005:; G->pos= yypos1004; G->thunkpos= yythunkpos1004; - { int yypos1006= G->pos, yythunkpos1006= G->thunkpos; if (!yy_HtmlBlockCloseOl(G)) { goto l1006; } goto l1003; - l1006:; G->pos= yypos1006; G->thunkpos= yythunkpos1006; - } if (!yymatchDot(G)) goto l1003; - } - l1004:; goto l1002; - l1003:; G->pos= yypos1003; G->thunkpos= yythunkpos1003; - } if (!yy_HtmlBlockCloseOl(G)) { goto l1001; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOl", G->buf+G->pos)); - return 1; - l1001:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseOl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseOl")); if (!yymatchChar(G, '<')) goto l1007; if (!yy_Spnl(G)) { goto l1007; } if (!yymatchChar(G, '/')) goto l1007; - { int yypos1008= G->pos, yythunkpos1008= G->thunkpos; if (!yymatchString(G, "ol")) goto l1009; goto l1008; - l1009:; G->pos= yypos1008; G->thunkpos= yythunkpos1008; if (!yymatchString(G, "OL")) goto l1007; - } - l1008:; if (!yy_Spnl(G)) { goto l1007; } if (!yymatchChar(G, '>')) goto l1007; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseOl", G->buf+G->pos)); - return 1; - l1007:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseOl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenOl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenOl")); if (!yymatchChar(G, '<')) goto l1010; if (!yy_Spnl(G)) { goto l1010; } - { int yypos1011= G->pos, yythunkpos1011= G->thunkpos; if (!yymatchString(G, "ol")) goto l1012; goto l1011; - l1012:; G->pos= yypos1011; G->thunkpos= yythunkpos1011; if (!yymatchString(G, "OL")) goto l1010; - } - l1011:; if (!yy_Spnl(G)) { goto l1010; } - l1013:; - { int yypos1014= G->pos, yythunkpos1014= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1014; } goto l1013; - l1014:; G->pos= yypos1014; G->thunkpos= yythunkpos1014; - } if (!yymatchChar(G, '>')) goto l1010; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenOl", G->buf+G->pos)); - return 1; - l1010:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenOl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockNoscript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockNoscript")); if (!yy_HtmlBlockOpenNoscript(G)) { goto l1015; } - l1016:; - { int yypos1017= G->pos, yythunkpos1017= G->thunkpos; - { int yypos1018= G->pos, yythunkpos1018= G->thunkpos; if (!yy_HtmlBlockNoscript(G)) { goto l1019; } goto l1018; - l1019:; G->pos= yypos1018; G->thunkpos= yythunkpos1018; - { int yypos1020= G->pos, yythunkpos1020= G->thunkpos; if (!yy_HtmlBlockCloseNoscript(G)) { goto l1020; } goto l1017; - l1020:; G->pos= yypos1020; G->thunkpos= yythunkpos1020; - } if (!yymatchDot(G)) goto l1017; - } - l1018:; goto l1016; - l1017:; G->pos= yypos1017; G->thunkpos= yythunkpos1017; - } if (!yy_HtmlBlockCloseNoscript(G)) { goto l1015; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockNoscript", G->buf+G->pos)); - return 1; - l1015:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockNoscript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseNoscript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseNoscript")); if (!yymatchChar(G, '<')) goto l1021; if (!yy_Spnl(G)) { goto l1021; } if (!yymatchChar(G, '/')) goto l1021; - { int yypos1022= G->pos, yythunkpos1022= G->thunkpos; if (!yymatchString(G, "noscript")) goto l1023; goto l1022; - l1023:; G->pos= yypos1022; G->thunkpos= yythunkpos1022; if (!yymatchString(G, "NOSCRIPT")) goto l1021; - } - l1022:; if (!yy_Spnl(G)) { goto l1021; } if (!yymatchChar(G, '>')) goto l1021; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseNoscript", G->buf+G->pos)); - return 1; - l1021:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseNoscript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenNoscript(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenNoscript")); if (!yymatchChar(G, '<')) goto l1024; if (!yy_Spnl(G)) { goto l1024; } - { int yypos1025= G->pos, yythunkpos1025= G->thunkpos; if (!yymatchString(G, "noscript")) goto l1026; goto l1025; - l1026:; G->pos= yypos1025; G->thunkpos= yythunkpos1025; if (!yymatchString(G, "NOSCRIPT")) goto l1024; - } - l1025:; if (!yy_Spnl(G)) { goto l1024; } - l1027:; - { int yypos1028= G->pos, yythunkpos1028= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1028; } goto l1027; - l1028:; G->pos= yypos1028; G->thunkpos= yythunkpos1028; - } if (!yymatchChar(G, '>')) goto l1024; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenNoscript", G->buf+G->pos)); - return 1; - l1024:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenNoscript", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockNoframes(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockNoframes")); if (!yy_HtmlBlockOpenNoframes(G)) { goto l1029; } - l1030:; - { int yypos1031= G->pos, yythunkpos1031= G->thunkpos; - { int yypos1032= G->pos, yythunkpos1032= G->thunkpos; if (!yy_HtmlBlockNoframes(G)) { goto l1033; } goto l1032; - l1033:; G->pos= yypos1032; G->thunkpos= yythunkpos1032; - { int yypos1034= G->pos, yythunkpos1034= G->thunkpos; if (!yy_HtmlBlockCloseNoframes(G)) { goto l1034; } goto l1031; - l1034:; G->pos= yypos1034; G->thunkpos= yythunkpos1034; - } if (!yymatchDot(G)) goto l1031; - } - l1032:; goto l1030; - l1031:; G->pos= yypos1031; G->thunkpos= yythunkpos1031; - } if (!yy_HtmlBlockCloseNoframes(G)) { goto l1029; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockNoframes", G->buf+G->pos)); - return 1; - l1029:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockNoframes", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseNoframes(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseNoframes")); if (!yymatchChar(G, '<')) goto l1035; if (!yy_Spnl(G)) { goto l1035; } if (!yymatchChar(G, '/')) goto l1035; - { int yypos1036= G->pos, yythunkpos1036= G->thunkpos; if (!yymatchString(G, "noframes")) goto l1037; goto l1036; - l1037:; G->pos= yypos1036; G->thunkpos= yythunkpos1036; if (!yymatchString(G, "NOFRAMES")) goto l1035; - } - l1036:; if (!yy_Spnl(G)) { goto l1035; } if (!yymatchChar(G, '>')) goto l1035; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseNoframes", G->buf+G->pos)); - return 1; - l1035:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseNoframes", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenNoframes(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenNoframes")); if (!yymatchChar(G, '<')) goto l1038; if (!yy_Spnl(G)) { goto l1038; } - { int yypos1039= G->pos, yythunkpos1039= G->thunkpos; if (!yymatchString(G, "noframes")) goto l1040; goto l1039; - l1040:; G->pos= yypos1039; G->thunkpos= yythunkpos1039; if (!yymatchString(G, "NOFRAMES")) goto l1038; - } - l1039:; if (!yy_Spnl(G)) { goto l1038; } - l1041:; - { int yypos1042= G->pos, yythunkpos1042= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1042; } goto l1041; - l1042:; G->pos= yypos1042; G->thunkpos= yythunkpos1042; - } if (!yymatchChar(G, '>')) goto l1038; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenNoframes", G->buf+G->pos)); - return 1; - l1038:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenNoframes", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockMenu(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockMenu")); if (!yy_HtmlBlockOpenMenu(G)) { goto l1043; } - l1044:; - { int yypos1045= G->pos, yythunkpos1045= G->thunkpos; - { int yypos1046= G->pos, yythunkpos1046= G->thunkpos; if (!yy_HtmlBlockMenu(G)) { goto l1047; } goto l1046; - l1047:; G->pos= yypos1046; G->thunkpos= yythunkpos1046; - { int yypos1048= G->pos, yythunkpos1048= G->thunkpos; if (!yy_HtmlBlockCloseMenu(G)) { goto l1048; } goto l1045; - l1048:; G->pos= yypos1048; G->thunkpos= yythunkpos1048; - } if (!yymatchDot(G)) goto l1045; - } - l1046:; goto l1044; - l1045:; G->pos= yypos1045; G->thunkpos= yythunkpos1045; - } if (!yy_HtmlBlockCloseMenu(G)) { goto l1043; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockMenu", G->buf+G->pos)); - return 1; - l1043:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockMenu", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseMenu(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseMenu")); if (!yymatchChar(G, '<')) goto l1049; if (!yy_Spnl(G)) { goto l1049; } if (!yymatchChar(G, '/')) goto l1049; - { int yypos1050= G->pos, yythunkpos1050= G->thunkpos; if (!yymatchString(G, "menu")) goto l1051; goto l1050; - l1051:; G->pos= yypos1050; G->thunkpos= yythunkpos1050; if (!yymatchString(G, "MENU")) goto l1049; - } - l1050:; if (!yy_Spnl(G)) { goto l1049; } if (!yymatchChar(G, '>')) goto l1049; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseMenu", G->buf+G->pos)); - return 1; - l1049:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseMenu", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenMenu(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenMenu")); if (!yymatchChar(G, '<')) goto l1052; if (!yy_Spnl(G)) { goto l1052; } - { int yypos1053= G->pos, yythunkpos1053= G->thunkpos; if (!yymatchString(G, "menu")) goto l1054; goto l1053; - l1054:; G->pos= yypos1053; G->thunkpos= yythunkpos1053; if (!yymatchString(G, "MENU")) goto l1052; - } - l1053:; if (!yy_Spnl(G)) { goto l1052; } - l1055:; - { int yypos1056= G->pos, yythunkpos1056= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1056; } goto l1055; - l1056:; G->pos= yypos1056; G->thunkpos= yythunkpos1056; - } if (!yymatchChar(G, '>')) goto l1052; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenMenu", G->buf+G->pos)); - return 1; - l1052:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenMenu", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH6(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH6")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1057; if (!yy_LocMarker(G)) { goto l1057; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH6(G)) { goto l1057; } - l1058:; - { int yypos1059= G->pos, yythunkpos1059= G->thunkpos; - { int yypos1060= G->pos, yythunkpos1060= G->thunkpos; if (!yy_HtmlBlockH6(G)) { goto l1061; } goto l1060; - l1061:; G->pos= yypos1060; G->thunkpos= yythunkpos1060; - { int yypos1062= G->pos, yythunkpos1062= G->thunkpos; if (!yy_HtmlBlockCloseH6(G)) { goto l1062; } goto l1059; - l1062:; G->pos= yypos1062; G->thunkpos= yythunkpos1062; - } if (!yymatchDot(G)) goto l1059; - } - l1060:; goto l1058; - l1059:; G->pos= yypos1059; G->thunkpos= yythunkpos1059; - } if (!yy_HtmlBlockCloseH6(G)) { goto l1057; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1057; yyDo(G, yy_1_HtmlBlockH6, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH6", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1057:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH6", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH6(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH6")); if (!yymatchChar(G, '<')) goto l1063; if (!yy_Spnl(G)) { goto l1063; } if (!yymatchChar(G, '/')) goto l1063; - { int yypos1064= G->pos, yythunkpos1064= G->thunkpos; if (!yymatchString(G, "h6")) goto l1065; goto l1064; - l1065:; G->pos= yypos1064; G->thunkpos= yythunkpos1064; if (!yymatchString(G, "H6")) goto l1063; - } - l1064:; if (!yy_Spnl(G)) { goto l1063; } if (!yymatchChar(G, '>')) goto l1063; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH6", G->buf+G->pos)); - return 1; - l1063:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH6", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH6(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH6")); if (!yymatchChar(G, '<')) goto l1066; if (!yy_Spnl(G)) { goto l1066; } - { int yypos1067= G->pos, yythunkpos1067= G->thunkpos; if (!yymatchString(G, "h6")) goto l1068; goto l1067; - l1068:; G->pos= yypos1067; G->thunkpos= yythunkpos1067; if (!yymatchString(G, "H6")) goto l1066; - } - l1067:; if (!yy_Spnl(G)) { goto l1066; } - l1069:; - { int yypos1070= G->pos, yythunkpos1070= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1070; } goto l1069; - l1070:; G->pos= yypos1070; G->thunkpos= yythunkpos1070; - } if (!yymatchChar(G, '>')) goto l1066; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH6", G->buf+G->pos)); - return 1; - l1066:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH6", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH5(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH5")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1071; if (!yy_LocMarker(G)) { goto l1071; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH5(G)) { goto l1071; } - l1072:; - { int yypos1073= G->pos, yythunkpos1073= G->thunkpos; - { int yypos1074= G->pos, yythunkpos1074= G->thunkpos; if (!yy_HtmlBlockH5(G)) { goto l1075; } goto l1074; - l1075:; G->pos= yypos1074; G->thunkpos= yythunkpos1074; - { int yypos1076= G->pos, yythunkpos1076= G->thunkpos; if (!yy_HtmlBlockCloseH5(G)) { goto l1076; } goto l1073; - l1076:; G->pos= yypos1076; G->thunkpos= yythunkpos1076; - } if (!yymatchDot(G)) goto l1073; - } - l1074:; goto l1072; - l1073:; G->pos= yypos1073; G->thunkpos= yythunkpos1073; - } if (!yy_HtmlBlockCloseH5(G)) { goto l1071; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1071; yyDo(G, yy_1_HtmlBlockH5, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH5", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1071:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH5", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH5(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH5")); if (!yymatchChar(G, '<')) goto l1077; if (!yy_Spnl(G)) { goto l1077; } if (!yymatchChar(G, '/')) goto l1077; - { int yypos1078= G->pos, yythunkpos1078= G->thunkpos; if (!yymatchString(G, "h5")) goto l1079; goto l1078; - l1079:; G->pos= yypos1078; G->thunkpos= yythunkpos1078; if (!yymatchString(G, "H5")) goto l1077; - } - l1078:; if (!yy_Spnl(G)) { goto l1077; } if (!yymatchChar(G, '>')) goto l1077; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH5", G->buf+G->pos)); - return 1; - l1077:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH5", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH5(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH5")); if (!yymatchChar(G, '<')) goto l1080; if (!yy_Spnl(G)) { goto l1080; } - { int yypos1081= G->pos, yythunkpos1081= G->thunkpos; if (!yymatchString(G, "h5")) goto l1082; goto l1081; - l1082:; G->pos= yypos1081; G->thunkpos= yythunkpos1081; if (!yymatchString(G, "H5")) goto l1080; - } - l1081:; if (!yy_Spnl(G)) { goto l1080; } - l1083:; - { int yypos1084= G->pos, yythunkpos1084= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1084; } goto l1083; - l1084:; G->pos= yypos1084; G->thunkpos= yythunkpos1084; - } if (!yymatchChar(G, '>')) goto l1080; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH5", G->buf+G->pos)); - return 1; - l1080:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH5", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH4(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH4")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1085; if (!yy_LocMarker(G)) { goto l1085; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH4(G)) { goto l1085; } - l1086:; - { int yypos1087= G->pos, yythunkpos1087= G->thunkpos; - { int yypos1088= G->pos, yythunkpos1088= G->thunkpos; if (!yy_HtmlBlockH4(G)) { goto l1089; } goto l1088; - l1089:; G->pos= yypos1088; G->thunkpos= yythunkpos1088; - { int yypos1090= G->pos, yythunkpos1090= G->thunkpos; if (!yy_HtmlBlockCloseH4(G)) { goto l1090; } goto l1087; - l1090:; G->pos= yypos1090; G->thunkpos= yythunkpos1090; - } if (!yymatchDot(G)) goto l1087; - } - l1088:; goto l1086; - l1087:; G->pos= yypos1087; G->thunkpos= yythunkpos1087; - } if (!yy_HtmlBlockCloseH4(G)) { goto l1085; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1085; yyDo(G, yy_1_HtmlBlockH4, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH4", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1085:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH4", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH4(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH4")); if (!yymatchChar(G, '<')) goto l1091; if (!yy_Spnl(G)) { goto l1091; } if (!yymatchChar(G, '/')) goto l1091; - { int yypos1092= G->pos, yythunkpos1092= G->thunkpos; if (!yymatchString(G, "h4")) goto l1093; goto l1092; - l1093:; G->pos= yypos1092; G->thunkpos= yythunkpos1092; if (!yymatchString(G, "H4")) goto l1091; - } - l1092:; if (!yy_Spnl(G)) { goto l1091; } if (!yymatchChar(G, '>')) goto l1091; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH4", G->buf+G->pos)); - return 1; - l1091:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH4", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH4(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH4")); if (!yymatchChar(G, '<')) goto l1094; if (!yy_Spnl(G)) { goto l1094; } - { int yypos1095= G->pos, yythunkpos1095= G->thunkpos; if (!yymatchString(G, "h4")) goto l1096; goto l1095; - l1096:; G->pos= yypos1095; G->thunkpos= yythunkpos1095; if (!yymatchString(G, "H4")) goto l1094; - } - l1095:; if (!yy_Spnl(G)) { goto l1094; } - l1097:; - { int yypos1098= G->pos, yythunkpos1098= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1098; } goto l1097; - l1098:; G->pos= yypos1098; G->thunkpos= yythunkpos1098; - } if (!yymatchChar(G, '>')) goto l1094; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH4", G->buf+G->pos)); - return 1; - l1094:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH4", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH3(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH3")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1099; if (!yy_LocMarker(G)) { goto l1099; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH3(G)) { goto l1099; } - l1100:; - { int yypos1101= G->pos, yythunkpos1101= G->thunkpos; - { int yypos1102= G->pos, yythunkpos1102= G->thunkpos; if (!yy_HtmlBlockH3(G)) { goto l1103; } goto l1102; - l1103:; G->pos= yypos1102; G->thunkpos= yythunkpos1102; - { int yypos1104= G->pos, yythunkpos1104= G->thunkpos; if (!yy_HtmlBlockCloseH3(G)) { goto l1104; } goto l1101; - l1104:; G->pos= yypos1104; G->thunkpos= yythunkpos1104; - } if (!yymatchDot(G)) goto l1101; - } - l1102:; goto l1100; - l1101:; G->pos= yypos1101; G->thunkpos= yythunkpos1101; - } if (!yy_HtmlBlockCloseH3(G)) { goto l1099; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1099; yyDo(G, yy_1_HtmlBlockH3, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH3", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1099:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH3", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH3(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH3")); if (!yymatchChar(G, '<')) goto l1105; if (!yy_Spnl(G)) { goto l1105; } if (!yymatchChar(G, '/')) goto l1105; - { int yypos1106= G->pos, yythunkpos1106= G->thunkpos; if (!yymatchString(G, "h3")) goto l1107; goto l1106; - l1107:; G->pos= yypos1106; G->thunkpos= yythunkpos1106; if (!yymatchString(G, "H3")) goto l1105; - } - l1106:; if (!yy_Spnl(G)) { goto l1105; } if (!yymatchChar(G, '>')) goto l1105; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH3", G->buf+G->pos)); - return 1; - l1105:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH3", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH3(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH3")); if (!yymatchChar(G, '<')) goto l1108; if (!yy_Spnl(G)) { goto l1108; } - { int yypos1109= G->pos, yythunkpos1109= G->thunkpos; if (!yymatchString(G, "h3")) goto l1110; goto l1109; - l1110:; G->pos= yypos1109; G->thunkpos= yythunkpos1109; if (!yymatchString(G, "H3")) goto l1108; - } - l1109:; if (!yy_Spnl(G)) { goto l1108; } - l1111:; - { int yypos1112= G->pos, yythunkpos1112= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1112; } goto l1111; - l1112:; G->pos= yypos1112; G->thunkpos= yythunkpos1112; - } if (!yymatchChar(G, '>')) goto l1108; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH3", G->buf+G->pos)); - return 1; - l1108:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH3", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH2")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1113; if (!yy_LocMarker(G)) { goto l1113; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH2(G)) { goto l1113; } - l1114:; - { int yypos1115= G->pos, yythunkpos1115= G->thunkpos; - { int yypos1116= G->pos, yythunkpos1116= G->thunkpos; if (!yy_HtmlBlockH2(G)) { goto l1117; } goto l1116; - l1117:; G->pos= yypos1116; G->thunkpos= yythunkpos1116; - { int yypos1118= G->pos, yythunkpos1118= G->thunkpos; if (!yy_HtmlBlockCloseH2(G)) { goto l1118; } goto l1115; - l1118:; G->pos= yypos1118; G->thunkpos= yythunkpos1118; - } if (!yymatchDot(G)) goto l1115; - } - l1116:; goto l1114; - l1115:; G->pos= yypos1115; G->thunkpos= yythunkpos1115; - } if (!yy_HtmlBlockCloseH2(G)) { goto l1113; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1113; yyDo(G, yy_1_HtmlBlockH2, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH2", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1113:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH2")); if (!yymatchChar(G, '<')) goto l1119; if (!yy_Spnl(G)) { goto l1119; } if (!yymatchChar(G, '/')) goto l1119; - { int yypos1120= G->pos, yythunkpos1120= G->thunkpos; if (!yymatchString(G, "h2")) goto l1121; goto l1120; - l1121:; G->pos= yypos1120; G->thunkpos= yythunkpos1120; if (!yymatchString(G, "H2")) goto l1119; - } - l1120:; if (!yy_Spnl(G)) { goto l1119; } if (!yymatchChar(G, '>')) goto l1119; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH2", G->buf+G->pos)); - return 1; - l1119:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH2")); if (!yymatchChar(G, '<')) goto l1122; if (!yy_Spnl(G)) { goto l1122; } - { int yypos1123= G->pos, yythunkpos1123= G->thunkpos; if (!yymatchString(G, "h2")) goto l1124; goto l1123; - l1124:; G->pos= yypos1123; G->thunkpos= yythunkpos1123; if (!yymatchString(G, "H2")) goto l1122; - } - l1123:; if (!yy_Spnl(G)) { goto l1122; } - l1125:; - { int yypos1126= G->pos, yythunkpos1126= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1126; } goto l1125; - l1126:; G->pos= yypos1126; G->thunkpos= yythunkpos1126; - } if (!yymatchChar(G, '>')) goto l1122; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH2", G->buf+G->pos)); - return 1; - l1122:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockH1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlockH1")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1127; if (!yy_LocMarker(G)) { goto l1127; } yyDo(G, yySet, -1, 0); if (!yy_HtmlBlockOpenH1(G)) { goto l1127; } - l1128:; - { int yypos1129= G->pos, yythunkpos1129= G->thunkpos; - { int yypos1130= G->pos, yythunkpos1130= G->thunkpos; if (!yy_HtmlBlockH1(G)) { goto l1131; } goto l1130; - l1131:; G->pos= yypos1130; G->thunkpos= yythunkpos1130; - { int yypos1132= G->pos, yythunkpos1132= G->thunkpos; if (!yy_HtmlBlockCloseH1(G)) { goto l1132; } goto l1129; - l1132:; G->pos= yypos1132; G->thunkpos= yythunkpos1132; - } if (!yymatchDot(G)) goto l1129; - } - l1130:; goto l1128; - l1129:; G->pos= yypos1129; G->thunkpos= yythunkpos1129; - } if (!yy_HtmlBlockCloseH1(G)) { goto l1127; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1127; yyDo(G, yy_1_HtmlBlockH1, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH1", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1127:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseH1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseH1")); if (!yymatchChar(G, '<')) goto l1133; if (!yy_Spnl(G)) { goto l1133; } if (!yymatchChar(G, '/')) goto l1133; - { int yypos1134= G->pos, yythunkpos1134= G->thunkpos; if (!yymatchString(G, "h1")) goto l1135; goto l1134; - l1135:; G->pos= yypos1134; G->thunkpos= yythunkpos1134; if (!yymatchString(G, "H1")) goto l1133; - } - l1134:; if (!yy_Spnl(G)) { goto l1133; } if (!yymatchChar(G, '>')) goto l1133; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH1", G->buf+G->pos)); - return 1; - l1133:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenH1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenH1")); if (!yymatchChar(G, '<')) goto l1136; if (!yy_Spnl(G)) { goto l1136; } - { int yypos1137= G->pos, yythunkpos1137= G->thunkpos; if (!yymatchString(G, "h1")) goto l1138; goto l1137; - l1138:; G->pos= yypos1137; G->thunkpos= yythunkpos1137; if (!yymatchString(G, "H1")) goto l1136; - } - l1137:; if (!yy_Spnl(G)) { goto l1136; } - l1139:; - { int yypos1140= G->pos, yythunkpos1140= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1140; } goto l1139; - l1140:; G->pos= yypos1140; G->thunkpos= yythunkpos1140; - } if (!yymatchChar(G, '>')) goto l1136; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH1", G->buf+G->pos)); - return 1; - l1136:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockForm(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockForm")); if (!yy_HtmlBlockOpenForm(G)) { goto l1141; } - l1142:; - { int yypos1143= G->pos, yythunkpos1143= G->thunkpos; - { int yypos1144= G->pos, yythunkpos1144= G->thunkpos; if (!yy_HtmlBlockForm(G)) { goto l1145; } goto l1144; - l1145:; G->pos= yypos1144; G->thunkpos= yythunkpos1144; - { int yypos1146= G->pos, yythunkpos1146= G->thunkpos; if (!yy_HtmlBlockCloseForm(G)) { goto l1146; } goto l1143; - l1146:; G->pos= yypos1146; G->thunkpos= yythunkpos1146; - } if (!yymatchDot(G)) goto l1143; - } - l1144:; goto l1142; - l1143:; G->pos= yypos1143; G->thunkpos= yythunkpos1143; - } if (!yy_HtmlBlockCloseForm(G)) { goto l1141; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockForm", G->buf+G->pos)); - return 1; - l1141:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockForm", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseForm(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseForm")); if (!yymatchChar(G, '<')) goto l1147; if (!yy_Spnl(G)) { goto l1147; } if (!yymatchChar(G, '/')) goto l1147; - { int yypos1148= G->pos, yythunkpos1148= G->thunkpos; if (!yymatchString(G, "form")) goto l1149; goto l1148; - l1149:; G->pos= yypos1148; G->thunkpos= yythunkpos1148; if (!yymatchString(G, "FORM")) goto l1147; - } - l1148:; if (!yy_Spnl(G)) { goto l1147; } if (!yymatchChar(G, '>')) goto l1147; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseForm", G->buf+G->pos)); - return 1; - l1147:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseForm", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenForm(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenForm")); if (!yymatchChar(G, '<')) goto l1150; if (!yy_Spnl(G)) { goto l1150; } - { int yypos1151= G->pos, yythunkpos1151= G->thunkpos; if (!yymatchString(G, "form")) goto l1152; goto l1151; - l1152:; G->pos= yypos1151; G->thunkpos= yythunkpos1151; if (!yymatchString(G, "FORM")) goto l1150; - } - l1151:; if (!yy_Spnl(G)) { goto l1150; } - l1153:; - { int yypos1154= G->pos, yythunkpos1154= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1154; } goto l1153; - l1154:; G->pos= yypos1154; G->thunkpos= yythunkpos1154; - } if (!yymatchChar(G, '>')) goto l1150; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenForm", G->buf+G->pos)); - return 1; - l1150:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenForm", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockFieldset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockFieldset")); if (!yy_HtmlBlockOpenFieldset(G)) { goto l1155; } - l1156:; - { int yypos1157= G->pos, yythunkpos1157= G->thunkpos; - { int yypos1158= G->pos, yythunkpos1158= G->thunkpos; if (!yy_HtmlBlockFieldset(G)) { goto l1159; } goto l1158; - l1159:; G->pos= yypos1158; G->thunkpos= yythunkpos1158; - { int yypos1160= G->pos, yythunkpos1160= G->thunkpos; if (!yy_HtmlBlockCloseFieldset(G)) { goto l1160; } goto l1157; - l1160:; G->pos= yypos1160; G->thunkpos= yythunkpos1160; - } if (!yymatchDot(G)) goto l1157; - } - l1158:; goto l1156; - l1157:; G->pos= yypos1157; G->thunkpos= yythunkpos1157; - } if (!yy_HtmlBlockCloseFieldset(G)) { goto l1155; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockFieldset", G->buf+G->pos)); - return 1; - l1155:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockFieldset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseFieldset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseFieldset")); if (!yymatchChar(G, '<')) goto l1161; if (!yy_Spnl(G)) { goto l1161; } if (!yymatchChar(G, '/')) goto l1161; - { int yypos1162= G->pos, yythunkpos1162= G->thunkpos; if (!yymatchString(G, "fieldset")) goto l1163; goto l1162; - l1163:; G->pos= yypos1162; G->thunkpos= yythunkpos1162; if (!yymatchString(G, "FIELDSET")) goto l1161; - } - l1162:; if (!yy_Spnl(G)) { goto l1161; } if (!yymatchChar(G, '>')) goto l1161; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseFieldset", G->buf+G->pos)); - return 1; - l1161:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseFieldset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenFieldset(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenFieldset")); if (!yymatchChar(G, '<')) goto l1164; if (!yy_Spnl(G)) { goto l1164; } - { int yypos1165= G->pos, yythunkpos1165= G->thunkpos; if (!yymatchString(G, "fieldset")) goto l1166; goto l1165; - l1166:; G->pos= yypos1165; G->thunkpos= yythunkpos1165; if (!yymatchString(G, "FIELDSET")) goto l1164; - } - l1165:; if (!yy_Spnl(G)) { goto l1164; } - l1167:; - { int yypos1168= G->pos, yythunkpos1168= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1168; } goto l1167; - l1168:; G->pos= yypos1168; G->thunkpos= yythunkpos1168; - } if (!yymatchChar(G, '>')) goto l1164; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenFieldset", G->buf+G->pos)); - return 1; - l1164:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenFieldset", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDl")); if (!yy_HtmlBlockOpenDl(G)) { goto l1169; } - l1170:; - { int yypos1171= G->pos, yythunkpos1171= G->thunkpos; - { int yypos1172= G->pos, yythunkpos1172= G->thunkpos; if (!yy_HtmlBlockDl(G)) { goto l1173; } goto l1172; - l1173:; G->pos= yypos1172; G->thunkpos= yythunkpos1172; - { int yypos1174= G->pos, yythunkpos1174= G->thunkpos; if (!yy_HtmlBlockCloseDl(G)) { goto l1174; } goto l1171; - l1174:; G->pos= yypos1174; G->thunkpos= yythunkpos1174; - } if (!yymatchDot(G)) goto l1171; - } - l1172:; goto l1170; - l1171:; G->pos= yypos1171; G->thunkpos= yythunkpos1171; - } if (!yy_HtmlBlockCloseDl(G)) { goto l1169; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDl", G->buf+G->pos)); - return 1; - l1169:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDl")); if (!yymatchChar(G, '<')) goto l1175; if (!yy_Spnl(G)) { goto l1175; } if (!yymatchChar(G, '/')) goto l1175; - { int yypos1176= G->pos, yythunkpos1176= G->thunkpos; if (!yymatchString(G, "dl")) goto l1177; goto l1176; - l1177:; G->pos= yypos1176; G->thunkpos= yythunkpos1176; if (!yymatchString(G, "DL")) goto l1175; - } - l1176:; if (!yy_Spnl(G)) { goto l1175; } if (!yymatchChar(G, '>')) goto l1175; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDl", G->buf+G->pos)); - return 1; - l1175:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDl")); if (!yymatchChar(G, '<')) goto l1178; if (!yy_Spnl(G)) { goto l1178; } - { int yypos1179= G->pos, yythunkpos1179= G->thunkpos; if (!yymatchString(G, "dl")) goto l1180; goto l1179; - l1180:; G->pos= yypos1179; G->thunkpos= yythunkpos1179; if (!yymatchString(G, "DL")) goto l1178; - } - l1179:; if (!yy_Spnl(G)) { goto l1178; } - l1181:; - { int yypos1182= G->pos, yythunkpos1182= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1182; } goto l1181; - l1182:; G->pos= yypos1182; G->thunkpos= yythunkpos1182; - } if (!yymatchChar(G, '>')) goto l1178; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDl", G->buf+G->pos)); - return 1; - l1178:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDiv(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDiv")); if (!yy_HtmlBlockOpenDiv(G)) { goto l1183; } - l1184:; - { int yypos1185= G->pos, yythunkpos1185= G->thunkpos; - { int yypos1186= G->pos, yythunkpos1186= G->thunkpos; if (!yy_HtmlBlockDiv(G)) { goto l1187; } goto l1186; - l1187:; G->pos= yypos1186; G->thunkpos= yythunkpos1186; - { int yypos1188= G->pos, yythunkpos1188= G->thunkpos; if (!yy_HtmlBlockCloseDiv(G)) { goto l1188; } goto l1185; - l1188:; G->pos= yypos1188; G->thunkpos= yythunkpos1188; - } if (!yymatchDot(G)) goto l1185; - } - l1186:; goto l1184; - l1185:; G->pos= yypos1185; G->thunkpos= yythunkpos1185; - } if (!yy_HtmlBlockCloseDiv(G)) { goto l1183; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDiv", G->buf+G->pos)); - return 1; - l1183:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDiv", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDiv(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDiv")); if (!yymatchChar(G, '<')) goto l1189; if (!yy_Spnl(G)) { goto l1189; } if (!yymatchChar(G, '/')) goto l1189; - { int yypos1190= G->pos, yythunkpos1190= G->thunkpos; if (!yymatchString(G, "div")) goto l1191; goto l1190; - l1191:; G->pos= yypos1190; G->thunkpos= yythunkpos1190; if (!yymatchString(G, "DIV")) goto l1189; - } - l1190:; if (!yy_Spnl(G)) { goto l1189; } if (!yymatchChar(G, '>')) goto l1189; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDiv", G->buf+G->pos)); - return 1; - l1189:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDiv", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDiv(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDiv")); if (!yymatchChar(G, '<')) goto l1192; if (!yy_Spnl(G)) { goto l1192; } - { int yypos1193= G->pos, yythunkpos1193= G->thunkpos; if (!yymatchString(G, "div")) goto l1194; goto l1193; - l1194:; G->pos= yypos1193; G->thunkpos= yythunkpos1193; if (!yymatchString(G, "DIV")) goto l1192; - } - l1193:; if (!yy_Spnl(G)) { goto l1192; } - l1195:; - { int yypos1196= G->pos, yythunkpos1196= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1196; } goto l1195; - l1196:; G->pos= yypos1196; G->thunkpos= yythunkpos1196; - } if (!yymatchChar(G, '>')) goto l1192; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDiv", G->buf+G->pos)); - return 1; - l1192:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDiv", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockDir(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockDir")); if (!yy_HtmlBlockOpenDir(G)) { goto l1197; } - l1198:; - { int yypos1199= G->pos, yythunkpos1199= G->thunkpos; - { int yypos1200= G->pos, yythunkpos1200= G->thunkpos; if (!yy_HtmlBlockDir(G)) { goto l1201; } goto l1200; - l1201:; G->pos= yypos1200; G->thunkpos= yythunkpos1200; - { int yypos1202= G->pos, yythunkpos1202= G->thunkpos; if (!yy_HtmlBlockCloseDir(G)) { goto l1202; } goto l1199; - l1202:; G->pos= yypos1202; G->thunkpos= yythunkpos1202; - } if (!yymatchDot(G)) goto l1199; - } - l1200:; goto l1198; - l1199:; G->pos= yypos1199; G->thunkpos= yythunkpos1199; - } if (!yy_HtmlBlockCloseDir(G)) { goto l1197; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDir", G->buf+G->pos)); - return 1; - l1197:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDir", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseDir(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseDir")); if (!yymatchChar(G, '<')) goto l1203; if (!yy_Spnl(G)) { goto l1203; } if (!yymatchChar(G, '/')) goto l1203; - { int yypos1204= G->pos, yythunkpos1204= G->thunkpos; if (!yymatchString(G, "dir")) goto l1205; goto l1204; - l1205:; G->pos= yypos1204; G->thunkpos= yythunkpos1204; if (!yymatchString(G, "DIR")) goto l1203; - } - l1204:; if (!yy_Spnl(G)) { goto l1203; } if (!yymatchChar(G, '>')) goto l1203; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDir", G->buf+G->pos)); - return 1; - l1203:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDir", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenDir(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenDir")); if (!yymatchChar(G, '<')) goto l1206; if (!yy_Spnl(G)) { goto l1206; } - { int yypos1207= G->pos, yythunkpos1207= G->thunkpos; if (!yymatchString(G, "dir")) goto l1208; goto l1207; - l1208:; G->pos= yypos1207; G->thunkpos= yythunkpos1207; if (!yymatchString(G, "DIR")) goto l1206; - } - l1207:; if (!yy_Spnl(G)) { goto l1206; } - l1209:; - { int yypos1210= G->pos, yythunkpos1210= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1210; } goto l1209; - l1210:; G->pos= yypos1210; G->thunkpos= yythunkpos1210; - } if (!yymatchChar(G, '>')) goto l1206; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDir", G->buf+G->pos)); - return 1; - l1206:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDir", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCenter(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCenter")); if (!yy_HtmlBlockOpenCenter(G)) { goto l1211; } - l1212:; - { int yypos1213= G->pos, yythunkpos1213= G->thunkpos; - { int yypos1214= G->pos, yythunkpos1214= G->thunkpos; if (!yy_HtmlBlockCenter(G)) { goto l1215; } goto l1214; - l1215:; G->pos= yypos1214; G->thunkpos= yythunkpos1214; - { int yypos1216= G->pos, yythunkpos1216= G->thunkpos; if (!yy_HtmlBlockCloseCenter(G)) { goto l1216; } goto l1213; - l1216:; G->pos= yypos1216; G->thunkpos= yythunkpos1216; - } if (!yymatchDot(G)) goto l1213; - } - l1214:; goto l1212; - l1213:; G->pos= yypos1213; G->thunkpos= yythunkpos1213; - } if (!yy_HtmlBlockCloseCenter(G)) { goto l1211; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCenter", G->buf+G->pos)); - return 1; - l1211:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCenter", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseCenter(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseCenter")); if (!yymatchChar(G, '<')) goto l1217; if (!yy_Spnl(G)) { goto l1217; } if (!yymatchChar(G, '/')) goto l1217; - { int yypos1218= G->pos, yythunkpos1218= G->thunkpos; if (!yymatchString(G, "center")) goto l1219; goto l1218; - l1219:; G->pos= yypos1218; G->thunkpos= yythunkpos1218; if (!yymatchString(G, "CENTER")) goto l1217; - } - l1218:; if (!yy_Spnl(G)) { goto l1217; } if (!yymatchChar(G, '>')) goto l1217; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseCenter", G->buf+G->pos)); - return 1; - l1217:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseCenter", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenCenter(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenCenter")); if (!yymatchChar(G, '<')) goto l1220; if (!yy_Spnl(G)) { goto l1220; } - { int yypos1221= G->pos, yythunkpos1221= G->thunkpos; if (!yymatchString(G, "center")) goto l1222; goto l1221; - l1222:; G->pos= yypos1221; G->thunkpos= yythunkpos1221; if (!yymatchString(G, "CENTER")) goto l1220; - } - l1221:; if (!yy_Spnl(G)) { goto l1220; } - l1223:; - { int yypos1224= G->pos, yythunkpos1224= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1224; } goto l1223; - l1224:; G->pos= yypos1224; G->thunkpos= yythunkpos1224; - } if (!yymatchChar(G, '>')) goto l1220; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenCenter", G->buf+G->pos)); - return 1; - l1220:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenCenter", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockBlockquote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockBlockquote")); if (!yy_HtmlBlockOpenBlockquote(G)) { goto l1225; } - l1226:; - { int yypos1227= G->pos, yythunkpos1227= G->thunkpos; - { int yypos1228= G->pos, yythunkpos1228= G->thunkpos; if (!yy_HtmlBlockBlockquote(G)) { goto l1229; } goto l1228; - l1229:; G->pos= yypos1228; G->thunkpos= yythunkpos1228; - { int yypos1230= G->pos, yythunkpos1230= G->thunkpos; if (!yy_HtmlBlockCloseBlockquote(G)) { goto l1230; } goto l1227; - l1230:; G->pos= yypos1230; G->thunkpos= yythunkpos1230; - } if (!yymatchDot(G)) goto l1227; - } - l1228:; goto l1226; - l1227:; G->pos= yypos1227; G->thunkpos= yythunkpos1227; - } if (!yy_HtmlBlockCloseBlockquote(G)) { goto l1225; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockBlockquote", G->buf+G->pos)); - return 1; - l1225:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockBlockquote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseBlockquote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseBlockquote")); if (!yymatchChar(G, '<')) goto l1231; if (!yy_Spnl(G)) { goto l1231; } if (!yymatchChar(G, '/')) goto l1231; - { int yypos1232= G->pos, yythunkpos1232= G->thunkpos; if (!yymatchString(G, "blockquote")) goto l1233; goto l1232; - l1233:; G->pos= yypos1232; G->thunkpos= yythunkpos1232; if (!yymatchString(G, "BLOCKQUOTE")) goto l1231; - } - l1232:; if (!yy_Spnl(G)) { goto l1231; } if (!yymatchChar(G, '>')) goto l1231; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseBlockquote", G->buf+G->pos)); - return 1; - l1231:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseBlockquote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenBlockquote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenBlockquote")); if (!yymatchChar(G, '<')) goto l1234; if (!yy_Spnl(G)) { goto l1234; } - { int yypos1235= G->pos, yythunkpos1235= G->thunkpos; if (!yymatchString(G, "blockquote")) goto l1236; goto l1235; - l1236:; G->pos= yypos1235; G->thunkpos= yythunkpos1235; if (!yymatchString(G, "BLOCKQUOTE")) goto l1234; - } - l1235:; if (!yy_Spnl(G)) { goto l1234; } - l1237:; - { int yypos1238= G->pos, yythunkpos1238= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1238; } goto l1237; - l1238:; G->pos= yypos1238; G->thunkpos= yythunkpos1238; - } if (!yymatchChar(G, '>')) goto l1234; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenBlockquote", G->buf+G->pos)); - return 1; - l1234:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenBlockquote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockAddress(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockAddress")); if (!yy_HtmlBlockOpenAddress(G)) { goto l1239; } - l1240:; - { int yypos1241= G->pos, yythunkpos1241= G->thunkpos; - { int yypos1242= G->pos, yythunkpos1242= G->thunkpos; if (!yy_HtmlBlockAddress(G)) { goto l1243; } goto l1242; - l1243:; G->pos= yypos1242; G->thunkpos= yythunkpos1242; - { int yypos1244= G->pos, yythunkpos1244= G->thunkpos; if (!yy_HtmlBlockCloseAddress(G)) { goto l1244; } goto l1241; - l1244:; G->pos= yypos1244; G->thunkpos= yythunkpos1244; - } if (!yymatchDot(G)) goto l1241; - } - l1242:; goto l1240; - l1241:; G->pos= yypos1241; G->thunkpos= yythunkpos1241; - } if (!yy_HtmlBlockCloseAddress(G)) { goto l1239; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockAddress", G->buf+G->pos)); - return 1; - l1239:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockAddress", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockCloseAddress(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockCloseAddress")); if (!yymatchChar(G, '<')) goto l1245; if (!yy_Spnl(G)) { goto l1245; } if (!yymatchChar(G, '/')) goto l1245; - { int yypos1246= G->pos, yythunkpos1246= G->thunkpos; if (!yymatchString(G, "address")) goto l1247; goto l1246; - l1247:; G->pos= yypos1246; G->thunkpos= yythunkpos1246; if (!yymatchString(G, "ADDRESS")) goto l1245; - } - l1246:; if (!yy_Spnl(G)) { goto l1245; } if (!yymatchChar(G, '>')) goto l1245; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseAddress", G->buf+G->pos)); - return 1; - l1245:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseAddress", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlAttribute(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlAttribute")); - { int yypos1251= G->pos, yythunkpos1251= G->thunkpos; if (!yy_AlphanumericAscii(G)) { goto l1252; } goto l1251; - l1252:; G->pos= yypos1251; G->thunkpos= yythunkpos1251; if (!yymatchChar(G, '-')) goto l1248; - } - l1251:; - l1249:; - { int yypos1250= G->pos, yythunkpos1250= G->thunkpos; - { int yypos1253= G->pos, yythunkpos1253= G->thunkpos; if (!yy_AlphanumericAscii(G)) { goto l1254; } goto l1253; - l1254:; G->pos= yypos1253; G->thunkpos= yythunkpos1253; if (!yymatchChar(G, '-')) goto l1250; - } - l1253:; goto l1249; - l1250:; G->pos= yypos1250; G->thunkpos= yythunkpos1250; - } if (!yy_Spnl(G)) { goto l1248; } - { int yypos1255= G->pos, yythunkpos1255= G->thunkpos; if (!yymatchChar(G, '=')) goto l1255; if (!yy_Spnl(G)) { goto l1255; } - { int yypos1257= G->pos, yythunkpos1257= G->thunkpos; if (!yy_Quoted(G)) { goto l1258; } goto l1257; - l1258:; G->pos= yypos1257; G->thunkpos= yythunkpos1257; - { int yypos1261= G->pos, yythunkpos1261= G->thunkpos; if (!yymatchChar(G, '>')) goto l1261; goto l1255; - l1261:; G->pos= yypos1261; G->thunkpos= yythunkpos1261; - } if (!yy_Nonspacechar(G)) { goto l1255; } - l1259:; - { int yypos1260= G->pos, yythunkpos1260= G->thunkpos; - { int yypos1262= G->pos, yythunkpos1262= G->thunkpos; if (!yymatchChar(G, '>')) goto l1262; goto l1260; - l1262:; G->pos= yypos1262; G->thunkpos= yythunkpos1262; - } if (!yy_Nonspacechar(G)) { goto l1260; } goto l1259; - l1260:; G->pos= yypos1260; G->thunkpos= yythunkpos1260; - } - } - l1257:; goto l1256; - l1255:; G->pos= yypos1255; G->thunkpos= yythunkpos1255; - } - l1256:; if (!yy_Spnl(G)) { goto l1248; } - yyprintf((stderr, " ok %s @ %s\n", "HtmlAttribute", G->buf+G->pos)); - return 1; - l1248:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlAttribute", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlockOpenAddress(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HtmlBlockOpenAddress")); if (!yymatchChar(G, '<')) goto l1263; if (!yy_Spnl(G)) { goto l1263; } - { int yypos1264= G->pos, yythunkpos1264= G->thunkpos; if (!yymatchString(G, "address")) goto l1265; goto l1264; - l1265:; G->pos= yypos1264; G->thunkpos= yythunkpos1264; if (!yymatchString(G, "ADDRESS")) goto l1263; - } - l1264:; if (!yy_Spnl(G)) { goto l1263; } - l1266:; - { int yypos1267= G->pos, yythunkpos1267= G->thunkpos; if (!yy_HtmlAttribute(G)) { goto l1267; } goto l1266; - l1267:; G->pos= yypos1267; G->thunkpos= yythunkpos1267; - } if (!yymatchChar(G, '>')) goto l1263; - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenAddress", G->buf+G->pos)); - return 1; - l1263:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenAddress", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_OptionallyIndentedLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "OptionallyIndentedLine")); - { int yypos1269= G->pos, yythunkpos1269= G->thunkpos; if (!yy_Indent(G)) { goto l1269; } goto l1270; - l1269:; G->pos= yypos1269; G->thunkpos= yythunkpos1269; - } - l1270:; if (!yy_Line(G)) { goto l1268; } - yyprintf((stderr, " ok %s @ %s\n", "OptionallyIndentedLine", G->buf+G->pos)); - return 1; - l1268:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "OptionallyIndentedLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Indent(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Indent")); - { int yypos1272= G->pos, yythunkpos1272= G->thunkpos; if (!yymatchChar(G, '\t')) goto l1273; goto l1272; - l1273:; G->pos= yypos1272; G->thunkpos= yythunkpos1272; if (!yymatchString(G, " ")) goto l1271; - } - l1272:; - yyprintf((stderr, " ok %s @ %s\n", "Indent", G->buf+G->pos)); - return 1; - l1271:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Indent", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListBlockLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "ListBlockLine")); - { int yypos1275= G->pos, yythunkpos1275= G->thunkpos; if (!yy_BlankLine(G)) { goto l1275; } goto l1274; - l1275:; G->pos= yypos1275; G->thunkpos= yythunkpos1275; - } - { int yypos1276= G->pos, yythunkpos1276= G->thunkpos; - { int yypos1277= G->pos, yythunkpos1277= G->thunkpos; if (!yy_Indent(G)) { goto l1277; } goto l1278; - l1277:; G->pos= yypos1277; G->thunkpos= yythunkpos1277; - } - l1278:; - { int yypos1279= G->pos, yythunkpos1279= G->thunkpos; if (!yy_Bullet(G)) { goto l1280; } goto l1279; - l1280:; G->pos= yypos1279; G->thunkpos= yythunkpos1279; if (!yy_Enumerator(G)) { goto l1276; } - } - l1279:; goto l1274; - l1276:; G->pos= yypos1276; G->thunkpos= yythunkpos1276; - } - { int yypos1281= G->pos, yythunkpos1281= G->thunkpos; if (!yy_HorizontalRule(G)) { goto l1281; } goto l1274; - l1281:; G->pos= yypos1281; G->thunkpos= yythunkpos1281; - } if (!yy_OptionallyIndentedLine(G)) { goto l1274; } - yyprintf((stderr, " ok %s @ %s\n", "ListBlockLine", G->buf+G->pos)); - return 1; - l1274:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListBlockLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListContinuationBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListContinuationBlock")); if (!yy_StartList(G)) { goto l1282; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1282; - l1283:; - { int yypos1284= G->pos, yythunkpos1284= G->thunkpos; if (!yy_BlankLine(G)) { goto l1284; } goto l1283; - l1284:; G->pos= yypos1284; G->thunkpos= yythunkpos1284; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1282; yyDo(G, yy_1_ListContinuationBlock, G->begin, G->end); if (!yy_Indent(G)) { goto l1282; } if (!yy_ListBlock(G)) { goto l1282; } yyDo(G, yy_2_ListContinuationBlock, G->begin, G->end); - l1285:; - { int yypos1286= G->pos, yythunkpos1286= G->thunkpos; if (!yy_Indent(G)) { goto l1286; } if (!yy_ListBlock(G)) { goto l1286; } yyDo(G, yy_2_ListContinuationBlock, G->begin, G->end); goto l1285; - l1286:; G->pos= yypos1286; G->thunkpos= yythunkpos1286; - } yyDo(G, yy_3_ListContinuationBlock, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListContinuationBlock", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1282:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListContinuationBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListBlock")); if (!yy_StartList(G)) { goto l1287; } yyDo(G, yySet, -1, 0); - { int yypos1288= G->pos, yythunkpos1288= G->thunkpos; if (!yy_BlankLine(G)) { goto l1288; } goto l1287; - l1288:; G->pos= yypos1288; G->thunkpos= yythunkpos1288; - } if (!yy_Line(G)) { goto l1287; } yyDo(G, yy_1_ListBlock, G->begin, G->end); - l1289:; - { int yypos1290= G->pos, yythunkpos1290= G->thunkpos; if (!yy_ListBlockLine(G)) { goto l1290; } yyDo(G, yy_2_ListBlock, G->begin, G->end); goto l1289; - l1290:; G->pos= yypos1290; G->thunkpos= yythunkpos1290; - } yyDo(G, yy_3_ListBlock, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListBlock", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1287:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListItem(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListItem")); - { int yypos1292= G->pos, yythunkpos1292= G->thunkpos; if (!yy_Bullet(G)) { goto l1293; } goto l1292; - l1293:; G->pos= yypos1292; G->thunkpos= yythunkpos1292; if (!yy_Enumerator(G)) { goto l1291; } - } - l1292:; if (!yy_StartList(G)) { goto l1291; } yyDo(G, yySet, -1, 0); if (!yy_ListBlock(G)) { goto l1291; } yyDo(G, yy_1_ListItem, G->begin, G->end); - l1294:; - { int yypos1295= G->pos, yythunkpos1295= G->thunkpos; if (!yy_ListContinuationBlock(G)) { goto l1295; } yyDo(G, yy_2_ListItem, G->begin, G->end); goto l1294; - l1295:; G->pos= yypos1295; G->thunkpos= yythunkpos1295; - } yyDo(G, yy_3_ListItem, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListItem", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1291:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListItem", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Enumerator(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Enumerator")); if (!yy_NonindentSpace(G)) { goto l1296; } yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1296; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l1296; - l1297:; - { int yypos1298= G->pos, yythunkpos1298= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l1298; goto l1297; - l1298:; G->pos= yypos1298; G->thunkpos= yythunkpos1298; - } if (!yymatchChar(G, '.')) goto l1296; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1296; if (!yy_Spacechar(G)) { goto l1296; } - l1299:; - { int yypos1300= G->pos, yythunkpos1300= G->thunkpos; if (!yy_Spacechar(G)) { goto l1300; } goto l1299; - l1300:; G->pos= yypos1300; G->thunkpos= yythunkpos1300; - } yyDo(G, yy_1_Enumerator, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Enumerator", G->buf+G->pos)); - return 1; - l1296:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Enumerator", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListItemTight(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListItemTight")); - { int yypos1302= G->pos, yythunkpos1302= G->thunkpos; if (!yy_Bullet(G)) { goto l1303; } goto l1302; - l1303:; G->pos= yypos1302; G->thunkpos= yythunkpos1302; if (!yy_Enumerator(G)) { goto l1301; } - } - l1302:; if (!yy_StartList(G)) { goto l1301; } yyDo(G, yySet, -1, 0); if (!yy_ListBlock(G)) { goto l1301; } yyDo(G, yy_1_ListItemTight, G->begin, G->end); - l1304:; - { int yypos1305= G->pos, yythunkpos1305= G->thunkpos; - { int yypos1306= G->pos, yythunkpos1306= G->thunkpos; if (!yy_BlankLine(G)) { goto l1306; } goto l1305; - l1306:; G->pos= yypos1306; G->thunkpos= yythunkpos1306; - } if (!yy_ListContinuationBlock(G)) { goto l1305; } yyDo(G, yy_2_ListItemTight, G->begin, G->end); goto l1304; - l1305:; G->pos= yypos1305; G->thunkpos= yythunkpos1305; - } - { int yypos1307= G->pos, yythunkpos1307= G->thunkpos; if (!yy_ListContinuationBlock(G)) { goto l1307; } goto l1301; - l1307:; G->pos= yypos1307; G->thunkpos= yythunkpos1307; - } yyDo(G, yy_3_ListItemTight, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListItemTight", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1301:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListItemTight", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListLoose(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 2, 0); - yyprintf((stderr, "%s\n", "ListLoose")); if (!yy_StartList(G)) { goto l1308; } yyDo(G, yySet, -2, 0); if (!yy_ListItem(G)) { goto l1308; } yyDo(G, yySet, -1, 0); - l1311:; - { int yypos1312= G->pos, yythunkpos1312= G->thunkpos; if (!yy_BlankLine(G)) { goto l1312; } goto l1311; - l1312:; G->pos= yypos1312; G->thunkpos= yythunkpos1312; - } yyDo(G, yy_1_ListLoose, G->begin, G->end); - l1309:; - { int yypos1310= G->pos, yythunkpos1310= G->thunkpos; if (!yy_ListItem(G)) { goto l1310; } yyDo(G, yySet, -1, 0); - l1313:; - { int yypos1314= G->pos, yythunkpos1314= G->thunkpos; if (!yy_BlankLine(G)) { goto l1314; } goto l1313; - l1314:; G->pos= yypos1314; G->thunkpos= yythunkpos1314; - } yyDo(G, yy_1_ListLoose, G->begin, G->end); goto l1309; - l1310:; G->pos= yypos1310; G->thunkpos= yythunkpos1310; - } yyDo(G, yy_2_ListLoose, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListLoose", G->buf+G->pos)); yyDo(G, yyPop, 2, 0); - return 1; - l1308:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListLoose", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_ListTight(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "ListTight")); if (!yy_StartList(G)) { goto l1315; } yyDo(G, yySet, -1, 0); if (!yy_ListItemTight(G)) { goto l1315; } yyDo(G, yy_1_ListTight, G->begin, G->end); - l1316:; - { int yypos1317= G->pos, yythunkpos1317= G->thunkpos; if (!yy_ListItemTight(G)) { goto l1317; } yyDo(G, yy_1_ListTight, G->begin, G->end); goto l1316; - l1317:; G->pos= yypos1317; G->thunkpos= yythunkpos1317; - } - l1318:; - { int yypos1319= G->pos, yythunkpos1319= G->thunkpos; if (!yy_BlankLine(G)) { goto l1319; } goto l1318; - l1319:; G->pos= yypos1319; G->thunkpos= yythunkpos1319; - } - { int yypos1320= G->pos, yythunkpos1320= G->thunkpos; - { int yypos1321= G->pos, yythunkpos1321= G->thunkpos; if (!yy_Bullet(G)) { goto l1322; } goto l1321; - l1322:; G->pos= yypos1321; G->thunkpos= yythunkpos1321; if (!yy_Enumerator(G)) { goto l1320; } - } - l1321:; goto l1315; - l1320:; G->pos= yypos1320; G->thunkpos= yythunkpos1320; - } yyDo(G, yy_2_ListTight, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "ListTight", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1315:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "ListTight", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Bullet(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Bullet")); - { int yypos1324= G->pos, yythunkpos1324= G->thunkpos; if (!yy_HorizontalRule(G)) { goto l1324; } goto l1323; - l1324:; G->pos= yypos1324; G->thunkpos= yythunkpos1324; - } if (!yy_NonindentSpace(G)) { goto l1323; } yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1323; - { int yypos1325= G->pos, yythunkpos1325= G->thunkpos; if (!yymatchChar(G, '+')) goto l1326; goto l1325; - l1326:; G->pos= yypos1325; G->thunkpos= yythunkpos1325; if (!yymatchChar(G, '*')) goto l1327; goto l1325; - l1327:; G->pos= yypos1325; G->thunkpos= yythunkpos1325; if (!yymatchChar(G, '-')) goto l1323; - } - l1325:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1323; if (!yy_Spacechar(G)) { goto l1323; } - l1328:; - { int yypos1329= G->pos, yythunkpos1329= G->thunkpos; if (!yy_Spacechar(G)) { goto l1329; } goto l1328; - l1329:; G->pos= yypos1329; G->thunkpos= yythunkpos1329; - } yyDo(G, yy_1_Bullet, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Bullet", G->buf+G->pos)); - return 1; - l1323:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Bullet", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TableCell(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TableCell")); if (!yy_Sp(G)) { goto l1330; } - l1331:; - { int yypos1332= G->pos, yythunkpos1332= G->thunkpos; - { int yypos1333= G->pos, yythunkpos1333= G->thunkpos; if (!yymatchChar(G, '|')) goto l1333; goto l1332; - l1333:; G->pos= yypos1333; G->thunkpos= yythunkpos1333; - } - { int yypos1334= G->pos, yythunkpos1334= G->thunkpos; if (!yy_Newline(G)) { goto l1334; } goto l1332; - l1334:; G->pos= yypos1334; G->thunkpos= yythunkpos1334; - } if (!yy_Inline(G)) { goto l1332; } goto l1331; - l1332:; G->pos= yypos1332; G->thunkpos= yythunkpos1332; - } if (!yy_TableBorder(G)) { goto l1330; } - yyprintf((stderr, " ok %s @ %s\n", "TableCell", G->buf+G->pos)); - return 1; - l1330:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TableCell", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TableBorder(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TableBorder")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1335; if (!yymatchChar(G, '|')) goto l1335; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1335; yyDo(G, yy_1_TableBorder, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "TableBorder", G->buf+G->pos)); - return 1; - l1335:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TableBorder", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TableLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TableLine")); if (!yy_TableBorder(G)) { goto l1336; } if (!yy_TableCell(G)) { goto l1336; } - l1337:; - { int yypos1338= G->pos, yythunkpos1338= G->thunkpos; if (!yy_TableCell(G)) { goto l1338; } goto l1337; - l1338:; G->pos= yypos1338; G->thunkpos= yythunkpos1338; - } if (!yy_Sp(G)) { goto l1336; } if (!yy_Newline(G)) { goto l1336; } - yyprintf((stderr, " ok %s @ %s\n", "TableLine", G->buf+G->pos)); - return 1; - l1336:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TableLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TableDelimiter(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "TableDelimiter")); if (!yy_TableBorder(G)) { goto l1339; } if (!yy_Sp(G)) { goto l1339; } - { int yypos1342= G->pos, yythunkpos1342= G->thunkpos; if (!yymatchChar(G, ':')) goto l1342; goto l1343; - l1342:; G->pos= yypos1342; G->thunkpos= yythunkpos1342; - } - l1343:; if (!yymatchChar(G, '-')) goto l1339; - l1344:; - { int yypos1345= G->pos, yythunkpos1345= G->thunkpos; if (!yymatchChar(G, '-')) goto l1345; goto l1344; - l1345:; G->pos= yypos1345; G->thunkpos= yythunkpos1345; - } - { int yypos1346= G->pos, yythunkpos1346= G->thunkpos; if (!yymatchChar(G, ':')) goto l1346; goto l1347; - l1346:; G->pos= yypos1346; G->thunkpos= yythunkpos1346; - } - l1347:; if (!yy_Sp(G)) { goto l1339; } if (!yy_TableBorder(G)) { goto l1339; } - l1340:; - { int yypos1341= G->pos, yythunkpos1341= G->thunkpos; if (!yy_Sp(G)) { goto l1341; } - { int yypos1348= G->pos, yythunkpos1348= G->thunkpos; if (!yymatchChar(G, ':')) goto l1348; goto l1349; - l1348:; G->pos= yypos1348; G->thunkpos= yythunkpos1348; - } - l1349:; if (!yymatchChar(G, '-')) goto l1341; - l1350:; - { int yypos1351= G->pos, yythunkpos1351= G->thunkpos; if (!yymatchChar(G, '-')) goto l1351; goto l1350; - l1351:; G->pos= yypos1351; G->thunkpos= yythunkpos1351; - } - { int yypos1352= G->pos, yythunkpos1352= G->thunkpos; if (!yymatchChar(G, ':')) goto l1352; goto l1353; - l1352:; G->pos= yypos1352; G->thunkpos= yythunkpos1352; - } - l1353:; if (!yy_Sp(G)) { goto l1341; } if (!yy_TableBorder(G)) { goto l1341; } goto l1340; - l1341:; G->pos= yypos1341; G->thunkpos= yythunkpos1341; - } if (!yy_Sp(G)) { goto l1339; } if (!yy_Newline(G)) { goto l1339; } - yyprintf((stderr, " ok %s @ %s\n", "TableDelimiter", G->buf+G->pos)); - return 1; - l1339:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TableDelimiter", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_TableHeader(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "TableHeader")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1354; if (!yy_LocMarker(G)) { goto l1354; } yyDo(G, yySet, -1, 0); if (!yy_TableLine(G)) { goto l1354; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1354; yyDo(G, yy_1_TableHeader, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "TableHeader", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1354:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "TableHeader", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_InlineEquationMultiple(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "InlineEquationMultiple")); - { int yypos1356= G->pos, yythunkpos1356= G->thunkpos; if (!yymatchChar(G, '$')) goto l1356; goto l1355; - l1356:; G->pos= yypos1356; G->thunkpos= yythunkpos1356; - } if (!yy_Nonspacechar(G)) { goto l1355; } - { int yypos1359= G->pos, yythunkpos1359= G->thunkpos; if (!yymatchChar(G, '$')) goto l1359; goto l1355; - l1359:; G->pos= yypos1359; G->thunkpos= yythunkpos1359; - } - { int yypos1360= G->pos, yythunkpos1360= G->thunkpos; if (!yy_Newline(G)) { goto l1360; } goto l1355; - l1360:; G->pos= yypos1360; G->thunkpos= yythunkpos1360; - } if (!yymatchDot(G)) goto l1355; - l1357:; - { int yypos1358= G->pos, yythunkpos1358= G->thunkpos; - { int yypos1361= G->pos, yythunkpos1361= G->thunkpos; if (!yymatchChar(G, '$')) goto l1361; goto l1358; - l1361:; G->pos= yypos1361; G->thunkpos= yythunkpos1361; - } - { int yypos1362= G->pos, yythunkpos1362= G->thunkpos; if (!yy_Newline(G)) { goto l1362; } goto l1358; - l1362:; G->pos= yypos1362; G->thunkpos= yythunkpos1362; - } if (!yymatchDot(G)) goto l1358; goto l1357; - l1358:; G->pos= yypos1358; G->thunkpos= yythunkpos1358; - } if (!yymatchChar(G, '$')) goto l1355; yyText(G, G->begin, G->end); if (!( IEP_POST )) goto l1355; - yyprintf((stderr, " ok %s @ %s\n", "InlineEquationMultiple", G->buf+G->pos)); - return 1; - l1355:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "InlineEquationMultiple", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_InlineEquationSingle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "InlineEquationSingle")); - { int yypos1364= G->pos, yythunkpos1364= G->thunkpos; if (!yymatchChar(G, '$')) goto l1364; goto l1363; - l1364:; G->pos= yypos1364; G->thunkpos= yythunkpos1364; - } - { int yypos1365= G->pos, yythunkpos1365= G->thunkpos; if (!yymatchChar(G, '\\')) goto l1365; goto l1363; - l1365:; G->pos= yypos1365; G->thunkpos= yythunkpos1365; - } if (!yy_Nonspacechar(G)) { goto l1363; } if (!yymatchChar(G, '$')) goto l1363; - yyprintf((stderr, " ok %s @ %s\n", "InlineEquationSingle", G->buf+G->pos)); - return 1; - l1363:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "InlineEquationSingle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_InlineEquation(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "InlineEquation")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_MATH) )) goto l1366; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1366; if (!yymatchChar(G, '$')) goto l1366; yyText(G, G->begin, G->end); if (!( IEP_PRE )) goto l1366; - { int yypos1367= G->pos, yythunkpos1367= G->thunkpos; if (!yy_InlineEquationSingle(G)) { goto l1368; } goto l1367; - l1368:; G->pos= yypos1367; G->thunkpos= yythunkpos1367; if (!yy_InlineEquationMultiple(G)) { goto l1366; } - } - l1367:; - { int yypos1369= G->pos, yythunkpos1369= G->thunkpos; if (!yymatchClass(G, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l1369; goto l1366; - l1369:; G->pos= yypos1369; G->thunkpos= yythunkpos1369; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1366; yyDo(G, yy_1_InlineEquation, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "InlineEquation", G->buf+G->pos)); - return 1; - l1366:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "InlineEquation", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Nonspacechar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Nonspacechar")); - { int yypos1371= G->pos, yythunkpos1371= G->thunkpos; if (!yy_Spacechar(G)) { goto l1371; } goto l1370; - l1371:; G->pos= yypos1371; G->thunkpos= yythunkpos1371; - } - { int yypos1372= G->pos, yythunkpos1372= G->thunkpos; if (!yy_Newline(G)) { goto l1372; } goto l1370; - l1372:; G->pos= yypos1372; G->thunkpos= yythunkpos1372; - } if (!yymatchDot(G)) goto l1370; - yyprintf((stderr, " ok %s @ %s\n", "Nonspacechar", G->buf+G->pos)); - return 1; - l1370:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Nonspacechar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_DisplayFormulaRawMark(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "DisplayFormulaRawMark")); - { int yypos1376= G->pos, yythunkpos1376= G->thunkpos; if (!yymatchChar(G, '{')) goto l1376; goto l1373; - l1376:; G->pos= yypos1376; G->thunkpos= yythunkpos1376; - } - { int yypos1377= G->pos, yythunkpos1377= G->thunkpos; if (!yymatchChar(G, '}')) goto l1377; goto l1373; - l1377:; G->pos= yypos1377; G->thunkpos= yythunkpos1377; - } if (!yy_Nonspacechar(G)) { goto l1373; } - l1374:; - { int yypos1375= G->pos, yythunkpos1375= G->thunkpos; - { int yypos1378= G->pos, yythunkpos1378= G->thunkpos; if (!yymatchChar(G, '{')) goto l1378; goto l1375; - l1378:; G->pos= yypos1378; G->thunkpos= yythunkpos1378; - } - { int yypos1379= G->pos, yythunkpos1379= G->thunkpos; if (!yymatchChar(G, '}')) goto l1379; goto l1375; - l1379:; G->pos= yypos1379; G->thunkpos= yythunkpos1379; - } if (!yy_Nonspacechar(G)) { goto l1375; } goto l1374; - l1375:; G->pos= yypos1375; G->thunkpos= yythunkpos1375; - } - yyprintf((stderr, " ok %s @ %s\n", "DisplayFormulaRawMark", G->buf+G->pos)); - return 1; - l1373:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "DisplayFormulaRawMark", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_DisplayFormulaRawEnd(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "DisplayFormulaRawEnd")); if (!yymatchString(G, "\\end")) goto l1380; if (!yymatchChar(G, '{')) goto l1380; if (!yy_DisplayFormulaRawMark(G)) { goto l1380; } if (!yymatchChar(G, '}')) goto l1380; - yyprintf((stderr, " ok %s @ %s\n", "DisplayFormulaRawEnd", G->buf+G->pos)); - return 1; - l1380:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "DisplayFormulaRawEnd", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Spnl(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Spnl")); if (!yy_Sp(G)) { goto l1381; } - { int yypos1382= G->pos, yythunkpos1382= G->thunkpos; if (!yy_Newline(G)) { goto l1382; } if (!yy_Sp(G)) { goto l1382; } goto l1383; - l1382:; G->pos= yypos1382; G->thunkpos= yythunkpos1382; - } - l1383:; - yyprintf((stderr, " ok %s @ %s\n", "Spnl", G->buf+G->pos)); - return 1; - l1381:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Spnl", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_DisplayFormulaRawStart(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "DisplayFormulaRawStart")); if (!yymatchString(G, "\\begin")) goto l1384; if (!yymatchChar(G, '{')) goto l1384; if (!yy_DisplayFormulaRawMark(G)) { goto l1384; } if (!yymatchChar(G, '}')) goto l1384; - yyprintf((stderr, " ok %s @ %s\n", "DisplayFormulaRawStart", G->buf+G->pos)); - return 1; - l1384:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "DisplayFormulaRawStart", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FormulaNumber(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FormulaNumber")); if (!yymatchChar(G, '(')) goto l1385; - { int yypos1388= G->pos, yythunkpos1388= G->thunkpos; if (!yymatchChar(G, ')')) goto l1388; goto l1385; - l1388:; G->pos= yypos1388; G->thunkpos= yythunkpos1388; - } - { int yypos1389= G->pos, yythunkpos1389= G->thunkpos; if (!yymatchChar(G, '$')) goto l1389; goto l1385; - l1389:; G->pos= yypos1389; G->thunkpos= yythunkpos1389; - } - { int yypos1390= G->pos, yythunkpos1390= G->thunkpos; if (!yy_Newline(G)) { goto l1390; } goto l1385; - l1390:; G->pos= yypos1390; G->thunkpos= yythunkpos1390; - } if (!yymatchDot(G)) goto l1385; - l1386:; - { int yypos1387= G->pos, yythunkpos1387= G->thunkpos; - { int yypos1391= G->pos, yythunkpos1391= G->thunkpos; if (!yymatchChar(G, ')')) goto l1391; goto l1387; - l1391:; G->pos= yypos1391; G->thunkpos= yythunkpos1391; - } - { int yypos1392= G->pos, yythunkpos1392= G->thunkpos; if (!yymatchChar(G, '$')) goto l1392; goto l1387; - l1392:; G->pos= yypos1392; G->thunkpos= yythunkpos1392; - } - { int yypos1393= G->pos, yythunkpos1393= G->thunkpos; if (!yy_Newline(G)) { goto l1393; } goto l1387; - l1393:; G->pos= yypos1393; G->thunkpos= yythunkpos1393; - } if (!yymatchDot(G)) goto l1387; goto l1386; - l1387:; G->pos= yypos1387; G->thunkpos= yythunkpos1387; - } if (!yymatchChar(G, ')')) goto l1385; - yyprintf((stderr, " ok %s @ %s\n", "FormulaNumber", G->buf+G->pos)); - return 1; - l1385:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FormulaNumber", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_DisplayFormulaRaw(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "DisplayFormulaRaw")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_MATH_RAW) )) goto l1394; if (!yy_NonindentSpace(G)) { goto l1394; } yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1394; if (!yy_DisplayFormulaRawStart(G)) { goto l1394; } yyText(G, G->begin, G->end); if (!( start_dfr() )) goto l1394; if (!yy_Spnl(G)) { goto l1394; } - l1395:; - { int yypos1396= G->pos, yythunkpos1396= G->thunkpos; - { int yypos1397= G->pos, yythunkpos1397= G->thunkpos; if (!yy_DisplayFormulaRawStart(G)) { goto l1398; } yyText(G, G->begin, G->end); if (!( inc_dfr() )) goto l1398; goto l1397; - l1398:; G->pos= yypos1397; G->thunkpos= yythunkpos1397; yyText(G, G->begin, G->end); if (!( nested_dfr() )) goto l1399; if (!yy_DisplayFormulaRawEnd(G)) { goto l1399; } yyText(G, G->begin, G->end); if (!( dec_dfr() )) goto l1399; goto l1397; - l1399:; G->pos= yypos1397; G->thunkpos= yythunkpos1397; - { int yypos1400= G->pos, yythunkpos1400= G->thunkpos; if (!yy_DisplayFormulaRawEnd(G)) { goto l1400; } goto l1396; - l1400:; G->pos= yypos1400; G->thunkpos= yythunkpos1400; - } - { int yypos1401= G->pos, yythunkpos1401= G->thunkpos; if (!yy_DisplayFormulaRawStart(G)) { goto l1401; } goto l1396; - l1401:; G->pos= yypos1401; G->thunkpos= yythunkpos1401; - } - { int yypos1402= G->pos, yythunkpos1402= G->thunkpos; if (!yy_Newline(G)) { goto l1402; } if (!yy_Newline(G)) { goto l1402; } - l1403:; - { int yypos1404= G->pos, yythunkpos1404= G->thunkpos; if (!yy_Newline(G)) { goto l1404; } goto l1403; - l1404:; G->pos= yypos1404; G->thunkpos= yythunkpos1404; - } goto l1396; - l1402:; G->pos= yypos1402; G->thunkpos= yythunkpos1402; - } if (!yymatchDot(G)) goto l1396; - } - l1397:; goto l1395; - l1396:; G->pos= yypos1396; G->thunkpos= yythunkpos1396; - } yyText(G, G->begin, G->end); if (!( !nested_dfr() )) goto l1394; if (!yy_DisplayFormulaRawEnd(G)) { goto l1394; } yyText(G, G->begin, G->end); if (!( dec_dfr() )) goto l1394; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1394; if (!yy_Sp(G)) { goto l1394; } if (!yy_Newline(G)) { goto l1394; } yyDo(G, yy_1_DisplayFormulaRaw, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "DisplayFormulaRaw", G->buf+G->pos)); - return 1; - l1394:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "DisplayFormulaRaw", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_DisplayFormulaDollar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "DisplayFormulaDollar")); if (!yy_NonindentSpace(G)) { goto l1405; } yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1405; if (!yymatchString(G, "$$")) goto l1405; - l1406:; - { int yypos1407= G->pos, yythunkpos1407= G->thunkpos; - { int yypos1408= G->pos, yythunkpos1408= G->thunkpos; if (!yymatchString(G, "$$")) goto l1408; goto l1407; - l1408:; G->pos= yypos1408; G->thunkpos= yythunkpos1408; - } if (!yymatchDot(G)) goto l1407; goto l1406; - l1407:; G->pos= yypos1407; G->thunkpos= yythunkpos1407; - } if (!yymatchString(G, "$$")) goto l1405; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1405; if (!yy_Sp(G)) { goto l1405; } - { int yypos1409= G->pos, yythunkpos1409= G->thunkpos; if (!yy_FormulaNumber(G)) { goto l1409; } goto l1410; - l1409:; G->pos= yypos1409; G->thunkpos= yythunkpos1409; - } - l1410:; if (!yy_Sp(G)) { goto l1405; } if (!yy_Newline(G)) { goto l1405; } yyDo(G, yy_1_DisplayFormulaDollar, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "DisplayFormulaDollar", G->buf+G->pos)); - return 1; - l1405:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "DisplayFormulaDollar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockTidle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockTidle")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1411; if (!yy_FencedCodeBlockStartTidleLine(G)) { goto l1411; } - l1412:; - { int yypos1413= G->pos, yythunkpos1413= G->thunkpos; if (!yy_FencedCodeBlockChunkTidle(G)) { goto l1413; } goto l1412; - l1413:; G->pos= yypos1413; G->thunkpos= yythunkpos1413; - } if (!yy_FencedCodeBlockEndTidle(G)) { goto l1411; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1411; yyDo(G, yy_1_FencedCodeBlockTidle, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockTidle", G->buf+G->pos)); - return 1; - l1411:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockTidle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockTick(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockTick")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1414; if (!yy_FencedCodeBlockStartTickLine(G)) { goto l1414; } - l1415:; - { int yypos1416= G->pos, yythunkpos1416= G->thunkpos; if (!yy_FencedCodeBlockChunkTick(G)) { goto l1416; } goto l1415; - l1416:; G->pos= yypos1416; G->thunkpos= yythunkpos1416; - } if (!yy_FencedCodeBlockEndTick(G)) { goto l1414; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1414; yyDo(G, yy_1_FencedCodeBlockTick, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockTick", G->buf+G->pos)); - return 1; - l1414:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockTick", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockEndTidle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockEndTidle")); if (!yymatchString(G, "~~~")) goto l1417; - l1418:; - { int yypos1419= G->pos, yythunkpos1419= G->thunkpos; if (!yy_Spacechar(G)) { goto l1419; } goto l1418; - l1419:; G->pos= yypos1419; G->thunkpos= yythunkpos1419; - } if (!yy_Newline(G)) { goto l1417; } - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockEndTidle", G->buf+G->pos)); - return 1; - l1417:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockEndTidle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockChunkTidle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockChunkTidle")); - { int yypos1421= G->pos, yythunkpos1421= G->thunkpos; if (!yy_FencedCodeBlockEndTidle(G)) { goto l1421; } goto l1420; - l1421:; G->pos= yypos1421; G->thunkpos= yythunkpos1421; - } - l1422:; - { int yypos1423= G->pos, yythunkpos1423= G->thunkpos; - { int yypos1424= G->pos, yythunkpos1424= G->thunkpos; if (!yy_Newline(G)) { goto l1424; } goto l1423; - l1424:; G->pos= yypos1424; G->thunkpos= yythunkpos1424; - } if (!yymatchDot(G)) goto l1423; goto l1422; - l1423:; G->pos= yypos1423; G->thunkpos= yythunkpos1423; - } if (!yy_Newline(G)) { goto l1420; } - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockChunkTidle", G->buf+G->pos)); - return 1; - l1420:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockChunkTidle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockStartTidleLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockStartTidleLine")); if (!yy_FencedCodeBlockStartTidle(G)) { goto l1425; } if (!yy_Newline(G)) { goto l1425; } - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockStartTidleLine", G->buf+G->pos)); - return 1; - l1425:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockStartTidleLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockStartTidle(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockStartTidle")); if (!yymatchString(G, "~~~")) goto l1426; - l1427:; - { int yypos1428= G->pos, yythunkpos1428= G->thunkpos; - { int yypos1429= G->pos, yythunkpos1429= G->thunkpos; if (!yy_Newline(G)) { goto l1429; } goto l1428; - l1429:; G->pos= yypos1429; G->thunkpos= yythunkpos1429; - } - { int yypos1430= G->pos, yythunkpos1430= G->thunkpos; if (!yymatchChar(G, '~')) goto l1430; goto l1428; - l1430:; G->pos= yypos1430; G->thunkpos= yythunkpos1430; - } if (!yymatchDot(G)) goto l1428; goto l1427; - l1428:; G->pos= yypos1428; G->thunkpos= yythunkpos1428; - } - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockStartTidle", G->buf+G->pos)); - return 1; - l1426:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockStartTidle", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Spacechar(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Spacechar")); - { int yypos1432= G->pos, yythunkpos1432= G->thunkpos; if (!yymatchChar(G, ' ')) goto l1433; goto l1432; - l1433:; G->pos= yypos1432; G->thunkpos= yythunkpos1432; if (!yymatchChar(G, '\t')) goto l1431; - } - l1432:; - yyprintf((stderr, " ok %s @ %s\n", "Spacechar", G->buf+G->pos)); - return 1; - l1431:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Spacechar", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockEndTick(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockEndTick")); if (!yymatchString(G, "```")) goto l1434; - l1435:; - { int yypos1436= G->pos, yythunkpos1436= G->thunkpos; if (!yy_Spacechar(G)) { goto l1436; } goto l1435; - l1436:; G->pos= yypos1436; G->thunkpos= yythunkpos1436; - } if (!yy_Newline(G)) { goto l1434; } - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockEndTick", G->buf+G->pos)); - return 1; - l1434:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockEndTick", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockChunkTick(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockChunkTick")); - { int yypos1438= G->pos, yythunkpos1438= G->thunkpos; if (!yy_FencedCodeBlockEndTick(G)) { goto l1438; } goto l1437; - l1438:; G->pos= yypos1438; G->thunkpos= yythunkpos1438; - } - l1439:; - { int yypos1440= G->pos, yythunkpos1440= G->thunkpos; - { int yypos1441= G->pos, yythunkpos1441= G->thunkpos; if (!yy_Newline(G)) { goto l1441; } goto l1440; - l1441:; G->pos= yypos1441; G->thunkpos= yythunkpos1441; - } if (!yymatchDot(G)) goto l1440; goto l1439; - l1440:; G->pos= yypos1440; G->thunkpos= yythunkpos1440; - } if (!yy_Newline(G)) { goto l1437; } - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockChunkTick", G->buf+G->pos)); - return 1; - l1437:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockChunkTick", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockStartTickLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockStartTickLine")); if (!yy_FencedCodeBlockStartTick(G)) { goto l1442; } if (!yy_Newline(G)) { goto l1442; } - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockStartTickLine", G->buf+G->pos)); - return 1; - l1442:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockStartTickLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlockStartTick(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlockStartTick")); if (!yymatchString(G, "```")) goto l1443; - l1444:; - { int yypos1445= G->pos, yythunkpos1445= G->thunkpos; - { int yypos1446= G->pos, yythunkpos1446= G->thunkpos; if (!yy_Newline(G)) { goto l1446; } goto l1445; - l1446:; G->pos= yypos1446; G->thunkpos= yythunkpos1446; - } - { int yypos1447= G->pos, yythunkpos1447= G->thunkpos; if (!yymatchChar(G, '`')) goto l1447; goto l1445; - l1447:; G->pos= yypos1447; G->thunkpos= yythunkpos1447; - } if (!yymatchDot(G)) goto l1445; goto l1444; - l1445:; G->pos= yypos1445; G->thunkpos= yythunkpos1445; - } - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlockStartTick", G->buf+G->pos)); - return 1; - l1443:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlockStartTick", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_VerbatimChunk(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "VerbatimChunk")); - l1449:; - { int yypos1450= G->pos, yythunkpos1450= G->thunkpos; if (!yy_BlankLine(G)) { goto l1450; } goto l1449; - l1450:; G->pos= yypos1450; G->thunkpos= yythunkpos1450; - } if (!yy_NonblankIndentedLine(G)) { goto l1448; } - l1451:; - { int yypos1452= G->pos, yythunkpos1452= G->thunkpos; if (!yy_NonblankIndentedLine(G)) { goto l1452; } goto l1451; - l1452:; G->pos= yypos1452; G->thunkpos= yythunkpos1452; - } - yyprintf((stderr, " ok %s @ %s\n", "VerbatimChunk", G->buf+G->pos)); - return 1; - l1448:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "VerbatimChunk", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_IndentedLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "IndentedLine")); if (!yy_Indent(G)) { goto l1453; } if (!yy_Line(G)) { goto l1453; } - yyprintf((stderr, " ok %s @ %s\n", "IndentedLine", G->buf+G->pos)); - return 1; - l1453:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "IndentedLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NonblankIndentedLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NonblankIndentedLine")); - { int yypos1455= G->pos, yythunkpos1455= G->thunkpos; if (!yy_BlankLine(G)) { goto l1455; } goto l1454; - l1455:; G->pos= yypos1455; G->thunkpos= yythunkpos1455; - } if (!yy_IndentedLine(G)) { goto l1454; } - yyprintf((stderr, " ok %s @ %s\n", "NonblankIndentedLine", G->buf+G->pos)); - return 1; - l1454:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NonblankIndentedLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Line(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Line")); if (!yy_RawLine(G)) { goto l1456; } yyDo(G, yy_1_Line, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Line", G->buf+G->pos)); - return 1; - l1456:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Line", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StartList(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "StartList")); - { int yypos1458= G->pos, yythunkpos1458= G->thunkpos; if (!yymatchDot(G)) goto l1457; G->pos= yypos1458; G->thunkpos= yythunkpos1458; - } yyDo(G, yy_1_StartList, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "StartList", G->buf+G->pos)); - return 1; - l1457:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StartList", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_BlockQuoteRaw(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "BlockQuoteRaw")); if (!yy_StartList(G)) { goto l1459; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1459; if (!yymatchChar(G, '>')) goto l1459; - { int yypos1462= G->pos, yythunkpos1462= G->thunkpos; if (!yymatchChar(G, ' ')) goto l1462; goto l1463; - l1462:; G->pos= yypos1462; G->thunkpos= yythunkpos1462; - } - l1463:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1459; yyDo(G, yy_1_BlockQuoteRaw, G->begin, G->end); if (!yy_Line(G)) { goto l1459; } yyDo(G, yy_2_BlockQuoteRaw, G->begin, G->end); - l1464:; - { int yypos1465= G->pos, yythunkpos1465= G->thunkpos; - { int yypos1466= G->pos, yythunkpos1466= G->thunkpos; if (!yymatchChar(G, '>')) goto l1466; goto l1465; - l1466:; G->pos= yypos1466; G->thunkpos= yythunkpos1466; - } - { int yypos1467= G->pos, yythunkpos1467= G->thunkpos; if (!yy_BlankLine(G)) { goto l1467; } goto l1465; - l1467:; G->pos= yypos1467; G->thunkpos= yythunkpos1467; - } if (!yy_Line(G)) { goto l1465; } yyDo(G, yy_3_BlockQuoteRaw, G->begin, G->end); goto l1464; - l1465:; G->pos= yypos1465; G->thunkpos= yythunkpos1465; - } - l1468:; - { int yypos1469= G->pos, yythunkpos1469= G->thunkpos; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1469; if (!yy_BlankLine(G)) { goto l1469; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1469; yyDo(G, yy_4_BlockQuoteRaw, G->begin, G->end); goto l1468; - l1469:; G->pos= yypos1469; G->thunkpos= yythunkpos1469; - } - l1460:; - { int yypos1461= G->pos, yythunkpos1461= G->thunkpos; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1461; if (!yymatchChar(G, '>')) goto l1461; - { int yypos1470= G->pos, yythunkpos1470= G->thunkpos; if (!yymatchChar(G, ' ')) goto l1470; goto l1471; - l1470:; G->pos= yypos1470; G->thunkpos= yythunkpos1470; - } - l1471:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1461; yyDo(G, yy_1_BlockQuoteRaw, G->begin, G->end); if (!yy_Line(G)) { goto l1461; } yyDo(G, yy_2_BlockQuoteRaw, G->begin, G->end); - l1472:; - { int yypos1473= G->pos, yythunkpos1473= G->thunkpos; - { int yypos1474= G->pos, yythunkpos1474= G->thunkpos; if (!yymatchChar(G, '>')) goto l1474; goto l1473; - l1474:; G->pos= yypos1474; G->thunkpos= yythunkpos1474; - } - { int yypos1475= G->pos, yythunkpos1475= G->thunkpos; if (!yy_BlankLine(G)) { goto l1475; } goto l1473; - l1475:; G->pos= yypos1475; G->thunkpos= yythunkpos1475; - } if (!yy_Line(G)) { goto l1473; } yyDo(G, yy_3_BlockQuoteRaw, G->begin, G->end); goto l1472; - l1473:; G->pos= yypos1473; G->thunkpos= yythunkpos1473; - } - l1476:; - { int yypos1477= G->pos, yythunkpos1477= G->thunkpos; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1477; if (!yy_BlankLine(G)) { goto l1477; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1477; yyDo(G, yy_4_BlockQuoteRaw, G->begin, G->end); goto l1476; - l1477:; G->pos= yypos1477; G->thunkpos= yythunkpos1477; - } goto l1460; - l1461:; G->pos= yypos1461; G->thunkpos= yythunkpos1461; - } yyDo(G, yy_5_BlockQuoteRaw, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "BlockQuoteRaw", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1459:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "BlockQuoteRaw", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Endline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Endline")); - { int yypos1479= G->pos, yythunkpos1479= G->thunkpos; if (!yy_LineBreak(G)) { goto l1480; } goto l1479; - l1480:; G->pos= yypos1479; G->thunkpos= yythunkpos1479; if (!yy_TerminalEndline(G)) { goto l1481; } goto l1479; - l1481:; G->pos= yypos1479; G->thunkpos= yythunkpos1479; if (!yy_NormalEndline(G)) { goto l1478; } - } - l1479:; - yyprintf((stderr, " ok %s @ %s\n", "Endline", G->buf+G->pos)); - return 1; - l1478:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Endline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_RawLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "RawLine")); - { int yypos1483= G->pos, yythunkpos1483= G->thunkpos; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1484; - l1485:; - { int yypos1486= G->pos, yythunkpos1486= G->thunkpos; - { int yypos1487= G->pos, yythunkpos1487= G->thunkpos; if (!yymatchChar(G, '\r')) goto l1487; goto l1486; - l1487:; G->pos= yypos1487; G->thunkpos= yythunkpos1487; - } - { int yypos1488= G->pos, yythunkpos1488= G->thunkpos; if (!yymatchChar(G, '\n')) goto l1488; goto l1486; - l1488:; G->pos= yypos1488; G->thunkpos= yythunkpos1488; - } if (!yymatchDot(G)) goto l1486; goto l1485; - l1486:; G->pos= yypos1486; G->thunkpos= yythunkpos1486; - } if (!yy_Newline(G)) { goto l1484; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1484; goto l1483; - l1484:; G->pos= yypos1483; G->thunkpos= yythunkpos1483; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1482; if (!yymatchDot(G)) goto l1482; - l1489:; - { int yypos1490= G->pos, yythunkpos1490= G->thunkpos; if (!yymatchDot(G)) goto l1490; goto l1489; - l1490:; G->pos= yypos1490; G->thunkpos= yythunkpos1490; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1482; if (!yy_Eof(G)) { goto l1482; } - } - l1483:; yyDo(G, yy_1_RawLine, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "RawLine", G->buf+G->pos)); - return 1; - l1482:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "RawLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextBottom2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SetextBottom2")); if (!yymatchChar(G, '-')) goto l1491; - l1492:; - { int yypos1493= G->pos, yythunkpos1493= G->thunkpos; if (!yymatchChar(G, '-')) goto l1493; goto l1492; - l1493:; G->pos= yypos1493; G->thunkpos= yythunkpos1493; - } if (!yy_Newline(G)) { goto l1491; } - yyprintf((stderr, " ok %s @ %s\n", "SetextBottom2", G->buf+G->pos)); - return 1; - l1491:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextBottom2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextBottom1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SetextBottom1")); if (!yymatchChar(G, '=')) goto l1494; - l1495:; - { int yypos1496= G->pos, yythunkpos1496= G->thunkpos; if (!yymatchChar(G, '=')) goto l1496; goto l1495; - l1496:; G->pos= yypos1496; G->thunkpos= yythunkpos1496; - } if (!yy_Newline(G)) { goto l1494; } - yyprintf((stderr, " ok %s @ %s\n", "SetextBottom1", G->buf+G->pos)); - return 1; - l1494:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextBottom1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextHeading2(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "SetextHeading2")); - { int yypos1498= G->pos, yythunkpos1498= G->thunkpos; if (!yy_RawLine(G)) { goto l1497; } if (!yy_SetextBottom2(G)) { goto l1497; } G->pos= yypos1498; G->thunkpos= yythunkpos1498; - } if (!yy_LocMarker(G)) { goto l1497; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1497; - { int yypos1501= G->pos, yythunkpos1501= G->thunkpos; if (!yy_Endline(G)) { goto l1501; } goto l1497; - l1501:; G->pos= yypos1501; G->thunkpos= yythunkpos1501; - } if (!yy_Inline(G)) { goto l1497; } - l1499:; - { int yypos1500= G->pos, yythunkpos1500= G->thunkpos; - { int yypos1502= G->pos, yythunkpos1502= G->thunkpos; if (!yy_Endline(G)) { goto l1502; } goto l1500; - l1502:; G->pos= yypos1502; G->thunkpos= yythunkpos1502; - } if (!yy_Inline(G)) { goto l1500; } goto l1499; - l1500:; G->pos= yypos1500; G->thunkpos= yythunkpos1500; - } if (!yy_Sp(G)) { goto l1497; } if (!yy_Newline(G)) { goto l1497; } if (!yy_SetextBottom2(G)) { goto l1497; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1497; yyDo(G, yy_1_SetextHeading2, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "SetextHeading2", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1497:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextHeading2", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextHeading1(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "SetextHeading1")); - { int yypos1504= G->pos, yythunkpos1504= G->thunkpos; if (!yy_RawLine(G)) { goto l1503; } if (!yy_SetextBottom1(G)) { goto l1503; } G->pos= yypos1504; G->thunkpos= yythunkpos1504; - } if (!yy_LocMarker(G)) { goto l1503; } yyDo(G, yySet, -1, 0); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1503; - { int yypos1507= G->pos, yythunkpos1507= G->thunkpos; if (!yy_Endline(G)) { goto l1507; } goto l1503; - l1507:; G->pos= yypos1507; G->thunkpos= yythunkpos1507; - } if (!yy_Inline(G)) { goto l1503; } - l1505:; - { int yypos1506= G->pos, yythunkpos1506= G->thunkpos; - { int yypos1508= G->pos, yythunkpos1508= G->thunkpos; if (!yy_Endline(G)) { goto l1508; } goto l1506; - l1508:; G->pos= yypos1508; G->thunkpos= yythunkpos1508; - } if (!yy_Inline(G)) { goto l1506; } goto l1505; - l1506:; G->pos= yypos1506; G->thunkpos= yythunkpos1506; - } if (!yy_Sp(G)) { goto l1503; } if (!yy_Newline(G)) { goto l1503; } if (!yy_SetextBottom1(G)) { goto l1503; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1503; yyDo(G, yy_1_SetextHeading1, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "SetextHeading1", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1503:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextHeading1", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_SetextHeading(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "SetextHeading")); - { int yypos1510= G->pos, yythunkpos1510= G->thunkpos; if (!yy_SetextHeading1(G)) { goto l1511; } goto l1510; - l1511:; G->pos= yypos1510; G->thunkpos= yythunkpos1510; if (!yy_SetextHeading2(G)) { goto l1509; } - } - l1510:; - yyprintf((stderr, " ok %s @ %s\n", "SetextHeading", G->buf+G->pos)); - return 1; - l1509:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "SetextHeading", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Space(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Space")); if (!yy_Spacechar(G)) { goto l1512; } - l1513:; - { int yypos1514= G->pos, yythunkpos1514= G->thunkpos; if (!yy_Spacechar(G)) { goto l1514; } goto l1513; - l1514:; G->pos= yypos1514; G->thunkpos= yythunkpos1514; - } - yyprintf((stderr, " ok %s @ %s\n", "Space", G->buf+G->pos)); - return 1; - l1512:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Space", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AtxHeading(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "AtxHeading")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1515; if (!yy_AtxStart(G)) { goto l1515; } yyDo(G, yySet, -1, 0); if (!yy_Space(G)) { goto l1515; } if (!yy_AtxInline(G)) { goto l1515; } - l1516:; - { int yypos1517= G->pos, yythunkpos1517= G->thunkpos; if (!yy_AtxInline(G)) { goto l1517; } goto l1516; - l1517:; G->pos= yypos1517; G->thunkpos= yythunkpos1517; - } - { int yypos1518= G->pos, yythunkpos1518= G->thunkpos; if (!yy_Sp(G)) { goto l1518; } - l1520:; - { int yypos1521= G->pos, yythunkpos1521= G->thunkpos; if (!yymatchChar(G, '#')) goto l1521; goto l1520; - l1521:; G->pos= yypos1521; G->thunkpos= yythunkpos1521; - } if (!yy_Sp(G)) { goto l1518; } goto l1519; - l1518:; G->pos= yypos1518; G->thunkpos= yythunkpos1518; - } - l1519:; if (!yy_Newline(G)) { goto l1515; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1515; yyDo(G, yy_1_AtxHeading, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "AtxHeading", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1515:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AtxHeading", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_AtxStart(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "AtxStart")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1522; - { int yypos1523= G->pos, yythunkpos1523= G->thunkpos; if (!yymatchString(G, "######")) goto l1524; goto l1523; - l1524:; G->pos= yypos1523; G->thunkpos= yythunkpos1523; if (!yymatchString(G, "#####")) goto l1525; goto l1523; - l1525:; G->pos= yypos1523; G->thunkpos= yythunkpos1523; if (!yymatchString(G, "####")) goto l1526; goto l1523; - l1526:; G->pos= yypos1523; G->thunkpos= yythunkpos1523; if (!yymatchString(G, "###")) goto l1527; goto l1523; - l1527:; G->pos= yypos1523; G->thunkpos= yythunkpos1523; if (!yymatchString(G, "##")) goto l1528; goto l1523; - l1528:; G->pos= yypos1523; G->thunkpos= yythunkpos1523; if (!yymatchChar(G, '#')) goto l1522; - } - l1523:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1522; yyDo(G, yy_1_AtxStart, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "AtxStart", G->buf+G->pos)); - return 1; - l1522:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AtxStart", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Inline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Inline")); - { int yypos1530= G->pos, yythunkpos1530= G->thunkpos; if (!yy_Str(G)) { goto l1531; } goto l1530; - l1531:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Endline(G)) { goto l1532; } goto l1530; - l1532:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_UlOrStarLine(G)) { goto l1533; } goto l1530; - l1533:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Space(G)) { goto l1534; } goto l1530; - l1534:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Strong(G)) { goto l1535; } goto l1530; - l1535:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Emph(G)) { goto l1536; } goto l1530; - l1536:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Strike(G)) { goto l1537; } goto l1530; - l1537:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Image(G)) { goto l1538; } goto l1530; - l1538:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Link(G)) { goto l1539; } goto l1530; - l1539:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_NoteReference(G)) { goto l1540; } goto l1530; - l1540:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_InlineNote(G)) { goto l1541; } goto l1530; - l1541:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Code(G)) { goto l1542; } goto l1530; - l1542:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_InlineEquation(G)) { goto l1543; } goto l1530; - l1543:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Mark(G)) { goto l1544; } goto l1530; - l1544:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_RawHtml(G)) { goto l1545; } goto l1530; - l1545:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Entity(G)) { goto l1546; } goto l1530; - l1546:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_EscapedChar(G)) { goto l1547; } goto l1530; - l1547:; G->pos= yypos1530; G->thunkpos= yythunkpos1530; if (!yy_Symbol(G)) { goto l1529; } - } - l1530:; - yyprintf((stderr, " ok %s @ %s\n", "Inline", G->buf+G->pos)); - return 1; - l1529:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Inline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Sp(GREG *G) -{ - yyprintf((stderr, "%s\n", "Sp")); - l1549:; - { int yypos1550= G->pos, yythunkpos1550= G->thunkpos; if (!yy_Spacechar(G)) { goto l1550; } goto l1549; - l1550:; G->pos= yypos1550; G->thunkpos= yythunkpos1550; - } - yyprintf((stderr, " ok %s @ %s\n", "Sp", G->buf+G->pos)); - return 1; -} -YY_RULE(int) yy_AtxInline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "AtxInline")); - { int yypos1552= G->pos, yythunkpos1552= G->thunkpos; if (!yy_Newline(G)) { goto l1552; } goto l1551; - l1552:; G->pos= yypos1552; G->thunkpos= yythunkpos1552; - } - { int yypos1553= G->pos, yythunkpos1553= G->thunkpos; if (!yy_Sp(G)) { goto l1553; } - l1554:; - { int yypos1555= G->pos, yythunkpos1555= G->thunkpos; if (!yymatchChar(G, '#')) goto l1555; goto l1554; - l1555:; G->pos= yypos1555; G->thunkpos= yythunkpos1555; - } if (!yy_Sp(G)) { goto l1553; } if (!yy_Newline(G)) { goto l1553; } goto l1551; - l1553:; G->pos= yypos1553; G->thunkpos= yythunkpos1553; - } if (!yy_Inline(G)) { goto l1551; } - yyprintf((stderr, " ok %s @ %s\n", "AtxInline", G->buf+G->pos)); - return 1; - l1551:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "AtxInline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Inlines(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Inlines")); - { int yypos1559= G->pos, yythunkpos1559= G->thunkpos; - { int yypos1561= G->pos, yythunkpos1561= G->thunkpos; if (!yy_Endline(G)) { goto l1561; } goto l1560; - l1561:; G->pos= yypos1561; G->thunkpos= yythunkpos1561; - } if (!yy_Inline(G)) { goto l1560; } goto l1559; - l1560:; G->pos= yypos1559; G->thunkpos= yythunkpos1559; if (!yy_Endline(G)) { goto l1556; } - { int yypos1562= G->pos, yythunkpos1562= G->thunkpos; if (!yy_Inline(G)) { goto l1556; } G->pos= yypos1562; G->thunkpos= yythunkpos1562; - } - } - l1559:; - l1557:; - { int yypos1558= G->pos, yythunkpos1558= G->thunkpos; - { int yypos1563= G->pos, yythunkpos1563= G->thunkpos; - { int yypos1565= G->pos, yythunkpos1565= G->thunkpos; if (!yy_Endline(G)) { goto l1565; } goto l1564; - l1565:; G->pos= yypos1565; G->thunkpos= yythunkpos1565; - } if (!yy_Inline(G)) { goto l1564; } goto l1563; - l1564:; G->pos= yypos1563; G->thunkpos= yythunkpos1563; if (!yy_Endline(G)) { goto l1558; } - { int yypos1566= G->pos, yythunkpos1566= G->thunkpos; if (!yy_Inline(G)) { goto l1558; } G->pos= yypos1566; G->thunkpos= yythunkpos1566; - } - } - l1563:; goto l1557; - l1558:; G->pos= yypos1558; G->thunkpos= yythunkpos1558; - } - { int yypos1567= G->pos, yythunkpos1567= G->thunkpos; if (!yy_Endline(G)) { goto l1567; } goto l1568; - l1567:; G->pos= yypos1567; G->thunkpos= yythunkpos1567; - } - l1568:; - yyprintf((stderr, " ok %s @ %s\n", "Inlines", G->buf+G->pos)); - return 1; - l1556:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Inlines", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_NonindentSpace(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "NonindentSpace")); - { int yypos1570= G->pos, yythunkpos1570= G->thunkpos; if (!yymatchString(G, " ")) goto l1571; goto l1570; - l1571:; G->pos= yypos1570; G->thunkpos= yythunkpos1570; if (!yymatchString(G, " ")) goto l1572; goto l1570; - l1572:; G->pos= yypos1570; G->thunkpos= yythunkpos1570; if (!yymatchChar(G, ' ')) goto l1573; goto l1570; - l1573:; G->pos= yypos1570; G->thunkpos= yythunkpos1570; if (!yymatchString(G, "")) goto l1569; - } - l1570:; - yyprintf((stderr, " ok %s @ %s\n", "NonindentSpace", G->buf+G->pos)); - return 1; - l1569:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "NonindentSpace", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Plain(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Plain")); if (!yy_Inlines(G)) { goto l1574; } - yyprintf((stderr, " ok %s @ %s\n", "Plain", G->buf+G->pos)); - return 1; - l1574:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Plain", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Para(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Para")); if (!yy_NonindentSpace(G)) { goto l1575; } if (!yy_Inlines(G)) { goto l1575; } if (!yy_BlankLine(G)) { goto l1575; } - l1576:; - { int yypos1577= G->pos, yythunkpos1577= G->thunkpos; if (!yy_BlankLine(G)) { goto l1577; } goto l1576; - l1577:; G->pos= yypos1577; G->thunkpos= yythunkpos1577; - } - yyprintf((stderr, " ok %s @ %s\n", "Para", G->buf+G->pos)); - return 1; - l1575:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Para", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_StyleBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "StyleBlock")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1578; if (!yy_LocMarker(G)) { goto l1578; } yyDo(G, yySet, -1, 0); if (!yy_InStyleTags(G)) { goto l1578; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1578; - l1579:; - { int yypos1580= G->pos, yythunkpos1580= G->thunkpos; if (!yy_BlankLine(G)) { goto l1580; } goto l1579; - l1580:; G->pos= yypos1580; G->thunkpos= yythunkpos1580; - } yyDo(G, yy_1_StyleBlock, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "StyleBlock", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1578:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "StyleBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HtmlBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "HtmlBlock")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1581; if (!yy_LocMarker(G)) { goto l1581; } yyDo(G, yySet, -1, 0); - { int yypos1582= G->pos, yythunkpos1582= G->thunkpos; if (!yy_HtmlBlockInTags(G)) { goto l1583; } goto l1582; - l1583:; G->pos= yypos1582; G->thunkpos= yythunkpos1582; if (!yy_HtmlComment(G)) { goto l1584; } goto l1582; - l1584:; G->pos= yypos1582; G->thunkpos= yythunkpos1582; if (!yy_HtmlBlockSelfClosing(G)) { goto l1581; } - } - l1582:; yyText(G, G->begin, G->end); if (!(YY_END)) goto l1581; if (!yy_BlankLine(G)) { goto l1581; } - l1585:; - { int yypos1586= G->pos, yythunkpos1586= G->thunkpos; if (!yy_BlankLine(G)) { goto l1586; } goto l1585; - l1586:; G->pos= yypos1586; G->thunkpos= yythunkpos1586; - } yyDo(G, yy_1_HtmlBlock, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HtmlBlock", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1581:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HtmlBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Table(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Table")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_TABLE) )) goto l1587; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1587; if (!yy_LocMarker(G)) { goto l1587; } yyDo(G, yySet, -1, 0); if (!yy_TableHeader(G)) { goto l1587; } if (!yy_TableDelimiter(G)) { goto l1587; } - l1588:; - { int yypos1589= G->pos, yythunkpos1589= G->thunkpos; if (!yy_TableLine(G)) { goto l1589; } goto l1588; - l1589:; G->pos= yypos1589; G->thunkpos= yythunkpos1589; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1587; yyDo(G, yy_1_Table, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Table", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1587:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Table", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_BulletList(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "BulletList")); - { int yypos1591= G->pos, yythunkpos1591= G->thunkpos; if (!yy_Bullet(G)) { goto l1590; } G->pos= yypos1591; G->thunkpos= yythunkpos1591; - } - { int yypos1592= G->pos, yythunkpos1592= G->thunkpos; if (!yy_ListTight(G)) { goto l1593; } goto l1592; - l1593:; G->pos= yypos1592; G->thunkpos= yythunkpos1592; if (!yy_ListLoose(G)) { goto l1590; } - } - l1592:; - yyprintf((stderr, " ok %s @ %s\n", "BulletList", G->buf+G->pos)); - return 1; - l1590:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "BulletList", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_OrderedList(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "OrderedList")); - { int yypos1595= G->pos, yythunkpos1595= G->thunkpos; if (!yy_Enumerator(G)) { goto l1594; } G->pos= yypos1595; G->thunkpos= yythunkpos1595; - } - { int yypos1596= G->pos, yythunkpos1596= G->thunkpos; if (!yy_ListTight(G)) { goto l1597; } goto l1596; - l1597:; G->pos= yypos1596; G->thunkpos= yythunkpos1596; if (!yy_ListLoose(G)) { goto l1594; } - } - l1596:; - yyprintf((stderr, " ok %s @ %s\n", "OrderedList", G->buf+G->pos)); - return 1; - l1594:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "OrderedList", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Heading(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Heading")); - { int yypos1599= G->pos, yythunkpos1599= G->thunkpos; if (!yy_SetextHeading(G)) { goto l1600; } goto l1599; - l1600:; G->pos= yypos1599; G->thunkpos= yythunkpos1599; if (!yy_AtxHeading(G)) { goto l1598; } - } - l1599:; - yyprintf((stderr, " ok %s @ %s\n", "Heading", G->buf+G->pos)); - return 1; - l1598:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Heading", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_HorizontalRule(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "HorizontalRule")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1601; if (!yy_NonindentSpace(G)) { goto l1601; } - { int yypos1602= G->pos, yythunkpos1602= G->thunkpos; if (!yymatchChar(G, '*')) goto l1603; if (!yy_Sp(G)) { goto l1603; } if (!yymatchChar(G, '*')) goto l1603; if (!yy_Sp(G)) { goto l1603; } if (!yymatchChar(G, '*')) goto l1603; - l1604:; - { int yypos1605= G->pos, yythunkpos1605= G->thunkpos; if (!yy_Sp(G)) { goto l1605; } if (!yymatchChar(G, '*')) goto l1605; goto l1604; - l1605:; G->pos= yypos1605; G->thunkpos= yythunkpos1605; - } goto l1602; - l1603:; G->pos= yypos1602; G->thunkpos= yythunkpos1602; if (!yymatchChar(G, '-')) goto l1606; if (!yy_Sp(G)) { goto l1606; } if (!yymatchChar(G, '-')) goto l1606; if (!yy_Sp(G)) { goto l1606; } if (!yymatchChar(G, '-')) goto l1606; - l1607:; - { int yypos1608= G->pos, yythunkpos1608= G->thunkpos; if (!yy_Sp(G)) { goto l1608; } if (!yymatchChar(G, '-')) goto l1608; goto l1607; - l1608:; G->pos= yypos1608; G->thunkpos= yythunkpos1608; - } goto l1602; - l1606:; G->pos= yypos1602; G->thunkpos= yythunkpos1602; if (!yymatchChar(G, '_')) goto l1601; if (!yy_Sp(G)) { goto l1601; } if (!yymatchChar(G, '_')) goto l1601; if (!yy_Sp(G)) { goto l1601; } if (!yymatchChar(G, '_')) goto l1601; - l1609:; - { int yypos1610= G->pos, yythunkpos1610= G->thunkpos; if (!yy_Sp(G)) { goto l1610; } if (!yymatchChar(G, '_')) goto l1610; goto l1609; - l1610:; G->pos= yypos1610; G->thunkpos= yythunkpos1610; - } - } - l1602:; if (!yy_Sp(G)) { goto l1601; } if (!yy_Newline(G)) { goto l1601; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1601; yyDo(G, yy_1_HorizontalRule, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "HorizontalRule", G->buf+G->pos)); - return 1; - l1601:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "HorizontalRule", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Reference(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 3, 0); - yyprintf((stderr, "%s\n", "Reference")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1611; if (!yy_LocMarker(G)) { goto l1611; } yyDo(G, yySet, -3, 0); if (!yy_NonindentSpace(G)) { goto l1611; } - { int yypos1612= G->pos, yythunkpos1612= G->thunkpos; if (!yymatchString(G, "[]")) goto l1612; goto l1611; - l1612:; G->pos= yypos1612; G->thunkpos= yythunkpos1612; - } if (!yy_Label(G)) { goto l1611; } yyDo(G, yySet, -2, 0); if (!yymatchChar(G, ':')) goto l1611; if (!yy_Spnl(G)) { goto l1611; } if (!yy_RefSrc(G)) { goto l1611; } yyDo(G, yySet, -1, 0); if (!yy_RefTitle(G)) { goto l1611; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1611; if (!yy_BlankLine(G)) { goto l1611; } - l1613:; - { int yypos1614= G->pos, yythunkpos1614= G->thunkpos; if (!yy_BlankLine(G)) { goto l1614; } goto l1613; - l1614:; G->pos= yypos1614; G->thunkpos= yythunkpos1614; - } yyDo(G, yy_1_Reference, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Reference", G->buf+G->pos)); yyDo(G, yyPop, 3, 0); - return 1; - l1611:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Reference", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Note(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Note")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_NOTES) )) goto l1615; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1615; if (!yy_LocMarker(G)) { goto l1615; } yyDo(G, yySet, -1, 0); if (!yy_NonindentSpace(G)) { goto l1615; } if (!yy_RawNoteReference(G)) { goto l1615; } if (!yymatchChar(G, ':')) goto l1615; if (!yy_Sp(G)) { goto l1615; } if (!yy_RawNoteBlock(G)) { goto l1615; } - l1616:; - { int yypos1617= G->pos, yythunkpos1617= G->thunkpos; - { int yypos1618= G->pos, yythunkpos1618= G->thunkpos; if (!yy_Indent(G)) { goto l1617; } G->pos= yypos1618; G->thunkpos= yythunkpos1618; - } if (!yy_RawNoteBlock(G)) { goto l1617; } goto l1616; - l1617:; G->pos= yypos1617; G->thunkpos= yythunkpos1617; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1615; yyDo(G, yy_1_Note, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Note", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1615:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Note", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_DisplayFormula(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "DisplayFormula")); yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_MATH) )) goto l1619; - { int yypos1620= G->pos, yythunkpos1620= G->thunkpos; if (!yy_DisplayFormulaDollar(G)) { goto l1621; } goto l1620; - l1621:; G->pos= yypos1620; G->thunkpos= yythunkpos1620; if (!yy_DisplayFormulaRaw(G)) { goto l1619; } - } - l1620:; - yyprintf((stderr, " ok %s @ %s\n", "DisplayFormula", G->buf+G->pos)); - return 1; - l1619:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "DisplayFormula", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FencedCodeBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FencedCodeBlock")); - { int yypos1623= G->pos, yythunkpos1623= G->thunkpos; if (!yy_FencedCodeBlockTick(G)) { goto l1624; } goto l1623; - l1624:; G->pos= yypos1623; G->thunkpos= yythunkpos1623; if (!yy_FencedCodeBlockTidle(G)) { goto l1622; } - } - l1623:; - yyprintf((stderr, " ok %s @ %s\n", "FencedCodeBlock", G->buf+G->pos)); - return 1; - l1622:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FencedCodeBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Verbatim(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "Verbatim")); yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1625; if (!yy_LocMarker(G)) { goto l1625; } yyDo(G, yySet, -1, 0); if (!yy_VerbatimChunk(G)) { goto l1625; } - l1626:; - { int yypos1627= G->pos, yythunkpos1627= G->thunkpos; if (!yy_VerbatimChunk(G)) { goto l1627; } goto l1626; - l1627:; G->pos= yypos1627; G->thunkpos= yythunkpos1627; - } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1625; yyDo(G, yy_1_Verbatim, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "Verbatim", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1625:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Verbatim", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_BlockQuote(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "BlockQuote")); if (!yy_BlockQuoteRaw(G)) { goto l1628; } yyDo(G, yySet, -1, 0); yyDo(G, yy_1_BlockQuote, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "BlockQuote", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1628:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "BlockQuote", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_BlankLine(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "BlankLine")); if (!yy_Sp(G)) { goto l1629; } if (!yy_Newline(G)) { goto l1629; } - yyprintf((stderr, " ok %s @ %s\n", "BlankLine", G->buf+G->pos)); - return 1; - l1629:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "BlankLine", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FrontMatterEndMark(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FrontMatterEndMark")); - { int yypos1631= G->pos, yythunkpos1631= G->thunkpos; if (!yymatchString(G, "---")) goto l1632; goto l1631; - l1632:; G->pos= yypos1631; G->thunkpos= yythunkpos1631; if (!yymatchString(G, "...")) goto l1630; - } - l1631:; - yyprintf((stderr, " ok %s @ %s\n", "FrontMatterEndMark", G->buf+G->pos)); - return 1; - l1630:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FrontMatterEndMark", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FrontMatterBlock(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "FrontMatterBlock")); - { int yypos1634= G->pos, yythunkpos1634= G->thunkpos; if (!yy_FrontMatterEndMark(G)) { goto l1634; } goto l1633; - l1634:; G->pos= yypos1634; G->thunkpos= yythunkpos1634; - } - l1635:; - { int yypos1636= G->pos, yythunkpos1636= G->thunkpos; - { int yypos1637= G->pos, yythunkpos1637= G->thunkpos; if (!yy_Newline(G)) { goto l1637; } goto l1636; - l1637:; G->pos= yypos1637; G->thunkpos= yythunkpos1637; - } if (!yymatchDot(G)) goto l1636; goto l1635; - l1636:; G->pos= yypos1636; G->thunkpos= yythunkpos1636; - } if (!yy_Newline(G)) { goto l1633; } - yyprintf((stderr, " ok %s @ %s\n", "FrontMatterBlock", G->buf+G->pos)); - return 1; - l1633:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FrontMatterBlock", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Newline(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Newline")); - { int yypos1639= G->pos, yythunkpos1639= G->thunkpos; if (!yymatchChar(G, '\n')) goto l1640; goto l1639; - l1640:; G->pos= yypos1639; G->thunkpos= yythunkpos1639; if (!yymatchChar(G, '\r')) goto l1638; - { int yypos1641= G->pos, yythunkpos1641= G->thunkpos; if (!yymatchChar(G, '\n')) goto l1641; goto l1642; - l1641:; G->pos= yypos1641; G->thunkpos= yythunkpos1641; - } - l1642:; - } - l1639:; - yyprintf((stderr, " ok %s @ %s\n", "Newline", G->buf+G->pos)); - return 1; - l1638:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Newline", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_LocMarker(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "LocMarker")); - { int yypos1644= G->pos, yythunkpos1644= G->thunkpos; if (!yymatchDot(G)) goto l1643; G->pos= yypos1644; G->thunkpos= yythunkpos1644; - } yyDo(G, yy_1_LocMarker, G->begin, G->end); - yyprintf((stderr, " ok %s @ %s\n", "LocMarker", G->buf+G->pos)); - return 1; - l1643:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "LocMarker", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Block(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Block")); - l1646:; - { int yypos1647= G->pos, yythunkpos1647= G->thunkpos; if (!yy_BlankLine(G)) { goto l1647; } goto l1646; - l1647:; G->pos= yypos1647; G->thunkpos= yythunkpos1647; - } - { int yypos1648= G->pos, yythunkpos1648= G->thunkpos; if (!yy_BlockQuote(G)) { goto l1649; } goto l1648; - l1649:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_Verbatim(G)) { goto l1650; } goto l1648; - l1650:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_FencedCodeBlock(G)) { goto l1651; } goto l1648; - l1651:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_DisplayFormula(G)) { goto l1652; } goto l1648; - l1652:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_Note(G)) { goto l1653; } goto l1648; - l1653:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_Reference(G)) { goto l1654; } goto l1648; - l1654:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_HorizontalRule(G)) { goto l1655; } goto l1648; - l1655:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_Heading(G)) { goto l1656; } goto l1648; - l1656:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_OrderedList(G)) { goto l1657; } goto l1648; - l1657:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_BulletList(G)) { goto l1658; } goto l1648; - l1658:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_Table(G)) { goto l1659; } goto l1648; - l1659:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_HtmlBlock(G)) { goto l1660; } goto l1648; - l1660:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_StyleBlock(G)) { goto l1661; } goto l1648; - l1661:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_Para(G)) { goto l1662; } goto l1648; - l1662:; G->pos= yypos1648; G->thunkpos= yythunkpos1648; if (!yy_Plain(G)) { goto l1645; } - } - l1648:; - yyprintf((stderr, " ok %s @ %s\n", "Block", G->buf+G->pos)); - return 1; - l1645:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Block", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_FrontMatter(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; yyDo(G, yyPush, 1, 0); - yyprintf((stderr, "%s\n", "FrontMatter")); if (!yy_LocMarker(G)) { goto l1663; } yyDo(G, yySet, -1, 0); - { int yypos1664= G->pos, yythunkpos1664= G->thunkpos; yyText(G, G->begin, G->end); if (!( EXT(pmh_EXT_FRONTMATTER) )) goto l1664; yyText(G, G->begin, G->end); if (!(YY_BEGIN)) goto l1664; if (!yymatchString(G, "---")) goto l1664; if (!yy_Newline(G)) { goto l1664; } - l1666:; - { int yypos1667= G->pos, yythunkpos1667= G->thunkpos; if (!yy_FrontMatterBlock(G)) { goto l1667; } goto l1666; - l1667:; G->pos= yypos1667; G->thunkpos= yythunkpos1667; - } if (!yy_FrontMatterEndMark(G)) { goto l1664; } if (!yy_Newline(G)) { goto l1664; } yyText(G, G->begin, G->end); if (!(YY_END)) goto l1664; yyDo(G, yy_1_FrontMatter, G->begin, G->end); goto l1665; - l1664:; G->pos= yypos1664; G->thunkpos= yythunkpos1664; - } - l1665:; - yyprintf((stderr, " ok %s @ %s\n", "FrontMatter", G->buf+G->pos)); yyDo(G, yyPop, 1, 0); - return 1; - l1663:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "FrontMatter", G->buf+G->pos)); - return 0; -} -YY_RULE(int) yy_Doc(GREG *G) -{ int yypos0= G->pos, yythunkpos0= G->thunkpos; - yyprintf((stderr, "%s\n", "Doc")); if (!yy_FrontMatter(G)) { goto l1668; } - l1669:; - { int yypos1670= G->pos, yythunkpos1670= G->thunkpos; if (!yy_Block(G)) { goto l1670; } goto l1669; - l1670:; G->pos= yypos1670; G->thunkpos= yythunkpos1670; - } - yyprintf((stderr, " ok %s @ %s\n", "Doc", G->buf+G->pos)); - return 1; - l1668:; G->pos= yypos0; G->thunkpos= yythunkpos0; - yyprintf((stderr, " fail %s @ %s\n", "Doc", G->buf+G->pos)); - return 0; -} - -#ifndef YY_PART - -typedef int (*yyrule)(GREG *G); - -YY_PARSE(int) YY_NAME(parse_from)(GREG *G, yyrule yystart) -{ - int yyok; - if (!G->buflen) - { - G->buflen= YY_BUFFER_START_SIZE; - G->buf= (char *)YY_ALLOC(G->buflen, G->data); - G->textlen= YY_BUFFER_START_SIZE; - G->text= (char *)YY_ALLOC(G->textlen, G->data); - G->thunkslen= YY_STACK_SIZE; - G->thunks= (yythunk *)YY_ALLOC(sizeof(yythunk) * G->thunkslen, G->data); - G->valslen= YY_STACK_SIZE; - G->vals= (YYSTYPE*)YY_ALLOC(sizeof(YYSTYPE) * G->valslen, G->data); - G->begin= G->end= G->pos= G->limit= G->thunkpos= 0; - } - G->pos = 0; - G->begin= G->end= G->pos; - G->thunkpos= 0; - G->val= G->vals; - yyok= yystart(G); - if (yyok) yyDone(G); - yyCommit(G); - return yyok; - (void)yyrefill(NULL); - (void)yymatchDot(NULL); - (void)yymatchChar(NULL, 0); - (void)yymatchString(NULL, NULL); - (void)yymatchClass(NULL, NULL); - (void)yyDo(NULL, NULL, 0, 0); - (void)yyText(NULL, 0, 0); - (void)yyDone(NULL); - (void)yyCommit(NULL); - (void)yyAccept(NULL, 0); - (void)yyPush(NULL, NULL, 0, NULL, NULL); - (void)yyPop(NULL, NULL, 0, NULL, NULL); - (void)yySet(NULL, NULL, 0, NULL, NULL); -} - -YY_PARSE(int) YY_NAME(parse)(GREG *G) -{ - return YY_NAME(parse_from)(G, yy_Doc); -} - -YY_PARSE(GREG *) YY_NAME(parse_new)(YY_XTYPE data) -{ - GREG *G = (GREG *)YY_CALLOC(1, sizeof(GREG), G->data); - G->data = data; - return G; -} - -YY_PARSE(void) YY_NAME(parse_free)(GREG *G) -{ - YY_FREE(G->buf); - YY_FREE(G->text); - YY_FREE(G->thunks); - YY_FREE(G->vals); - YY_FREE(G); -} - -#endif - - - - -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_parser_foot.c - * - * Code to be appended to the end of the parser code generated from the - * PEG grammar. - */ - - -static void _parse(parser_data *p_data, yyrule start_rule) -{ - GREG *g = YY_NAME(parse_new)(p_data); - if (start_rule == NULL) - YY_NAME(parse)(g); - else - YY_NAME(parse_from)(g, start_rule); - YY_NAME(parse_free)(g); - - pmh_PRINTF("\n\n"); -} - -static void parse_markdown(parser_data *p_data) -{ - pmh_PRINTF("\nPARSING DOCUMENT: "); - - _parse(p_data, NULL); -} - -static void parse_references(parser_data *p_data) -{ - pmh_PRINTF("\nPARSING REFERENCES: "); - - p_data->parsing_only_references = true; - _parse(p_data, yy_References); - p_data->parsing_only_references = false; - - p_data->references = p_data->head_elems[pmh_REFERENCE]; - p_data->head_elems[pmh_REFERENCE] = NULL; -} - diff --git a/peg-highlight/pmh_parser.h b/peg-highlight/pmh_parser.h deleted file mode 100644 index 78086cab..00000000 --- a/peg-highlight/pmh_parser.h +++ /dev/null @@ -1,91 +0,0 @@ -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_parser.h - */ - -#ifdef Q_CC_GNU -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -/** \file -* \brief Parser public interface. -*/ - -#ifndef __cplusplus -#include -#endif - -#include -#include -#include "pmh_definitions.h" - - -/** -* \brief Parse Markdown text, return elements -* -* Parses the given Markdown text and returns the results as an -* array of linked lists of elements, indexed by type. -* -* \param[in] text The Markdown text to parse for highlighting. -* \param[in] extensions The extensions to use in parsing (a bitfield -* of pmh_extensions values). -* \param[out] out_result A pmh_element array, indexed by type, containing -* the results of the parsing (linked lists of elements). -* You must pass this to pmh_free_elements() when it's -* not needed anymore. -* -* \sa pmh_element_type -*/ -void pmh_markdown_to_elements(char *text, int extensions, - pmh_element **out_result[]); - -/** -* \brief Sort elements in list by start offset. -* -* Sorts the linked lists of elements in the list returned by -* pmh_markdown_to_elements() by their start offsets (pos). -* -* \param[in] element_lists Array of linked lists of elements (output -* from pmh_markdown_to_elements()). -* -* \sa pmh_markdown_to_elements -* \sa pmh_element::pos -*/ -void pmh_sort_elements_by_pos(pmh_element *element_lists[]); - -/** -* \brief Free pmh_element array -* -* Frees an pmh_element array returned by pmh_markdown_to_elements(). -* -* \param[in] elems The pmh_element array resulting from calling -* pmh_markdown_to_elements(). -* -* \sa pmh_markdown_to_elements -*/ -void pmh_free_elements(pmh_element **elems); - -/** -* \brief Get element type name -* -* \param[in] type The type value to get the name for. -* -* \return The name of the given type as a null-terminated string. -* -* \sa pmh_element_type -*/ -char *pmh_element_name_from_type(pmh_element_type type); - -/** -* \brief Get element type from a name -* -* \param[in] name The name of the type. -* -* \return The element type corresponding to the given name. -* -* \sa pmh_element_type -*/ -pmh_element_type pmh_element_type_from_name(char *name); - diff --git a/peg-highlight/pmh_styleparser.c b/peg-highlight/pmh_styleparser.c deleted file mode 100644 index ae4fd4c5..00000000 --- a/peg-highlight/pmh_styleparser.c +++ /dev/null @@ -1,937 +0,0 @@ -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * styleparser.c - * - * Parser for custom syntax highlighting stylesheets. - */ - -#include -#include -#include -#include -#include - -#include "pmh_styleparser.h" -#include "pmh_parser.h" - - -#if pmh_DEBUG_OUTPUT -#define pmhsp_PRINTF(x, ...) fprintf(stderr, x, ##__VA_ARGS__) -#else -#define pmhsp_PRINTF(x, ...) -#endif - - -// vasprintf is not in the C standard nor in POSIX so we provide our own -static int our_vasprintf(char **strptr, const char *fmt, va_list argptr) -{ - int ret; - va_list argptr2; - *strptr = NULL; - - va_copy(argptr2, argptr); - ret = vsnprintf(NULL, 0, fmt, argptr2); - if (ret <= 0) - return ret; - - *strptr = (char *)malloc(ret+1); - if (*strptr == NULL) - return -1; - - va_copy(argptr2, argptr); - ret = vsnprintf(*strptr, ret+1, fmt, argptr2); - - return ret; -} - - - -// Parsing context data -typedef struct -{ - char *input; - void (*error_callback)(char*,int,void*); - void *error_callback_context; - int styles_pos; - pmh_style_collection *styles; -} style_parser_data; - -typedef struct raw_attribute -{ - char *name; - char *value; - int line_number; - struct raw_attribute *next; -} raw_attribute; - -static raw_attribute *new_raw_attribute(char *name, char *value, - int line_number) -{ - raw_attribute *v = (raw_attribute *)malloc(sizeof(raw_attribute)); - v->name = name; - v->value = value; - v->line_number = line_number; - v->next = NULL; - return v; -} - -static void free_raw_attributes(raw_attribute *list) -{ - raw_attribute *cur = list; - while (cur != NULL) - { - raw_attribute *pattr = NULL; - if (cur->name != NULL) free(cur->name); - if (cur->value != NULL) free(cur->value); - pattr = cur; - cur = cur->next; - free(pattr); - } -} - - -static void report_error(style_parser_data *p_data, - int line_number, char *str, ...) -{ - va_list argptr; - if (p_data->error_callback == NULL) - return; - - va_start(argptr, str); - char *errmsg; - our_vasprintf(&errmsg, str, argptr); - va_end(argptr); - p_data->error_callback(errmsg, line_number, - p_data->error_callback_context); - free(errmsg); -} - - - -static char *trim_str(char *str) -{ - while (isspace(*str)) - str++; - if (*str == '\0') - return str; - char *end = str + strlen(str) - 1; - while (end > str && isspace(*end)) - end--; - *(end+1) = '\0'; - return str; -} - -static char *trim_str_dup(char *str) -{ - size_t start = 0; - while (isspace(*(str + start))) - start++; - size_t end = strlen(str) - 1; - while (start < end && isspace(*(str + end))) - end--; - - size_t len = end - start + 1; - char *ret = (char *)malloc(sizeof(char)*len + 1); - *ret = '\0'; - strncat(ret, (str + start), len); - - return ret; -} - -static char *strcpy_lower(char *str) -{ - char *low = strdup(str); - int i; - int len = strlen(str); - for (i = 0; i < len; i++) - *(low+i) = tolower(*(low+i)); - return low; -} - -static char *standardize_str(char *str) -{ - return strcpy_lower(trim_str(str)); -} - - - - -static pmh_attr_argb_color *new_argb_color(int r, int g, int b, int a) -{ - pmh_attr_argb_color *c = (pmh_attr_argb_color *) - malloc(sizeof(pmh_attr_argb_color)); - c->red = r; c->green = g; c->blue = b; c->alpha = a; - return c; -} -static pmh_attr_argb_color *new_argb_from_hex(long long hex, bool has_alpha) -{ - // 0xaarrggbb - int a = has_alpha ? ((hex >> 24) & 0xFF) : 255; - int r = ((hex >> 16) & 0xFF); - int g = ((hex >> 8) & 0xFF); - int b = (hex & 0xFF); - return new_argb_color(r,g,b,a); -} -static pmh_attr_argb_color *new_argb_from_hex_str(style_parser_data *p_data, - int attr_line_number, - char *str) -{ - // "aarrggbb" - int len = strlen(str); - if (len != 6 && len != 8) { - report_error(p_data, attr_line_number, - "Value '%s' is not a valid color value: it should be a " - "hexadecimal number, 6 or 8 characters long.", - str); - return NULL; - } - char *endptr = NULL; - long long num = strtoll(str, &endptr, 16); - if (*endptr != '\0') { - report_error(p_data, attr_line_number, - "Value '%s' is not a valid color value: the character " - "'%c' is invalid. The color value should be a hexadecimal " - "number, 6 or 8 characters long.", - str, *endptr); - return NULL; - } - return new_argb_from_hex(num, (len == 8)); -} - -static pmh_attr_value *new_attr_value() -{ - return (pmh_attr_value *)malloc(sizeof(pmh_attr_value)); -} - -static pmh_attr_font_styles *new_font_styles() -{ - pmh_attr_font_styles *ret = (pmh_attr_font_styles *) - malloc(sizeof(pmh_attr_font_styles)); - ret->italic = false; - ret->bold = false; - ret->underlined = false; - ret->strikeout = false; - return ret; -} - -static pmh_attr_font_size *new_font_size() -{ - pmh_attr_font_size *ret = (pmh_attr_font_size *) - malloc(sizeof(pmh_attr_font_size)); - ret->is_relative = false; - ret->size_pt = 0; - return ret; -} - -static pmh_style_attribute *new_attr(char *name, pmh_attr_type type) -{ - pmh_style_attribute *attr = (pmh_style_attribute *)malloc(sizeof(pmh_style_attribute)); - attr->name = strdup(name); - attr->type = type; - attr->next = NULL; - return attr; -} - -static void free_style_attributes(pmh_style_attribute *list) -{ - pmh_style_attribute *cur = list; - while (cur != NULL) - { - if (cur->name != NULL) - free(cur->name); - if (cur->value != NULL) - { - if (cur->type == pmh_attr_type_foreground_color - || cur->type == pmh_attr_type_background_color - || cur->type == pmh_attr_type_caret_color - || cur->type == pmh_attr_type_strike_color) - free(cur->value->argb_color); - else if (cur->type == pmh_attr_type_font_family) - free(cur->value->font_family); - else if (cur->type == pmh_attr_type_font_style) - free(cur->value->font_styles); - else if (cur->type == pmh_attr_type_font_size_pt) - free(cur->value->font_size); - else if (cur->type == pmh_attr_type_other) - free(cur->value->string); - free(cur->value); - } - pmh_style_attribute *pattr = cur; - cur = cur->next; - free(pattr); - } -} - - - - - -#define IF_ATTR_NAME(x) if (strcmp(x, name) == 0) -pmh_attr_type pmh_attr_type_from_name(char *name) -{ - IF_ATTR_NAME("color") return pmh_attr_type_foreground_color; - else IF_ATTR_NAME("foreground") return pmh_attr_type_foreground_color; - else IF_ATTR_NAME("foreground-color") return pmh_attr_type_foreground_color; - else IF_ATTR_NAME("background") return pmh_attr_type_background_color; - else IF_ATTR_NAME("background-color") return pmh_attr_type_background_color; - else IF_ATTR_NAME("caret") return pmh_attr_type_caret_color; - else IF_ATTR_NAME("caret-color") return pmh_attr_type_caret_color; - else IF_ATTR_NAME("strike") return pmh_attr_type_strike_color; - else IF_ATTR_NAME("strike-color") return pmh_attr_type_strike_color; - else IF_ATTR_NAME("font-size") return pmh_attr_type_font_size_pt; - else IF_ATTR_NAME("font-family") return pmh_attr_type_font_family; - else IF_ATTR_NAME("font-style") return pmh_attr_type_font_style; - return pmh_attr_type_other; -} - -char *pmh_attr_name_from_type(pmh_attr_type type) -{ - switch (type) - { - case pmh_attr_type_foreground_color: - return "foreground-color"; break; - case pmh_attr_type_background_color: - return "background-color"; break; - case pmh_attr_type_caret_color: - return "caret-color"; break; - case pmh_attr_type_strike_color: - return "strike-color"; break; - case pmh_attr_type_font_size_pt: - return "font-size"; break; - case pmh_attr_type_font_family: - return "font-family"; break; - case pmh_attr_type_font_style: - return "font-style"; break; - default: - return "unknown"; - } -} - - -typedef struct multi_value -{ - char *value; - size_t length; - int line_number; - struct multi_value *next; -} multi_value; - -static multi_value *split_multi_value(char *input, char separator) -{ - multi_value *head = NULL; - multi_value *tail = NULL; - - char *c = input; - while (*c != '\0') - { - size_t i; - for (i = 0; (*(c+i) != '\0' && *(c+i) != separator); i++); - - multi_value *mv = (multi_value *)malloc(sizeof(multi_value)); - mv->value = (char *)malloc(sizeof(char)*i + 1); - mv->length = i; - mv->line_number = 0; - mv->next = NULL; - *mv->value = '\0'; - strncat(mv->value, c, i); - - if (head == NULL) { - head = mv; - tail = mv; - } else { - tail->next = mv; - tail = mv; - } - - if (*(c+i) == separator) - i++; - c += i; - } - - return head; -} - -static void free_multi_value(multi_value *val) -{ - multi_value *cur = val; - while (cur != NULL) - { - multi_value *pvalue = cur; - multi_value *next_cur = cur->next; - free(pvalue->value); - free(pvalue); - cur = next_cur; - } -} - - - - -#define EQUALS(a,b) (strcmp(a, b) == 0) - -static pmh_style_attribute *interpret_attributes(style_parser_data *p_data, - pmh_element_type lang_element_type, - raw_attribute *raw_attributes) -{ - pmh_style_attribute *attrs = NULL; - - raw_attribute *cur = raw_attributes; - while (cur != NULL) - { - pmh_attr_type atype = pmh_attr_type_from_name(cur->name); - pmh_style_attribute *attr = new_attr(cur->name, atype); - attr->lang_element_type = lang_element_type; - attr->value = new_attr_value(); - - if (atype == pmh_attr_type_foreground_color - || atype == pmh_attr_type_background_color - || atype == pmh_attr_type_caret_color - || atype == pmh_attr_type_strike_color) - { - char *hexstr = trim_str(cur->value); - // new_argb_from_hex_str() reports conversion errors - attr->value->argb_color = - new_argb_from_hex_str(p_data, cur->line_number, hexstr); - if (attr->value->argb_color == NULL) { - free_style_attributes(attr); - attr = NULL; - } - } - else if (atype == pmh_attr_type_font_size_pt) - { - pmh_attr_font_size *fs = new_font_size(); - attr->value->font_size = fs; - - char *trimmed_value = trim_str_dup(cur->value); - - fs->is_relative = (*trimmed_value == '+' || *trimmed_value == '-'); - char *endptr = NULL; - fs->size_pt = (int)strtol(cur->value, &endptr, 10); - if (endptr == cur->value) { - report_error(p_data, cur->line_number, - "Value '%s' is invalid for attribute '%s'", - cur->value, cur->name); - free_style_attributes(attr); - attr = NULL; - } - - free(trimmed_value); - } - else if (atype == pmh_attr_type_font_family) - { - attr->value->font_family = trim_str_dup(cur->value); - } - else if (atype == pmh_attr_type_font_style) - { - attr->value->font_styles = new_font_styles(); - multi_value *values = split_multi_value(cur->value, ','); - multi_value *value_cur = values; - while (value_cur != NULL) - { - char *standardized_value = standardize_str(value_cur->value); - - if (EQUALS(standardized_value, "italic")) - attr->value->font_styles->italic = true; - else if (EQUALS(standardized_value, "bold")) - attr->value->font_styles->bold = true; - else if (EQUALS(standardized_value, "underlined")) - attr->value->font_styles->underlined = true; - else if (EQUALS(standardized_value, "strikeout")) - attr->value->font_styles->strikeout = true; - else { - report_error(p_data, cur->line_number, - "Value '%s' is invalid for attribute '%s'", - standardized_value, cur->name); - } - - free(standardized_value); - value_cur = value_cur->next; - } - free_multi_value(values); - } - else if (atype == pmh_attr_type_other) - { - attr->value->string = trim_str_dup(cur->value); - } - - if (attr != NULL) { - // add to linked list - attr->next = attrs; - attrs = attr; - } - - cur = cur->next; - } - - return attrs; -} - - -static void interpret_and_add_style(style_parser_data *p_data, - char *style_rule_name, - int style_rule_line_number, - raw_attribute *raw_attributes) -{ - bool isEditorType = false; - bool isCurrentLineType = false; - bool isSelectionType = false; - pmh_element_type type = pmh_element_type_from_name(style_rule_name); - if (type == pmh_NO_TYPE) - { - if (EQUALS(style_rule_name, "editor")) - isEditorType = true, type = pmh_NO_TYPE; - else if (EQUALS(style_rule_name, "editor-current-line")) - isCurrentLineType = true, type = pmh_NO_TYPE; - else if (EQUALS(style_rule_name, "editor-selection")) - isSelectionType = true, type = pmh_NO_TYPE; - else { - report_error(p_data, style_rule_line_number, - "Style rule '%s' is not a language element type name or " - "one of the following: 'editor', 'editor-current-line', " - "'editor-selection'", - style_rule_name); - return; - } - } - pmh_style_attribute *attrs = interpret_attributes(p_data, type, raw_attributes); - if (isEditorType) - p_data->styles->editor_styles = attrs; - else if (isCurrentLineType) - p_data->styles->editor_current_line_styles = attrs; - else if (isSelectionType) - p_data->styles->editor_selection_styles = attrs; - else - p_data->styles->element_styles[(p_data->styles_pos)++] = attrs; -} - - - - - - - -static bool char_is_whitespace(char c) -{ - return (c == ' ' || c == '\t'); -} - -static bool char_begins_linecomment(char c) -{ - return (c == '#'); -} - -static bool line_is_comment(multi_value *line) -{ - char *c; - for (c = line->value; *c != '\0'; c++) - { - if (!char_is_whitespace(*c)) - return char_begins_linecomment(*c); - } - return false; -} - -static bool line_is_empty(multi_value *line) -{ - char *c; - for (c = line->value; *c != '\0'; c++) - { - if (!char_is_whitespace(*c)) - return false; - } - return true; -} - - - -typedef struct block -{ - multi_value *lines; - struct block *next; -} block; - -static block *new_block() -{ - block *ret = (block *)malloc(sizeof(block)); - ret->next = NULL; - ret->lines = NULL; - return ret; -} - -static void free_blocks(block *val) -{ - block *cur = val; - while (cur != NULL) - { - block *pblock = cur; - block *next = pblock->next; - free_multi_value(pblock->lines); - free(pblock); - cur = next; - } -} - -static block *get_blocks(char *input) -{ - block *head = NULL; - block *tail = NULL; - block *current_block = NULL; - - multi_value *discarded_lines = NULL; - - int line_number_counter = 1; - - multi_value *lines = split_multi_value(input, '\n'); - multi_value *previous_line = NULL; - multi_value *line_cur = lines; - while (line_cur != NULL) - { - bool discard_line = false; - - line_cur->line_number = line_number_counter++; - - if (line_is_empty(line_cur)) - { - discard_line = true; - - if (current_block != NULL) - { - // terminate block - if (tail != current_block) - tail->next = current_block; - tail = current_block; - current_block = NULL; - previous_line->next = NULL; - } - } - else if (line_is_comment(line_cur)) - { - // Do not discard (i.e. free()) comment lines within blocks: - if (current_block == NULL) - discard_line = true; - } - else - { - if (current_block == NULL) - { - // start block - current_block = new_block(); - current_block->lines = line_cur; - if (previous_line != NULL) - previous_line->next = NULL; - } - if (head == NULL) { - head = current_block; - tail = current_block; - } - } - - multi_value *next_cur = line_cur->next; - previous_line = (discard_line) ? NULL : line_cur; - - if (discard_line) { - line_cur->next = discarded_lines; - discarded_lines = line_cur; - } - - line_cur = next_cur; - } - - if (current_block != NULL && tail != current_block) - tail->next = current_block; - - free_multi_value(discarded_lines); - - return head; -} - - -#define ASSIGNMENT_OP_UITEXT "':' or '='" -#define IS_ASSIGNMENT_OP(c) ((c) == ':' || (c) == '=') -#define IS_STYLE_RULE_NAME_CHAR(c) \ - ( (c) != '\0' && !isspace(c) \ - && !char_begins_linecomment(c) && !IS_ASSIGNMENT_OP(c) ) -#define IS_ATTRIBUTE_NAME_CHAR(c) \ - ( (c) != '\0' && !char_begins_linecomment(c) && !IS_ASSIGNMENT_OP(c) ) -#define IS_ATTRIBUTE_VALUE_CHAR(c) \ - ( (c) != '\0' && !char_begins_linecomment(c) ) - -static char *get_style_rule_name(multi_value *line) -{ - char *str = line->value; - - // Scan past leading whitespace: - size_t start_index; - for (start_index = 0; - (*(str+start_index) != '\0' && isspace(*(str+start_index))); - start_index++); - - // Scan until style rule name characters end: - size_t value_end_index; - for (value_end_index = start_index; - IS_STYLE_RULE_NAME_CHAR(*(str + value_end_index)); - value_end_index++); - - // Copy style rule name: - size_t value_len = value_end_index - start_index; - char *value = (char *)malloc(sizeof(char)*value_len + 1); - *value = '\0'; - strncat(value, (str + start_index), value_len); - - return value; -} - -static bool parse_attribute_line(style_parser_data *p_data, multi_value *line, - char **out_attr_name, char **out_attr_value) -{ - char *str = line->value; - - // Scan past leading whitespace: - size_t name_start_index; - for (name_start_index = 0; - ( *(str+name_start_index) != '\0' && - isspace(*(str+name_start_index)) ); - name_start_index++); - - // Scan until attribute name characters end: - size_t name_end_index; - for (name_end_index = name_start_index; - IS_ATTRIBUTE_NAME_CHAR(*(str + name_end_index)); - name_end_index++); - // Scan backwards to trim trailing whitespace off: - while (name_start_index < name_end_index - && isspace(*(str + name_end_index - 1))) - name_end_index--; - - // Scan until just after the first assignment operator: - size_t assignment_end_index; - for (assignment_end_index = name_end_index; - ( *(str + assignment_end_index) != '\0' && - !IS_ASSIGNMENT_OP(*(str + assignment_end_index)) ); - assignment_end_index++); - - // Scan over the found assignment operator, or report error: - if (IS_ASSIGNMENT_OP(*(str + assignment_end_index))) - assignment_end_index++; - else - { - report_error(p_data, line->line_number, - "Invalid attribute definition: str does not contain " - "an assignment operator (%s): '%s'", - ASSIGNMENT_OP_UITEXT, str); - return false; - } - - size_t value_start_index = assignment_end_index; - // Scan until attribute value characters end: - size_t value_end_index; - for (value_end_index = value_start_index; - IS_ATTRIBUTE_VALUE_CHAR(*(str + value_end_index)); - value_end_index++); - - // Copy attribute name: - size_t name_len = name_end_index - name_start_index; - char *attr_name = (char *)malloc(sizeof(char)*name_len + 1); - *attr_name = '\0'; - strncat(attr_name, (str + name_start_index), name_len); - *out_attr_name = attr_name; - - // Copy attribute value: - size_t attr_value_len = value_end_index - assignment_end_index; - char *attr_value_str = (char *)malloc(sizeof(char)*attr_value_len + 1); - *attr_value_str = '\0'; - strncat(attr_value_str, (str + assignment_end_index), attr_value_len); - *out_attr_value = attr_value_str; - - return true; -} - - -#define HAS_UTF8_BOM(x) ( ((*x & 0xFF) == 0xEF)\ - && ((*(x+1) & 0xFF) == 0xBB)\ - && ((*(x+2) & 0xFF) == 0xBF) ) - -// - Removes UTF-8 BOM -// - Standardizes line endings to \n -static char *strcpy_preformat_style(char *str) -{ - char *new_str = (char *)malloc(sizeof(char) * strlen(str) + 1); - - char *c = str; - int i = 0; - - if (HAS_UTF8_BOM(c)) - c += 3; - - while (*c != '\0') - { - if (*c == '\r' && *(c+1) == '\n') - { - *(new_str+i) = '\n'; - i++; - c += 2; - } - else if (*c == '\r') - { - *(new_str+i) = '\n'; - i++; - c++; - } - else - { - *(new_str+i) = *c; - i++; - c++; - } - } - *(new_str+i) = '\0'; - - return new_str; -} - - - -static void _sty_parse(style_parser_data *p_data) -{ - // We don't have to worry about leaking the original p_data->input; - // the user of the library is responsible for that: - p_data->input = strcpy_preformat_style(p_data->input); - - block *blocks = get_blocks(p_data->input); - - block *block_cur = blocks; - while (block_cur != NULL) - { - raw_attribute *attributes_head = NULL; - raw_attribute *attributes_tail = NULL; - - pmhsp_PRINTF("Block:\n"); - multi_value *header_line = block_cur->lines; - if (header_line == NULL) { - block_cur = block_cur->next; - continue; - } - - pmhsp_PRINTF(" Head line (len %ld): '%s'\n", - header_line->length, header_line->value); - char *style_rule_name = get_style_rule_name(header_line); - pmhsp_PRINTF(" Style rule name: '%s'\n", style_rule_name); - - multi_value *attr_line_cur = header_line->next; - if (attr_line_cur == NULL) - report_error(p_data, header_line->line_number, - "No style attributes defined for style rule '%s'", - style_rule_name); - - while (attr_line_cur != NULL) - { - if (line_is_comment(attr_line_cur)) - { - attr_line_cur = attr_line_cur->next; - continue; - } - - pmhsp_PRINTF(" Attr line (len %ld): '%s'\n", - attr_line_cur->length, attr_line_cur->value); - char *attr_name_str; - char *attr_value_str; - bool success = parse_attribute_line(p_data, - attr_line_cur, - &attr_name_str, - &attr_value_str); - if (success) - { - pmhsp_PRINTF(" Attr: '%s' Value: '%s'\n", - attr_name_str, attr_value_str); - raw_attribute *attribute = - new_raw_attribute(attr_name_str, attr_value_str, - attr_line_cur->line_number); - if (attributes_head == NULL) { - attributes_head = attribute; - attributes_tail = attribute; - } else { - attributes_tail->next = attribute; - attributes_tail = attribute; - } - } - - attr_line_cur = attr_line_cur->next; - } - - if (attributes_head != NULL) - { - interpret_and_add_style(p_data, style_rule_name, - header_line->line_number, attributes_head); - free_raw_attributes(attributes_head); - } - - free(style_rule_name); - - block_cur = block_cur->next; - } - - free_blocks(blocks); - free(p_data->input); -} - - - -static pmh_style_collection *new_style_collection() -{ - pmh_style_collection *sc = (pmh_style_collection *) - malloc(sizeof(pmh_style_collection)); - - sc->element_styles = (pmh_style_attribute**) - malloc(sizeof(pmh_style_attribute*) - * pmh_NUM_LANG_TYPES); - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - sc->element_styles[i] = NULL; - - sc->editor_styles = NULL; - sc->editor_current_line_styles = NULL; - sc->editor_selection_styles = NULL; - - return sc; -} - -void pmh_free_style_collection(pmh_style_collection *coll) -{ - free_style_attributes(coll->editor_styles); - free_style_attributes(coll->editor_current_line_styles); - free_style_attributes(coll->editor_selection_styles); - int i; - for (i = 0; i < pmh_NUM_LANG_TYPES; i++) - free_style_attributes(coll->element_styles[i]); - free(coll->element_styles); - free(coll); -} - -static style_parser_data *new_style_parser_data(char *input) -{ - style_parser_data *p_data = (style_parser_data*) - malloc(sizeof(style_parser_data)); - p_data->input = input; - p_data->styles_pos = 0; - p_data->styles = new_style_collection(); - return p_data; -} - -pmh_style_collection *pmh_parse_styles(char *input, - void(*error_callback)(char*,int,void*), - void *error_callback_context) -{ - style_parser_data *p_data = new_style_parser_data(input); - p_data->error_callback = error_callback; - p_data->error_callback_context = error_callback_context; - - _sty_parse(p_data); - - pmh_style_collection *ret = p_data->styles; - free(p_data); - return ret; -} - - diff --git a/peg-highlight/pmh_styleparser.h b/peg-highlight/pmh_styleparser.h deleted file mode 100644 index 7b9d1baa..00000000 --- a/peg-highlight/pmh_styleparser.h +++ /dev/null @@ -1,149 +0,0 @@ -/* PEG Markdown Highlight - * Copyright 2011-2016 Ali Rantakari -- http://hasseg.org - * Licensed under the GPL2+ and MIT licenses (see LICENSE for more info). - * - * pmh_styleparser.h - * - * Public interface of a parser for custom syntax highlighting stylesheets. - */ - -/** \file -* \brief Style parser public interface. -*/ - -#include "pmh_definitions.h" -#include - -/** -* \brief Color (ARGB) attribute value. -* -* All values are 0-255. -*/ -typedef struct -{ - int red; /**< Red color component (0-255) */ - int green; /**< Green color component (0-255) */ - int blue; /**< Blue color component (0-255) */ - int alpha; /**< Alpha (opacity) color component (0-255) */ -} pmh_attr_argb_color; - -/** \brief Font style attribute value. */ -typedef struct -{ - bool italic; - bool bold; - bool underlined; - bool strikeout; -} pmh_attr_font_styles; - -/** \brief Font size attribute value. */ -typedef struct -{ - int size_pt; /**< The font point size */ - bool is_relative; /**< Whether the size is relative (i.e. size_pt points - larger than the default font) */ -} pmh_attr_font_size; - -/** \brief Style attribute types. */ -typedef enum -{ - pmh_attr_type_foreground_color, /**< Foreground color */ - pmh_attr_type_background_color, /**< Background color */ - pmh_attr_type_caret_color, /**< Caret (insertion point) color */ - pmh_attr_type_font_size_pt, /**< Font size (in points) */ - pmh_attr_type_font_family, /**< Font family */ - pmh_attr_type_font_style, /**< Font style */ - pmh_attr_type_strike_color, /**< Strike-through color */ - pmh_attr_type_other /**< Arbitrary custom attribute */ -} pmh_attr_type; - -/** -* \brief Style attribute value. -* -* Determine which member to access in this union based on the -* 'type' value of the pmh_style_attribute. -* -* \sa pmh_style_attribute -*/ -typedef union -{ - pmh_attr_argb_color *argb_color; /**< ARGB color */ - pmh_attr_font_styles *font_styles; /**< Font styles */ - pmh_attr_font_size *font_size; /**< Font size */ - char *font_family; /**< Font family */ - char *string; /**< Arbitrary custom string value - (use this if the attribute's type - is pmh_attr_type_other) */ -} pmh_attr_value; - -/** \brief Style attribute. */ -typedef struct pmh_style_attribute -{ - pmh_element_type lang_element_type; /**< The Markdown language element this - style applies to */ - pmh_attr_type type; /**< The type of the attribute */ - char *name; /**< The name of the attribute (if type - is pmh_attr_type_other, you can - use this value to determine what - the attribute is) */ - pmh_attr_value *value; /**< The value of the attribute */ - struct pmh_style_attribute *next; /**< Next attribute in linked list */ -} pmh_style_attribute; - -/** \brief Collection of styles. */ -typedef struct -{ - /** Styles that apply to the editor in general */ - pmh_style_attribute *editor_styles; - - /** Styles that apply to the line in the editor where the caret (insertion - point) resides */ - pmh_style_attribute *editor_current_line_styles; - - /** Styles that apply to the range of selected text in the editor */ - pmh_style_attribute *editor_selection_styles; - - /** Styles that apply to specific Markdown language elements */ - pmh_style_attribute **element_styles; -} pmh_style_collection; - - -/** -* \brief Parse stylesheet string, return style collection -* -* \param[in] input The stylesheet string to parse. -* \param[in] error_callback Callback function to be called when errors -* occur during parsing. The first argument -* to the callback function is the error -* message and the second one the line number -* in the original input where the error -* occurred. The last argument will always -* get the value you pass in for the -* error_callback_context argument to this -* function. -* Pass in NULL to suppress error reporting. -* \param[in] error_callback_context Arbitrary context pointer for the error -* callback function; will be passed in as -* the last argument to error_callback. -* -* \return A pmh_style_collection. You must pass this value to -* pmh_free_style_collection() when it's not needed anymore. -*/ -pmh_style_collection *pmh_parse_styles(char *input, - void(*error_callback)(char*,int,void*), - void *error_callback_context); - -/** -* \brief Free a pmh_style_collection. -* -* Frees a pmh_style_collection value returned by pmh_parse_styles(). -* -* \param[in] collection The collection to free. -*/ -void pmh_free_style_collection(pmh_style_collection *collection); - - -char *pmh_attr_name_from_type(pmh_attr_type type); - -pmh_attr_type pmh_attr_type_from_name(char *name); - diff --git a/peg-highlight/styles/error.style b/peg-highlight/styles/error.style deleted file mode 100644 index 4036ff9b..00000000 --- a/peg-highlight/styles/error.style +++ /dev/null @@ -1,8 +0,0 @@ -NONEXISTENT_TYPE -x: 3 - -STRONG -font-style: funkadelic, bold, snazzy -foreground: 13bx12 -background: 5 - diff --git a/peg-highlight/styles/fontsizes.style b/peg-highlight/styles/fontsizes.style deleted file mode 100644 index d6b40c5c..00000000 --- a/peg-highlight/styles/fontsizes.style +++ /dev/null @@ -1,87 +0,0 @@ -# Styles using 'Solarized' color scheme -# by Ethan Schoonover: http://ethanschoonover.com/solarized -# -# (dark background version) - -editor -foreground: 93a1a1 # base1 -background: 002b36 # base03 -caret: ffffff -font-size: 13 - -H1 -foreground: 6c71c4 # violet -font-style: bold -font-size: +6 - -H2 -foreground: 6c71c4 # violet -font-style: bold -font-size: +5 - -H3 -foreground: 6c71c4 # violet -font-size: +4 - -H4 -foreground: 268bd2 # blue -font-size: +3 - -H5 -foreground: 268bd2 # blue -font-size: +2 - -H6 -foreground: 268bd2 # blue -font-size: +1 - -HRULE -foreground: 586e75 # base01 - -LIST_BULLET -foreground: b58900 # yellow - -LIST_ENUMERATOR -foreground: b58900 # yellow - -LINK -foreground: 2aa198 # cyan - -AUTO_LINK_URL -foreground: 2aa198 # cyan - -AUTO_LINK_EMAIL -foreground: 2aa198 # cyan - -IMAGE -foreground: d33682 # magenta - -REFERENCE -foreground: 80b58900 # yellow, reduced alpha -font-size: -2 - -CODE -foreground: 859900 # green - -EMPH -foreground: cb4b16 # orange -font-style: italic - -STRONG -foreground: dc322f # red -font-style: bold - -HTML_ENTITY -foreground: 6c71c4 # violet - -COMMENT -foreground: 93a1a1 # base1 - -VERBATIM -foreground: 859900 # green - -BLOCKQUOTE -foreground: d33682 # magenta - -STRIKE -strike-color: 93a1a1 # base1 diff --git a/peg-highlight/styles/macoslineseparator.style b/peg-highlight/styles/macoslineseparator.style deleted file mode 100644 index b6b92559..00000000 --- a/peg-highlight/styles/macoslineseparator.style +++ /dev/null @@ -1 +0,0 @@ -# linecomment editor # comment foreground : 13ff13 background : 000000 # comment # linecomment STRONG: EMPH= # comment foreground: 00ff00 comment asd background: AB0000ff STRONG : dog: 1 # something cat: 4 font-style: underlined, Italic , BoLD #hi, hello font-size: 14pt font-family: Courier New, Times # linecomment BOO x: 3 editor-selection: foreground: abcdef background: abcdef editor-current-line: background: ffffff \ No newline at end of file diff --git a/peg-highlight/styles/playground.style b/peg-highlight/styles/playground.style deleted file mode 100644 index 464768d5..00000000 --- a/peg-highlight/styles/playground.style +++ /dev/null @@ -1,22 +0,0 @@ -editor : - foreground : 13ff13 - background : 000000 - caret: ffffff - -EMPH - font-style: italic - -STRONG - font-style: bold - -LINK - font-style: underlined - -editor-selection: - foreground: ff0000 - background: eeeeee - font-style: underlined - -editor-current-line: - background: ffffff - diff --git a/peg-highlight/styles/solarized-dark.style b/peg-highlight/styles/solarized-dark.style deleted file mode 100644 index 635d5b3e..00000000 --- a/peg-highlight/styles/solarized-dark.style +++ /dev/null @@ -1,79 +0,0 @@ -# Styles using 'Solarized' color scheme -# by Ethan Schoonover: http://ethanschoonover.com/solarized -# -# (dark background version) - -editor -foreground: 93a1a1 # base1 -background: 002b36 # base03 -caret: ffffff - -H1 -foreground: 6c71c4 # violet -font-style: bold - -H2 -foreground: 6c71c4 # violet -font-style: bold - -H3 -foreground: 6c71c4 # violet - -H4 -foreground: 268bd2 # blue - -H5 -foreground: 268bd2 # blue - -H6 -foreground: 268bd2 # blue - -HRULE -foreground: 586e75 # base01 - -LIST_BULLET -foreground: b58900 # yellow - -LIST_ENUMERATOR -foreground: b58900 # yellow - -LINK -foreground: 2aa198 # cyan - -AUTO_LINK_URL -foreground: 2aa198 # cyan - -AUTO_LINK_EMAIL -foreground: 2aa198 # cyan - -IMAGE -foreground: d33682 # magenta - -REFERENCE -foreground: 80b58900 # yellow, reduced alpha - -CODE -foreground: 859900 # green - -EMPH -foreground: cb4b16 # orange -font-style: italic - -STRONG -foreground: dc322f # red -font-style: bold - -HTML_ENTITY -foreground: 6c71c4 # violet - -COMMENT -foreground: 93a1a1 # base1 - -VERBATIM -foreground: 859900 # green - -BLOCKQUOTE -foreground: d33682 # magenta - -STRIKE -strike-color: 93a1a1 # base1 diff --git a/peg-highlight/styles/solarized-light.style b/peg-highlight/styles/solarized-light.style deleted file mode 100644 index 5d496177..00000000 --- a/peg-highlight/styles/solarized-light.style +++ /dev/null @@ -1,80 +0,0 @@ -# Styles using 'Solarized' color scheme -# by Ethan Schoonover: http://ethanschoonover.com/solarized -# -# (light background version) - -editor -foreground: 586e75 # base01 -background: fdf6e3 # base3 -caret: 000000 - -H1 -foreground: 6c71c4 # violet -font-style: bold - -H2 -foreground: 6c71c4 # violet -font-style: bold - -H3 -foreground: 6c71c4 # violet - -H4 -foreground: 268bd2 # blue - -H5 -foreground: 268bd2 # blue - -H6 -foreground: 268bd2 # blue - -HRULE -foreground: 586e75 # base01 - -LIST_BULLET -foreground: b58900 # yellow - -LIST_ENUMERATOR -foreground: b58900 # yellow - -LINK -foreground: 2aa198 # cyan - -AUTO_LINK_URL -foreground: 2aa198 # cyan - -AUTO_LINK_EMAIL -foreground: 2aa198 # cyan - -IMAGE -foreground: d33682 # magenta - -REFERENCE -foreground: 80b58900 # yellow, reduced alpha - -CODE -foreground: 859900 # green - -EMPH -foreground: cb4b16 # orange -font-style: italic - -STRONG -foreground: dc322f # red -font-style: bold - -HTML_ENTITY -foreground: 6c71c4 # violet - -COMMENT -foreground: 93a1a1 # base1 - -VERBATIM -foreground: 859900 # green - -BLOCKQUOTE -foreground: d33682 # magenta - -STRIKE -strike-color: 586e75 # base01 - diff --git a/peg-highlight/styles/teststyle.style b/peg-highlight/styles/teststyle.style deleted file mode 100644 index 87ae7f1b..00000000 --- a/peg-highlight/styles/teststyle.style +++ /dev/null @@ -1,33 +0,0 @@ -# linecomment - -editor # comment - foreground : 13ff13 - background : 000000 # comment - -# linecomment -STRONG: - -EMPH= - # comment - foreground: 00ff00 -comment asd - background: AB0000ff - -STRONG : - dog: 1 # something - cat: 4 - font-style: underlined, Italic , BoLD #hi, hello - font-size: 14pt - font-family: Courier New, Times - -# linecomment -BOO - x: 3 - -editor-selection: - foreground: abcdef - background: abcdef - -editor-current-line: - background: ffffff - diff --git a/peg-highlight/styles/winlineseparator.style b/peg-highlight/styles/winlineseparator.style deleted file mode 100644 index adb421ae..00000000 --- a/peg-highlight/styles/winlineseparator.style +++ /dev/null @@ -1,33 +0,0 @@ -# linecomment - -editor # comment - foreground : 13ff13 - background : 000000 # comment - -# linecomment -STRONG: - -EMPH= - # comment - foreground: 00ff00 -comment asd - background: AB0000ff - -STRONG : - dog: 1 # something - cat: 4 - font-style: underlined, Italic , BoLD #hi, hello - font-size: 14pt - font-family: Courier New, Times - -# linecomment -BOO - x: 3 - -editor-selection: - foreground: abcdef - background: abcdef - -editor-current-line: - background: ffffff - diff --git a/peg-highlight/stylesheet_syntax.md b/peg-highlight/stylesheet_syntax.md deleted file mode 100644 index 687e91ed..00000000 --- a/peg-highlight/stylesheet_syntax.md +++ /dev/null @@ -1,199 +0,0 @@ - -The Syntax of PEG Markdown Highlight Stylesheets -================================================ - -[PEG Markdown Highlight][pmh] includes a parser for stylesheets that define how different Markdown language elements are to be highlighted. This document describes the syntax of these stylesheets. - -[pmh]: http://hasseg.org/peg-markdown-highlight/ - - -Example -------- - -Here is a quick, simple example of a stylesheet: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# The first comment lines
# describe the stylesheet.
 
Style rule →editor:
  foreground: ff0000 # red text← Comment
Attribute name →  font-family: Consolas← Attribute value
 
EMPH:
  font-size: 14
  font-style: bold, underlined
- - -Style Rules ------------ - -A stylesheet is composed of one or more *rules*. Rules are separated from each other by **empty lines** like so: - - H2: - foreground: ff0000 - - H3: - foreground: 00ff00 - -Each begins with the ***name* of the rule**, which is always on its own line, and may be one of the following: - -- **`editor`**: Styles that apply to the whole document/editor -- **`editor-current-line`**: Styles that apply to the current line in the editor (i.e. the line where the caret is) -- **`editor-selection`**: Styles that apply to the selected range in the editor when the user makes a selection in the text -- A Markdown element type (like `EMPH`, `REFERENCE` or `H1`): Styles that apply to occurrences of that particular element. The supported element types are: - - **`LINK`:** Explicit link (like `[click here][ref]`) - - **`AUTO_LINK_URL`:** Implicit URL link (like ``) - - **`AUTO_LINK_EMAIL`:** Implicit email link (like ``) - - **`IMAGE`:** Image definition - - **`REFERENCE`:** Reference (like `[id]: http://www.google.com`) - - **`CODE`:** Inline code - - **`EMPH`:** Emphasized text - - **`STRONG`:** Strong text - - **`LIST_BULLET`:** Bullet for an unordered list item - - **`LIST_ENUMERATOR`:** Enumerator for an ordered list item - - **`H1`:** Header, level 1 - - **`H2`:** Header, level 2 - - **`H3`:** Header, level 3 - - **`H4`:** Header, level 4 - - **`H5`:** Header, level 5 - - **`H6`:** Header, level 6 - - **`BLOCKQUOTE`:** Blockquote marker - - **`VERBATIM`:** Block of code - - **`HRULE`:** Horizontal rule - - **`HTML`:** HTML tag - - **`HTML_ENTITY`:** HTML special entity definition (like `…`) - - **`HTMLBLOCK`:** Block of HTML - - **`COMMENT`:** (HTML) Comment - - **`NOTE`:** Note - - **`STRIKE`:** Strike-through - -The name may be optionally followed by an assignment operator (either `:` or `=`): - - H1: - foreground: ff00ff - - H2 = - foreground: ff0000 - - H3 - foreground: 00ff00 - -The **order of style rules is significant**; it defines the order in which different language elements should be highlighted. *(Of course applications that use PEG Markdown Highlight and the style parser may disregard this and highlight elements in whatever order they desire.)* - -After the name of the rule, there can be one or more *attributes*. - - -Style Attributes ----------------- - -Attribute assignments are each on their own line, and they consist of the *name* of the attribute as well as the *value* assigned to it. An assignment operator (either `:` or `=`) separates the name from the value: - - attribute-name: value - attribute-name= value - -Attribute assignment lines **may be indented**. - -### Attribute Names and Types - -The following is a list of the names of predefined attributes, and the values they may be assigned: - -- `foreground-color` *(aliases: `foreground` and `color`)* - - See the *Color Attribute Values* subsection for information about valid values for this attribute. -- `background-color` *(alias: `background`)* - - See the *Color Attribute Values* subsection for information about valid values for this attribute. -- `caret-color` *(alias: `caret`)* - - See the *Color Attribute Values* subsection for information about valid values for this attribute. -- `strike-color` *(alias: `strike`)* - - See the *Color Attribute Values* subsection for information about valid values for this attribute. -- `font-size` - - An integer value for the font size, *in points* (i.e. not in pixels). The number may have a textual suffix such as `pt`. - - If the value begins with `+` or `-`, it is considered *relative* to some base font size (as defined by the host application). For example, the value `3` defines the font size as 3 (absolute) while `+3` defines it as +3 (relative), i.e. 3 point sizes larger than the base font size. -- `font-family` - - A comma-separated list of one or more arbitrary font family names. *(It is up to the application that uses the PEG Markdown Highlight library to resolve this string to actual fonts on the system.)* -- `font-style` - - A comma-separated list of one or more of the following: - - `italic` - - `bold` - - `underlined` - -Applications may also include support for any **custom attribute names and values** they desire — attributes other than the ones listed above will be included in the style parser results, with their values stored as strings. - - -## Color Attribute Values - -Colors can be specified either in **RGB** (red, green, blue) or **ARGB** (alpha, red, green, blue) formats. In both, each component is a two-character hexadecimal value (from `00` to `FF`): - - foreground: ff00ee # red = ff, green = 00, blue = ee (and implicitly, alpha = ff) - background: 99ff00ee # alpha = 99, red = ff, green = 00, blue = ee - - -Comments --------- - -Each line in a stylesheet may have a comment. The `#` character begins a line comment that continues until the end of the line: - - # this line has only this comment - H1: # this line has a style rule name and then a comment - foreground: ff0000 # this line has an attribute and then a comment - - - - - - - - - diff --git a/screenshots/_1513485266_1616037517.png b/screenshots/_1513485266_1616037517.png deleted file mode 100644 index 68a6a195..00000000 Binary files a/screenshots/_1513485266_1616037517.png and /dev/null differ diff --git a/screenshots/_inplacepre_1525155248_405615820.png b/screenshots/_inplacepre_1525155248_405615820.png deleted file mode 100644 index ea983ee7..00000000 Binary files a/screenshots/_inplacepre_1525155248_405615820.png and /dev/null differ diff --git a/screenshots/_universale_1522894821_465772669.png b/screenshots/_universale_1522894821_465772669.png deleted file mode 100644 index 301b141d..00000000 Binary files a/screenshots/_universale_1522894821_465772669.png and /dev/null differ diff --git a/screenshots/_vnotemaini_1525154456_1561295841.png b/screenshots/_vnotemaini_1525154456_1561295841.png deleted file mode 100644 index 8f3f961c..00000000 Binary files a/screenshots/_vnotemaini_1525154456_1561295841.png and /dev/null differ diff --git a/screenshots/alipay.png b/screenshots/alipay.png deleted file mode 100644 index 85ea76f0..00000000 Binary files a/screenshots/alipay.png and /dev/null differ diff --git a/screenshots/vnote.png b/screenshots/vnote.png deleted file mode 100644 index aef63b0e..00000000 Binary files a/screenshots/vnote.png and /dev/null differ diff --git a/screenshots/vnote_md.jpg b/screenshots/vnote_md.jpg deleted file mode 100644 index 0d3f601f..00000000 Binary files a/screenshots/vnote_md.jpg and /dev/null differ diff --git a/screenshots/vnote_qq.jpg b/screenshots/vnote_qq.jpg deleted file mode 100644 index 15d28e49..00000000 Binary files a/screenshots/vnote_qq.jpg and /dev/null differ diff --git a/screenshots/wechat_pay.png b/screenshots/wechat_pay.png deleted file mode 100644 index 12c600fb..00000000 Binary files a/screenshots/wechat_pay.png and /dev/null differ diff --git a/snapcraft.yaml b/snapcraft.yaml deleted file mode 100644 index 5dd52b86..00000000 --- a/snapcraft.yaml +++ /dev/null @@ -1,57 +0,0 @@ -name: vnote -version: "2.3" -summary: Markdown note-taking app -description: | - VNote is a note-taking application that - knows programmers and Markdown better. - It's designed to provide both powerful - note management and pleasant Markdown - experience. - -confinement: devmode - -apps: - vnote: - command: desktop-launch VNote - -parts: - vnote: - source: https://github.com/tamlok/vnote.git - plugin: qmake - qt-version: qt5 - options: - - CONFIG+=release - - CONFIG+=c++11 - - CONFIG+=c99 - - QMAKE_CXX=g++-6 - - QMAKE_CC=gcc-6 - - QMAKE_CFLAGS+=-std=c99 - - ./VNote.pro - build-packages: - - build-essential - - g++-6 - - gcc-6 - - qtbase5-dev - - libqt5svg5-dev - - libqt5webchannel5-dev - - qt5-default - - qtpositioning5-dev - - qtwebengine5-dev - - libxcb1-dev - - libxcb-xkb-dev - - libssl-dev - - libgl1-mesa-dev - stage-packages: - - libqt5gui5 - - libqt5core5a - - libqt5network5 - - libqt5printsupport5 - - libqt5webchannel5 - - libqt5webenginecore5 - - libqt5webenginewidgets5 - - libqt5widgets5 - - libqt5svg5 - - libxcb1 - - libxcb-xkb1 - - openssl - after: [desktop-qt5] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 7d343030..00000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,126 +0,0 @@ -add_executable(VNote MACOSX_BUNDLE main.cpp) - -file(GLOB SRC_FILES *.cpp) -file(GLOB DIALOG_SRCS dialog/*.cpp) -file(GLOB UTILS_SRCS utils/*.cpp) -file(GLOB WIDGETS_SRCS widgets/*.cpp) -file(GLOB QRC_FILES *.qrc) -file(GLOB TRANSLATIONS translations/*.qm) - -target_sources(VNote PRIVATE ${SRC_FILES}) -target_sources(VNote PRIVATE ${DIALOG_SRCS}) -target_sources(VNote PRIVATE ${UTILS_SRCS}) -target_sources(VNote PRIVATE ${WIDGETS_SRCS}) -target_sources(VNote PRIVATE ${QRC_FILES}) -if(WIN32) -target_sources(VNote PRIVATE resources/icon.rc) -endif(WIN32) - -include_directories(dialog utils widgets) - -# Remove the console of gui program -if(WIN32) - if(MSVC) - set_target_properties(VNote PROPERTIES - WIN32_EXECUTABLE YES - LINK_FLAGS "/ENTRY:mainCRTStartup" - ) - elseif(CMAKE_COMPILER_IS_GNUCXX) - # SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested - else() - message(SEND_ERROR "You are using an unsupported Windows compiler! (Not MSVC or GCC)") - endif(MSVC) -elseif(APPLE) - set_target_properties(VNote PROPERTIES - MACOSX_BUNDLE YES - ) -elseif(UNIX) - # Nothing special required -else() - message(SEND_ERROR "You are on an unsupported platform! (Not Win32, Mac OS X or Unix)") -endif(WIN32) - -# Qt5 libraries -target_link_libraries(VNote PRIVATE Qt5::Core Qt5::WebEngine Qt5::WebEngineWidgets - Qt5::Network Qt5::PrintSupport Qt5::WebChannel Qt5::Widgets - Qt5::PrintSupport Qt5::Svg) -set_property(TARGET VNote PROPERTY AUTORCC_OPTIONS "--compress;9") - -# Thirdparty libraries -target_include_directories(VNote PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/peg-highlight ${CMAKE_SOURCE_DIR}/hoedown) -target_link_libraries(VNote PRIVATE peg-highlight hoedown) - -# Compile options -if(GCC_VERSION VERSION_GREATER_EQUAL 8.0) - target_compile_options(VNote PRIVATE "-Wno-class-memaccess") -endif() - -if (WIN32 AND NOT UNIX) - # MSVC and not mingw32 - install(TARGETS VNote RUNTIME DESTINATION bin) - install(FILES ${TRANSLATIONS} DESTINATION translations ) -elseif (APPLE) - set_target_properties(VNote PROPERTIES MACOSX_PACKAGE_LOCATION "${PROJECT_NAME}.app/Contents") - if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "/Applications" CACHE PATH "Reset installation path to MacOS default." FORCE) - endif() - install(TARGETS VNote BUNDLE DESTINATION . COMPONENT Runtime - RUNTIME DESTINATION bin COMPONENT Runtime) - install(FILES ${TRANSLATIONS} DESTINATION translations COMPONENT Runtime) - set(MACOSX_BUNDLE_BUNDLE_NAME "VNote") - set(MACOSX_BUNDLE_BUNDLE_GUI_IDENTIFIER "com.tamlok.VNote") - set(MACOSX_BUNDLE_ICON_FILE ${CMAKE_SOURCE_DIR}/src/resources/icons/vnote.icns) - set(MACOSX_BUNDLE_BUNDLE_VERSION "VNOTE ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING ${MACOSX_BUNDLE_BUNDLE_VERSION}) - # Set short version independent with project version to be able to increment independendently. - math(EXPR SHORT_VERSION_MAJOR "${PROJECT_VERSION_MAJOR} * 100 + ${PROJECT_VERSION_MINOR}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${SHORT_VERSION_MAJOR}.${PROJECT_VERSION_PATCH}.0") - set(MACOSX_BUNDLE_EXECUTABLE_NAME "VNote") - set(MACOSX_BUNDLE_COPYRIGHT "Distributed under MIT license. Copyright 2016-2019 Le Tan") - set(MACOSX_BUNDLE_INFO_STRING "VNote is a note-taking application that knows programmers and Markdown better. Distributed under MIT license. Copyright 2017 Le Tan") - - set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") -else() - # Linux, mingw32 - if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "Reset installation path to MacOS default." FORCE) - endif() - install(TARGETS VNote RUNTIME DESTINATION bin) - install(FILES ${TRANSLATIONS} DESTINATION translations ) - - set(desktop.path applications) - set(desktop.files vnote.desktop) - - set(icon16.path icons/hicolor/16x16/apps) - set(icon16.files resources/icons/16x16/vnote.png) - - set(icon32.path icons/hicolor/32x32/apps) - set(icon32.files resources/icons/32x32/vnote.png) - - set(icon48.path icons/hicolor/48x48/apps) - set(icon48.files resources/icons/48x48/vnote.png) - - set(icon64.path icons/hicolor/64x64/apps) - set(icon64.files resources/icons/64x64/vnote.png) - - set(icon128.path icons/hicolor/128x128/apps) - set(icon128.files resources/icons/128x128/vnote.png) - - set(icon256.path icons/hicolor/256x256/apps) - set(icon256.files resources/icons/256x256/vnote.png) - - set(iconsvg.path icons/hicolor/scalable/apps) - set(iconsvg.files resources/icons/vnote.svg) - - foreach(items IN ITEMS desktop icon16 icon32 icon48 icon64 icon128 icon256 iconsvg) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${${items}.files} - DESTINATION share/${${items}.path} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ) - endforeach() - install(FILES ${CMAKE_SOURCE_DIR}/LICENSE - DESTINATION share/doc/vnote/ - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ - RENAME copyright) -endif() - diff --git a/src/dialog/vconfirmdeletiondialog.cpp b/src/dialog/vconfirmdeletiondialog.cpp deleted file mode 100644 index e4181bdf..00000000 --- a/src/dialog/vconfirmdeletiondialog.cpp +++ /dev/null @@ -1,248 +0,0 @@ -#include "vconfirmdeletiondialog.h" - -#include - -#include "utils/vutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -ConfirmItemWidget::ConfirmItemWidget(bool p_checked, - const QString &p_file, - const QString &p_tip, - int p_index, - QWidget *p_parent) - : QWidget(p_parent), m_index(p_index) -{ - setupUI(); - - m_checkBox->setChecked(p_checked); - m_fileLabel->setText(p_file); - if (!p_tip.isEmpty()) { - m_fileLabel->setToolTip(p_tip); - } -} - -void ConfirmItemWidget::setupUI() -{ - m_checkBox = new QCheckBox; - connect(m_checkBox, &QCheckBox::stateChanged, - this, &ConfirmItemWidget::checkStateChanged); - - m_fileLabel = new QLabel; - QHBoxLayout *mainLayout = new QHBoxLayout; - mainLayout->addWidget(m_checkBox); - mainLayout->addWidget(m_fileLabel); - mainLayout->addStretch(); - mainLayout->setContentsMargins(3, 0, 0, 0); - - setLayout(mainLayout); -} - -bool ConfirmItemWidget::isChecked() const -{ - return m_checkBox->isChecked(); -} - -int ConfirmItemWidget::getIndex() const -{ - return m_index; -} - -VConfirmDeletionDialog::VConfirmDeletionDialog(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QVector &p_items, - bool p_enableAskAgain, - bool p_askAgainEnabled, - bool p_enablePreview, - QWidget *p_parent) - : QDialog(p_parent), - m_enableAskAgain(p_enableAskAgain), - m_askAgainEnabled(p_askAgainEnabled), - m_enablePreview(p_enablePreview), - m_items(p_items) -{ - setupUI(p_title, p_text, p_info); - - initItems(); - - updateCountLabel(); -} - -void VConfirmDeletionDialog::setupUI(const QString &p_title, - const QString &p_text, - const QString &p_info) -{ - QLabel *textLabel = NULL; - if (!p_text.isEmpty()) { - textLabel = new QLabel(p_text); - textLabel->setWordWrap(true); - } - - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - m_countLabel = new QLabel("Items"); - QHBoxLayout *labelLayout = new QHBoxLayout; - labelLayout->addWidget(m_countLabel); - labelLayout->addStretch(); - labelLayout->setContentsMargins(0, 0, 0, 0); - - m_listWidget = new QListWidget(); - m_listWidget->setAttribute(Qt::WA_MacShowFocusRect, false); - connect(m_listWidget, &QListWidget::currentRowChanged, - this, &VConfirmDeletionDialog::currentFileChanged); - connect(m_listWidget, &QListWidget::itemActivated, - this, [this](QListWidgetItem *p_item) { - // Open it using resource manager. - if (!p_item) { - return; - } - - ConfirmItemWidget *widget = getItemWidget(p_item); - Q_ASSERT(widget); - QString filePath = m_items[widget->getIndex()].m_path; - - if (!filePath.isEmpty()) { - QUrl url = QUrl::fromLocalFile(filePath); - QDesktopServices::openUrl(url); - } - }); - - m_previewer = new QLabel(); - - m_askAgainCB = new QCheckBox(tr("Do not ask for confirmation again")); - m_askAgainCB->setChecked(!m_askAgainEnabled); - m_askAgainCB->setVisible(m_enableAskAgain); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("DangerBtn", true); - - QHBoxLayout *midLayout = new QHBoxLayout; - midLayout->addWidget(m_listWidget); - if (m_enablePreview) { - midLayout->addStretch(); - midLayout->addWidget(m_previewer); - midLayout->addStretch(); - } else { - midLayout->addWidget(m_previewer); - m_previewer->setVisible(false); - } - - QVBoxLayout *mainLayout = new QVBoxLayout; - if (textLabel) { - mainLayout->addWidget(textLabel); - } - - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addWidget(m_askAgainCB); - mainLayout->addWidget(m_btnBox); - mainLayout->addLayout(labelLayout); - mainLayout->addLayout(midLayout); - - setLayout(mainLayout); - setWindowTitle(p_title); -} - -QVector VConfirmDeletionDialog::getConfirmedItems() const -{ - QVector confirmedItems; - - for (int i = 0; i < m_listWidget->count(); ++i) { - ConfirmItemWidget *widget = getItemWidget(m_listWidget->item(i)); - if (widget->isChecked()) { - confirmedItems.push_back(m_items[widget->getIndex()]); - } - } - - return confirmedItems; -} - -void VConfirmDeletionDialog::initItems() -{ - m_listWidget->clear(); - - for (int i = 0; i < m_items.size(); ++i) { - ConfirmItemWidget *itemWidget = new ConfirmItemWidget(true, - m_items[i].m_name, - m_items[i].m_tip, - i, - this); - connect(itemWidget, &ConfirmItemWidget::checkStateChanged, - this, &VConfirmDeletionDialog::updateCountLabel); - - QListWidgetItem *item = new QListWidgetItem(); - QSize size = itemWidget->sizeHint(); - size.setHeight(size.height() * 2); - item->setSizeHint(size); - - m_listWidget->addItem(item); - m_listWidget->setItemWidget(item, itemWidget); - } - - m_listWidget->setMinimumSize(m_listWidget->sizeHint()); - m_listWidget->setCurrentRow(-1); - m_listWidget->setCurrentRow(0); -} - -bool VConfirmDeletionDialog::getAskAgainEnabled() const -{ - return !m_askAgainCB->isChecked(); -} - -void VConfirmDeletionDialog::currentFileChanged(int p_row) -{ - bool succeed = false; - if (p_row > -1 && m_enablePreview) { - ConfirmItemWidget *widget = getItemWidget(m_listWidget->item(p_row)); - if (widget) { - int idx = widget->getIndex(); - Q_ASSERT(idx < m_items.size()); - QPixmap image(m_items[idx].m_path); - if (!image.isNull()) { - int width = 512 * VUtils::calculateScaleFactor(); - QSize previewSize(width, width); - if (image.width() > width || image.height() > width) { - m_previewer->setPixmap(image.scaled(previewSize, Qt::KeepAspectRatio)); - } else { - m_previewer->setPixmap(image); - } - - succeed = true; - } - } - } - - m_previewer->setVisible(succeed); -} - -ConfirmItemWidget *VConfirmDeletionDialog::getItemWidget(QListWidgetItem *p_item) const -{ - QWidget *wid = m_listWidget->itemWidget(p_item); - return dynamic_cast(wid); -} - -void VConfirmDeletionDialog::updateCountLabel() -{ - int total = m_listWidget->count(); - int checked = 0; - - for (int i = 0; i < total; ++i) { - ConfirmItemWidget *widget = getItemWidget(m_listWidget->item(i)); - if (widget->isChecked()) { - ++checked; - } - } - - m_countLabel->setText(tr("%1/%2 Items").arg(checked).arg(total)); -} diff --git a/src/dialog/vconfirmdeletiondialog.h b/src/dialog/vconfirmdeletiondialog.h deleted file mode 100644 index d67d74b4..00000000 --- a/src/dialog/vconfirmdeletiondialog.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef VCONFIRMDELETIONDIALOG_H -#define VCONFIRMDELETIONDIALOG_H - -#include -#include - -class QLabel; -class QPushButton; -class QDialogButtonBox; -class QListWidget; -class QListWidgetItem; -class ConfirmItemWidget; -class QCheckBox; - -// Information about a deletion item needed to confirm. -struct ConfirmItemInfo -{ - ConfirmItemInfo() - : m_data(NULL) - { - } - - ConfirmItemInfo(const QString &p_name, - const QString &p_tip, - const QString &p_path, - void *p_data) - : m_name(p_name), m_tip(p_tip), m_path(p_path), m_data(p_data) - { - } - - QString m_name; - QString m_tip; - QString m_path; - void *m_data; -}; - -class ConfirmItemWidget : public QWidget -{ - Q_OBJECT -public: - ConfirmItemWidget(bool p_checked, - const QString &p_file, - const QString &p_tip, - int p_index, - QWidget *p_parent = NULL); - - bool isChecked() const; - - int getIndex() const; - -signals: - // Emit when item's check state changed. - void checkStateChanged(int p_state); - -private: - void setupUI(); - - QCheckBox *m_checkBox; - QLabel *m_fileLabel; - - int m_index; -}; - -class VConfirmDeletionDialog : public QDialog -{ - Q_OBJECT -public: - VConfirmDeletionDialog(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QVector &p_items, - bool p_enableAskAgain, - bool p_askAgainEnabled, - bool p_enablePreview, - QWidget *p_parent = 0); - - QVector getConfirmedItems() const; - - bool getAskAgainEnabled() const; - -private slots: - void currentFileChanged(int p_row); - - void updateCountLabel(); - -private: - void setupUI(const QString &p_title, - const QString &p_text, - const QString &p_info); - - void initItems(); - - ConfirmItemWidget *getItemWidget(QListWidgetItem *p_item) const; - - QLabel *m_countLabel; - QListWidget *m_listWidget; - QLabel *m_previewer; - QDialogButtonBox *m_btnBox; - QCheckBox *m_askAgainCB; - - bool m_enableAskAgain; - // Init value if m_enableAskAgain is true. - bool m_askAgainEnabled; - - bool m_enablePreview; - - QVector m_items; -}; - -#endif // VCONFIRMDELETIONDIALOG_H diff --git a/src/dialog/vcopytextashtmldialog.cpp b/src/dialog/vcopytextashtmldialog.cpp deleted file mode 100644 index a4fd62bc..00000000 --- a/src/dialog/vcopytextashtmldialog.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "vcopytextashtmldialog.h" - -#include -#include -#include -#include -#include - -#include "utils/vutils.h" -#include "utils/vclipboardutils.h" -#include "utils/vwebutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -extern VWebUtils *g_webUtils; - -VCopyTextAsHtmlDialog::VCopyTextAsHtmlDialog(const QString &p_text, - const QString &p_copyTarget, - QWidget *p_parent) - : QDialog(p_parent), m_text(p_text), m_copyTarget(p_copyTarget) -{ - setupUI(); -} - -void VCopyTextAsHtmlDialog::setupUI() -{ - QLabel *textLabel = new QLabel(tr("Text:")); - m_textEdit = new QPlainTextEdit(m_text); - m_textEdit->setReadOnly(true); - m_textEdit->setProperty("LineEdit", true); - - m_htmlLabel = new QLabel(tr("HTML:")); - m_htmlViewer = VUtils::getWebEngineView(g_config->getBaseBackground()); - m_htmlViewer->setContextMenuPolicy(Qt::NoContextMenu); - m_htmlViewer->setMinimumSize(600, 400); - - m_infoLabel = new QLabel(tr("Converting text to HTML ...")); - - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(textLabel); - mainLayout->addWidget(m_textEdit); - mainLayout->addWidget(m_htmlLabel); - mainLayout->addWidget(m_htmlViewer); - mainLayout->addWidget(m_infoLabel); - mainLayout->addStretch(); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - setWindowTitle(tr("Copy Text As HTML (%1)").arg(m_copyTarget)); - - setHtmlVisible(false); -} - -void VCopyTextAsHtmlDialog::setHtmlVisible(bool p_visible) -{ - m_htmlLabel->setVisible(p_visible); - m_htmlViewer->setVisible(p_visible); -} - -void VCopyTextAsHtmlDialog::setConvertedHtml(const QUrl &p_baseUrl, - const QString &p_html) -{ - QString html = p_html; - m_htmlViewer->setHtml("" + html + "", p_baseUrl); - setHtmlVisible(true); - - g_webUtils->alterHtmlAsTarget(p_baseUrl, html, m_copyTarget); - - QClipboard *clipboard = QApplication::clipboard(); - QMimeData *data = new QMimeData(); - data->setText(m_text); - data->setHtml(html); - VClipboardUtils::setMimeDataToClipboard(clipboard, data, QClipboard::Clipboard); - - QTimer::singleShot(3000, this, &VCopyTextAsHtmlDialog::accept); - m_infoLabel->setText(tr("HTML has been copied. Will be closed in 3 seconds.")); -} diff --git a/src/dialog/vcopytextashtmldialog.h b/src/dialog/vcopytextashtmldialog.h deleted file mode 100644 index a4bad341..00000000 --- a/src/dialog/vcopytextashtmldialog.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef VCOPYTEXTASHTMLDIALOG_H -#define VCOPYTEXTASHTMLDIALOG_H - -#include -#include - - -class QPlainTextEdit; -class QWebEngineView; -class QDialogButtonBox; -class VWaitingWidget; -class QLabel; - -class VCopyTextAsHtmlDialog : public QDialog -{ - Q_OBJECT -public: - VCopyTextAsHtmlDialog(const QString &p_text, - const QString &p_copyTarget, - QWidget *p_parent = nullptr); - - void setConvertedHtml(const QUrl &p_baseUrl, const QString &p_html); - - const QString &getText() const; - -private: - void setupUI(); - - void setHtmlVisible(bool p_visible); - - QPlainTextEdit *m_textEdit; - - QLabel *m_htmlLabel; - - QWebEngineView *m_htmlViewer; - - QLabel *m_infoLabel; - - QDialogButtonBox *m_btnBox; - - QString m_text; - - QString m_copyTarget; -}; - -inline const QString &VCopyTextAsHtmlDialog::getText() const -{ - return m_text; -} -#endif // VCOPYTEXTASHTMLDIALOG_H diff --git a/src/dialog/vdeletenotebookdialog.cpp b/src/dialog/vdeletenotebookdialog.cpp deleted file mode 100644 index ffab9fce..00000000 --- a/src/dialog/vdeletenotebookdialog.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include "vdeletenotebookdialog.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VDeleteNotebookDialog::VDeleteNotebookDialog(const QString &p_title, - const VNotebook *p_notebook, - QWidget *p_parent) - : QDialog(p_parent), m_notebook(p_notebook) -{ - setupUI(p_title, m_notebook->getName()); -} - -void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_name) -{ - QLabel *infoLabel = new QLabel(tr("Are you sure to delete notebook %2?") - .arg(g_config->c_dataTextStyle).arg(p_name)); - m_warningLabel = new QLabel(); - m_warningLabel->setWordWrap(true); - - m_deleteCheck = new QCheckBox(tr("Delete files from disk"), this); - m_deleteCheck->setChecked(false); - m_deleteCheck->setToolTip(tr("When checked, VNote will delete all files (including Recycle Bin) of this notebook from disk")); - connect(m_deleteCheck, &QCheckBox::stateChanged, - this, &VDeleteNotebookDialog::deleteCheckChanged); - - deleteCheckChanged(false); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("DangerBtn", true); - - // Standard Warning icon. - QLabel *iconLabel = new QLabel(); - QPixmap pixmap = standardIcon(QMessageBox::Warning); - if (pixmap.isNull()) { - iconLabel->hide(); - } else { - iconLabel->setPixmap(pixmap); - } - - QVBoxLayout *iconLayout = new QVBoxLayout(); - iconLayout->addStretch(); - iconLayout->addWidget(iconLabel); - iconLayout->addStretch(); - - QVBoxLayout *infoLayout = new QVBoxLayout(); - infoLayout->addWidget(infoLabel); - infoLayout->addWidget(m_deleteCheck); - infoLayout->addWidget(m_warningLabel); - - QHBoxLayout *topLayout = new QHBoxLayout(); - topLayout->addLayout(iconLayout); - topLayout->addLayout(infoLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(p_title); -} - -bool VDeleteNotebookDialog::getDeleteFiles() const -{ - return m_deleteCheck->isChecked(); -} - -QPixmap VDeleteNotebookDialog::standardIcon(QMessageBox::Icon p_icon) -{ - QStyle *style = this->style(); - int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this); - QIcon tmpIcon; - switch (p_icon) { - case QMessageBox::Information: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation, 0, this); - break; - case QMessageBox::Warning: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning, 0, this); - break; - case QMessageBox::Critical: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical, 0, this); - break; - case QMessageBox::Question: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion, 0, this); - break; - default: - break; - } - - if (!tmpIcon.isNull()) { - QWindow *window = this->windowHandle(); - if (!window) { - if (const QWidget *nativeParent = this->nativeParentWidget()) { - window = nativeParent->windowHandle(); - } - } - return tmpIcon.pixmap(window, QSize(iconSize, iconSize)); - } - return QPixmap(); -} - -void VDeleteNotebookDialog::deleteCheckChanged(int p_state) -{ - if (!p_state) { - m_warningLabel->setText(tr("VNote won't delete files in directory %2.") - .arg(g_config->c_dataTextStyle).arg(m_notebook->getPath())); - } else { - m_warningLabel->setText(tr("WARNING: " - "VNote may delete ANY files in directory %3 " - "and directory %4!
" - "VNote will try to delete all the root folders within this notebook one by one.
" - "It may be UNRECOVERABLE!") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getPath()) - .arg(m_notebook->getRecycleBinFolderPath())); - } -} diff --git a/src/dialog/vdeletenotebookdialog.h b/src/dialog/vdeletenotebookdialog.h deleted file mode 100644 index 0f6f949e..00000000 --- a/src/dialog/vdeletenotebookdialog.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef VDELETENOTEBOOKDIALOG_H -#define VDELETENOTEBOOKDIALOG_H - -#include -#include - -class QLabel; -class QString; -class QCheckBox; -class QDialogButtonBox; -class VNotebook; - -class VDeleteNotebookDialog : public QDialog -{ - Q_OBJECT -public: - VDeleteNotebookDialog(const QString &p_title, - const VNotebook *p_notebook, - QWidget *p_parent = 0); - - // Whether delete files from disk. - bool getDeleteFiles() const; - -private slots: - void deleteCheckChanged(int p_state); - -private: - void setupUI(const QString &p_title, const QString &p_name); - QPixmap standardIcon(QMessageBox::Icon p_icon); - - const VNotebook *m_notebook; - QLabel *m_warningLabel; - QCheckBox *m_deleteCheck; - QDialogButtonBox *m_btnBox; -}; - -#endif // VDELETENOTEBOOKDIALOG_H diff --git a/src/dialog/vdirinfodialog.cpp b/src/dialog/vdirinfodialog.cpp deleted file mode 100644 index c423bc01..00000000 --- a/src/dialog/vdirinfodialog.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include "vdirinfodialog.h" -#include "vdirectory.h" -#include "vconfigmanager.h" -#include "vmetawordlineedit.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VDirInfoDialog::VDirInfoDialog(const QString &title, - const QString &info, - const VDirectory *directory, - VDirectory *parentDirectory, - QWidget *parent) - : QDialog(parent), title(title), info(info), - m_directory(directory), m_parentDirectory(parentDirectory) -{ - setupUI(); - - connect(m_nameEdit, &VMetaWordLineEdit::textChanged, this, &VDirInfoDialog::handleInputChanged); - - handleInputChanged(); -} - -void VDirInfoDialog::setupUI() -{ - QLabel *infoLabel = NULL; - if (!info.isEmpty()) { - infoLabel = new QLabel(info); - } - - m_nameEdit = new VMetaWordLineEdit(m_directory->getName()); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - m_nameEdit->selectAll(); - - // Created time. - QString createdTimeStr = VUtils::displayDateTime(m_directory->getCreatedTimeUtc().toLocalTime()); - QLabel *createdTimeLabel = new QLabel(createdTimeStr); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Folder &name:"), m_nameEdit); - topLayout->addRow(tr("Created time:"), createdTimeLabel); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - - setWindowTitle(title); -} - -void VDirInfoDialog::handleInputChanged() -{ - bool showWarnLabel = false; - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk && name != m_directory->getName()) { - // Check if the name conflicts with existing directory name. - // Case-insensitive when creating note. - const VDirectory *directory = m_parentDirectory->findSubDirectory(name, false); - QString warnText; - if (directory && directory != m_directory) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); -} - -QString VDirInfoDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} diff --git a/src/dialog/vdirinfodialog.h b/src/dialog/vdirinfodialog.h deleted file mode 100644 index b20529ee..00000000 --- a/src/dialog/vdirinfodialog.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef VDIRINFODIALOG_H -#define VDIRINFODIALOG_H - -#include - -class QLabel; -class VMetaWordLineEdit; -class QDialogButtonBox; -class QString; -class VDirectory; - -class VDirInfoDialog : public QDialog -{ - Q_OBJECT -public: - VDirInfoDialog(const QString &title, - const QString &info, - const VDirectory *directory, - VDirectory *parentDirectory, - QWidget *parent = 0); - - QString getNameInput() const; - -private slots: - void handleInputChanged(); - -private: - void setupUI(); - - VMetaWordLineEdit *m_nameEdit; - QLabel *m_warnLabel; - QDialogButtonBox *m_btnBox; - - QString title; - QString info; - - const VDirectory *m_directory; - VDirectory *m_parentDirectory; -}; -#endif // VDIRINFODIALOG_H diff --git a/src/dialog/veditsnippetdialog.cpp b/src/dialog/veditsnippetdialog.cpp deleted file mode 100644 index fcdc5563..00000000 --- a/src/dialog/veditsnippetdialog.cpp +++ /dev/null @@ -1,310 +0,0 @@ -#include "veditsnippetdialog.h" -#include - -#include "utils/vutils.h" -#include "vmetawordlineedit.h" -#include "vconfigmanager.h" -#include "utils/vmetawordmanager.h" -#include "vlineedit.h" - -extern VMetaWordManager *g_mwMgr; - -extern VConfigManager *g_config; - -VEditSnippetDialog::VEditSnippetDialog(const QString &p_title, - const QString &p_info, - const QVector &p_snippets, - const VSnippet &p_snippet, - QWidget *p_parent) - : QDialog(p_parent), - m_snippets(p_snippets), - m_snippet(p_snippet) -{ - setupUI(p_title, p_info); - - handleInputChanged(); -} - -void VEditSnippetDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - // Name. - m_nameEdit = new VMetaWordLineEdit(m_snippet.getName()); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - - // Type. - m_typeCB = VUtils::getComboBox(); - for (int i = 0; i < VSnippet::Type::Invalid; ++i) { - m_typeCB->addItem(VSnippet::typeStr(static_cast(i)), i); - } - - int typeIdx = m_typeCB->findData((int)m_snippet.getType()); - Q_ASSERT(typeIdx > -1); - m_typeCB->setCurrentIndex(typeIdx); - - // Shortcut. - m_shortcutCB = VUtils::getComboBox(); - m_shortcutCB->addItem(tr("None"), QChar()); - auto shortcuts = getAvailableShortcuts(); - for (auto it : shortcuts) { - m_shortcutCB->addItem(it, it); - } - - QChar sh = m_snippet.getShortcut(); - if (sh.isNull()) { - m_shortcutCB->setCurrentIndex(0); - } else { - int shortcutIdx = m_shortcutCB->findData(sh); - m_shortcutCB->setCurrentIndex(shortcutIdx < 0 ? 0 : shortcutIdx); - } - - // Cursor mark. - m_cursorMarkEdit = new VLineEdit(m_snippet.getCursorMark()); - m_cursorMarkEdit->setToolTip(tr("String in the content to mark the cursor position")); - - // Selection mark. - m_selectionMarkEdit = new VLineEdit(m_snippet.getSelectionMark()); - m_selectionMarkEdit->setToolTip(tr("String in the content to be replaced with selected text")); - - // Auto Indent. - m_autoIndentCB = new QCheckBox(tr("Auto indent"), this); - m_autoIndentCB->setToolTip(tr("Auto indent the content according to the first line")); - m_autoIndentCB->setChecked(m_snippet.getAutoIndent()); - - // Content. - m_contentEdit = new QTextEdit(); - m_contentEdit->setProperty("LineEdit", true); - setContentEditByType(); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Snippet &name:"), m_nameEdit); - topLayout->addRow(tr("Snippet &type:"), m_typeCB); - topLayout->addRow(tr("Shortc&ut:"), m_shortcutCB); - topLayout->addRow(tr("Cursor &mark:"), m_cursorMarkEdit); - topLayout->addRow(tr("&Selection mark:"), m_selectionMarkEdit); - topLayout->addWidget(m_autoIndentCB); - topLayout->addRow(tr("&Content:"), m_contentEdit); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - - setWindowTitle(p_title); - - connect(m_nameEdit, &VMetaWordLineEdit::textChanged, - this, &VEditSnippetDialog::handleInputChanged); - - connect(m_typeCB, static_cast(&QComboBox::currentIndexChanged), - this, &VEditSnippetDialog::handleInputChanged); - - connect(m_cursorMarkEdit, &VLineEdit::textChanged, - this, &VEditSnippetDialog::handleInputChanged); - - connect(m_selectionMarkEdit, &VLineEdit::textChanged, - this, &VEditSnippetDialog::handleInputChanged); - - connect(m_contentEdit, &QTextEdit::textChanged, - this, &VEditSnippetDialog::handleInputChanged); -} - -void VEditSnippetDialog::handleInputChanged() -{ - bool showWarnLabel = false; - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk && name != m_snippet.getName()) { - // Check if the name conflicts with existing snippet name. - // Case-insensitive. - QString lowerName = name.toLower(); - bool conflicted = false; - for (auto const & item : m_snippets) { - if (item.getName() == name) { - conflicted = true; - break; - } - } - - QString warnText; - if (conflicted) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - QString cursorMark = m_cursorMarkEdit->text(); - bool cursorMarkOk = true; - if (nameOk && !cursorMark.isEmpty()) { - // Check if the mark appears more than once in the content. - QString selectionMark = m_selectionMarkEdit->text(); - QString content = getContentEditByType(); - content = g_mwMgr->evaluate(content); - QString warnText; - if (content.count(cursorMark) > 1) { - cursorMarkOk = false; - warnText = tr("WARNING: " - "Cursor mark %3 occurs more than once " - "in the content (after magic word evaluation). " - "Please choose another mark.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(cursorMark); - } else if ((cursorMark == selectionMark - || cursorMark.contains(selectionMark) - || selectionMark.contains(cursorMark)) - && !selectionMark.isEmpty()) { - cursorMarkOk = false; - warnText = tr("WARNING: " - "Cursor mark %3 conflicts with selection mark. " - "Please choose another mark.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(cursorMark); - } - - if (!cursorMarkOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk && cursorMarkOk); -} - -void VEditSnippetDialog::setContentEditByType() -{ - switch (m_snippet.getType()) { - case VSnippet::Type::PlainText: - m_contentEdit->setPlainText(m_snippet.getContent()); - break; - - case VSnippet::Type::Html: - m_contentEdit->setHtml(m_snippet.getContent()); - break; - - default: - m_contentEdit->setPlainText(m_snippet.getContent()); - break; - } -} - -QString VEditSnippetDialog::getContentEditByType() const -{ - if (m_typeCB->currentIndex() == -1) { - return QString(); - } - - switch (static_cast(m_typeCB->currentData().toInt())) { - case VSnippet::Type::PlainText: - return m_contentEdit->toPlainText(); - - case VSnippet::Type::Html: - return m_contentEdit->toHtml(); - - default: - return m_contentEdit->toPlainText(); - } -} - -QString VEditSnippetDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} - -VSnippet::Type VEditSnippetDialog::getTypeInput() const -{ - return static_cast(m_typeCB->currentData().toInt()); -} - -QString VEditSnippetDialog::getCursorMarkInput() const -{ - return m_cursorMarkEdit->text(); -} - -QString VEditSnippetDialog::getSelectionMarkInput() const -{ - return m_selectionMarkEdit->text(); -} - -QString VEditSnippetDialog::getContentInput() const -{ - return getContentEditByType(); -} - -QChar VEditSnippetDialog::getShortcutInput() const -{ - return m_shortcutCB->currentData().toChar(); -} - -bool VEditSnippetDialog::getAutoIndentInput() const -{ - return m_autoIndentCB->isChecked(); -} - -QVector VEditSnippetDialog::getAvailableShortcuts() const -{ - QVector ret = VSnippet::getAllShortcuts(); - - QChar curCh = m_snippet.getShortcut(); - // Remove those have already been assigned to snippets. - for (auto const & snip : m_snippets) { - QChar ch = snip.getShortcut(); - if (ch.isNull()) { - continue; - } - - if (ch != curCh) { - ret.removeOne(ch); - } - } - - return ret; -} diff --git a/src/dialog/veditsnippetdialog.h b/src/dialog/veditsnippetdialog.h deleted file mode 100644 index 8f3c0cd4..00000000 --- a/src/dialog/veditsnippetdialog.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef VEDITSNIPPETDIALOG_H -#define VEDITSNIPPETDIALOG_H - -#include -#include - -#include "vsnippet.h" - -class VMetaWordLineEdit; -class VLineEdit; -class QLabel; -class QDialogButtonBox; -class QComboBox; -class QTextEdit; -class QCheckBox; - - -class VEditSnippetDialog : public QDialog -{ - Q_OBJECT -public: - VEditSnippetDialog(const QString &p_title, - const QString &p_info, - const QVector &p_snippets, - const VSnippet &p_snippet, - QWidget *p_parent = nullptr); - - QString getNameInput() const; - - VSnippet::Type getTypeInput() const; - - QString getCursorMarkInput() const; - - QString getSelectionMarkInput() const; - - QString getContentInput() const; - - QChar getShortcutInput() const; - - bool getAutoIndentInput() const; - -private slots: - void handleInputChanged(); - -private: - void setupUI(const QString &p_title, const QString &p_info); - - void setContentEditByType(); - - QString getContentEditByType() const; - - QVector getAvailableShortcuts() const; - - VMetaWordLineEdit *m_nameEdit; - QComboBox *m_typeCB; - QComboBox *m_shortcutCB; - VLineEdit *m_cursorMarkEdit; - VLineEdit *m_selectionMarkEdit; - QCheckBox *m_autoIndentCB; - QTextEdit *m_contentEdit; - - QLabel *m_warnLabel; - QDialogButtonBox *m_btnBox; - - const QVector &m_snippets; - - const VSnippet &m_snippet; -}; - -#endif // VEDITSNIPPETDIALOG_H diff --git a/src/dialog/vexportdialog.cpp b/src/dialog/vexportdialog.cpp deleted file mode 100644 index 9c782fd7..00000000 --- a/src/dialog/vexportdialog.cpp +++ /dev/null @@ -1,1500 +0,0 @@ -#include "vexportdialog.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifndef QT_NO_PRINTER -#include -#include -#endif - -#include "utils/vutils.h" -#include "utils/vclipboardutils.h" -#include "vlineedit.h" -#include "vnotebook.h" -#include "vfile.h" -#include "vdirectory.h" -#include "vcart.h" -#include "vconfigmanager.h" -#include "vnotefile.h" -#include "vnote.h" -#include "vexporter.h" -#include "vlineedit.h" -#include "utils/vprocessutils.h" - -extern VConfigManager *g_config; - -extern VNote *g_vnote; - -QString VExportDialog::s_lastOutputFolder; - -ExportOption VExportDialog::s_opt; - -#define LOGERR(x) do { QString msg = (x); \ - VUtils::addErrMsg(p_errMsg, msg); \ - appendLogLine(msg); \ - } while (0) - -VExportDialog::VExportDialog(VNotebook *p_notebook, - VDirectory *p_directory, - VFile *p_file, - VCart *p_cart, - MarkdownConverterType p_renderer, - QWidget *p_parent) - : QDialog(p_parent), - m_notebook(p_notebook), - m_directory(p_directory), - m_file(p_file), - m_cart(p_cart), - m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), - QPageLayout::Portrait, - QMarginsF(10, 16, 10, 10), - QPageLayout::Millimeter)), - m_inExport(false), - m_askedToStop(false) -{ - if (s_lastOutputFolder.isEmpty()) { - s_lastOutputFolder = g_config->getExportFolderPath(); - } - - setupUI(); - - m_exporter = new VExporter(this); - connect(m_exporter, &VExporter::outputLog, - this, [this](const QString &p_log) { - appendLogLine(p_log); - }); - - initUIFields(p_renderer); - - handleInputChanged(); -} - -void VExportDialog::setupUI() -{ - // Notes to export. - m_srcCB = VUtils::getComboBox(); - m_srcCB->setToolTip(tr("Choose notes to export")); - m_srcCB->setSizeAdjustPolicy(QComboBox::AdjustToContents); - connect(m_srcCB, SIGNAL(currentIndexChanged(int)), - this, SLOT(handleCurrentSrcChanged(int))); - - // Target format. - m_formatCB = VUtils::getComboBox(); - m_formatCB->setToolTip(tr("Choose target format to export as")); - m_formatCB->setSizeAdjustPolicy(QComboBox::AdjustToContents); - connect(m_formatCB, SIGNAL(currentIndexChanged(int)), - this, SLOT(handleCurrentFormatChanged(int))); - - // Markdown renderer. - m_rendererCB = VUtils::getComboBox(); - m_rendererCB->setToolTip(tr("Choose converter to render Markdown")); - m_rendererCB->setSizeAdjustPolicy(QComboBox::AdjustToContents); - - // Markdown rendering background. - m_renderBgCB = VUtils::getComboBox(); - m_renderBgCB->setToolTip(tr("Choose rendering background color for Markdown")); - - // Markdown rendering style. - m_renderStyleCB = VUtils::getComboBox(); - m_renderStyleCB->setToolTip(tr("Choose rendering style for Markdown")); - - // Markdown rendering code block style. - m_renderCodeBlockStyleCB = VUtils::getComboBox(); - m_renderCodeBlockStyleCB->setToolTip(tr("Choose rendering code block style for Markdown")); - - // Output directory. - m_outputEdit = new VLineEdit(s_lastOutputFolder); - connect(m_outputEdit, &QLineEdit::textChanged, - this, &VExportDialog::handleInputChanged); - QPushButton *browseBtn = new QPushButton(tr("&Browse")); - connect(browseBtn, &QPushButton::clicked, - this, &VExportDialog::handleOutputBrowseBtnClicked); - QHBoxLayout *outputLayout = new QHBoxLayout(); - outputLayout->addWidget(m_outputEdit); - outputLayout->addWidget(browseBtn); - - m_basicBox = new QGroupBox(tr("Information")); - - m_settingBox = new QGroupBox(tr("Advanced Settings")); - - m_consoleEdit = new QPlainTextEdit(); - m_consoleEdit->setReadOnly(true); - m_consoleEdit->setLineWrapMode(QPlainTextEdit::WidgetWidth); - m_consoleEdit->setProperty("LineEdit", true); - m_consoleEdit->setPlaceholderText(tr("Output logs will be shown here")); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Close); - m_exportBtn = m_btnBox->addButton(tr("Export"), QDialogButtonBox::ActionRole); - m_openBtn = m_btnBox->addButton(tr("Open Directory"), QDialogButtonBox::ActionRole); - m_openBtn->setToolTip(tr("Open output directory")); - m_copyBtn = m_btnBox->addButton(tr("Copy Content"), QDialogButtonBox::ActionRole); - m_copyBtn->setToolTip(tr("Copy the content of the exported file")); - m_copyBtn->setEnabled(false); - connect(m_btnBox, &QDialogButtonBox::rejected, - this, [this]() { - if (m_inExport) { - // Just cancel the export. Do not exit. - m_askedToStop = true; - m_exporter->setAskedToStop(true); - appendLogLine(tr("Cancelling the export...")); - } else { - QDialog::reject(); - } - }); - - m_exportBtn->setProperty("SpecialBtn", true); - connect(m_exportBtn, &QPushButton::clicked, - this, &VExportDialog::startExport); - - connect(m_openBtn, &QPushButton::clicked, - this, [this]() { - QUrl url = QUrl::fromLocalFile(getOutputDirectory()); - QDesktopServices::openUrl(url); - }); - - connect(m_copyBtn, &QPushButton::clicked, - this, [this]() { - if (m_exportedFile.isEmpty()) { - return; - } - - bool ret = false; - QString content = VUtils::readFileFromDisk(m_exportedFile); - if (!content.isNull()) { - QMimeData *data = new QMimeData(); - data->setText(content); - VClipboardUtils::setMimeDataToClipboard(QApplication::clipboard(), data, QClipboard::Clipboard); - ret = true; - } - - if (ret) { - appendLogLine(tr("Copied content of file %1").arg(m_exportedFile)); - } else { - appendLogLine(tr("Fail to copy content of file %1").arg(m_exportedFile)); - } - }); - - // Progress bar. - m_proBar = new QProgressBar(); - m_proBar->setRange(0, 0); - m_proBar->hide(); - - QHBoxLayout *btnLayout = new QHBoxLayout(); - btnLayout->addWidget(m_proBar); - btnLayout->addWidget(m_btnBox); - - QFormLayout *basicLayout = new QFormLayout(); - basicLayout->addRow(tr("Notes to export:"), m_srcCB); - basicLayout->addRow(tr("Target format:"), m_formatCB); - basicLayout->addRow(tr("Markdown renderer:"), m_rendererCB); - basicLayout->addRow(tr("Markdown rendering background:"), m_renderBgCB); - basicLayout->addRow(tr("Markdown rendering style:"), m_renderStyleCB); - basicLayout->addRow(tr("Markdown rendering code block style:"), m_renderCodeBlockStyleCB); - basicLayout->addRow(tr("Output directory:"), outputLayout); - - m_basicBox->setLayout(basicLayout); - - // Settings box. - m_generalSettings = setupGeneralAdvancedSettings(); - m_htmlSettings = setupHTMLAdvancedSettings(); - m_pdfSettings = setupPDFAdvancedSettings(); - m_customSettings = setupCustomAdvancedSettings(); - - QVBoxLayout *advLayout = new QVBoxLayout(); - advLayout->addWidget(m_generalSettings); - advLayout->addWidget(m_htmlSettings); - advLayout->addWidget(m_pdfSettings); - advLayout->addWidget(m_customSettings); - - m_settingBox->setLayout(advLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_basicBox); - mainLayout->addWidget(m_settingBox); - mainLayout->addWidget(m_consoleEdit); - mainLayout->addLayout(btnLayout); - - setLayout(mainLayout); - - setWindowTitle(tr("Export")); -} - -QWidget *VExportDialog::setupPDFAdvancedSettings() -{ - // Page layout settings. - m_layoutLabel = new QLabel(); - QPushButton *layoutBtn = new QPushButton(tr("Settings")); - -#ifndef QT_NO_PRINTER - connect(layoutBtn, &QPushButton::clicked, - this, &VExportDialog::handleLayoutBtnClicked); -#else - layoutBtn->hide(); -#endif - - updatePageLayoutLabel(); - - // Enable table of contents. - m_tableOfContentsCB = new QCheckBox(tr("Enable Table Of Contents")); - m_tableOfContentsCB->setToolTip(tr("Add a table of contents to the document")); - - // Use wkhtmltopdf. - m_wkhtmltopdfCB = new QCheckBox(tr("Use wkhtmltopdf")); - m_wkhtmltopdfCB->setToolTip(tr("Use wkhtmltopdf tool to generate PDF (wkhtmltopdf needed to be installed)")); - connect(m_wkhtmltopdfCB, &QCheckBox::stateChanged, - this, [this](int p_state) { - bool checked = p_state == Qt::Checked; - m_wkPathEdit->setEnabled(checked); - m_wkPathBrowseBtn->setEnabled(checked); - m_wkBackgroundCB->setEnabled(checked); - m_wkPageNumberCB->setEnabled(checked); - m_wkExtraArgsEdit->setEnabled(checked); - }); - - QPushButton *wkBtn = new QPushButton(tr("Download wkhtmltopdf")); - connect(wkBtn, &QPushButton::clicked, - this, [this]() { - QString url("https://wkhtmltopdf.org/downloads.html"); - QDesktopServices::openUrl(QUrl(url)); - }); - - // wkhtmltopdf Path. - m_wkPathEdit = new VLineEdit(); - m_wkPathEdit->setToolTip(tr("Tell VNote where to find wkhtmltopdf tool")); - m_wkPathEdit->setEnabled(false); - - m_wkPathBrowseBtn = new QPushButton(tr("&Browse")); - connect(m_wkPathBrowseBtn, &QPushButton::clicked, - this, &VExportDialog::handleWkPathBrowseBtnClicked); - m_wkPathBrowseBtn->setEnabled(false); - - m_wkTitleEdit = new VLineEdit(); - m_wkTitleEdit->setPlaceholderText(tr("Empty to use the name of the first source file")); - m_wkTitleEdit->setToolTip(tr("Title of the generated PDF file")); - m_wkTitleEdit->setEnabled(false); - - m_wkTargetFileNameEdit = new VLineEdit(); - m_wkTargetFileNameEdit->setPlaceholderText(tr("Empty to use the name of the first source file")); - m_wkTargetFileNameEdit->setToolTip(tr("Name of the generated PDF file")); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_wkTargetFileNameEdit); - m_wkTargetFileNameEdit->setValidator(validator); - m_wkTargetFileNameEdit->setEnabled(false); - - // wkhtmltopdf enable background. - m_wkBackgroundCB = new QCheckBox(tr("Enable background")); - m_wkBackgroundCB->setToolTip(tr("Enable background when printing")); - m_wkBackgroundCB->setEnabled(false); - - // wkhtmltopdf page number. - m_wkPageNumberCB = VUtils::getComboBox(); - m_wkPageNumberCB->setToolTip(tr("Append page number as footer")); - m_wkPageNumberCB->setEnabled(false); - - // wkhtmltopdf extra argumnets. - m_wkExtraArgsEdit = new VLineEdit(); - m_wkExtraArgsEdit->setToolTip(tr("Additional global options passed to wkhtmltopdf")); - m_wkExtraArgsEdit->setPlaceholderText(tr("Use \" to enclose options containing spaces")); - m_wkExtraArgsEdit->setEnabled(false); - - QGridLayout *advLayout = new QGridLayout(); - advLayout->addWidget(new QLabel(tr("Page layout:")), 0, 0); - advLayout->addWidget(m_layoutLabel, 0, 1); - advLayout->addWidget(layoutBtn, 0, 2); - advLayout->addWidget(m_tableOfContentsCB, 0, 4, 1, 2); - - advLayout->addWidget(m_wkhtmltopdfCB, 1, 1, 1, 2); - advLayout->addWidget(wkBtn, 1, 4, 1, 2); - - advLayout->addWidget(new QLabel(tr("wkhtmltopdf path:")), 2, 0); - advLayout->addWidget(m_wkPathEdit, 2, 1, 1, 4); - advLayout->addWidget(m_wkPathBrowseBtn, 2, 5); - - advLayout->addWidget(new QLabel(tr("Title:")), 3, 0); - advLayout->addWidget(m_wkTitleEdit, 3, 1, 1, 2); - - advLayout->addWidget(new QLabel(tr("Output file name:")), 3, 3); - advLayout->addWidget(m_wkTargetFileNameEdit, 3, 4, 1, 2); - - advLayout->addWidget(new QLabel(tr("Page number:")), 4, 0); - advLayout->addWidget(m_wkPageNumberCB, 4, 1, 1, 2); - advLayout->addWidget(m_wkBackgroundCB, 4, 4, 1, 2); - - advLayout->addWidget(new QLabel(tr("Additional options:")), 5, 0); - advLayout->addWidget(m_wkExtraArgsEdit, 5, 1, 1, 5); - - advLayout->setContentsMargins(0, 0, 0, 0); - - QWidget *wid = new QWidget(); - wid->setLayout(advLayout); - - return wid; -} - -QWidget *VExportDialog::setupHTMLAdvancedSettings() -{ - // Embed CSS styles. - m_embedStyleCB = new QCheckBox(tr("Embed CSS styles"), this); - m_embedStyleCB->setToolTip(tr("Embed CSS styles in HTML file")); - - // Embed images as data URI. - m_embedImagesCB = new QCheckBox(tr("Embed images"), this); - m_embedImagesCB->setToolTip(tr("Embed images as data URI")); - - // Complete HTML. - m_completeHTMLCB = new QCheckBox(tr("Complete page"), this); - m_completeHTMLCB->setToolTip(tr("Export the whole web page along with pictures " - "which may not keep the HTML link structure of " - "the original page")); - connect(m_completeHTMLCB, &QCheckBox::stateChanged, - this, [this](int p_state) { - bool checked = p_state == Qt::Checked; - m_embedImagesCB->setEnabled(checked); - if (!checked) { - m_embedImagesCB->setChecked(false); - } - }); - - // Mime HTML. - m_mimeHTMLCB = new QCheckBox(tr("MIME HTML"), this); - m_mimeHTMLCB->setToolTip(tr("Export as a complete web page in MIME HTML format")); - connect(m_mimeHTMLCB, &QCheckBox::stateChanged, - this, [this](int p_state) { - bool checked = p_state == Qt::Checked; - m_embedStyleCB->setEnabled(!checked); - m_completeHTMLCB->setEnabled(!checked); - }); - - // Outline panel. - m_outlinePanelCB = new QCheckBox(tr("Enable outline panel"), this); - m_outlinePanelCB->setToolTip(tr("Add an outline panel in HTML file")); - - QGridLayout *advLayout = new QGridLayout(); - advLayout->addWidget(m_embedStyleCB, 0, 1, 1, 2); - advLayout->addWidget(m_completeHTMLCB, 0, 4, 1, 2); - advLayout->addWidget(m_embedImagesCB, 1, 1, 1, 2); - advLayout->addWidget(m_mimeHTMLCB, 1, 4, 1, 2); - advLayout->addWidget(m_outlinePanelCB, 2, 1, 1, 2); - - advLayout->setContentsMargins(0, 0, 0, 0); - - QWidget *wid = new QWidget(); - wid->setLayout(advLayout); - - return wid; -} - -QWidget *VExportDialog::setupGeneralAdvancedSettings() -{ - // Include subfolders. - m_subfolderCB = new QCheckBox(tr("Process subfolders")); - m_subfolderCB->setToolTip(tr("Process subfolders recursively")); - - QFormLayout *advLayout = new QFormLayout(); - advLayout->addRow(m_subfolderCB); - - advLayout->setContentsMargins(0, 0, 0, 0); - - QWidget *wid = new QWidget(); - wid->setLayout(advLayout); - - return wid; -} - -void VExportDialog::initUIFields(MarkdownConverterType p_renderer) -{ - // Notes to export. - if (m_file) { - m_srcCB->addItem(tr("Current Note (%1)").arg(m_file->getName()), - (int)ExportSource::CurrentNote); - } - - if (m_directory) { - m_srcCB->addItem(tr("Current Folder (%1)").arg(m_directory->getName()), - (int)ExportSource::CurrentFolder); - } - - if (m_notebook) { - m_srcCB->addItem(tr("Current Notebook (%1)").arg(m_notebook->getName()), - (int)ExportSource::CurrentNotebook); - } - - if (m_cart && m_cart->count() > 0) { - m_srcCB->addItem(tr("Cart (%1)").arg(m_cart->count()), - (int)ExportSource::Cart); - } - - m_subfolderCB->setChecked(s_opt.m_processSubfolders); - - // Export format. - m_formatCB->addItem(tr("Markdown"), (int)ExportFormat::Markdown); - m_formatCB->addItem(tr("HTML"), (int)ExportFormat::HTML); - m_formatCB->addItem(tr("PDF"), (int)ExportFormat::PDF); - m_formatCB->addItem(tr("PDF (All In One)"), (int)ExportFormat::OnePDF); - m_formatCB->addItem(tr("Custom"), (int)ExportFormat::Custom); - m_formatCB->setCurrentIndex(m_formatCB->findData((int)s_opt.m_format)); - - // Markdown renderer. - m_rendererCB->addItem(tr("Hoedown"), MarkdownConverterType::Hoedown); - m_rendererCB->addItem(tr("Marked"), MarkdownConverterType::Marked); - m_rendererCB->addItem(tr("Markdown-it"), MarkdownConverterType::MarkdownIt); - m_rendererCB->addItem(tr("Showdown"), MarkdownConverterType::Showdown); - m_rendererCB->setCurrentIndex(m_rendererCB->findData(p_renderer)); - - // Markdown rendering background. - m_renderBgCB->addItem(tr("System"), "System"); - m_renderBgCB->addItem(tr("Transparent"), "Transparent"); - const QVector &bgColors = g_config->getCustomColors(); - for (int i = 0; i < bgColors.size(); ++i) { - m_renderBgCB->addItem(bgColors[i].m_name, bgColors[i].m_name); - } - - if (s_opt.m_renderBg.isEmpty()) { - s_opt.m_renderBg = g_config->getCurRenderBackgroundColor(); - } - - m_renderBgCB->setCurrentIndex(m_renderBgCB->findData(s_opt.m_renderBg)); - - // Markdown rendering style. - QList styles = g_config->getCssStyles(); - for (auto const &style : styles) { - m_renderStyleCB->addItem(style, style); - } - - m_renderStyleCB->setCurrentIndex( - m_renderStyleCB->findData(g_config->getCssStyle())); - - // Markdown rendering code block style. - QList cbStyles = g_config->getCodeBlockCssStyles(); - for (auto const &style : cbStyles) { - m_renderCodeBlockStyleCB->addItem(style, style); - } - - m_renderCodeBlockStyleCB->setCurrentIndex( - m_renderCodeBlockStyleCB->findData(g_config->getCodeBlockCssStyle())); - - m_embedStyleCB->setChecked(s_opt.m_htmlOpt.m_embedCssStyle); - - m_completeHTMLCB->setChecked(s_opt.m_htmlOpt.m_completeHTML); - - m_embedImagesCB->setChecked(s_opt.m_htmlOpt.m_embedImages); - - m_mimeHTMLCB->setChecked(s_opt.m_htmlOpt.m_mimeHTML); - - m_outlinePanelCB->setChecked(s_opt.m_htmlOpt.m_outlinePanel); - - m_tableOfContentsCB->setChecked(s_opt.m_pdfOpt.m_enableTableOfContents); - - m_wkhtmltopdfCB->setChecked(s_opt.m_pdfOpt.m_wkhtmltopdf); - - // wkhtmltopdf path. - m_wkPathEdit->setText(g_config->getWkhtmltopdfPath()); - - m_wkBackgroundCB->setChecked(s_opt.m_pdfOpt.m_wkEnableBackground); - - // wkhtmltopdf page number. - m_wkPageNumberCB->addItem(tr("None"), (int)ExportPageNumber::None); - m_wkPageNumberCB->addItem(tr("Left"), (int)ExportPageNumber::Left); - m_wkPageNumberCB->addItem(tr("Center"), (int)ExportPageNumber::Center); - m_wkPageNumberCB->addItem(tr("Right"), (int)ExportPageNumber::Right); - m_wkPageNumberCB->setCurrentIndex(m_wkPageNumberCB->findData((int)s_opt.m_pdfOpt.m_wkPageNumber)); - - m_wkExtraArgsEdit->setText(g_config->getWkhtmltopdfArgs()); - - // Custom export. - // Read from config every time. - ExportCustomOption customOpt(g_config->getCustomExport()); - - m_customSrcFormatCB->addItem(tr("Markdown"), (int)ExportCustomOption::SourceFormat::Markdown); - m_customSrcFormatCB->addItem(tr("HTML"), (int)ExportCustomOption::SourceFormat::HTML); - m_customSrcFormatCB->setCurrentIndex(m_customSrcFormatCB->findData((int)customOpt.m_srcFormat)); - - m_customSuffixEdit->setText(customOpt.m_outputSuffix); - - m_customCmdEdit->setPlainText(customOpt.m_cmd); - - m_customAllInOneCB->setChecked(s_opt.m_customOpt.m_allInOne); - - m_customPdfLikeCB->setChecked(s_opt.m_customOpt.m_pdfLike); - - m_customFolderSepEdit->setText(s_opt.m_customOpt.m_folderSep); -} - -bool VExportDialog::checkWkhtmltopdfExecutable(const QString &p_file) -{ - QStringList args; - args << "--version"; - QByteArray out, err; - int exitCode = -1; - int ret = VProcessUtils::startProcess(p_file, args, exitCode, out, err); - switch (ret) { - case -2: - appendLogLine(tr("Fail to start wkhtmltopdf (%1).").arg(p_file)); - break; - - case -1: - appendLogLine(tr("wkhtmltopdf crashed (%1).").arg(p_file)); - break; - - case 0: - appendLogLine(tr("Use %1 (%2).").arg(p_file).arg(exitCode)); - break; - - default: - Q_ASSERT(false); - break; - } - - return ret == 0; -} - -void VExportDialog::startExport() -{ - if (m_inExport) { - return; - } - - m_exportBtn->setEnabled(false); - m_proBar->show(); - m_askedToStop = false; - m_exporter->setAskedToStop(false); - m_inExport = true; - m_exportedFile.clear(); - m_copyBtn->setEnabled(false); - - QString outputFolder = QDir::cleanPath(QDir(getOutputDirectory()).absolutePath()); - - QString renderStyle = m_renderStyleCB->currentData().toString(); - QString renderCodeBlockStyle = m_renderCodeBlockStyleCB->currentData().toString(); - - s_opt = ExportOption(currentSource(), - currentFormat(), - (MarkdownConverterType)m_rendererCB->currentData().toInt(), - m_renderBgCB->currentData().toString(), - renderStyle, - renderCodeBlockStyle, - m_subfolderCB->isChecked(), - ExportPDFOption(&m_pageLayout, - m_wkhtmltopdfCB->isChecked(), - QDir::toNativeSeparators(m_wkPathEdit->text()), - m_wkBackgroundCB->isChecked(), - m_tableOfContentsCB->isChecked(), - m_wkTitleEdit->text(), - m_wkTargetFileNameEdit->text(), - (ExportPageNumber) - m_wkPageNumberCB->currentData().toInt(), - m_wkExtraArgsEdit->text()), - ExportHTMLOption(m_embedStyleCB->isChecked(), - m_completeHTMLCB->isChecked(), - m_embedImagesCB->isChecked(), - m_mimeHTMLCB->isChecked(), - m_outlinePanelCB->isChecked()), - ExportCustomOption((ExportCustomOption::SourceFormat) - m_customSrcFormatCB->currentData().toInt(), - m_customSuffixEdit->text(), - m_customCmdEdit->toPlainText(), - g_config->getCssStyleUrl(renderStyle), - g_config->getCodeBlockCssStyleUrl(renderCodeBlockStyle), - m_customAllInOneCB->isChecked(), - m_customPdfLikeCB->isChecked(), - m_customFolderSepEdit->text(), - m_customTargetFileNameEdit->text())); - - m_consoleEdit->clear(); - appendLogLine(tr("Export to %1.").arg(outputFolder)); - - if (s_opt.m_format == ExportFormat::PDF - || s_opt.m_format == ExportFormat::OnePDF - || s_opt.m_format == ExportFormat::HTML) { - if (s_opt.m_format != ExportFormat::OnePDF) { - s_opt.m_pdfOpt.m_wkTitle.clear(); - } - - if ((s_opt.m_format == ExportFormat::PDF - && s_opt.m_pdfOpt.m_wkhtmltopdf) - || s_opt.m_format == ExportFormat::OnePDF) { - g_config->setWkhtmltopdfPath(s_opt.m_pdfOpt.m_wkPath); - g_config->setWkhtmltopdfArgs(s_opt.m_pdfOpt.m_wkExtraArgs); - - if (!checkWkhtmltopdfExecutable(s_opt.m_pdfOpt.m_wkPath)) { - m_inExport = false; - m_exportBtn->setEnabled(true); - m_proBar->hide(); - return; - } - } - - m_exporter->prepareExport(s_opt); - } else if (s_opt.m_format == ExportFormat::Custom) { - const ExportCustomOption &opt = s_opt.m_customOpt; - if (opt.m_srcFormat == ExportCustomOption::HTML) { - m_exporter->prepareExport(s_opt); - } - - // Save it to config. - g_config->setCustomExport(opt.toConfig()); - - if (opt.m_outputSuffix.isEmpty() - || opt.m_cmd.isEmpty() - || (opt.m_allInOne && opt.m_folderSep.isEmpty())) { - appendLogLine(tr("Invalid configurations for custom export.")); - m_inExport = false; - m_exportBtn->setEnabled(true); - m_proBar->hide(); - return; - } - } - - int ret = 0; - QString msg; - - if (s_opt.m_format == ExportFormat::OnePDF) { - QList files; - // Output HTMLs to a tmp folder. - QTemporaryDir tmpDir; - if (!tmpDir.isValid()) { - goto exit; - } - - ret = outputAsHTML(tmpDir.path(), &msg, &files); - if (m_askedToStop) { - ret = 0; - goto exit; - } - - Q_ASSERT(ret == files.size()); - if (!files.isEmpty()) { - ret = doExportPDFAllInOne(files, s_opt, outputFolder, &msg); - } - } else if (s_opt.m_format == ExportFormat::Custom - && s_opt.m_customOpt.m_allInOne) { - QList files; - QTemporaryDir tmpDir; - if (!tmpDir.isValid()) { - goto exit; - } - - if (s_opt.m_customOpt.m_srcFormat == ExportCustomOption::HTML) { - // Output HTMLs to a tmp folder. - ret = outputAsHTML(tmpDir.path(), &msg, &files); - if (m_askedToStop) { - ret = 0; - goto exit; - } - - Q_ASSERT(ret == files.size()); - } else { - // Collect all markdown files. - files = collectFiles(&msg); - } - - if (!files.isEmpty()) { - ret = doExportCustomAllInOne(files, s_opt, outputFolder, &msg); - } - } else { - switch (s_opt.m_source) { - case ExportSource::CurrentNote: - { - QStringList files; - ret = doExport(m_file, s_opt, outputFolder, &msg, &files); - if (ret == 1 && s_opt.m_format == ExportFormat::HTML) { - Q_ASSERT(files.size() == 1); - m_exportedFile = files.first(); - } - - break; - } - - case ExportSource::CurrentFolder: - ret = doExport(m_directory, s_opt, outputFolder, &msg); - break; - - case ExportSource::CurrentNotebook: - ret = doExport(m_notebook, s_opt, outputFolder, &msg); - break; - - case ExportSource::Cart: - ret = doExport(m_cart, s_opt, outputFolder, &msg); - break; - - default: - break; - } - } - -exit: - - if (m_askedToStop) { - appendLogLine(tr("User cancelled the export. Aborted!")); - m_askedToStop = false; - m_exporter->setAskedToStop(false); - } - - if (!msg.isEmpty()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Errors found during export."), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - appendLogLine(tr("%1 notes exported.").arg(ret)); - - m_inExport = false; - m_exportBtn->setEnabled(true); - m_proBar->hide(); - - m_copyBtn->setEnabled(!m_exportedFile.isEmpty()); -} - -QString VExportDialog::getOutputDirectory() const -{ - return m_outputEdit->text(); -} - -void VExportDialog::handleOutputBrowseBtnClicked() -{ - QString initPath = getOutputDirectory(); - if (!QFileInfo::exists(initPath)) { - initPath = g_config->getDocumentPathOrHomePath(); - } - - QString dirPath = QFileDialog::getExistingDirectory(this, - tr("Select Output Directory To Export To"), - initPath, - QFileDialog::ShowDirsOnly - | QFileDialog::DontResolveSymlinks); - - if (!dirPath.isEmpty()) { - m_outputEdit->setText(dirPath); - s_lastOutputFolder = dirPath; - } -} - -void VExportDialog::handleWkPathBrowseBtnClicked() -{ - QString initPath = m_wkPathEdit->text(); - if (!QFileInfo::exists(initPath)) { - initPath = QCoreApplication::applicationDirPath(); - } - -#if defined(Q_OS_WIN) - QString filter = tr("Executable (*.exe)"); -#else - QString filter; -#endif - - QString filePath = QFileDialog::getOpenFileName(this, - tr("Select wkhtmltopdf Executable"), - initPath, - filter); - - if (!filePath.isEmpty()) { - m_wkPathEdit->setText(filePath); - } -} - -void VExportDialog::handleInputChanged() -{ - // Source. - bool sourceOk = true; - if (m_srcCB->count() == 0) { - sourceOk = false; - } - - // Output folder. - bool pathOk = true; - QString path = getOutputDirectory(); - if (path.isEmpty() || !VUtils::checkPathLegal(path)) { - pathOk = false; - } - - m_exportBtn->setEnabled(sourceOk && pathOk); - m_openBtn->setEnabled(pathOk); -} - -void VExportDialog::appendLogLine(const QString &p_text) -{ - m_consoleEdit->appendPlainText(">>> " + p_text); - m_consoleEdit->ensureCursorVisible(); - QCoreApplication::sendPostedEvents(); -} - -int VExportDialog::doExport(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg, - QList *p_outputFiles) -{ - Q_ASSERT(p_file); - - appendLogLine(tr("Exporting note %1.").arg(p_file->fetchPath())); - - int ret = 0; - switch (p_opt.m_format) { - case ExportFormat::Markdown: - ret = doExportMarkdown(p_file, p_opt, p_outputFolder, p_errMsg, p_outputFiles); - break; - - case ExportFormat::PDF: - V_FALLTHROUGH; - case ExportFormat::OnePDF: - ret = doExportPDF(p_file, p_opt, p_outputFolder, p_errMsg, p_outputFiles); - break; - - case ExportFormat::HTML: - ret = doExportHTML(p_file, p_opt, p_outputFolder, p_errMsg, p_outputFiles); - break; - - case ExportFormat::Custom: - ret = doExportCustom(p_file, p_opt, p_outputFolder, p_errMsg, p_outputFiles); - break; - - default: - break; - } - - return ret; -} - -int VExportDialog::doExport(VDirectory *p_directory, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg, - QList *p_outputFiles) -{ - Q_ASSERT(p_directory); - - bool opened = p_directory->isOpened(); - if (!opened && !p_directory->open()) { - LOGERR(tr("Fail to open folder %1.").arg(p_directory->fetchRelativePath())); - return 0; - } - - int ret = 0; - - QString folderName = VUtils::getDirNameWithSequence(p_outputFolder, - p_directory->getName()); - QString outputPath = QDir(p_outputFolder).filePath(folderName); - if (!VUtils::makePath(outputPath)) { - LOGERR(tr("Fail to create directory %1.").arg(outputPath)); - goto exit; - } - - // Export child notes. - for (auto const & file : p_directory->getFiles()) { - if (!checkUserAction()) { - goto exit; - } - - ret += doExport(file, p_opt, outputPath, p_errMsg, p_outputFiles); - } - - // Export subfolders. - if (p_opt.m_processSubfolders) { - for (auto const & dir : p_directory->getSubDirs()) { - if (!checkUserAction()) { - goto exit; - } - - ret += doExport(dir, p_opt, outputPath, p_errMsg, p_outputFiles); - } - } - -exit: - if (!opened) { - p_directory->close(); - } - - return ret; -} - -int VExportDialog::doExport(VNotebook *p_notebook, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg, - QList *p_outputFiles) -{ - Q_ASSERT(p_notebook); - - bool opened = p_notebook->isOpened(); - if (!opened && !p_notebook->open()) { - LOGERR(tr("Fail to open notebook %1.").arg(p_notebook->getName())); - return 0; - } - - int ret = 0; - - QString folderName = VUtils::getDirNameWithSequence(p_outputFolder, - p_notebook->getName()); - QString outputPath = QDir(p_outputFolder).filePath(folderName); - if (!VUtils::makePath(outputPath)) { - LOGERR(tr("Fail to create directory %1.").arg(outputPath)); - goto exit; - } - - // Export subfolder. - for (auto const & dir : p_notebook->getRootDir()->getSubDirs()) { - if (!checkUserAction()) { - goto exit; - } - - ret += doExport(dir, p_opt, outputPath, p_errMsg, p_outputFiles); - } - -exit: - if (!opened) { - p_notebook->close(); - } - - return ret; -} - -int VExportDialog::doExport(VCart *p_cart, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg, - QList *p_outputFiles) -{ - Q_UNUSED(p_cart); - Q_ASSERT(p_cart); - int ret = 0; - - QVector files = m_cart->getFiles(); - for (auto const & it : files) { - VFile *file = g_vnote->getFile(it); - if (!file) { - LOGERR(tr("Fail to open file %1.").arg(it)); - continue; - } - - ret += doExport(file, p_opt, p_outputFolder, p_errMsg, p_outputFiles); - } - - return ret; -} - -int VExportDialog::doExportMarkdown(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg, - QList *p_outputFiles) -{ - Q_UNUSED(p_opt); - - QString srcFilePath(p_file->fetchPath()); - - if (p_file->getDocType() != DocType::Markdown) { - LOGERR(tr("Skip exporting non-Markdown file %1 as Markdown.").arg(srcFilePath)); - return 0; - } - - // Export it to a folder with the same name. - QString name = VUtils::getDirNameWithSequence(p_outputFolder, p_file->getName()); - QString outputPath = QDir(p_outputFolder).filePath(name); - if (!VUtils::makePath(outputPath)) { - LOGERR(tr("Fail to create directory %1.").arg(outputPath)); - return 0; - } - - // Copy the note file. - QString destPath = QDir(outputPath).filePath(p_file->getName()); - if (!VUtils::copyFile(srcFilePath, destPath, false)) { - LOGERR(tr("Fail to copy the note file %1.").arg(srcFilePath)); - return 0; - } - - // Copy images. - int ret = 1; - int nrImageCopied = 0; - QVector images = VUtils::fetchImagesFromMarkdownFile(p_file, - ImageLink::LocalRelativeInternal); - if (!VNoteFile::copyInternalImages(images, - outputPath, - false, - &nrImageCopied, - p_errMsg)) { - ret = 0; - appendLogLine(tr("Fail to copy images of note %1.").arg(srcFilePath)); - } - - // Copy attachments. - if (p_file->getType() == FileType::Note) { - VNoteFile *noteFile = static_cast(p_file); - QString attaFolder = noteFile->getAttachmentFolder(); - if (!attaFolder.isEmpty()) { - QString attaFolderPath; - attaFolderPath = noteFile->fetchAttachmentFolderPath(); - QString relativePath = QDir(noteFile->fetchBasePath()).relativeFilePath(attaFolderPath); - QString folderPath = QDir(outputPath).filePath(relativePath); - - // Copy attaFolder to folderPath. - if (!VUtils::copyDirectory(attaFolderPath, folderPath, false)) { - LOGERR(tr("Fail to copy attachments folder %1 to %2.") - .arg(attaFolderPath).arg(folderPath)); - ret = 0; - } - } - } - - if (ret) { - if (p_outputFiles) { - p_outputFiles->append(destPath); - } - - appendLogLine(tr("Note %1 exported to %2.").arg(srcFilePath).arg(outputPath)); - } - - return ret; -} - -int VExportDialog::doExportPDF(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg, - QList *p_outputFiles) -{ - Q_UNUSED(p_opt); - - QString srcFilePath(p_file->fetchPath()); - - if (p_file->getDocType() != DocType::Markdown) { - LOGERR(tr("Skip exporting non-Markdown file %1 as PDF.").arg(srcFilePath)); - return 0; - } - - if (!VUtils::makePath(p_outputFolder)) { - LOGERR(tr("Fail to create directory %1.").arg(p_outputFolder)); - return 0; - } - - // Get output file. - QString suffix = ".pdf"; - QString name = VUtils::getFileNameWithSequence(p_outputFolder, - QFileInfo(p_file->getName()).completeBaseName() + suffix); - QString outputPath = QDir(p_outputFolder).filePath(name); - - if (m_exporter->exportPDF(p_file, p_opt, outputPath, p_errMsg)) { - if (p_outputFiles) { - p_outputFiles->append(outputPath); - } - - appendLogLine(tr("Note %1 exported to %2.").arg(srcFilePath).arg(outputPath)); - return 1; - } else { - appendLogLine(tr("Fail to export note %1.").arg(srcFilePath)); - return 0; - } -} - -int VExportDialog::doExportHTML(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg, - QList *p_outputFiles) -{ - Q_UNUSED(p_opt); - - QString srcFilePath(p_file->fetchPath()); - - if (p_file->getDocType() != DocType::Markdown) { - LOGERR(tr("Skip exporting non-Markdown file %1 as HTML.").arg(srcFilePath)); - return 0; - } - - if (!VUtils::makePath(p_outputFolder)) { - LOGERR(tr("Fail to create directory %1.").arg(p_outputFolder)); - return 0; - } - - // Get output file. - QString suffix = p_opt.m_htmlOpt.m_mimeHTML ? ".mht" : ".html"; - QString name = VUtils::getFileNameWithSequence(p_outputFolder, - QFileInfo(p_file->getName()).completeBaseName() + suffix); - QString outputPath = QDir(p_outputFolder).filePath(name); - - if (m_exporter->exportHTML(p_file, p_opt, outputPath, p_errMsg)) { - if (p_outputFiles) { - p_outputFiles->append(outputPath); - } - - appendLogLine(tr("Note %1 exported to %2.").arg(srcFilePath).arg(outputPath)); - return 1; - } else { - appendLogLine(tr("Fail to export note %1.").arg(srcFilePath)); - return 0; - } -} - -int VExportDialog::doExportCustom(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg, - QList *p_outputFiles) -{ - Q_UNUSED(p_opt); - - QString srcFilePath(p_file->fetchPath()); - - if (p_file->getDocType() != DocType::Markdown) { - LOGERR(tr("Skip exporting non-Markdown file %1.").arg(srcFilePath)); - return 0; - } - - if (!VUtils::makePath(p_outputFolder)) { - LOGERR(tr("Fail to create directory %1.").arg(p_outputFolder)); - return 0; - } - - // Get output file. - QString suffix = "." + p_opt.m_customOpt.m_outputSuffix; - QString name = VUtils::getFileNameWithSequence(p_outputFolder, - QFileInfo(p_file->getName()).completeBaseName() + suffix); - QString outputPath = QDir(p_outputFolder).filePath(name); - - if (m_exporter->exportCustom(p_file, p_opt, outputPath, p_errMsg)) { - if (p_outputFiles) { - p_outputFiles->append(outputPath); - } - - appendLogLine(tr("Note %1 exported to %2.").arg(srcFilePath).arg(outputPath)); - return 1; - } else { - appendLogLine(tr("Fail to export note %1.").arg(srcFilePath)); - return 0; - } -} - -bool VExportDialog::checkUserAction() -{ - if (m_askedToStop) { - return false; - } - - QCoreApplication::processEvents(); - - return true; -} - -void VExportDialog::handleLayoutBtnClicked() -{ -#ifndef QT_NO_PRINTER - QPrinter printer; - printer.setPageLayout(m_pageLayout); - - QPageSetupDialog dlg(&printer, this); - if (dlg.exec() != QDialog::Accepted) { - return; - } - - m_pageLayout.setUnits(QPageLayout::Millimeter); - m_pageLayout.setPageSize(printer.pageLayout().pageSize()); - m_pageLayout.setMargins(printer.pageLayout().margins(QPageLayout::Millimeter)); - m_pageLayout.setOrientation(printer.pageLayout().orientation()); - - updatePageLayoutLabel(); -#endif -} - -void VExportDialog::updatePageLayoutLabel() -{ - m_layoutLabel->setText(QString("%1, %2").arg(m_pageLayout.pageSize().name()) - .arg(m_pageLayout.orientation() == QPageLayout::Portrait ? - tr("Portrait") : tr("Landscape"))); -} - -void VExportDialog::handleCurrentFormatChanged(int p_index) -{ - bool pdfEnabled = false; - bool htmlEnabled = false; - bool pdfTitleNameEnabled = false; - bool customEnabled = false; - - if (p_index >= 0) { - switch (currentFormat()) { - case ExportFormat::PDF: - pdfEnabled = true; - m_wkhtmltopdfCB->setEnabled(true); - break; - - case ExportFormat::HTML: - htmlEnabled = true; - break; - - case ExportFormat::OnePDF: - pdfEnabled = true; - pdfTitleNameEnabled = true; - m_wkhtmltopdfCB->setChecked(true); - m_wkhtmltopdfCB->setEnabled(false); - break; - - case ExportFormat::Custom: - customEnabled = true; - break; - - default: - break; - } - } - - m_pdfSettings->setVisible(pdfEnabled); - m_htmlSettings->setVisible(htmlEnabled); - m_customSettings->setVisible(customEnabled); - - m_wkTitleEdit->setEnabled(pdfTitleNameEnabled); - m_wkTargetFileNameEdit->setEnabled(pdfTitleNameEnabled); - - QTimer::singleShot(100, [this]() { - resize(size().width(), minimumSizeHint().height()); - }); -} - -void VExportDialog::handleCurrentSrcChanged(int p_index) -{ - bool subfolderEnabled = false; - - if (p_index >= 0) { - switch (currentSource()) { - case ExportSource::CurrentFolder: - subfolderEnabled = true; - break; - - default: - break; - } - } - - m_subfolderCB->setVisible(subfolderEnabled); -} - -int VExportDialog::doExportPDFAllInOne(const QList &p_files, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg) -{ - if (p_files.isEmpty()) { - return 0; - } - - if (!VUtils::makePath(p_outputFolder)) { - LOGERR(tr("Fail to create directory %1.").arg(p_outputFolder)); - return 0; - } - - // Get output file. - const QString suffix = ".pdf"; - QString name = p_opt.m_pdfOpt.m_wkTargetFileName; - if (name.isEmpty()) { - name = VUtils::getFileNameWithSequence(p_outputFolder, - QFileInfo(p_files.first()).completeBaseName() + suffix); - } else if (!name.endsWith(suffix)) { - name += suffix; - } - - QString outputPath = QDir(p_outputFolder).filePath(name); - - int ret = m_exporter->exportPDFInOne(p_files, p_opt, outputPath, p_errMsg); - if (ret > 0) { - appendLogLine(tr("%1 notes exported to %2.").arg(ret).arg(outputPath)); - } else { - appendLogLine(tr("Fail to export %1 notes in one PDF.").arg(p_files.size())); - } - - return ret; -} - -int VExportDialog::doExportCustomAllInOne(const QList &p_files, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg) -{ - if (p_files.isEmpty()) { - return 0; - } - - if (!VUtils::makePath(p_outputFolder)) { - LOGERR(tr("Fail to create directory %1.").arg(p_outputFolder)); - return 0; - } - - // Get output file. - QString suffix = "." + p_opt.m_customOpt.m_outputSuffix; - QString name = p_opt.m_customOpt.m_targetFileName; - if (name.isEmpty()) { - name = VUtils::getFileNameWithSequence(p_outputFolder, - QFileInfo(p_files.first()).completeBaseName() + suffix); - } else if (!name.endsWith(suffix)) { - name += suffix; - } - - QString outputPath = QDir(p_outputFolder).filePath(name); - - int ret = m_exporter->exportCustomInOne(p_files, p_opt, outputPath, p_errMsg); - if (ret > 0) { - appendLogLine(tr("%1 notes exported to %2.").arg(ret).arg(outputPath)); - } else { - appendLogLine(tr("Fail to export %1 notes in one.").arg(p_files.size())); - } - - return ret; -} - -QWidget *VExportDialog::setupCustomAdvancedSettings() -{ - // Source format. - m_customSrcFormatCB = VUtils::getComboBox(this); - m_customSrcFormatCB->setToolTip(tr("Choose format of the input")); - - // Output suffix. - m_customSuffixEdit = new VLineEdit(this); - m_customSuffixEdit->setPlaceholderText(tr("Without the preceding dot")); - m_customSuffixEdit->setToolTip(tr("Suffix of the output file without the preceding dot")); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_customSuffixEdit); - m_customSuffixEdit->setValidator(validator); - - QLabel *tipsLabel = new QLabel(tr("%0 for the input file; " - "%1 for the output file; " - "%2 for the rendering CSS style file; " - "%3 for the input file directory; " - "%4 for the rendering code block CSS style file."), - this); - tipsLabel->setWordWrap(true); - - // Enable All In One. - m_customAllInOneCB = new QCheckBox(tr("Enable All In One"), this); - m_customAllInOneCB->setToolTip(tr("Pass a list of input files to the custom command")); - connect(m_customAllInOneCB, &QCheckBox::stateChanged, - this, [this](int p_state) { - bool checked = p_state == Qt::Checked; - m_customFolderSepEdit->setEnabled(checked); - m_customTargetFileNameEdit->setEnabled(checked); - }); - - // Enable PDF-like. - m_customPdfLikeCB = new QCheckBox(tr("PDF-Like"), this); - m_customPdfLikeCB->setToolTip(tr("Treat the exported file as PDF, such as wrapping line")); - - // Input directory separator. - m_customFolderSepEdit = new VLineEdit(this); - m_customFolderSepEdit->setPlaceholderText(tr("Separator to concatenate input files directories")); - m_customFolderSepEdit->setToolTip(tr("Separator to concatenate input files directories")); - m_customFolderSepEdit->setEnabled(false); - - // Target file name for all in one. - m_customTargetFileNameEdit = new VLineEdit(this); - m_customTargetFileNameEdit->setPlaceholderText(tr("Empty to use the name of the first source file")); - m_customTargetFileNameEdit->setToolTip(tr("Name of the generated All-In-One file")); - validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_customTargetFileNameEdit); - m_customTargetFileNameEdit->setValidator(validator); - m_customTargetFileNameEdit->setEnabled(false); - - // Cmd edit. - m_customCmdEdit = new QPlainTextEdit(this); - m_customCmdEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); - QString cmdExamp("pandoc --resource-path=.:\"%3\" --css=\"%2\" --css=\"%4\" -s -o \"%1\" \"%0\""); - m_customCmdEdit->setPlaceholderText(cmdExamp); - m_customCmdEdit->setToolTip(tr("Custom command to be executed")); - m_customCmdEdit->setProperty("LineEdit", true); - - QGridLayout *advLayout = new QGridLayout(); - advLayout->addWidget(new QLabel(tr("Source format:")), 0, 0); - advLayout->addWidget(m_customSrcFormatCB, 0, 1, 1, 2); - - advLayout->addWidget(new QLabel(tr("Output suffix:")), 0, 3); - advLayout->addWidget(m_customSuffixEdit, 0, 4, 1, 2); - - advLayout->addWidget(m_customAllInOneCB, 1, 1, 1, 2); - advLayout->addWidget(m_customPdfLikeCB, 1, 4, 1, 2); - - advLayout->addWidget(new QLabel(tr("Output file name:")), 2, 0); - advLayout->addWidget(m_customTargetFileNameEdit, 2, 1, 1, 2); - - advLayout->addWidget(new QLabel(tr("Input directories separator:")), 2, 3); - advLayout->addWidget(m_customFolderSepEdit, 2, 4, 1, 2); - - advLayout->addWidget(tipsLabel, 3, 0, 1, 6); - - advLayout->addWidget(m_customCmdEdit, 4, 0, 1, 6); - - advLayout->setContentsMargins(0, 0, 0, 0); - - QWidget *wid = new QWidget(); - wid->setLayout(advLayout); - - m_customCmdEdit->setMaximumHeight(m_customSrcFormatCB->height() * 3); - - return wid; -} - -int VExportDialog::outputAsHTML(const QString &p_outputFolder, - QString *p_errMsg, - QList *p_outputFiles) -{ - int ret = 0; - ExportFormat fmt = s_opt.m_format; - s_opt.m_format = ExportFormat::HTML; - switch (s_opt.m_source) { - case ExportSource::CurrentNote: - ret = doExport(m_file, s_opt, p_outputFolder, p_errMsg, p_outputFiles); - break; - - case ExportSource::CurrentFolder: - ret = doExport(m_directory, s_opt, p_outputFolder, p_errMsg, p_outputFiles); - break; - - case ExportSource::CurrentNotebook: - ret = doExport(m_notebook, s_opt, p_outputFolder, p_errMsg, p_outputFiles); - break; - - case ExportSource::Cart: - ret = doExport(m_cart, s_opt, p_outputFolder, p_errMsg, p_outputFiles); - break; - - default: - break; - } - - s_opt.m_format = fmt; - - return ret; -} - -QList VExportDialog::collectFiles(QString *p_errMsg) -{ - Q_UNUSED(p_errMsg); - - QList files; - switch (s_opt.m_source) { - case ExportSource::CurrentNote: - files.append(m_file->fetchPath()); - break; - - case ExportSource::CurrentFolder: - files = m_directory->collectFiles(); - break; - - case ExportSource::CurrentNotebook: - files = m_notebook->collectFiles(); - break; - - case ExportSource::Cart: - files = m_cart->getFiles().toList(); - break; - - default: - break; - } - - return files; -} diff --git a/src/dialog/vexportdialog.h b/src/dialog/vexportdialog.h deleted file mode 100644 index 48a0afec..00000000 --- a/src/dialog/vexportdialog.h +++ /dev/null @@ -1,516 +0,0 @@ -#ifndef VEXPORTDIALOG_H -#define VEXPORTDIALOG_H - -#include -#include -#include -#include - -#include "vconstants.h" - -class QLabel; -class VLineEdit; -class QDialogButtonBox; -class QPushButton; -class QGroupBox; -class QPlainTextEdit; -class VNotebook; -class VDirectory; -class VFile; -class VCart; -class VExporter; -class QCheckBox; -class VLineEdit; -class QProgressBar; - - -enum class ExportSource -{ - CurrentNote = 0, - CurrentFolder, - CurrentNotebook, - Cart -}; - - -enum class ExportFormat -{ - Markdown = 0, - HTML, - PDF, - OnePDF, - Custom -}; - - -enum class ExportPageNumber -{ - None = 0, - Left, - Center, - Right -}; - - -struct ExportHTMLOption -{ - ExportHTMLOption() - : m_embedCssStyle(true), - m_completeHTML(true), - m_embedImages(true), - m_mimeHTML(false), - m_outlinePanel(true) - { - } - - ExportHTMLOption(bool p_embedCssStyle, - bool p_completeHTML, - bool p_embedImages, - bool p_mimeHTML, - bool p_outlinePanel) - : m_embedCssStyle(p_embedCssStyle), - m_completeHTML(p_completeHTML), - m_embedImages(p_embedImages), - m_mimeHTML(p_mimeHTML), - m_outlinePanel(p_outlinePanel) - { - } - - bool m_embedCssStyle; - bool m_completeHTML; - bool m_embedImages; - bool m_mimeHTML; - bool m_outlinePanel; -}; - - -struct ExportPDFOption -{ - ExportPDFOption() - : m_layout(NULL), - m_wkhtmltopdf(false), - m_wkEnableBackground(true), - m_enableTableOfContents(false), - m_wkPageNumber(ExportPageNumber::None) - { - } - - ExportPDFOption(QPageLayout *p_layout, - bool p_wkhtmltopdf, - const QString &p_wkPath, - bool p_wkEnableBackground, - bool p_enableTableOfContents, - const QString &p_wkTitle, - const QString &p_wkTargetFileName, - ExportPageNumber p_wkPageNumber, - const QString &p_wkExtraArgs) - : m_layout(p_layout), - m_wkhtmltopdf(p_wkhtmltopdf), - m_wkPath(p_wkPath), - m_wkEnableBackground(p_wkEnableBackground), - m_enableTableOfContents(p_enableTableOfContents), - m_wkTitle(p_wkTitle), - m_wkTargetFileName(p_wkTargetFileName), - m_wkPageNumber(p_wkPageNumber), - m_wkExtraArgs(p_wkExtraArgs) - { - } - - QPageLayout *m_layout; - bool m_wkhtmltopdf; - QString m_wkPath; - bool m_wkEnableBackground; - bool m_enableTableOfContents;; - QString m_wkTitle; - QString m_wkTargetFileName; - ExportPageNumber m_wkPageNumber; - QString m_wkExtraArgs; -}; - - -struct ExportCustomOption -{ -#if defined(Q_OS_WIN) - #define DEFAULT_SEP ";" -#else - #define DEFAULT_SEP ":" -#endif - - enum SourceFormat - { - Markdown = 0, - HTML - }; - - ExportCustomOption() - : m_srcFormat(SourceFormat::Markdown), - m_allInOne(false), - m_pdfLike(false), - m_folderSep(DEFAULT_SEP) - { - } - - ExportCustomOption(const QStringList &p_config) - : m_srcFormat(SourceFormat::Markdown), - m_allInOne(false), - m_pdfLike(false), - m_folderSep(DEFAULT_SEP) - { - if (p_config.size() < 3) { - return; - } - - if (p_config.at(0).trimmed() != "0") { - m_srcFormat = SourceFormat::HTML; - } - - m_outputSuffix = p_config.at(1).trimmed(); - - m_cmd = p_config.at(2).trimmed(); - } - - ExportCustomOption(ExportCustomOption::SourceFormat p_srcFormat, - const QString &p_outputSuffix, - const QString &p_cmd, - const QString &p_cssUrl, - const QString &p_codeBlockCssUrl, - bool p_allInOne, - bool p_pdfLike, - const QString &p_folderSep, - const QString &p_targetFileName) - : m_srcFormat(p_srcFormat), - m_outputSuffix(p_outputSuffix), - m_cssUrl(p_cssUrl), - m_codeBlockCssUrl(p_codeBlockCssUrl), - m_allInOne(p_allInOne), - m_pdfLike(p_pdfLike), - m_folderSep(p_folderSep), - m_targetFileName(p_targetFileName) - { - QStringList cmds = p_cmd.split('\n'); - if (!cmds.isEmpty()) { - m_cmd = cmds.first(); - } - } - - QStringList toConfig() const - { - QStringList config; - config << QString::number((int)m_srcFormat); - config << m_outputSuffix; - config << m_cmd; - - return config; - } - - SourceFormat m_srcFormat; - QString m_outputSuffix; - QString m_cmd; - - QString m_cssUrl; - QString m_codeBlockCssUrl; - - bool m_allInOne; - bool m_pdfLike; - - QString m_folderSep; - QString m_targetFileName; -}; - - -struct ExportOption -{ - ExportOption() - : m_source(ExportSource::CurrentNote), - m_format(ExportFormat::Markdown), - m_renderer(MarkdownConverterType::MarkdownIt), - m_processSubfolders(true) - { - } - - ExportOption(ExportSource p_source, - ExportFormat p_format, - MarkdownConverterType p_renderer, - const QString &p_renderBg, - const QString &p_renderStyle, - const QString &p_renderCodeBlockStyle, - bool p_processSubfolders, - const ExportPDFOption &p_pdfOpt, - const ExportHTMLOption &p_htmlOpt, - const ExportCustomOption &p_customOpt) - : m_source(p_source), - m_format(p_format), - m_renderer(p_renderer), - m_renderBg(p_renderBg), - m_renderStyle(p_renderStyle), - m_renderCodeBlockStyle(p_renderCodeBlockStyle), - m_processSubfolders(p_processSubfolders), - m_pdfOpt(p_pdfOpt), - m_htmlOpt(p_htmlOpt), - m_customOpt(p_customOpt) - { - } - - ExportSource m_source; - ExportFormat m_format; - MarkdownConverterType m_renderer; - - // Background name. - QString m_renderBg; - - QString m_renderStyle; - QString m_renderCodeBlockStyle; - - // Whether process subfolders recursively when source is CurrentFolder. - bool m_processSubfolders; - - ExportPDFOption m_pdfOpt; - - ExportHTMLOption m_htmlOpt; - - ExportCustomOption m_customOpt; -}; - - -class VExportDialog : public QDialog -{ - Q_OBJECT -public: - VExportDialog(VNotebook *p_notebook, - VDirectory *p_directory, - VFile *p_file, - VCart *p_cart, - MarkdownConverterType p_renderer, - QWidget *p_parent = nullptr); - -private slots: - void startExport(); - - void handleOutputBrowseBtnClicked(); - - void handleWkPathBrowseBtnClicked(); - - void handleInputChanged(); - - void handleLayoutBtnClicked(); - - void handleCurrentFormatChanged(int p_index); - - void handleCurrentSrcChanged(int p_index); - -private: - void setupUI(); - - QWidget *setupPDFAdvancedSettings(); - - QWidget *setupHTMLAdvancedSettings(); - - QWidget *setupGeneralAdvancedSettings(); - - QWidget *setupCustomAdvancedSettings(); - - void initUIFields(MarkdownConverterType p_renderer); - - QString getOutputDirectory() const; - - void appendLogLine(const QString &p_text); - - // Return number of files exported. - int doExport(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL, - QList *p_outputFiles = NULL); - - int doExport(VDirectory *p_directory, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL, - QList *p_outputFiles = NULL); - - int doExport(VNotebook *p_notebook, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL, - QList *p_outputFiles = NULL); - - int doExport(VCart *p_cart, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL, - QList *p_outputFiles = NULL); - - int doExportMarkdown(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL, - QList *p_outputFiles = NULL); - - int doExportPDF(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL, - QList *p_outputFiles = NULL); - - int doExportHTML(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL, - QList *p_outputFiles = NULL); - - int doExportPDFAllInOne(const QList &p_files, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL); - - int doExportCustomAllInOne(const QList &p_files, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL); - - int doExportCustom(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFolder, - QString *p_errMsg = NULL, - QList *p_outputFiles = NULL); - - // Return false if we could not continue. - bool checkUserAction(); - - void updatePageLayoutLabel(); - - bool checkWkhtmltopdfExecutable(const QString &p_file); - - ExportSource currentSource() const; - - ExportFormat currentFormat() const; - - int outputAsHTML(const QString &p_outputFolder, - QString *p_errMsg = NULL, - QList *p_outputFiles = NULL); - - // Collect files to be handled. - QList collectFiles(QString *p_errMsg = NULL); - - QComboBox *m_srcCB; - - QComboBox *m_formatCB; - - QComboBox *m_rendererCB; - - QComboBox *m_renderBgCB; - - QComboBox *m_renderStyleCB; - - QComboBox *m_renderCodeBlockStyleCB; - - VLineEdit *m_outputEdit; - - QGroupBox *m_basicBox; - - QGroupBox *m_settingBox; - - QWidget *m_pdfSettings; - - QWidget *m_htmlSettings; - - QWidget *m_generalSettings; - - QWidget *m_customSettings; - - QPlainTextEdit *m_consoleEdit; - - QDialogButtonBox *m_btnBox; - - QPushButton *m_openBtn; - - QPushButton *m_exportBtn; - - QPushButton *m_copyBtn; - - QLabel *m_layoutLabel; - - QCheckBox *m_wkhtmltopdfCB; - - VLineEdit *m_wkPathEdit; - - QPushButton *m_wkPathBrowseBtn; - - VLineEdit *m_wkTitleEdit; - - VLineEdit *m_wkTargetFileNameEdit; - - QCheckBox *m_wkBackgroundCB; - - QCheckBox *m_tableOfContentsCB; - - QComboBox *m_wkPageNumberCB; - - VLineEdit *m_wkExtraArgsEdit; - - QCheckBox *m_embedStyleCB; - - QCheckBox *m_completeHTMLCB; - - QCheckBox *m_embedImagesCB; - - QCheckBox *m_mimeHTMLCB; - - QCheckBox *m_outlinePanelCB; - - QCheckBox *m_subfolderCB; - - QComboBox *m_customSrcFormatCB; - - VLineEdit *m_customSuffixEdit; - - QCheckBox *m_customAllInOneCB; - - QCheckBox *m_customPdfLikeCB; - - QPlainTextEdit *m_customCmdEdit; - - VLineEdit *m_customFolderSepEdit; - - VLineEdit *m_customTargetFileNameEdit; - - VNotebook *m_notebook; - - VDirectory *m_directory; - - VFile *m_file; - - VCart *m_cart; - - QProgressBar *m_proBar; - - QPageLayout m_pageLayout; - - // Whether we are exporting files. - bool m_inExport; - - // Asked to stop exporting by user. - bool m_askedToStop; - - // Exporter used to export PDF and HTML. - VExporter *m_exporter; - - // Last exproted file path. - QString m_exportedFile; - - // Last output folder path. - static QString s_lastOutputFolder; - - static ExportOption s_opt; -}; - -inline ExportSource VExportDialog::currentSource() const -{ - return (ExportSource)m_srcCB->currentData().toInt(); -} - -inline ExportFormat VExportDialog::currentFormat() const -{ - return (ExportFormat)m_formatCB->currentData().toInt(); -} -#endif // VEXPORTDIALOG_H diff --git a/src/dialog/vfileinfodialog.cpp b/src/dialog/vfileinfodialog.cpp deleted file mode 100644 index 23b6a446..00000000 --- a/src/dialog/vfileinfodialog.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include "vfileinfodialog.h" -#include "vdirectory.h" -#include "vnotefile.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vmetawordlineedit.h" - -extern VConfigManager *g_config; - -VFileInfoDialog::VFileInfoDialog(const QString &title, - const QString &info, - VDirectory *directory, - const VNoteFile *file, - QWidget *parent) - : QDialog(parent), m_directory(directory), m_file(file) -{ - setupUI(title, info); - - connect(m_nameEdit, &VMetaWordLineEdit::textChanged, this, &VFileInfoDialog::handleInputChanged); - - handleInputChanged(); -} - -void VFileInfoDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - } - - // File name. - QString name = m_file->getName(); - m_nameEdit = new VMetaWordLineEdit(name); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - int baseStart = 0, baseLength = name.size(); - int dotIdx = name.lastIndexOf('.'); - if (dotIdx != -1) { - baseLength = dotIdx; - } - - // Select without suffix. - m_nameEdit->setSelection(baseStart, baseLength); - - // File path. - QLineEdit *filePathEdit = new QLineEdit(m_file->fetchPath()); - filePathEdit->setReadOnly(true); - - // Attachment folder. - VLineEdit *attachmentFolderEdit = new VLineEdit(m_file->getAttachmentFolder()); - attachmentFolderEdit->setPlaceholderText(tr("Will be assigned when adding attachments")); - attachmentFolderEdit->setToolTip(tr("The folder to hold attachments of this note")); - attachmentFolderEdit->setReadOnly(true); - - // Created time. - QString createdTimeStr = VUtils::displayDateTime(m_file->getCreatedTimeUtc().toLocalTime()); - QLabel *createdTimeLabel = new QLabel(createdTimeStr); - - // Modified time. - createdTimeStr = VUtils::displayDateTime(m_file->getModifiedTimeUtc().toLocalTime()); - QLabel *modifiedTimeLabel = new QLabel(createdTimeStr); - modifiedTimeLabel->setToolTip(tr("Last modified time within VNote")); - - // Tags. - QLineEdit *tagEdit = new QLineEdit(m_file->getTags().join(", ")); - QString tagTip = tr("Add tags to a note at the right bottom status bar when it is opened"); - tagEdit->setPlaceholderText(tagTip); - tagEdit->setToolTip(tr("Tags of this note separated by , (%1)").arg(tagTip)); - tagEdit->setReadOnly(true); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Note &name:"), m_nameEdit); - topLayout->addRow(tr("File path:"), filePathEdit); - topLayout->addRow(tr("Attachment folder:"), attachmentFolderEdit); - topLayout->addRow(tr("Created time:"), createdTimeLabel); - topLayout->addRow(tr("Modified time:"), modifiedTimeLabel); - topLayout->addRow(tr("Tags:"), tagEdit); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - - setWindowTitle(p_title); -} - -void VFileInfoDialog::handleInputChanged() -{ - bool showWarnLabel = false; - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk && name != m_file->getName()) { - // Check if the name conflicts with existing note name. - // Case-insensitive when creating note. - const VNoteFile *file = m_directory->findFile(name, false); - QString warnText; - if (file && file != m_file) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (m_file->getDocType() != DocType::Unknown - && VUtils::docTypeFromName(name) != m_file->getDocType()) { - // Check if the name change the doc type. - nameOk = false; - warnText = tr("WARNING: " - "Changing type of the note is not supported. " - "Please use the same suffix as the old one.") - .arg(g_config->c_warningTextStyle); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); -} - -QString VFileInfoDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} diff --git a/src/dialog/vfileinfodialog.h b/src/dialog/vfileinfodialog.h deleted file mode 100644 index 628689d0..00000000 --- a/src/dialog/vfileinfodialog.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef VFILEINFODIALOG_H -#define VFILEINFODIALOG_H - -#include - -class QLabel; -class VMetaWordLineEdit; -class QDialogButtonBox; -class QString; -class VDirectory; -class VNoteFile; - -// File information dialog for internal note file. -class VFileInfoDialog : public QDialog -{ - Q_OBJECT -public: - VFileInfoDialog(const QString &title, - const QString &info, - VDirectory *directory, - const VNoteFile *file, - QWidget *parent = 0); - - QString getNameInput() const; - -private slots: - void handleInputChanged(); - -private: - void setupUI(const QString &p_title, const QString &p_info); - - VMetaWordLineEdit *m_nameEdit; - QLabel *m_warnLabel; - QDialogButtonBox *m_btnBox; - - VDirectory *m_directory; - const VNoteFile *m_file; -}; - -#endif // VFILEINFODIALOG_H diff --git a/src/dialog/vfindreplacedialog.cpp b/src/dialog/vfindreplacedialog.cpp deleted file mode 100644 index 2e713448..00000000 --- a/src/dialog/vfindreplacedialog.cpp +++ /dev/null @@ -1,314 +0,0 @@ -#include "vfindreplacedialog.h" -#include - -#include "utils/viconutils.h" -#include "vlineedit.h" - -VFindReplaceDialog::VFindReplaceDialog(QWidget *p_parent) - : QWidget(p_parent), m_options(0), m_replaceAvailable(true) -{ - setupUI(); -} - -void VFindReplaceDialog::setupUI() -{ - QLabel *titleLabel = new QLabel(tr("Find/Replace")); - titleLabel->setProperty("TitleLabel", true); - m_closeBtn = new QPushButton(VIconUtils::titleIcon(":/resources/icons/close.svg"), ""); - m_closeBtn->setProperty("TitleBtn", true); - QHBoxLayout *titleLayout = new QHBoxLayout(); - titleLayout->addWidget(titleLabel); - titleLayout->addWidget(m_closeBtn); - titleLayout->setStretch(0, 1); - titleLayout->setStretch(1, 0); - titleLayout->setContentsMargins(0, 0, 0, 0); - titleLayout->setSpacing(0); - QWidget *titleWidget = new QWidget(); - titleWidget->setObjectName("FindReplaceTitleWidget"); - titleWidget->setLayout(titleLayout); - - // Find - QLabel *findLabel = new QLabel(tr("Find:")); - m_findEdit = new VLineEdit(); - m_findEdit->setPlaceholderText(tr("Enter text to search")); - findLabel->setBuddy(m_findEdit); - m_findNextBtn = new QPushButton(tr("Find &Next")); - m_findNextBtn->setProperty("FlatBtn", true); - m_findNextBtn->setDefault(true); - m_findPrevBtn = new QPushButton(tr("Find &Previous")); - m_findPrevBtn->setProperty("FlatBtn", true); - - // Replace - QLabel *replaceLabel = new QLabel(tr("&Replace with:")); - m_replaceEdit = new VLineEdit(); - m_replaceEdit->setPlaceholderText(tr("\\1, \\2 for back reference in regular expression")); - replaceLabel->setBuddy(m_replaceEdit); - m_replaceBtn = new QPushButton(tr("Replace")); - m_replaceBtn->setProperty("FlatBtn", true); - m_replaceFindBtn = new QPushButton(tr("Replace && Fin&d")); - m_replaceFindBtn->setProperty("FlatBtn", true); - m_replaceAllBtn = new QPushButton(tr("Replace A&ll")); - m_replaceAllBtn->setProperty("FlatBtn", true); - m_advancedBtn = new QPushButton(tr("&Advanced >>>")); - m_advancedBtn->setProperty("FlatBtn", true); - m_advancedBtn->setCheckable(true); - - // Options - m_caseSensitiveCheck = new QCheckBox(tr("&Case sensitive"), this); - connect(m_caseSensitiveCheck, &QCheckBox::stateChanged, - this, &VFindReplaceDialog::optionBoxToggled); - m_wholeWordOnlyCheck = new QCheckBox(tr("&Whole word only"), this); - connect(m_wholeWordOnlyCheck, &QCheckBox::stateChanged, - this, &VFindReplaceDialog::optionBoxToggled); - m_regularExpressionCheck = new QCheckBox(tr("Re&gular expression"), this); - connect(m_regularExpressionCheck, &QCheckBox::stateChanged, - this, &VFindReplaceDialog::optionBoxToggled); - m_incrementalSearchCheck = new QCheckBox(tr("&Incremental search"), this); - connect(m_incrementalSearchCheck, &QCheckBox::stateChanged, - this, &VFindReplaceDialog::optionBoxToggled); - - QGridLayout *gridLayout = new QGridLayout(); - gridLayout->addWidget(findLabel, 0, 0); - gridLayout->addWidget(m_findEdit, 0, 1); - gridLayout->addWidget(m_findNextBtn, 0, 2); - gridLayout->addWidget(m_findPrevBtn, 0, 3); - gridLayout->addWidget(replaceLabel, 1, 0); - gridLayout->addWidget(m_replaceEdit, 1, 1); - gridLayout->addWidget(m_replaceBtn, 1, 2); - gridLayout->addWidget(m_replaceFindBtn, 1, 3); - gridLayout->addWidget(m_replaceAllBtn, 1, 4); - gridLayout->addWidget(m_advancedBtn, 1, 5); - gridLayout->addWidget(m_caseSensitiveCheck, 2, 1); - gridLayout->addWidget(m_wholeWordOnlyCheck, 2, 2); - gridLayout->addWidget(m_regularExpressionCheck, 3, 1); - gridLayout->addWidget(m_incrementalSearchCheck, 3, 2); - gridLayout->setColumnStretch(0, 0); - gridLayout->setColumnStretch(1, 4); - gridLayout->setColumnStretch(2, 1); - gridLayout->setColumnStretch(3, 1); - gridLayout->setColumnStretch(4, 1); - gridLayout->setColumnStretch(5, 1); - gridLayout->setColumnStretch(6, 3); - - QMargins margin = gridLayout->contentsMargins(); - margin.setLeft(3); - gridLayout->setContentsMargins(margin); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(titleWidget); - mainLayout->addLayout(gridLayout); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); - - setTabOrder(m_findEdit, m_findNextBtn); - setTabOrder(m_findNextBtn, m_findPrevBtn); - setTabOrder(m_findPrevBtn, m_replaceEdit); - setTabOrder(m_replaceEdit, m_replaceBtn); - setTabOrder(m_replaceBtn, m_replaceFindBtn); - setTabOrder(m_replaceFindBtn, m_replaceAllBtn); - setTabOrder(m_replaceAllBtn, m_advancedBtn); - setTabOrder(m_advancedBtn, m_caseSensitiveCheck); - setTabOrder(m_caseSensitiveCheck, m_wholeWordOnlyCheck); - setTabOrder(m_wholeWordOnlyCheck, m_regularExpressionCheck); - setTabOrder(m_regularExpressionCheck, m_incrementalSearchCheck); - setTabOrder(m_incrementalSearchCheck, m_closeBtn); - - m_caseSensitiveCheck->hide(); - m_wholeWordOnlyCheck->hide(); - m_regularExpressionCheck->hide(); - m_incrementalSearchCheck->hide(); - - // Signals - connect(m_closeBtn, &QPushButton::clicked, - this, &VFindReplaceDialog::closeDialog); - connect(m_findEdit, &VLineEdit::textChanged, - this, &VFindReplaceDialog::handleFindTextChanged); - connect(m_advancedBtn, &QPushButton::toggled, - this, &VFindReplaceDialog::advancedBtnToggled); - connect(m_findNextBtn, SIGNAL(clicked(bool)), - this, SLOT(findNext())); - connect(m_findPrevBtn, SIGNAL(clicked(bool)), - this, SLOT(findPrevious())); - connect(m_replaceBtn, SIGNAL(clicked(bool)), - this, SLOT(replace())); - connect(m_replaceFindBtn, SIGNAL(clicked(bool)), - this, SLOT(replaceFind())); - connect(m_replaceAllBtn, SIGNAL(clicked(bool)), - this, SLOT(replaceAll())); -} - -void VFindReplaceDialog::closeDialog() -{ - if (this->isVisible()) { - hide(); - emit dialogClosed(); - } -} - -void VFindReplaceDialog::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Escape: - event->accept(); - closeDialog(); - return; - - case Qt::Key_Return: - { - int modifiers = event->modifiers(); - bool shift = false; - if (modifiers == Qt::ShiftModifier) { - shift = true; - } else if (modifiers != Qt::NoModifier) { - break; - } - if (!m_findEdit->hasFocus() && !m_replaceEdit->hasFocus()) { - break; - } - event->accept(); - if (shift) { - findPrevious(); - } else { - findNext(); - } - return; - } - - default: - break; - } - QWidget::keyPressEvent(event); -} - -void VFindReplaceDialog::openDialog(QString p_text) -{ - show(); - if (!p_text.isEmpty()) { - m_findEdit->setText(p_text); - } - m_findEdit->setFocus(); - m_findEdit->selectAll(); -} - -void VFindReplaceDialog::handleFindTextChanged(const QString &p_text) -{ - emit findTextChanged(p_text, m_options); -} - -void VFindReplaceDialog::advancedBtnToggled(bool p_checked) -{ - if (p_checked) { - m_advancedBtn->setText(tr("B&asic <<<")); - } else { - m_advancedBtn->setText(tr("&Advanced >>>")); - } - - m_caseSensitiveCheck->setVisible(p_checked); - m_wholeWordOnlyCheck->setVisible(p_checked); - m_regularExpressionCheck->setVisible(p_checked); - m_incrementalSearchCheck->setVisible(p_checked); -} - -void VFindReplaceDialog::optionBoxToggled(int p_state) -{ - QObject *obj = sender(); - FindOption opt = FindOption::CaseSensitive; - if (obj == m_caseSensitiveCheck) { - opt = FindOption::CaseSensitive; - } else if (obj == m_wholeWordOnlyCheck) { - opt = FindOption::WholeWordOnly; - } else if (obj == m_regularExpressionCheck) { - opt = FindOption::RegularExpression; - } else { - opt = FindOption::IncrementalSearch; - } - - if (p_state) { - m_options |= opt; - } else { - m_options &= ~opt; - } - emit findOptionChanged(m_options); -} - -void VFindReplaceDialog::setOption(FindOption p_opt, bool p_enabled) -{ - if (p_opt == FindOption::CaseSensitive) { - m_caseSensitiveCheck->setChecked(p_enabled); - } else if (p_opt == FindOption::WholeWordOnly) { - m_wholeWordOnlyCheck->setChecked(p_enabled); - } else if (p_opt == FindOption::RegularExpression) { - m_regularExpressionCheck->setChecked(p_enabled); - } else if (p_opt == FindOption::IncrementalSearch) { - m_incrementalSearchCheck->setChecked(p_enabled); - } else { - Q_ASSERT(false); - } -} - -void VFindReplaceDialog::findNext() -{ - QString text = m_findEdit->text(); - if (text.isEmpty()) { - return; - } - emit findNext(text, m_options, true); -} - -void VFindReplaceDialog::findPrevious() -{ - QString text = m_findEdit->text(); - if (text.isEmpty()) { - return; - } - emit findNext(text, m_options, false); -} - -void VFindReplaceDialog::replace() -{ - QString text = m_findEdit->text(); - if (text.isEmpty() || !m_replaceAvailable) { - return; - } - QString replaceText = m_replaceEdit->text(); - emit replace(text, m_options, replaceText, false); -} - -void VFindReplaceDialog::replaceFind() -{ - QString text = m_findEdit->text(); - if (text.isEmpty() || !m_replaceAvailable) { - return; - } - QString replaceText = m_replaceEdit->text(); - emit replace(text, m_options, replaceText, true); -} - -void VFindReplaceDialog::replaceAll() -{ - QString text = m_findEdit->text(); - if (text.isEmpty() || !m_replaceAvailable) { - return; - } - QString replaceText = m_replaceEdit->text(); - emit replaceAll(text, m_options, replaceText); -} - -void VFindReplaceDialog::updateState(DocType p_docType, bool p_editMode) -{ - if (p_editMode || p_docType == DocType::Html) { - m_wholeWordOnlyCheck->setEnabled(true); - m_regularExpressionCheck->setEnabled(true); - } else if (p_docType == DocType::Markdown) { - m_wholeWordOnlyCheck->setEnabled(false); - m_regularExpressionCheck->setEnabled(false); - } - - m_replaceAvailable = p_editMode; -} - -QString VFindReplaceDialog::textToFind() const -{ - return m_findEdit->text(); -} diff --git a/src/dialog/vfindreplacedialog.h b/src/dialog/vfindreplacedialog.h deleted file mode 100644 index 740839c2..00000000 --- a/src/dialog/vfindreplacedialog.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef VFINDREPLACEDIALOG_H -#define VFINDREPLACEDIALOG_H - -#include -#include -#include "vconstants.h" - -class VLineEdit; -class QPushButton; -class QCheckBox; - -class VFindReplaceDialog : public QWidget -{ - Q_OBJECT -public: - explicit VFindReplaceDialog(QWidget *p_parent = 0); - - uint options() const; - - void setOption(FindOption p_opt, bool p_enabled); - - // Update the options enabled/disabled state according to current - // edit tab. - void updateState(DocType p_docType, bool p_editMode); - - QString textToFind() const; - -signals: - void dialogClosed(); - void findTextChanged(const QString &p_text, uint p_options); - void findOptionChanged(uint p_options); - void findNext(const QString &p_text, uint p_options, bool p_forward); - void replace(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext); - void replaceAll(const QString &p_text, uint p_options, - const QString &p_replaceText); - -protected: - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - -public slots: - void closeDialog(); - void openDialog(QString p_text = ""); - void findNext(); - void findPrevious(); - void replace(); - void replaceFind(); - void replaceAll(); - -private slots: - void handleFindTextChanged(const QString &p_text); - void advancedBtnToggled(bool p_checked); - void optionBoxToggled(int p_state); - -private: - void setupUI(); - - // Bit OR of FindOption - uint m_options; - bool m_replaceAvailable; - - VLineEdit *m_findEdit; - VLineEdit *m_replaceEdit; - QPushButton *m_findNextBtn; - QPushButton *m_findPrevBtn; - QPushButton *m_replaceBtn; - QPushButton *m_replaceFindBtn; - QPushButton *m_replaceAllBtn; - QPushButton *m_advancedBtn; - QPushButton *m_closeBtn; - QCheckBox *m_caseSensitiveCheck; - QCheckBox *m_wholeWordOnlyCheck; - QCheckBox *m_regularExpressionCheck; - QCheckBox *m_incrementalSearchCheck; -}; - -inline uint VFindReplaceDialog::options() const -{ - return m_options; -} -#endif // VFINDREPLACEDIALOG_H diff --git a/src/dialog/vfixnotebookdialog.cpp b/src/dialog/vfixnotebookdialog.cpp deleted file mode 100644 index 9e75bc41..00000000 --- a/src/dialog/vfixnotebookdialog.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include "vfixnotebookdialog.h" - -#include - -#include "vconfigmanager.h" -#include "vlineedit.h" -#include "vnotebook.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VFixNotebookDialog::VFixNotebookDialog(const VNotebook *p_notebook, - const QVector &p_notebooks, - QWidget *p_parent) - : QDialog(p_parent), m_notebook(p_notebook), m_notebooks(p_notebooks) -{ - setupUI(); - - handleInputChanged(); -} - -void VFixNotebookDialog::setupUI() -{ - QLabel *infoLabel = new QLabel(tr("VNote could not find the root folder of notebook " - "%2. Please specify the new path " - "to the root folder if you moved it somewhere, or VNote " - "will just remove this notebook.") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getName()), this); - infoLabel->setWordWrap(true); - - QLabel *nameLabel = new QLabel(m_notebook->getName(), this); - - m_pathEdit = new VLineEdit(m_notebook->getPath(), this); - connect(m_pathEdit, &VLineEdit::textChanged, - this, &VFixNotebookDialog::handleInputChanged); - - m_browseBtn = new QPushButton(tr("&Browse"), this); - connect(m_browseBtn, &QPushButton::clicked, - this, &VFixNotebookDialog::handleBrowseBtnClicked); - - m_relativePathCB = new QCheckBox(tr("Use relative path"), this); - m_relativePathCB->setToolTip(tr("Use relative path (to VNote's executable) in configuration file")); - m_relativePathCB->setChecked(!QDir::isAbsolutePath(m_notebook->getPathInConfig())); - connect(m_relativePathCB, &QCheckBox::stateChanged, - this, &VFixNotebookDialog::handleInputChanged); - - QHBoxLayout *pathLayout = new QHBoxLayout(); - pathLayout->addWidget(m_pathEdit); - pathLayout->addWidget(m_browseBtn); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Notebook name:"), nameLabel); - topLayout->addRow(tr("Notebook root folder:"), pathLayout); - topLayout->addRow(m_relativePathCB); - - // Warning label. - m_warnLabel = new QLabel(this); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(infoLabel); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(tr("Fix Notebook")); -} - -void VFixNotebookDialog::handleBrowseBtnClicked() -{ - static QString defaultPath; - - if (defaultPath.isEmpty()) { - defaultPath = g_config->getVnoteNotebookFolderPath(); - if (!QFileInfo::exists(defaultPath)) { - defaultPath = g_config->getDocumentPathOrHomePath(); - } - } - - QString dirPath = QFileDialog::getExistingDirectory(this, - tr("Select Root Folder Of The Notebook"), - defaultPath, - QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - - if (!dirPath.isEmpty()) { - if (m_pathEdit->text() == dirPath) { - handleInputChanged(); - } else { - m_pathEdit->setText(dirPath); - } - - defaultPath = VUtils::basePathFromPath(dirPath); - } -} - -void VFixNotebookDialog::handleInputChanged() -{ - QString warnText = tr("WARNING: The folder chosen is NOT a valid root " - "folder of a notebook.") - .arg(g_config->c_warningTextStyle); - bool pathOk = false; - - QString path = m_pathEdit->text(); - if (!path.isEmpty()) { - if (!QDir::isAbsolutePath(path)) { - QString tmp = tr("WARNING: Please specify absolute path.") - .arg(g_config->c_warningTextStyle); - m_warnLabel->setText(tmp); - } else if (VConfigManager::directoryConfigExist(path)) { - pathOk = true; - } - } - - if (pathOk) { - // Check if this path has been in VNote. - int idx = -1; - for (idx = 0; idx < m_notebooks.size(); ++idx) { - if (m_notebooks[idx] != m_notebook - && VUtils::equalPath(m_notebooks[idx]->getPath(), path)) { - break; - } - } - - if (idx < m_notebooks.size()) { - pathOk = false; - QString existText = tr("WARNING: The folder chosen has already been a root folder " - "of existing notebook %3 in VNote.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(m_notebooks[idx]->getName()); - m_warnLabel->setText(existText); - } - } else { - m_warnLabel->setText(warnText); - } - - if (pathOk && isUseRelativePath()) { - if (!VUtils::inSameDrive(QCoreApplication::applicationDirPath(), path)) { - pathOk = false; - QString existText = tr("WARNING: Please choose a folder in the same drive as " - "%3 when relative path is enabled.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(QCoreApplication::applicationDirPath()); - m_warnLabel->setText(existText); - } - } - - m_warnLabel->setVisible(!pathOk); - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(pathOk); -} - -QString VFixNotebookDialog::getPathInput() const -{ - // absoluteFilePath() to convert the drive to upper case. - // cleanPath() to remove duplicate separator, '.', and '..'. - QString ret; - if (isUseRelativePath()) { - // Use relative path in config file. - QDir appDir(QCoreApplication::applicationDirPath()); - ret = QDir::cleanPath(appDir.relativeFilePath(m_pathEdit->text())); - } else { - ret = QDir::cleanPath(QFileInfo(m_pathEdit->text()).absoluteFilePath()); - } - - return ret; -} - -bool VFixNotebookDialog::isUseRelativePath() const -{ - return m_relativePathCB->isChecked(); -} diff --git a/src/dialog/vfixnotebookdialog.h b/src/dialog/vfixnotebookdialog.h deleted file mode 100644 index 6d348afe..00000000 --- a/src/dialog/vfixnotebookdialog.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef VFIXNOTEBOOKDIALOG_H -#define VFIXNOTEBOOKDIALOG_H - -#include - -class VNotebook; -class VLineEdit; -class QLabel; -class QPushButton; -class QDialogButtonBox; -class QCheckBox; - -class VFixNotebookDialog : public QDialog -{ - Q_OBJECT -public: - VFixNotebookDialog(const VNotebook *p_notebook, - const QVector &p_notebooks, - QWidget *p_parent = nullptr); - - QString getPathInput() const; - -private slots: - void handleBrowseBtnClicked(); - - void handleInputChanged(); - -private: - void setupUI(); - - // Whether relative path will be used in config file. - bool isUseRelativePath() const; - - const VNotebook *m_notebook; - - const QVector &m_notebooks; - - VLineEdit *m_pathEdit; - - QPushButton *m_browseBtn; - - QCheckBox *m_relativePathCB; - - QLabel *m_warnLabel; - - QDialogButtonBox *m_btnBox; -}; - -#endif // VFIXNOTEBOOKDIALOG_H diff --git a/src/dialog/vinsertimagedialog.cpp b/src/dialog/vinsertimagedialog.cpp deleted file mode 100644 index 4d3c0511..00000000 --- a/src/dialog/vinsertimagedialog.cpp +++ /dev/null @@ -1,377 +0,0 @@ -#include -#include -#include - -#include "vinsertimagedialog.h" -#include "utils/vutils.h" -#include "vmetawordlineedit.h" -#include "vdownloader.h" -#include "vlineedit.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VInsertImageDialog::VInsertImageDialog(const QString &p_title, - const QString &p_imageTitle, - const QString &p_imagePath, - bool p_browsable, - QWidget *p_parent) - : QDialog(p_parent), - m_browsable(p_browsable) -{ - setupUI(p_title, p_imageTitle, p_imagePath); - - connect(m_imageTitleEdit, &VMetaWordLineEdit::textChanged, - this, &VInsertImageDialog::handleInputChanged); - - if (m_browsable) { - connect(m_pathEdit, &VLineEdit::editingFinished, - this, &VInsertImageDialog::handlePathEditChanged); - - connect(browseBtn, &QPushButton::clicked, - this, &VInsertImageDialog::handleBrowseBtnClicked); - - fetchImageFromClipboard(); - } - - autoCompleteTitleFromPath(); - - handleInputChanged(); -} - -void VInsertImageDialog::setupUI(const QString &p_title, - const QString &p_imageTitle, - const QString &p_imagePath) -{ - // Path. - m_pathEdit = new VLineEdit(p_imagePath); - m_pathEdit->setReadOnly(!m_browsable); - browseBtn = new QPushButton(tr("&Browse")); - browseBtn->setEnabled(m_browsable); - - // Title. - m_imageTitleEdit = new VMetaWordLineEdit(p_imageTitle); - m_imageTitleEdit->selectAll(); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_imageTitleRegExp), - m_imageTitleEdit); - m_imageTitleEdit->setValidator(validator); - - // Scale. - m_widthSpin = new QSpinBox(); - m_widthSpin->setMinimum(1); - m_widthSpin->setSingleStep(10); - m_widthSpin->setSuffix(" px"); - connect(m_widthSpin, static_cast(&QSpinBox::valueChanged), - this, [this](int p_val) { - if (!m_image) { - return; - } - - int height = m_image->height() * (1.0 * p_val / m_image->width()); - m_imageLabel->resize(p_val, height); - }); - - // 0.1 to 2.0 -> 1 to 20. - m_scaleSlider = new QSlider(); - m_scaleSlider->setOrientation(Qt::Horizontal); - m_scaleSlider->setMinimum(1); - m_scaleSlider->setMaximum(20); - m_scaleSlider->setValue(10); - m_scaleSlider->setSingleStep(1); - m_scaleSlider->setPageStep(5); - connect(m_scaleSlider, &QSlider::valueChanged, - this, [this](int p_val) { - if (!m_image) { - return; - } - - int width = m_image->width(); - qreal factor = 1.0; - if (p_val != 10) { - factor = p_val / 10.0; - width = m_image->width() * factor; - } - - m_widthSpin->setValue(width); - m_sliderLabel->setText(QString::number(factor) + "x"); - }); - - m_sliderLabel = new QLabel("1x"); - - QGridLayout *topLayout = new QGridLayout(); - topLayout->addWidget(new QLabel(tr("From:")), 0, 0, 1, 1); - topLayout->addWidget(m_pathEdit, 0, 1, 1, 3); - topLayout->addWidget(browseBtn, 0, 4, 1, 1); - topLayout->addWidget(new QLabel(tr("Title:")), 1, 0, 1, 1); - topLayout->addWidget(m_imageTitleEdit, 1, 1, 1, 4); - topLayout->addWidget(new QLabel(tr("Scaling width:")), 2, 0, 1, 1); - topLayout->addWidget(m_widthSpin, 2, 1, 1, 1); - topLayout->addWidget(m_scaleSlider, 2, 2, 1, 2); - topLayout->addWidget(m_sliderLabel, 2, 4, 1, 1); - - topLayout->setColumnStretch(0, 0); - topLayout->setColumnStretch(1, 0); - topLayout->setColumnStretch(2, 1); - topLayout->setColumnStretch(3, 1); - topLayout->setColumnStretch(4, 0); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - - m_imageLabel = new QLabel(); - m_imageLabel->setScaledContents(true); - - m_previewArea = new QScrollArea(); - m_previewArea->setBackgroundRole(QPalette::Dark); - m_previewArea->setWidget(m_imageLabel); - int minWidth = 512 * VUtils::calculateScaleFactor(); - m_previewArea->setMinimumSize(minWidth, minWidth); - - setImageControlsVisible(false); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_btnBox); - mainLayout->addWidget(m_previewArea); - setLayout(mainLayout); - - setWindowTitle(p_title); - - m_imageTitleEdit->setFocus(); -} - -void VInsertImageDialog::handleInputChanged() -{ - QString title = m_imageTitleEdit->getEvaluatedText(); - QRegExp reg(VUtils::c_imageTitleRegExp); - bool titleOk = reg.exactMatch(title); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(titleOk && m_image); -} - -QString VInsertImageDialog::getImageTitleInput() const -{ - return m_imageTitleEdit->getEvaluatedText(); -} - -QString VInsertImageDialog::getPathInput() const -{ - if (m_tempFile.isNull()) { - return m_pathEdit->text(); - } else { - return m_tempFile->fileName(); - } -} - -void VInsertImageDialog::handleBrowseBtnClicked() -{ - QString bpath(m_browsePath); - if (bpath.isEmpty()) { - bpath = g_config->getImageBrowsePath(); - if (bpath.isEmpty()) { - bpath = QDir::homePath(); - } - } - - QString filePath = QFileDialog::getOpenFileName(this, tr("Select The Image To Be Inserted"), - bpath, tr("Images (*.png *.xpm *.jpg *.bmp *.gif *.svg)")); - if (filePath.isEmpty()) { - return; - } - - // Update browse path. - g_config->setImageBrowsePath(QFileInfo(filePath).path()); - - m_imageType = ImageType::LocalFile; - - setPath(filePath); - - autoCompleteTitleFromPath(); - - m_imageTitleEdit->setFocus(); -} - -void VInsertImageDialog::setImage(const QImage &p_image) -{ - if (p_image.isNull()) { - m_image.clear(); - m_imageLabel->clear(); - - setImageControlsVisible(false); - } else { - m_image.reset(new QImage(p_image)); - - m_imageLabel->setPixmap(QPixmap::fromImage(*m_image)); - - m_imageLabel->adjustSize(); - - // Set the scaling widgets. - m_scaleSlider->setValue(10); - - int width = m_image->width(); - m_widthSpin->setMaximum(width * 5); - m_widthSpin->setValue(width); - - setImageControlsVisible(true); - } - - handleInputChanged(); -} - -void VInsertImageDialog::imageDownloaded(const QByteArray &data) -{ - setImage(QImage::fromData(data)); - - // Try to save it to a temp file. - { - if (data.isEmpty()) { - goto image_data; - } - - QString format = QFileInfo(VUtils::purifyUrl(getPathInput())).suffix(); - if (format.isEmpty()) { - goto image_data; - } - - m_tempFile.reset(VUtils::createTemporaryFile(format)); - if (!m_tempFile->open()) { - goto image_data; - } - - if (m_tempFile->write(data) == -1) { - goto image_data; - } - - m_imageType = ImageType::LocalFile; - m_tempFile->close(); - return; - } - -image_data: - m_tempFile.clear(); - m_imageType = ImageType::ImageData; -} - -QImage VInsertImageDialog::getImage() const -{ - if (!m_image) { - return QImage(); - } else return *m_image; -} - -void VInsertImageDialog::fetchImageFromClipboard() -{ - if (!m_browsable || !m_pathEdit->text().isEmpty()) { - return; - } - - Q_ASSERT(!m_image); - - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - - QUrl url; - - if (mimeData->hasImage()) { - QImage im = qvariant_cast(mimeData->imageData()); - if (im.isNull()) { - return; - } - - setImage(im); - m_imageType = ImageType::ImageData; - return; - } else if (mimeData->hasUrls()) { - QList urls = mimeData->urls(); - if (urls.size() != 1) { - return; - } - - url = urls[0]; - } else if (mimeData->hasText()) { - url = QUrl(mimeData->text()); - } - - if (url.isValid()) { - if (url.isLocalFile()) { - setPath(url.toLocalFile()); - } else { - setPath(url.toString()); - } - } -} - -void VInsertImageDialog::handlePathEditChanged() -{ - QString text = m_pathEdit->text(); - QUrl url = QUrl::fromUserInput(text); - if (text.isEmpty() || !url.isValid()) { - setImage(QImage()); - return; - } - - QImage image; - if (url.isLocalFile()) { - image = VUtils::imageFromFile(url.toLocalFile()); - setImage(image); - m_imageType = ImageType::LocalFile; - } else { - setImage(QImage()); - m_imageType = ImageType::ImageData; - VDownloader *downloader = new VDownloader(this); - connect(downloader, &VDownloader::downloadFinished, - this, &VInsertImageDialog::imageDownloaded); - downloader->download(url.toString()); - } - - handleInputChanged(); -} - -void VInsertImageDialog::setPath(const QString &p_path) -{ - m_pathEdit->setText(p_path); - handlePathEditChanged(); -} - -void VInsertImageDialog::setImageControlsVisible(bool p_visible) -{ - m_widthSpin->setEnabled(p_visible); - m_scaleSlider->setEnabled(p_visible); - m_sliderLabel->setEnabled(p_visible); - - m_previewArea->setVisible(p_visible); -} - -int VInsertImageDialog::getOverridenWidth() const -{ - int width = m_widthSpin->value(); - if (m_image && m_image->width() != width) { - return width; - } - - return 0; -} - -void VInsertImageDialog::autoCompleteTitleFromPath() -{ - if (!m_imageTitleEdit->text().isEmpty()) { - return; - } - - QString imgPath = m_pathEdit->text(); - if (imgPath.isEmpty()) { - return; - } - - m_imageTitleEdit->setText(QFileInfo(imgPath).baseName()); - m_imageTitleEdit->selectAll(); -} - -void VInsertImageDialog::setBrowsePath(const QString &p_path) -{ - m_browsePath = p_path; -} diff --git a/src/dialog/vinsertimagedialog.h b/src/dialog/vinsertimagedialog.h deleted file mode 100644 index ec7f65e3..00000000 --- a/src/dialog/vinsertimagedialog.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef VINSERTIMAGEDIALOG_H -#define VINSERTIMAGEDIALOG_H - -#include -#include -#include -#include -#include -#include - -class QLabel; -class VLineEdit; -class VMetaWordLineEdit; -class QPushButton; -class QDialogButtonBox; -class QScrollArea; -class QSpinBox; -class QSlider; - -class VInsertImageDialog : public QDialog -{ - Q_OBJECT -public: - enum ImageType - { - LocalFile = 0, - ImageData - }; - - VInsertImageDialog(const QString &p_title, - const QString &p_imageTitle, - const QString &p_imagePath, - bool p_browsable = true, - QWidget *p_parent = nullptr); - - QString getImageTitleInput() const; - - QString getPathInput() const; - - void setImage(const QImage &p_image); - - QImage getImage() const; - - VInsertImageDialog::ImageType getImageType() const; - - // Return 0 if no override. - int getOverridenWidth() const; - - void setBrowsePath(const QString &p_path); - -public slots: - void imageDownloaded(const QByteArray &data); - -private slots: - void handleInputChanged(); - - void handleBrowseBtnClicked(); - - void handlePathEditChanged(); - -private: - void setupUI(const QString &p_title, - const QString &p_imageTitle, - const QString &p_imagePath); - - void fetchImageFromClipboard(); - - void setPath(const QString &p_path); - - void setImageControlsVisible(bool p_visible); - - void autoCompleteTitleFromPath(); - - VMetaWordLineEdit *m_imageTitleEdit; - VLineEdit *m_pathEdit; - QPushButton *browseBtn; - - QSpinBox *m_widthSpin; - QSlider *m_scaleSlider; - QLabel *m_sliderLabel; - - QDialogButtonBox *m_btnBox; - - QLabel *m_imageLabel; - QScrollArea *m_previewArea; - - QSharedPointer m_image; - - // Whether enable the browse action. - bool m_browsable; - - ImageType m_imageType; - - QSharedPointer m_tempFile; - - // Default path when browsing images to insert. - QString m_browsePath; -}; - -inline VInsertImageDialog::ImageType VInsertImageDialog::getImageType() const -{ - return m_imageType; -} - -#endif // VINSERTIMAGEDIALOG_H diff --git a/src/dialog/vinsertlinkdialog.cpp b/src/dialog/vinsertlinkdialog.cpp deleted file mode 100644 index c3ca4a61..00000000 --- a/src/dialog/vinsertlinkdialog.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include "vinsertlinkdialog.h" - -#include - -#include "vmetawordlineedit.h" - -VInsertLinkDialog::VInsertLinkDialog(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QString &p_linkText, - const QString &p_linkUrl, - bool p_linkTextEmptyAllowed, - QWidget *p_parent) - : QDialog(p_parent), - m_linkTextEmptyAllowed(p_linkTextEmptyAllowed) -{ - setupUI(p_title, p_text, p_info, p_linkText, p_linkUrl); - - fetchLinkFromClipboard(); - - handleInputChanged(); -} - -void VInsertLinkDialog::setupUI(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QString &p_linkText, - const QString &p_linkUrl) -{ - QLabel *textLabel = NULL; - if (!p_text.isEmpty()) { - textLabel = new QLabel(p_text); - textLabel->setWordWrap(true); - } - - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - m_linkTextEdit = new VMetaWordLineEdit(p_linkText); - m_linkTextEdit->selectAll(); - - m_linkUrlEdit = new VLineEdit(p_linkUrl); - m_linkUrlEdit->setToolTip(tr("Absolute or relative path of the link")); - - QFormLayout *inputLayout = new QFormLayout(); - inputLayout->addRow(tr("&Text:"), m_linkTextEdit); - inputLayout->addRow(tr("&URL:"), m_linkUrlEdit); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_linkTextEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout; - if (textLabel) { - mainLayout->addWidget(textLabel); - } - - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(inputLayout); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - setWindowTitle(p_title); - - connect(m_linkTextEdit, &VMetaWordLineEdit::textChanged, - this, &VInsertLinkDialog::handleInputChanged); - connect(m_linkUrlEdit, &VLineEdit::textChanged, - this, &VInsertLinkDialog::handleInputChanged); -} - -void VInsertLinkDialog::handleInputChanged() -{ - bool textOk = true; - if (m_linkTextEdit->getEvaluatedText().isEmpty() - && !m_linkTextEmptyAllowed) { - textOk = false; - } - - bool urlOk = true; - if (m_linkUrlEdit->text().isEmpty()) { - urlOk = false; - } - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(textOk && urlOk); -} - -void VInsertLinkDialog::fetchLinkFromClipboard() -{ - if (!m_linkUrlEdit->text().isEmpty() - || !m_linkTextEdit->text().isEmpty()) { - return; - } - - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - - if (!mimeData->hasText()) { - return; - } - - QString text = mimeData->text(); - text = text.trimmed(); - if (text.isEmpty()) { - return; - } - - QUrl url = QUrl::fromUserInput(text); - if (url.isValid()) { - if (m_linkUrlEdit->text().isEmpty()) { - if (url.isLocalFile()) { - m_linkUrlEdit->setText(url.toString(QUrl::EncodeSpaces)); - } else { - m_linkUrlEdit->setText(text); - } - } - } else if (m_linkTextEdit->text().isEmpty()) { - m_linkTextEdit->setText(text); - } -} - -QString VInsertLinkDialog::getLinkText() const -{ - return m_linkTextEdit->getEvaluatedText(); -} - -QString VInsertLinkDialog::getLinkUrl() const -{ - return m_linkUrlEdit->text(); -} - -void VInsertLinkDialog::showEvent(QShowEvent *p_event) -{ - QDialog::showEvent(p_event); - - if (!m_linkTextEdit->text().isEmpty() && m_linkUrlEdit->text().isEmpty()) { - m_linkUrlEdit->setFocus(); - } -} diff --git a/src/dialog/vinsertlinkdialog.h b/src/dialog/vinsertlinkdialog.h deleted file mode 100644 index 633289e1..00000000 --- a/src/dialog/vinsertlinkdialog.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef VINSERTLINKDIALOG_H -#define VINSERTLINKDIALOG_H - -#include -#include - -class VMetaWordLineEdit; -class VLineEdit; -class QDialogButtonBox; -class QShowEvent; - -class VInsertLinkDialog : public QDialog -{ - Q_OBJECT -public: - VInsertLinkDialog(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QString &p_linkText, - const QString &p_linkUrl, - bool p_linkTextEmptyAllowed, - QWidget *p_parent = nullptr); - - QString getLinkText() const; - - QString getLinkUrl() const; - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void handleInputChanged(); - -private: - void setupUI(const QString &p_title, - const QString &p_text, - const QString &p_info, - const QString &p_linkText, - const QString &p_linkUrl); - - // Infer link text/url from clipboard only when text and url are both empty. - void fetchLinkFromClipboard(); - - VMetaWordLineEdit *m_linkTextEdit; - - VLineEdit *m_linkUrlEdit; - - QDialogButtonBox *m_btnBox; - - bool m_linkTextEmptyAllowed; -}; - -#endif // VINSERTLINKDIALOG_H diff --git a/src/dialog/vinserttabledialog.cpp b/src/dialog/vinserttabledialog.cpp deleted file mode 100644 index 0d20612c..00000000 --- a/src/dialog/vinserttabledialog.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "vinserttabledialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -VInsertTableDialog::VInsertTableDialog(QWidget *p_parent) - : QDialog(p_parent), - m_alignment(VTable::None) -{ - setupUI(); -} - -void VInsertTableDialog::setupUI() -{ - m_rowCount = new QSpinBox(this); - m_rowCount->setToolTip(tr("Number of rows of the table body")); - m_rowCount->setMaximum(1000); - m_rowCount->setMinimum(0); - - m_colCount = new QSpinBox(this); - m_colCount->setToolTip(tr("Number of columns of the table")); - m_colCount->setMaximum(1000); - m_colCount->setMinimum(1); - - QRadioButton *noneBtn = new QRadioButton(tr("None"), this); - QRadioButton *leftBtn = new QRadioButton(tr("Left"), this); - QRadioButton *centerBtn = new QRadioButton(tr("Center"), this); - QRadioButton *rightBtn = new QRadioButton(tr("Right"), this); - QHBoxLayout *alignLayout = new QHBoxLayout(); - alignLayout->addWidget(noneBtn); - alignLayout->addWidget(leftBtn); - alignLayout->addWidget(centerBtn); - alignLayout->addWidget(rightBtn); - alignLayout->addStretch(); - - noneBtn->setChecked(true); - - QButtonGroup *bg = new QButtonGroup(this); - bg->addButton(noneBtn, VTable::None); - bg->addButton(leftBtn, VTable::Left); - bg->addButton(centerBtn, VTable::Center); - bg->addButton(rightBtn, VTable::Right); - connect(bg, static_cast(&QButtonGroup::buttonToggled), - this, [this](int p_id, bool p_checked){ - if (p_checked) { - m_alignment = static_cast(p_id); - } - }); - - QGridLayout *topLayout = new QGridLayout(); - topLayout->addWidget(new QLabel(tr("Row:")), 0, 0, 1, 1); - topLayout->addWidget(m_rowCount, 0, 1, 1, 1); - topLayout->addWidget(new QLabel(tr("Column:")), 0, 2, 1, 1); - topLayout->addWidget(m_colCount, 0, 3, 1, 1); - - topLayout->addWidget(new QLabel(tr("Alignment:")), 1, 0, 1, 1); - topLayout->addLayout(alignLayout, 1, 1, 1, 3); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - setWindowTitle(tr("Insert Table")); -} - -int VInsertTableDialog::getRowCount() const -{ - return m_rowCount->value(); -} - -int VInsertTableDialog::getColumnCount() const -{ - return m_colCount->value(); -} - -VTable::Alignment VInsertTableDialog::getAlignment() const -{ - return m_alignment; -} diff --git a/src/dialog/vinserttabledialog.h b/src/dialog/vinserttabledialog.h deleted file mode 100644 index 6b4fa9d0..00000000 --- a/src/dialog/vinserttabledialog.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef VINSERTTABLEDIALOG_H -#define VINSERTTABLEDIALOG_H - -#include - -#include "../vtable.h" - -class QDialogButtonBox; -class QSpinBox; - -class VInsertTableDialog : public QDialog -{ - Q_OBJECT -public: - explicit VInsertTableDialog(QWidget *p_parent = nullptr); - - int getRowCount() const; - int getColumnCount() const; - VTable::Alignment getAlignment() const; - -private: - void setupUI(); - - QSpinBox *m_rowCount; - QSpinBox *m_colCount; - - QDialogButtonBox *m_btnBox; - - VTable::Alignment m_alignment; -}; - -#endif // VINSERTTABLEDIALOG_H diff --git a/src/dialog/vkeyboardlayoutmappingdialog.cpp b/src/dialog/vkeyboardlayoutmappingdialog.cpp deleted file mode 100644 index ec1a6a51..00000000 --- a/src/dialog/vkeyboardlayoutmappingdialog.cpp +++ /dev/null @@ -1,497 +0,0 @@ -#include "vkeyboardlayoutmappingdialog.h" - -#include - -#include "vlineedit.h" -#include "utils/vkeyboardlayoutmanager.h" -#include "utils/vutils.h" -#include "utils/viconutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VKeyboardLayoutMappingDialog::VKeyboardLayoutMappingDialog(QWidget *p_parent) - : QDialog(p_parent), - m_mappingModified(false), - m_listenIndex(-1) -{ - setupUI(); - - loadAvailableMappings(); -} - -void VKeyboardLayoutMappingDialog::setupUI() -{ - QString info = tr("Manage keybaord layout mappings to used in shortcuts."); - info += "\n"; - info += tr("Double click an item to set mapping key."); - QLabel *infoLabel = new QLabel(info, this); - - // Selector. - m_selectorCombo = VUtils::getComboBox(this); - connect(m_selectorCombo, static_cast(&QComboBox::currentIndexChanged), - this, [this](int p_idx) { - loadMappingInfo(m_selectorCombo->itemData(p_idx).toString()); - }); - - // Add. - m_addBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/add.svg"), "", this); - m_addBtn->setToolTip(tr("New Mapping")); - m_addBtn->setProperty("FlatBtn", true); - connect(m_addBtn, &QPushButton::clicked, - this, &VKeyboardLayoutMappingDialog::newMapping); - - // Delete. - m_deleteBtn = new QPushButton(VIconUtils::buttonDangerIcon(":/resources/icons/delete.svg"), - "", - this); - m_deleteBtn->setToolTip(tr("Delete Mapping")); - m_deleteBtn->setProperty("FlatBtn", true); - connect(m_deleteBtn, &QPushButton::clicked, - this, &VKeyboardLayoutMappingDialog::deleteCurrentMapping); - - QHBoxLayout *selectLayout = new QHBoxLayout(); - selectLayout->addWidget(new QLabel(tr("Keyboard layout mapping:"), this)); - selectLayout->addWidget(m_selectorCombo); - selectLayout->addWidget(m_addBtn); - selectLayout->addWidget(m_deleteBtn); - selectLayout->addStretch(); - - // Name. - m_nameEdit = new VLineEdit(this); - connect(m_nameEdit, &QLineEdit::textEdited, - this, [this](const QString &p_text) { - Q_UNUSED(p_text); - setModified(true); - }); - - QHBoxLayout *editLayout = new QHBoxLayout(); - editLayout->addWidget(new QLabel(tr("Name:"), this)); - editLayout->addWidget(m_nameEdit); - editLayout->addStretch(); - - // Tree. - m_contentTree = new QTreeWidget(this); - m_contentTree->setProperty("ItemBorder", true); - m_contentTree->setRootIsDecorated(false); - m_contentTree->setColumnCount(2); - m_contentTree->setSelectionBehavior(QAbstractItemView::SelectRows); - QStringList headers; - headers << tr("Key") << tr("New Key"); - m_contentTree->setHeaderLabels(headers); - - m_contentTree->installEventFilter(this); - - connect(m_contentTree, &QTreeWidget::itemDoubleClicked, - this, [this](QTreeWidgetItem *p_item, int p_column) { - Q_UNUSED(p_column); - int idx = m_contentTree->indexOfTopLevelItem(p_item); - if (m_listenIndex == -1) { - // Listen key for this item. - setListeningKey(idx); - } else if (idx == m_listenIndex) { - // Cancel listening key for this item. - cancelListeningKey(); - } else { - // Recover previous item. - cancelListeningKey(); - setListeningKey(idx); - } - }); - - connect(m_contentTree, &QTreeWidget::itemClicked, - this, [this](QTreeWidgetItem *p_item, int p_column) { - Q_UNUSED(p_column); - int idx = m_contentTree->indexOfTopLevelItem(p_item); - if (idx != m_listenIndex) { - cancelListeningKey(); - } - }); - - QVBoxLayout *infoLayout = new QVBoxLayout(); - infoLayout->addLayout(editLayout); - infoLayout->addWidget(m_contentTree); - - QGroupBox *box = new QGroupBox(tr("Mapping Information")); - box->setLayout(infoLayout); - - // Ok is the default button. - QDialogButtonBox *btnBox = new QDialogButtonBox(QDialogButtonBox::Ok - | QDialogButtonBox::Apply - | QDialogButtonBox::Cancel); - connect(btnBox, &QDialogButtonBox::accepted, - this, [this]() { - if (applyChanges()) { - QDialog::accept(); - } - }); - connect(btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - - m_applyBtn = btnBox->button(QDialogButtonBox::Apply); - connect(m_applyBtn, &QPushButton::clicked, - this, &VKeyboardLayoutMappingDialog::applyChanges); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(infoLabel); - mainLayout->addLayout(selectLayout); - mainLayout->addWidget(box); - mainLayout->addWidget(btnBox); - - setLayout(mainLayout); - - setWindowTitle(tr("Keyboard Layout Mappings")); -} - -void VKeyboardLayoutMappingDialog::newMapping() -{ - QString name = getNewMappingName(); - if (!VKeyboardLayoutManager::addLayout(name)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to add mapping %2.") - .arg(g_config->c_dataTextStyle) - .arg(name), - tr("Please check the configuration file and try again."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - loadAvailableMappings(); - - setCurrentMapping(name); -} - -QString VKeyboardLayoutMappingDialog::getNewMappingName() const -{ - QString name; - QString baseName("layout_mapping"); - int seq = 1; - do { - name = QString("%1_%2").arg(baseName).arg(QString::number(seq++), 3, '0'); - } while (m_selectorCombo->findData(name) != -1); - - return name; -} - -void VKeyboardLayoutMappingDialog::deleteCurrentMapping() -{ - QString mapping = currentMapping(); - if (mapping.isEmpty()) { - return; - } - - int ret = VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Are you sure to delete mapping %2?") - .arg(g_config->c_dataTextStyle) - .arg(mapping), - "", - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - this); - if (ret != QMessageBox::Ok) { - return; - } - - if (!VKeyboardLayoutManager::removeLayout(mapping)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete mapping %2.") - .arg(g_config->c_dataTextStyle) - .arg(mapping), - tr("Please check the configuration file and try again."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - loadAvailableMappings(); -} - -void VKeyboardLayoutMappingDialog::loadAvailableMappings() -{ - m_selectorCombo->setCurrentIndex(-1); - m_selectorCombo->clear(); - - QStringList layouts = VKeyboardLayoutManager::availableLayouts(); - for (auto const & layout : layouts) { - m_selectorCombo->addItem(layout, layout); - } - - if (m_selectorCombo->count() > 0) { - m_selectorCombo->setCurrentIndex(0); - } -} - -static QList keysNeededToMap() -{ - QList keys; - - for (int i = Qt::Key_0; i <= Qt::Key_9; ++i) { - keys.append(i); - } - - for (int i = Qt::Key_A; i <= Qt::Key_Z; ++i) { - keys.append(i); - } - - QList addi = g_config->getKeyboardLayoutMappingKeys(); - for (auto tmp : addi) { - if (!keys.contains(tmp)) { - keys.append(tmp); - } - } - - return keys; -} - -static void recoverTreeItem(QTreeWidgetItem *p_item) -{ - int key = p_item->data(0, Qt::UserRole).toInt(); - QString text0 = QString("%1 (%2)").arg(VUtils::keyToChar(key, false)) - .arg(key); - p_item->setText(0, text0); - - int newKey = p_item->data(1, Qt::UserRole).toInt(); - QString text1; - if (newKey > 0) { - text1 = QString("%1 (%2)").arg(VUtils::keyToChar(newKey, false)) - .arg(newKey); - } - - p_item->setText(1, text1); -} - -// @p_newKey, 0 if there is no mapping. -static void fillTreeItem(QTreeWidgetItem *p_item, int p_key, int p_newKey) -{ - p_item->setData(0, Qt::UserRole, p_key); - p_item->setData(1, Qt::UserRole, p_newKey); - recoverTreeItem(p_item); -} - -static void setTreeItemMapping(QTreeWidgetItem *p_item, int p_newKey) -{ - p_item->setData(1, Qt::UserRole, p_newKey); -} - -static void fillMappingTree(QTreeWidget *p_tree, const QHash &p_mappings) -{ - QList keys = keysNeededToMap(); - - for (auto key : keys) { - int val = 0; - auto it = p_mappings.find(key); - if (it != p_mappings.end()) { - val = it.value(); - } - - QTreeWidgetItem *item = new QTreeWidgetItem(p_tree); - fillTreeItem(item, key, val); - } -} - -static QHash retrieveMappingFromTree(QTreeWidget *p_tree) -{ - QHash mappings; - int cnt = p_tree->topLevelItemCount(); - for (int i = 0; i < cnt; ++i) { - QTreeWidgetItem *item = p_tree->topLevelItem(i); - int key = item->data(0, Qt::UserRole).toInt(); - int newKey = item->data(1, Qt::UserRole).toInt(); - if (newKey > 0) { - mappings.insert(key, newKey); - } - } - - return mappings; -} - -void VKeyboardLayoutMappingDialog::loadMappingInfo(const QString &p_layout) -{ - setModified(false); - - if (p_layout.isEmpty()) { - m_nameEdit->clear(); - m_contentTree->clear(); - m_nameEdit->setEnabled(false); - m_contentTree->setEnabled(false); - return; - } - - m_nameEdit->setText(p_layout); - m_nameEdit->setEnabled(true); - - m_contentTree->clear(); - if (!p_layout.isEmpty()) { - auto mappings = VKeyboardLayoutManager::readLayoutMapping(p_layout); - fillMappingTree(m_contentTree, mappings); - } - m_contentTree->setEnabled(true); -} - -void VKeyboardLayoutMappingDialog::updateButtons() -{ - QString mapping = currentMapping(); - - m_deleteBtn->setEnabled(!mapping.isEmpty()); - m_applyBtn->setEnabled(m_mappingModified); -} - -QString VKeyboardLayoutMappingDialog::currentMapping() const -{ - return m_selectorCombo->currentData().toString(); -} - -void VKeyboardLayoutMappingDialog::setCurrentMapping(const QString &p_layout) -{ - return m_selectorCombo->setCurrentIndex(m_selectorCombo->findData(p_layout)); -} - -bool VKeyboardLayoutMappingDialog::applyChanges() -{ - if (!m_mappingModified) { - return true; - } - - QString mapping = currentMapping(); - if (mapping.isEmpty()) { - setModified(false); - return true; - } - - // Check the name. - QString newName = m_nameEdit->text(); - if (newName.isEmpty() || newName.toLower() == "global") { - // Set back the original name. - m_nameEdit->setText(mapping); - m_nameEdit->selectAll(); - m_nameEdit->setFocus(); - return false; - } else if (newName != mapping) { - // Rename the mapping. - if (!VKeyboardLayoutManager::renameLayout(mapping, newName)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to rename mapping %2.") - .arg(g_config->c_dataTextStyle) - .arg(mapping), - tr("Please check the configuration file and try again."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - m_nameEdit->setText(mapping); - m_nameEdit->selectAll(); - m_nameEdit->setFocus(); - return false; - } - - // Update the combobox. - int idx = m_selectorCombo->currentIndex(); - m_selectorCombo->setItemText(idx, newName); - m_selectorCombo->setItemData(idx, newName); - - mapping = newName; - } - - // Check the mappings. - QHash mappings = retrieveMappingFromTree(m_contentTree); - if (!VKeyboardLayoutManager::updateLayout(mapping, mappings)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to update mapping %2.") - .arg(g_config->c_dataTextStyle) - .arg(mapping), - tr("Please check the configuration file and try again."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return false; - } - - setModified(false); - return true; -} - -bool VKeyboardLayoutMappingDialog::eventFilter(QObject *p_obj, QEvent *p_event) -{ - if (p_obj == m_contentTree) { - switch (p_event->type()) { - case QEvent::FocusOut: - cancelListeningKey(); - break; - - case QEvent::KeyPress: - if (listenKey(static_cast(p_event))) { - return true; - } - - break; - - default: - break; - } - } - - return QDialog::eventFilter(p_obj, p_event); -} - -bool VKeyboardLayoutMappingDialog::listenKey(QKeyEvent *p_event) -{ - if (m_listenIndex == -1) { - return false; - } - - int key = p_event->key(); - - if (VUtils::isMetaKey(key)) { - return false; - } - - if (key == Qt::Key_Escape) { - cancelListeningKey(); - return true; - } - - // Set the mapping. - QTreeWidgetItem *item = m_contentTree->topLevelItem(m_listenIndex); - setTreeItemMapping(item, key); - setModified(true); - - // Try next item automatically. - int nextIdx = m_listenIndex + 1; - cancelListeningKey(); - - if (nextIdx < m_contentTree->topLevelItemCount()) { - QTreeWidgetItem *item = m_contentTree->topLevelItem(nextIdx); - m_contentTree->clearSelection(); - m_contentTree->setCurrentItem(item); - - setListeningKey(nextIdx); - } - - return true; -} - -void VKeyboardLayoutMappingDialog::cancelListeningKey() -{ - if (m_listenIndex > -1) { - // Recover that item. - recoverTreeItem(m_contentTree->topLevelItem(m_listenIndex)); - - m_listenIndex = -1; - } -} - -void VKeyboardLayoutMappingDialog::setListeningKey(int p_idx) -{ - Q_ASSERT(m_listenIndex == -1 && p_idx > -1); - m_listenIndex = p_idx; - QTreeWidgetItem *item = m_contentTree->topLevelItem(m_listenIndex); - item->setText(1, tr("Press key to set mapping")); -} diff --git a/src/dialog/vkeyboardlayoutmappingdialog.h b/src/dialog/vkeyboardlayoutmappingdialog.h deleted file mode 100644 index fa219b08..00000000 --- a/src/dialog/vkeyboardlayoutmappingdialog.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef VKEYBOARDLAYOUTMAPPINGDIALOG_H -#define VKEYBOARDLAYOUTMAPPINGDIALOG_H - -#include - - -class QDialogButtonBox; -class QString; -class QTreeWidget; -class VLineEdit; -class QPushButton; -class QComboBox; - -class VKeyboardLayoutMappingDialog : public QDialog -{ - Q_OBJECT -public: - explicit VKeyboardLayoutMappingDialog(QWidget *p_parent = nullptr); - -protected: - bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void newMapping(); - - void deleteCurrentMapping(); - - // Return true if changes are saved. - bool applyChanges(); - -private: - void setupUI(); - - void loadAvailableMappings(); - - void loadMappingInfo(const QString &p_layout); - - void updateButtons(); - - QString currentMapping() const; - - void setCurrentMapping(const QString &p_layout); - - QString getNewMappingName() const; - - bool listenKey(QKeyEvent *p_event); - - void cancelListeningKey(); - - void setListeningKey(int p_idx); - - void setModified(bool p_modified); - - QComboBox *m_selectorCombo; - QPushButton *m_addBtn; - QPushButton *m_deleteBtn; - VLineEdit *m_nameEdit; - QTreeWidget *m_contentTree; - QPushButton *m_applyBtn; - - bool m_mappingModified; - - // Index of the item in the tree which is listening key. - // -1 for not listening. - int m_listenIndex; -}; - -inline void VKeyboardLayoutMappingDialog::setModified(bool p_modified) -{ - m_mappingModified = p_modified; - updateButtons(); -} -#endif // VKEYBOARDLAYOUTMAPPINGDIALOG_H diff --git a/src/dialog/vnewdirdialog.cpp b/src/dialog/vnewdirdialog.cpp deleted file mode 100644 index f0c778bc..00000000 --- a/src/dialog/vnewdirdialog.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include "vnewdirdialog.h" -#include "vdirectory.h" -#include "vconfigmanager.h" -#include "vmetawordlineedit.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VNewDirDialog::VNewDirDialog(const QString &title, - const QString &info, - const QString &defaultName, - VDirectory *directory, - QWidget *parent) - : QDialog(parent), title(title), info(info), defaultName(defaultName), - m_directory(directory) -{ - setupUI(); - - connect(m_nameEdit, &VMetaWordLineEdit::textChanged, this, &VNewDirDialog::handleInputChanged); - - handleInputChanged(); -} - -void VNewDirDialog::setupUI() -{ - QLabel *infoLabel = NULL; - if (!info.isEmpty()) { - infoLabel = new QLabel(info); - infoLabel->setWordWrap(true); - } - - QLabel *nameLabel = new QLabel(tr("Folder &name:")); - m_nameEdit = new VMetaWordLineEdit(defaultName); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - m_nameEdit->selectAll(); - nameLabel->setBuddy(m_nameEdit); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - - QHBoxLayout *topLayout = new QHBoxLayout(); - topLayout->addWidget(nameLabel); - topLayout->addWidget(m_nameEdit); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - setWindowTitle(title); -} - -void VNewDirDialog::handleInputChanged() -{ - bool showWarnLabel = false; - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk) { - // Check if the name conflicts with existing directory name. - // Case-insensitive when creating folder. - QString warnText; - if (m_directory->findSubDirectory(name, false)) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); -} - -QString VNewDirDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} diff --git a/src/dialog/vnewdirdialog.h b/src/dialog/vnewdirdialog.h deleted file mode 100644 index 2472321b..00000000 --- a/src/dialog/vnewdirdialog.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef VNEWDIRDIALOG_H -#define VNEWDIRDIALOG_H - -#include - -class QLabel; -class VMetaWordLineEdit; -class QDialogButtonBox; -class QString; -class VDirectory; - -class VNewDirDialog : public QDialog -{ - Q_OBJECT -public: - VNewDirDialog(const QString &title, - const QString &info, - const QString &defaultName, - VDirectory *directory, - QWidget *parent = 0); - - QString getNameInput() const; - -private slots: - void handleInputChanged(); - -private: - void setupUI(); - - VMetaWordLineEdit *m_nameEdit; - QDialogButtonBox *m_btnBox; - - QLabel *m_warnLabel; - - QString title; - QString info; - QString defaultName; - - VDirectory *m_directory; -}; - -#endif // VNEWDIRDIALOG_H diff --git a/src/dialog/vnewfiledialog.cpp b/src/dialog/vnewfiledialog.cpp deleted file mode 100644 index 00c8f0c6..00000000 --- a/src/dialog/vnewfiledialog.cpp +++ /dev/null @@ -1,285 +0,0 @@ -#include -#include "vnewfiledialog.h" -#include "vconfigmanager.h" -#include "vdirectory.h" -#include "vmetawordlineedit.h" -#include "utils/vutils.h" -#include "utils/vmetawordmanager.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; - -extern VMetaWordManager *g_mwMgr; - -QString VNewFileDialog::s_lastTemplateFile; - - -VNewFileDialog::VNewFileDialog(const QString &p_title, - const QString &p_info, - const QString &p_defaultName, - VDirectory *p_directory, - QWidget *p_parent) - : QDialog(p_parent), - m_currentTemplateType(DocType::Unknown), - m_directory(p_directory) -{ - setupUI(p_title, p_info, p_defaultName); - - connect(m_nameEdit, &VMetaWordLineEdit::textChanged, this, &VNewFileDialog::handleInputChanged); - - connect(m_templateCB, static_cast(&QComboBox::currentIndexChanged), - this, &VNewFileDialog::handleCurrentTemplateChanged); - - handleInputChanged(); - - tryToSelectLastTemplate(); -} - -void VNewFileDialog::setupUI(const QString &p_title, - const QString &p_info, - const QString &p_defaultName) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - } - - // Name. - m_nameEdit = new VMetaWordLineEdit(p_defaultName); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - int dotIndex = p_defaultName.lastIndexOf('.'); - m_nameEdit->setSelection(0, (dotIndex == -1) ? p_defaultName.size() : dotIndex); - - // Template. - m_templateCB = VUtils::getComboBox(); - m_templateCB->setToolTip(tr("Choose a template (magic word supported)")); - m_templateCB->setSizeAdjustPolicy(QComboBox::AdjustToContents); - - QPushButton *templateBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/manage_template.svg"), - ""); - templateBtn->setToolTip(tr("Manage Templates")); - templateBtn->setProperty("FlatBtn", true); - connect(templateBtn, &QPushButton::clicked, - this, []() { - QUrl url = QUrl::fromLocalFile(g_config->getTemplateConfigFolder()); - QDesktopServices::openUrl(url); - }); - - QHBoxLayout *tempBtnLayout = new QHBoxLayout(); - tempBtnLayout->addWidget(m_templateCB); - tempBtnLayout->addWidget(templateBtn); - tempBtnLayout->addStretch(); - - m_templateEdit = new QTextEdit(); - m_templateEdit->setReadOnly(true); - - QVBoxLayout *templateLayout = new QVBoxLayout(); - templateLayout->addLayout(tempBtnLayout); - templateLayout->addWidget(m_templateEdit); - - m_templateEdit->hide(); - - // InsertTitle. - m_insertTitleCB = new QCheckBox(tr("Insert note name as title (for Markdown only)")); - m_insertTitleCB->setToolTip(tr("Insert note name into the new note as a title")); - m_insertTitleCB->setChecked(g_config->getInsertTitleFromNoteName()); - connect(m_insertTitleCB, &QCheckBox::stateChanged, - this, [](int p_state) { - g_config->setInsertTitleFromNoteName(p_state == Qt::Checked); - }); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Note &name:"), m_nameEdit); - topLayout->addWidget(m_insertTitleCB); - topLayout->addRow(tr("Template:"), templateLayout); - - m_nameEdit->setMinimumWidth(m_insertTitleCB->sizeHint().width()); - - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, - this, [this]() { - s_lastTemplateFile = m_templateCB->currentData().toString(); - QDialog::accept(); - }); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_templateCB->setMaximumWidth(okBtn->sizeHint().width() * 4); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setLayout(mainLayout); - - setWindowTitle(p_title); -} - -void VNewFileDialog::handleInputChanged() -{ - bool showWarnLabel = false; - const QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (nameOk) { - // Check if the name conflicts with existing note name. - // Case-insensitive when creating note. - QString warnText; - if (m_directory->findFile(name, false)) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); - - if (nameOk) { - updateTemplates(VUtils::docTypeFromName(name)); - } -} - -QString VNewFileDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} - -bool VNewFileDialog::getInsertTitleInput() const -{ - return m_insertTitleCB->isEnabled() && m_insertTitleCB->isChecked(); -} - -void VNewFileDialog::updateTemplates(DocType p_type) -{ - if (m_currentTemplateType == p_type) { - return; - } - - m_currentTemplateType = p_type; - - // Clear the combo. - m_templateCB->clear(); - - // Add None item. - m_templateCB->addItem(tr("None"), "None"); - - if (m_currentTemplateType == DocType::Unknown) { - return; - } - - int idx = 1; - auto templates = g_config->getNoteTemplates(m_currentTemplateType); - for (auto const & tp : templates) { - m_templateCB->addItem(tp, tp); - m_templateCB->setItemData(idx++, tp, Qt::ToolTipRole); - } -} - -void VNewFileDialog::handleCurrentTemplateChanged(int p_idx) -{ - if (p_idx == -1) { - m_templateEdit->hide(); - enableInsertTitleCB(false); - return; - } - - QString file = m_templateCB->itemData(p_idx).toString(); - if (file == "None") { - m_templateEdit->hide(); - enableInsertTitleCB(false); - return; - } - - // Read the template file. - QString filePath = QDir(g_config->getTemplateConfigFolder()).filePath(file); - m_template = VUtils::readFileFromDisk(filePath); - DocType type = VUtils::docTypeFromName(file); - switch (type) { - case DocType::Html: - m_templateEdit->setHtml(m_template); - break; - - case DocType::Markdown: - m_templateEdit->setPlainText(m_template); - break; - - default: - m_templateEdit->setPlainText(m_template); - break; - } - - m_templateEdit->show(); - enableInsertTitleCB(true); -} - -void VNewFileDialog::enableInsertTitleCB(bool p_hasTemplate) -{ - m_insertTitleCB->setEnabled(!p_hasTemplate - && VUtils::docTypeFromName(m_nameEdit->getEvaluatedText()) - == DocType::Markdown); -} - -bool VNewFileDialog::isTemplateUsed() const -{ - QString file = m_templateCB->currentData().toString(); - return !(file.isEmpty() || file == "None"); -} - -QString VNewFileDialog::getTemplate() const -{ - QString name = m_nameEdit->getEvaluatedText(); - QHash overriddenTable; - overriddenTable.insert("note", name); - overriddenTable.insert("no", QFileInfo(name).completeBaseName()); - return g_mwMgr->evaluate(m_template, overriddenTable); -} - -void VNewFileDialog::tryToSelectLastTemplate() -{ - Q_ASSERT(m_templateCB->count() > 0 - && m_templateCB->itemData(0).toString() == "None"); - if (s_lastTemplateFile.isEmpty() || s_lastTemplateFile == "None") { - m_templateCB->setCurrentIndex(0); - return; - } - - int idx = m_templateCB->findData(s_lastTemplateFile); - if (idx != -1) { - m_templateCB->setCurrentIndex(idx); - } else { - s_lastTemplateFile.clear(); - } -} diff --git a/src/dialog/vnewfiledialog.h b/src/dialog/vnewfiledialog.h deleted file mode 100644 index 3ad6168b..00000000 --- a/src/dialog/vnewfiledialog.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef VNEWFILEDIALOG_H -#define VNEWFILEDIALOG_H - -#include - -#include "vconstants.h" - -class QLabel; -class VMetaWordLineEdit; -class QDialogButtonBox; -class QCheckBox; -class VDirectory; -class QComboBox; -class QTextEdit; - -class VNewFileDialog : public QDialog -{ - Q_OBJECT -public: - VNewFileDialog(const QString &p_title, - const QString &p_info, - const QString &p_defaultName, - VDirectory *p_directory, - QWidget *p_parent = 0); - - QString getNameInput() const; - - bool getInsertTitleInput() const; - - // Whether user choose a note template. - bool isTemplateUsed() const; - - // Get the template content (after magic words evaluated) user chose. - QString getTemplate() const; - -private slots: - void handleInputChanged(); - - void handleCurrentTemplateChanged(int p_idx); - -private: - void setupUI(const QString &p_title, - const QString &p_info, - const QString &p_defaultName); - - // Update the templates according to @p_type. - void updateTemplates(DocType p_type); - - void enableInsertTitleCB(bool p_hasTemplate); - - void tryToSelectLastTemplate(); - - VMetaWordLineEdit *m_nameEdit; - - QComboBox *m_templateCB; - - // Used for template preview. - QTextEdit *m_templateEdit; - - QCheckBox *m_insertTitleCB; - - QPushButton *okBtn; - QDialogButtonBox *m_btnBox; - - QLabel *m_warnLabel; - - // Template content. - QString m_template; - - // Doc type of current template. - DocType m_currentTemplateType; - - // Last chosen template file. - static QString s_lastTemplateFile; - - VDirectory *m_directory; -}; - -#endif // VNEWFILEDIALOG_H diff --git a/src/dialog/vnewnotebookdialog.cpp b/src/dialog/vnewnotebookdialog.cpp deleted file mode 100644 index 3047200c..00000000 --- a/src/dialog/vnewnotebookdialog.cpp +++ /dev/null @@ -1,405 +0,0 @@ -#include -#include -#include "vnewnotebookdialog.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vnotebook.h" -#include "vmetawordlineedit.h" - -extern VConfigManager *g_config; - -VNewNotebookDialog::VNewNotebookDialog(const QString &title, const QString &info, - const QString &defaultName, const QString &defaultPath, - const QVector &p_notebooks, - QWidget *parent) - : QDialog(parent), - defaultName(defaultName), defaultPath(defaultPath), - m_importNotebook(false), m_importExternalProject(false), m_manualPath(false), m_manualName(false), - m_notebooks(p_notebooks) -{ - setupUI(title, info); - - connect(m_nameEdit, &VMetaWordLineEdit::textChanged, this, &VNewNotebookDialog::handleInputChanged); - connect(m_pathEdit, &VLineEdit::textChanged, this, &VNewNotebookDialog::handleInputChanged); - connect(browseBtn, &QPushButton::clicked, this, &VNewNotebookDialog::handleBrowseBtnClicked); - - handleInputChanged(); -} - -void VNewNotebookDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - QLabel *nameLabel = new QLabel(tr("Notebook &name:")); - m_nameEdit = new VMetaWordLineEdit(defaultName); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - nameLabel->setBuddy(m_nameEdit); - - QLabel *pathLabel = new QLabel(tr("Notebook &root folder:")); - m_pathEdit = new VLineEdit(defaultPath); - pathLabel->setBuddy(m_pathEdit); - browseBtn = new QPushButton(tr("&Browse")); - - m_relativePathCB = new QCheckBox(tr("Use relative path")); - m_relativePathCB->setToolTip(tr("Use relative path (to VNote's executable) in configuration file")); - connect(m_relativePathCB, &QCheckBox::stateChanged, - this, &VNewNotebookDialog::handleInputChanged); - - QLabel *imageFolderLabel = new QLabel(tr("&Image folder:")); - m_imageFolderEdit = new VLineEdit(); - imageFolderLabel->setBuddy(m_imageFolderEdit); - m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getImageFolder())); - m_imageFolderEdit->setToolTip(tr("Set the name of the folder to hold images of all the notes in this notebook " - "(empty to use global configuration)")); - imageFolderLabel->setToolTip(m_imageFolderEdit->toolTip()); - validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit); - m_imageFolderEdit->setValidator(validator); - - QLabel *attachmentFolderLabel = new QLabel(tr("&Attachment folder:")); - m_attachmentFolderEdit = new VLineEdit(); - attachmentFolderLabel->setBuddy(m_attachmentFolderEdit); - m_attachmentFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getAttachmentFolder())); - m_attachmentFolderEdit->setToolTip(tr("Set the name of the folder to hold attachments of all the notes in this notebook " - "(empty to use global configuration, read-only once created)")); - attachmentFolderLabel->setToolTip(m_attachmentFolderEdit->toolTip()); - validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_attachmentFolderEdit); - m_attachmentFolderEdit->setValidator(validator); - - QGridLayout *topLayout = new QGridLayout(); - topLayout->addWidget(nameLabel, 0, 0); - topLayout->addWidget(m_nameEdit, 0, 1, 1, 2); - topLayout->addWidget(pathLabel, 1, 0); - topLayout->addWidget(m_pathEdit, 1, 1); - topLayout->addWidget(browseBtn, 1, 2); - topLayout->addWidget(m_relativePathCB, 2, 1); - topLayout->addWidget(imageFolderLabel, 3, 0); - topLayout->addWidget(m_imageFolderEdit, 3, 1); - topLayout->addWidget(attachmentFolderLabel, 4, 0); - topLayout->addWidget(m_attachmentFolderEdit, 4, 1); - - // Warning label. - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(this); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - - // Will set the parent of above widgets properly. - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(p_title); -} - -QString VNewNotebookDialog::getNameInput() const -{ - return m_nameEdit->getEvaluatedText(); -} - -QString VNewNotebookDialog::getPathInput() const -{ - // absoluteFilePath() to convert the drive to upper case. - // cleanPath() to remove duplicate separator, '.', and '..'. - QString ret; - if (isUseRelativePath()) { - // Use relative path in config file. - QDir appDir(QCoreApplication::applicationDirPath()); - ret = QDir::cleanPath(appDir.relativeFilePath(m_pathEdit->text())); - } else { - ret = QDir::cleanPath(QFileInfo(m_pathEdit->text()).absoluteFilePath()); - } - - return ret; -} - -QString VNewNotebookDialog::getImageFolder() const -{ - if (m_imageFolderEdit->isEnabled()) { - return m_imageFolderEdit->text(); - } else { - return QString(); - } -} - -QString VNewNotebookDialog::getAttachmentFolder() const -{ - if (m_attachmentFolderEdit->isEnabled()) { - return m_attachmentFolderEdit->text(); - } else { - return QString(); - } -} - -void VNewNotebookDialog::handleBrowseBtnClicked() -{ - static QString defaultPath; - - if (defaultPath.isEmpty()) { - defaultPath = g_config->getVnoteNotebookFolderPath(); - if (!QFileInfo::exists(defaultPath)) { - defaultPath = g_config->getDocumentPathOrHomePath(); - } - } - - QString dirPath = QFileDialog::getExistingDirectory(this, - tr("Select Root Folder Of The Notebook"), - defaultPath, - QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - - if (!dirPath.isEmpty()) { - m_manualPath = true; - if (m_pathEdit->text() == dirPath) { - handleInputChanged(); - } else { - m_pathEdit->setText(dirPath); - } - - defaultPath = VUtils::basePathFromPath(dirPath); - } -} - -bool VNewNotebookDialog::isImportExistingNotebook() const -{ - return m_importNotebook; -} - -bool VNewNotebookDialog::isImportExternalProject() const -{ - return m_importExternalProject; -} - -void VNewNotebookDialog::showEvent(QShowEvent *event) -{ - m_nameEdit->setFocus(); - QDialog::showEvent(event); -} - -void VNewNotebookDialog::handleInputChanged() -{ - bool pathOk = false; - bool configExist = false; - bool showWarnLabel = false; - - // User has input some texts. - if (m_pathEdit->isModified()) { - m_manualPath = true; - } - - if (m_nameEdit->isModified()) { - m_manualName = true; - } - - if (autoComplete()) { - return; - } - - QString path = m_pathEdit->text(); - if (!path.isEmpty()) { - if (!QDir::isAbsolutePath(path)) { - showWarnLabel = true; - QString tmp = tr("WARNING: Please specify absolute path.") - .arg(g_config->c_warningTextStyle); - m_warnLabel->setText(tmp); - } else if (QFileInfo::exists(path)) { - QDir dir(path); - QStringList files = dir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden); - if (!files.isEmpty()) { - // Folder is not empty. - configExist = VConfigManager::directoryConfigExist(path); - if (configExist) { - QString infoText = tr("INFO: The folder chosen seems to be a root " - "folder of a notebook created by VNote before. " - "VNote will try to import it by reading the configuration file.") - .arg("font-weight:bold;"); - m_warnLabel->setText(infoText); - } else { - QString warnText = tr("WARNING: The folder chosen is NOT empty! " - "It is highly recommended to use an EMPTY and EXCLUSIVE folder for a new notebook. " - "If continue, VNote will try to create a notebook based on existing " - "folders and files recursively.") - .arg(g_config->c_warningTextStyle); - m_warnLabel->setText(warnText); - - m_importExternalProject = true; - } - - showWarnLabel = true; - } - - pathOk = true; - } else { - pathOk = true; - } - } - - // Try to validate if this is a legal path on the OS. - if (pathOk) { - pathOk = VUtils::checkPathLegal(path); - if (!pathOk) { - showWarnLabel = true; - QString tmp = tr("WARNING: The path seems to be illegal. " - "Please choose another one.") - .arg(g_config->c_warningTextStyle); - m_warnLabel->setText(tmp); - } - } - - if (pathOk) { - // Check if this path has been in VNote. - int idx = -1; - for (idx = 0; idx < m_notebooks.size(); ++idx) { - if (VUtils::equalPath(m_notebooks[idx]->getPath(), path)) { - break; - } - } - - if (idx < m_notebooks.size()) { - pathOk = false; - showWarnLabel = true; - QString existText = tr("WARNING: The folder chosen has already been a root folder " - "of existing notebook %3 in VNote.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(m_notebooks[idx]->getName()); - m_warnLabel->setText(existText); - } - } - - if (pathOk && isUseRelativePath()) { - if (!VUtils::inSameDrive(QCoreApplication::applicationDirPath(), path)) { - pathOk = false; - showWarnLabel = true; - QString existText = tr("WARNING: Please choose a folder in the same drive as " - "%3 when relative path is enabled.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(QCoreApplication::applicationDirPath()); - m_warnLabel->setText(existText); - } - } - - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - if (pathOk && nameOk) { - // Check if the name conflicts with existing notebook name. - // Case-insensitive. - int idx = -1; - for (idx = 0; idx < m_notebooks.size(); ++idx) { - if (m_notebooks[idx]->getName().toLower() == name.toLower()) { - break; - } - } - - QString warnText; - if (idx < m_notebooks.size()) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - m_importNotebook = configExist; - m_imageFolderEdit->setEnabled(!m_importNotebook); - m_attachmentFolderEdit->setEnabled(!m_importNotebook); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk && pathOk); -} - -bool VNewNotebookDialog::autoComplete() -{ - QString nameText = m_nameEdit->getEvaluatedText(); - - if (m_manualPath) { - if (m_manualName) { - return false; - } - - // Set the name according to user-chosen path. - QString pathText = m_pathEdit->text(); - if (!pathText.isEmpty()) { - QString autoName = VUtils::directoryNameFromPath(pathText); - if (autoName != nameText) { - m_nameEdit->setText(autoName); - return true; - } - } - - return false; - } - - QString vnoteFolder = g_config->getVnoteNotebookFolderPath(); - QString pathText = m_pathEdit->text(); - if (!pathText.isEmpty() - && !VUtils::equalPath(vnoteFolder, VUtils::basePathFromPath(pathText))) { - return false; - } - - bool ret = false; - if (nameText.isEmpty()) { - if (m_manualName) { - return false; - } - - // Get a folder name under vnoteFolder and set it as the name of the notebook. - QString name = "vnotebook"; - name = VUtils::getDirNameWithSequence(vnoteFolder, name); - m_nameEdit->setText(name); - ret = true; - } else { - // Use the name as the folder name under vnoteFolder. - QString autoPath = QDir::cleanPath(QDir(vnoteFolder).filePath(nameText)); - if (autoPath != pathText) { - m_pathEdit->setText(autoPath); - ret = true; - } - } - - return ret; -} - -bool VNewNotebookDialog::isUseRelativePath() const -{ - return m_relativePathCB->isChecked(); -} diff --git a/src/dialog/vnewnotebookdialog.h b/src/dialog/vnewnotebookdialog.h deleted file mode 100644 index 027354f4..00000000 --- a/src/dialog/vnewnotebookdialog.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef VNEWNOTEBOOKDIALOG_H -#define VNEWNOTEBOOKDIALOG_H - -#include -#include - -class QLabel; -class VLineEdit; -class VMetaWordLineEdit; -class QPushButton; -class QDialogButtonBox; -class VNotebook; -class QCheckBox; - -class VNewNotebookDialog : public QDialog -{ - Q_OBJECT -public: - VNewNotebookDialog(const QString &title, const QString &info, const QString &defaultName, - const QString &defaultPath, const QVector &p_notebooks, - QWidget *parent = 0); - - QString getNameInput() const; - - QString getPathInput() const; - - // Whether import existing notebook by reading the config file. - bool isImportExistingNotebook() const; - - // Whether import external project - bool isImportExternalProject() const; - - // Get the custom image folder for this notebook. - // Empty string indicates using global config. - QString getImageFolder() const; - - // Get the custom attachment folder for this notebook. - // Empty string indicates using global config. - QString getAttachmentFolder() const; - -private slots: - void handleBrowseBtnClicked(); - - // Handle the change of the name and path input. - void handleInputChanged(); - -protected: - void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; - -private: - void setupUI(const QString &p_title, const QString &p_info); - - // Should be called before enableOkButton() when path changed. - void checkRootFolder(const QString &p_path); - - // Try to figure out name and path. - // Returns true if name or path is modified. - bool autoComplete(); - - // Whether relative path will be used in config file. - bool isUseRelativePath() const; - - VMetaWordLineEdit *m_nameEdit; - VLineEdit *m_pathEdit; - QPushButton *browseBtn; - QCheckBox *m_relativePathCB; - QLabel *m_warnLabel; - VLineEdit *m_imageFolderEdit; - VLineEdit *m_attachmentFolderEdit; - QDialogButtonBox *m_btnBox; - - QString defaultName; - QString defaultPath; - - // Whether import existing notebook config file. - bool m_importNotebook; - - // Whether import external project - bool m_importExternalProject; - - // True if user has change the content of the path edit. - bool m_manualPath; - - // True if user has change the content of the name edit. - bool m_manualName; - - // All existing notebooks in VNote. - const QVector &m_notebooks; -}; - -#endif // VNEWNOTEBOOKDIALOG_H diff --git a/src/dialog/vnotebookinfodialog.cpp b/src/dialog/vnotebookinfodialog.cpp deleted file mode 100644 index bb087c9e..00000000 --- a/src/dialog/vnotebookinfodialog.cpp +++ /dev/null @@ -1,167 +0,0 @@ -#include -#include "vnotebookinfodialog.h" -#include "vnotebook.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" -#include "vmetawordlineedit.h" - -extern VConfigManager *g_config; - -VNotebookInfoDialog::VNotebookInfoDialog(const QString &p_title, - const QString &p_info, - const VNotebook *p_notebook, - const QVector &p_notebooks, - QWidget *p_parent) - : QDialog(p_parent), m_notebook(p_notebook), - m_notebooks(p_notebooks) -{ - setupUI(p_title, p_info); - - connect(m_nameEdit, &VMetaWordLineEdit::textChanged, - this, &VNotebookInfoDialog::handleInputChanged); - - handleInputChanged(); -} - -void VNotebookInfoDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - } - - m_nameEdit = new VMetaWordLineEdit(m_notebook->getName()); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_nameEdit); - m_nameEdit->setValidator(validator); - m_nameEdit->selectAll(); - - m_pathEdit = new VLineEdit(m_notebook->getPath()); - m_pathEdit->setReadOnly(true); - - // Image folder. - m_imageFolderEdit = new VLineEdit(m_notebook->getImageFolderConfig()); - m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getImageFolder())); - m_imageFolderEdit->setToolTip(tr("Set the name of the folder to hold images of all the notes in this notebook " - "(empty to use global configuration)")); - validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit); - m_imageFolderEdit->setValidator(validator); - - // Attachment folder. - Q_ASSERT(!m_notebook->getAttachmentFolder().isEmpty()); - m_attachmentFolderEdit = new VLineEdit(m_notebook->getAttachmentFolder()); - m_attachmentFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getAttachmentFolder())); - m_attachmentFolderEdit->setToolTip(tr("The folder to hold attachments of all the notes in this notebook")); - m_attachmentFolderEdit->setReadOnly(true); - - // Recycle bin folder. - VLineEdit *recycleBinFolderEdit = new VLineEdit(m_notebook->getRecycleBinFolder()); - recycleBinFolderEdit->setReadOnly(true); - recycleBinFolderEdit->setToolTip(tr("The folder to hold deleted files from within VNote of all the notes in this notebook")); - - // Created time. - QString createdTimeStr = VUtils::displayDateTime(const_cast(m_notebook)->getCreatedTimeUtc().toLocalTime()); - QLabel *createdTimeLabel = new QLabel(createdTimeStr); - - QFormLayout *topLayout = new QFormLayout(); - topLayout->addRow(tr("Notebook &name:"), m_nameEdit); - topLayout->addRow(tr("Notebook &root folder:"), m_pathEdit); - topLayout->addRow(tr("&Image folder:"), m_imageFolderEdit); - topLayout->addRow(tr("Attachment folder:"), m_attachmentFolderEdit); - topLayout->addRow(tr("Recycle bin folder:"), recycleBinFolderEdit); - topLayout->addRow(tr("Created time:"), createdTimeLabel); - - // Warning label. - m_warnLabel = new QLabel(); - m_warnLabel->setWordWrap(true); - m_warnLabel->hide(); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_warnLabel); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - setWindowTitle(p_title); -} - -void VNotebookInfoDialog::handleInputChanged() -{ - QString name = m_nameEdit->getEvaluatedText(); - bool nameOk = !name.isEmpty(); - bool showWarnLabel = false; - - if (nameOk && name != m_notebook->getName()) { - // Check if the name conflicts with existing notebook name. - // Case-insensitive. - int idx = -1; - for (idx = 0; idx < m_notebooks.size(); ++idx) { - if (m_notebooks[idx]->getName().toLower() == name.toLower()) { - break; - } - } - - QString warnText; - if (idx < m_notebooks.size() && m_notebooks[idx] != m_notebook) { - nameOk = false; - warnText = tr("WARNING: " - "Name (case-insensitive) %3 already exists. " - "Please choose another name.") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } else if (!VUtils::checkFileNameLegal(name)) { - // Check if evaluated name contains illegal characters. - nameOk = false; - warnText = tr("WARNING: " - "Name %3 contains illegal characters " - "(after magic word evaluation).") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(name); - } - - if (!nameOk) { - showWarnLabel = true; - m_warnLabel->setText(warnText); - } - } - - m_warnLabel->setVisible(showWarnLabel); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(nameOk); -} - -QString VNotebookInfoDialog::getName() const -{ - return m_nameEdit->getEvaluatedText(); -} - -QString VNotebookInfoDialog::getImageFolder() const -{ - return m_imageFolderEdit->text(); -} - -void VNotebookInfoDialog::showEvent(QShowEvent *p_event) -{ - m_nameEdit->setFocus(); - QDialog::showEvent(p_event); -} - diff --git a/src/dialog/vnotebookinfodialog.h b/src/dialog/vnotebookinfodialog.h deleted file mode 100644 index b016cd76..00000000 --- a/src/dialog/vnotebookinfodialog.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef VNOTEBOOKINFODIALOG_H -#define VNOTEBOOKINFODIALOG_H - -#include -#include - -class QLabel; -class VLineEdit; -class VMetaWordLineEdit; -class QDialogButtonBox; -class VNotebook; - -class VNotebookInfoDialog : public QDialog -{ - Q_OBJECT -public: - VNotebookInfoDialog(const QString &p_title, - const QString &p_info, - const VNotebook *p_notebook, - const QVector &p_notebooks, - QWidget *p_parent = 0); - - QString getName() const; - - // Get the custom image folder for this notebook. - // Empty string indicates using global config. - QString getImageFolder() const; - -private slots: - // Handle the change of the name and path input. - void handleInputChanged(); - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private: - void setupUI(const QString &p_title, const QString &p_info); - - const VNotebook *m_notebook; - - VMetaWordLineEdit *m_nameEdit; - VLineEdit *m_pathEdit; - VLineEdit *m_imageFolderEdit; - // Read-only. - VLineEdit *m_attachmentFolderEdit; - QLabel *m_warnLabel; - QDialogButtonBox *m_btnBox; - const QVector &m_notebooks; -}; - -#endif // VNOTEBOOKINFODIALOG_H diff --git a/src/dialog/vorphanfileinfodialog.cpp b/src/dialog/vorphanfileinfodialog.cpp deleted file mode 100644 index 4d9c26c5..00000000 --- a/src/dialog/vorphanfileinfodialog.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "vorphanfileinfodialog.h" - -#include -#include "vorphanfile.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vlineedit.h" - -extern VConfigManager *g_config; - -VOrphanFileInfoDialog::VOrphanFileInfoDialog(const VOrphanFile *p_file, QWidget *p_parent) - : QDialog(p_parent), m_file(p_file) -{ - setupUI(); - - connect(m_imageFolderEdit, &VLineEdit::textChanged, - this, &VOrphanFileInfoDialog::handleInputChanged); - - handleInputChanged(); -} - -void VOrphanFileInfoDialog::setupUI() -{ - QFormLayout *topLayout = new QFormLayout(); - - QLabel *fileLabel = new QLabel(m_file->fetchPath()); - fileLabel->setTextInteractionFlags(fileLabel->textInteractionFlags() | Qt::TextSelectableByMouse); - fileLabel->setWordWrap(true); - topLayout->addRow(tr("File:"), fileLabel); - - m_imageFolderEdit = new VLineEdit(m_file->getImageFolder()); - m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getImageFolderExt())); - QString imgFolderTip = tr("Set the path of the image folder to store images " - "of this file.\nIf absolute path is used, " - "VNote will not manage those images." - "(empty to use global configuration)"); - m_imageFolderEdit->setToolTip(imgFolderTip); - topLayout->addRow(tr("&Image folder:"), m_imageFolderEdit); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setProperty("SpecialBtn", true); - m_imageFolderEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_btnBox); - mainLayout->setSizeConstraint(QLayout::SetFixedSize); - - setLayout(mainLayout); - setWindowTitle(tr("External File Information")); -} - -QString VOrphanFileInfoDialog::getImageFolder() const -{ - return QDir::fromNativeSeparators(m_imageFolderEdit->text()); -} - -void VOrphanFileInfoDialog::handleInputChanged() -{ - bool ok = false; - QString imgFolder = m_imageFolderEdit->text(); - if (imgFolder.isEmpty() || VUtils::checkPathLegal(imgFolder)) { - ok = true; - } - - QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); - okBtn->setEnabled(ok); -} diff --git a/src/dialog/vorphanfileinfodialog.h b/src/dialog/vorphanfileinfodialog.h deleted file mode 100644 index 9093a77e..00000000 --- a/src/dialog/vorphanfileinfodialog.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef VORPHANFILEINFODIALOG_H -#define VORPHANFILEINFODIALOG_H - -#include - -class VOrphanFile; -class QDialogButtonBox; -class VLineEdit; - -class VOrphanFileInfoDialog : public QDialog -{ - Q_OBJECT - -public: - VOrphanFileInfoDialog(const VOrphanFile *p_file, QWidget *p_parent = 0); - - // Get the custom image folder for this external file. - // Empty string indicates using global config. - QString getImageFolder() const; - -private slots: - // Handle the change of the image folder input. - void handleInputChanged(); - -private: - void setupUI(); - - const VOrphanFile *m_file; - - QDialogButtonBox *m_btnBox; - VLineEdit *m_imageFolderEdit; -}; - -#endif // VORPHANFILEINFODIALOG_H diff --git a/src/dialog/vselectdialog.cpp b/src/dialog/vselectdialog.cpp deleted file mode 100644 index b87690d2..00000000 --- a/src/dialog/vselectdialog.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include - -#include "vselectdialog.h" -#include "utils/vimnavigationforwidget.h" - -#define CANCEL_ID -1 - -VSelectDialog::VSelectDialog(const QString &p_title, QWidget *p_parent) - : QDialog(p_parent), m_choice(-1) -{ - setupUI(p_title); -} - -void VSelectDialog::setupUI(const QString &p_title) -{ - m_list = new QListWidget(); - m_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_list->setSelectionMode(QAbstractItemView::SingleSelection); - m_list->setAttribute(Qt::WA_MacShowFocusRect, false); - connect(m_list, &QListWidget::itemActivated, - this, &VSelectDialog::selectionChosen); - - // Add cancel item. - QListWidgetItem *cancelItem = new QListWidgetItem(tr("Cancel")); - cancelItem->setData(Qt::UserRole, CANCEL_ID); - - m_list->addItem(cancelItem); - m_list->setCurrentRow(0); - - QVBoxLayout *layout = new QVBoxLayout(); - layout->addWidget(m_list); - - layout->setContentsMargins(0, 0, 0, 0); - - setLayout(layout); - setWindowTitle(p_title); -} - -void VSelectDialog::addSelection(const QString &p_selectStr, int p_selectID) -{ - Q_ASSERT(p_selectID >= 0); - - QListWidgetItem *item = new QListWidgetItem(p_selectStr); - item->setData(Qt::UserRole, p_selectID); - m_list->insertItem(m_list->count() - 1, item); - - m_list->setCurrentRow(0); -} - -void VSelectDialog::selectionChosen(QListWidgetItem *p_item) -{ - m_choice = p_item->data(Qt::UserRole).toInt(); - if (m_choice == CANCEL_ID) { - reject(); - } else { - accept(); - } -} - -int VSelectDialog::getSelection() const -{ - return m_choice; -} - -void VSelectDialog::updateSize() -{ - Q_ASSERT(m_list->count() > 0); - - int height = 0; - for (int i = 0; i < m_list->count(); ++i) { - height += m_list->sizeHintForRow(i); - } - - height += 2 * m_list->count(); - int wid = width(); - m_list->resize(wid, height); - resize(wid, height); -} - -void VSelectDialog::showEvent(QShowEvent *p_event) -{ - QDialog::showEvent(p_event); - - updateSize(); -} - -void VSelectDialog::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(m_list, - p_event, - this)) { - return; - } - - // On Mac OS X, it is `Command+O` to activate an item, instead of Return. -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - int key = p_event->key(); - if (key == Qt::Key_Return || key == Qt::Key_Enter) { - p_event->accept(); - if (auto item = m_list->currentItem()) { - selectionChosen(item); - } - - return; - } -#endif - - QDialog::keyPressEvent(p_event); -} - diff --git a/src/dialog/vselectdialog.h b/src/dialog/vselectdialog.h deleted file mode 100644 index 821e9bed..00000000 --- a/src/dialog/vselectdialog.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef VSELECTDIALOG_H -#define VSELECTDIALOG_H - -#include -#include - -class QPushButton; -class QMouseEvent; -class QListWidget; -class QListWidgetItem; -class QShowEvent; -class QKeyEvent; - -class VSelectDialog : public QDialog -{ - Q_OBJECT -public: - VSelectDialog(const QString &p_title, QWidget *p_parent = 0); - - // @p_selectID should >= 0. - void addSelection(const QString &p_selectStr, int p_selectID); - - int getSelection() const; - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void selectionChosen(QListWidgetItem *p_item); - -private: - void setupUI(const QString &p_title); - - void updateSize(); - - int m_choice; - - QListWidget *m_list; -}; - -#endif // VSELECTDIALOG_H diff --git a/src/dialog/vsettingsdialog.cpp b/src/dialog/vsettingsdialog.cpp deleted file mode 100644 index aa36ff90..00000000 --- a/src/dialog/vsettingsdialog.cpp +++ /dev/null @@ -1,2084 +0,0 @@ -#include "vsettingsdialog.h" -#include -#include -#include - -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vconstants.h" -#include "vlineedit.h" -#include "vplantumlhelper.h" -#include "vgraphvizhelper.h" -#include "utils/vkeyboardlayoutmanager.h" -#include "dialog/vkeyboardlayoutmappingdialog.h" - -extern VConfigManager *g_config; - -VSettingsDialog::VSettingsDialog(QWidget *p_parent) - : QDialog(p_parent), - m_needUpdateEditorFont(false) -{ - m_tabList = new QListWidget(this); - m_tabList->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); - - m_tabs = new QStackedLayout(); - - // Reset VNote. - m_resetVNoteBtn = new QPushButton(tr("Reset VNote"), this); - m_resetVNoteBtn->setProperty("DangerBtn", true); - m_resetVNoteBtn->setToolTip(tr("Reset all the configurations of VNote")); - connect(m_resetVNoteBtn, &QPushButton::clicked, - this, &VSettingsDialog::resetVNote); - - // Reset Layout. - m_resetLayoutBtn = new QPushButton(tr("Reset Layout"), this); - m_resetLayoutBtn->setToolTip(tr("Reset layout of VNote")); - connect(m_resetLayoutBtn, &QPushButton::clicked, - this, &VSettingsDialog::resetLayout); - - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &VSettingsDialog::saveConfiguration); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - - m_btnBox->addButton(m_resetVNoteBtn, QDialogButtonBox::ResetRole); - m_btnBox->addButton(m_resetLayoutBtn, QDialogButtonBox::ResetRole); - - QHBoxLayout *tabLayout = new QHBoxLayout(); - tabLayout->addWidget(m_tabList); - tabLayout->addLayout(m_tabs); - tabLayout->setContentsMargins(0, 0, 0, 0); - tabLayout->setSpacing(0); - tabLayout->setStretch(0, 0); - tabLayout->setStretch(1, 5); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(tabLayout); - mainLayout->addWidget(m_btnBox); - setLayout(mainLayout); - - setWindowTitle(tr("Settings")); - - // Add tabs. - addTab(new VGeneralTab(), tr("General")); - addTab(new VLookTab(), tr("Appearance")); - addTab(new VReadEditTab(this), tr("Read/Edit")); - addTab(new VNoteManagementTab(), tr("Note Management")); - addTab(new VMarkdownTab(), tr("Markdown")); - addTab(new VMiscTab(), tr("Misc")); - addTab(new VImageHostingTab(), tr("Image Hosting")); - - m_tabList->setMaximumWidth(m_tabList->sizeHintForColumn(0) + 5); - - connect(m_tabList, &QListWidget::currentItemChanged, - this, [this](QListWidgetItem *p_cur, QListWidgetItem *p_pre) { - Q_UNUSED(p_pre); - Q_ASSERT(p_cur); - int idx = p_cur->data(Qt::UserRole).toInt(); - Q_ASSERT(idx >= 0); - m_tabs->setCurrentWidget(m_tabs->widget(idx)); - }); - - m_tabList->setCurrentRow(0); - - loadConfiguration(); -} - -void VSettingsDialog::resetVNote() -{ - int ret = VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Are you sure to reset VNote?"), - tr("All configurations (except notebooks information) " - "will be reset to default values. " - "It is UNRECOVERABLE!"), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Cancel, - this, - MessageBoxType::Danger); - - if (ret == QMessageBox::Cancel) { - return; - } - - g_config->resetConfigurations(); - - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Please restart VNote to make it work."), - tr("Any change to VNote before restart will be lost!"), - QMessageBox::Ok, - QMessageBox::Ok, - this); - - reject(); -} - -void VSettingsDialog::resetLayout() -{ - int ret = VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Are you sure to reset the layout of VNote?"), - tr("The view and layout mode will be reset. " - "It is UNRECOVERABLE!"), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Cancel, - this, - MessageBoxType::Danger); - - if (ret == QMessageBox::Cancel) { - return; - } - - g_config->resetLayoutConfigurations(); - - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Please restart VNote to make it work."), - tr("Any change to VNote before restart will be lost!"), - QMessageBox::Ok, - QMessageBox::Ok, - this); - - reject(); -} - -void VSettingsDialog::addTab(QWidget *p_widget, const QString &p_label) -{ - int idx = m_tabs->addWidget(p_widget); - QListWidgetItem *item = new QListWidgetItem(p_label, m_tabList); - item->setData(Qt::UserRole, idx); -} - -void VSettingsDialog::loadConfiguration() -{ - int idx = 0; - // General Tab. - { - VGeneralTab *generalTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(generalTab); - if (!generalTab->loadConfiguration()) { - goto err; - } - } - - // Appearance Tab. - { - VLookTab *lookTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(lookTab); - if (!lookTab->loadConfiguration()) { - goto err; - } - } - - // Read/Edit Tab. - { - VReadEditTab *readEditTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(readEditTab); - if (!readEditTab->loadConfiguration()) { - goto err; - } - } - - // Note Management Tab. - { - VNoteManagementTab *noteManagementTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(noteManagementTab); - if (!noteManagementTab->loadConfiguration()) { - goto err; - } - } - - // Markdown Tab. - { - VMarkdownTab *markdownTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(markdownTab); - if (!markdownTab->loadConfiguration()) { - goto err; - } - } - - // Misc Tab. - { - VMiscTab *miscTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(miscTab); - if (!miscTab->loadConfiguration()) { - goto err; - } - } - - // ImageBed Tab - { - VImageHostingTab *imageBedTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(imageBedTab); - if (!imageBedTab->loadConfiguration()) { - goto err; - } - } - - return; -err: - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to load configuration."), "", - QMessageBox::Ok, QMessageBox::Ok, NULL); - QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection); -} - -void VSettingsDialog::saveConfiguration() -{ - int idx = 0; - // General Tab. - { - VGeneralTab *generalTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(generalTab); - if (!generalTab->saveConfiguration()) { - goto err; - } - } - - // Appearance Tab. - { - VLookTab *lookTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(lookTab); - if (!lookTab->saveConfiguration()) { - goto err; - } - } - - // Read/Edit Tab. - { - VReadEditTab *readEditTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(readEditTab); - if (!readEditTab->saveConfiguration()) { - goto err; - } - } - - // Note Management Tab. - { - VNoteManagementTab *noteManagementTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(noteManagementTab); - if (!noteManagementTab->saveConfiguration()) { - goto err; - } - } - - // Markdown Tab. - { - VMarkdownTab *markdownTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(markdownTab); - if (!markdownTab->saveConfiguration()) { - goto err; - } - } - - // Misc Tab. - { - VMiscTab *miscTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(miscTab); - if (!miscTab->saveConfiguration()) { - goto err; - } - } - - // Image Hosting Tab. - { - VImageHostingTab *imageBedTab = dynamic_cast(m_tabs->widget(idx++)); - Q_ASSERT(imageBedTab); - if (!imageBedTab->saveConfiguration()) { - goto err; - } - } - - accept(); - return; -err: - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to save configuration. Please try it again."), "", - QMessageBox::Ok, QMessageBox::Ok, NULL); -} - -const QVector VGeneralTab::c_availableLangs = { "System", "English", "Chinese", "Japanese" }; - -VGeneralTab::VGeneralTab(QWidget *p_parent) - : QWidget(p_parent) -{ - // Language combo. - m_langCombo = VUtils::getComboBox(this); - m_langCombo->setToolTip(tr("Choose the language of VNote interface")); - m_langCombo->addItem(tr("System"), "System"); - auto langs = VUtils::getAvailableLanguages(); - for (auto const &lang : langs) { - m_langCombo->addItem(lang.second, lang.first); - } - - // System tray checkbox. - m_systemTray = new QCheckBox(tr("System tray"), this); - m_systemTray->setToolTip(tr("Minimized to the system tray after closing VNote" - " (not supported in macOS)")); -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - // Do not support minimized to tray on macOS. - m_systemTray->setEnabled(false); -#endif - - // Startup pages. - QLayout *startupLayout = setupStartupPagesLayout(); - - // Quick access. - m_quickAccessEdit = new VLineEdit(this); - m_quickAccessEdit->setPlaceholderText(tr("Path of file to quick access")); - m_quickAccessEdit->setToolTip(tr("Set the path of a file to quick access " - "(absolute or relative to configuration folder)")); - - QPushButton *browseBtn = new QPushButton(tr("Browse"), this); - connect(browseBtn, &QPushButton::clicked, - this, [this]() { - QString filePath = QFileDialog::getOpenFileName(this, - tr("Select File To Quick Access"), - g_config->getDocumentPathOrHomePath()); - - if (!filePath.isEmpty()) { - m_quickAccessEdit->setText(filePath); - } - }); - - QHBoxLayout *qaLayout = new QHBoxLayout(); - qaLayout->addWidget(m_quickAccessEdit); - qaLayout->addWidget(browseBtn); - - // Keyboard layout mappings. - m_keyboardLayoutCombo = VUtils::getComboBox(this); - m_keyboardLayoutCombo->setToolTip(tr("Choose the keyboard layout mapping to use in shortcuts")); - - // OpenGL option. -#if defined(Q_OS_WIN) - m_openGLCombo = VUtils::getComboBox(this); - m_openGLCombo->setToolTip(tr("Choose the OpenGL implementation to load (restart VNote to make it work)")); -#endif - - QPushButton *editLayoutBtn = new QPushButton(tr("Edit"), this); - connect(editLayoutBtn, &QPushButton::clicked, - this, [this]() { - VKeyboardLayoutMappingDialog dialog(this); - dialog.exec(); - loadKeyboardLayoutMapping(); - }); - - QHBoxLayout *klLayout = new QHBoxLayout(); - klLayout->addWidget(m_keyboardLayoutCombo); - klLayout->addWidget(editLayoutBtn); - klLayout->addStretch(); - - QFormLayout *optionLayout = new QFormLayout(); - optionLayout->addRow(tr("Language:"), m_langCombo); - optionLayout->addRow(m_systemTray); - optionLayout->addRow(tr("Startup pages:"), startupLayout); - optionLayout->addRow(tr("Quick access:"), qaLayout); - optionLayout->addRow(tr("Keyboard layout mapping:"), klLayout); - -#if defined(Q_OS_WIN) - optionLayout->addRow(tr("OpenGL:"), m_openGLCombo); -#endif - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(optionLayout); - - setLayout(mainLayout); -} - -QLayout *VGeneralTab::setupStartupPagesLayout() -{ - m_startupPageTypeCombo = VUtils::getComboBox(this); - m_startupPageTypeCombo->setToolTip(tr("Restore tabs or open specific notes on startup")); - m_startupPageTypeCombo->addItem(tr("None"), (int)StartupPageType::None); - m_startupPageTypeCombo->addItem(tr("Continue where you left off"), (int)StartupPageType::ContinueLeftOff); - m_startupPageTypeCombo->addItem(tr("Open specific pages"), (int)StartupPageType::SpecificPages); - connect(m_startupPageTypeCombo, static_cast(&QComboBox::activated), - this, [this](int p_index) { - int type = m_startupPageTypeCombo->itemData(p_index).toInt(); - bool pagesEditVisible = type == (int)StartupPageType::SpecificPages; - m_startupPagesEdit->setVisible(pagesEditVisible); - m_startupPagesAddBtn->setVisible(pagesEditVisible); - }); - - m_startupPagesEdit = new QPlainTextEdit(this); - m_startupPagesEdit->setProperty("LineEdit", true); - m_startupPagesEdit->setToolTip(tr("Absolute path of the notes to open on startup (one note per line)")); - - m_startupPagesAddBtn = new QPushButton(tr("Browse"), this); - m_startupPagesAddBtn->setToolTip(tr("Select files to add as startup pages")); - connect(m_startupPagesAddBtn, &QPushButton::clicked, - this, [this]() { - static QString lastPath = QDir::homePath(); - QStringList files = QFileDialog::getOpenFileNames(this, - tr("Select Files As Startup Pages"), - lastPath); - if (files.isEmpty()) { - return; - } - - // Update lastPath - lastPath = QFileInfo(files[0]).path(); - - m_startupPagesEdit->appendPlainText(files.join("\n")); - }); - - QHBoxLayout *startupPagesBtnLayout = new QHBoxLayout(); - startupPagesBtnLayout->addStretch(); - startupPagesBtnLayout->addWidget(m_startupPagesAddBtn); - - QVBoxLayout *startupPagesLayout = new QVBoxLayout(); - startupPagesLayout->addWidget(m_startupPagesEdit); - startupPagesLayout->addLayout(startupPagesBtnLayout); - - QVBoxLayout *startupLayout = new QVBoxLayout(); - startupLayout->addWidget(m_startupPageTypeCombo); - startupLayout->addLayout(startupPagesLayout); - - m_startupPagesEdit->hide(); - m_startupPagesAddBtn->hide(); - - return startupLayout; -} - -bool VGeneralTab::loadConfiguration() -{ - if (!loadLanguage()) { - return false; - } - - if (!loadSystemTray()) { - return false; - } - - if (!loadStartupPageType()) { - return false; - } - - if (!loadQuickAccess()) { - return false; - } - - if (!loadKeyboardLayoutMapping()) { - return false; - } - - if (!loadOpenGL()) { - return false; - } - - return true; -} - -bool VGeneralTab::saveConfiguration() -{ - if (!saveLanguage()) { - return false; - } - - if (!saveSystemTray()) { - return false; - } - - if (!saveStartupPageType()) { - return false; - } - - if (!saveQuickAccess()) { - return false; - } - - if (!saveKeyboardLayoutMapping()) { - return false; - } - - if (!saveOpenGL()) { - return false; - } - - return true; -} - -bool VGeneralTab::loadLanguage() -{ - QString lang = g_config->getLanguage(); - if (lang.isNull()) { - return false; - } else if (lang == "System") { - m_langCombo->setCurrentIndex(0); - return true; - } - bool found = false; - // lang is the value, not name. - for (int i = 0; i < m_langCombo->count(); ++i) { - if (m_langCombo->itemData(i).toString() == lang) { - found = true; - m_langCombo->setCurrentIndex(i); - break; - } - } - if (!found) { - qWarning() << "invalid language configuration (using default value)"; - m_langCombo->setCurrentIndex(0); - } - return true; -} - -bool VGeneralTab::saveLanguage() -{ - QString curLang = m_langCombo->currentData().toString(); - g_config->setLanguage(curLang); - return true; -} - -bool VGeneralTab::loadSystemTray() -{ - m_systemTray->setChecked(g_config->getMinimizeToStystemTray() != 0); - return true; -} - -bool VGeneralTab::saveSystemTray() -{ - if (m_systemTray->isEnabled()) { - g_config->setMinimizeToSystemTray(m_systemTray->isChecked() ? 1 : 0); - } - - return true; -} - -bool VGeneralTab::loadStartupPageType() -{ - StartupPageType type = g_config->getStartupPageType(); - bool found = false; - for (int i = 0; i < m_startupPageTypeCombo->count(); ++i) { - if (m_startupPageTypeCombo->itemData(i).toInt() == (int)type) { - found = true; - m_startupPageTypeCombo->setCurrentIndex(i); - } - } - - Q_ASSERT(found); - - const QStringList &pages = g_config->getStartupPages(); - m_startupPagesEdit->setPlainText(pages.join("\n")); - - bool pagesEditVisible = type == StartupPageType::SpecificPages; - m_startupPagesEdit->setVisible(pagesEditVisible); - m_startupPagesAddBtn->setVisible(pagesEditVisible); - - return true; -} - -bool VGeneralTab::saveStartupPageType() -{ - StartupPageType type = (StartupPageType)m_startupPageTypeCombo->currentData().toInt(); - g_config->setStartupPageType(type); - - if (type == StartupPageType::SpecificPages) { - QStringList pages = m_startupPagesEdit->toPlainText().split("\n"); - g_config->setStartupPages(pages); - } - - return true; -} - -bool VGeneralTab::loadQuickAccess() -{ - m_quickAccessEdit->setText(g_config->getQuickAccess()); - return true; -} - -bool VGeneralTab::saveQuickAccess() -{ - g_config->setQuickAccess(m_quickAccessEdit->text()); - return true; -} - -bool VGeneralTab::loadKeyboardLayoutMapping() -{ - m_keyboardLayoutCombo->clear(); - - m_keyboardLayoutCombo->addItem(tr("None"), ""); - - QStringList layouts = VKeyboardLayoutManager::availableLayouts(); - for (auto const & layout : layouts) { - m_keyboardLayoutCombo->addItem(layout, layout); - } - - int idx = 0; - const auto &cur = VKeyboardLayoutManager::currentLayout(); - if (!cur.m_name.isEmpty()) { - idx = m_keyboardLayoutCombo->findData(cur.m_name); - if (idx == -1) { - idx = 0; - VKeyboardLayoutManager::setCurrentLayout(""); - } - } - - m_keyboardLayoutCombo->setCurrentIndex(idx); - return true; -} - -bool VGeneralTab::saveKeyboardLayoutMapping() -{ - g_config->setKeyboardLayout(m_keyboardLayoutCombo->currentData().toString()); - VKeyboardLayoutManager::update(); - return true; -} - -bool VGeneralTab::loadOpenGL() -{ -#if defined(Q_OS_WIN) - m_openGLCombo->clear(); - - m_openGLCombo->addItem(tr("System"), OpenGLDefault); - m_openGLCombo->addItem(tr("DesktopOpenGL"), OpenGLDesktop); - m_openGLCombo->addItem(tr("OpenGLES"), OpenGLAngle); - m_openGLCombo->addItem(tr("SoftwareOpenGL"), OpenGLSoftware); - - int opt = VConfigManager::getWindowsOpenGL(); - int idx = m_openGLCombo->findData(opt); - if (idx == -1) { - idx = 0; - } - m_openGLCombo->setCurrentIndex(idx); -#endif - return true; -} - -bool VGeneralTab::saveOpenGL() -{ -#if defined(Q_OS_WIN) - VConfigManager::setWindowsOpenGL(m_openGLCombo->currentData().toInt()); -#endif - return true; -} - -VLookTab::VLookTab(QWidget *p_parent) - : QWidget(p_parent) -{ - m_tbIconSizeSpin = new QSpinBox(this); - m_tbIconSizeSpin->setToolTip(tr("Icon size in pixel of tool bar (restart VNote to make it work)")); - m_tbIconSizeSpin->setMaximum(100); - m_tbIconSizeSpin->setMinimum(5); - - QFormLayout *layout = new QFormLayout(); - layout->addRow(tr("Tool bar icon size:"), m_tbIconSizeSpin); - - setLayout(layout); -} - -bool VLookTab::loadConfiguration() -{ - if (!loadToolBarIconSize()) { - return false; - } - - return true; -} - -bool VLookTab::saveConfiguration() -{ - if (!saveToolBarIconSize()) { - return false; - } - - return true; -} - -bool VLookTab::loadToolBarIconSize() -{ - int sz = g_config->getToolBarIconSize(); - m_tbIconSizeSpin->setValue(sz); - return true; -} - -bool VLookTab::saveToolBarIconSize() -{ - g_config->setToolBarIconSize(m_tbIconSizeSpin->value()); - return true; -} - -VReadEditTab::VReadEditTab(VSettingsDialog *p_dlg, QWidget *p_parent) - : QWidget(p_parent), - m_settingsDlg(p_dlg) -{ - m_readBox = new QGroupBox(tr("Read Mode (For Markdown Only)")); - m_editBox = new QGroupBox(tr("Edit Mode")); - - // Web Zoom Factor. - m_customWebZoom = new QCheckBox(tr("Custom Web zoom factor")); - m_customWebZoom->setToolTip(tr("Set the zoom factor of the Web page when reading")); - m_webZoomFactorSpin = new QDoubleSpinBox(); - m_webZoomFactorSpin->setMaximum(c_webZoomFactorMax); - m_webZoomFactorSpin->setMinimum(c_webZoomFactorMin); - m_webZoomFactorSpin->setSingleStep(0.25); - connect(m_customWebZoom, &QCheckBox::stateChanged, - this, [this](int p_state) { - this->m_webZoomFactorSpin->setEnabled(p_state == Qt::Checked); - }); - QHBoxLayout *zoomFactorLayout = new QHBoxLayout(); - zoomFactorLayout->addWidget(m_customWebZoom); - zoomFactorLayout->addWidget(m_webZoomFactorSpin); - - // Web flash anchor. - m_flashAnchor = new QCheckBox(tr("Flash current heading")); - m_flashAnchor->setToolTip(tr("Flash current heading on change")); - - // Swap file. - m_swapFile = new QCheckBox(tr("Swap file (Recommended)")); - m_swapFile->setToolTip(tr("Automatically save changes to a swap file for backup")); - connect(m_swapFile, &QCheckBox::stateChanged, - this, &VReadEditTab::showTipsAboutAutoSave); - - // Auto save. - m_autoSave = new QCheckBox(tr("Auto save (Buggy)")); - m_autoSave->setToolTip(tr("Automatically save the note when editing" - " (may DELETE images on save)")); - connect(m_autoSave, &QCheckBox::stateChanged, - this, &VReadEditTab::showTipsAboutAutoSave); - - // Key mode. - m_keyModeCB = VUtils::getComboBox(); - m_keyModeCB->setToolTip(tr("Choose the key mode in editor")); - m_keyModeCB->addItem(tr("Normal"), (int)KeyMode::Normal); - m_keyModeCB->addItem(tr("Vim"), (int)KeyMode::Vim); - connect(m_keyModeCB, static_cast(&QComboBox::currentIndexChanged), - this, [this](int p_index) { - int mode = m_keyModeCB->itemData(p_index).toInt(); - m_smartIM->setVisible(mode == (int)KeyMode::Vim); - }); - - // Smart IM in Vim. - m_smartIM = new QCheckBox(tr("Smart input method in Vim mode")); - m_smartIM->setToolTip(tr("Disable input method when leaving Insert mode in Vim mode")); - - // Editor font family. - m_customEditorFont = new QCheckBox(tr("Custom editor font")); - m_customEditorFont->setToolTip(tr("Set the font of editor to override style configuration")); - connect(m_customEditorFont, &QCheckBox::stateChanged, - this, [this](int p_state) { - m_editorFontFamilyCB->setEnabled(p_state == Qt::Checked); - }); - m_editorFontFamilyCB = new QFontComboBox(); - QHBoxLayout *editorFontLayout = new QHBoxLayout(); - editorFontLayout->addWidget(m_customEditorFont); - editorFontLayout->addWidget(m_editorFontFamilyCB); - - // Editor zoom delta. - m_editorZoomDeltaSpin = new QSpinBox(); - m_editorZoomDeltaSpin->setToolTip(tr("Set the zoom delta of the editor font")); - m_editorZoomDeltaSpin->setMaximum(c_editorZoomDeltaMax); - m_editorZoomDeltaSpin->setMinimum(c_editorZoomDeltaMin); - m_editorZoomDeltaSpin->setSingleStep(1); - - QVBoxLayout *readLayout = new QVBoxLayout(); - readLayout->addLayout(zoomFactorLayout); - readLayout->addWidget(m_flashAnchor); - m_readBox->setLayout(readLayout); - - QFormLayout *editLayout = new QFormLayout(); - editLayout->addRow(m_swapFile); - editLayout->addRow(m_autoSave); - editLayout->addRow(tr("Key mode:"), m_keyModeCB); - editLayout->addWidget(m_smartIM); - editLayout->addRow(tr("Editor zoom delta:"), m_editorZoomDeltaSpin); - editLayout->addRow(editorFontLayout); - m_editBox->setLayout(editLayout); - - m_smartIM->hide(); - m_keyModeCB->setCurrentIndex(0); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_readBox); - mainLayout->addWidget(m_editBox); - setLayout(mainLayout); -} - -void VReadEditTab::showTipsAboutAutoSave() -{ - if (m_autoSave->isChecked() && m_swapFile->isChecked()) { - // Show a tooltip. - QPoint pos = m_editBox->mapToGlobal(QPoint(0, 0)); - QToolTip::showText(pos, - tr("It's recommended to enable \"Swap file\" " - "or \"Auto save\", not both"), - m_editBox); - } -} - -bool VReadEditTab::loadConfiguration() -{ - if (!loadWebZoomFactor()) { - return false; - } - - if (!loadFlashAnchor()) { - return false; - } - - if (!loadSwapFile()) { - return false; - } - - if (!loadAutoSave()) { - return false; - } - - if (!loadEditorZoomDelta()) { - return false; - } - - if (!loadEditorFontFamily()) { - return false; - } - - if (!loadKeyMode()) { - return false; - } - - return true; -} - -bool VReadEditTab::saveConfiguration() -{ - if (!saveWebZoomFactor()) { - return false; - } - - if (!saveFlashAnchor()) { - return false; - } - - if (!saveSwapFile()) { - return false; - } - - if (!saveAutoSave()) { - return false; - } - - if (!saveEditorZoomDelta()) { - return false; - } - - if (!saveEditorFontFamily()) { - return false; - } - - if (!saveKeyMode()) { - return false; - } - - return true; -} - -bool VReadEditTab::loadWebZoomFactor() -{ - qreal factor = g_config->getWebZoomFactor(); - bool customFactor = g_config->isCustomWebZoomFactor(); - if (customFactor) { - if (factor < c_webZoomFactorMin || factor > c_webZoomFactorMax) { - factor = 1; - } - m_customWebZoom->setChecked(true); - m_webZoomFactorSpin->setValue(factor); - } else { - m_customWebZoom->setChecked(false); - m_webZoomFactorSpin->setValue(factor); - m_webZoomFactorSpin->setEnabled(false); - } - - return true; -} - -bool VReadEditTab::saveWebZoomFactor() -{ - if (m_customWebZoom->isChecked()) { - g_config->setWebZoomFactor(m_webZoomFactorSpin->value()); - } else { - g_config->setWebZoomFactor(-1); - } - - return true; -} - -bool VReadEditTab::loadEditorZoomDelta() -{ - m_editorZoomDeltaSpin->setValue(g_config->getEditorZoomDelta()); - return true; -} - -bool VReadEditTab::saveEditorZoomDelta() -{ - g_config->setEditorZoomDelta(m_editorZoomDeltaSpin->value()); - return true; -} - -bool VReadEditTab::loadEditorFontFamily() -{ - const QString &family = g_config->getEditorFontFamily(); - m_customEditorFont->setChecked(!family.isEmpty()); - - m_editorFontFamilyCB->setCurrentFont(g_config->getMdEditFont()); - m_editorFontFamilyCB->setEnabled(m_customEditorFont->isChecked()); - return true; -} - -bool VReadEditTab::saveEditorFontFamily() -{ - QString family; - if (m_customEditorFont->isChecked()) { - QFont font = m_editorFontFamilyCB->currentFont(); - family = font.family(); - } - - if (family != g_config->getEditorFontFamily()) { - g_config->setEditorFontFamily(family); - m_settingsDlg->setNeedUpdateEditorFont(true); - } - - return true; -} - -bool VReadEditTab::loadFlashAnchor() -{ - m_flashAnchor->setChecked(g_config->getEnableFlashAnchor()); - return true; -} - -bool VReadEditTab::saveFlashAnchor() -{ - g_config->setEnableFlashAnchor(m_flashAnchor->isChecked()); - return true; -} - -bool VReadEditTab::loadSwapFile() -{ - m_swapFile->setChecked(g_config->getEnableBackupFile()); - return true; -} - -bool VReadEditTab::saveSwapFile() -{ - g_config->setEnableBackupFile(m_swapFile->isChecked()); - return true; -} - -bool VReadEditTab::loadAutoSave() -{ - m_autoSave->setChecked(g_config->getEnableAutoSave()); - return true; -} - -bool VReadEditTab::saveAutoSave() -{ - g_config->setEnableAutoSave(m_autoSave->isChecked()); - return true; -} - -bool VReadEditTab::loadKeyMode() -{ - m_keyModeCB->setCurrentIndex(m_keyModeCB->findData((int)g_config->getKeyMode())); - m_smartIM->setChecked(g_config->getEnableSmartImInVimMode()); - return true; -} - -bool VReadEditTab::saveKeyMode() -{ - g_config->setKeyMode((KeyMode)m_keyModeCB->currentData().toInt()); - g_config->setEnableSmartImInVimMode(m_smartIM->isChecked()); - return true; -} - -VNoteManagementTab::VNoteManagementTab(QWidget *p_parent) - : QWidget(p_parent) -{ - m_noteBox = new QGroupBox(tr("Notes")); - m_externalBox = new QGroupBox(tr("External Files")); - - // Note. - // Image folder. - m_customImageFolder = new QCheckBox(tr("Custom image folder"), this); - m_customImageFolder->setToolTip(tr("Set the global name of the image folder to hold images " - "of notes (restart VNote to make it work)")); - connect(m_customImageFolder, &QCheckBox::stateChanged, - this, &VNoteManagementTab::customImageFolderChanged); - - m_imageFolderEdit = new VLineEdit(this); - m_imageFolderEdit->setPlaceholderText(tr("Name of the image folder")); - m_imageFolderEdit->setToolTip(m_customImageFolder->toolTip()); - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), this); - m_imageFolderEdit->setValidator(validator); - - QHBoxLayout *imageFolderLayout = new QHBoxLayout(); - imageFolderLayout->addWidget(m_customImageFolder); - imageFolderLayout->addWidget(m_imageFolderEdit); - - // Attachment folder. - m_customAttachmentFolder = new QCheckBox(tr("Custom attachment folder"), this); - m_customAttachmentFolder->setToolTip(tr("Set the global name of the attachment folder to hold attachments " - "of notes (restart VNote to make it work)")); - connect(m_customAttachmentFolder, &QCheckBox::stateChanged, - this, &VNoteManagementTab::customAttachmentFolderChanged); - - m_attachmentFolderEdit = new VLineEdit(this); - m_attachmentFolderEdit->setPlaceholderText(tr("Name of the attachment folder")); - m_attachmentFolderEdit->setToolTip(m_customAttachmentFolder->toolTip()); - validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), this); - m_attachmentFolderEdit->setValidator(validator); - - QHBoxLayout *attachmentFolderLayout = new QHBoxLayout(); - attachmentFolderLayout->addWidget(m_customAttachmentFolder); - attachmentFolderLayout->addWidget(m_attachmentFolderEdit); - - // Single click open. - m_singleClickOpen = new QCheckBox(tr("Single click to open a note in current tab"), this); - m_singleClickOpen->setToolTip(tr("Single click a note in the notes list to open it in current tab, " - "double click to open it in a new tab")); - - QFormLayout *noteLayout = new QFormLayout(); - noteLayout->addRow(imageFolderLayout); - noteLayout->addRow(attachmentFolderLayout); - noteLayout->addRow(m_singleClickOpen); - m_noteBox->setLayout(noteLayout); - - // External File. - // Image folder. - m_customImageFolderExt = new QCheckBox(tr("Custom image folder"), this); - m_customImageFolderExt->setToolTip(tr("Set the path of the global image folder to hold images " - "of external files (restart VNote to make it work).\nYou " - "could use both absolute or relative path here. If " - "absolute path is used, VNote will not manage\nthose images, " - "so you need to clean up unused images manually.")); - connect(m_customImageFolderExt, &QCheckBox::stateChanged, - this, &VNoteManagementTab::customImageFolderExtChanged); - - m_imageFolderEditExt = new VLineEdit(this); - m_imageFolderEditExt->setToolTip(m_customImageFolderExt->toolTip()); - m_imageFolderEditExt->setPlaceholderText(tr("Name of the image folder")); - - QHBoxLayout *imageFolderExtLayout = new QHBoxLayout(); - imageFolderExtLayout->addWidget(m_customImageFolderExt); - imageFolderExtLayout->addWidget(m_imageFolderEditExt); - - QFormLayout *externalLayout = new QFormLayout(); - externalLayout->addRow(imageFolderExtLayout); - m_externalBox->setLayout(externalLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_noteBox); - mainLayout->addWidget(m_externalBox); - - setLayout(mainLayout); -} - -bool VNoteManagementTab::loadConfiguration() -{ - if (!loadImageFolder()) { - return false; - } - - if (!loadAttachmentFolder()) { - return false; - } - - if (!loadImageFolderExt()) { - return false; - } - - if (!loadSingleClickOpen()) { - return false; - } - - return true; -} - -bool VNoteManagementTab::saveConfiguration() -{ - if (!saveImageFolder()) { - return false; - } - - if (!saveAttachmentFolder()) { - return false; - } - - if (!saveImageFolderExt()) { - return false; - } - - if (!saveSingleClickOpen()) { - return false; - } - - return true; -} - -bool VNoteManagementTab::loadImageFolder() -{ - bool isCustom = g_config->isCustomImageFolder(); - - m_customImageFolder->setChecked(isCustom); - m_imageFolderEdit->setText(g_config->getImageFolder()); - m_imageFolderEdit->setEnabled(isCustom); - - return true; -} - -bool VNoteManagementTab::saveImageFolder() -{ - if (m_customImageFolder->isChecked()) { - g_config->setImageFolder(m_imageFolderEdit->text()); - } else { - g_config->setImageFolder(""); - } - - return true; -} - -void VNoteManagementTab::customImageFolderChanged(int p_state) -{ - if (p_state == Qt::Checked) { - m_imageFolderEdit->setEnabled(true); - m_imageFolderEdit->selectAll(); - m_imageFolderEdit->setFocus(); - } else { - m_imageFolderEdit->setEnabled(false); - } -} - -bool VNoteManagementTab::loadAttachmentFolder() -{ - bool isCustom = g_config->isCustomAttachmentFolder(); - - m_customAttachmentFolder->setChecked(isCustom); - m_attachmentFolderEdit->setText(g_config->getAttachmentFolder()); - m_attachmentFolderEdit->setEnabled(isCustom); - - return true; -} - -bool VNoteManagementTab::saveAttachmentFolder() -{ - if (m_customAttachmentFolder->isChecked()) { - g_config->setAttachmentFolder(m_attachmentFolderEdit->text()); - } else { - g_config->setAttachmentFolder(""); - } - - return true; -} - -void VNoteManagementTab::customAttachmentFolderChanged(int p_state) -{ - if (p_state == Qt::Checked) { - m_attachmentFolderEdit->setEnabled(true); - m_attachmentFolderEdit->selectAll(); - m_attachmentFolderEdit->setFocus(); - } else { - m_attachmentFolderEdit->setEnabled(false); - } -} - -bool VNoteManagementTab::loadImageFolderExt() -{ - bool isCustom = g_config->isCustomImageFolderExt(); - - m_customImageFolderExt->setChecked(isCustom); - m_imageFolderEditExt->setText(g_config->getImageFolderExt()); - m_imageFolderEditExt->setEnabled(isCustom); - - return true; -} - -bool VNoteManagementTab::saveImageFolderExt() -{ - if (m_customImageFolderExt->isChecked()) { - g_config->setImageFolderExt(QDir::fromNativeSeparators(m_imageFolderEditExt->text())); - } else { - g_config->setImageFolderExt(""); - } - - return true; -} - -void VNoteManagementTab::customImageFolderExtChanged(int p_state) -{ - if (p_state == Qt::Checked) { - m_imageFolderEditExt->setEnabled(true); - m_imageFolderEditExt->selectAll(); - m_imageFolderEditExt->setFocus(); - } else { - m_imageFolderEditExt->setEnabled(false); - } -} - -bool VNoteManagementTab::loadSingleClickOpen() -{ - m_singleClickOpen->setChecked(g_config->getSingleClickClosePreviousTab()); - return true; -} - -bool VNoteManagementTab::saveSingleClickOpen() -{ - g_config->setSingleClickClosePreviousTab(m_singleClickOpen->isChecked()); - return true; -} - -VMarkdownTab::VMarkdownTab(QWidget *p_parent) - : QWidget(p_parent) -{ - // Default note open mode. - m_openModeCombo = VUtils::getComboBox(); - m_openModeCombo->setToolTip(tr("Default mode to open a file")); - m_openModeCombo->addItem(tr("Read Mode"), (int)OpenFileMode::Read); - m_openModeCombo->addItem(tr("Edit Mode"), (int)OpenFileMode::Edit); - - // Heading sequence. - m_headingSequenceTypeCombo = VUtils::getComboBox(); - m_headingSequenceTypeCombo->setToolTip(tr("Enable auto sequence for all headings (in the form like 1.2.3.4.)")); - m_headingSequenceTypeCombo->addItem(tr("Disabled"), (int)HeadingSequenceType::Disabled); - m_headingSequenceTypeCombo->addItem(tr("Enabled"), (int)HeadingSequenceType::Enabled); - m_headingSequenceTypeCombo->addItem(tr("Enabled for internal notes only"), (int)HeadingSequenceType::EnabledNoteOnly); - - m_headingSequenceLevelCombo = VUtils::getComboBox(); - m_headingSequenceLevelCombo->setToolTip(tr("Base level to start heading sequence")); - m_headingSequenceLevelCombo->addItem(tr("1"), 1); - m_headingSequenceLevelCombo->addItem(tr("2"), 2); - m_headingSequenceLevelCombo->addItem(tr("3"), 3); - m_headingSequenceLevelCombo->addItem(tr("4"), 4); - m_headingSequenceLevelCombo->addItem(tr("5"), 5); - m_headingSequenceLevelCombo->addItem(tr("6"), 6); - m_headingSequenceLevelCombo->setEnabled(false); - - connect(m_headingSequenceTypeCombo, static_cast(&QComboBox::activated), - this, [this](int p_index){ - if (p_index > -1) { - HeadingSequenceType type = (HeadingSequenceType)m_headingSequenceTypeCombo->itemData(p_index).toInt(); - m_headingSequenceLevelCombo->setEnabled(type != HeadingSequenceType::Disabled); - } - }); - - QHBoxLayout *headingSequenceLayout = new QHBoxLayout(); - headingSequenceLayout->addWidget(m_headingSequenceTypeCombo); - headingSequenceLayout->addWidget(m_headingSequenceLevelCombo); - - // Color column. - m_colorColumnEdit = new VLineEdit(); - m_colorColumnEdit->setToolTip(tr("Specify the screen column in fenced code block " - "which will be highlighted")); - QValidator *validator = new QRegExpValidator(QRegExp("\\d+"), this); - m_colorColumnEdit->setValidator(validator); - - QLabel *colorColumnLabel = new QLabel(tr("Color column:")); - colorColumnLabel->setToolTip(m_colorColumnEdit->toolTip()); - - // Code block copy button. - m_codeBlockCopyButtonCB = new QCheckBox(tr("Code block copy button")); - m_codeBlockCopyButtonCB->setToolTip(tr("Display a copy button at the top right corner of each code block to copy the content in read mode")); - - // MathJax. - m_mathjaxConfigEdit = new VLineEdit(); - m_mathjaxConfigEdit->setToolTip(tr("Location of MathJax JavaScript and its configuration " - "(restart VNote to make it work in in-place preview)")); - m_mathjaxConfigEdit->setPlaceholderText(tr("Need to prepend \"file://\" to local path")); - - // PlantUML. - m_plantUMLModeCombo = VUtils::getComboBox(); - m_plantUMLModeCombo->setToolTip(tr("Enable PlantUML support in Markdown")); - m_plantUMLModeCombo->addItem(tr("Disabled"), PlantUMLMode::DisablePlantUML); - m_plantUMLModeCombo->addItem(tr("Online Service"), PlantUMLMode::OnlinePlantUML); - m_plantUMLModeCombo->addItem(tr("Local JAR"), PlantUMLMode::LocalPlantUML); - - m_plantUMLServerEdit = new VLineEdit(); - m_plantUMLServerEdit->setToolTip(tr("Server address for online PlantUML")); - - m_plantUMLJarEdit = new VLineEdit(); - m_plantUMLJarEdit->setToolTip(tr("Location to the PlantUML JAR executable for local PlantUML")); - - QPushButton *plantUMLJarTestBtn = new QPushButton(tr("Test")); - plantUMLJarTestBtn->setToolTip(tr("Test PlantUML JAR configuration")); - connect(plantUMLJarTestBtn, &QPushButton::clicked, - this, [this]() { - QString jar = m_plantUMLJarEdit->text(); - if (jar.isEmpty() || !QFileInfo::exists(jar)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("The JAR file specified does not exist."), - tr("Please input the right absolute file path to the JAR file."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - if (!jar.trimmed().toLower().endsWith(".jar")) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Please specify the absolute file path to the JAR file."), - tr("It should be something like \"/path/to/plantuml.jar\"."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - QString msg; - bool ret = VPlantUMLHelper::testPlantUMLJar(jar, msg); - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Test %1.").arg((ret ? tr("succeeded") : tr("failed"))), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - }); - - QHBoxLayout *plantUMLLayout = new QHBoxLayout(); - plantUMLLayout->addWidget(m_plantUMLJarEdit); - plantUMLLayout->addWidget(plantUMLJarTestBtn); - - // Graphviz. - m_graphvizCB = new QCheckBox(tr("Graphviz")); - m_graphvizCB->setToolTip(tr("Enable Graphviz for drawing graph")); - - m_graphvizDotEdit = new VLineEdit(); - m_graphvizDotEdit->setPlaceholderText(tr("Empty to detect automatically")); - m_graphvizDotEdit->setToolTip(tr("Location to the GraphViz dot executable")); - - QPushButton *graphvizTestBtn = new QPushButton(tr("Test")); - graphvizTestBtn->setToolTip(tr("Test Graphviz executable configuration")); - connect(graphvizTestBtn, &QPushButton::clicked, - this, [this]() { - QString dot = m_graphvizDotEdit->text(); - if (dot.isEmpty()) { - dot = "dot"; - } - - QString msg; - bool ret = VGraphvizHelper::testGraphviz(dot, msg); - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Test %1.").arg((ret ? tr("succeeded") : tr("failed"))), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - }); - - QHBoxLayout *graphvizLayout = new QHBoxLayout(); - graphvizLayout->addWidget(m_graphvizDotEdit); - graphvizLayout->addWidget(graphvizTestBtn); - - QFormLayout *mainLayout = new QFormLayout(); - mainLayout->addRow(tr("Open mode:"), m_openModeCombo); - mainLayout->addRow(tr("Heading sequence:"), headingSequenceLayout); - mainLayout->addRow(colorColumnLabel, m_colorColumnEdit); - mainLayout->addRow(m_codeBlockCopyButtonCB); - mainLayout->addRow(tr("MathJax configuration:"), m_mathjaxConfigEdit); - mainLayout->addRow(tr("PlantUML:"), m_plantUMLModeCombo); - mainLayout->addRow(tr("PlantUML server:"), m_plantUMLServerEdit); - mainLayout->addRow(tr("PlantUML JAR:"), plantUMLLayout); - mainLayout->addRow(m_graphvizCB); - mainLayout->addRow(tr("Graphviz executable:"), graphvizLayout); - - setLayout(mainLayout); -} - -bool VMarkdownTab::loadConfiguration() -{ - if (!loadOpenMode()) { - return false; - } - - if (!loadHeadingSequence()) { - return false; - } - - if (!loadColorColumn()) { - return false; - } - - if (!loadCodeBlockCopyButton()) { - return false; - } - - if (!loadMathJax()) { - return false; - } - - if (!loadPlantUML()) { - return false; - } - - if (!loadGraphviz()) { - return false; - } - - return true; -} - -bool VMarkdownTab::saveConfiguration() -{ - if (!saveOpenMode()) { - return false; - } - - if (!saveHeadingSequence()) { - return false; - } - - if (!saveColorColumn()) { - return false; - } - - if (!saveCodeBlockCopyButton()) { - return false; - } - - if (!saveMathJax()) { - return false; - } - - if (!savePlantUML()) { - return false; - } - - if (!saveGraphviz()) { - return false; - } - - return true; -} - -bool VMarkdownTab::loadOpenMode() -{ - int mode = (int)g_config->getNoteOpenMode(); - bool found = false; - for (int i = 0; i < m_openModeCombo->count(); ++i) { - if (m_openModeCombo->itemData(i).toInt() == mode) { - m_openModeCombo->setCurrentIndex(i); - found = true; - break; - } - } - - Q_ASSERT(found); - return true; -} - -bool VMarkdownTab::saveOpenMode() -{ - int mode = m_openModeCombo->currentData().toInt(); - g_config->setNoteOpenMode((OpenFileMode)mode); - return true; -} - -bool VMarkdownTab::loadHeadingSequence() -{ - HeadingSequenceType type = g_config->getHeadingSequenceType(); - int level = g_config->getHeadingSequenceBaseLevel(); - if (level < 1 || level > 6) { - level = 1; - } - - int idx = m_headingSequenceTypeCombo->findData((int)type); - Q_ASSERT(idx > -1); - m_headingSequenceTypeCombo->setCurrentIndex(idx); - m_headingSequenceLevelCombo->setCurrentIndex(level - 1); - m_headingSequenceLevelCombo->setEnabled(type != HeadingSequenceType::Disabled); - - return true; -} - -bool VMarkdownTab::saveHeadingSequence() -{ - QVariant typeData = m_headingSequenceTypeCombo->currentData(); - Q_ASSERT(typeData.isValid()); - g_config->setHeadingSequenceType((HeadingSequenceType)typeData.toInt()); - g_config->setHeadingSequenceBaseLevel(m_headingSequenceLevelCombo->currentData().toInt()); - - return true; -} - -bool VMarkdownTab::loadColorColumn() -{ - int colorColumn = g_config->getColorColumn(); - m_colorColumnEdit->setText(QString::number(colorColumn <= 0 ? 0 : colorColumn)); - return true; -} - -bool VMarkdownTab::saveColorColumn() -{ - bool ok = false; - int colorColumn = m_colorColumnEdit->text().toInt(&ok); - if (ok && colorColumn >= 0) { - g_config->setColorColumn(colorColumn); - } - - return true; -} - -bool VMarkdownTab::loadCodeBlockCopyButton() -{ - m_codeBlockCopyButtonCB->setChecked(g_config->getEnableCodeBlockCopyButton()); - return true; -} - -bool VMarkdownTab::saveCodeBlockCopyButton() -{ - g_config->setEnableCodeBlockCopyButton(m_codeBlockCopyButtonCB->isChecked()); - return true; -} - -bool VMarkdownTab::loadMathJax() -{ - m_mathjaxConfigEdit->setText(g_config->getMathjaxJavascript()); - return true; -} - -bool VMarkdownTab::saveMathJax() -{ - g_config->setMathjaxJavascript(m_mathjaxConfigEdit->text()); - return true; -} - -bool VMarkdownTab::loadPlantUML() -{ - m_plantUMLModeCombo->setCurrentIndex(m_plantUMLModeCombo->findData(g_config->getPlantUMLMode())); - m_plantUMLServerEdit->setText(g_config->getPlantUMLServer()); - m_plantUMLJarEdit->setText(g_config->getPlantUMLJar()); - return true; -} - -bool VMarkdownTab::savePlantUML() -{ - g_config->setPlantUMLMode(m_plantUMLModeCombo->currentData().toInt()); - g_config->setPlantUMLServer(m_plantUMLServerEdit->text()); - g_config->setPlantUMLJar(m_plantUMLJarEdit->text()); - return true; -} - -bool VMarkdownTab::loadGraphviz() -{ - m_graphvizCB->setChecked(g_config->getEnableGraphviz()); - m_graphvizDotEdit->setText(g_config->getGraphvizDot()); - return true; -} - -bool VMarkdownTab::saveGraphviz() -{ - g_config->setEnableGraphviz(m_graphvizCB->isChecked()); - g_config->setGraphvizDot(m_graphvizDotEdit->text()); - return true; -} - -VMiscTab::VMiscTab(QWidget *p_parent) - : QWidget(p_parent) -{ - m_matchesInPageCB = new QCheckBox(tr("Highlight matches of a full-text search in page"), - this); - - QFormLayout *mainLayout = new QFormLayout(); - mainLayout->addRow(m_matchesInPageCB); - - setLayout(mainLayout); -} - -bool VMiscTab::loadConfiguration() -{ - if (!loadMatchesInPage()) { - return false; - } - return true; -} - -bool VMiscTab::saveConfiguration() -{ - if (!saveMatchesInPage()) { - return false; - } - - return true; -} - -bool VMiscTab::loadMatchesInPage() -{ - m_matchesInPageCB->setChecked(g_config->getHighlightMatchesInPage()); - return true; -} - -bool VMiscTab::saveMatchesInPage() -{ - g_config->setHighlightMatchesInPage(m_matchesInPageCB->isChecked()); - return true; -} - -VImageHostingTab::VImageHostingTab(QWidget *p_parent) - : QWidget(p_parent) -{ - QTabWidget *imageHostingTabWeg = new QTabWidget(this); - QWidget *githubImageHostingTab = new QWidget(); - QWidget *wechatImageHostingTab = new QWidget(); - QWidget *tencentImageHostingTab = new QWidget(); - QWidget *giteeImageHostingTab = new QWidget(); - imageHostingTabWeg->addTab(githubImageHostingTab, tr("GitHub")); - imageHostingTabWeg->addTab(giteeImageHostingTab, tr("Gitee")); - imageHostingTabWeg->addTab(wechatImageHostingTab, tr("WeChat")); - imageHostingTabWeg->addTab(tencentImageHostingTab, tr("Tencent Cloud")); - imageHostingTabWeg->setCurrentIndex(0); - - // Set the tab of GitHub image Hosting - m_githubPersonalAccessTokenEdit = new VLineEdit(); - m_githubPersonalAccessTokenEdit->setToolTip(tr("GitHub personal access token")); - m_githubPersonalAccessTokenEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_githubRepoNameEdit = new VLineEdit(); - m_githubRepoNameEdit->setToolTip(tr("Name of GitHub repository for image hosting")); - m_githubRepoNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_githubUserNameEdit = new VLineEdit(); - m_githubUserNameEdit->setToolTip(tr("User name of GitHub")); - m_githubUserNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_githubKeepImgScaleCB = new QCheckBox(tr("Keep image scale(such as '=100x')")); - m_githubDoNotReplaceLinkCB = new QCheckBox(tr("Copy the new content instead of replacing")); - - QFormLayout *githubLayout = new QFormLayout(); - githubLayout->addRow(tr("Personal access token:"), m_githubPersonalAccessTokenEdit); - githubLayout->addRow(tr("Repo name:"), m_githubRepoNameEdit); - githubLayout->addRow(tr("User name:"), m_githubUserNameEdit); - githubLayout->addRow(m_githubKeepImgScaleCB); - githubLayout->addRow(m_githubDoNotReplaceLinkCB); - - githubImageHostingTab->setLayout(githubLayout); - - // Set the tab of Gitee image Hosting - m_giteePersonalAccessTokenEdit = new VLineEdit(); - m_giteePersonalAccessTokenEdit->setToolTip(tr("Gitee personal access token")); - m_giteePersonalAccessTokenEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_giteeRepoNameEdit = new VLineEdit(); - m_giteeRepoNameEdit->setToolTip(tr("Name of Gitee repository for image hosting")); - m_giteeRepoNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_giteeUserNameEdit = new VLineEdit(); - m_giteeUserNameEdit->setToolTip(tr("User name of Gitee")); - m_giteeUserNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_giteeKeepImgScaleCB = new QCheckBox(tr("Keep image scale(such as '=100x')")); - m_giteeDoNotReplaceLinkCB = new QCheckBox(tr("Copy the new content instead of replacing")); - - QFormLayout *giteeLayout = new QFormLayout(); - giteeLayout->addRow(tr("Personal access token:"), m_giteePersonalAccessTokenEdit); - giteeLayout->addRow(tr("Repo name:"), m_giteeRepoNameEdit); - giteeLayout->addRow(tr("User name:"), m_giteeUserNameEdit); - giteeLayout->addRow(m_giteeKeepImgScaleCB); - giteeLayout->addRow(m_giteeDoNotReplaceLinkCB); - - giteeImageHostingTab->setLayout(giteeLayout); - - // Set the tab of Wechat image Hosting - m_wechatAppidEdit = new VLineEdit(); - m_wechatAppidEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_wechatSecretEdit = new VLineEdit(); - m_wechatSecretEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_markdown2WechatToolUrlEdit = new VLineEdit(); - m_markdown2WechatToolUrlEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_wechatKeepImgScaleCB = new QCheckBox(tr("Keep image scale(such as '=100x')")); - m_wechatDoNotReplaceLinkCB = new QCheckBox(tr("Copy the new content instead of replacing")); - - QFormLayout *wechatLayout = new QFormLayout(); - wechatLayout->addRow(tr("AppId:"), m_wechatAppidEdit); - wechatLayout->addRow(tr("AppSecret:"), m_wechatSecretEdit); - wechatLayout->addRow(tr("markdown2WechatToolUrl:"), m_markdown2WechatToolUrlEdit); - wechatLayout->addRow(m_wechatKeepImgScaleCB); - wechatLayout->addRow(m_wechatDoNotReplaceLinkCB); - - wechatImageHostingTab->setLayout(wechatLayout); - - // Set the tab of Tencent image Hosting. - m_tencentAccessDomainNameEdit = new VLineEdit(); - m_tencentAccessDomainNameEdit->setToolTip(tr("Tencent access domain name")); - m_tencentAccessDomainNameEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_tencentSecretIdEdit = new VLineEdit(); - m_tencentSecretIdEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_tencentSecretKeyEdit = new VLineEdit(); - m_tencentSecretKeyEdit->setMinimumWidth(250 * VUtils::calculateScaleFactor()); - m_tencentKeepImgScaleCB = new QCheckBox(tr("Keep image scale(such as '=100x')")); - m_tencentDoNotReplaceLinkCB = new QCheckBox(tr("Copy the new content instead of replacing")); - - QFormLayout *tencentLayout = new QFormLayout(); - tencentLayout->addRow(tr("Access domain name:"), m_tencentAccessDomainNameEdit); - tencentLayout->addRow(tr("SecretId:"), m_tencentSecretIdEdit); - tencentLayout->addRow(tr("SecretKey:"), m_tencentSecretKeyEdit); - tencentLayout->addRow(m_tencentKeepImgScaleCB); - tencentLayout->addRow(m_tencentDoNotReplaceLinkCB); - - tencentImageHostingTab->setLayout(tencentLayout); -} - -bool VImageHostingTab::loadWechatAppid() -{ - m_wechatAppidEdit->setText(g_config->getWechatAppid()); - return true; -} - -bool VImageHostingTab::saveWechatAppid() -{ - g_config->setWechatAppid(m_wechatAppidEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadWechatSecret() -{ - m_wechatSecretEdit->setText(g_config->getWechatSecret()); - return true; -} - -bool VImageHostingTab::saveWechatSecret() -{ - g_config->setWechatSecret(m_wechatSecretEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadMarkdown2WechatToolUrl() -{ - m_markdown2WechatToolUrlEdit->setText(g_config->getMarkdown2WechatToolUrl()); - return true; -} - -bool VImageHostingTab::saveMarkdown2WechatToolUrl() -{ - g_config->setMarkdown2WechatToolUrl(m_markdown2WechatToolUrlEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadWechatKeepImgScale() -{ - m_wechatKeepImgScaleCB->setChecked(g_config->getWechatKeepImgScale()); - return true; -} - -bool VImageHostingTab::saveWechatKeepImgScale() -{ - g_config->setWechatKeepImgScale(m_wechatKeepImgScaleCB->isChecked()); - return true; -} - -bool VImageHostingTab::loadWechatDoNotReplaceLink() -{ - m_wechatDoNotReplaceLinkCB->setChecked(g_config->getWechatDoNotReplaceLink()); - return true; -} - -bool VImageHostingTab::saveWechatDoNotReplaceLink() -{ - g_config->setWechatDoNotReplaceLink(m_wechatDoNotReplaceLinkCB->isChecked()); - return true; -} - -bool VImageHostingTab::loadGithubPersonalAccessToken() -{ - m_githubPersonalAccessTokenEdit->setText(g_config->getGithubPersonalAccessToken()); - return true; -} - -bool VImageHostingTab::saveGithubPersonalAccessToken() -{ - g_config->setGithubPersonalAccessToken(m_githubPersonalAccessTokenEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadGithubReposName() -{ - m_githubRepoNameEdit->setText(g_config->getGithubReposName()); - return true; -} - -bool VImageHostingTab::saveGithubReposName() -{ - g_config->setGithubReposName(m_githubRepoNameEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadGithubUserName() -{ - m_githubUserNameEdit->setText(g_config->getGithubUserName()); - return true; -} - -bool VImageHostingTab::saveGithubUserName() -{ - g_config->setGithubUserName(m_githubUserNameEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadGithubKeepImgScale() -{ - m_githubKeepImgScaleCB->setChecked(g_config->getGithubKeepImgScale()); - return true; -} - -bool VImageHostingTab::saveGithubKeepImgScale() -{ - g_config->setGithubKeepImgScale(m_githubKeepImgScaleCB->isChecked()); - return true; -} - -bool VImageHostingTab::loadGithubDoNotReplaceLink() -{ - m_githubDoNotReplaceLinkCB->setChecked(g_config->getGithubDoNotReplaceLink()); - return true; -} - -bool VImageHostingTab::saveGithubDoNotReplaceLink() -{ - g_config->setGithubDoNotReplaceLink(m_githubDoNotReplaceLinkCB->isChecked()); - return true; -} - -bool VImageHostingTab::loadTencentAccessDomainName() -{ - m_tencentAccessDomainNameEdit->setText(g_config->getTencentAccessDomainName()); - return true; -} - -bool VImageHostingTab::saveTencentAccessDomainName() -{ - g_config->setTencentAccessDomainName(m_tencentAccessDomainNameEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadTencentSecretId() -{ - m_tencentSecretIdEdit->setText(g_config->getTencentSecretId()); - return true; -} - -bool VImageHostingTab::saveTencentSecretId() -{ - g_config->setTencentSecretId(m_tencentSecretIdEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadTencentSecretKey() -{ - m_tencentSecretKeyEdit->setText(g_config->getTencentSecretKey()); - return true; -} - -bool VImageHostingTab::saveTencentSecretKey() -{ - g_config->setTencentSecretKey(m_tencentSecretKeyEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadTencentKeepImgScale() -{ - m_tencentKeepImgScaleCB->setChecked(g_config->getTencentKeepImgScale()); - return true; -} - -bool VImageHostingTab::saveTencentKeepImgScale() -{ - g_config->setTencentKeepImgScale(m_tencentKeepImgScaleCB->isChecked()); - return true; -} - -bool VImageHostingTab::loadTencentDoNotReplaceLink() -{ - m_tencentDoNotReplaceLinkCB->setChecked(g_config->getTencentDoNotReplaceLink()); - return true; -} - -bool VImageHostingTab::saveTencentDoNotReplaceLink() -{ - g_config->setTencentDoNotReplaceLink(m_tencentDoNotReplaceLinkCB->isChecked()); - return true; -} - -bool VImageHostingTab::loadGiteePersonalAccessToken() -{ - m_giteePersonalAccessTokenEdit->setText(g_config->getGiteePersonalAccessToken()); - return true; -} - -bool VImageHostingTab::saveGiteePersonalAccessToken() -{ - g_config->setGiteePersonalAccessToken(m_giteePersonalAccessTokenEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadGiteeReposName() -{ - m_giteeRepoNameEdit->setText(g_config->getGiteeReposName()); - return true; -} - -bool VImageHostingTab::saveGiteeReposName() -{ - g_config->setGiteeReposName(m_giteeRepoNameEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadGiteeUserName() -{ - m_giteeUserNameEdit->setText(g_config->getGiteeUserName()); - return true; -} - -bool VImageHostingTab::saveGiteeUserName() -{ - g_config->setGiteeUserName(m_giteeUserNameEdit->text().trimmed()); - return true; -} - -bool VImageHostingTab::loadGiteeKeepImgScale() -{ - m_giteeKeepImgScaleCB->setChecked(g_config->getGiteeKeepImgScale()); - return true; -} - -bool VImageHostingTab::saveGiteeKeepImgScale() -{ - g_config->setGiteeKeepImgScale(m_giteeKeepImgScaleCB->isChecked()); - return true; -} - -bool VImageHostingTab::loadGiteeDoNotReplaceLink() -{ - m_giteeDoNotReplaceLinkCB->setChecked(g_config->getGiteeDoNotReplaceLink()); - return true; -} - -bool VImageHostingTab::saveGiteeDoNotReplaceLink() -{ - g_config->setGiteeDoNotReplaceLink(m_giteeDoNotReplaceLinkCB->isChecked()); - return true; -} - -bool VImageHostingTab::loadConfiguration() -{ - if(!loadGithubPersonalAccessToken()){ - return false; - } - if(!loadGithubReposName()){ - return false; - } - if(!loadGithubUserName()){ - return false; - } - if(!loadGithubKeepImgScale()){ - return false; - } - if(!loadGithubDoNotReplaceLink()){ - return false; - } - if(!loadGiteePersonalAccessToken()){ - return false; - } - if(!loadGiteeReposName()){ - return false; - } - if(!loadGiteeUserName()){ - return false; - } - if(!loadGiteeKeepImgScale()){ - return false; - } - if(!loadGiteeDoNotReplaceLink()){ - return false; - } - if(!loadWechatAppid()){ - return false; - } - if(!loadWechatSecret()){ - return false; - } - if(!loadMarkdown2WechatToolUrl()){ - return false; - } - if(!loadWechatKeepImgScale()){ - return false; - } - if(!loadWechatDoNotReplaceLink()){ - return false; - } - if(!loadTencentAccessDomainName()){ - return false; - } - if(!loadTencentSecretId()){ - return false; - } - if(!loadTencentSecretKey()){ - return false; - } - if(!loadTencentKeepImgScale()){ - return false; - } - if(!loadTencentDoNotReplaceLink()){ - return false; - } - return true; -} - -bool VImageHostingTab::saveConfiguration() -{ - if(!saveGithubPersonalAccessToken()){ - return false; - } - if(!saveGithubReposName()){ - return false; - } - if(!saveGithubUserName()){ - return false; - } - if(!saveGithubKeepImgScale()){ - return false; - } - if(!saveGithubDoNotReplaceLink()){ - return false; - } - if(!saveGiteePersonalAccessToken()){ - return false; - } - if(!saveGiteeReposName()){ - return false; - } - if(!saveGiteeUserName()){ - return false; - } - if(!saveGiteeKeepImgScale()){ - return false; - } - if(!saveGiteeDoNotReplaceLink()){ - return false; - } - if(!saveWechatAppid()){ - return false; - } - if(!saveWechatSecret()){ - return false; - } - if(!saveMarkdown2WechatToolUrl()){ - return false; - } - if(!saveWechatKeepImgScale()){ - return false; - } - if(!saveWechatDoNotReplaceLink()){ - return false; - } - if(!saveTencentAccessDomainName()){ - return false; - } - if(!saveTencentSecretId()){ - return false; - } - if(!saveTencentSecretKey()){ - return false; - } - if(!saveTencentKeepImgScale()){ - return false; - } - if(!saveTencentDoNotReplaceLink()){ - return false; - } - return true; -} diff --git a/src/dialog/vsettingsdialog.h b/src/dialog/vsettingsdialog.h deleted file mode 100644 index fa5b5b06..00000000 --- a/src/dialog/vsettingsdialog.h +++ /dev/null @@ -1,421 +0,0 @@ -#ifndef VSETTINGSDIALOG_H -#define VSETTINGSDIALOG_H - -#include -#include -#include -#include - -class QDialogButtonBox; -class QComboBox; -class QGroupBox; -class QDoubleSpinBox; -class QSpinBox; -class QCheckBox; -class VLineEdit; -class QStackedLayout; -class QListWidget; -class QPlainTextEdit; -class QVBoxLayout; -class QFontComboBox; - -class VSettingsDialog; - -class VGeneralTab : public QWidget -{ - Q_OBJECT -public: - explicit VGeneralTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - -private: - QLayout *setupStartupPagesLayout(); - - bool loadLanguage(); - bool saveLanguage(); - - bool loadSystemTray(); - bool saveSystemTray(); - - bool loadStartupPageType(); - bool saveStartupPageType(); - - bool loadQuickAccess(); - bool saveQuickAccess(); - - bool loadKeyboardLayoutMapping(); - bool saveKeyboardLayoutMapping(); - - bool loadOpenGL(); - bool saveOpenGL(); - - // Language - QComboBox *m_langCombo; - - // System tray - QCheckBox *m_systemTray; - - // Startup page type. - QComboBox *m_startupPageTypeCombo; - - // Startup pages. - QPlainTextEdit *m_startupPagesEdit; - - // Startup pages add files button. - QPushButton *m_startupPagesAddBtn; - - // Quick access note path. - VLineEdit *m_quickAccessEdit; - - // Keyboard layout mappings. - QComboBox *m_keyboardLayoutCombo; - -#if defined(Q_OS_WIN) - // Windows OpenGL. - QComboBox *m_openGLCombo; -#endif - - static const QVector c_availableLangs; -}; - -class VLookTab: public QWidget -{ - Q_OBJECT -public: - explicit VLookTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - -private: - bool loadToolBarIconSize(); - bool saveToolBarIconSize(); - - // Tool bar icon size. - QSpinBox *m_tbIconSizeSpin; -}; - -class VReadEditTab : public QWidget -{ - Q_OBJECT -public: - explicit VReadEditTab(VSettingsDialog *p_dlg, QWidget *p_parent = 0); - - bool loadConfiguration(); - bool saveConfiguration(); - -private: - bool loadWebZoomFactor(); - bool saveWebZoomFactor(); - - bool loadSwapFile(); - bool saveSwapFile(); - - bool loadAutoSave(); - bool saveAutoSave(); - - void showTipsAboutAutoSave(); - - bool loadKeyMode(); - bool saveKeyMode(); - - bool loadFlashAnchor(); - bool saveFlashAnchor(); - - bool loadEditorZoomDelta(); - bool saveEditorZoomDelta(); - - bool loadEditorFontFamily(); - bool saveEditorFontFamily(); - - VSettingsDialog *m_settingsDlg; - - // Web zoom factor. - QCheckBox *m_customWebZoom; - QDoubleSpinBox *m_webZoomFactorSpin; - - // Web flash anchor. - QCheckBox *m_flashAnchor; - - // Swap file. - QCheckBox *m_swapFile; - - // Auto save. - QCheckBox *m_autoSave; - - // Key mode. - QComboBox *m_keyModeCB; - - // Smart IM in Vim mode. - QCheckBox *m_smartIM; - - // Editor zoom delta. - QSpinBox *m_editorZoomDeltaSpin; - - // Editor font family. - QCheckBox *m_customEditorFont; - QFontComboBox *m_editorFontFamilyCB; - - QGroupBox *m_readBox; - QGroupBox *m_editBox; -}; - -class VNoteManagementTab : public QWidget -{ - Q_OBJECT -public: - explicit VNoteManagementTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - -private slots: - void customImageFolderChanged(int p_state); - void customImageFolderExtChanged(int p_state); - void customAttachmentFolderChanged(int p_state); - -private: - bool loadImageFolder(); - bool saveImageFolder(); - - bool loadImageFolderExt(); - bool saveImageFolderExt(); - - bool loadAttachmentFolder(); - bool saveAttachmentFolder(); - - bool loadSingleClickOpen(); - bool saveSingleClickOpen(); - - QGroupBox *m_noteBox; - QGroupBox *m_externalBox; - - // Image folder. - QCheckBox *m_customImageFolder; - VLineEdit *m_imageFolderEdit; - - // Image folder of External File. - QCheckBox *m_customImageFolderExt; - VLineEdit *m_imageFolderEditExt; - - // Attachment folder. - QCheckBox *m_customAttachmentFolder; - VLineEdit *m_attachmentFolderEdit; - - // Single click to open note in current tab. - QCheckBox *m_singleClickOpen; -}; - -class VMarkdownTab : public QWidget -{ - Q_OBJECT -public: - explicit VMarkdownTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - -private: - bool loadOpenMode(); - bool saveOpenMode(); - - bool loadHeadingSequence(); - bool saveHeadingSequence(); - - bool loadColorColumn(); - bool saveColorColumn(); - - bool loadCodeBlockCopyButton(); - bool saveCodeBlockCopyButton(); - - bool loadMathJax(); - bool saveMathJax(); - - bool loadPlantUML(); - bool savePlantUML(); - - bool loadGraphviz(); - bool saveGraphviz(); - - // Default note open mode for markdown. - QComboBox *m_openModeCombo; - - // Whether enable heading sequence. - QComboBox *m_headingSequenceTypeCombo; - QComboBox *m_headingSequenceLevelCombo; - - // Color column in code block. - VLineEdit *m_colorColumnEdit; - - // Copy button in code block. - QCheckBox *m_codeBlockCopyButtonCB; - - // MathJax. - VLineEdit *m_mathjaxConfigEdit; - - // PlantUML. - QComboBox *m_plantUMLModeCombo; - VLineEdit *m_plantUMLServerEdit; - VLineEdit *m_plantUMLJarEdit; - - // Graphviz. - QCheckBox *m_graphvizCB; - VLineEdit *m_graphvizDotEdit; -}; - -class VMiscTab : public QWidget -{ - Q_OBJECT -public: - explicit VMiscTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - -private: - bool loadMatchesInPage(); - bool saveMatchesInPage(); - - // Highlight matches in page. - QCheckBox *m_matchesInPageCB; -}; - -class VImageHostingTab : public QWidget -{ - Q_OBJECT -public: - explicit VImageHostingTab(QWidget *p_parent = 0); - bool loadConfiguration(); - bool saveConfiguration(); - -private: - bool loadGithubPersonalAccessToken(); - bool saveGithubPersonalAccessToken(); - - bool loadGithubReposName(); - bool saveGithubReposName(); - - bool loadGithubUserName(); - bool saveGithubUserName(); - - bool loadGithubKeepImgScale(); - bool saveGithubKeepImgScale(); - - bool loadGithubDoNotReplaceLink(); - bool saveGithubDoNotReplaceLink(); - - bool loadWechatAppid(); - bool saveWechatAppid(); - - bool loadWechatSecret(); - bool saveWechatSecret(); - - bool loadMarkdown2WechatToolUrl(); - bool saveMarkdown2WechatToolUrl(); - - bool loadWechatKeepImgScale(); - bool saveWechatKeepImgScale(); - - bool loadWechatDoNotReplaceLink(); - bool saveWechatDoNotReplaceLink(); - - bool loadTencentAccessDomainName(); - bool saveTencentAccessDomainName(); - - bool loadTencentSecretId(); - bool saveTencentSecretId(); - - bool loadTencentSecretKey(); - bool saveTencentSecretKey(); - - bool loadTencentKeepImgScale(); - bool saveTencentKeepImgScale(); - - bool loadTencentDoNotReplaceLink(); - bool saveTencentDoNotReplaceLink(); - - bool loadGiteePersonalAccessToken(); - bool saveGiteePersonalAccessToken(); - - bool loadGiteeReposName(); - bool saveGiteeReposName(); - - bool loadGiteeUserName(); - bool saveGiteeUserName(); - - bool loadGiteeKeepImgScale(); - bool saveGiteeKeepImgScale(); - - bool loadGiteeDoNotReplaceLink(); - bool saveGiteeDoNotReplaceLink(); - - // Github configuration edit. - VLineEdit *m_githubPersonalAccessTokenEdit; - VLineEdit *m_githubRepoNameEdit; - VLineEdit *m_githubUserNameEdit; - QCheckBox *m_githubKeepImgScaleCB; - QCheckBox *m_githubDoNotReplaceLinkCB; - - // Gitee configuration edit. - VLineEdit *m_giteePersonalAccessTokenEdit; - VLineEdit *m_giteeRepoNameEdit; - VLineEdit *m_giteeUserNameEdit; - QCheckBox *m_giteeKeepImgScaleCB; - QCheckBox *m_giteeDoNotReplaceLinkCB; - - // Wechat configuration edit. - VLineEdit *m_wechatAppidEdit; - VLineEdit *m_wechatSecretEdit; - VLineEdit *m_markdown2WechatToolUrlEdit; - QCheckBox *m_wechatKeepImgScaleCB; - QCheckBox *m_wechatDoNotReplaceLinkCB; - - // Tencent configuration edit. - VLineEdit *m_tencentAccessDomainNameEdit; - VLineEdit *m_tencentSecretIdEdit; - VLineEdit *m_tencentSecretKeyEdit; - QCheckBox *m_tencentKeepImgScaleCB; - QCheckBox *m_tencentDoNotReplaceLinkCB; -}; - -class VSettingsDialog : public QDialog -{ - Q_OBJECT -public: - explicit VSettingsDialog(QWidget *p_parent = 0); - - void setNeedUpdateEditorFont(bool p_need); - bool getNeedUpdateEditorFont() const; - -private slots: - void saveConfiguration(); - - void resetVNote(); - - void resetLayout(); - -private: - void loadConfiguration(); - - void addTab(QWidget *p_widget, const QString &p_label); - - QStackedLayout *m_tabs; - QListWidget *m_tabList; - QDialogButtonBox *m_btnBox; - - // Reset all the configuration of VNote. - QPushButton *m_resetVNoteBtn; - - // Reset the layout. - QPushButton *m_resetLayoutBtn; - - bool m_needUpdateEditorFont; -}; - -inline void VSettingsDialog::setNeedUpdateEditorFont(bool p_need) -{ - m_needUpdateEditorFont = p_need; -} - -inline bool VSettingsDialog::getNeedUpdateEditorFont() const -{ - return m_needUpdateEditorFont; -} -#endif // VSETTINGSDIALOG_H diff --git a/src/dialog/vsortdialog.cpp b/src/dialog/vsortdialog.cpp deleted file mode 100644 index 614ad047..00000000 --- a/src/dialog/vsortdialog.cpp +++ /dev/null @@ -1,251 +0,0 @@ -#include "vsortdialog.h" - -#include - -VSortDialog::VSortDialog(const QString &p_title, - const QString &p_info, - QWidget *p_parent) - : QDialog(p_parent) -{ - setupUI(p_title, p_info); -} - -void VSortDialog::setupUI(const QString &p_title, const QString &p_info) -{ - QLabel *infoLabel = NULL; - if (!p_info.isEmpty()) { - infoLabel = new QLabel(p_info); - infoLabel->setWordWrap(true); - } - - m_treeWidget = new VTreeWidget(); - m_treeWidget->setRootIsDecorated(false); - m_treeWidget->setSelectionMode(QAbstractItemView::ContiguousSelection); - m_treeWidget->setDragDropMode(QAbstractItemView::InternalMove); - connect(m_treeWidget, &VTreeWidget::rowsMoved, - this, [this](int p_first, int p_last, int p_row) { - Q_UNUSED(p_first); - Q_UNUSED(p_last); - QTreeWidgetItem *item = m_treeWidget->topLevelItem(p_row); - if (item) { - m_treeWidget->setCurrentItem(item); - - // Select all items back. - int cnt = p_last - p_first + 1; - for (int i = 0; i < cnt; ++i) { - QTreeWidgetItem *it = m_treeWidget->topLevelItem(p_row + i); - if (it) { - it->setSelected(true); - } - } - } - }); - - // Buttons for top/up/down/bottom. - m_topBtn = new QPushButton(tr("&Top")); - m_topBtn->setToolTip(tr("Move selected items to top")); - connect(m_topBtn, &QPushButton::clicked, - this, [this]() { - this->handleMoveOperation(MoveOperation::Top); - }); - - m_upBtn = new QPushButton(tr("&Up")); - m_upBtn->setToolTip(tr("Move selected items up")); - connect(m_upBtn, &QPushButton::clicked, - this, [this]() { - this->handleMoveOperation(MoveOperation::Up); - }); - - m_downBtn = new QPushButton(tr("&Down")); - m_downBtn->setToolTip(tr("Move selected items down")); - connect(m_downBtn, &QPushButton::clicked, - this, [this]() { - this->handleMoveOperation(MoveOperation::Down); - }); - - m_bottomBtn = new QPushButton(tr("&Bottom")); - m_bottomBtn->setToolTip(tr("Move selected items to bottom")); - connect(m_bottomBtn, &QPushButton::clicked, - this, [this]() { - this->handleMoveOperation(MoveOperation::Bottom); - }); - - QVBoxLayout *btnLayout = new QVBoxLayout; - btnLayout->addWidget(m_topBtn); - btnLayout->addWidget(m_upBtn); - btnLayout->addWidget(m_downBtn); - btnLayout->addWidget(m_bottomBtn); - btnLayout->addStretch(); - - QHBoxLayout *midLayout = new QHBoxLayout; - midLayout->addWidget(m_treeWidget); - midLayout->addLayout(btnLayout); - - // Ok is the default button. - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - - QVBoxLayout *mainLayout = new QVBoxLayout; - if (infoLabel) { - mainLayout->addWidget(infoLabel); - } - - mainLayout->addLayout(midLayout); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - setWindowTitle(p_title); -} - -void VSortDialog::treeUpdated() -{ - int cols = m_treeWidget->columnCount(); - for (int i = 0; i < cols; ++i) { - m_treeWidget->resizeColumnToContents(i); - } - - QHeaderView *header = m_treeWidget->header(); - if (header) { - header->setStretchLastSection(true); - } - - // We just need single level. - int cnt = m_treeWidget->topLevelItemCount(); - for (int i = 0; i < cnt; ++i) { - QTreeWidgetItem *item = m_treeWidget->topLevelItem(i); - item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled); - } - - m_treeWidget->sortByColumn(-1); - m_treeWidget->setSortingEnabled(true); -} - -void VSortDialog::handleMoveOperation(MoveOperation p_op) -{ - const QList selectedItems = m_treeWidget->selectedItems(); - if (selectedItems.isEmpty()) { - return; - } - - int first = m_treeWidget->topLevelItemCount(); - int last = -1; - for (auto const & it : selectedItems) { - int idx = m_treeWidget->indexOfTopLevelItem(it); - Q_ASSERT(idx > -1); - if (idx < first) { - first = idx; - } - - if (idx > last) { - last = idx; - } - } - - Q_ASSERT(first <= last && (last - first + 1) == selectedItems.size()); - QTreeWidgetItem *firstItem = NULL; - - switch (p_op) { - case MoveOperation::Top: - if (first == 0) { - break; - } - - m_treeWidget->clearSelection(); - - // Insert item[last] to index 0 repeatedly. - for (int i = last - first; i >= 0; --i) { - QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(last); - Q_ASSERT(item); - m_treeWidget->insertTopLevelItem(0, item); - item->setSelected(true); - } - - firstItem = m_treeWidget->topLevelItem(0); - - break; - - case MoveOperation::Up: - if (first == 0) { - break; - } - - m_treeWidget->clearSelection(); - - // Insert item[last] to index (first -1) repeatedly. - for (int i = last - first; i >= 0; --i) { - QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(last); - Q_ASSERT(item); - m_treeWidget->insertTopLevelItem(first - 1, item); - item->setSelected(true); - } - - firstItem = m_treeWidget->topLevelItem(first - 1); - - break; - - case MoveOperation::Down: - if (last == m_treeWidget->topLevelItemCount() - 1) { - break; - } - - m_treeWidget->clearSelection(); - - // Insert item[first] to index (last) repeatedly. - for (int i = last - first; i >= 0; --i) { - QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(first); - Q_ASSERT(item); - m_treeWidget->insertTopLevelItem(last + 1, item); - item->setSelected(true); - - if (!firstItem) { - firstItem = item; - } - } - - break; - - case MoveOperation::Bottom: - if (last == m_treeWidget->topLevelItemCount() - 1) { - break; - } - - m_treeWidget->clearSelection(); - - // Insert item[first] to the last of the tree repeatedly. - for (int i = last - first; i >= 0; --i) { - QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(first); - Q_ASSERT(item); - m_treeWidget->addTopLevelItem(item); - item->setSelected(true); - - if (!firstItem) { - firstItem = item; - } - } - - break; - - default: - return; - } - - if (firstItem) { - m_treeWidget->setCurrentItem(firstItem); - m_treeWidget->scrollToItem(firstItem); - } -} - -QVector VSortDialog::getSortedData() const -{ - int cnt = m_treeWidget->topLevelItemCount(); - QVector data(cnt); - for (int i = 0; i < cnt; ++i) { - QTreeWidgetItem *item = m_treeWidget->topLevelItem(i); - Q_ASSERT(item); - data[i] = item->data(0, Qt::UserRole); - } - - return data; -} diff --git a/src/dialog/vsortdialog.h b/src/dialog/vsortdialog.h deleted file mode 100644 index 7e77ed57..00000000 --- a/src/dialog/vsortdialog.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef VSORTDIALOG_H -#define VSORTDIALOG_H - -#include -#include - -#include "vtreewidget.h" - -class QPushButton; -class QDialogButtonBox; - -class VSortDialog : public QDialog -{ - Q_OBJECT -public: - VSortDialog(const QString &p_title, - const QString &p_info, - QWidget *p_parent = 0); - - QTreeWidget *getTreeWidget() const; - - // Called after updating the m_treeWidget. - void treeUpdated(); - - // Get user data of column 0 from sorted items. - QVector getSortedData() const; - -private: - enum MoveOperation { Top, Up, Down, Bottom }; - -private slots: - void handleMoveOperation(MoveOperation p_op); - -private: - void setupUI(const QString &p_title, const QString &p_info); - - VTreeWidget *m_treeWidget; - QPushButton *m_topBtn; - QPushButton *m_upBtn; - QPushButton *m_downBtn; - QPushButton *m_bottomBtn; - QDialogButtonBox *m_btnBox; -}; - -inline QTreeWidget *VSortDialog::getTreeWidget() const -{ - return m_treeWidget; -} - -#endif // VSORTDIALOG_H diff --git a/src/dialog/vtipsdialog.cpp b/src/dialog/vtipsdialog.cpp deleted file mode 100644 index 9e093664..00000000 --- a/src/dialog/vtipsdialog.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "vtipsdialog.h" - -#include -#include - -#include "vconfigmanager.h" -#include "vmarkdownconverter.h" -#include "utils/vutils.h" -#include "vnote.h" - -extern VConfigManager *g_config; - -VTipsDialog::VTipsDialog(const QString &p_tipFile, - const QString &p_actionText, - TipsDialogFunc p_action, - QWidget *p_parent) - : QDialog(p_parent), m_actionBtn(NULL), m_action(p_action) -{ - setupUI(p_actionText); - - readFile(p_tipFile); -} - -void VTipsDialog::setupUI(const QString &p_actionText) -{ - m_viewer = VUtils::getWebEngineView(g_config->getBaseBackground()); - m_viewer->setContextMenuPolicy(Qt::NoContextMenu); - - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - - m_okBtn = m_btnBox->button(QDialogButtonBox::Ok); - - if (!p_actionText.isEmpty()) { - Q_ASSERT(m_action != nullptr); - m_actionBtn = m_btnBox->addButton(p_actionText, QDialogButtonBox::ActionRole); - m_actionBtn->setProperty("SpecialBtn", true); - m_actionBtn->setDefault(true); - - connect(m_actionBtn, &QPushButton::clicked, - this, [this]() { - m_action(); - }); - } - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_viewer); - mainLayout->addWidget(m_btnBox); - - setLayout(mainLayout); - setWindowTitle(tr("VNote Tips")); -} - -void VTipsDialog::readFile(const QString &p_tipFile) -{ - QString content = VUtils::readFileFromDisk(p_tipFile); - VMarkdownConverter mdConverter; - QString toc; - QString html = mdConverter.generateHtml(content, - g_config->getMarkdownExtensions(), - toc); - html = VUtils::generateSimpleHtmlTemplate(html); - // Add a base URL to enable it to access local style files. - m_viewer->setHtml(html, QUrl("qrc:/resources")); -} - -void VTipsDialog::showEvent(QShowEvent *p_event) -{ - QDialog::showEvent(p_event); - - if (m_actionBtn) { - m_actionBtn->setFocus(); - } else { - m_okBtn->setFocus(); - } -} diff --git a/src/dialog/vtipsdialog.h b/src/dialog/vtipsdialog.h deleted file mode 100644 index 2c652e0c..00000000 --- a/src/dialog/vtipsdialog.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef VTIPSDIALOG_H -#define VTIPSDIALOG_H - -#include - -#include - -class QDialogButtonBox; -class QWebEngineView; -class QPushButton; -class QShowEvent; - -typedef std::function TipsDialogFunc; - -class VTipsDialog : public QDialog -{ - Q_OBJECT -public: - VTipsDialog(const QString &p_tipFile, - const QString &p_actionText = QString(), - TipsDialogFunc p_action = nullptr, - QWidget *p_parent = nullptr); - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private: - void setupUI(const QString &p_actionText); - - void readFile(const QString &p_tipFile); - - QWebEngineView *m_viewer; - - QDialogButtonBox *m_btnBox; - - QPushButton *m_actionBtn; - - QPushButton *m_okBtn; - - TipsDialogFunc m_action; -}; - -#endif // VTIPSDIALOG_H diff --git a/src/dialog/vupdater.cpp b/src/dialog/vupdater.cpp deleted file mode 100644 index ad308a00..00000000 --- a/src/dialog/vupdater.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "vupdater.h" - -#include -#include -#include -#include -#include - -#include "vconfigmanager.h" -#include "vdownloader.h" -#include "vmarkdownconverter.h" -#include "utils/vutils.h" -#include "vnote.h" - -extern VConfigManager *g_config; - -VUpdater::VUpdater(QWidget *p_parent) - : QDialog(p_parent) -{ - setupUI(); -} - -void VUpdater::setupUI() -{ - QImage img(":/resources/icons/vnote_update.svg"); - QSize imgSize(128, 128); - QLabel *imgLabel = new QLabel(); - imgLabel->setPixmap(QPixmap::fromImage(img.scaled(imgSize))); - - m_versionLabel = new QLabel(tr("Current Version: v%1") - .arg(g_config->c_version)); - - m_proLabel = new QLabel(tr("Checking for updates...")); - m_proLabel->setOpenExternalLinks(true); - m_proBar = new QProgressBar(); - m_proBar->setTextVisible(false); - - m_descriptionWV = VUtils::getWebEngineView(g_config->getBaseBackground()); - m_descriptionWV->setContextMenuPolicy(Qt::NoContextMenu); - m_descriptionWV->setHtml(VUtils::generateSimpleHtmlTemplate(VNote::s_sloganTemplate), - QUrl("qrc:/resources")); - - m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok); - m_btnBox->button(QDialogButtonBox::Ok)->setProperty("SpecialBtn", true); - connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - - QVBoxLayout *verLayout = new QVBoxLayout(); - verLayout->addStretch(); - verLayout->addWidget(m_versionLabel); - verLayout->addStretch(); - verLayout->addWidget(m_proLabel); - verLayout->addWidget(m_proBar); - - QHBoxLayout *topLayout = new QHBoxLayout(); - topLayout->addWidget(imgLabel); - topLayout->addLayout(verLayout); - topLayout->addStretch(); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(topLayout); - mainLayout->addWidget(m_descriptionWV, 1); - mainLayout->addWidget(m_btnBox); - - m_proLabel->hide(); - m_proBar->hide(); - - setLayout(mainLayout); - setWindowTitle(tr("VNote Update")); -} - -void VUpdater::showEvent(QShowEvent *p_event) -{ - QDialog::showEvent(p_event); - - QTimer *timer = new QTimer(this); - timer->setSingleShot(true); - timer->setInterval(1000); - connect(timer, &QTimer::timeout, - this, [this]() { - this->checkUpdates(); - }); - - timer->start(); -} - -void VUpdater::checkUpdates() -{ - // Change UI. - m_proLabel->setText(tr("Checking for updates...")); - m_proLabel->show(); - - m_proBar->setEnabled(true); - m_proBar->setMinimum(0); - m_proBar->setMaximum(100); - m_proBar->reset(); - m_proBar->show(); - - QString url("https://api.github.com/repos/tamlok/vnote/releases/latest"); - VDownloader *downloader = new VDownloader(this); - connect(downloader, &VDownloader::downloadFinished, - this, &VUpdater::parseResult); - downloader->download(url); - - m_proBar->setValue(20); -} - -// Return if @p_latestVersion is newer than p_curVersion. -// They are both in format xx.xx.xx.xx -bool isNewerVersion(const QString &p_curVersion, const QString &p_latestVersion) -{ - QStringList curList = p_curVersion.split('.', QString::SkipEmptyParts); - QStringList latestList = p_latestVersion.split('.', QString::SkipEmptyParts); - - int i = 0; - for (; i < curList.size() && i < latestList.size(); ++i) { - int a = curList[i].toInt(); - int b = latestList[i].toInt(); - - if (a > b) { - return false; - } else if (a < b) { - return true; - } - } - - - if (i < curList.size()) { - // 1.2.1 vs 1.2 - return false; - } else if (i < latestList.size()) { - // 1.2 vs 1.2.1 - return true; - } else { - // 1.2 vs 1.2 - return false; - } -} - -void VUpdater::parseResult(const QByteArray &p_data) -{ - m_proBar->setValue(40); - QJsonDocument jsonDoc = QJsonDocument::fromJson(p_data); - QJsonObject json = jsonDoc.object(); - - if (jsonDoc.isNull() || json.empty()) { - m_proBar->setEnabled(false); - m_proLabel->setText(tr(":( Fail to check for updates.\n" - "Please try it later.")); - - return; - } - - m_proBar->setValue(100); - - QString tag = json["tag_name"].toString(); - if (tag.startsWith('v') && tag.size() > 3) { - tag = tag.right(tag.size() - 1); - } - - QString releaseName = json["name"].toString(); - QString releaseUrl = json["html_url"].toString(); - QString body = json["body"].toString(); - - m_versionLabel->setText(tr("Current Version: v%1\nLatest Version: v%2") - .arg(g_config->c_version).arg(tag)); - if (isNewerVersion(g_config->c_version, tag)) { - m_proLabel->setText(tr("Updates Available!
" - "Please visit GitHub Releases to download the latest version.") - .arg(releaseUrl)); - } else { - m_proLabel->setText(tr("VNote is already the latest version.")); - } - - QString mdText = "# " + releaseName + "\n" + body; - VMarkdownConverter mdConverter; - QString toc; - QString html = mdConverter.generateHtml(mdText, - g_config->getMarkdownExtensions(), - toc); - html = VUtils::generateSimpleHtmlTemplate(html); - m_descriptionWV->setHtml(html, QUrl("qrc:/resources")); - m_proBar->hide(); -} diff --git a/src/dialog/vupdater.h b/src/dialog/vupdater.h deleted file mode 100644 index dcff3bcc..00000000 --- a/src/dialog/vupdater.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef VUPDATER_H -#define VUPDATER_H - -#include -#include - -class QLabel; -class QDialogButtonBox; -class QWebEngineView; -class QProgressBar; -class QShowEvent; - -class VUpdater : public QDialog -{ - Q_OBJECT -public: - VUpdater(QWidget *p_parent = 0); - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - // Calling to Github api got responses. - void parseResult(const QByteArray &p_data); - -private: - void setupUI(); - - // Fetch the latest release info from Github. - void checkUpdates(); - - QLabel *m_versionLabel; - QWebEngineView *m_descriptionWV; - QDialogButtonBox *m_btnBox; - - // Progress label and bar. - QLabel *m_proLabel; - QProgressBar *m_proBar; -}; - -#endif // VUPDATER_H diff --git a/src/isearchengine.cpp b/src/isearchengine.cpp deleted file mode 100644 index 97a5d4ba..00000000 --- a/src/isearchengine.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "isearchengine.h" diff --git a/src/isearchengine.h b/src/isearchengine.h deleted file mode 100644 index 2d511efe..00000000 --- a/src/isearchengine.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef ISEARCHENGINE_H -#define ISEARCHENGINE_H - -#include -#include -#include - -#include "vsearchconfig.h" - -// Abstract class for search engine. -class ISearchEngine : public QObject -{ - Q_OBJECT -public: - explicit ISearchEngine(QObject *p_parent = nullptr) - : QObject(p_parent) - { - } - - virtual ~ISearchEngine() - { - m_result.clear(); - } - - virtual void search(const QSharedPointer &p_config, - const QSharedPointer &p_result) = 0; - - virtual void stop() = 0; - - virtual void clear() = 0; - -signals: - void finished(const QSharedPointer &p_result); - - void resultItemsAdded(const QList > &p_items); - -protected: - QSharedPointer m_result; -}; -#endif // ISEARCHENGINE_H diff --git a/src/iuniversalentry.cpp b/src/iuniversalentry.cpp deleted file mode 100644 index b470e1a4..00000000 --- a/src/iuniversalentry.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "iuniversalentry.h" diff --git a/src/iuniversalentry.h b/src/iuniversalentry.h deleted file mode 100644 index a2587050..00000000 --- a/src/iuniversalentry.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef IUNIVERSALENTRY_H -#define IUNIVERSALENTRY_H - -#include -#include - -// Interface for one Universal Entry. -// An entry may be used for different keys, in which case we could use an ID to -// identify. -class IUniversalEntry : public QObject -{ - Q_OBJECT -public: - enum State - { - Idle, - Busy, - Success, - Fail, - Cancelled - }; - - IUniversalEntry(QObject *p_parent = nullptr) - : QObject(p_parent), - m_initialized(false), - m_widgetParent(NULL) - { - } - - virtual ~IUniversalEntry() - { - } - - // Return a description string for the entry. - virtual QString description(int p_id) const = 0; - - // Return the widget to show to user. - virtual QWidget *widget(int p_id) = 0; - - virtual void processCommand(int p_id, const QString &p_cmd) = 0; - - // This UE is not used now. Free resources. - virtual void clear(int p_id) = 0; - - // UE is hidden by the user. - virtual void entryHidden(int p_id) - { - Q_UNUSED(p_id); - } - - // UE is shown by the user. - virtual void entryShown(int p_id, const QString &p_cmd) - { - Q_UNUSED(p_id); - Q_UNUSED(p_cmd); - } - - // Select next item. - virtual void selectNextItem(int p_id, bool p_forward) - { - Q_UNUSED(p_id); - Q_UNUSED(p_forward); - } - - // Select parent item. - virtual void selectParentItem(int p_id) - { - Q_UNUSED(p_id); - } - - // Activate current item. - virtual void activate(int p_id) - { - Q_UNUSED(p_id); - } - - // Ask the UE to stop asynchronously. - virtual void askToStop(int p_id) - { - Q_UNUSED(p_id); - } - - virtual void toggleItemExpanded(int p_id) - { - Q_UNUSED(p_id); - } - - virtual void sort(int p_id) - { - Q_UNUSED(p_id); - } - - // Ask the UE to return current item folder path or the folder containing current - // item note. - virtual QString currentItemFolder(int p_id) - { - Q_UNUSED(p_id); - return QString(); - } - - void setWidgetParent(QWidget *p_parent) - { - m_widgetParent = p_parent; - } - - virtual void expandCollapseAll(int p_id) - { - Q_UNUSED(p_id); - } - -signals: - void widgetUpdated(); - - void stateUpdated(IUniversalEntry::State p_state); - - void requestHideUniversalEntry(); - -protected: - virtual void init() = 0; - - bool m_initialized; - - QWidget *m_widgetParent; -}; - -#endif // IUNIVERSALENTRY_H diff --git a/src/lineeditdelegate.cpp b/src/lineeditdelegate.cpp deleted file mode 100644 index 0c5a0faa..00000000 --- a/src/lineeditdelegate.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "lineeditdelegate.h" - -#include "vlineedit.h" - - -LineEditDelegate::LineEditDelegate(QObject *p_parent) - : QStyledItemDelegate(p_parent) -{ -} - -QWidget *LineEditDelegate::createEditor(QWidget *p_parent, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const -{ - Q_UNUSED(p_option); - Q_UNUSED(p_index); - - VLineEdit *edit = new VLineEdit(p_parent); - return edit; -} - -void LineEditDelegate::setEditorData(QWidget *p_editor, const QModelIndex &p_index) const -{ - QString text = p_index.model()->data(p_index, Qt::EditRole).toString(); - - VLineEdit *edit = static_cast(p_editor); - edit->setText(text); -} - -void LineEditDelegate::setModelData(QWidget *p_editor, - QAbstractItemModel *p_model, - const QModelIndex &p_index) const -{ - VLineEdit *edit = static_cast(p_editor); - - p_model->setData(p_index, edit->text(), Qt::EditRole); -} - -void LineEditDelegate::updateEditorGeometry(QWidget *p_editor, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const -{ - Q_UNUSED(p_index); - p_editor->setGeometry(p_option.rect); -} diff --git a/src/lineeditdelegate.h b/src/lineeditdelegate.h deleted file mode 100644 index 018a6821..00000000 --- a/src/lineeditdelegate.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef LINEEDITDELEGATE_H -#define LINEEDITDELEGATE_H - -#include - - -class LineEditDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - LineEditDelegate(QObject *p_parent = nullptr); - - QWidget *createEditor(QWidget *p_parent, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const Q_DECL_OVERRIDE; - - void setEditorData(QWidget *p_editor, const QModelIndex &p_index) const Q_DECL_OVERRIDE; - - void setModelData(QWidget *p_editor, - QAbstractItemModel *p_model, - const QModelIndex &p_index) const Q_DECL_OVERRIDE; - - void updateEditorGeometry(QWidget *p_editor, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const Q_DECL_OVERRIDE; -}; - -#endif // LINEEDITDELEGATE_H diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 53153deb..00000000 --- a/src/main.cpp +++ /dev/null @@ -1,288 +0,0 @@ -#include "vmainwindow.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils/vutils.h" -#include "vsingleinstanceguard.h" -#include "vconfigmanager.h" -#include "vpalette.h" -#include "vapplication.h" - -VConfigManager *g_config; - -VPalette *g_palette; - -#if defined(QT_NO_DEBUG) -// 5MB log size. -#define MAX_LOG_SIZE 5 * 1024 * 1024 - -// Whether print debug log in RELEASE mode. -bool g_debugLog = false; - -QFile g_logFile; - -static void initLogFile(const QString &p_file) -{ - g_logFile.setFileName(p_file); - if (g_logFile.size() >= MAX_LOG_SIZE) { - g_logFile.open(QIODevice::WriteOnly | QIODevice::Text); - } else { - g_logFile.open(QIODevice::Append | QIODevice::Text); - } -} -#endif - -void VLogger(QtMsgType type, const QMessageLogContext &context, const QString &msg) -{ -#if defined(QT_NO_DEBUG) - if (!g_debugLog && type == QtDebugMsg) { - return; - } -#endif - - QByteArray localMsg = msg.toUtf8(); - QString header; - - switch (type) { - case QtDebugMsg: - header = "Debug:"; - break; - - case QtInfoMsg: - header = "Info:"; - break; - - case QtWarningMsg: - header = "Warning:"; - break; - - case QtCriticalMsg: - header = "Critical:"; - break; - - case QtFatalMsg: - header = "Fatal:"; - - default: - break; - } - - QString fileName = QFileInfo(context.file).fileName(); -#if defined(QT_NO_DEBUG) - QTextStream stream(&g_logFile); - stream << header << (QString("(%1:%2) ").arg(fileName).arg(context.line)) - << localMsg << "\n"; - - if (type == QtFatalMsg) { - g_logFile.close(); - abort(); - } -#else - std::string fileStr = fileName.toStdString(); - const char *file = fileStr.c_str(); - - switch (type) { - case QtDebugMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - break; - case QtInfoMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - break; - case QtWarningMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - break; - case QtCriticalMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - break; - case QtFatalMsg: - fprintf(stderr, "%s(%s:%u) %s\n", - header.toStdString().c_str(), file, context.line, localMsg.constData()); - abort(); - } - - fflush(stderr); -#endif -} - -int main(int argc, char *argv[]) -{ -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - bool allowMultiInstances = true; -#else - bool allowMultiInstances = false; -#endif - for (int i = 1; i < argc; ++i) { - if (!qstrcmp(argv[i], "-m")) { - allowMultiInstances = true; - break; - } - } - - VSingleInstanceGuard guard; - bool canRun = true; - if (!allowMultiInstances) { - canRun = guard.tryRun(); - } - - QTextCodec *codec = QTextCodec::codecForName("UTF8"); - if (codec) { - QTextCodec::setCodecForLocale(codec); - } - - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - - // This only takes effect on Win, X11 and Android. - // It will disturb original scaling. Just disable it for now. - // QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - - // Set openGL version. - // Or set environment QT_OPENGL to "angle/desktop/software". - // QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); -#if defined(Q_OS_WIN) - int winOpenGL = VConfigManager::getWindowsOpenGL(); - qInfo() << "OpenGL option" << winOpenGL; - switch (winOpenGL) { - case 1: - QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); - break; - - case 2: - QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); - break; - - case 3: - QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); - break; - - case 0: - V_FALLTHROUGH; - default: - break; - } -#endif - - VApplication app(argc, argv); - - // The file path passed via command line arguments. - QStringList filePaths = VUtils::filterFilePathsToOpen(app.arguments().mid(1)); - - if (!canRun) { - // Ask another instance to open files passed in. - if (!filePaths.isEmpty()) { - guard.openExternalFiles(filePaths); - } else { - guard.showInstance(); - } - - return 0; - } - - VConfigManager vconfig; - vconfig.initialize(); - g_config = &vconfig; - -#if defined(QT_NO_DEBUG) - for (int i = 1; i < argc; ++i) { - if (!qstrcmp(argv[i], "-d")) { - g_debugLog = true; - break; - } - } - - initLogFile(vconfig.getLogFilePath()); -#endif - - qInstallMessageHandler(VLogger); - - qInfo() << "VNote started" << g_config->c_version << QDateTime::currentDateTime().toString(); - - QString locale = VUtils::getLocale(); - // Set default locale. - if (locale == "zh_CN") { - QLocale::setDefault(QLocale(QLocale::Chinese, QLocale::China)); - } - - qDebug() << "command line arguments" << app.arguments(); - qDebug() << "files to open from arguments" << filePaths; - - // Check the openSSL. - qInfo() << "openGL" << QOpenGLContext::openGLModuleType(); - qInfo() << "openSSL" - << QSslSocket::sslLibraryBuildVersionString() - << QSslSocket::sslLibraryVersionNumber(); - - // Load missing translation for Qt (QTextEdit/QPlainTextEdit/QTextBrowser). - QTranslator qtTranslator1; - if (qtTranslator1.load("widgets_" + locale, ":/translations")) { - app.installTranslator(&qtTranslator1); - } - - QTranslator qtTranslator2; - if (qtTranslator2.load("qdialogbuttonbox_" + locale, ":/translations")) { - app.installTranslator(&qtTranslator2); - } - - QTranslator qtTranslator3; - if (qtTranslator3.load("qwebengine_" + locale, ":/translations")) { - app.installTranslator(&qtTranslator3); - } - - // Load translation for Qt from resource. - QTranslator qtTranslator; - if (qtTranslator.load("qt_" + locale, ":/translations")) { - app.installTranslator(&qtTranslator); - } - - // Load translation for Qt from env. - QTranslator qtTranslatorEnv; - if (qtTranslatorEnv.load("qt_" + locale, "translations")) { - app.installTranslator(&qtTranslatorEnv); - } - - // Load translation for vnote. - QTranslator translator; - if (translator.load("vnote_" + locale, ":/translations")) { - app.installTranslator(&translator); - } - - VPalette palette(g_config->getThemeFile()); - g_palette = &palette; - - VMainWindow w(&guard); - app.setWindow(&w); - QString style = palette.fetchQtStyleSheet(); - if (!style.isEmpty()) { - app.setStyleSheet(style); - } - - w.show(); - - g_config->setBaseBackground(w.palette().color(QPalette::Window)); - - w.kickOffStartUpTimer(filePaths); - - int ret = app.exec(); - app.setWindow(nullptr); - if (ret == RESTART_EXIT_CODE) { - // Ask to restart VNote. - guard.exit(); - QProcess::startDetached(qApp->applicationFilePath(), QStringList()); - return 0; - } - - return ret; -} diff --git a/src/markdownhighlighterdata.h b/src/markdownhighlighterdata.h deleted file mode 100644 index dae95dbf..00000000 --- a/src/markdownhighlighterdata.h +++ /dev/null @@ -1,227 +0,0 @@ -#ifndef MARKDOWNHIGHLIGHTERDATA_H -#define MARKDOWNHIGHLIGHTERDATA_H - -#include - -#include "vconstants.h" - -extern "C" { -#include -} - -struct HighlightingStyle -{ - pmh_element_type type; - QTextCharFormat format; -}; - -// One continuous region for a certain markdown highlight style -// within a QTextBlock. -// Pay attention to the change of HighlightingStyles[] -struct HLUnit -{ - // Highlight offset @start and @length with style HighlightingStyles[styleIndex] - // within a QTextBlock - unsigned long start; - unsigned long length; - unsigned int styleIndex; - - bool operator==(const HLUnit &p_a) const - { - return start == p_a.start - && length == p_a.length - && styleIndex == p_a.styleIndex; - } - - QString toString() const - { - return QString("HLUnit %1 %2 %3").arg(start).arg(length).arg(styleIndex); - } -}; - -struct HLUnitStyle -{ - unsigned long start; - unsigned long length; - QString style; - - bool operator==(const HLUnitStyle &p_a) const - { - if (start != p_a.start || length != p_a.length) { - return false; - } - - return style == p_a.style; - } -}; - -// Fenced code block only. -struct VCodeBlock -{ - // Global position of the start. - int m_startPos; - - int m_startBlock; - int m_endBlock; - - QString m_lang; - - QString m_text; - - bool equalContent(const VCodeBlock &p_block) const - { - return p_block.m_lang == m_lang && p_block.m_text == m_text; - } - - void updateNonContent(const VCodeBlock &p_block) - { - m_startPos = p_block.m_startPos; - m_startBlock = p_block.m_startBlock; - m_endBlock = p_block.m_endBlock; - } -}; - - -struct VMathjaxBlock -{ - VMathjaxBlock() - : m_blockNumber(-1), - m_previewedAsBlock(false), - m_index(-1), - m_length(-1) - { - } - - bool equalContent(const VMathjaxBlock &p_block) const - { - return m_text == p_block.m_text; - } - - void updateNonContent(const VMathjaxBlock &p_block) - { - m_blockNumber = p_block.m_blockNumber; - m_previewedAsBlock = p_block.m_previewedAsBlock; - m_index = p_block.m_index; - m_length = p_block.m_length; - } - - // Block number for in-place preview. - int m_blockNumber; - - // Whether it should be previewed as block or not. - bool m_previewedAsBlock; - - // Start index wihtin block with number m_blockNumber, including the start mark. - int m_index; - - // Length of this mathjax in block with number m_blockNumber, including the end mark. - int m_length; - - QString m_text; -}; - - -struct VTableBlock -{ - VTableBlock() - : m_startPos(-1), - m_endPos(-1) - { - } - - bool isValid() const - { - return m_startPos > -1 && m_endPos >= m_startPos; - } - - void clear() - { - m_startPos = m_endPos = -1; - m_borders.clear(); - } - - QString toString() const - { - return QString("table [%1,%2) borders %3").arg(m_startPos) - .arg(m_endPos) - .arg(m_borders.size()); - } - - int m_startPos; - int m_endPos; - - // Global position of the table borders in ascending order. - QVector m_borders; -}; - - -// Highlight unit with global position and string style name. -struct HLUnitPos -{ - HLUnitPos() : m_position(-1), m_length(-1) - { - } - - HLUnitPos(int p_position, int p_length, const QString &p_style) - : m_position(p_position), m_length(p_length), m_style(p_style) - { - } - - int m_position; - int m_length; - QString m_style; -}; - -// Denote the region of a certain Markdown element. -struct VElementRegion -{ - VElementRegion() : m_startPos(0), m_endPos(0) {} - - VElementRegion(int p_start, int p_end) : m_startPos(p_start), m_endPos(p_end) {} - - // The start position of the region in document. - int m_startPos; - - // The end position of the region in document. - int m_endPos; - - // Whether this region contains @p_pos. - bool contains(int p_pos) const - { - return m_startPos <= p_pos && m_endPos > p_pos; - } - - bool contains(const VElementRegion &p_reg) const - { - return m_startPos <= p_reg.m_startPos && m_endPos >= p_reg.m_endPos; - } - - bool intersect(int p_start, int p_end) const - { - return !(p_end <= m_startPos || p_start >= m_endPos); - } - - bool operator==(const VElementRegion &p_other) const - { - return (m_startPos == p_other.m_startPos - && m_endPos == p_other.m_endPos); - } - - bool operator<(const VElementRegion &p_other) const - { - if (m_startPos < p_other.m_startPos) { - return true; - } else if (m_startPos == p_other.m_startPos) { - // If a < b is true, then b < a must be false. - return m_endPos < p_other.m_endPos; - } else { - return false; - } - } - - QString toString() const - { - return QString("[%1,%2)").arg(m_startPos).arg(m_endPos); - } -}; -#endif // MARKDOWNHIGHLIGHTERDATA_H diff --git a/src/markdownitoption.h b/src/markdownitoption.h deleted file mode 100644 index 8c555b0e..00000000 --- a/src/markdownitoption.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef MARKDOWNITOPTION_H -#define MARKDOWNITOPTION_H - -#include - -struct MarkdownitOption -{ - MarkdownitOption() - : MarkdownitOption(true, - false, - true, - false, - false, - false, - false) - { - } - - MarkdownitOption(bool p_html, - bool p_breaks, - bool p_linkify, - bool p_sub, - bool p_sup, - bool p_metadata, - bool p_emoji) - : m_html(p_html), - m_breaks(p_breaks), - m_linkify(p_linkify), - m_sub(p_sub), - m_sup(p_sup), - m_metadata(p_metadata), - m_emoji(p_emoji) - { - } - - QStringList toConfig() const - { - QStringList conf; - if (m_html) { - conf << "html"; - } - - if (m_breaks) { - conf << "break"; - } - - if (m_linkify) { - conf << "linkify"; - } - - if (m_sub) { - conf << "sub"; - } - - if (m_sup) { - conf << "sup"; - } - - if (m_metadata) { - conf << "metadata"; - } - - if (m_emoji) { - conf << "emoji"; - } - - return conf; - } - - static MarkdownitOption fromConfig(const QStringList &p_conf) - { - return MarkdownitOption(testOption(p_conf, "html"), - testOption(p_conf, "break"), - testOption(p_conf, "linkify"), - testOption(p_conf, "sub"), - testOption(p_conf, "sup"), - testOption(p_conf, "metadata"), - testOption(p_conf, "emoji")); - } - - bool operator==(const MarkdownitOption &p_opt) const - { - return m_html == p_opt.m_html - && m_breaks == p_opt.m_breaks - && m_linkify == p_opt.m_linkify - && m_sub == p_opt.m_sub - && m_sup == p_opt.m_sup - && m_metadata == p_opt.m_metadata - && m_emoji == p_opt.m_emoji; - } - - // Eanble HTML tags in source. - bool m_html; - - // Convert '\n' in paragraphs into
. - bool m_breaks; - - // Auto-convert URL-like text to links. - bool m_linkify; - - // Enable subscript. - bool m_sub; - - // Enable superscript. - bool m_sup; - - // Enable metadata in YML format. - bool m_metadata; - - // Enable emoji and emoticon. - bool m_emoji; - -private: - static bool testOption(const QStringList &p_conf, const QString &p_opt) - { - return p_conf.contains(p_opt); - } -}; - -#endif // MARKDOWNITOPTION_H diff --git a/src/peghighlighterresult.cpp b/src/peghighlighterresult.cpp deleted file mode 100644 index 1419f74a..00000000 --- a/src/peghighlighterresult.cpp +++ /dev/null @@ -1,459 +0,0 @@ -#include "peghighlighterresult.h" - -#include -#include - -#include "pegmarkdownhighlighter.h" -#include "utils/vutils.h" - -PegHighlighterFastResult::PegHighlighterFastResult() - : m_timeStamp(0) -{ -} - -PegHighlighterFastResult::PegHighlighterFastResult(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result) - : m_timeStamp(p_result->m_timeStamp) -{ - PegHighlighterResult::parseBlocksHighlights(m_blocksHighlights, p_peg, p_result); -} - - -PegHighlighterResult::PegHighlighterResult() - : m_timeStamp(0), - m_numOfBlocks(0), - m_codeBlockTimeStamp(0), - m_numOfCodeBlockHighlightsToRecv(0) -{ - m_codeBlockStartExp = QRegularExpression(VUtils::c_fencedCodeBlockStartRegExp); - m_codeBlockEndExp = QRegularExpression(VUtils::c_fencedCodeBlockEndRegExp); -} - -PegHighlighterResult::PegHighlighterResult(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result) - : m_timeStamp(p_result->m_timeStamp), - m_numOfBlocks(p_result->m_numOfBlocks), - m_codeBlockHighlightReceived(false), - m_codeBlockTimeStamp(0), - m_numOfCodeBlockHighlightsToRecv(0) -{ - m_codeBlockStartExp = QRegularExpression(VUtils::c_fencedCodeBlockStartRegExp); - m_codeBlockEndExp = QRegularExpression(VUtils::c_fencedCodeBlockEndRegExp); - - parseBlocksHighlights(m_blocksHighlights, p_peg, p_result); - - // Implicit sharing. - m_imageRegions = p_result->m_imageRegions; - m_headerRegions = p_result->m_headerRegions; - - parseFencedCodeBlocks(p_peg, p_result); - - parseMathjaxBlocks(p_peg, p_result); - - parseHRuleBlocks(p_peg, p_result); - - parseTableBlocks(p_result); -} - -static bool compHLUnit(const HLUnit &p_a, const HLUnit &p_b) -{ - if (p_a.start < p_b.start) { - return true; - } else if (p_a.start == p_b.start) { - return p_a.length > p_b.length; - } else { - return false; - } -} - -void PegHighlighterResult::parseBlocksHighlights(QVector> &p_blocksHighlights, - const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result) -{ - p_blocksHighlights.resize(p_result->m_numOfBlocks); - if (p_result->isEmpty()) { - return; - } - - int offset = p_result->m_offset; - const QTextDocument *doc = p_peg->getDocument(); - const QVector &styles = p_peg->getStyles(); - auto pmhResult = p_result->m_pmhElements; - for (int i = 0; i < styles.size(); i++) - { - const HighlightingStyle &style = styles[i]; - pmh_element *elem_cursor = pmhResult[style.type]; - while (elem_cursor != NULL) - { - // elem_cursor->pos and elem_cursor->end is the start - // and end position of the element in document. - if (elem_cursor->end <= elem_cursor->pos) { - elem_cursor = elem_cursor->next; - continue; - } - - parseBlocksHighlightOne(p_blocksHighlights, - doc, - offset + elem_cursor->pos, - offset + elem_cursor->end, - i); - elem_cursor = elem_cursor->next; - } - } - - // Sort p_blocksHighlights. - for (int i = 0; i < p_blocksHighlights.size(); ++i) { - if (p_blocksHighlights[i].size() > 1) { - std::sort(p_blocksHighlights[i].begin(), p_blocksHighlights[i].end(), compHLUnit); - } - } -} - -void PegHighlighterResult::parseBlocksHighlightOne(QVector> &p_blocksHighlights, - const QTextDocument *p_doc, - unsigned long p_pos, - unsigned long p_end, - int p_styleIndex) -{ - // When the the highlight element is at the end of document, @p_end will equals - // to the characterCount. - unsigned int nrChar = (unsigned int)p_doc->characterCount(); - if (p_end >= nrChar && nrChar > 0) { - p_end = nrChar - 1; - } - - QTextBlock block = p_doc->findBlock(p_pos); - int startBlockNum = block.blockNumber(); - int endBlockNum = p_doc->findBlock(p_end - 1).blockNumber(); - if (endBlockNum >= p_blocksHighlights.size()) { - endBlockNum = p_blocksHighlights.size() - 1; - } - - while (block.isValid()) - { - int blockNum = block.blockNumber(); - if (blockNum > endBlockNum) { - break; - } - - int blockStartPos = block.position(); - HLUnit unit; - if (blockNum == startBlockNum) { - unit.start = p_pos - blockStartPos; - unit.length = (startBlockNum == endBlockNum) ? - (p_end - p_pos) : (block.length() - unit.start); - } else if (blockNum == endBlockNum) { - unit.start = 0; - unit.length = p_end - blockStartPos; - } else { - unit.start = 0; - unit.length = block.length(); - } - - unit.styleIndex = p_styleIndex; - - Q_ASSERT(unit.length > 0); - - if (unit.length > 0) { - p_blocksHighlights[blockNum].append(unit); - } - - block = block.next(); - } -} - -#if 0 -void PegHighlighterResult::parseBlocksElementRegionOne(QHash> &p_regs, - const QTextDocument *p_doc, - unsigned long p_pos, - unsigned long p_end) -{ - // When the the highlight element is at the end of document, @p_end will equals - // to the characterCount. - unsigned int nrChar = (unsigned int)p_doc->characterCount(); - if (p_end >= nrChar && nrChar > 0) { - p_end = nrChar - 1; - } - - QTextBlock block = p_doc->findBlock(p_pos); - int startBlockNum = block.blockNumber(); - int endBlockNum = p_doc->findBlock(p_end - 1).blockNumber(); - if (endBlockNum >= p_regs.size()) { - endBlockNum = p_regs.size() - 1; - } - - while (block.isValid()) - { - int blockNum = block.blockNumber(); - if (blockNum > endBlockNum) { - break; - } - - int blockStartPos = block.position(); - QVector ®s = p_regs[blockNum]; - int start, end; - if (blockNum == startBlockNum) { - start = p_pos - blockStartPos; - end = (startBlockNum == endBlockNum) ? (p_end - blockStartPos) - : block.length(); - } else if (blockNum == endBlockNum) { - start = 0; - end = p_end - blockStartPos; - } else { - start = 0; - end = block.length(); - } - - regs.append(VElementRegion(start, end)); - } -} -#endif - -void PegHighlighterResult::parseFencedCodeBlocks(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result) -{ - const QMap ®s = p_result->m_codeBlockRegions; - - const QTextDocument *doc = p_peg->getDocument(); - VCodeBlock item; - bool inBlock = false; - QString marker; - for (auto it = regs.begin(); it != regs.end(); ++it) { - QTextBlock block = doc->findBlock(it.value().m_startPos); - int lastBlock = doc->findBlock(it.value().m_endPos - 1).blockNumber(); - if (lastBlock >= p_result->m_numOfBlocks) { - lastBlock = p_result->m_numOfBlocks - 1; - } - - while (block.isValid()) { - int blockNumber = block.blockNumber(); - if (blockNumber > lastBlock) { - break; - } - - HighlightBlockState state = HighlightBlockState::Normal; - QString text = block.text(); - if (inBlock) { - item.m_text = item.m_text + "\n" + text; - auto match = m_codeBlockEndExp.match(text); - if (match.hasMatch() && marker == match.captured(2)) { - // End block. - inBlock = false; - marker.clear(); - - state = HighlightBlockState::CodeBlockEnd; - item.m_endBlock = blockNumber; - m_codeBlocks.append(item); - } else { - // Within code block. - state = HighlightBlockState::CodeBlock; - } - } else { - auto match = m_codeBlockStartExp.match(text); - if (match.hasMatch()) { - // Start block. - inBlock = true; - marker = match.captured(2); - - state = HighlightBlockState::CodeBlockStart; - item.m_startBlock = blockNumber; - item.m_startPos = block.position(); - item.m_text = text; - item.m_lang = match.captured(3).trimmed(); - } - } - - if (state != HighlightBlockState::Normal) { - m_codeBlocksState.insert(blockNumber, state); - } - - block = block.next(); - } - } -} - -void PegHighlighterResult::parseTableBlocks(const QSharedPointer &p_result) -{ - const QVector &tableRegs = p_result->m_tableRegions; - const QVector &headerRegs = p_result->m_tableHeaderRegions; - const QVector &borderRegs = p_result->m_tableBorderRegions; - - VTableBlock item; - int headerIdx = 0, borderIdx = 0; - for (int tableIdx = 0; tableIdx < tableRegs.size(); ++tableIdx) { - const auto ® = tableRegs[tableIdx]; - if (headerIdx < headerRegs.size()) { - if (reg.contains(headerRegs[headerIdx])) { - // A new table. - if (item.isValid()) { - // Save previous table. - m_tableBlocks.append(item); - - auto &table = m_tableBlocks.back(); - // Fill borders. - for (; borderIdx < borderRegs.size(); ++borderIdx) { - if (borderRegs[borderIdx].m_startPos >= table.m_startPos - && borderRegs[borderIdx].m_endPos <= table.m_endPos) { - table.m_borders.append(borderRegs[borderIdx].m_startPos); - } else { - break; - } - } - } - - item.clear(); - item.m_startPos = reg.m_startPos; - item.m_endPos = reg.m_endPos; - - ++headerIdx; - continue; - } - } - - // Continue previous table. - item.m_endPos = reg.m_endPos; - } - - if (item.isValid()) { - // Another table. - m_tableBlocks.append(item); - - // Fill borders. - auto &table = m_tableBlocks.back(); - for (; borderIdx < borderRegs.size(); ++borderIdx) { - if (borderRegs[borderIdx].m_startPos >= table.m_startPos - && borderRegs[borderIdx].m_endPos <= table.m_endPos) { - table.m_borders.append(borderRegs[borderIdx].m_startPos); - } else { - break; - } - } - } -} - -static inline bool isDisplayFormulaRawEnd(const QString &p_text) -{ - QRegExp regex("\\\\end\\{[^{}\\s\\r\\n]+\\}$"); - if (p_text.indexOf(regex) > -1) { - return true; - } - - return false; -} - -void PegHighlighterResult::parseMathjaxBlocks(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result) -{ - const QTextDocument *doc = p_peg->getDocument(); - - // Inline equations. - const QVector &inlineRegs = p_result->m_inlineEquationRegions; - - for (auto it = inlineRegs.begin(); it != inlineRegs.end(); ++it) { - const VElementRegion &r = *it; - QTextBlock block = doc->findBlock(r.m_startPos); - if (!block.isValid()) { - continue; - } - - // Inline equation MUST in one block. - if (r.m_endPos - block.position() > block.length()) { - continue; - } - - VMathjaxBlock item; - item.m_blockNumber = block.blockNumber(); - item.m_previewedAsBlock = false; - item.m_index = r.m_startPos - block.position(); - item.m_length = r.m_endPos - r.m_startPos; - item.m_text = block.text().mid(item.m_index, item.m_length); - m_mathjaxBlocks.append(item); - } - - // Display formulas. - // One block may be split into several regions due to list indentation. - const QVector &formulaRegs = p_result->m_displayFormulaRegions; - VMathjaxBlock item; - bool inBlock = false; - QString marker("$$"); - QString rawMarkerStart("\\begin{"); - for (auto it = formulaRegs.begin(); it != formulaRegs.end(); ++it) { - const VElementRegion &r = *it; - QTextBlock block = doc->findBlock(r.m_startPos); - int lastBlock = doc->findBlock(r.m_endPos - 1).blockNumber(); - if (lastBlock >= p_result->m_numOfBlocks) { - lastBlock = p_result->m_numOfBlocks - 1; - } - - while (block.isValid()) { - int blockNum = block.blockNumber(); - if (blockNum > lastBlock) { - break; - } - - int pib = qMax(r.m_startPos - block.position(), 0); - int length = qMin(r.m_endPos - block.position() - pib, block.length() - 1); - QString text = block.text().mid(pib, length); - if (inBlock) { - item.m_text = item.m_text + "\n" + text; - if (text.endsWith(marker) - || (blockNum == lastBlock && isDisplayFormulaRawEnd(text))) { - // End of block. - inBlock = false; - item.m_blockNumber = blockNum; - item.m_index = pib; - item.m_length = length; - m_mathjaxBlocks.append(item); - } - } else { - if (!text.startsWith(marker) - && !text.startsWith(rawMarkerStart)) { - break; - } - - if ((text.size() > 2 && text.endsWith(marker)) - || (blockNum == lastBlock && isDisplayFormulaRawEnd(text))) { - // Within one block. - item.m_blockNumber = blockNum; - item.m_previewedAsBlock = true; - item.m_index = pib; - item.m_length = length; - item.m_text = text; - m_mathjaxBlocks.append(item); - } else { - inBlock = true; - item.m_previewedAsBlock = true; - item.m_text = text; - } - } - - block = block.next(); - } - } -} - -void PegHighlighterResult::parseHRuleBlocks(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result) -{ - const QTextDocument *doc = p_peg->getDocument(); - const QVector ®s = p_result->m_hruleRegions; - - for (auto it = regs.begin(); it != regs.end(); ++it) { - QTextBlock block = doc->findBlock(it->m_startPos); - int lastBlock = doc->findBlock(it->m_endPos - 1).blockNumber(); - if (lastBlock >= p_result->m_numOfBlocks) { - lastBlock = p_result->m_numOfBlocks - 1; - } - - while (block.isValid()) { - int blockNumber = block.blockNumber(); - if (blockNumber > lastBlock) { - break; - } - - m_hruleBlocks.insert(blockNumber); - - block = block.next(); - } - } -} diff --git a/src/peghighlighterresult.h b/src/peghighlighterresult.h deleted file mode 100644 index 5e6f84e3..00000000 --- a/src/peghighlighterresult.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef PEGHIGHLIGHTERRESULT_H -#define PEGHIGHLIGHTERRESULT_H - -#include -#include - -#include "vconstants.h" -#include "pegparser.h" - -class PegMarkdownHighlighter; -class QTextDocument; - -class PegHighlighterFastResult -{ -public: - PegHighlighterFastResult(); - - PegHighlighterFastResult(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result); - - bool matched(TimeStamp p_timeStamp) const - { - return m_timeStamp == p_timeStamp; - } - - void clear() - { - m_blocksHighlights.clear(); - } - - TimeStamp m_timeStamp; - - QVector> m_blocksHighlights; -}; - - -class PegHighlighterResult -{ -public: - PegHighlighterResult(); - - // TODO: handle p_result->m_offset. - PegHighlighterResult(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result); - - bool matched(TimeStamp p_timeStamp) const; - - // Parse highlight elements for all the blocks from parse results. - static void parseBlocksHighlights(QVector> &p_blocksHighlights, - const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result); - - TimeStamp m_timeStamp; - - int m_numOfBlocks; - - QVector> m_blocksHighlights; - - // Use another member to store the codeblocks highlights, because the highlight - // sequence is blockHighlights, regular-expression-based highlihgts, and then - // codeBlockHighlights. - // Support fenced code block only. - QVector > m_codeBlocksHighlights; - - // Whether the code block highlight results of this result have been received. - bool m_codeBlockHighlightReceived; - - // Timestamp for m_codeBlocksHighlights. - TimeStamp m_codeBlockTimeStamp; - - // All image link regions. - QVector m_imageRegions; - - // All header regions. - // Sorted by start position. - QVector m_headerRegions; - - // All fenced code blocks. - QVector m_codeBlocks; - - // Indexed by block number. - QHash m_codeBlocksState; - - int m_numOfCodeBlockHighlightsToRecv; - - // All MathJax blocks. - QVector m_mathjaxBlocks; - - QSet m_hruleBlocks; - - // All table blocks. - // Sorted by start position ascendingly. - QVector m_tableBlocks; - -private: - // Parse highlight elements for blocks from one parse result. - static void parseBlocksHighlightOne(QVector> &p_blocksHighlights, - const QTextDocument *p_doc, - unsigned long p_pos, - unsigned long p_end, - int p_styleIndex); - - // Parse fenced code blocks from parse results. - void parseFencedCodeBlocks(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result); - - // Parse mathjax blocks from parse results. - void parseMathjaxBlocks(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result); - - // Parse HRule blocks from parse results. - void parseHRuleBlocks(const PegMarkdownHighlighter *p_peg, - const QSharedPointer &p_result); - - // Parse table blocks from parse results. - void parseTableBlocks(const QSharedPointer &p_result); - -#if 0 - void parseBlocksElementRegionOne(QHash> &p_regs, - const QTextDocument *p_doc, - unsigned long p_pos, - unsigned long p_end); -#endif - - QRegularExpression m_codeBlockStartExp; - QRegularExpression m_codeBlockEndExp; -}; - -inline bool PegHighlighterResult::matched(TimeStamp p_timeStamp) const -{ - return m_timeStamp == p_timeStamp; -} -#endif // PEGHIGHLIGHTERRESULT_H diff --git a/src/pegmarkdownhighlighter.cpp b/src/pegmarkdownhighlighter.cpp deleted file mode 100644 index 7bf1004d..00000000 --- a/src/pegmarkdownhighlighter.cpp +++ /dev/null @@ -1,983 +0,0 @@ -#include "pegmarkdownhighlighter.h" - -#include -#include -#include - -#include "pegparser.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "utils/veditutils.h" -#include "vmdeditor.h" - -extern VConfigManager *g_config; - -#define LARGE_BLOCK_NUMBER 1000 - -PegMarkdownHighlighter::PegMarkdownHighlighter(QTextDocument *p_doc, VMdEditor *p_editor) - : QSyntaxHighlighter(p_doc), - m_doc(p_doc), - m_editor(p_editor), - m_timeStamp(0), - m_codeBlockTimeStamp(0), - m_parser(NULL), - m_parserExts(pmh_EXT_NOTES - | pmh_EXT_STRIKE - | pmh_EXT_FRONTMATTER - | pmh_EXT_MARK - | pmh_EXT_TABLE), - m_parseInterval(50), - m_notifyHighlightComplete(false), - m_fastParseInterval(30) -{ -} - -void PegMarkdownHighlighter::init(const QVector &p_styles, - const QHash &p_codeBlockStyles, - bool p_mathjaxEnabled, - int p_timerInterval) -{ - m_styles = p_styles; - m_codeBlockStyles = p_codeBlockStyles; - - if (p_mathjaxEnabled) { - m_parserExts |= (pmh_EXT_MATH | pmh_EXT_MATH_RAW); - } - - m_parseInterval = p_timerInterval; - - m_codeBlockFormat.setForeground(QBrush(Qt::darkYellow)); - for (int index = 0; index < m_styles.size(); ++index) { - switch (m_styles[index].type) { - case pmh_FENCEDCODEBLOCK: - m_codeBlockFormat = m_styles[index].format; - break; - - default: - break; - } - } - - m_colorColumnFormat = m_codeBlockFormat; - m_colorColumnFormat.setForeground(QColor(g_config->getEditorColorColumnFg())); - m_colorColumnFormat.setBackground(QColor(g_config->getEditorColorColumnBg())); - - m_result.reset(new PegHighlighterResult()); - m_fastResult.reset(new PegHighlighterFastResult()); - - m_fastParseBlocks = QPair(-1, -1); - - m_parser = new PegParser(this); - connect(m_parser, &PegParser::parseResultReady, - this, &PegMarkdownHighlighter::handleParseResult); - - m_timer = new QTimer(this); - m_timer->setSingleShot(true); - m_timer->setInterval(m_parseInterval); - connect(m_timer, &QTimer::timeout, - this, &PegMarkdownHighlighter::startParse); - - m_fastParseTimer = new QTimer(this); - m_fastParseTimer->setSingleShot(true); - m_fastParseTimer->setInterval(m_fastParseInterval); - connect(m_fastParseTimer, &QTimer::timeout, - this, [this]() { - startFastParse(m_fastParseInfo.m_position, - m_fastParseInfo.m_charsRemoved, - m_fastParseInfo.m_charsAdded); - }); - - m_scrollRehighlightTimer = new QTimer(this); - m_scrollRehighlightTimer->setSingleShot(true); - m_scrollRehighlightTimer->setInterval(5); - connect(m_scrollRehighlightTimer, &QTimer::timeout, - this, [this]() { - if (m_result->m_numOfBlocks > LARGE_BLOCK_NUMBER) { - rehighlightSensitiveBlocks(); - } - }); - - m_rehighlightTimer = new QTimer(this); - m_rehighlightTimer->setSingleShot(true); - m_rehighlightTimer->setInterval(10); - connect(m_rehighlightTimer, &QTimer::timeout, - this, &PegMarkdownHighlighter::rehighlightBlocks); - - connect(m_doc, &QTextDocument::contentsChange, - this, &PegMarkdownHighlighter::handleContentsChange); - - connect(m_editor->verticalScrollBar(), &QScrollBar::valueChanged, - m_scrollRehighlightTimer, static_cast(&QTimer::start)); - - m_contentChangeTime.start(); -} - -// Just use parse results to highlight block. -// Do not maintain block data and state here. -void PegMarkdownHighlighter::highlightBlock(const QString &p_text) -{ - QSharedPointer result(m_result); - - QTextBlock block = currentBlock(); - int blockNum = block.blockNumber(); - - bool isCodeBlock = currentBlockState() == HighlightBlockState::CodeBlock; - bool isNewBlock = block.userData() == NULL; - VTextBlockData *blockData = VTextBlockData::blockData(block); - QVector *cache = &blockData->getBlockHighlightCache(); - - // Fast parse can not cross multiple empty lines in code block, which - // cause the wrong parse results. - if (isNewBlock) { - int pstate = previousBlockState(); - if (pstate == HighlightBlockState::CodeBlock - || pstate == HighlightBlockState::CodeBlockStart) { - setCurrentBlockState(HighlightBlockState::CodeBlock); - isCodeBlock = true; - } - } - - bool cacheValid = true; - if (result->matched(m_timeStamp)) { - if (preHighlightSingleFormatBlock(result->m_blocksHighlights, - blockNum, - p_text, - isCodeBlock)) { - cacheValid = false; - } else if (blockData->isCacheValid() && blockData->getTimeStamp() == m_timeStamp) { - // Use the cache to highlight. - highlightBlockOne(*cache); - } else { - cache->clear(); - highlightBlockOne(result->m_blocksHighlights, blockNum, cache); - } - } else { - // If fast result cover this block, we do not need to use the outdated one. - if (isFastParseBlock(blockNum)) { - if (!preHighlightSingleFormatBlock(m_fastResult->m_blocksHighlights, - blockNum, - p_text, - isCodeBlock)) { - highlightBlockOne(m_fastResult->m_blocksHighlights, blockNum, NULL); - } - - cacheValid = false; - } else { - if (preHighlightSingleFormatBlock(result->m_blocksHighlights, - blockNum, - p_text, - isCodeBlock)) { - cacheValid = false; - } else if (blockData->isCacheValid() && result->matched(blockData->getTimeStamp())) { - // Use the cache to highlight. - highlightBlockOne(*cache); - } else { - cache->clear(); - highlightBlockOne(result->m_blocksHighlights, blockNum, cache); - } - } - } - - blockData->setCacheValid(cacheValid); - PegMarkdownHighlighter::updateBlockTimeStamp(block, result->m_timeStamp); - - if (isCodeBlock) { - QVector *cbCache = &blockData->getCodeBlockHighlightCache(); - if (blockData->getCodeBlockTimeStamp() == result->m_codeBlockTimeStamp - || !result->m_codeBlockHighlightReceived) { - highlightCodeBlock(*cbCache, p_text); - } else { - cbCache->clear(); - highlightCodeBlock(result, blockNum, p_text, cbCache); - PegMarkdownHighlighter::updateBlockCodeBlockTimeStamp(block, result->m_codeBlockTimeStamp); - } - - highlightCodeBlockColorColumn(p_text); - } -} - -inline -static bool containSpecialChar(const QString &p_str) -{ - QChar fi = p_str[0]; - QChar la = p_str[p_str.size() - 1]; - - return fi == '#' - || la == '`' || la == '$' || la == '~' || la == '*' || la == '_'; -} - -bool PegMarkdownHighlighter::preHighlightSingleFormatBlock(const QVector> &p_highlights, - int p_blockNum, - const QString &p_text, - bool p_forced) -{ - int sz = p_text.size(); - if (sz == 0) { - return false; - } - - if (p_highlights.size() <= p_blockNum) { - return false; - } - - if (!p_forced && !m_singleFormatBlocks.contains(p_blockNum)) { - return false; - } - - const QVector &units = p_highlights[p_blockNum]; - if (units.size() == 1) { - const HLUnit &unit = units[0]; - if (unit.start == 0 - && (int)unit.length < sz - && (p_forced || containSpecialChar(p_text))) { - setFormat(0, sz, m_styles[unit.styleIndex].format); - return true; - } - } - - return false; -} - -bool PegMarkdownHighlighter::highlightBlockOne(const QVector> &p_highlights, - int p_blockNum, - QVector *p_cache) -{ - bool highlighted = false; - if (p_highlights.size() > p_blockNum) { - // units are sorted by start position and length. - const QVector &units = p_highlights[p_blockNum]; - if (!units.isEmpty()) { - highlighted = true; - if (p_cache) { - p_cache->append(units); - } - - highlightBlockOne(units); - } - } - - return highlighted; -} - -void PegMarkdownHighlighter::highlightBlockOne(const QVector &p_units) -{ - for (int i = 0; i < p_units.size(); ++i) { - const HLUnit &unit = p_units[i]; - if (i == 0) { - // No need to merge format. - setFormat(unit.start, - unit.length, - m_styles[unit.styleIndex].format); - } else { - QTextCharFormat newFormat = m_styles[unit.styleIndex].format; - for (int j = i - 1; j >= 0; --j) { - if (p_units[j].start + p_units[j].length <= unit.start) { - // It won't affect current unit. - continue; - } else { - // Merge the format. - QTextCharFormat tmpFormat(newFormat); - newFormat = m_styles[p_units[j].styleIndex].format; - // tmpFormat takes precedence. - newFormat.merge(tmpFormat); - } - } - - setFormat(unit.start, unit.length, newFormat); - } - } -} - -#define KEY_PRESS_INTERVAL 50 - -// highlightBlock() will be called before this function. -void PegMarkdownHighlighter::handleContentsChange(int p_position, int p_charsRemoved, int p_charsAdded) -{ - Q_UNUSED(p_position); - - int interval = m_contentChangeTime.restart(); - - if (p_charsRemoved == 0 && p_charsAdded == 0) { - return; - } - - ++m_timeStamp; - - m_timer->stop(); - - if (m_timeStamp > 2) { - m_fastParseInfo.m_position = p_position; - m_fastParseInfo.m_charsRemoved = p_charsRemoved; - m_fastParseInfo.m_charsAdded = p_charsAdded; - m_fastParseTimer->start(interval < KEY_PRESS_INTERVAL ? 100 : m_fastParseInterval); - } - - // We still need a timer to start a complete parse. - m_timer->start(m_timeStamp == 2 ? 0 : m_parseInterval); -} - -void PegMarkdownHighlighter::startParse() -{ - QSharedPointer config(new PegParseConfig()); - config->m_timeStamp = m_timeStamp; - config->m_data = m_doc->toPlainText().toUtf8(); - config->m_numOfBlocks = m_doc->blockCount(); - config->m_extensions = m_parserExts; - - m_parser->parseAsync(config); -} - -void PegMarkdownHighlighter::startFastParse(int p_position, int p_charsRemoved, int p_charsAdded) -{ - // Get affected block range. - int firstBlockNum, lastBlockNum; - getFastParseBlockRange(p_position, p_charsRemoved, p_charsAdded, firstBlockNum, lastBlockNum); - if (firstBlockNum == -1) { - // We could not let m_fastResult NULL here. - clearFastParseResult(); - m_fastParseInterval = 100; - return; - } else { - m_fastParseInterval = (lastBlockNum - firstBlockNum) < 5 ? 0 : 30; - } - - QString text; - QTextBlock block = m_doc->findBlockByNumber(firstBlockNum); - int offset = block.position(); - while (block.isValid()) { - int blockNum = block.blockNumber(); - if (blockNum > lastBlockNum) { - break; - } else if (blockNum == firstBlockNum) { - text = block.text(); - } else { - text = text + "\n" + block.text(); - } - - block = block.next(); - } - - m_fastParseBlocks.first = firstBlockNum; - m_fastParseBlocks.second = lastBlockNum; - - QSharedPointer config(new PegParseConfig()); - config->m_timeStamp = m_timeStamp; - config->m_data = text.toUtf8(); - config->m_numOfBlocks = m_doc->blockCount(); - config->m_offset = offset; - config->m_extensions = m_parserExts; - config->m_fast = true; - - QSharedPointer parseRes = m_parser->parse(config); - processFastParseResult(parseRes); -} - -void PegMarkdownHighlighter::processFastParseResult(const QSharedPointer &p_result) -{ - m_fastResult.reset(new PegHighlighterFastResult(this, p_result)); - - // Add additional single format blocks. - updateSingleFormatBlocks(m_fastResult->m_blocksHighlights); - - if (!m_fastResult->matched(m_timeStamp) || m_result->matched(m_timeStamp)) { - return; - } - - for (int i = m_fastParseBlocks.first; i <= m_fastParseBlocks.second; ++i) { - QTextBlock block = m_doc->findBlockByNumber(i); - rehighlightBlock(block); - } -} - -static bool compHLUnitStyle(const HLUnitStyle &a, const HLUnitStyle &b) -{ - if (a.start < b.start) { - return true; - } else if (a.start == b.start) { - return a.length > b.length; - } else { - return false; - } -} - -void PegMarkdownHighlighter::setCodeBlockHighlights(TimeStamp p_timeStamp, - const QVector &p_units) -{ - QSharedPointer result(m_result); - if (!result->matched(p_timeStamp) - || result->m_numOfCodeBlockHighlightsToRecv <= 0) { - return; - } - - if (p_units.isEmpty()) { - goto exit; - } - - { - QVector> highlights(result->m_codeBlocksHighlights.size()); - for (auto const &unit : p_units) { - int pos = unit.m_position; - int end = unit.m_position + unit.m_length; - QTextBlock block = m_doc->findBlock(pos); - int startBlockNum = block.blockNumber(); - int endBlockNum = m_doc->findBlock(end).blockNumber(); - - // Text has been changed. Abandon the obsolete parsed result. - if (startBlockNum == -1 || endBlockNum >= highlights.size()) { - goto exit; - } - - while (block.isValid()) { - int blockNumber = block.blockNumber(); - if (blockNumber > endBlockNum) { - break; - } - - int blockStartPos = block.position(); - HLUnitStyle hl; - hl.style = unit.m_style; - if (blockNumber == startBlockNum) { - hl.start = pos - blockStartPos; - hl.length = (startBlockNum == endBlockNum) ? - (end - pos) : (block.length() - hl.start); - } else if (blockNumber == endBlockNum) { - hl.start = 0; - hl.length = end - blockStartPos; - } else { - hl.start = 0; - hl.length = block.length(); - } - - highlights[blockNumber].append(hl); - - block = block.next(); - } - } - - // Need to highlight in order. - for (int i = 0; i < highlights.size(); ++i) { - QVector &units = highlights[i]; - if (!units.isEmpty()) { - if (units.size() > 1) { - std::sort(units.begin(), units.end(), compHLUnitStyle); - } - - result->m_codeBlocksHighlights[i].append(units); - } - } - } - -exit: - if (--result->m_numOfCodeBlockHighlightsToRecv <= 0) { - result->m_codeBlockTimeStamp = nextCodeBlockTimeStamp(); - result->m_codeBlockHighlightReceived = true; - rehighlightBlocksLater(); - } -} - -void PegMarkdownHighlighter::updateHighlight() -{ - m_timer->stop(); - if (m_result->matched(m_timeStamp)) { - // No need to parse again. Already the latest. - updateCodeBlocks(m_result); - rehighlightBlocksLater(); - completeHighlight(m_result); - } else { - startParse(); - } -} - -void PegMarkdownHighlighter::handleParseResult(const QSharedPointer &p_result) -{ - if (!m_result.isNull() && m_result->m_timeStamp > p_result->m_timeStamp) { - return; - } - - clearFastParseResult(); - - m_result.reset(new PegHighlighterResult(this, p_result)); - - m_result->m_codeBlockTimeStamp = nextCodeBlockTimeStamp(); - - m_singleFormatBlocks.clear(); - updateSingleFormatBlocks(m_result->m_blocksHighlights); - - bool matched = m_result->matched(m_timeStamp); - if (matched) { - clearAllBlocksUserDataAndState(m_result); - - updateAllBlocksUserState(m_result); - - updateCodeBlocks(m_result); - } - - if (m_result->m_timeStamp == 2) { - m_notifyHighlightComplete = true; - rehighlightBlocks(); - } else { - rehighlightBlocksLater(); - } - - if (matched) { - completeHighlight(m_result); - } -} - -void PegMarkdownHighlighter::updateSingleFormatBlocks(const QVector> &p_highlights) -{ - for (int i = 0; i < p_highlights.size(); ++i) { - const QVector &units = p_highlights[i]; - if (units.size() == 1) { - const HLUnit &unit = units[0]; - if (unit.start == 0 && unit.length > 0) { - QTextBlock block = m_doc->findBlockByNumber(i); - if (block.length() - 1 <= (int)unit.length) { - m_singleFormatBlocks.insert(i); - } - } - } - } -} - -void PegMarkdownHighlighter::updateCodeBlocks(const QSharedPointer &p_result) -{ - // Only need to receive code block highlights when it is empty. - if (g_config->getEnableCodeBlockHighlight()) { - int cbSz = p_result->m_codeBlocks.size(); - if (cbSz > 0) { - if (PegMarkdownHighlighter::isEmptyCodeBlockHighlights(p_result->m_codeBlocksHighlights)) { - p_result->m_codeBlocksHighlights.resize(p_result->m_numOfBlocks); - p_result->m_numOfCodeBlockHighlightsToRecv = cbSz; - } - } else { - p_result->m_codeBlockHighlightReceived = true; - } - } else { - p_result->m_codeBlockHighlightReceived = true; - } - - emit codeBlocksUpdated(p_result->m_timeStamp, p_result->m_codeBlocks); -} - -void PegMarkdownHighlighter::clearAllBlocksUserDataAndState(const QSharedPointer &p_result) -{ - QTextBlock block = m_doc->firstBlock(); - while (block.isValid()) { - clearBlockUserData(p_result, block); - - block.setUserState(HighlightBlockState::Normal); - - block = block.next(); - } -} - -void PegMarkdownHighlighter::clearBlockUserData(const QSharedPointer &p_result, - QTextBlock &p_block) -{ - Q_UNUSED(p_result); - - int blockNum = p_block.blockNumber(); - VTextBlockData *data = VTextBlockData::blockData(p_block); - if (!data) { - return; - } - - data->setCodeBlockIndentation(-1); - if (data->getPreviews().isEmpty()) { - m_possiblePreviewBlocks.remove(blockNum); - } else { - m_possiblePreviewBlocks.insert(blockNum); - } -} - -void PegMarkdownHighlighter::updateAllBlocksUserState(const QSharedPointer &p_result) -{ - // Code blocks. - bool hlColumn = g_config->getColorColumn() > 0; - const QHash &cbStates = p_result->m_codeBlocksState; - for (auto it = cbStates.begin(); it != cbStates.end(); ++it) { - QTextBlock block = m_doc->findBlockByNumber(it.key()); - if (!block.isValid()) { - continue; - } - - // Set code block indentation. - if (hlColumn) { - VTextBlockData *blockData = static_cast(block.userData()); - Q_ASSERT(blockData); - - switch (it.value()) { - case HighlightBlockState::CodeBlockStart: - { - int startLeadingSpaces = 0; - QRegularExpression reg(VUtils::c_fencedCodeBlockStartRegExp); - auto match = reg.match(block.text()); - if (match.hasMatch()) { - startLeadingSpaces = match.captured(1).size(); - } - - blockData->setCodeBlockIndentation(startLeadingSpaces); - break; - } - - case HighlightBlockState::CodeBlock: - V_FALLTHROUGH; - case HighlightBlockState::CodeBlockEnd: - { - int startLeadingSpaces = 0; - VTextBlockData *preBlockData = previousBlockData(block); - if (preBlockData) { - startLeadingSpaces = preBlockData->getCodeBlockIndentation(); - } - - blockData->setCodeBlockIndentation(startLeadingSpaces); - break; - } - - default: - Q_ASSERT(false); - break; - } - } - - block.setUserState(it.value()); - } - - // HRule blocks. - foreach (int blk, p_result->m_hruleBlocks) { - QTextBlock block = m_doc->findBlockByNumber(blk); - if (block.isValid()) { - block.setUserState(HighlightBlockState::HRule); - } - } -} - -void PegMarkdownHighlighter::highlightCodeBlock(const QSharedPointer &p_result, - int p_blockNum, - const QString &p_text, - QVector *p_cache) -{ - // Brush the indentation spaces. - if (currentBlockState() == HighlightBlockState::CodeBlock) { - int spaces = VEditUtils::fetchIndentation(p_text); - if (spaces > 0) { - setFormat(0, spaces, m_codeBlockFormat); - } - } - - if (p_result->m_codeBlocksHighlights.size() > p_blockNum) { - const QVector &units = p_result->m_codeBlocksHighlights[p_blockNum]; - if (!units.isEmpty()) { - if (p_cache) { - p_cache->append(units); - } - - highlightCodeBlockOne(units); - } - } -} - -void PegMarkdownHighlighter::highlightCodeBlock(const QVector &p_units, - const QString &p_text) -{ - // Brush the indentation spaces. - if (currentBlockState() == HighlightBlockState::CodeBlock) { - int spaces = VEditUtils::fetchIndentation(p_text); - if (spaces > 0) { - setFormat(0, spaces, m_codeBlockFormat); - } - } - - if (!p_units.isEmpty()) { - highlightCodeBlockOne(p_units); - } -} - -void PegMarkdownHighlighter::highlightCodeBlockOne(const QVector &p_units) -{ - QVector formats(p_units.size(), NULL); - for (int i = 0; i < p_units.size(); ++i) { - const HLUnitStyle &unit = p_units[i]; - auto it = m_codeBlockStyles.find(unit.style); - if (it == m_codeBlockStyles.end()) { - continue; - } - - formats[i] = &(*it); - - QTextCharFormat newFormat = m_codeBlockFormat; - newFormat.merge(*it); - for (int j = i - 1; j >= 0; --j) { - if (p_units[j].start + p_units[j].length <= unit.start) { - // It won't affect current unit. - continue; - } else { - // Merge the format. - if (formats[j]) { - QTextCharFormat tmpFormat(newFormat); - newFormat = *(formats[j]); - // tmpFormat takes precedence. - newFormat.merge(tmpFormat); - } - } - } - - setFormat(unit.start, unit.length, newFormat); - } -} - -void PegMarkdownHighlighter::highlightCodeBlockColorColumn(const QString &p_text) -{ - int cc = g_config->getColorColumn(); - if (cc <= 0) { - return; - } - - VTextBlockData *blockData = currentBlockData(); - Q_ASSERT(blockData); - int indent = blockData->getCodeBlockIndentation(); - if (indent == -1) { - return; - } - - cc += indent; - if (p_text.size() < cc) { - return; - } - - setFormat(cc - 1, 1, m_colorColumnFormat); -} - -void PegMarkdownHighlighter::completeHighlight(QSharedPointer p_result) -{ - m_notifyHighlightComplete = true; - - if (isMathJaxEnabled()) { - emit mathjaxBlocksUpdated(p_result->m_mathjaxBlocks); - } - - emit tableBlocksUpdated(p_result->m_tableBlocks); - - emit imageLinksUpdated(p_result->m_imageRegions); - emit headersUpdated(p_result->m_headerRegions); -} - -void PegMarkdownHighlighter::getFastParseBlockRange(int p_position, - int p_charsRemoved, - int p_charsAdded, - int &p_firstBlock, - int &p_lastBlock) const -{ - const int maxNumOfBlocks = 15; - - int charsChanged = p_charsRemoved + p_charsAdded; - QTextBlock firstBlock = m_doc->findBlock(p_position); - - // May be an invalid block. - QTextBlock lastBlock = m_doc->findBlock(qMax(0, p_position + charsChanged)); - if (!lastBlock.isValid()) { - lastBlock = m_doc->lastBlock(); - } - - int num = lastBlock.blockNumber() - firstBlock.blockNumber() + 1; - if (num > maxNumOfBlocks) { - p_firstBlock = p_lastBlock = -1; - return; - } - - // Look up. - while (firstBlock.isValid() && num <= maxNumOfBlocks) { - QTextBlock preBlock = firstBlock.previous(); - if (!preBlock.isValid()) { - break; - } - - // Check code block. - int state = firstBlock.userState(); - if (state == HighlightBlockState::CodeBlock - || state == HighlightBlockState::CodeBlockEnd) { - goto goup; - } - - // Empty block. - if (VEditUtils::isEmptyBlock(firstBlock)) { - goto goup; - } - - if (VEditUtils::fetchIndentation(firstBlock) < 4) { - // If previous block is empty, then we could stop now. - if (VEditUtils::isEmptyBlock(preBlock)) { - int preState = preBlock.userState(); - if (preState != HighlightBlockState::CodeBlockStart - && preState != HighlightBlockState::CodeBlock) { - break; - } - } - } - -goup: - firstBlock = preBlock; - ++num; - } - - // Look down. - bool inCodeBlock = false; - while (lastBlock.isValid() && num <= maxNumOfBlocks) { - QTextBlock nextBlock = lastBlock.next(); - if (!nextBlock.isValid()) { - break; - } - - // Check code block. - switch (lastBlock.userState()) { - case HighlightBlockState::CodeBlockStart: - V_FALLTHROUGH; - case HighlightBlockState::CodeBlock: - inCodeBlock = true; - goto godown; - - case HighlightBlockState::CodeBlockEnd: - inCodeBlock = false; - break; - - default: - break; - } - - // Empty block. - if (VEditUtils::isEmptyBlock(nextBlock) && !inCodeBlock) { - int nstate = nextBlock.userState(); - if (nstate != HighlightBlockState::CodeBlockStart - && nstate != HighlightBlockState::CodeBlock - && nstate != HighlightBlockState::CodeBlockEnd) { - break; - } - } - -godown: - lastBlock = nextBlock; - ++num; - } - - p_firstBlock = firstBlock.blockNumber(); - p_lastBlock = lastBlock.blockNumber(); - if (p_lastBlock < p_firstBlock) { - p_lastBlock = p_firstBlock; - } else if (p_lastBlock - p_firstBlock + 1 > maxNumOfBlocks) { - p_firstBlock = p_lastBlock = -1; - } -} - -void PegMarkdownHighlighter::rehighlightSensitiveBlocks() -{ - QTextBlock cb = m_editor->textCursorW().block(); - - int first, last; - m_editor->visibleBlockRange(first, last); - - bool cursorVisible = cb.blockNumber() >= first && cb.blockNumber() <= last; - - // Include extra blocks. - const int nrUpExtra = 5; - const int nrDownExtra = 20; - first = qMax(0, first - nrUpExtra); - last = qMin(m_doc->blockCount() - 1, last + nrDownExtra); - - if (rehighlightBlockRange(first, last)) { - if (cursorVisible) { - m_editor->ensureCursorVisibleW(); - } - } -} - -void PegMarkdownHighlighter::rehighlightBlocks() -{ - if (m_result->m_numOfBlocks <= LARGE_BLOCK_NUMBER) { - rehighlightBlockRange(0, m_result->m_numOfBlocks - 1); - } else { - rehighlightSensitiveBlocks(); - } - - if (m_notifyHighlightComplete) { - m_notifyHighlightComplete = false; - emit highlightCompleted(); - } -} - -bool PegMarkdownHighlighter::rehighlightBlockRange(int p_first, int p_last) -{ - bool highlighted = false; - const QHash &cbStates = m_result->m_codeBlocksState; - const QVector> &hls = m_result->m_blocksHighlights; - const QVector> &cbHls = m_result->m_codeBlocksHighlights; - - int nr = 0; - QTextBlock block = m_doc->findBlockByNumber(p_first); - while (block.isValid()) { - int blockNum = block.blockNumber(); - if (blockNum > p_last) { - break; - } - - bool needHL = false; - bool updateTS = false; - VTextBlockData *data = VTextBlockData::blockData(block); - if (PegMarkdownHighlighter::blockTimeStamp(block) != m_result->m_timeStamp) { - needHL = true; - // Try to find cache. - if (blockNum < hls.size()) { - if (data->isBlockHighlightCacheMatched(hls[blockNum])) { - needHL = false; - updateTS = true; - } - } - } - - if (!needHL) { - // FIXME: what about a previous code block turn into a non-code block? For now, - // they can be distinguished by block highlights. - auto it = cbStates.find(blockNum); - if (it != cbStates.end() && it.value() == HighlightBlockState::CodeBlock) { - if (PegMarkdownHighlighter::blockCodeBlockTimeStamp(block) != m_result->m_codeBlockTimeStamp - && m_result->m_codeBlockHighlightReceived) { - needHL = true; - // Try to find cache. - if (blockNum < cbHls.size()) { - if (data->isCodeBlockHighlightCacheMatched(cbHls[blockNum])) { - needHL = false; - updateTS = true; - } - } - } - } - } - - if (needHL) { - highlighted = true; - rehighlightBlock(block); - ++nr; - } else if (updateTS) { - data->setCacheValid(true); - data->setTimeStamp(m_result->m_timeStamp); - data->setCodeBlockTimeStamp(m_result->m_codeBlockTimeStamp); - } - - block = block.next(); - } - - qDebug() << "rehighlightBlockRange" << p_first << p_last << nr; - return highlighted; -} - -void PegMarkdownHighlighter::clearFastParseResult() -{ - m_fastParseBlocks.first = -1; - m_fastParseBlocks.second = -1; - m_fastResult->clear(); -} - -void PegMarkdownHighlighter::rehighlightBlocksLater() -{ - m_rehighlightTimer->start(); -} diff --git a/src/pegmarkdownhighlighter.h b/src/pegmarkdownhighlighter.h deleted file mode 100644 index 6780937d..00000000 --- a/src/pegmarkdownhighlighter.h +++ /dev/null @@ -1,380 +0,0 @@ -#ifndef PEGMARKDOWNHIGHLIGHTER_H -#define PEGMARKDOWNHIGHLIGHTER_H - -#include -#include -#include - -#include "vtextblockdata.h" -#include "markdownhighlighterdata.h" -#include "peghighlighterresult.h" - -class PegParser; -class QTimer; -class VMdEditor; - -class PegMarkdownHighlighter : public QSyntaxHighlighter -{ - Q_OBJECT -public: - PegMarkdownHighlighter(QTextDocument *p_doc, VMdEditor *p_editor); - - void init(const QVector &p_styles, - const QHash &p_codeBlockStyles, - bool p_mathjaxEnabled, - int p_timerInterval); - - // Set code block highlight result by VCodeBlockHighlightHelper. - void setCodeBlockHighlights(TimeStamp p_timeStamp, const QVector &p_units); - - const QVector &getHeaderRegions() const; - - const QSet &getPossiblePreviewBlocks() const; - - void clearPossiblePreviewBlocks(const QVector &p_blocksToClear); - - void addPossiblePreviewBlock(int p_blockNumber); - - QHash &getCodeBlockStyles(); - - QVector &getStyles(); - - const QVector &getStyles() const; - - const QTextDocument *getDocument() const; - - const QVector &getImageRegions() const; - - const QVector &getCodeBlocks() const; - -public slots: - // Parse and rehighlight immediately. - void updateHighlight(); - - // Rehighlight sensitive blocks using current parse result, mainly - // visible blocks. - void rehighlightSensitiveBlocks(); - -signals: - void highlightCompleted(); - - // QVector is implicitly shared. - void codeBlocksUpdated(TimeStamp p_timeStamp, const QVector &p_codeBlocks); - - // Emitted when image regions have been fetched from a new parsing result. - void imageLinksUpdated(const QVector &p_imageRegions); - - // Emitted when header regions have been fetched from a new parsing result. - void headersUpdated(const QVector &p_headerRegions); - - // Emitted when Mathjax blocks updated. - void mathjaxBlocksUpdated(const QVector &p_mathjaxBlocks); - - // Emitted when table blocks updated. - void tableBlocksUpdated(const QVector &p_tableBlocks); - -protected: - void highlightBlock(const QString &p_text) Q_DECL_OVERRIDE; - -private slots: - void handleContentsChange(int p_position, int p_charsRemoved, int p_charsAdded); - - void handleParseResult(const QSharedPointer &p_result); - -private: - struct FastParseInfo - { - int m_position; - int m_charsRemoved; - int m_charsAdded; - } m_fastParseInfo; - - void startParse(); - - void startFastParse(int p_position, int p_charsRemoved, int p_charsAdded); - - void clearAllBlocksUserDataAndState(const QSharedPointer &p_result); - - void updateAllBlocksUserState(const QSharedPointer &p_result); - - void updateCodeBlocks(const QSharedPointer &p_result); - - void clearBlockUserData(const QSharedPointer &p_result, - QTextBlock &p_block); - - // Highlight fenced code block according to VCodeBlockHighlightHelper result. - void highlightCodeBlock(const QSharedPointer &p_result, - int p_blockNum, - const QString &p_text, - QVector *p_cache); - - void highlightCodeBlock(const QVector &p_units, - const QString &p_text); - - void highlightCodeBlockOne(const QVector &p_units); - - // Highlight color column in code block. - void highlightCodeBlockColorColumn(const QString &p_text); - - VTextBlockData *currentBlockData() const; - - VTextBlockData *previousBlockData() const; - - VTextBlockData *previousBlockData(const QTextBlock &p_block) const; - - void completeHighlight(QSharedPointer p_result); - - bool isMathJaxEnabled() const; - - void getFastParseBlockRange(int p_position, - int p_charsRemoved, - int p_charsAdded, - int &p_firstBlock, - int &p_lastBlock) const; - - void processFastParseResult(const QSharedPointer &p_result); - - bool highlightBlockOne(const QVector> &p_highlights, - int p_blockNum, - QVector *p_cache); - - void highlightBlockOne(const QVector &p_units); - - // To avoid line height jitter and code block mess. - bool preHighlightSingleFormatBlock(const QVector> &p_highlights, - int p_blockNum, - const QString &p_text, - bool p_forced); - - void updateSingleFormatBlocks(const QVector> &p_highlights); - - void rehighlightBlocks(); - - void rehighlightBlocksLater(); - - bool rehighlightBlockRange(int p_first, int p_last); - - TimeStamp nextCodeBlockTimeStamp(); - - bool isFastParseBlock(int p_blockNum) const; - - void clearFastParseResult(); - - static VTextBlockData *getBlockData(const QTextBlock &p_block); - - static bool isEmptyCodeBlockHighlights(const QVector> &p_highlights); - - static TimeStamp blockTimeStamp(const QTextBlock &p_block); - - static void updateBlockTimeStamp(const QTextBlock &p_block, TimeStamp p_ts); - - static TimeStamp blockCodeBlockTimeStamp(const QTextBlock &p_block); - - static void updateBlockCodeBlockTimeStamp(const QTextBlock &p_block, TimeStamp p_ts); - - QTextDocument *m_doc; - - VMdEditor *m_editor; - - TimeStamp m_timeStamp; - - TimeStamp m_codeBlockTimeStamp; - - QVector m_styles; - QHash m_codeBlockStyles; - - QTextCharFormat m_codeBlockFormat; - QTextCharFormat m_colorColumnFormat; - - PegParser *m_parser; - - QSharedPointer m_result; - - QSharedPointer m_fastResult; - - // Block range of fast parse, inclusive. - QPair m_fastParseBlocks; - - // Block number of those blocks which possible contains previewed image. - QSet m_possiblePreviewBlocks; - - // Extensions for parser. - int m_parserExts; - - // Timer to trigger parse. - QTimer *m_timer; - - int m_parseInterval; - - QTimer *m_fastParseTimer; - - QTimer *m_scrollRehighlightTimer; - - QTimer *m_rehighlightTimer; - - // Blocks have only one format set which occupies the whole block. - QSet m_singleFormatBlocks; - - bool m_notifyHighlightComplete; - - // Time since last content change. - QTime m_contentChangeTime; - - // Interval for fast parse timer. - int m_fastParseInterval; -}; - -inline const QVector &PegMarkdownHighlighter::getHeaderRegions() const -{ - return m_result->m_headerRegions; -} - -inline const QVector &PegMarkdownHighlighter::getImageRegions() const -{ - return m_result->m_imageRegions; -} - -inline const QSet &PegMarkdownHighlighter::getPossiblePreviewBlocks() const -{ - return m_possiblePreviewBlocks; -} - -inline void PegMarkdownHighlighter::clearPossiblePreviewBlocks(const QVector &p_blocksToClear) -{ - for (auto i : p_blocksToClear) { - m_possiblePreviewBlocks.remove(i); - } -} - -inline void PegMarkdownHighlighter::addPossiblePreviewBlock(int p_blockNumber) -{ - m_possiblePreviewBlocks.insert(p_blockNumber); -} - -inline QHash &PegMarkdownHighlighter::getCodeBlockStyles() -{ - return m_codeBlockStyles; -} - -inline QVector &PegMarkdownHighlighter::getStyles() -{ - return m_styles; -} - -inline const QVector &PegMarkdownHighlighter::getStyles() const -{ - return m_styles; -} - -inline const QTextDocument *PegMarkdownHighlighter::getDocument() const -{ - return m_doc; -} - -inline VTextBlockData *PegMarkdownHighlighter::currentBlockData() const -{ - return static_cast(currentBlockUserData()); -} - -inline VTextBlockData *PegMarkdownHighlighter::previousBlockData() const -{ - QTextBlock block = currentBlock().previous(); - if (!block.isValid()) { - return NULL; - } - - return static_cast(block.userData()); -} - -inline VTextBlockData *PegMarkdownHighlighter::previousBlockData(const QTextBlock &p_block) const -{ - if (!p_block.isValid()) { - return NULL; - } - - QTextBlock block = p_block.previous(); - if (!block.isValid()) { - return NULL; - } - - return static_cast(block.userData()); -} - -inline bool PegMarkdownHighlighter::isMathJaxEnabled() const -{ - return m_parserExts & pmh_EXT_MATH; -} - -inline TimeStamp PegMarkdownHighlighter::blockTimeStamp(const QTextBlock &p_block) -{ - VTextBlockData *data = static_cast(p_block.userData()); - if (data) { - return data->getTimeStamp(); - } else { - return 0; - } -} - -inline void PegMarkdownHighlighter::updateBlockTimeStamp(const QTextBlock &p_block, TimeStamp p_ts) -{ - VTextBlockData *data = static_cast(p_block.userData()); - if (data) { - data->setTimeStamp(p_ts); - } -} - -inline TimeStamp PegMarkdownHighlighter::blockCodeBlockTimeStamp(const QTextBlock &p_block) -{ - VTextBlockData *data = static_cast(p_block.userData()); - if (data) { - return data->getCodeBlockTimeStamp(); - } else { - return 0; - } -} - -inline void PegMarkdownHighlighter::updateBlockCodeBlockTimeStamp(const QTextBlock &p_block, TimeStamp p_ts) -{ - VTextBlockData *data = static_cast(p_block.userData()); - if (data) { - data->setCodeBlockTimeStamp(p_ts); - } -} - -inline bool PegMarkdownHighlighter::isEmptyCodeBlockHighlights(const QVector> &p_highlights) -{ - if (p_highlights.isEmpty()) { - return true; - } - - bool empty = true; - for (int i = 0; i < p_highlights.size(); ++i) { - if (!p_highlights[i].isEmpty()) { - empty = false; - break; - } - } - - return empty; -} - -inline VTextBlockData *PegMarkdownHighlighter::getBlockData(const QTextBlock &p_block) -{ - return static_cast(p_block.userData()); -} - -inline TimeStamp PegMarkdownHighlighter::nextCodeBlockTimeStamp() -{ - return ++m_codeBlockTimeStamp; -} - -inline bool PegMarkdownHighlighter::isFastParseBlock(int p_blockNum) const -{ - return p_blockNum >= m_fastParseBlocks.first && p_blockNum <= m_fastParseBlocks.second; -} - -inline const QVector &PegMarkdownHighlighter::getCodeBlocks() const -{ - return m_result->m_codeBlocks; -} -#endif // PEGMARKDOWNHIGHLIGHTER_H diff --git a/src/pegparser.cpp b/src/pegparser.cpp deleted file mode 100644 index 0b93fa08..00000000 --- a/src/pegparser.cpp +++ /dev/null @@ -1,539 +0,0 @@ -#include "pegparser.h" - -enum WorkerState -{ - Idle, - Busy, - Cancelled, - Finished -}; - -void PegParseResult::parse(QAtomicInt &p_stop, bool p_fast) -{ - if (p_fast) { - return; - } - - parseImageRegions(p_stop); - - parseHeaderRegions(p_stop); - - parseFencedCodeBlockRegions(p_stop); - - parseInlineEquationRegions(p_stop); - - parseDisplayFormulaRegions(p_stop); - - parseHRuleRegions(p_stop); - - parseTableRegions(p_stop); - - parseTableHeaderRegions(p_stop); - - parseTableBorderRegions(p_stop); -} - -void PegParseResult::parseImageRegions(QAtomicInt &p_stop) -{ - parseRegions(p_stop, - pmh_IMAGE, - m_imageRegions, - false); -} - -void PegParseResult::parseHeaderRegions(QAtomicInt &p_stop) -{ - // From Qt5.7, the capacity is preserved. - m_headerRegions.clear(); - if (isEmpty()) { - return; - } - - pmh_element_type hx[6] = {pmh_H1, pmh_H2, pmh_H3, pmh_H4, pmh_H5, pmh_H6}; - for (int i = 0; i < 6; ++i) { - pmh_element *elem = m_pmhElements[hx[i]]; - while (elem != NULL) { - if (elem->end <= elem->pos) { - elem = elem->next; - continue; - } - - if (p_stop.load() == 1) { - return; - } - - m_headerRegions.push_back(VElementRegion(m_offset + elem->pos, m_offset + elem->end)); - elem = elem->next; - } - } - - if (p_stop.load() == 1) { - return; - } - - std::sort(m_headerRegions.begin(), m_headerRegions.end()); -} - -void PegParseResult::parseFencedCodeBlockRegions(QAtomicInt &p_stop) -{ - m_codeBlockRegions.clear(); - if (isEmpty()) { - return; - } - - pmh_element *elem = m_pmhElements[pmh_FENCEDCODEBLOCK]; - while (elem != NULL) { - if (elem->end <= elem->pos) { - elem = elem->next; - continue; - } - - if (p_stop.load() == 1) { - return; - } - - if (!m_codeBlockRegions.contains(m_offset + elem->pos)) { - m_codeBlockRegions.insert(m_offset + elem->pos, - VElementRegion(m_offset + elem->pos, m_offset + elem->end)); - } - - elem = elem->next; - } -} - -void PegParseResult::parseInlineEquationRegions(QAtomicInt &p_stop) -{ - parseRegions(p_stop, - pmh_INLINEEQUATION, - m_inlineEquationRegions, - false); -} - -void PegParseResult::parseDisplayFormulaRegions(QAtomicInt &p_stop) -{ - parseRegions(p_stop, - pmh_DISPLAYFORMULA, - m_displayFormulaRegions, - true); -} - -void PegParseResult::parseHRuleRegions(QAtomicInt &p_stop) -{ - parseRegions(p_stop, - pmh_HRULE, - m_hruleRegions, - false); -} - -void PegParseResult::parseTableRegions(QAtomicInt &p_stop) -{ - parseRegions(p_stop, - pmh_TABLE, - m_tableRegions, - true); -} - -void PegParseResult::parseTableHeaderRegions(QAtomicInt &p_stop) -{ - parseRegions(p_stop, - pmh_TABLEHEADER, - m_tableHeaderRegions, - true); -} - -void PegParseResult::parseTableBorderRegions(QAtomicInt &p_stop) -{ - parseRegions(p_stop, - pmh_TABLEBORDER, - m_tableBorderRegions, - true); -} - -void PegParseResult::parseRegions(QAtomicInt &p_stop, - pmh_element_type p_type, - QVector &p_result, - bool p_sort) -{ - p_result.clear(); - if (isEmpty()) { - return; - } - - pmh_element *elem = m_pmhElements[p_type]; - while (elem != NULL) { - if (elem->end <= elem->pos) { - elem = elem->next; - continue; - } - - if (p_stop.load() == 1) { - return; - } - - p_result.push_back(VElementRegion(m_offset + elem->pos, m_offset + elem->end)); - elem = elem->next; - } - - if (p_sort && p_stop.load() != 1) { - std::sort(p_result.begin(), p_result.end()); - } -} - - -PegParserWorker::PegParserWorker(QObject *p_parent) - : QThread(p_parent), - m_stop(0), - m_state(WorkerState::Idle) -{ -} - -void PegParserWorker::prepareParse(const QSharedPointer &p_config) -{ - Q_ASSERT(m_parseConfig.isNull()); - - m_state = WorkerState::Busy; - m_parseConfig = p_config; -} - -void PegParserWorker::reset() -{ - m_parseConfig.reset(); - m_parseResult.reset(); - m_stop.store(0); - m_state = WorkerState::Idle; -} - -void PegParserWorker::stop() -{ - m_stop.store(1); -} - -void PegParserWorker::run() -{ - Q_ASSERT(m_state == WorkerState::Busy); - - m_parseResult = parseMarkdown(m_parseConfig, m_stop); - - if (isAskedToStop()) { - m_state = WorkerState::Cancelled; - return; - } - - m_state = WorkerState::Finished; -} - -QSharedPointer PegParserWorker::parseMarkdown(const QSharedPointer &p_config, - QAtomicInt &p_stop) -{ - QSharedPointer result(new PegParseResult(p_config)); - - if (p_config->m_data.isEmpty()) { - return result; - } - - result->m_pmhElements = PegParser::parseMarkdownToElements(p_config); - - if (p_stop.load() == 1) { - return result; - } - - result->parse(p_stop, p_config->m_fast); - - return result; -} - - -#define NUM_OF_THREADS 2 - -PegParser::PegParser(QObject *p_parent) - : QObject(p_parent) -{ - init(); -} - -void PegParser::init() -{ - for (int i = 0; i < NUM_OF_THREADS; ++i) { - PegParserWorker *th = new PegParserWorker(this); - connect(th, &PegParserWorker::finished, - this, [this, th]() { - handleWorkerFinished(th); - }); - - m_workers.append(th); - } -} - -void PegParser::clear() -{ - m_pendingWork.reset(); - - for (auto const & th : m_workers) { - th->quit(); - th->wait(); - - delete th; - } - - m_workers.clear(); -} - -PegParser::~PegParser() -{ - clear(); -} - -void PegParser::parseAsync(const QSharedPointer &p_config) -{ - m_pendingWork = p_config; - - pickWorker(); -} - -QSharedPointer PegParser::parse(const QSharedPointer &p_config) -{ - QSharedPointer result(new PegParseResult(p_config)); - - if (p_config->m_data.isEmpty()) { - return result; - } - - result->m_pmhElements = PegParser::parseMarkdownToElements(p_config); - - QAtomicInt stop(0); - result->parse(stop, p_config->m_fast); - - return result; -} - -void PegParser::handleWorkerFinished(PegParserWorker *p_worker) -{ - QSharedPointer result; - if (p_worker->state() == WorkerState::Finished) { - result = p_worker->parseResult(); - } - - p_worker->reset(); - - pickWorker(); - - if (!result.isNull()) { - emit parseResultReady(result); - } -} - -void PegParser::pickWorker() -{ - if (m_pendingWork.isNull()) { - return; - } - - bool allBusy = true; - for (auto th : m_workers) { - if (th->state() == WorkerState::Idle) { - scheduleWork(th, m_pendingWork); - m_pendingWork.reset(); - return; - } else if (th->state() != WorkerState::Busy) { - allBusy = false; - } - } - - if (allBusy) { - // Need to stop the worker with non-minimal timestamp. - int idx = 0; - TimeStamp minTS = m_workers[idx]->workTimeStamp(); - - if (m_workers.size() > 1) { - if (m_workers[1]->workTimeStamp() > minTS) { - idx = 1; - } - } - - m_workers[idx]->stop(); - } -} - -void PegParser::scheduleWork(PegParserWorker *p_worker, - const QSharedPointer &p_config) -{ - Q_ASSERT(p_worker->state() == WorkerState::Idle); - - p_worker->reset(); - p_worker->prepareParse(p_config); - p_worker->start(); -} - -QVector PegParser::parseImageRegions(const QSharedPointer &p_config) -{ - QVector regs; - pmh_element **res = PegParser::parseMarkdownToElements(p_config); - if (!res) { - return regs; - } - - int offset = p_config->m_offset; - pmh_element *elem = res[pmh_IMAGE]; - while (elem != NULL) { - if (elem->end <= elem->pos) { - elem = elem->next; - continue; - } - - regs.push_back(VElementRegion(offset + elem->pos, offset + elem->end)); - elem = elem->next; - } - - pmh_free_elements(res); - - return regs; -} - -#define MAX_CODE_POINT 65535 - -#define X_CHAR 86U - -#define HAS_UTF8_BOM(x) ( ((*x & 0xFF) == 0xEF)\ - && ((*(x+1) & 0xFF) == 0xBB)\ - && ((*(x+2) & 0xFF) == 0xBF) ) - -// Calculate the UTF8 code point. -// Return the number of chars consumed. -static inline int utf8CodePoint(const char *p_ch, int &p_codePoint) -{ - unsigned char uch = *p_ch; - - if ((uch & 0x80) == 0) { - p_codePoint = uch; - return 1; - } else if ((uch & 0xE0) == 0xC0) { - // 110yyyxx 10xxxxxx -> 00000yyy xxxxxxxx - unsigned char uch2 = *(p_ch + 1); - p_codePoint = ((uch & 0x1CL) << 6) + ((uch & 0x3L) << 6) + (uch2 & 0x3FL); - return 2; - } else if ((uch & 0xF0) == 0xE0) { - // 1110yyyy 10yyyyxx 10xxxxxx -> yyyyyyyy xxxxxxxx - unsigned char uch2 = *(p_ch + 1); - unsigned char uch3 = *(p_ch + 2); - p_codePoint = ((uch & 0xF) << 12) - + ((uch2 & 0x3CL) << 6) + ((uch2 & 0x3L) << 6) - + (uch3 & 0x3FL); - return 3; - } else if ((uch & 0xF8) == 0xF0) { - // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx -> 000zzzzz yyyyyyyy xxxxxxxx - unsigned char uch2 = *(p_ch + 1); - unsigned char uch3 = *(p_ch + 2); - unsigned char uch4 = *(p_ch + 3); - p_codePoint = ((uch & 0x7L) << 18) - + ((uch2 & 0x30L) << 12) + ((uch2 & 0xFL) << 12) - + ((uch3 & 0x3CL) << 6) + ((uch3 & 0x3L) << 6) - + (uch4 & 0x3FL); - return 4; - } else { - return -1; - } -} - -static inline void copyChars(char *p_dest, const char *p_src, int p_num) -{ - for (int i = 0; i < p_num; ++i) { - *(p_dest + i) = *(p_src + i); - } -} - -// @p_data: UTF-8 data array. -// If @p_data contain unicode characters with code value above 65535, it will break -// it into two characters with code value below 65536. -// Return null if there is no fix. Otherwise, return a fixed copy of the data. -static QSharedPointer tryFixUnicodeData(const char *p_data) -{ - bool needFix = false; - int sz = 0; - - const char *ch = p_data; - bool hasBOM = false; - if (HAS_UTF8_BOM(ch)) { - hasBOM = true; - ch += 3; - sz += 3; - } - - // Calculate the size of fixed data. - while (*ch != '\0') { - int cp; - int nr = utf8CodePoint(ch, cp); - if (nr == -1) { - return NULL; - } - - if (cp > MAX_CODE_POINT) { - needFix = true; - ch += nr; - // Use two one-byte chars to replace. - sz += 2; - } else { - ch += nr; - sz += nr; - } - } - - if (!needFix) { - return NULL; - } - - // Replace those chars with two one-byte chars. - QSharedPointer res(new char[sz + 1]); - char *newChar = res.data(); - int idx = 0; - ch = p_data; - if (hasBOM) { - copyChars(newChar + idx, ch, 3); - ch += 3; - idx += 3; - } - - while (*ch != '\0') { - int cp; - int nr = utf8CodePoint(ch, cp); - Q_ASSERT(nr > 0); - if (cp > MAX_CODE_POINT) { - *(newChar + idx) = X_CHAR; - *(newChar + idx + 1) = X_CHAR; - ch += nr; - idx += 2; - } else { - copyChars(newChar + idx, ch, nr); - ch += nr; - idx += nr; - } - } - - Q_ASSERT(idx == sz); - *(newChar + sz) = '\0'; - - return res; -} - -pmh_element **PegParser::parseMarkdownToElements(const QSharedPointer &p_config) -{ - if (p_config->m_data.isEmpty()) { - return NULL; - } - - pmh_element **pmhResult = NULL; - - // p_config->m_data is encoding in UTF-8. - // QString stores a string of 16-bit QChars. Unicode characters with code values above 65535 are stored using surrogate pairs, i.e., two consecutive QChars. - // Hence, a QString using two QChars to save one code value if it's above 65535, with size() - // returning 2. pmh_markdown_to_elements() will treat it at the size of 1 (expectively). - // To make it work, we split unicode characters whose code value is above 65535 into two unicode - // characters whose code value is below 65535. - char *data = p_config->m_data.data(); - QSharedPointer fixedData = tryFixUnicodeData(data); - if (fixedData) { - data = fixedData.data(); - } - - pmh_markdown_to_elements(data, p_config->m_extensions, &pmhResult); - return pmhResult; -} diff --git a/src/pegparser.h b/src/pegparser.h deleted file mode 100644 index a5012d7b..00000000 --- a/src/pegparser.h +++ /dev/null @@ -1,248 +0,0 @@ -#ifndef PEGPARSER_H -#define PEGPARSER_H - -#include - -#include -#include -#include -#include - -#include "vconstants.h" -#include "markdownhighlighterdata.h" - -struct PegParseConfig -{ - PegParseConfig() - : m_timeStamp(0), - m_numOfBlocks(0), - m_offset(0), - m_extensions(pmh_EXT_NONE), - m_fast(false) - { - } - - TimeStamp m_timeStamp; - - QByteArray m_data; - - int m_numOfBlocks; - - // Offset of m_data in the document. - int m_offset; - - int m_extensions; - - // Fast parse. - bool m_fast; - - QString toString() const - { - return QString("PegParseConfig ts %1 data %2 blocks %3").arg(m_timeStamp) - .arg(m_data.size()) - .arg(m_numOfBlocks); - } -}; - -struct PegParseResult -{ - PegParseResult(const QSharedPointer &p_config) - : m_timeStamp(p_config->m_timeStamp), - m_numOfBlocks(p_config->m_numOfBlocks), - m_offset(p_config->m_offset), - m_pmhElements(NULL) - { - } - - ~PegParseResult() - { - clearPmhElements(); - } - - void clearPmhElements() - { - if (m_pmhElements) { - pmh_free_elements(m_pmhElements); - m_pmhElements = NULL; - } - } - - bool operator<(const PegParseResult &p_other) const - { - return m_timeStamp < p_other.m_timeStamp; - } - - QString toString() const - { - return QString("PegParseResult ts %1").arg(m_timeStamp); - } - - bool isEmpty() const - { - return !m_pmhElements; - } - - // Parse m_pmhElements. - void parse(QAtomicInt &p_stop, bool p_fast); - - TimeStamp m_timeStamp; - - int m_numOfBlocks; - - int m_offset; - - pmh_element **m_pmhElements; - - // All image link regions. - QVector m_imageRegions; - - // All header regions. - // Sorted by start position. - QVector m_headerRegions; - - // Fenced code block regions. - // Ordered by start position in ascending order. - QMap m_codeBlockRegions; - - // All $ $ inline equation regions. - QVector m_inlineEquationRegions; - - // All $$ $$ display formula regions. - // Sorted by start position. - QVector m_displayFormulaRegions; - - // HRule regions. - QVector m_hruleRegions; - - // All table regions. - // Sorted by start position. - QVector m_tableRegions; - - // All table header regions. - QVector m_tableHeaderRegions; - - // All table border regions. - QVector m_tableBorderRegions; - -private: - void parseImageRegions(QAtomicInt &p_stop); - - void parseHeaderRegions(QAtomicInt &p_stop); - - void parseFencedCodeBlockRegions(QAtomicInt &p_stop); - - void parseInlineEquationRegions(QAtomicInt &p_stop); - - void parseDisplayFormulaRegions(QAtomicInt &p_stop); - - void parseHRuleRegions(QAtomicInt &p_stop); - - void parseTableRegions(QAtomicInt &p_stop); - - void parseTableHeaderRegions(QAtomicInt &p_stop); - - void parseTableBorderRegions(QAtomicInt &p_stop); - - void parseRegions(QAtomicInt &p_stop, - pmh_element_type p_type, - QVector &p_result, - bool p_sort = false); -}; - -class PegParserWorker : public QThread -{ - Q_OBJECT -public: - explicit PegParserWorker(QObject *p_parent = nullptr); - - void prepareParse(const QSharedPointer &p_config); - - void reset(); - - int state() const - { - return m_state; - } - - TimeStamp workTimeStamp() const - { - if (m_parseConfig.isNull()) { - return 0; - } - - return m_parseConfig->m_timeStamp; - } - - const QSharedPointer &parseConfig() const - { - return m_parseConfig; - } - - const QSharedPointer &parseResult() const - { - return m_parseResult; - } - -public slots: - void stop(); - -protected: - void run() Q_DECL_OVERRIDE; - -private: - QSharedPointer parseMarkdown(const QSharedPointer &p_config, - QAtomicInt &p_stop); - - bool isAskedToStop() const - { - return m_stop.load() == 1; - } - - QAtomicInt m_stop; - - int m_state; - - QSharedPointer m_parseConfig; - - QSharedPointer m_parseResult; -}; - -class PegParser : public QObject -{ - Q_OBJECT -public: - explicit PegParser(QObject *p_parent = nullptr); - - ~PegParser(); - - QSharedPointer parse(const QSharedPointer &p_config); - - void parseAsync(const QSharedPointer &p_config); - - static QVector parseImageRegions(const QSharedPointer &p_config); - - // MUST pmh_free_elements() the result. - static pmh_element **parseMarkdownToElements(const QSharedPointer &p_config); - -signals: - void parseResultReady(const QSharedPointer &p_result); - -private slots: - void handleWorkerFinished(PegParserWorker *p_worker); - -private: - void init(); - - void clear(); - - void pickWorker(); - - void scheduleWork(PegParserWorker *p_worker, const QSharedPointer &p_config); - - // Maintain a fixed number of workers to pick work. - QVector m_workers; - - QSharedPointer m_pendingWork; -}; - -#endif // PEGPARSER_H diff --git a/src/resources/common.css b/src/resources/common.css deleted file mode 100644 index 6518f21d..00000000 --- a/src/resources/common.css +++ /dev/null @@ -1,247 +0,0 @@ -div.mark-rect { - background: transparent; - border: 5px solid #5768c4; - border-radius: 2px; - position: absolute; -} - -#vnote-footer { - width: 100%; - text-align: center; - opacity: 0.2; - margin-top: 3rem; -} - -#vnote-footer p { - font-size: 0.8rem; -} - -#vnote-footer a { - color: inherit !important; -} - -/* Mathjax */ -x-eqs { - display: flex; - flex-direction: row; - align-content: space-between; - align-items: center; -} - -x-eqs > x-eqn { - width: 100%; - margin-left: 3rem; -} - -x-eqs > span { - text-align:right; -} -/* Mathjax */ - -/* View Image */ -.view-image,.view-svg { - transition: 0.3s; -} - -.modal-box { - display: none; - position: fixed; - z-index: 1000; - padding-top: 50px; - left: 0; - top: 0; - width: 100%; - height: 100%; - overflow: hidden; - background-color: rgb(68, 68, 68); - background-color: rgba(68, 68, 68, 0.95); -} - -.modal-content { - margin: auto; - display: block; - width: auto; - height: auto; - cursor: move; -} - -/* Add Animation */ -.modal-content { - -webkit-animation-name: zoom; - -webkit-animation-duration: 0.6s; - animation-name: zoom; - animation-duration: 0.6s; -} - -@-webkit-keyframes zoom { - from {-webkit-transform:scale(0)} - to {-webkit-transform:scale(1)} -} - -@keyframes zoom { - from {transform:scale(0)} - to {transform:scale(1)} -} - -/* The Close Button */ -span.modal-close { - position: absolute; - z-index: 1000; - top: 15px; - right: 35px; - color: #DADADA; - font-size: 40px; - font-weight: bold; - transition: 0.3s; -} - -span.modal-close:hover, -span.modal-close:focus { - color: #EEEEEE; - text-decoration: none; - cursor: pointer; -} -/* View Image */ - -/* Print */ -@media print { - pre, pre code, td.hljs-ln-code { - white-space: pre-wrap !important; - word-break: break-all !important; - } - - code, a { - word-break: break-all !important; - } - - div.flowchart-diagram, div.mermaid-diagram, div.plantuml-diagram { - overflow: hidden !important; - } - - img { - max-width: 100% !important; - height: auto !important; - } - - #vnote-footer { - display: none !important; - } -} -/* Print*/ - -/* Alert */ -.alert { - position: relative; - padding: .75rem 1.25rem; - margin-bottom: 1rem; - border: 1px solid transparent; - border-radius: .25rem; -} - -.alert-primary { - color: #004085; - background-color: #cce5ff; - border-color: #b8daff; -} - -.alert-secondary { - color: #383d41; - background-color: #e2e3e5; - border-color: #d6d8db; -} - -.alert-success { - color: #155724; - background-color: #d4edda; - border-color: #c3e6cb; -} - -.alert-info { - color: #0c5460; - background-color: #d1ecf1; - border-color: #bee5eb; -} - -.alert-warning { - color: #856404; - background-color: #fff3cd; - border-color: #ffeeba; -} - -.alert-danger { - color: #721c24; - background-color: #f8d7da; - border-color: #f5c6cb; -} - -.alert-light { - color: #818182; - background-color: #fefefe; - border-color: #fdfdfe; -} - -.alert-dark { - color: #1b1e21; - background-color: #d6d8d9; - border-color: #c6c8ca; -} -/* Alert */ - -/* Anchor */ -.vnote-anchor { - font-weight: 400; - color: rgba(0,123,255,.5); - transition: color .16s linear; - padding-left: 0.375em; - -webkit-font-smoothing: antialiased; - text-decoration: none; - opacity: 0; -} - -.vnote-anchor:hover { - color: rgba(0,123,255,1); - text-decoration: none; - opacity: 1; -} - -.vnote-anchor::after { - content: attr(data-anchor-icon); -} -/* Anchor */ - -/* Button */ -.vnote-btn { - position: relative; - display: inline-block; - padding: 6px 12px; - font-size: 13px; - font-weight: 700; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; - cursor: pointer; - border: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-appearance: none; -} - -.vnote-copy-clipboard-btn { - transition: opacity .3s ease-in-out; - opacity: 0; - padding: 2px 6px; - position: absolute; - top: 5px; - right: 5px; -} - -pre:hover .vnote-copy-clipboard-btn { - opacity: 1; -} - -pre.vnote-snippet { - position: relative; -} -/* Button */ diff --git a/src/resources/common.js b/src/resources/common.js deleted file mode 100644 index 765a5003..00000000 --- a/src/resources/common.js +++ /dev/null @@ -1,46 +0,0 @@ -var httpGet = function(url, type, callback) { - var xmlHttp = new XMLHttpRequest(); - xmlHttp.open("GET", url); - xmlHttp.responseType = type; - - xmlHttp.onload = function() { - callback(xmlHttp.response); - }; - - xmlHttp.send(null); -}; - -var getPlantUMLOnlineURL = function(server, format, text) { - var s = unescape(encodeURIComponent(text)); - var arr = []; - for (var i = 0; i < s.length; i++) { - arr.push(s.charCodeAt(i)); - } - - var compressor = new Zopfli.RawDeflate(arr); - var compressed = compressor.compress(); - var url = server + "/" + format + "/" + encode64_(compressed); - return url; -}; - -var renderPlantUMLOnline = function(server, format, text, callback, data) { - var url = getPlantUMLOnlineURL(server, format, text); - - if (format == 'png') { - httpGet(url, 'blob', function(resp) { - var blob = resp; - var reader = new FileReader(); - reader.onload = function () { - var dataUrl = reader.result; - var png = dataUrl.substring(dataUrl.indexOf(',') + 1); - callback(data, format, png); - }; - - reader.readAsDataURL(blob); - }); - } else if (format == 'svg') { - httpGet(url, 'text', function(resp) { - callback(data, format, resp); - }); - } -}; diff --git a/src/resources/docs/en/markdown_guide.md b/src/resources/docs/en/markdown_guide.md deleted file mode 100644 index c831d574..00000000 --- a/src/resources/docs/en/markdown_guide.md +++ /dev/null @@ -1,266 +0,0 @@ -# Markdown Guide -This is a quick guide [^1] for Markdown, a lightweight and easy-to-use syntax for writing. - -## What is Markdown? -Markdown is a way to style text via a few simple marker characters. You could write the document in plain text and then read it with a beautiful typesetting. - -There is no a standard Markdown syntax and many editor will add its own additional syntax. VNote supports only the widely-used basic syntax. - -## How to Use Markdown? -If you are new to Markdown, it is better to learn the syntax elements step by step. Knowing headers and emphasis is enough to make you survive. You could learn another new syntax and practise it every one or two days. - -## Syntax Guide -Here is an overview of Markdown syntax supported by VNote. - -### Headers -```md -# This is an

tag -## This is an

tag -###### This is an

tag -``` - -**Notes**: - -- At least one space is needed after the `#`; -- A header should occupy one entire line; - -### Emphasis -```md -*This text will be italic* -_This text will be italic_ - -**This text will be bold** -__This text will be bold__ -``` - -**Notes**: - -- `*` is recommended in VNote; -- If the render failed, try to add an additional space before the first `*` and after the last `*`. The space is necessary if the surrounded text begins or ends with full width punctuation; -- VNote provides shortcuts `Ctrl+I` and `Ctrl+B` to insert italic and bold text; - -### Lists -#### Unordered -```md -* Item 1 -This is a text under Item 1. Notice that there are two spaces at the end above. -* Item 2 - * Item 2a - * Item 2b -* Item 3 - -To end a list, there should be one empty line above. -``` - -#### Ordered -```md -1. Item 1 -1. Item 2 -Notice that the sequence number is irrelevant. Markdown will change the sequence automatically when renderring. -3. Item 3 - 1. Item 3a - 2. Item 3b -4. Item 4 -``` - -### Tables -```md -| col 1 | col 2 | col 3 | -| --- | --- | --- | -| cell1 | cell2 | cell3 | -| cell4 | cell5 | cell6 | -``` - -### Images and Links -```md -![Image Alt Text](/url/to/image.png "Optional Text") - -![Image Alt Text](/url/to/image.png "Image specified with width and height" =800x600) - -![Image Alt Text](/url/to/image.png =800x600) - -![Image Alt Text](/url/to/image.png "Image specified with width" =800x) - -![Image Alt Text](/url/to/image.png "Image specified with height" =x600) - -[Link Text](/url/of/the/link) -``` - -**Notes**: - -- It is not recommended to use image links in reference format. VNote will not preview those images. -- Specifying size of image is supported only in **markdown-it**. - -### Blockquotes -```md -As VNote suggests: - -> VNote is the best Markdown note-taking application -> ever. -> -> THere is two spaces after `ever.` above to insert a -> new line. -``` - -**Notes**: - -- Space is needed after the marker `>`; -- You could just add only one `>` at the first line; - -### Fenced Code Block - ```lang - This is a fenced code block. - ``` - - ~~~ - This is another fenced code block. - ~~~ - -**Notes**: - -- `lang` is optional to specify the language of the code; if not specified, VNote won't highlight the code; - -### Diagrams - -> You need to enable Flowchart.js or Mermaid or WaveDrom in the `Markdown` menu and restart current opened tabs. - -VNote supports the following engines to draw diagrams. You should specify particular language of the fenced code block and write the definition of your diagram within it. - -- [Flowchart.js](http://flowchart.js.org/) for *flowchart* with language `flow` or `flowchart`; -- [Mermaid](https://mermaidjs.github.io/) with language `mermaid`; -- [WaveDrom](https://wavedrom.com/) for *digital timing diagram* with language `wavedrom`; - -For example, - - ```flowchart - st=>start: Start:>http://www.google.com[blank] - e=>end:>http://www.google.com - op1=>operation: My Operation - sub1=>subroutine: My Subroutine - cond=>condition: Yes - or No?:>http://www.google.com - io=>inputoutput: catch something... - - st->op1->cond - cond(yes)->io->e - cond(no)->sub1(right)->op1 - ``` - -#### UML - -> You need to enable PlantUML in the settings. Pay attention to the privacy issue if you use online PlantUML server. You may need to prepare Java runtime, PlantUML, and Graphviz if you choose local PlantUML. - -VNote supports [PlantUML](http://plantuml.com/) to draw UML diagrams. You should use `puml` specified as the language of the fenced code block and write the definition of your diagram within it. - - ```puml - @startuml - Bob -> Alice : hello - @enduml - ``` - -#### Graphviz - -> You need to enable Graphviz in the settings. - -VNote supports [Graphviz](http://www.graphviz.org/) to draw diagrams. You should use `dot` specified as the language of the fenced code block and write the definition of your diagram within it. - -### Math Formulas - -> You need to enable MathJax in the `Markdown` menu and restart VNote. - -VNote supports math formulas via [MathJax](https://www.mathjax.org/). The default math delimiters are `$$...$$` for **displayed mathematics**, and `$...$` for **inline mathematics**. - -- Inline mathematics should not cross multiple lines; -- Forms like `3$abc$`, `$abc$4`, `$ abc$`, and `$abc $` will not be treated as mathematics; -- Use `\` to escape `$`; -- There should be only space chars before opening `$$` and after closing `$$`; - -VNote also supports displayed mathematics via fenced code block with language `mathjax` specified. - - ```mathjax - $$ - J(\theta) = \frac 1 2 \sum_{i=1}^m (h_\theta(x^{(i)})-y^{(i)})^2 - $$ - ``` - -Equation number of displayed mathematics is supported: - - $$vnote x markdown = awesome$$ (1.2.1) - -### Inline Code -```md -Here is a `inline code`. -``` - -To insert one `` ` ``, you need to use two `` ` `` to enclose it, such as ``` `` ` `` ```. To insert two `` ` ``, you need to use three `` ` ``. - -### Strikethrough -```md -Here is a ~~text~~ with strikethrough. -``` - -**Notes**: - -- VNote provides shortcuts `Ctrl+D` to insert text with strikethrough; - -### Task Lists -```md -- [x] this is a complete item. -- [ ] this is an incomplete item. -``` - -### Footnote -```md -This is a footnote [^1]. - -[^1]: Here is the detail of the footnote. -``` - -### Superscript and Subscript - -> You need to enable Superscript or Subscript in the `Markdown` menu and use `Markdown-it` renderer. - -```md -This is the 1^st^ superscript. - -This is the H~2~O subscript. -``` - -### Alert -With `Markdown-it` renderer, you can add some alert text. - -```md -::: alert-info - -This is an info text. - -::: - -::: alert-danger - -This is a danger text. - -::: -``` - -Available variants: - -``` -alert-primary -alert-secondary -alert-success -alert-info -alert-warning -alert-danger -alert-light -alert-dark -``` - -### New Line and Paragraph -If you want to enter a new line, you should add two spaces after current line and then continue your input. VNote provides `Shift+Enter` to help. - -If you want to enter a new paragraph, you should add an empty line and then continue entering the new paragraph. - -Generally, you need to add an empty line after a block element (such as code block, lists, blockquote) to explicitly end it. - -[^1]: This guide references [Mastering Markdown](https://guides.github.com/features/mastering-markdown/). diff --git a/src/resources/docs/en/shortcuts.md b/src/resources/docs/en/shortcuts.md deleted file mode 100644 index 3d439612..00000000 --- a/src/resources/docs/en/shortcuts.md +++ /dev/null @@ -1,329 +0,0 @@ -# VNote Shortcuts -1. All the keys without special notice are **case insensitive**; -2. On macOS, `Ctrl` corresponds to `Command` except in Vim mode. - -## Normal Shortcuts -- `Ctrl+E E` -Toggle expanding the edit area. -- `Ctrl+Alt+N` -Create a note in current folder. -- `Ctrl+F` -Find/Replace in current note. -- `Ctrl+Alt+F` -Advanced find. -- `Ctrl+Q` -Quit VNote. -- `Ctrl+J`/`Ctrl+K` -VNote supports `Ctrl+J` and `Ctrl+K` for navigation in the notebooks list, directories list, notes list, opened notes list, and outline list. -- `Ctrl+Left Mouse` -Scroll in all directions. -- `Ctrl+Shift+T` -Recover last closed file. -- `Ctrl+Alt+L` -Open Flash Page. -- `Ctrl+Alt+I` -Open Quick Access. -- `Ctrl+T` -Edit current note or save changes and exit edit mode. -- `Ctrl+G` -Activate Universal Entry. -- `Ctrl+8`/`Ctrl+9` -Jump to the next/previous match in last find action. - -### Read Mode -- `H`/`J`/`K`/`L` -Navigation, corresponding to Left/Down/Up/Right arrow keys. -- `Ctrl+U` -Scroll up half screen. -- `Ctrl+D` -Scroll down half screen. -- `gg`/`G` -Jump to the beginning or end of the note. (Case Sensitive). -- `Ctrl + +/-` -Zoom in/out the page. -- `Ctrl+Wheel` -Zoom in/out the page through the mouse scroll. -- `Ctrl+0` -Recover the page zoom factor to 100%. -- Jump between titles - - `[[`: jump to previous `N` title; - - `]]`: jump to next `N` title; - - `[]`: jump to previous `N` title at the same level; - - `][`: jump to next `N` title at the same level; - - `[{`: jump to previous `N` title at a higher level; - - `]}`: jump to next `N` title at a higher level; -- `/` or `?` to search forward or backward - - `N`: find next match; - - `Shift+N`: find previous match; -- `:` for Vim command - - `:q`: close current note; - - `:noh[lsearch]`: clear search highlights; - -### Edit Mode -- `Ctrl+S` -Save current changes. -- `Ctrl + +/-` -Zoom in/out the page. -- `Ctrl+Wheel` -Zoom in/out the page through the mouse scroll. -- `Ctrl+0` -Recover the page zoom factor to 100%. -- `Ctrl+J/K` -Scroll page down/up without changing cursor. -- `Ctrl+N/P` -Activate auto-completion. - - `Ctrl+N/P` - Navigate through the completion list and insert current completion. - - `Ctrl+J/K` - Navigate through the completion list. - - `Ctrl+E` - Cancel completion. - - `Enter` - Insert current completion. - - `Ctrl+[` or `Escape` - Finish completion. - -#### Text Editing -- `Ctrl+B` -Insert bold. Press `Ctrl+B` again to exit. Current selected text will be changed to bold if exists. -- `Ctrl+I` -Insert italic. Press `Ctrl+I` again to exit. Current selected text will be changed to italic if exists. -- `Ctrl+D` -Insert strikethrought. Press `Ctrl+D` again to exit. Current selected text will be changed to strikethrough if exists. -- `Ctrl+;` -Insert inline code. Press `Ctrl+;` again to exit. Current selected text will be changed to inline code if exists. -- `Ctrl+M` -Insert fenced code block. Press `Ctrl+M` again to exit. Current selected text will be wrapped into a code block if exists. -- `Ctrl+L` -Insert link. -- `Ctrl+.` -Insert table. -- `Ctrl+'` -Insert image. -- `Ctrl+H` -Backspace. Delete a character backward. -- `Ctrl+W` -Delete all the characters from current cursor to the first space backward. -- `Ctrl+U` -Delete all the characters from current cursor to the beginning of current line. -- `Ctrl+` -Insert title at level ``. `` should be 1 to 6. Current selected text will be changed to title if exists. -- `Ctrl+7` -Delete the title mark of current line or selected text. -- `Tab`/`Shift+Tab` -Increase or decrease the indentation. If any text is selected, the indentation will operate on all these selected lines. -- `Shift+Enter` -Insert two spaces followed by a new line, namely a soft linebreak in Markdown. -- `Shift+Left`, `Shift+Right`, `Shift+Up`, `Shift+Down` -Expand the selection one character left or right, or one line up or down. -- `Ctrl+Shift+Left`, `Ctrl+Shift+Right` -Expand the selection to the beginning or end of current word. -- `Ctrl+Shift+Up`, `Ctrl+Sfhit+Down` -Expand the selection to the beginning or end of current paragraph. -- `Shift+Home`, `Shift+End` -Expand the selection to the beginning or end of current line. -- `Ctrl+Shift+Home`, `Ctrl+Shift+End` -Expand the selection to the beginning or end of current note. - -## Customize Shortcuts -VNote supports customizing some standard shortcuts, though it is not recommended. VNote stores shortcuts' configuration information in the `[shortcuts]` and `[captain_mode_shortcuts]` sections of user configuration file `vnote.ini`. - -For example, the default configruation may look like this: - -```ini -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Customized shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Save current note -SaveNote=Ctrl+S -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Alternate one/two panels view -OnePanelView=P -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=Shift+? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -``` - -Each item is in the form `operation=keysequence`, with `keysequence` empty to disable shortcuts for that operation. - -Pay attention that `Ctrl+Q` is reserved for quitting VNote. - -# Captain Mode -To efficiently utilize the shortcuts, VNote supports the **Captain Mode**. - -Press the leader key `Ctrl+E`, then VNote will enter the Captain Mode, within which VNote supports more efficient shortcuts. - -- `E` -Toggle expanding the edit area. -- `Y` -Focus to the edit area. -- `T` -Toggle the Tools panel. -- `Shift+#` -Toggle the Tool Bar. -- `F` -Popup the opened notes list of current split window. Within this list, pressing the sequence number in front of each note could jump to that note. -- `A` -Popup the attachments list of current note. -- `X` -Close current tab. -- `J` -Jump to the next tab. -- `K` -Jump to the previous tab. -- `1` - `9` -Number key 1 to 9 will jump to the tabs with corresponding sequence number. -- `0` -Jump to previous tab. Alternate between current and previous tab. -- `D` -Locate to the folder of current note. -- `Q` -Discard current changes and exit edit mode. -- `V` -Vertically split current window. -- `R` -Remove current split window. -- `Shift+|` -Maximize current split window. -- `=` -Distribute all the split windows evenly. -- `H` -Jump to the first split window on the left. -- `L` -Jump to the first split window on the right. -- `Shift+H` -Move current tab one split window left. -- `Shift+L` -Move current tab one split window right. -- `M` -Evaluate current cursor word or selected text as magic words. -- `S` -Apply a snippet in edit mode. -- `O` -Export notes. -- `I` -Toggle live preview panel. -- `U` -Expand/restore live preview panel. -- `C` -Toggle full-text search. -- `P` -Parse HTML as Markdown text in clipboard and paste. -- `N` -View and edit current note's information. -- `Shift+?` -Display shortcuts documentation. - -## Navigation Mode -Within the Captain Mode, `W` will turn VNote into **Navigation Mode**. In this mode, VNote will display at most two characters on some major widgets, and then pressing corresponding characters will jump to that widget. - -# Vim Mode -VNote supports a simple but useful Vim mode, including **Normal**, **Insert**, **Visual**, and **VisualLine** modes. - -::: alert-info - -Open `Settings` dialog via the `File` menu, then jump to `Read/Edit` tab and you could enable Vim via the combo box in `Key mode`. Restart VNote to take effect. - -::: - -VNote supports following features of Vim: - -- `r`, `s`, `S`, `i`, `I`, `a`, `A`, `c`, `C`, `o`, and `O`; -- Actions `d`, `c`, `y`, `p`, `<`, `>`, `gu`, `gU`, `J`, `gJ`, and `~`; -- Movements `h/j/k/l`, `gj/gk/g0`, `Ctrl+U`, `Ctrl+D`, `gg`, `G`, `0`, `^`, `{`, `}`, and `$`; -- Marks `a-z`; -- Registers `"`, `_`, `+`, `a-z`(`A-Z`); -- Jump locations list (`Ctrl+O` and `Ctrl+I`); -- Leader key (`Space`) - - Currently `y/d/p` equals to `"+y/d/p`, which will access the system's clipboard; - - `` to clear search highlight; - - `w` to save note; -- `zz`, `zb`, `zt`; -- `u` and `Ctrl+R` for undo and redo; -- Text objects `i/a`: word, WORD, `''`, `""`, `` ` ` ``, `()`, `[]`, `<>`, and `{}`; -- Command line `:w`, `:wq`, `:x`, `:q`, `:q!`, and `:noh[lsearch]`; -- Jump between titles - - `[[`: jump to previous title; - - `]]`: jump to next title; - - `[]`: jump to previous title at the same level; - - `][`: jump to next title at the same level; - - `[{`: jump to previous title at a higher level; - - `]}`: jump to next title at a higher level; -- `/` and `?` to search - - `n` and `N` to find next or previous occurence; - - `Ctrl+N` and `Ctrl+P` to navigate through the search history; -- `Ctrl+R` to read the content of a register; -- `Ctrl+O` in Insert mode to enter Normal mode temporarily; - -For now, VNote does **NOT** support the macro and repeat(`.`) features of Vim. - -Enjoy Vim in VNote! - -# Others -- `Ctrl+J` and `Ctrl+K` to navigate through items; -- `Ctrl+N` and `Ctrl+P` to navigate through search results in list; diff --git a/src/resources/docs/en/tips_add_style.md b/src/resources/docs/en/tips_add_style.md deleted file mode 100644 index bce20209..00000000 --- a/src/resources/docs/en/tips_add_style.md +++ /dev/null @@ -1,19 +0,0 @@ -# VNote Styles -VNote supports custom styles for both edit and read modes. The best way to make a custom style is to download the default styles [here](https://github.com/tamlok/vnote/tree/master/src/resources/themes), rename them, put them in the style folder, and tune it to your taste. - -A restart is needed to detect a new style. A re-open of current tabs is needed to apply a new style. - -For detailed information about a style, please visit [VNote](https://github.com/tamlok/vnote). - -## Editor Style -An editor style is a file with suffix `.mdhl`. By default, it locates in subfolder `styles` in VNote's configuration folder. - -You could visit [Stylesheets from PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html) for detailed syntax. - -## Read Mode Style -A read mode style is a file with suffix `.css`. By default, it locates in subfolder `styles` in VNote's configuration folder. - -### Code Block Style -A code block style is a file with suffix `.css`. By default, it locates in subfolder `styles/codeblock_styles` in VNote's configuration folder. - -You could visit [Highlight.js](https://github.com/isagalaev/highlight.js) for more styles. diff --git a/src/resources/docs/en/tips_add_theme.md b/src/resources/docs/en/tips_add_theme.md deleted file mode 100644 index 5118349b..00000000 --- a/src/resources/docs/en/tips_add_theme.md +++ /dev/null @@ -1,8 +0,0 @@ -# VNote Themes -VNote supports themes. A theme is a folder in the subfolder `themes` in VNote's configuration folder. The best way to make a custom theme is to copy one of the default themes, rename related files, put them in the theme folder, and tune it to your taste. - -Please do not modify the default themes directly, or you may lose your changes. - -A restart is needed to detect or apply a new theme. - -For detailed information about a theme, please visit [VNote](https://github.com/tamlok/vnote). diff --git a/src/resources/docs/en/tips_custom_shortcut.md b/src/resources/docs/en/tips_custom_shortcut.md deleted file mode 100644 index 30f04629..00000000 --- a/src/resources/docs/en/tips_custom_shortcut.md +++ /dev/null @@ -1,91 +0,0 @@ -# Customize Shortcuts -VNote supports customizing some standard shortcuts, though it is not recommended. VNote stores shortcuts' configuration information in the `[shortcuts]` and `[captain_mode_shortcuts]` sections of user configuration file `vnote.ini`. - -For example, the default configruation may look like this: - -```ini -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Customized shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Save current note -SaveNote=Ctrl+S -; Save changes and enter read mode -SaveAndRead=Ctrl+T -; Edit current note -EditNote=Ctrl+W -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Alternate one/two panels view -OnePanelView=P -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -``` - -Each item is in the form `operation=keysequence`, with `keysequence` empty to disable shortcuts for that operation. - -Pay attention that `Ctrl+Q` is reserved for quitting VNote. diff --git a/src/resources/docs/en/tips_external_program.md b/src/resources/docs/en/tips_external_program.md deleted file mode 100644 index 05062702..00000000 --- a/src/resources/docs/en/tips_external_program.md +++ /dev/null @@ -1,21 +0,0 @@ -# External Programs -VNote supports opening notes with external programs. VNote stores external programs' configuration information in the `[external_editors]` section of user configuration file `vnote.ini`. - -A sample configuration may look like this: - -```ini -[external_editors] -; Define external editors which could be called to edit notes -; One program per line with the format name="program \"%0\" arg1 arg2", -; in which %0 will be replaced with the note file path (so it is better to enclose it -; with double quotes) -; Shortcut could be empty -; Need to escape \ and ", use double quotes to quote paths/arguments with spaces -; SHOULD defined in user config file, not here - -GVim=C:\\\"Program Files (x86)\"\\Vim\\vim80\\gvim.exe \"%0\", F4 -Notepad=notepad \"%0\" -Notepad%2B%2B=C:\\\"Program Files (x86)\"\\notepad++\\notepad++.exe \"%0\" -``` - -A restart is needed to detect new external programs. diff --git a/src/resources/docs/en/welcome.md b/src/resources/docs/en/welcome.md deleted file mode 100644 index 49e3fcb6..00000000 --- a/src/resources/docs/en/welcome.md +++ /dev/null @@ -1,38 +0,0 @@ -# Welcome to VNote -![VNote](qrc:/resources/icons/256x256/vnote.png) - -> A note-taking application that knows programmers and Markdown better. - -[VNote](https://tamlok.github.io/vnote) provides fancy Markdown experience as well as powerful notes management. - -VNote is **open source** and currently mainly developed and maintained by one single person in spare time. Hence, please don't hesitate to give VNote a hand if she does improve your productivity. Thank [users who donated to VNote](https://github.com/tamlok/vnote/wiki/Donate-List)! - -## Troubleshooting Guide -::: alert-info - -**How to enable Vim mode?** - -Open `Settings` dialog via the `File` menu, then jump to `Read/Edit` tab and you could enable Vim via the combo box in `Key mode`. Restart VNote to take effect. - -If you do not know what Vim is, please do not enable it! - -::: - -VNote could be used in two ways: - -1. Note-taking application via notebooks, folders and notes. VNote manages all the data and provides additional functionality such as attachment and tag. -2. Editor. VNote provides the explorer for local file system to open external files to edit. - -Steps to troubleshoot: - -1. Go through the context menu, menu bar, tool bar, settings, and help menu to check if you miss something; -2. Changes to configuration may need re-opening current tabs or restarting VNote; -3. There is a Markdown guide and shortcuts guide in the help menu, which might be helpful; -4. Do a quick search in [GitHub Issues](https://github.com/tamlok/vnote/issues) and VNote's [Documentation](https://tamlok.github.io/vnote/en_us/#!docs/_vnote.json); -5. Post an issue *in detail* on GitHub to ask for help. - -Now, how about pressing `Ctrl+G` and start today's work from **Universal Entry**? - -Have fun! - -Fork me on GitHub diff --git a/src/resources/docs/ja/markdown_guide.md b/src/resources/docs/ja/markdown_guide.md deleted file mode 100644 index 95c9a5c5..00000000 --- a/src/resources/docs/ja/markdown_guide.md +++ /dev/null @@ -1,263 +0,0 @@ -# Markdownガイド -これは、軽量で使いやすい構文であるMarkdownのためのクイックガイド[^1]です。 - -## Markdownとは何ですか? -Mark downは、いくつかの単純なマーカー文字を使ってテキストをスタイル設定する方法です。文書をプレーンテキストで書くことができ、それを美しい表示で読むことができます。 - -標準的なMarkdown構文は存在せず、多くのエディタは独自の構文を追加することになります。VNoteは、広く使用されている基本構文のみをサポートしています。 - -## Markdownの使い方。 -Markdownを初めて使用する場合は、構文要素をステップごとに学習しておくことをお勧めします。ヘッダーと強調を知ることは、あなたが生き残るのに十分です。毎日ひとつ、別の新しい構文を学び、それを実践することができます。 - -## 構文ガイド -ここでは、VNoteによってサポートされるMarkdown構文の概要を示します。 - -### ヘッダー -```md -#これは

タグです。 -##これは

タグです。 -#####これは、

タグです。 -``` - -**注意事項**: - -- `#`の後には、少なくとも1つのスペースが必要です; -- ヘッダーは1行全体を占める必要があります。 - -### 強調 -```md -*このテキストは斜体です* -_このテキストはイタリックになります_ - - **このテキストは太字で表示されます** - __このテキストは太字になります__ -``` - -**注意事項**: - -- `*`がVNoteでは推奨されます; -- レンダリングが失敗した場合は、最初の`*`の前と最後の`*`の後に追加スペースを追加してみてください。囲まれたテキストが完全な幅の句読点で始まるか、終了する場合は、スペースが必要です。 -- VNoteは、`Ctrl+I`および`Ctrl+B`による斜体と太字のテキスト挿入ショートカットを提供しています。 - -### 箇条書き -#### 順序なしリスト -```md -* 項目1 -これは、箇条書きの項目の1つ目です。ここで、項目のあとに二つの空白文字を挿入していることに注意してください。 -* 項目 2 - * 項目 2a - * 項目 2b -* 項目 3 - -箇条書きの最後には、上記のような空行が必要です。 -``` - -#### 番号ありリスト -```md -1. 項目 1 -1. 項目 2 -ここで、シーケンス番号が関係していないことに注意してください。Markdownは、レンダリング時に自動的にシーケンス番号を付番します。 -3. 項目 3 - 1. 項目 3a - 2. 項目 3b -4. 項目 4 -``` - -### 表 -```md -| col 1 | col 2 | col 3 | -| --- | --- | --- | -| cell1 | cell2 | cell3 | -| cell4 | cell5 | cell6 | -``` - -### 画像とリンク -```md -![Image Alt Text](/url/to/image.png "Optional Text") - -![Image Alt Text](/url/to/image.png "Image specified with width and height" =800x600) - -![Image Alt Text](/url/to/image.png =800x600) - -![Image Alt Text](/url/to/image.png "Image specified with width" =800x) - -![Image Alt Text](/url/to/image.png "Image specified with height" =x600) - -[Link Text](/url/of/the/link) -``` - -**注意事項**: - -- リファレンスフォーマットでは、イメージリンクの使用は推奨されません。VNoteは、これらの画像のプレビューをおこないません。 -- 画像のサイズの指定については、**Markdown-it**レンダリングエンジンでのみ有効です。 - -### ブロック引用 -```md -VNoteは次のことを示唆しています: - -> VNoteは、過去最強のMarkdownノート作成アプリです。 -ここで、二つの空白文字が、アプリです。の後に挿入されていることに注意してください。 -``` - -**注意事項**: - -- マーカー`>`の後には、少なくとも1つのスペースが必要です; -- 最初の行には、`>`を一つのみ追加できます; - -### フェンスコードブロック - ```lang - This is a fenced code block. - ``` - - ~~~ - This is another fenced code block. - ~~~ - -**注意事項**: - -- `lang`はコードの言語を指定するオプションです。もし指定されなければ、VNoteはハイライト表示をしません。 - -### 図 - -> `Markdown`メニューから、Flowcharts.js か、Mermaidか、WaveDromを有効にする必要があります。 - -VNoteは、図を描くために次のエンジンをサポートしています。フェンスコードブロックに、特定の言語を指定して、その中に図の定義を記述する必要があります。 - -- [Flowchart.js](http://flowchart.js.org/) for *flowchart* with language `flow` or `flowchart`; -- [Mermaid](https://mermaidjs.github.io/) with language `mermaid`; -- [WaveDrom](https://wavedrom.com/) for *digital timing diagram* with language `wavedrom`; - -たとえば - - ```flowchart - st=>start: Start:>http://www.google.com[blank] - e=>end:>http://www.google.com - op1=>operation: My Operation - sub1=>subroutine: My Subroutine - cond=>condition: Yes - or No?:>http://www.google.com - io=>inputoutput: catch something... - - st->op1->cond - cond(yes)->io->e - cond(no)->sub1(right)->op1 - ``` - -#### UML - -> 設定では、PlantUMLを有効にする必要があります。オンラインPlantUMLサーバを使用する場合は、プライバシーの問題に注意してください。ローカルPlantUMLを選択する場合は、Javaランタイム、PlantUML、およびGraphvizを準備する必要があります。 - -VNoteは、[PlantUML](http://plantuml.com/)をサポートしてUML図を描画します。フェンスコードブロックの言語として、`puml`を指定し、そのなかにダイヤグラム定義を書くようにしてください。 - - ```puml - @startuml - Bob -> Alice : hello - @enduml - ``` - -#### Graphviz - -> 設定でGraphvizを有効にする必要があります。 - -VNoteは、図を描くために[Graphviz](http://www.graphviz.org/)をサポートしています。フェンスコードブロックの言語として、`dot`を指定し、そのなかにダイヤグラム定義を書くようにしてください。 - -### 数式 - -> `Markdown`メニューでMathJaxを有効にし、VNoteを再起動する必要があります。 - -VNoteは、[MathJax](https://www.mathjax.org/)により数式をサポートしています。既定の数式区切りは、**独立数式表示**は`$$...$$`で、**インライン数式表示**は`$...$`です。 - -- インライン数式は複数行にまたがることはできません。 -- `3$abc$`や`$abc$4`、`$ abc$`、`$abc $`のような文字列は、数式としては扱われません。 -- `$`文字をエスケープするには、`\`を用いてください。 -- 数式開始の`$$`の前や、数式後の`$$`のあとには、空白文字のみ置くことができます。 - -VNoteは、`mathjax`が指定された言語のフェンスコードブロックを通じて、独立数式をサポートすることができます。 - - ```mathjax - $$ - J(\theta) = \frac 1 2 \sum_{i=1}^m (h_\theta(x^{(i)})-y^{(i)})^2 - $$ - ``` - -独立数式表示では、数式番号がサポートされています: - - $$vnote x markdown = awesome$$ (1.2.1) - -### インラインコード -```md -これは、`インラインコード`です。 -``` - -`````を一つ入力するには、`````を二つ入力した文字でかこむ必要があります。たとえば````` ` `````となります。ふたつ`````を入力するには、`````が3つ必要です。 - -### 取り消し線 -```md -ここでは~~テキスト~~を取り消し線付きで示しています。 -``` - -**注意事項**: - -- VNoteでは、取消線つき文字列を挿入するために、`Ctrl+D`のショートカットを用意しています。 - -### タスク・リスト -```md -- [x] これは完了したアイテムです。 -- [ ] これは未完了のアイテムです。 -``` - -### 脚注 -```md -これは脚注[^1]です。 - -[^1]:これは脚注の詳細です。 -``` - -### 上付き文字と下付き文字 - -> `Markdown`メニューで、上付き文字または下付き文字を有効にし、`Markdown-it`レンダラーを使用する必要があります。 - -```md -これは、1^st^の上付き文字です。 - -これは、H~2~O下付き文字です。 -``` - -### アラート -`Markdown-it`レンダラを使用すると、警告テキストを追加することができます。 - -```md -::: alert-info - -This is an info text. - -::: - -::: alert-danger - -This is a danger text. - -::: -``` - -使用可能なバリアント: - -``` -alert-primary -alert-secondary -alert-success -alert-info -alert-warning -alert-danger -alert-light -alert-dark -``` - -### 改行と段落 -新しい行を入力する場合は、現在の行に2つのスペースを追加してから、入力を続行します。VNoteは、その支援のために`Shift+Enter`を提供します。 - -新しい段落を入力する場合は、空行を追加してから、新しい段落の入力を続ける必要があります。 - -一般的に、ブロック要素(コードブロック、リスト、ブロッククォートなど)の後に空の行を追加して、明示的に終了する必要があります。 - -[^1]:このガイドは、[Mastering Markdown](https://guides.github.com/features/mastering-markdown/)を参照しています。 diff --git a/src/resources/docs/ja/shortcuts.md b/src/resources/docs/ja/shortcuts.md deleted file mode 100644 index 4fb6319f..00000000 --- a/src/resources/docs/ja/shortcuts.md +++ /dev/null @@ -1,321 +0,0 @@ -# VNote ショートカット -1. 特別な説明がないすべてのキーは**大文字と小文字が区別されません**; -2. mac OSでは、`Ctrl`はVimモードを除いて`Command`に対応しています。 - -## 通常のショートカット -- `Ctrl+E E` - 編集領域の拡張を切り替えます。 -- `Ctrl+Alt+N` -現在のフォルダにノートを作成します。 -- `Ctrl+F` -現在のノートで検索/置換します。 -- `Ctrl+Alt+F` - 詳細検索の実行。 -- `Ctrl+Q` -VNoteを終了します。 -- `Ctrl+J`/`Ctrl+K` - Vnoteは、ノートブック・リスト、ディレクトリー・リスト、ノート・リスト、オープン・ノート・リスト、アウトライン・リストでのナビゲーション用に`Ctrl+J`と`Ctrl+K`をサポートしています。 -- `Ctrl+左マウス` -すべての方向にスクロールします。 -- `Ctrl+Shift+T]` -最後に閉じたファイルをリカバリします。 -- `Ctrl+Alt+L` - Flashページを開きます。 -- `Ctrl+Alt+I` -クイックアクセスを開きます。 -- `Ctrl+T` -現在のノートの編集を開始するか、変更を保存して編集を終了します。 -- `Ctrl+G` -Universal Entryをアクティブにします。 -- `Ctrl+8`/`Ctrl+9` -最後の検索アクションで、次の/前の一致にジャンプします。 - -### 読み取りモード -- `H`/`J``K``L` -移動、それぞれ左/下/上/右キー。 -- `Ctrl+U` -半画面上スクロール -- `Ctrl+D` -半画面下スクロール -- `gg`/`G`ノートの先頭または末尾へ移動。(大文字小文字を識別). -- `Ctrl+ +` -ズームイン/ズームアウト。 -- `Ctrl+wheel`マウスのスクロールにあわせてズームイン/ズームアウト。 -- `Ctrl+O` -ページのズームレベルを100%にリセット。 -- タイトル間ジャンプ - - `[[`: 前の `N`タイトルにジャンプする。 - - `[[`: 次の `N`タイトルにジャンプする。 - - `[[`: 同じレベルの前の `N`タイトルにジャンプする。 - - `[[`: 同じレベルの次の `N`タイトルにジャンプする。 - - `[[`: 上のレベルの前の `N`タイトルにジャンプする。 - - `[[`: 上のレベルの次の `N`タイトルにジャンプする。 -- `/` または `?` 前方検索または後方検索 - - `N`:次を検索 - - `Shift+N`: 前を検索 -- `:` Vimコマンドモード - - `:q`: 現在のノートを閉じる。 - - `:noh[lsearch]`: 検索ハイライトをクリアー。 - -### 編集モード -- `Ctrl+S` -現在の変更を保存する。 -- `Ctrl+ +` -ズームイン/ズームアウト。 -- `Ctrl+wheel`マウスのスクロールにあわせてズームイン/ズームアウト。 -- `Ctrl+O` -ページのズームレベルを100%にリセット。 -- `Ctrl+J/K` -カーソル位置を変更せずに、ページダウン/アップ スクロール。 -- `Ctrl+N/P` -自動補完を有効化。 - - `Ctrl+N/P` -自動補完リスト上を移動し、選択した補完候補を挿入する。 - - `Ctrl+J/K` -自動補完リスト上を移動する。 - - `Ctrl+E` -自動補完をキャンセル。 - - `Enter` -現在の補完を挿入します。 - - `Ctrl+[`]または`Escape` -補完を完了。 - -#### テキスト編集 -- `Ctrl+B` -太字を挿入します。`Ctrl+B`を再度押して終了します。現在選択されているテキストは太字に変更されます。 -- `Ctrl+I` -斜体を挿入します。`Ctrl+I`を再度押して、終了します。現在選択されているテキストはイタリックに変更されます。 -- `Ctrl+D` -取消線を挿入します。`Ctrl+D`をもう一度押して終了します。現在選択されているテキストは取り消し線に変更されます。 -- `Ctrl+;` -インライン・コードを挿入します。`Ctrl+;`をもう一度押して終了します。現在選択されているテキストは、存在する場合はインライン・コードに変更されます。 -- `Ctrl+M` -フェンス付きコードブロックを挿入します。`Ctrl+M`を再度押して、終了します。現在選択されているテキストは、存在する場合はコードブロックにラップされます。 -- `Ctrl+L` リンクを挿入します。 -- `Ctrl+.` テーブルを挿入します。 -- `Ctrl+'` 画像を挿入します。 -- `Ctrl+H` バックスペース。前の文字を削除します。 -- `Ctrl+W` -現在のカーソルから1番目最初のスペースまでのすべての文字を削除します。 -- `Ctrl+U` -現在のカーソルから現在の行の先頭の間のすべての文字を削除します。 -- `Ctrl+<数値>` -レベル`<数値>`のタイトル行を挿入します。`<数値>`は1から6である必要があります。現在選択されているテキストはタイトルに変更されます。 -- `Ctrl+7` - 現在の行または選択したテキストのタイトル記号を削除します。 -- `Tab`/`Shift+Tab` -Increase or decrease the indentation. テキストが選択されている場合、インデントはこれらの選択されたすべての行に対して動作します。 -- `Shift+入力` 2つのスペースを挿入し、その後に新しい行を挿入します。つまり、Markdownにソフトラインブレークを挿入します。 -- `Shift+左`、`Shift+右`、`Shift+上`、`Shift+下` 選択範囲を1文字左または右に拡張するか、1行上または下に拡大します。 -- `Ctrl+Shift+左`、`Ctrl+Shift+右` -選択範囲を現在の単語の先頭または末尾に拡大します。 -- `Ctrl+Shift+上`、`Ctrl+Sfhit+下` -選択範囲を現在の段落の先頭または末尾に拡大します。 -- `Shift+Home`、`Shift+End` -選択範囲を現在の線分の先頭または末尾に拡大します。 -- `Ctrl+Shift+Home`、`Ctrl+Shift+End` -選択範囲を現在の注記の先頭または末尾に拡大します。 - -## ショートカットのカスタマイズ -VNoteでは、標準ショートカットのカスタマイズもサポートされていますが、推奨されません。VNoteは、ユーザー構成ファイル`vnote.ini`の`[shortcuts]`セクションおよび`[captain_mode_shortcuts]`セクションに外部プログラムの構成情報を格納します。 - -たとえば、デフォルトの設定は次のようになります。 - -```ini -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Customized shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Save current note -SaveNote=Ctrl+S -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Alternate one/two panels view -OnePanelView=P -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=Shift+? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -``` - -各項目は、`操作=キーシーケンス`の形式です。操作のショートカットを無効にするには、`キーシーケンス`を空にします。 - -`Ctrl+Q`は、Vnoteを終了するために予約されていることに注意してください。 - -# キャプテンモード -ショートカットを効率的に利用するために、VNoteは**キャプテンモード**をサポートしています。 - -リーダーキー`Ctrl+E`を押すと、VNoteがキャプテンモードに入り、VNoteがより効率的なショートカットをサポートするようになります。 - -- `E` - 編集領域の拡張を切り替えます。 -- `Y` -編集領域にフォーカスします。 -- `T` -ツールパネルを切り替えます。 -- `Shift+#` -ツールバーを切り替えます。 -- `F` -現在の分割ウィンドウの開いているノートリストをポップアップします。このリストの中で、各ノートの前でシーケンス番号を押すと、そのノートにジャンプできます。 -- `A` -現在のノートの添付ファイルリストをポップアップします。 -- `X` -現在のタブを閉じます。 -- `J` -次のタブにジャンプします。 -- `K` -前のタブにジャンプします。 -- `1`-`9` - 番号キー1~9は、対応するシーケンス番号を持つタブにジャンプします。 -- `0` -前のタブにジャンプします。現在のタブと前のタブとの間で切り替えます。 -- `D` -現在のノートのフォルダに移動します。 -- `Q` -現在の変更を破棄し、編集モードを終了します。 -- `V` -カレントウィンドウ垂直に分割します。 -- `R` -現在の分割ウィンドウを削除します。 -- `Shift+]` - 現在の分割ウィンドウを最大化します。 -- `=` -すべての分割ウィンドウを均等に分配します。 -- `H` -左側の最初の分割ウィンドウにジャンプします。 -- `L` -右側の最初の分割ウィンドウにジャンプします。 -- `Shift+H` -現在のタブを一つ左の分割ウィンドウに移動します。 -- `Shift+L` -現在のタブを1つの分割ウィンドウ右側に移動します。 -- `M` -現在のカーソルワードまたは選択されたテキストをマジックワードとして評価します。 -- `S` - 編集モードでスニペットを適用します。 -- `O` -ノートをエクスポートします。 -- `I` -ライブプレビューパネルを切り替えます。 -- `U` -ライブプレビューパネルを展開します。 -- `C` -全文検索を切り替えます。 -- `P` -クリップボードのHTMLをMarksownテキストとして貼り付けます。 -- `N` -View and edit current note's information. -- `Shift+?` -ショートカットのドキュメントを表示します。 - -## ナビゲーション・モード -キャプテンモードでは、`W`はVNoteを**ナビゲーションモード**に変える。このモードでは、VNoteは主要ウィジェットに最大2文字の文字を表示し、その後対応する文字を押すとそのウィジェットにジャンプします。 - -# Vimモード -VNoteは、**Normal**、**Insert**、**Visual**、および**VisualLine**の各モードを含む、単純で有用なVimモードをサポートしています。 - -::: alert-info - -`ファイル`メニューから、`設定`ダイアログを開き、 `読み取り/編集` タブへすすみます。 コンボボックスの`キーモード`を -選択することでVimモードを有効にできます。 すぐに稼動させるには、VNoteの再起動が必要です。 - -::: - -VNoteはVimの次の機能をサポートしています: - -- `r`, `s`, `S`, `i`, `I`, `a`, `A`, `c`, `C`, `o`, and `O`; -- Actions `d`, `c`, `y`, `p`, `<`, `>`, `gu`, `gU`, `J`, `gJ`, and `~`; -- Movements `h/j/k/l`, `gj/gk/g0`, `Ctrl+U`, `Ctrl+D`, `gg`, `G`, `0`, `^`, `{`, `}`, and `$`; -- マーク`a-z`; -- Registers `"`, `_`, `+`, `a-z`(`A-Z`); -- ジャンプ位置リスト(`Ctrl+O`および`Ctrl+I`); -- リーダーキー (`Space`) - - 現在のところ、`y/d/p`は、`"+y/d/p`と同等で、システムのクリップボードにアクセスします; - - ``検索ハイライトをクリアします。 - - `w`ノートを保存します。 -- `zz`, `zb`, `zt`; -- 取り消しとやり直しには`u`と`Ctrl+R`を指定します。 -- Text objects `i/a`: word, WORD, `''`, `""`, `` ` ` ``, `()`, `[]`, `<>`, and `{}`; -- コマンドライン `:w`および, `:wq`, `:x`, `:q`, `:q!`, `:noh[lsearch]`; -- タイトル間ジャンプ - - `[[`: 前のタイトルにジャンプ; - - `]]`: 次のタイトルにジャンプ。 - - `[]`: 同じレベルで前のタイトルにジャンプします。 - - `][`: 同じレベルで次のタイトルにジャンプします。 - - `[{`: 上位レベルの前のタイトルにジャンプする; - - `[{`: 上位レベルの次のタイトルにジャンプする; -- 検索するには`/`と`?` - - `n`と`N`により、次の出現または前の出現を見つける; - - `Ctrl+N`と`Ctrl+P`は、検索履歴をナビゲートするために使用します; -- `Ctrl+R`レジスタの内容を読み出す; -- 挿入モード時に`Ctrl+O`で、通常モードに一時的に入る; - -現在のところ、VNoteは、Vimのマクロと再実行(`.`)機能をサポート**しません**。 - -VNoteでVimを楽しんでください! - -# その他 -- `Ctrl+J`と`Ctrl+K`は、アイテム間を移動するために使用できます; -- `Ctrl+N`と`Ctrl+P`は、リスト内の検索結果中を移動するために使用できます; diff --git a/src/resources/docs/ja/tips_add_style.md b/src/resources/docs/ja/tips_add_style.md deleted file mode 100644 index 7e7ffac9..00000000 --- a/src/resources/docs/ja/tips_add_style.md +++ /dev/null @@ -1,19 +0,0 @@ -# VNoteのスタイル -VNoteでは、編集モードと読み込みモードの両方でカスタムスタイルをサポートしています。カスタムスタイルを作成する最良の方法は、既定のスタイルを[ここから](https://github.com/tamlok/vnote/tree/master/src/resources/themes)コピーし、関連ファイルを名前変更し、スタイルフォルダに配置して、それを好みに合わせて調整することです。 - -新しいスタイルを適用するには、再起動が必要です。現在のタブを改めて開くと、新しいスタイルを適用できます。 - -スタイルの詳細については、[VNote](https://github.com/tamlok/vnote)を参照してください。 - -## エディタスタイル -エディタのスタイルは、拡張子`.mdhl`を持つファイルです。デフォルトでは、VNoteの構成フォルダのサブフォルダ`styles`に配置されます。 - -詳細な構文については、[PEG Markdown Highlightのスタイルシート](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html)を参照してください。 - -## 読み取りモードスタイル -読み取りモードのスタイルは、拡張子が`.css`であるファイルです。デフォルトでは、VNoteの構成フォルダのサブフォルダ`styles`に配置されます。 - -### コードブロックのスタイル -コードブロックスタイルは、拡張子が`.css`であるファイルです。既定では、VNoteの設定フォルダのサブフォルダ`スタイル/codeblock_styles`に配置されます。 - -[Highlight.js](https://github.com/isagalaev/highlight.js)を訪問するお、より多くのスタイルを見ることができます。 diff --git a/src/resources/docs/ja/tips_add_theme.md b/src/resources/docs/ja/tips_add_theme.md deleted file mode 100644 index 57eec9b7..00000000 --- a/src/resources/docs/ja/tips_add_theme.md +++ /dev/null @@ -1,8 +0,0 @@ -# VNoteテーマ -VNoteはテーマをサポートしています。テーマは、VNote設定フォルダのサブフォルダの`themes`にあるフォルダです。カスタムテーマを作成する最良の方法は、既定のテーマの一つをコピーし、関連ファイルを名前変更し、テーマフォルダに配置して、それを好みに合わせて調整することです。 - -デフォルトのテーマを直接変更することはできません。また、変更を失うこともあります。 - -新しいテーマを検出または適用するには、再始動が必要です。 - -テーマの詳細については、[VNote](https://github.com/tamlok/vnote)を参照してください。 diff --git a/src/resources/docs/ja/tips_custom_shortcut.md b/src/resources/docs/ja/tips_custom_shortcut.md deleted file mode 100644 index 4a7c392f..00000000 --- a/src/resources/docs/ja/tips_custom_shortcut.md +++ /dev/null @@ -1,91 +0,0 @@ -# ショートカットのカスタマイズ -VNoteでは、標準ショートカットのカスタマイズもサポートされていますが、推奨されません。VNoteは、ユーザー構成ファイル`vnote.ini`の`[shortcuts]`セクションおよび`[captain_mode_shortcuts]`セクションに外部プログラムの構成情報を格納します。 - -たとえば、デフォルトの設定は次のようになります。 - -```ini -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Customized shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Save current note -SaveNote=Ctrl+S -; Save changes and enter read mode -SaveAndRead=Ctrl+T -; Edit current note -EditNote=Ctrl+W -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Alternate one/two panels view -OnePanelView=P -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -``` - -各項目は、`操作=キーシーケンス`の形式です。操作のショートカットを無効にするには、`キーシーケンス`を空にします。 - -`Ctrl+Q`は、Vnoteを終了するために予約されていることに注意してください。 diff --git a/src/resources/docs/ja/tips_external_program.md b/src/resources/docs/ja/tips_external_program.md deleted file mode 100644 index 8ac38698..00000000 --- a/src/resources/docs/ja/tips_external_program.md +++ /dev/null @@ -1,21 +0,0 @@ -# 外部プログラム -VNoteでは、外部プログラムでのノートの編集をサポートしています。VNoteは、ユーザー構成ファイル`vnote.ini`の`[external_editors]`セクションに外部プログラムの構成情報を格納します。 - -サンプル設定は次のようになります: - -```ini -[external_editors] -; Define external editors which could be called to edit notes -; One program per line with the format name="program \"%0\" arg1 arg2", -; in which %0 will be replaced with the note file path (so it is better to enclose it -; with double quotes) -; Shortcut could be empty -; Need to escape \ and ", use double quotes to quote paths/arguments with spaces -; SHOULD defined in user config file, not here - -GVim=C:\\\"Program Files (x86)\"\\Vim\\vim80\\gvim.exe \"%0\", F4 -Notepad=notepad \"%0\" -Notepad%2B%2B=C:\\\"Program Files (x86)\"\\notepad++\\notepad++.exe \"%0\" -``` - -新しい外部プログラムを検出するには、再起動が必要です。 diff --git a/src/resources/docs/ja/welcome.md b/src/resources/docs/ja/welcome.md deleted file mode 100644 index 12939768..00000000 --- a/src/resources/docs/ja/welcome.md +++ /dev/null @@ -1,39 +0,0 @@ -# VNoteへようこそ -![VNote](qrc:/resources/icons/256x256/vnote.png) - -> **VNote は、プログラマとMarkdownをよく理解するノート作成アプリケーションです。** - -[VNote](https://tamlok.github.io/vnote)は、快適なマークダウン経験と強力なノート管理を提供しています。 - -VNoteは**オープンソース**で、現在は主に1人の個人によって開発され、スペアタイムで管理されています。ですから、生産性を向上させてくれるなら、どんどんVNoteを利用してよいのです。[VNoteヘ寄付されたユーザに](https://github.com/tamlok/vnote/wiki/Donate-List)感謝いたします! - -## トラブルシューティング・ガイド -::: alert-info - -**Vim modeを有効化する** - -`ファイル`メニューから、`設定`ダイアログを開き、 `読み取り/編集` タブへすすみます。 コンボボックスの`キーモード`を -選択することでVimモードを有効にできます。 すぐに稼動させるには、VNoteの再起動が必要です。 - -Vimが何か知らない場合は、有効にしないでください。 - -::: - -VNoteは、次の2つの方法で使用できます。 - -1. ノートブック、フォルダ、ノートを使用してノートを作成することができます。VNoteはすべてのデータを管理し、添付ファイルやタグなどの追加機能を提供します。 -2. エディタ。VNoteは、ローカルファイルを編集するために外部ファイルを開くためのエクスプローラを提供します。 - -トラブルシューティングの手順: - -1. コンテキストメニュー、メニューバー、ツールバー、設定、ヘルプメニューを使用して、何かを見落としているかどうかを確認します。 -2. 構成を変更するには、現在のタブを再オープンするか、またはVnoteを再起動する必要があります。 -3. ヘルプメニューには、マークダウンガイドとショートカットガイドが用意されています。このガイドを参考にしてください。 -4. [GitHub Issues](https://github.com/tamlok/vnote/issues) およびVNoteの[ドキュメント](https://tamlok.github.io/vnote/en_us/#!docs/_vnote.json)でクイック検索をおこなってください; -5. 助けをもとめるには、GitHubで、*詳細に*Issueを投稿してください。 - -`Ctrl+G`を押して、**ユニバーサルエントリ**から今日の仕事をはじめてはどうでしょうか? - -たのしみましょう! - -Fork me on GitHub diff --git a/src/resources/docs/zh_CN/markdown_guide.md b/src/resources/docs/zh_CN/markdown_guide.md deleted file mode 100644 index 0204c014..00000000 --- a/src/resources/docs/zh_CN/markdown_guide.md +++ /dev/null @@ -1,267 +0,0 @@ -# Markdown指南 -Markdown是一种轻量级的易用的书写语法。本文是Markdown的一个快速指南[^1]。 - -## 什么是Markdown? -Markdown是一种通过少量简单的标记字符来格式化文本的方法。您可以用纯文本来书写文档,然后在阅读时呈现一个美观的排版。 - -其实并没有一个标准的Markdown语法,很多编辑器都会添加自己的扩展语法。不同于此,为了兼容性,VNote仅仅支持那些被广泛使用的基本语法。 - -## 如何上手Markdown? -如果您是刚接触Markdown,那么比较好的一个方法是逐个学习Markdown语法。刚开始,懂得标题和强调语法就能够写出基本的文档;然后,每天可以学习一个新的语法并不断练习。 - - -## 语法指南 -下面是VNote支持的Markdown语法的一个概览。 - -### 标题 -```md -# This is an

tag -## This is an

tag -###### This is an

tag -``` - -**注意**: - -- `#`之后需要至少一个空格; -- 一个标题应该占一整行; - -### 强调 -```md -*This text will be italic* -_This text will be italic_ - -**This text will be bold** -__This text will be bold__ -``` - -**注意**: - -- VNote推荐使用`*`; -- 如果渲染错误,请尝试在第一个`*`之前以及最后一个`*`之后添加一个空格。如果被标记的文本是以全角符号开始或结尾,一般都需要前后添加一个空格; -- VNote提供快捷键`Ctrl+I`和`Ctrl+B`来插入斜体和粗体; - -### 列表 -#### 无序列表 -```md -* Item 1 -只是一段在Item 1下面的文字。需要注意上面一行结尾有两个空格。 -* Item 2 - * Item 2a - * Item 2b -* Item 3 - -使用一个空行来来结束一个列表。 -``` - -#### 有序列表 -```md -1. Item 1 -1. Item 2 -注意,列表前面的序号其实是无关紧要的,渲染时Markdown会自动修改该序号。 -3. Item 3 - 1. Item 3a - 2. Item 3b -4. Item 4 -``` - -### 表格 -```md -| col 1 | col 2 | col 3 | -| --- | --- | --- | -| cell1 | cell2 | cell3 | -| cell4 | cell5 | cell6 | -``` - -### 图片和链接 -```md -![Image Alt Text](/url/to/image.png "Optional Text") - -![Image Alt Text](/url/to/image.png "Image specified with width and height" =800x600) - -![Image Alt Text](/url/to/image.png =800x600) - -![Image Alt Text](/url/to/image.png "Image specified with width" =800x) - -![Image Alt Text](/url/to/image.png "Image specified with height" =x600) - -[Link Text](/url/of/the/link) -``` - -**注意**: - -- VNote不推荐使用参考式的图片链接。VNote不会预览这些图片。 -- 声明图片尺寸只在 **markdown-it** 中支持。 - -### 块引用 -```md -As VNote suggests: - -> VNote is the best Markdown note-taking application -> ever. -> -> THere is two spaces after `ever.` above to insert a -> new line. -``` - -**注意**: - -- `>`标记后面需要至少一个空格; -- 多行连续的引用可以只在第一行添加标记; - -### 代码块 - ```lang - This is a fenced code block. - ``` - - ~~~ - This is another fenced code block. - ~~~ - -**注意**: - -- `lang`用于指定代码块的代码语言,可选;如果不指定,VNote不会尝试高亮代码; - -### 图表 - -> 需要在`Markdown`菜单中启用Flowchart.js或Mermaid或WaveDrom,并重新打开当前标签页。 - -VNote支持使用以下引擎来绘制图表。您需要使用代码块,并标明特定语言,然后在代码块里面定义图表。 - -- [Flowchart.js](http://flowchart.js.org/),语言为`flow`或`flowchart`; -- [Mermaid](https://mermaidjs.github.io/),语言为`mermaid`; -- [WaveDrom](https://wavedrom.com/),数字时序图,语言为`wavedrom`; - -例如, - - ```flowchart - st=>start: Start:>http://www.google.com[blank] - e=>end:>http://www.google.com - op1=>operation: My Operation - sub1=>subroutine: My Subroutine - cond=>condition: Yes - or No?:>http://www.google.com - io=>inputoutput: catch something... - - st->op1->cond - cond(yes)->io->e - cond(no)->sub1(right)->op1 - ``` - -#### UML - -> 需要在设置中启用PlantUML。如果使用在线的PlantUML服务器,请注意隐私问题;如果使用本地PlantUML,可能需要安装Java运行时、PlantUML以及Graphviz。 - -VNote支持 [PlantUML](http://plantuml.com/) 来实现UML图表。您需要使用代码块,并标明语言为`puml`,然后在代码块里面定义图表。 - - ```puml - @startuml - Bob -> Alice : hello - @enduml - ``` - -#### Graphviz - -> 需要在设置中启用Graphviz。 - -VNote支持 [Graphviz](http://www.graphviz.org/) 来绘制图表。您需要使用代码块,并标明语言为`dot`,然后在代码块里面定义图表。 - -### 数学公式 - -> 需要在`Markdown`菜单中启用MathJax,并重启VNote。 - -VNote通过 [MathJax](https://www.mathjax.org/) 来支持数学公式。默认的**块公式**的分隔符是`$$...$$`,**行内公式**的分隔符是`$...$`。 - -- 行内公式不能跨多行; -- 形如`3$abc$`/`$abc$4`/`$ abc$`和`$abc $`的不会被解析为公式; -- 使用`\`转义`$`; -- 开始的`$$`之前以及结束的`$$`之后都只允许出现空格字符; - -VNote也可以使用标明语言`mathjax`的代码块来实现块公式。 - - ```mathjax - $$ - J(\theta) = \frac 1 2 \sum_{i=1}^m (h_\theta(x^{(i)})-y^{(i)})^2 - $$ - ``` - -块公式支持公式序号: - - $$vnote x markdown = awesome$$ (1.2.1) - -### 行内代码 -```md -Here is a `inline code`. -``` - -如果想输入一个 `` ` ``,需要使用两个 `` ` `` 来括住它,例如 ``` `` ` `` ```。 要输入两个 `` ` ``,则需要使用三个 `` ` ``。 - -### 删除线 -```md -Here is a ~~text~~ with strikethrough. -``` - -**注意**: - -- VNote提供快捷键`Ctrl+D`来插入带有删除线的文本; - -### 任务列表 -```md -- [x] this is a complete item. -- [ ] this is an incomplete item. -``` - -### 脚注 -```md -This is a footnote [^1]. - -[^1]: Here is the detail of the footnote. -``` - -### 上标和下标 - -> 需要在`Markdown`菜单中启用上标和下标并使用`Markdown-it`渲染引擎。 - -```md -This is the 1^st^ superscript. - -This is the H~2~O subscript. -``` - -### 警告 -使用`Markdown-it`渲染引擎时,可以添加警告信息。 - -```md -::: alert-info - -这是一个信息文本。 - -::: - -::: alert-danger - -这是一个危险文本。 - -::: -``` - -可用的一些警告形式如下: - -``` -alert-primary -alert-secondary -alert-success -alert-info -alert-warning -alert-danger -alert-light -alert-dark -``` - -### 换行和段落 -如果需要换行,您应该在当前行末尾添加两个空格,然后换行。VNote提供快捷键`Shift+Enter`来辅助用户输入两个空格并换行。 - -如果需要一个新的段落,您应该先插入一个空行然后才输入新的段落的文本。 - -一般来说,您应该在一个块元素(例如代码块、列表和块引用)后面插入一个空行来显式结束该元素。 - -[^1]: 该指南参考了 [Mastering Markdown](https://guides.github.com/features/mastering-markdown/). diff --git a/src/resources/docs/zh_CN/shortcuts.md b/src/resources/docs/zh_CN/shortcuts.md deleted file mode 100644 index 2c92ee9c..00000000 --- a/src/resources/docs/zh_CN/shortcuts.md +++ /dev/null @@ -1,331 +0,0 @@ -# VNote快捷键说明 -1. 以下按键除特别说明外,都不区分大小写; -2. 在macOS下,`Ctrl`对应于`Command`,在Vim模式下除外。 - -## 常规快捷键 -- `Ctrl+E E` -是否扩展编辑区域。 -- `Ctrl+Alt+N` -在当前文件夹下新建笔记。 -- `Ctrl+F` -页内查找和替换。 -- `Ctrl+Alt+F` -高级查找。 -- `Ctrl+Q` -退出VNote。 -- `Ctrl+J`/`Ctrl+K` -在笔记本列表、文件夹列表、笔记列表、已打开笔记列表和大纲目录中,均支持`Ctrl+J`和`Ctrl+K`导航。 -- `Ctrl+Left Mouse` -任意滚动。 -- `Ctrl+Shift+T` -恢复上一个关闭的文件。 -- `Ctrl+Alt+L` -打开灵犀页。 -- `Ctrl+Alt+I` -打开快速访问。 -- `Ctrl+T` -编辑当前笔记或保存更改并退出编辑模式。 -- `Ctrl+G` -激活通用入口。 -- `Ctrl+8`/`Ctrl+9` -跳转到最近一次查找的下一个/上一个匹配。 - -### 阅读模式 -- `H`/`J`/`K`/`L` -导航,对应于左/下/上/右方向键。 -- `Ctrl+U` -向上滚动半屏。 -- `Ctrl+D` -向下滚动半屏。 -- `gg`/`G` -跳转到笔记的开始或结尾。(区分大小写)。 -- `Ctrl + +/-` -放大/缩小页面。 -- `Ctrl+Wheel` -鼠标滚轮实现放大/缩小页面。 -- `Ctrl+0` -恢复页面大小为100%。 -- 标题跳转 - - `[[`:跳转到上`N`个标题; - - `]]`: 跳转到下`N`个标题; - - `[]`:跳转到上`N`个同层级的标题; - - `][`:跳转到下`N`个同层级的标题; - - `[{`:跳转到上`N`个高一层级的标题; - - `]}`:跳转到下`N`个高一层级的标题; -- `/`或`?`向前或向后查找 - - `N`:查找下一个匹配; - - `Shift+N`:查找上一个匹配; -- `:`执行Vim命令 - - `:q`:关闭当前笔记; - - `:noh[lsearch]`:清空查找高亮; - -### 编辑模式 -- `Ctrl+S` -保存当前更改。 -- `Ctrl + +/-` -放大/缩小页面。 -- `Ctrl+Wheel` -鼠标滚轮实现放大/缩小页面。 -- `Ctrl+0` -恢复页面大小为100%。 -- `Ctrl+J/K` -向下/向上滚动页面,不会改变光标。 -- `Ctrl+N/P` -激活自动补全。 - - `Ctrl+N/P` - 浏览补全列表并插入当前补全。 - - `Ctrl+J/K` - 浏览补全列表。 - - `Ctrl+E` - 取消补全。 - - `Enter` - 插入补全。 - - `Ctrl+[` or `Escape` - 结束补全。 - -#### 文本编辑 -- `Ctrl+B` -插入粗体;再次按`Ctrl+B`退出。如果已经选择文本,则将当前选择文本加粗。 -- `Ctrl+I` -插入斜体;再次按`Ctrl+I`退出。如果已经选择文本,则将当前选择文本改为斜体。 -- `Ctrl+D` -插入删除线;再次按`Ctrl+D`退出。如果已经选择文本,则将当前选择文本改为删除线。 -- `Ctrl+;` -插入行内代码;再次按`Ctrl+;`退出。如果已经选择文本,则将当前选择文本改为行内代码。 -- `Ctrl+M` -插入代码块;再次按`Ctrl+M`退出。如果已经选择文本,则将当前选择文本嵌入到代码块中。 -- `Ctrl+L` -插入链接。 -- `Ctrl+.` -插入表格。 -- `Ctrl+'` -插入图片。 -- `Ctrl+H` -退格键,向前删除一个字符。 -- `Ctrl+W` -删除光标位置向后到第一个空白字符之间的所有字符。 -- `Ctrl+U` -删除光标位置到行首的所有字符。 -- `Ctrl+` -插入级别为``的标题。``应该是1到6的一个数字。如果已经选择文本,则将当前选择文本改为标题。 -- `Ctrl+7` -删除当前行或所选择文本的标题标记。 -- `Tab`/`Shift+Tab` -增加或减小缩进。如果已经选择文本,则对所有选择的行进行缩进操作。 -- `Shift+Enter` -插入两个空格然后换行,在Markdown中类似于软换行的概念。 -- `Shift+Left`, `Shift+Right`, `Shift+Up`, `Shift+Down` -扩展选定左右一个字符,或上下一行。 -- `Ctrl+Shift+Left`, `Ctrl+Shift+Right` -扩展选定到单词开始或结尾。 -- `Ctrl+Shift+Up`, `Ctrl+Sfhit+Down` -扩展选定到段尾或段首。 -- `Shift+Home`, `Shift+End` -扩展选定到行首和行尾。 -- `Ctrl+Shift+Home`, `Ctrl+Shift+End` -扩展选定到笔记开始或结尾处。 - -## 自定义快捷键 -VNote支持自定义部分标准快捷键(但并不建议这么做)。VNote将快捷键信息保存在用户配置文件`vnote.ini`中的`[shortcuts]`和`[captain_mode_shortcuts]`两个小节。 - -例如,默认的配置可能是这样子的: - - -```ini -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Custom shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Save current note -SaveNote=Ctrl+S -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Alternate one/two panels view -OnePanelView=P -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=Shift+? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -``` - -每一项配置的形式为`操作=按键序列`。如果`按键序列`为空,则表示禁用该操作的快捷键。 - -注意,`Ctrl+Q`保留为退出VNote。 - -# 舰长模式 -为了更有效地利用快捷键,VNote支持 **舰长模式**。 - -按前导键`Ctrl+E`后,VNote会进入舰长模式。在舰长模式中,VNote会支持更多高效的快捷操作。 - -- `E` -是否扩展编辑区域。 -- `Y` -将焦点设为编辑区域。 -- `T` -打开或关闭工具面板。 -- `Shift+#` -打开或关闭工具栏。 -- `F` -打开当前分割窗口的笔记列表。在该列表中,可以直接按笔记对应的序号实现跳转。 -- `A` -打开当前笔记的附件列表。 -- `X` -关闭当前标签页。 -- `J` -跳转到下一个标签页。 -- `K` -跳转到上一个标签页。 -- `1` - `9` -数字1到9会跳转到对应序号的标签页。 -- `0` -跳转到前一个标签页(即前一个当前标签页)。实现当前标签页和前一个标签页之间的轮换。 -- `D` -定位当前笔记所在文件夹。 -- `Q` -放弃当前更改并退出编辑模式。 -- `V` -垂直分割当前窗口。 -- `R` -移除当前分割窗口。 -- `Shift+|` -最大化当前分割窗口。 -- `=` -均等分布所有分割窗口。 -- `H` -跳转到左边一个分割窗口。 -- `L` -跳转到右边一个分割窗口。 -- `Shift+H` -将当前标签页左移一个分割窗口。 -- `Shift+L` -将当前标签页右移一个分割窗口。 -- `M` -编辑模式中,将当前光标所在词或者所选文本进行幻词解析。 -- `S` -在编辑模式中应用片段。 -- `O` -导出笔记。 -- `I` -打开或关闭实时预览面板。 -- `U` -扩展或还原实时预览面板。 -- `C` -打开或关闭全文查找。 -- `P` -解析剪切板中的HTML为Markdown文本并粘贴。 -- `N` -查看和编辑当前笔记信息。 -- `Shift+?` -显示本快捷键说明。 - -## 展览模式 -在舰长模式中,`W`命令会进入 **展览模式**。在展览模式中,VNote会在常用的主要部件上显示至多两个字母,此时输入对应的字母即可跳转到该部件中,从而实现快速切换焦点并触发功能。 - -# Vim Mode -VNote支持一个简单但有用的Vim模式,包括 **正常**, **插入**, **可视**, **可视行** 模式。 - -::: alert-info - -在`文件`菜单中选择`设置`打开对话框,跳转到`阅读/编辑`标签页,在`按键模式`下拉框中选择开启Vim即可。需要重启VNote以生效。 - -::: - -VNote支持以下几个Vim的特性: - -- `r`, `s`, `S`, `i`, `I`, `a`, `A`, `c`, `C`, `o`, `O`; -- 操作 `d`, `c`, `y`, `p`, `<`, `>`, `gu`, `gU`, `J`, `gJ`, `~`; -- 移动 `h/j/k/l`, `gj/gk/g0`, `Ctrl+U`, `Ctrl+D`, `gg`, `G`, `0`, `^`, `{`, `}`, `$`; -- 标记 `a-z`; -- 寄存器 `"`, `_`, `+`, `a-z`(`A-Z`); -- 跳转位置列表 (`Ctrl+O` and `Ctrl+I`); -- 前导键 (`Space`) - - 目前 `y/d/p` 等同于 `"+y/d/p`, 从而可以访问系统剪切板; - - `` 清除查找高亮; - - `w` 保存笔记; -- `zz`, `zb`, `zt`; -- `u` 和 `Ctrl+R` 撤销和重做; -- 文本对象 `i/a`:word, WORD, `''`, `""`, `` ` ` ``, `()`, `[]`, `<>`, `{}`; -- 命令行 `:w`, `:wq`, `:x`, `:q`, `:q!`, `:noh[lsearch]`; -- 标题跳转 - - `[[`:跳转到上一个标题; - - `]]`: 跳转到下一个标题; - - `[]`:跳转到上一个同层级的标题; - - `][`:跳转到下一个同层级的标题; - - `[{`:跳转到上一个高一层级的标题; - - `]}`:跳转到下一个高一层级的标题; -- `/` 和 `?` 开始查找 - - `n` 和 `N` 查找下一处或上一处; - - `Ctrl+N` 和 `Ctrl+P` 浏览查找历史; -- `Ctrl+R` 读取指定寄存器的值; -- `Ctrl+O` 在插入模式中临时切换为正常模式; -- `/` - -VNote目前暂时不支持Vim的宏和重复(`.`)特性。 - -在VNote上享受Vim的美好时光吧! - -# 其他 -- `Ctrl+J` 和 `Ctrl+K` 浏览导航; -- 在列表中,`Ctrl+N` 和 `Ctrl+P` 在搜索结果中导航; diff --git a/src/resources/docs/zh_CN/tips_add_style.md b/src/resources/docs/zh_CN/tips_add_style.md deleted file mode 100644 index 3ca8b456..00000000 --- a/src/resources/docs/zh_CN/tips_add_style.md +++ /dev/null @@ -1,19 +0,0 @@ -# VNote样式 -VNote支持自定义编辑和阅读模式的样式。自定义样式最好的方法是下载默认的[样式](https://github.com/tamlok/vnote/tree/master/src/resources/themes),重命名,将这些文件放到样式文件夹下,并逐步修改调试。 - -VNote需要重新启动以检测新的样式。需要重新打开当前标签页以应用新的样式。 - -关于样式的更多信息,请访问 [VNote](https://github.com/tamlok/vnote) 。 - -## 编辑器样式 -一个编辑器样式是一个后缀名为`.mhdl`的文件。编辑器样式默认位于VNote的配置文件夹的子文件夹`styles`中。 - -关于样式的详细语法,请访问 [Stylesheets from PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html) 。 - -## 阅读模式样式 -一个阅读模式样式是一个后缀名为`.css`的文件。阅读模式样式默认位于VNote的配置文件夹的子文件夹`styles`中。 - -### 代码块样式 -一个代码块样式是一个后缀名为`.css`的文件。代码块样式默认位于VNote的配置文件夹的子文件夹`styles/codeblock_styles`中。 - -请访问 [Highlight.js](https://github.com/isagalaev/highlight.js) 来获取更多的样式。 diff --git a/src/resources/docs/zh_CN/tips_add_theme.md b/src/resources/docs/zh_CN/tips_add_theme.md deleted file mode 100644 index 7b334143..00000000 --- a/src/resources/docs/zh_CN/tips_add_theme.md +++ /dev/null @@ -1,8 +0,0 @@ -# VNote主题 -VNote支持主题。一个主题对应于VNote的配置文件夹的子文件夹`themes`下的一个文件夹。自定义主题最好的方法是复制一个默认的主题,重命名相关文件,将该文件夹放到主题文件夹下,并逐步修改调试。 - -请不要直接修改默认的主题,否则您的更改可能会丢失。 - -VNote需要重新启动以检测新的主题或应用一个主题。 - -关于主题的更多信息,请访问 [VNote](https://github.com/tamlok/vnote) 。 diff --git a/src/resources/docs/zh_CN/tips_custom_shortcut.md b/src/resources/docs/zh_CN/tips_custom_shortcut.md deleted file mode 100644 index 8c379c5d..00000000 --- a/src/resources/docs/zh_CN/tips_custom_shortcut.md +++ /dev/null @@ -1,93 +0,0 @@ -# 自定义快捷键 -VNote支持自定义部分标准快捷键(但并不建议这么做)。VNote将快捷键信息保存在用户配置文件`vnote.ini`中的`[shortcuts]`和`[captain_mode_shortcuts]`两个小节。 - -例如,默认的配置可能是这样子的: - - -```ini -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Custom shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Save current note -SaveNote=Ctrl+S -; Save changes and enter read mode -SaveAndRead=Ctrl+T -; Edit current note -EditNote=Ctrl+W -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Alternate one/two panels view -OnePanelView=P -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -``` - -每一项配置的形式为`操作=按键序列`。如果`按键序列`为空,则表示禁用该操作的快捷键。 - -注意,`Ctrl+Q`保留为退出VNote。 - diff --git a/src/resources/docs/zh_CN/tips_external_program.md b/src/resources/docs/zh_CN/tips_external_program.md deleted file mode 100644 index ba0b3bdd..00000000 --- a/src/resources/docs/zh_CN/tips_external_program.md +++ /dev/null @@ -1,21 +0,0 @@ -# 外部程序 -VNote支持使用外部程序来打开笔记。VNote将外部程序的配置信息保存在用户配置文件`vnote.ini`的`[external_editors]`小节中。 - -一个配置可能如下: - -```ini -[external_editors] -; Define external editors which could be called to edit notes -; One program per line with the format name="program \"%0\" arg1 arg2", -; in which %0 will be replaced with the note file path (so it is better to enclose it -; with double quotes) -; Shortcut could be empty -; Need to escape \ and ", use double quotes to quote paths/arguments with spaces -; SHOULD defined in user config file, not here - -GVim=C:\\\"Program Files (x86)\"\\Vim\\vim80\\gvim.exe \"%0\", F4 -Notepad=notepad \"%0\" -Notepad%2B%2B=C:\\\"Program Files (x86)\"\\notepad++\\notepad++.exe \"%0\" -``` - -VNote需要重启以检测新的外部程序。 diff --git a/src/resources/docs/zh_CN/welcome.md b/src/resources/docs/zh_CN/welcome.md deleted file mode 100644 index 4a57d832..00000000 --- a/src/resources/docs/zh_CN/welcome.md +++ /dev/null @@ -1,38 +0,0 @@ -# 欢迎使用VNote -![VNote](qrc:/resources/icons/256x256/vnote.png) - -> 一个更懂程序员和Markdown的笔记。 - -[VNote](https://tamlok.github.io/vnote) 提供了美妙的Markdown体验以及强大的笔记管理。 - -VNote是**开源**的,当前主要由个人在业余时间进行开发和维护。因此,如果VNote给您的效率带来了提升,请考虑帮助VNote成长。非常感谢[这些用户](https://github.com/tamlok/vnote/wiki/Donate-List)对VNote的捐赠! - -## 问题解决指南 -::: alert-info - -**如何启用Vim模式** - -在`文件`菜单中选择`设置`打开对话框,跳转到`阅读/编辑`标签页,在`按键模式`下拉框中选择开启Vim即可。需要重启VNote以生效。 - -如果您不了解Vim,请不要启用该模式! - -::: - -VNote有两种使用方式: - -1. 提供笔记本、文件夹和笔记的笔记软件。VNote管理所有的数据并提供诸如附件和标签的额外功能。 -2. 编辑器。VNote提供浏览器来浏览本地文件系统并打开编辑外部文件。 - -问题诊断步骤: - -1. 浏览上下文菜单、菜单栏、工具栏、设置以及帮助菜单; -2. 更改配置可能需要重新打开当前标签页或重启VNote; -3. 帮助菜单中包含了一份Markdown语法指南和一份快捷键指南; -4. 在[GitHub Issues](https://github.com/tamlok/vnote/issues)和VNote[文档](https://tamlok.github.io/vnote/zh_cn/#!docs/_vnote.json)中搜索您的问题; -5. 在GitHub上提交一个*详细*的Issue寻求帮助。 - -现在,不妨按下`Ctrl+G`,让一天的工作从**通用入口**开始吧! - -Markdown愉快! - -Fork me on GitHub diff --git a/src/resources/export/export_template.html b/src/resources/export/export_template.html deleted file mode 100644 index 50c840b5..00000000 --- a/src/resources/export/export_template.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - -
-
- -
- -
-
-
- - - - - - diff --git a/src/resources/export/outline.css b/src/resources/export/outline.css deleted file mode 100644 index b73b2ba1..00000000 --- a/src/resources/export/outline.css +++ /dev/null @@ -1,205 +0,0 @@ -*, -*::before, -*::after { - box-sizing: border-box; -} - -.container-fluid { - width: 100%; - padding-right: 15px; - padding-left: 15px; - margin-right: auto; - margin-left: auto; -} - -.col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto { - position: relative; - width: 100%; - min-height: 1px; - padding-right: 15px; - padding-left: 15px; -} - -.col-12 { - -webkit-box-flex: 0; - -ms-flex: 0 0 100%; - flex: 0 0 100%; - max-width: 100%; -} - -@media (min-width: 768px) { - .col-md-3 { - -webkit-box-flex: 0; - -ms-flex: 0 0 25%; - flex: 0 0 25%; - max-width: 25%; - } -} - -@media (min-width: 768px) { - .col-md-9 { - -webkit-box-flex: 0; - -ms-flex: 0 0 75%; - flex: 0 0 75%; - max-width: 75%; - } -} - -@media (min-width: 1200px) { - .col-xl-2 { - -webkit-box-flex: 0; - -ms-flex: 0 0 16.666667%; - flex: 0 0 16.666667%; - max-width: 16.666667%; - } -} - -@media (min-width: 1200px) { - .col-xl-10 { - -webkit-box-flex: 0; - -ms-flex: 0 0 83.333333%; - flex: 0 0 83.333333%; - max-width: 83.333333%; - } -} - -@media (min-width: 768px) { - .pt-md-3, .py-md-3 { - padding-top: 1rem!important; - } -} - -@media (min-width: 768px) { - .pb-md-3, .py-md-3 { - padding-bottom: 1rem!important; - } -} - -@media (min-width: 768px) { - .pl-md-5, .px-md-5 { - padding-left: 3rem!important; - } -} - -.d-none { - display: none!important; -} - -@media (min-width: 1200px) { - .d-xl-block { - display: block!important; - } -} - -@media (min-width: 768px) { - .d-md-block { - display: block!important; - } -} - -.bd-content { - -webkit-box-ordinal-group: 1; - -ms-flex-order: 0; - order: 0; -} - -.bd-toc { - position: -webkit-sticky; - position: sticky; - top: 4rem; - height: calc(100vh - 10rem); - overflow-y: auto; -} - -.bd-toc { - -webkit-box-ordinal-group: 2; - -ms-flex-order: 1; - order: 1; - padding-top: 1.5rem; - padding-bottom: 1.5rem; - font-size: .875rem; -} - -.section-nav { - padding-left: 0; -} - -.section-nav ul { - font-size: .875rem; - list-style-type: none; -} - -.section-nav li { - font-size: .875rem; -} - -.section-nav a { - color: inherit !important; -} - -.row { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - margin-right: -15px; - margin-left: -15px; -} - -@media (min-width: 1200px) { - .flex-xl-nowrap { - flex-wrap: nowrap !important; - } -} - -#floating-button { - width: 2.5rem; - height: 2.5rem; - border-radius: 50%; - background: #00897B; - position: fixed; - top: .5rem; - right: .5rem; - cursor: pointer; - box-shadow: 0px 2px 5px #666; -} - -#floating-button .more { - color: #F5F5F5; - position: absolute; - top: 0; - display: block; - bottom: 0; - left: 0; - right: 0; - text-align: center; - padding: 0; - margin: 0; - line-height: 2.5rem; - font-size: 2rem; - font-family: 'monospace'; - font-weight: 300; -} - -.hide-none { - display: none !important; -} - -.col-expand { - -webkit-box-flex: 0; - -ms-flex: 0 0 100% !important; - flex: 0 0 100% !important; - max-width: 100% !important; - padding-right: 3rem !important; -} - -.outline-bold { - font-weight: bolder !important; -} - -@media print { - #floating-button { - display: none !important; - } -} diff --git a/src/resources/export/outline.js b/src/resources/export/outline.js deleted file mode 100644 index 748f9f85..00000000 --- a/src/resources/export/outline.js +++ /dev/null @@ -1,241 +0,0 @@ -var toc = []; - -var setVisible = function(node, visible) { - var cl = 'hide-none'; - if (visible) { - node.classList.remove(cl); - } else { - node.classList.add(cl); - } -}; - -var isVisible = function(node) { - var cl = 'hide-none'; - return !node.classList.contains(cl); -}; - -var setPostContentExpanded = function(node, expanded) { - var cl = 'col-expand'; - if (expanded) { - node.classList.add(cl); - } else { - node.classList.remove(cl); - } -}; - -var setOutlinePanelVisible = function(visible) { - var outlinePanel = document.getElementById('outline-panel'); - var postContent = document.getElementById('post-content'); - - setVisible(outlinePanel, visible); - setPostContentExpanded(postContent, !visible); -}; - -var isOutlinePanelVisible = function() { - var outlinePanel = document.getElementById('outline-panel'); - return isVisible(outlinePanel); -}; - -window.addEventListener('load', function() { - var outlinePanel = document.getElementById('outline-panel'); - outlinePanel.style.display = 'initial'; - - var floatingContainer = document.getElementById('container-floating'); - floatingContainer.style.display = 'initial'; - - var outlineContent = document.getElementById('outline-content'); - var postContent = document.getElementById('post-content'); - - // Escape @text to Html. - var escapeHtml = function(text) { - var map = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - return text.replace(/[&<>"']/g, function(m) { return map[m]; }); - } - - // Fetch the outline. - var headers = postContent.querySelectorAll("h1, h2, h3, h4, h5, h6"); - toc = []; - for (var i = 0; i < headers.length; ++i) { - var header = headers[i]; - - toc.push({ - level: parseInt(header.tagName.substr(1)), - anchor: header.id, - title: escapeHtml(header.textContent) - }); - } - - if (toc.length == 0) { - setOutlinePanelVisible(false); - setVisible(floatingContainer, false); - return; - } - - var baseLevel = baseLevelOfToc(toc); - var tocTree = tocToTree(toPerfectToc(toc, baseLevel), baseLevel); - - outlineContent.innerHTML = tocTree; - setOutlinePanelVisible(true); - setVisible(floatingContainer, true); -}); - -// Return the topest level of @toc, starting from 1. -var baseLevelOfToc = function(p_toc) { - var level = -1; - for (i in p_toc) { - if (level == -1) { - level = p_toc[i].level; - } else if (level > p_toc[i].level) { - level = p_toc[i].level; - } - } - - if (level == -1) { - level = 1; - } - - return level; -}; - -// Handle wrong title levels, such as '#' followed by '###' -var toPerfectToc = function(p_toc, p_baseLevel) { - var i; - var curLevel = p_baseLevel - 1; - var perfToc = []; - for (i in p_toc) { - var item = p_toc[i]; - - // Insert empty header. - while (item.level > curLevel + 1) { - curLevel += 1; - var tmp = { level: curLevel, - anchor: '', - title: '[EMPTY]' - }; - perfToc.push(tmp); - } - - perfToc.push(item); - curLevel = item.level; - } - - return perfToc; -}; - -var itemToHtml = function(item) { - return '' + item.title + ''; -}; - -// Turn a perfect toc to a tree using
    -var tocToTree = function(p_toc, p_baseLevel) { - var i; - var front = '
  • '; - var ending = ['
  • ']; - var curLevel = p_baseLevel; - for (i in p_toc) { - var item = p_toc[i]; - if (item.level == curLevel) { - front += ''; - front += '
  • '; - front += itemToHtml(item); - } else if (item.level > curLevel) { - // assert(item.level - curLevel == 1) - front += '
      '; - ending.push('
    '); - front += '
  • '; - front += itemToHtml(item); - ending.push('
  • '); - curLevel = item.level; - } else { - while (item.level < curLevel) { - var ele = ending.pop(); - front += ele; - if (ele == '
') { - curLevel--; - } - } - front += ''; - front += '
  • '; - front += itemToHtml(item); - } - } - while (ending.length > 0) { - front += ending.pop(); - } - front = front.replace("
  • ", ""); - front = '
      ' + front + '
    '; - return front; -}; - -var toggleMore = function() { - if (toc.length == 0) { - return; - } - - var p = document.getElementById('floating-more'); - if (isOutlinePanelVisible()) { - p.textContent = '<'; - setOutlinePanelVisible(false); - } else { - p.textContent = '>'; - setOutlinePanelVisible(true); - } -}; - -window.addEventListener('scroll', function() { - if (toc.length == 0 || !isOutlinePanelVisible()) { - return; - } - - var postContent = document.getElementById('post-content'); - var scrollTop = document.documentElement.scrollTop - || document.body.scrollTop - || window.pageYOffset; - var eles = postContent.querySelectorAll("h1, h2, h3, h4, h5, h6"); - - if (eles.length == 0) { - return; - } - - var idx = -1; - var biaScrollTop = scrollTop + 50; - for (var i = 0; i < eles.length; ++i) { - if (biaScrollTop >= eles[i].offsetTop) { - idx = i; - } else { - break; - } - } - - var header = ''; - if (idx != -1) { - header = eles[idx].id; - } - - highlightItemOnlyInOutline(header); -}); - -var highlightItemOnlyInOutline = function(id) { - var cl = 'outline-bold'; - var outlineContent = document.getElementById('outline-content'); - var eles = outlineContent.querySelectorAll("a"); - var target = null; - for (var i = 0; i < eles.length; ++i) { - var ele = eles[i]; - if (ele.getAttribute('data') == id) { - target = ele; - ele.classList.add(cl); - } else { - ele.classList.remove(cl); - } - } - - // TODO: scroll target into view within the outline panel scroll area. -}; diff --git a/src/resources/hoedown.js b/src/resources/hoedown.js deleted file mode 100644 index ebf56437..00000000 --- a/src/resources/hoedown.js +++ /dev/null @@ -1,131 +0,0 @@ -var VRenderer = 'hoedown'; - -// Use Marked to highlight code blocks in edit mode. -marked.setOptions({ - highlight: function(code, lang) { - if (lang) { - if (lang === 'wavedrom') { - lang = 'json'; - } - - if (hljs.getLanguage(lang)) { - return hljs.highlight(lang, code, true).value; - } else { - return hljs.highlightAuto(code).value; - } - } else { - return code; - } - } -}); - -var updateHtml = function(html) { - startFreshRender(); - - // There is at least one async job for MathJax. - asyncJobsCount = 1; - - contentDiv.innerHTML = html; - - insertImageCaption(); - setupImageView(); - - var codes = document.getElementsByTagName('code'); - mermaidIdx = 0; - flowchartIdx = 0; - wavedromIdx = 0; - plantUMLIdx = 0; - graphvizIdx = 0; - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.parentElement.tagName.toLowerCase() == 'pre') { - if (VEnableMermaid && code.classList.contains('language-mermaid')) { - // Mermaid code block. - if (renderMermaidOne(code)) { - // replaceChild() will decrease codes.length. - --i; - continue; - } - } else if (VEnableFlowchart - && (code.classList.contains('language-flowchart') - || code.classList.contains('language-flow'))) { - // Flowchart code block. - if (renderFlowchartOne(code)) { - // replaceChild() will decrease codes.length. - --i; - continue; - } - } else if (VEnableWavedrom && code.classList.contains('language-wavedrom')) { - // Wavedrom code block. - if (renderWavedromOne(code)) { - // replaceChild() will decrease codes.length. - --i; - continue; - } - } else if (VEnableMathjax && code.classList.contains('language-mathjax')) { - // Mathjax code block. - continue; - } else if (VPlantUMLMode != 0 - && code.classList.contains('language-puml')) { - // PlantUML code block. - if (VPlantUMLMode == 1) { - if (renderPlantUMLOneOnline(code)) { - // replaceChild() will decrease codes.length. - --i; - } - } else { - renderPlantUMLOneLocal(code); - } - - continue; - } else if (VEnableGraphviz - && code.classList.contains('language-dot')) { - // Graphviz code block. - renderGraphvizOneLocal(code); - continue; - } - - - if (listContainsRegex(code.classList, /language-.*/)) { - hljs.highlightBlock(code); - } - } - } - - addClassToCodeBlock(); - addCopyButtonToCodeBlock(); - renderCodeBlockLineNumber(); - - // If you add new logics after handling MathJax, please pay attention to - // finishLoading logic. - // MathJax may be not loaded for now. - if (VEnableMathjax && (typeof MathJax != "undefined")) { - MathJax.texReset(); - MathJax - .typesetPromise([contentDiv]) - .then(postProcessMathJax) - .catch(function (err) { - content.setLog("err: " + err); - finishOneAsyncJob(); - }); - } else { - finishOneAsyncJob(); - } -}; - -var highlightText = function(text, id, timeStamp) { - var html = marked(text); - content.highlightTextCB(html, id, timeStamp); -} - -var textToHtml = function(identifier, id, timeStamp, text, inlineStyle) { - var html = marked(text); - if (inlineStyle) { - var container = textHtmlDiv; - container.innerHTML = html; - html = getHtmlWithInlineStyles(container); - container.innerHTML = ""; - } - - content.textToHtmlCB(identifier, id, timeStamp, html); -} diff --git a/src/resources/icon.rc b/src/resources/icon.rc deleted file mode 100644 index 0669e583..00000000 --- a/src/resources/icon.rc +++ /dev/null @@ -1 +0,0 @@ -IDI_ICON1 ICON DISCARDABLE "resources/icons/vnote.ico" \ No newline at end of file diff --git a/src/resources/icons/128x128/vnote.png b/src/resources/icons/128x128/vnote.png deleted file mode 100644 index 78a70c92..00000000 Binary files a/src/resources/icons/128x128/vnote.png and /dev/null differ diff --git a/src/resources/icons/16x16/vnote.png b/src/resources/icons/16x16/vnote.png deleted file mode 100644 index bf75a7aa..00000000 Binary files a/src/resources/icons/16x16/vnote.png and /dev/null differ diff --git a/src/resources/icons/256x256/vnote.png b/src/resources/icons/256x256/vnote.png deleted file mode 100644 index aef63b0e..00000000 Binary files a/src/resources/icons/256x256/vnote.png and /dev/null differ diff --git a/src/resources/icons/32x32/vnote.png b/src/resources/icons/32x32/vnote.png deleted file mode 100644 index eef98715..00000000 Binary files a/src/resources/icons/32x32/vnote.png and /dev/null differ diff --git a/src/resources/icons/48x48/vnote.png b/src/resources/icons/48x48/vnote.png deleted file mode 100644 index 474640a6..00000000 Binary files a/src/resources/icons/48x48/vnote.png and /dev/null differ diff --git a/src/resources/icons/64x64/vnote.png b/src/resources/icons/64x64/vnote.png deleted file mode 100644 index 88aba8b2..00000000 Binary files a/src/resources/icons/64x64/vnote.png and /dev/null differ diff --git a/src/resources/icons/add.svg b/src/resources/icons/add.svg deleted file mode 100644 index b9e8f00d..00000000 --- a/src/resources/icons/add.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/add_attachment.svg b/src/resources/icons/add_attachment.svg deleted file mode 100644 index b9e8f00d..00000000 --- a/src/resources/icons/add_attachment.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/add_program.svg b/src/resources/icons/add_program.svg deleted file mode 100644 index b9e8f00d..00000000 --- a/src/resources/icons/add_program.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/add_snippet.svg b/src/resources/icons/add_snippet.svg deleted file mode 100644 index b9e8f00d..00000000 --- a/src/resources/icons/add_snippet.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/add_style.svg b/src/resources/icons/add_style.svg deleted file mode 100644 index b9e8f00d..00000000 --- a/src/resources/icons/add_style.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/apply_snippet.svg b/src/resources/icons/apply_snippet.svg deleted file mode 100644 index a1a3b6ef..00000000 --- a/src/resources/icons/apply_snippet.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/resources/icons/attachment.svg b/src/resources/icons/attachment.svg deleted file mode 100644 index 8b7b4ed5..00000000 --- a/src/resources/icons/attachment.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/bold.svg b/src/resources/icons/bold.svg deleted file mode 100644 index e950b379..00000000 --- a/src/resources/icons/bold.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 1 - B - - diff --git a/src/resources/icons/cart.svg b/src/resources/icons/cart.svg deleted file mode 100644 index 27e63e70..00000000 --- a/src/resources/icons/cart.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - diff --git a/src/resources/icons/clear_attachment.svg b/src/resources/icons/clear_attachment.svg deleted file mode 100644 index 59af5e14..00000000 --- a/src/resources/icons/clear_attachment.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/clear_cart.svg b/src/resources/icons/clear_cart.svg deleted file mode 100644 index 59af5e14..00000000 --- a/src/resources/icons/clear_cart.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/clear_history.svg b/src/resources/icons/clear_history.svg deleted file mode 100644 index 59af5e14..00000000 --- a/src/resources/icons/clear_history.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/clear_search.svg b/src/resources/icons/clear_search.svg deleted file mode 100644 index 59af5e14..00000000 --- a/src/resources/icons/clear_search.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/close.svg b/src/resources/icons/close.svg deleted file mode 100644 index ce23b83e..00000000 --- a/src/resources/icons/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/close_note_tb.svg b/src/resources/icons/close_note_tb.svg deleted file mode 100644 index ce23b83e..00000000 --- a/src/resources/icons/close_note_tb.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/close_red.svg b/src/resources/icons/close_red.svg deleted file mode 100644 index 3f300f1c..00000000 --- a/src/resources/icons/close_red.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/code_block.svg b/src/resources/icons/code_block.svg deleted file mode 100644 index 4bebd6b2..00000000 --- a/src/resources/icons/code_block.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - # - - diff --git a/src/resources/icons/copy.svg b/src/resources/icons/copy.svg deleted file mode 100644 index 7ababcd8..00000000 --- a/src/resources/icons/copy.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/corner_menu.svg b/src/resources/icons/corner_menu.svg deleted file mode 100644 index f7202eaa..00000000 --- a/src/resources/icons/corner_menu.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/corner_menu_cur.svg b/src/resources/icons/corner_menu_cur.svg deleted file mode 100644 index e290311b..00000000 --- a/src/resources/icons/corner_menu_cur.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/corner_tablist.svg b/src/resources/icons/corner_tablist.svg deleted file mode 100644 index b20efa2c..00000000 --- a/src/resources/icons/corner_tablist.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/corner_tablist_cur.svg b/src/resources/icons/corner_tablist_cur.svg deleted file mode 100644 index 4a2770b2..00000000 --- a/src/resources/icons/corner_tablist_cur.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/create_note.svg b/src/resources/icons/create_note.svg deleted file mode 100644 index 689eeeed..00000000 --- a/src/resources/icons/create_note.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/create_note_tb.svg b/src/resources/icons/create_note_tb.svg deleted file mode 100644 index 962ef8ad..00000000 --- a/src/resources/icons/create_note_tb.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - diff --git a/src/resources/icons/create_notebook.svg b/src/resources/icons/create_notebook.svg deleted file mode 100644 index 689eeeed..00000000 --- a/src/resources/icons/create_notebook.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/create_rootdir.svg b/src/resources/icons/create_rootdir.svg deleted file mode 100644 index 689eeeed..00000000 --- a/src/resources/icons/create_rootdir.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/create_rootdir_tb.svg b/src/resources/icons/create_rootdir_tb.svg deleted file mode 100644 index 1c680678..00000000 --- a/src/resources/icons/create_rootdir_tb.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - diff --git a/src/resources/icons/create_subdir.svg b/src/resources/icons/create_subdir.svg deleted file mode 100644 index cde438a1..00000000 --- a/src/resources/icons/create_subdir.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - Layer 1 - - - - - - diff --git a/src/resources/icons/cut.svg b/src/resources/icons/cut.svg deleted file mode 100644 index 58c392ed..00000000 --- a/src/resources/icons/cut.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/decrease_outline_level.svg b/src/resources/icons/decrease_outline_level.svg deleted file mode 100644 index 01f101f5..00000000 --- a/src/resources/icons/decrease_outline_level.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete.svg b/src/resources/icons/delete.svg deleted file mode 100644 index 382a85ce..00000000 --- a/src/resources/icons/delete.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_attachment.svg b/src/resources/icons/delete_attachment.svg deleted file mode 100644 index 382a85ce..00000000 --- a/src/resources/icons/delete_attachment.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_cart_item.svg b/src/resources/icons/delete_cart_item.svg deleted file mode 100644 index 382a85ce..00000000 --- a/src/resources/icons/delete_cart_item.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_dir.svg b/src/resources/icons/delete_dir.svg deleted file mode 100644 index 366b12cc..00000000 --- a/src/resources/icons/delete_dir.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_note.svg b/src/resources/icons/delete_note.svg deleted file mode 100644 index 366b12cc..00000000 --- a/src/resources/icons/delete_note.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_note_tb.svg b/src/resources/icons/delete_note_tb.svg deleted file mode 100644 index e875331f..00000000 --- a/src/resources/icons/delete_note_tb.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_notebook.svg b/src/resources/icons/delete_notebook.svg deleted file mode 100644 index 366b12cc..00000000 --- a/src/resources/icons/delete_notebook.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/delete_snippet.svg b/src/resources/icons/delete_snippet.svg deleted file mode 100644 index 382a85ce..00000000 --- a/src/resources/icons/delete_snippet.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/dir_info.svg b/src/resources/icons/dir_info.svg deleted file mode 100644 index a9ea538a..00000000 --- a/src/resources/icons/dir_info.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/dir_item.svg b/src/resources/icons/dir_item.svg deleted file mode 100644 index 672e65f5..00000000 --- a/src/resources/icons/dir_item.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/discard_exit.svg b/src/resources/icons/discard_exit.svg deleted file mode 100644 index 7cc62972..00000000 --- a/src/resources/icons/discard_exit.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/edit_note.svg b/src/resources/icons/edit_note.svg deleted file mode 100644 index c4283b86..00000000 --- a/src/resources/icons/edit_note.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/src/resources/icons/editing.svg b/src/resources/icons/editing.svg deleted file mode 100644 index 05fd34cc..00000000 --- a/src/resources/icons/editing.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/editing_modified.svg b/src/resources/icons/editing_modified.svg deleted file mode 100644 index 9ae66550..00000000 --- a/src/resources/icons/editing_modified.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/empty_recycle_bin.svg b/src/resources/icons/empty_recycle_bin.svg deleted file mode 100644 index a2200617..00000000 --- a/src/resources/icons/empty_recycle_bin.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - Layer 1 - - - - Layer 1 copy - - diff --git a/src/resources/icons/expand.svg b/src/resources/icons/expand.svg deleted file mode 100644 index 81e4759c..00000000 --- a/src/resources/icons/expand.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/src/resources/icons/explore_root.svg b/src/resources/icons/explore_root.svg deleted file mode 100644 index 6eab7dc3..00000000 --- a/src/resources/icons/explore_root.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/explorer.svg b/src/resources/icons/explorer.svg deleted file mode 100644 index 464707da..00000000 --- a/src/resources/icons/explorer.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/src/resources/icons/find_replace.svg b/src/resources/icons/find_replace.svg deleted file mode 100644 index c3f6bf6f..00000000 --- a/src/resources/icons/find_replace.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/flash_page.svg b/src/resources/icons/flash_page.svg deleted file mode 100644 index 555ed2c3..00000000 --- a/src/resources/icons/flash_page.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/fullscreen.svg b/src/resources/icons/fullscreen.svg deleted file mode 100644 index 53ed9a2f..00000000 --- a/src/resources/icons/fullscreen.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/heading.svg b/src/resources/icons/heading.svg deleted file mode 100644 index 0c07c6f1..00000000 --- a/src/resources/icons/heading.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 1 - H - - diff --git a/src/resources/icons/heading_sequence.svg b/src/resources/icons/heading_sequence.svg deleted file mode 100644 index b8014ac6..00000000 --- a/src/resources/icons/heading_sequence.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 2 - 1.2. - - diff --git a/src/resources/icons/history.svg b/src/resources/icons/history.svg deleted file mode 100644 index 3f9d0fe2..00000000 --- a/src/resources/icons/history.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/import_note.svg b/src/resources/icons/import_note.svg deleted file mode 100644 index b7e13b74..00000000 --- a/src/resources/icons/import_note.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/src/resources/icons/increase_outline_level.svg b/src/resources/icons/increase_outline_level.svg deleted file mode 100644 index 7dc602b4..00000000 --- a/src/resources/icons/increase_outline_level.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/inline_code.svg b/src/resources/icons/inline_code.svg deleted file mode 100644 index f2db1336..00000000 --- a/src/resources/icons/inline_code.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 1 - C - - diff --git a/src/resources/icons/insert_image.svg b/src/resources/icons/insert_image.svg deleted file mode 100644 index d981d7ce..00000000 --- a/src/resources/icons/insert_image.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/italic.svg b/src/resources/icons/italic.svg deleted file mode 100644 index 114e2093..00000000 --- a/src/resources/icons/italic.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - Layer 1 - I - - diff --git a/src/resources/icons/link.svg b/src/resources/icons/link.svg deleted file mode 100644 index 81802452..00000000 --- a/src/resources/icons/link.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/locate_attachment.svg b/src/resources/icons/locate_attachment.svg deleted file mode 100644 index ce387636..00000000 --- a/src/resources/icons/locate_attachment.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/locate_note.svg b/src/resources/icons/locate_note.svg deleted file mode 100644 index 45fe23e7..00000000 --- a/src/resources/icons/locate_note.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/locate_snippet.svg b/src/resources/icons/locate_snippet.svg deleted file mode 100644 index ce387636..00000000 --- a/src/resources/icons/locate_snippet.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/manage_template.svg b/src/resources/icons/manage_template.svg deleted file mode 100644 index ce387636..00000000 --- a/src/resources/icons/manage_template.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/menubar.svg b/src/resources/icons/menubar.svg deleted file mode 100644 index e20aea38..00000000 --- a/src/resources/icons/menubar.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/move_tab_left.svg b/src/resources/icons/move_tab_left.svg deleted file mode 100644 index e87c7333..00000000 --- a/src/resources/icons/move_tab_left.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/move_tab_right.svg b/src/resources/icons/move_tab_right.svg deleted file mode 100644 index 403d203b..00000000 --- a/src/resources/icons/move_tab_right.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/resources/icons/note_info.svg b/src/resources/icons/note_info.svg deleted file mode 100644 index a9ea538a..00000000 --- a/src/resources/icons/note_info.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/note_info_tb.svg b/src/resources/icons/note_info_tb.svg deleted file mode 100644 index a9ea538a..00000000 --- a/src/resources/icons/note_info_tb.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/note_item.svg b/src/resources/icons/note_item.svg deleted file mode 100644 index 411ae214..00000000 --- a/src/resources/icons/note_item.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/notebook.svg b/src/resources/icons/notebook.svg deleted file mode 100644 index f7ba80b7..00000000 --- a/src/resources/icons/notebook.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/src/resources/icons/notebook_info.svg b/src/resources/icons/notebook_info.svg deleted file mode 100644 index a9ea538a..00000000 --- a/src/resources/icons/notebook_info.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/notebook_item.svg b/src/resources/icons/notebook_item.svg deleted file mode 100644 index eff98dc8..00000000 --- a/src/resources/icons/notebook_item.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/src/resources/icons/open_location.svg b/src/resources/icons/open_location.svg deleted file mode 100644 index d279ec4c..00000000 --- a/src/resources/icons/open_location.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/outline.svg b/src/resources/icons/outline.svg deleted file mode 100644 index 085bc67c..00000000 --- a/src/resources/icons/outline.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/resources/icons/paste.svg b/src/resources/icons/paste.svg deleted file mode 100644 index 80d8a17d..00000000 --- a/src/resources/icons/paste.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/pin.svg b/src/resources/icons/pin.svg deleted file mode 100644 index 9036a5de..00000000 --- a/src/resources/icons/pin.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/src/resources/icons/print.svg b/src/resources/icons/print.svg deleted file mode 100644 index 6d355bf7..00000000 --- a/src/resources/icons/print.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/quick_access.svg b/src/resources/icons/quick_access.svg deleted file mode 100644 index debb0d2b..00000000 --- a/src/resources/icons/quick_access.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/resources/icons/reading.svg b/src/resources/icons/reading.svg deleted file mode 100644 index 04a767b2..00000000 --- a/src/resources/icons/reading.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/src/resources/icons/reading_modified.svg b/src/resources/icons/reading_modified.svg deleted file mode 100644 index 217b2c30..00000000 --- a/src/resources/icons/reading_modified.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/src/resources/icons/recycle_bin.svg b/src/resources/icons/recycle_bin.svg deleted file mode 100644 index 88730b7d..00000000 --- a/src/resources/icons/recycle_bin.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - Layer 1 - - - - Layer 1 copy - - - diff --git a/src/resources/icons/remove_split.svg b/src/resources/icons/remove_split.svg deleted file mode 100644 index ce23b83e..00000000 --- a/src/resources/icons/remove_split.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/save_exit.svg b/src/resources/icons/save_exit.svg deleted file mode 100644 index 357d3026..00000000 --- a/src/resources/icons/save_exit.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/save_note.svg b/src/resources/icons/save_note.svg deleted file mode 100644 index 1e43c853..00000000 --- a/src/resources/icons/save_note.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Layer 1 - - - - - - - - - - - \ No newline at end of file diff --git a/src/resources/icons/search.svg b/src/resources/icons/search.svg deleted file mode 100644 index 0927bfb2..00000000 --- a/src/resources/icons/search.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/search_advanced.svg b/src/resources/icons/search_advanced.svg deleted file mode 100644 index 71ead32d..00000000 --- a/src/resources/icons/search_advanced.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/search_console.svg b/src/resources/icons/search_console.svg deleted file mode 100644 index 7308917e..00000000 --- a/src/resources/icons/search_console.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/search_wrap.svg b/src/resources/icons/search_wrap.svg deleted file mode 100644 index 13fb2a89..00000000 --- a/src/resources/icons/search_wrap.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/settings.svg b/src/resources/icons/settings.svg deleted file mode 100644 index 913c2a7d..00000000 --- a/src/resources/icons/settings.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - diff --git a/src/resources/icons/snippet_info.svg b/src/resources/icons/snippet_info.svg deleted file mode 100644 index 768fefeb..00000000 --- a/src/resources/icons/snippet_info.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/snippets.svg b/src/resources/icons/snippets.svg deleted file mode 100644 index 42d9b616..00000000 --- a/src/resources/icons/snippets.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/resources/icons/sort.svg b/src/resources/icons/sort.svg deleted file mode 100644 index 9dcee9ac..00000000 --- a/src/resources/icons/sort.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - Layer 2 - A - Z - - diff --git a/src/resources/icons/split_window.svg b/src/resources/icons/split_window.svg deleted file mode 100644 index e269d0a8..00000000 --- a/src/resources/icons/split_window.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/src/resources/icons/star.svg b/src/resources/icons/star.svg deleted file mode 100644 index e857a234..00000000 --- a/src/resources/icons/star.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/icons/stay_on_top.svg b/src/resources/icons/stay_on_top.svg deleted file mode 100644 index 9036a5de..00000000 --- a/src/resources/icons/stay_on_top.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/src/resources/icons/strikethrough.svg b/src/resources/icons/strikethrough.svg deleted file mode 100644 index 131bb3ea..00000000 --- a/src/resources/icons/strikethrough.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - Layer 1 - S - - - diff --git a/src/resources/icons/table.svg b/src/resources/icons/table.svg deleted file mode 100644 index d2a38552..00000000 --- a/src/resources/icons/table.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/src/resources/icons/tag.svg b/src/resources/icons/tag.svg deleted file mode 100644 index 743e07a3..00000000 --- a/src/resources/icons/tag.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/tag_explorer.svg b/src/resources/icons/tag_explorer.svg deleted file mode 100644 index 05fa0e67..00000000 --- a/src/resources/icons/tag_explorer.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - diff --git a/src/resources/icons/tags.svg b/src/resources/icons/tags.svg deleted file mode 100644 index 8031efbc..00000000 --- a/src/resources/icons/tags.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/resources/icons/universal_entry_tb.svg b/src/resources/icons/universal_entry_tb.svg deleted file mode 100644 index fb1aa0dd..00000000 --- a/src/resources/icons/universal_entry_tb.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/src/resources/icons/unstar.svg b/src/resources/icons/unstar.svg deleted file mode 100644 index c2d9b453..00000000 --- a/src/resources/icons/unstar.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/src/resources/icons/up.svg b/src/resources/icons/up.svg deleted file mode 100644 index e0b94b4d..00000000 --- a/src/resources/icons/up.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/src/resources/icons/view.svg b/src/resources/icons/view.svg deleted file mode 100644 index 176f2647..00000000 --- a/src/resources/icons/view.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/icons/vnote.icns b/src/resources/icons/vnote.icns deleted file mode 100644 index f52afb88..00000000 Binary files a/src/resources/icons/vnote.icns and /dev/null differ diff --git a/src/resources/icons/vnote.ico b/src/resources/icons/vnote.ico deleted file mode 100644 index b6c2e0d9..00000000 Binary files a/src/resources/icons/vnote.ico and /dev/null differ diff --git a/src/resources/icons/vnote.png b/src/resources/icons/vnote.png deleted file mode 100644 index 5945ba12..00000000 Binary files a/src/resources/icons/vnote.png and /dev/null differ diff --git a/src/resources/icons/vnote.svg b/src/resources/icons/vnote.svg deleted file mode 100644 index b32c753f..00000000 --- a/src/resources/icons/vnote.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/src/resources/icons/vnote_ink.svg b/src/resources/icons/vnote_ink.svg deleted file mode 100644 index e8e1e6db..00000000 --- a/src/resources/icons/vnote_ink.svg +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/src/resources/icons/vnote_small.png b/src/resources/icons/vnote_small.png deleted file mode 100644 index 7c2e07c8..00000000 Binary files a/src/resources/icons/vnote_small.png and /dev/null differ diff --git a/src/resources/icons/vnote_update.svg b/src/resources/icons/vnote_update.svg deleted file mode 100644 index b32c753f..00000000 --- a/src/resources/icons/vnote_update.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/src/resources/markdown-it.js b/src/resources/markdown-it.js deleted file mode 100644 index 5a623251..00000000 --- a/src/resources/markdown-it.js +++ /dev/null @@ -1,286 +0,0 @@ -var nameCounter = 0; -var toc = []; // Table of Content as a list - -var getHeadingLevel = function(h) { - var level = 1; - switch (h) { - case 'h1': - break; - - case 'h2': - level += 1; - break; - - case 'h3': - level += 2; - break; - - case 'h4': - level += 3; - break; - - case 'h5': - level += 4; - break; - - case 'h6': - level += 5; - break; - - default: - level += 6; - break; - } - return level; -} - -var VRenderer = 'markdown-it'; - -// There is a VMarkdownitOption struct passed in. -// var VMarkdownitOption = { html, breaks, linkify, sub, sup }; -var mdit = window.markdownit({ - html: VMarkdownitOption.html, - breaks: VMarkdownitOption.breaks, - linkify: VMarkdownitOption.linkify, - typographer: false, - langPrefix: 'lang-', - highlight: function(str, lang) { - if (lang && (!specialCodeBlock(lang) || highlightSpecialBlocks)) { - if (lang === 'wavedrom') { - lang = 'json'; - } - - if (hljs.getLanguage(lang)) { - return hljs.highlight(lang, str, true).value; - } else { - return hljs.highlightAuto(str).value; - } - } - - // Use external default escaping. - return ''; - } -}); - -mdit = mdit.use(window.markdownitHeadingAnchor, { - anchorClass: 'vnote-anchor', - addHeadingID: true, - addHeadingAnchor: true, - anchorIcon: '#', - slugify: function(md, s) { - return 'toc_' + nameCounter++; - }, - headingHook: function(openToken, inlineToken, anchor) { - toc.push({ - level: getHeadingLevel(openToken.tag), - anchor: anchor, - title: mdit.utils.escapeHtml(inlineToken.content) - }); - } -}); - -// Enable file: scheme. -var validateLinkMDIT = mdit.validateLink; -var fileSchemeRE = /^file:/; -mdit.validateLink = function(url) { - var str = url.trim().toLowerCase(); - return fileSchemeRE.test(str) ? true : validateLinkMDIT(url); -}; - -mdit = mdit.use(window.markdownitTaskLists); - -if (VMarkdownitOption.sub) { - mdit = mdit.use(window.markdownitSub); -} - -if (VMarkdownitOption.sup) { - mdit = mdit.use(window.markdownitSup); -} - -var metaDataText = null; -if (VMarkdownitOption.metadata) { - mdit = mdit.use(window.markdownitFrontMatter, function(text){ - metaDataText = text; - }); -} - -if (VMarkdownitOption.emoji) { - mdit = mdit.use(window.markdownitEmoji); - mdit.renderer.rules.emoji = function(token, idx) { - return '' + token[idx].content + ''; - }; -} - -mdit = mdit.use(window.markdownitFootnote); - -mdit = mdit.use(window["markdown-it-imsize.js"]); - -if (typeof texmath != 'undefined') { - mdit = mdit.use(texmath, { delimiters: ['dollars', 'raw'] }); -} - -mdit.use(window.markdownitContainer, 'alert', { - validate: function(params) { - return params.trim().match(/^alert-\S+$/); - }, - - render: function (tokens, idx) { - let type = tokens[idx].info.trim().match(/^(alert-\S+)$/); - if (tokens[idx].nesting === 1) { - // opening tag - let alertClass = type[1]; - return '\n'; - } - } -}); - -var mdHasTocSection = function(markdown) { - var n = markdown.search(/(\n|^)\[toc\]/i); - return n != -1; -}; - -var markdownToHtml = function(markdown, needToc) { - toc = []; - nameCounter = 0; - var html = mdit.render(markdown); - if (needToc) { - return html.replace(/

    \[TOC\]<\/p>/ig, '

    '); - } else { - return html; - } -}; - -var updateText = function(text) { - if (VAddTOC) { - text = "[TOC]\n\n" + text; - } - - startFreshRender(); - - // There is at least one async job for MathJax. - asyncJobsCount = 1; - metaDataText = null; - - var needToc = mdHasTocSection(text); - var html = markdownToHtml(text, needToc); - contentDiv.innerHTML = html; - handleToc(needToc); - insertImageCaption(); - setupImageView(); - handleMetaData(); - renderMermaid('lang-mermaid'); - renderFlowchart(['lang-flowchart', 'lang-flow']); - renderWavedrom('lang-wavedrom'); - renderPlantUML('lang-puml'); - renderGraphviz('lang-dot'); - addClassToCodeBlock(); - addCopyButtonToCodeBlock(); - renderCodeBlockLineNumber(); - - // If you add new logics after handling MathJax, please pay attention to - // finishLoading logic. - if (VEnableMathjax) { - var texToRender = document.getElementsByClassName('tex-to-render'); - var nrTex = texToRender.length; - if (nrTex == 0) { - finishOneAsyncJob(); - return; - } - - var eles = []; - for (var i = 0; i < nrTex; ++i) { - eles.push(texToRender[i]); - } - - MathJax.texReset(); - MathJax - .typesetPromise(eles) - .then(postProcessMathJax) - .catch(function (err) { - content.setLog("err: " + err); - finishOneAsyncJob(); - }); - } else { - finishOneAsyncJob(); - } -}; - -var highlightText = function(text, id, timeStamp) { - highlightSpecialBlocks = true; - var html = mdit.render(text); - highlightSpecialBlocks = false; - content.highlightTextCB(html, id, timeStamp); -}; - -var textToHtml = function(identifier, id, timeStamp, text, inlineStyle) { - var html = mdit.render(text); - if (inlineStyle) { - var container = textHtmlDiv; - container.innerHTML = html; - html = getHtmlWithInlineStyles(container); - container.innerHTML = ""; - } - - content.textToHtmlCB(identifier, id, timeStamp, html); -}; - -// Add a PRE containing metaDataText if it is not empty. -var handleMetaData = function() { - if (!metaDataText || metaDataText.length == 0) { - return; - } - - var pre = document.createElement('pre'); - var code = document.createElement('code'); - code.classList.add(VMetaDataCodeClass); - - var text = hljs.highlight('yaml', metaDataText, true).value; - code.innerHTML = text; - - pre.appendChild(code); - contentDiv.insertAdjacentElement('afterbegin', pre); -}; - -var postProcessMathJaxWhenMathjaxReady = function() { - var all = Array.from(MathJax.startup.document.math); - for (var i = 0; i < all.length; ++i) { - var node = all[i].SourceElement().parentNode; - if (VRemoveMathjaxScript) { - // Remove the SourceElement. - try { - node.removeChild(all[i].SourceElement()); - } catch (err) { - content.setLog("err: " + err); - } - } - } -}; - -var handleMathjaxReady = function() { - if (!VEnableMathjax) { - return; - } - - var texToRender = document.getElementsByClassName('tex-to-render'); - var nrTex = texToRender.length; - if (nrTex == 0) { - return; - } - - var eles = []; - for (var i = 0; i < nrTex; ++i) { - eles.push(texToRender[i]); - } - - MathJax.texReset(); - MathJax - .typesetPromise(eles) - .then(postProcessMathJaxWhenMathjaxReady) - .catch(function (err) { - content.setLog("err: " + err); - finishOneAsyncJob(); - }); -}; diff --git a/src/resources/markdown_template.html b/src/resources/markdown_template.html deleted file mode 100644 index 474ca42c..00000000 --- a/src/resources/markdown_template.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - diff --git a/src/resources/markdown_template.js b/src/resources/markdown_template.js deleted file mode 100644 index 8081e519..00000000 --- a/src/resources/markdown_template.js +++ /dev/null @@ -1,1985 +0,0 @@ -var channelInitialized = false; - -var contentDiv = document.getElementById('content-div'); - -var previewDiv = document.getElementById('preview-div'); - -var inplacePreviewDiv = document.getElementById('inplace-preview-div'); - -var textHtmlDiv = document.getElementById('text-html-div'); - -var content; - -// Current header index in all headers. -var currentHeaderIdx = -1; - -// Pending keys for keydown. -var pendingKeys = []; - -var VMermaidDivClass = 'mermaid-diagram'; -var VFlowchartDivClass = 'flowchart-diagram'; -var VWavedromDivClass = 'wavedrom-diagram'; -var VPlantUMLDivClass = 'plantuml-diagram'; -var VMetaDataCodeClass = 'markdown-metadata'; -var VMarkRectDivClass = 'mark-rect'; - -var hljsClass = 'hljs'; - -var VPreviewMode = false; - -if (typeof VEnableMermaid == 'undefined') { - VEnableMermaid = false; -} else if (VEnableMermaid) { - mermaid.initialize({ - startOnLoad: false - }); -} - -if (typeof VEnableFlowchart == 'undefined') { - VEnableFlowchart = false; -} - -if (typeof VEnableMathjax == 'undefined') { - VEnableMathjax = false; -} - -if (typeof VEnableWavedrom == 'undefined') { - VEnableWavedrom = false; -} - -if (typeof VEnableHighlightLineNumber == 'undefined') { - VEnableHighlightLineNumber = false; -} - -if (typeof VEnableCodeBlockCopyButton == 'undefined') { - VEnableCodeBlockCopyButton = false; -} - -if (typeof VStylesToInline == 'undefined') { - VStylesToInline = ''; -} - -// 0 - disable PlantUML; -// 1 - Use online PlantUML processor; -// 2 - Use local PlantUML processor; -if (typeof VPlantUMLMode == 'undefined') { - VPlantUMLMode = 0; -} - -if (typeof VPlantUMLServer == 'undefined') { - VPlantUMLServer = 'http://www.plantuml.com/plantuml'; -} - -if (typeof VPlantUMLFormat == 'undefined') { - VPlantUMLFormat = 'svg'; -} - -if (typeof VEnableGraphviz == 'undefined') { - VEnableGraphviz = false; -} - -if (typeof VGraphvizFormat == 'undefined') { - VGraphvizFormat = 'svg'; -} - -// Add a caption (using alt text) under the image. -var VImageCenterClass = 'img-center'; -var VImageCaptionClass = 'img-caption'; -var VImagePackageClass = 'img-package'; -if (typeof VEnableImageCaption == 'undefined') { - VEnableImageCaption = false; -} - -if (typeof VEnableFlashAnchor == 'undefined') { - VEnableFlashAnchor = false; -} - -if (typeof VRemoveMathjaxScript == 'undefined') { - VRemoveMathjaxScript = false; -} - -if (typeof VAddTOC == 'undefined') { - VAddTOC = false; -} - -if (typeof VOS == 'undefined') { - VOS = 'win'; -} - -if (typeof VRenderer == 'undefined') { - VRenderer = 'markdown-it'; -} - -if (typeof handleMathjaxReady == 'undefined') { - var handleMathjaxReady = function() {}; -} - -// Whether highlight special blocks like puml, flowchart. -var highlightSpecialBlocks = false; - -var getUrlScheme = function(url) { - var idx = url.indexOf(':'); - if (idx > -1) { - return url.substr(0, idx); - } else { - return null; - } -}; - -var replaceCssUrl = function(baseUrl, match, p1, offset, str) { - if (getUrlScheme(p1)) { - return match; - } - - var url = baseUrl + '/' + p1; - return "url(\"" + url + "\");"; -}; - -var translateCssUrlToAbsolute = function(baseUrl, css) { - return css.replace(/\burl\(\"([^\"\)]+)\"\);/g, replaceCssUrl.bind(undefined, baseUrl)); -}; - -var styleContent = function() { - var styles = ""; - for (var i = 0; i < document.styleSheets.length; ++i) { - var styleSheet = document.styleSheets[i]; - if (styleSheet.cssRules) { - var baseUrl = null; - if (styleSheet.href) { - var scheme = getUrlScheme(styleSheet.href); - // We only translate local resources. - if (scheme == 'file' || scheme == 'qrc') { - baseUrl = styleSheet.href.substr(0, styleSheet.href.lastIndexOf('/')); - } - } - - for (var j = 0; j < styleSheet.cssRules.length; ++j) { - var css = styleSheet.cssRules[j].cssText; - if (baseUrl) { - // Try to replace the url() with absolute path. - css = translateCssUrlToAbsolute(baseUrl, css); - } - - styles = styles + css + "\n"; - } - } - } - - return styles; -}; - -var htmlContent = function() { - content.htmlContentCB("", styleContent(), contentDiv.innerHTML); -}; - -var mute = function(muted) { - g_muteScroll = muted; -}; - -new QWebChannel(qt.webChannelTransport, - function(channel) { - content = channel.objects.content; - - content.requestScrollToAnchor.connect(scrollToAnchor); - - content.requestMuted.connect(mute); - - if (typeof highlightText == "function") { - content.requestHighlightText.connect(highlightText); - content.noticeReadyToHighlightText(); - } - - if (typeof htmlToText == "function") { - content.requestHtmlToText.connect(htmlToText); - } - - if (typeof textToHtml == "function") { - content.requestTextToHtml.connect(textToHtml); - content.noticeReadyToTextToHtml(); - } - - if (typeof htmlContent == "function") { - content.requestHtmlContent.connect(htmlContent); - } - - content.plantUMLResultReady.connect(handlePlantUMLResult); - content.graphvizResultReady.connect(handleGraphvizResult); - - content.requestPreviewEnabled.connect(setPreviewEnabled); - - content.requestPreviewCodeBlock.connect(previewCodeBlock); - - content.requestSetPreviewContent.connect(setPreviewContent); - content.requestPerformSmartLivePreview.connect(performSmartLivePreview); - - if (typeof updateHtml == "function") { - updateHtml(content.html); - content.htmlChanged.connect(updateHtml); - } - - if (typeof updateText == "function") { - content.textChanged.connect(updateText); - content.updateText(); - } - - channelInitialized = true; - }); - -var VHighlightedAnchorClass = 'highlighted-anchor'; - -var clearHighlightedAnchor = function() { - var headers = document.getElementsByClassName(VHighlightedAnchorClass); - while (headers.length > 0) { - headers[0].classList.remove(VHighlightedAnchorClass); - } -}; - -var flashAnchor = function(anchor) { - if (!VEnableFlashAnchor) { - return; - } - - clearHighlightedAnchor(); - anchor.classList.add(VHighlightedAnchorClass); -}; - -var g_muteScroll = false; - -var scrollToAnchor = function(anchor) { - g_muteScroll = true; - currentHeaderIdx = -1; - if (!anchor) { - window.scrollTo(0, 0); - g_muteScroll = false; - return; - } - - var anc = document.getElementById(anchor); - if (anc != null) { - anc.scrollIntoView(); - flashAnchor(anc); - - var headers = document.querySelectorAll("h1, h2, h3, h4, h5, h6"); - for (var i = 0; i < headers.length; ++i) { - if (headers[i] == anc) { - currentHeaderIdx = i; - break; - } - } - } - - // Disable scroll temporarily. - setTimeout("g_muteScroll = false", 100); -}; - -window.onwheel = function(e) { - e = e || window.event; - var ctrl = !!e.ctrlKey; - if (ctrl) { - e.preventDefault(); - } -} - -var skipScrollCheckRange = null; - -var VClipboardDataTextAttr = 'source-text'; - -window.addEventListener('load', function() { - new ClipboardJS('.vnote-copy-clipboard-btn', { - text: function(trigger) { - var t = trigger.getAttribute(VClipboardDataTextAttr); - if (t[t.length - 1] == '\n') { - return t.substring(0, t.length - 1); - } else { - return t; - } - } - }); -}); - -window.onscroll = function() { - if (g_muteScroll) { - return; - } - - var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset; - if (skipScrollCheckRange - && skipScrollCheckRange.start <= scrollTop - && skipScrollCheckRange.end > scrollTop) { - return; - } - - currentHeaderIdx = -1; - skipScrollCheckRange = null; - var eles = document.querySelectorAll("h1, h2, h3, h4, h5, h6"); - - if (eles.length == 0) { - content.setHeader(""); - return; - } - - var bias = 50; - var biaScrollTop = scrollTop + bias; - for (var i = 0; i < eles.length; ++i) { - if (biaScrollTop >= eles[i].offsetTop) { - currentHeaderIdx = i; - } else { - break; - } - } - - var curHeader = null; - if (currentHeaderIdx != -1) { - curHeader = eles[currentHeaderIdx].getAttribute("id"); - - // Update the range which can be skipped to check. - var endOffset; - if (currentHeaderIdx < eles.length - 1) { - endOffset = eles[currentHeaderIdx + 1].offsetTop - bias; - } else { - endOffset = document.documentElement.scrollHeight; - } - - skipScrollCheckRange = { start: eles[currentHeaderIdx].offsetTop - bias, - end: endOffset }; - } - - content.setHeader(curHeader ? curHeader : ""); -}; - -// Used to record the repeat token of user input. -var repeatToken = 0; - -document.onkeydown = function(e) { - // Need to clear pending kyes. - var clear = true; - - // This even has been handled completely. No need to call the default handler. - var accept = true; - - e = e || window.event; - var key; - var shift; - var ctrl; - var meta; - if (e.which) { - key = e.which; - } else { - key = e.keyCode; - } - - shift = !!e.shiftKey; - ctrl = !!e.ctrlKey; - meta = !!e.metaKey; - var isCtrl = VOS == 'mac' ? e.metaKey : e.ctrlKey; - switch (key) { - // Skip Ctrl, Shift, Alt, Supper. - case 16: - case 17: - case 18: - case 91: - case 92: - clear = false; - break; - - // 0 - 9. - case 48: - case 49: - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: - case 56: - case 57: - case 96: - case 97: - case 98: - case 99: - case 100: - case 101: - case 102: - case 103: - case 104: - case 105: - { - if (pendingKeys.length != 0 || ctrl || shift || meta) { - accept = false; - break; - } - - var num = key >= 96 ? key - 96 : key - 48; - repeatToken = repeatToken * 10 + num; - clear = false; - break; - } - - case 74: // J - if (!shift && (!ctrl || isCtrl) && (!meta || isCtrl)) { - window.scrollBy(0, 100); - break; - } - - accept = false; - break; - - case 75: // K - if (!shift && (!ctrl || isCtrl) && (!meta || isCtrl)) { - window.scrollBy(0, -100); - break; - } - - accept = false; - break; - - case 72: // H - if (!ctrl && !shift && !meta) { - window.scrollBy(-100, 0); - break; - } - - accept = false; - break; - - case 76: // L - if (!ctrl && !shift && !meta) { - window.scrollBy(100, 0); - break; - } - - accept = false; - break; - - case 71: // G - if (shift) { - if (pendingKeys.length == 0) { - var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset; - var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight; - window.scrollTo(scrollLeft, scrollHeight); - break; - } - } else if (!ctrl && !meta) { - if (pendingKeys.length == 0) { - // First g, pend it. - pendingKeys.push({ - key: key, - ctrl: ctrl, - shift: shift - }); - - clear = false; - break; - } else if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - var scrollLeft = document.documentElement.scrollLeft - || document.body.scrollLeft - || window.pageXOffset; - window.scrollTo(scrollLeft, 0); - break; - } - } - } - - accept = false; - break; - - case 85: // U - if (ctrl) { - var clientHeight = document.documentElement.clientHeight; - window.scrollBy(0, -clientHeight / 2); - break; - } - - accept = false; - break; - - case 68: // D - if (ctrl) { - var clientHeight = document.documentElement.clientHeight; - window.scrollBy(0, clientHeight / 2); - break; - } - - accept = false; - break; - - case 219: // [ or { - { - var repeat = repeatToken < 1 ? 1 : repeatToken; - if (shift) { - // { - if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - // [{, jump to previous title at a higher level. - jumpTitle(false, -1, repeat); - break; - } - } - } else if (!ctrl && !meta) { - // [ - if (pendingKeys.length == 0) { - // First [, pend it. - pendingKeys.push({ - key: key, - ctrl: ctrl, - shift: shift - }); - - clear = false; - break; - } else if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - // [[, jump to previous title. - jumpTitle(false, 1, repeat); - break; - } else if (pendKey.key == 221 && !pendKey.shift && !pendKey.ctrl) { - // ][, jump to next title at the same level. - jumpTitle(true, 0, repeat); - break; - } - } - } - - accept = false; - break; - } - - case 221: // ] or } - { - var repeat = repeatToken < 1 ? 1 : repeatToken; - if (shift) { - // } - if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - // ]}, jump to next title at a higher level. - jumpTitle(true, -1, repeat); - break; - } - } - } else if (!ctrl && !meta) { - // ] - if (pendingKeys.length == 0) { - // First ], pend it. - pendingKeys.push({ - key: key, - ctrl: ctrl, - shift: shift - }); - - clear = false; - break; - } else if (pendingKeys.length == 1) { - var pendKey = pendingKeys[0]; - if (pendKey.key == key && !pendKey.shift && !pendKey.ctrl) { - // ]], jump to next title. - jumpTitle(true, 1, repeat); - break; - } else if (pendKey.key == 219 && !pendKey.shift && !pendKey.ctrl) { - // [], jump to previous title at the same level. - jumpTitle(false, 0, repeat); - break; - } - } - } - - accept = false; - break; - } - - default: - accept = false; - break; - } - - if (clear) { - repeatToken = 0; - pendingKeys = []; - } - - if (accept) { - e.preventDefault(); - } else { - content.keyPressEvent(key, ctrl, shift, meta); - } -}; - -var mermaidIdx = 0; - -// @className, the class name of the mermaid code block, such as 'lang-mermaid'. -var renderMermaid = function(className) { - if (!VEnableMermaid) { - return; - } - - var codes = document.getElementsByTagName('code'); - mermaidIdx = 0; - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.classList.contains(className)) { - if (renderMermaidOne(code)) { - // replaceChild() will decrease codes.length. - --i; - } - } - } -}; - -// Render @code as Mermaid graph. -// Returns true if succeeded. -var renderMermaidOne = function(code) { - // Mermaid code block. - mermaidIdx++; - try { - // Do not increment mermaidIdx here. - var graph = mermaid.render('mermaid-diagram-' + mermaidIdx, - code.textContent, - function(){}); - } catch (err) { - content.setLog("err: " + err); - // Clean the container element, or mermaid won't render the graph with - // the same id. - var errGraph = document.getElementById('mermaid-diagram-' + mermaidIdx); - if (errGraph) { - var parentNode = errGraph.parentElement; - parentNode.outerHTML = ''; - delete parentNode; - } - return false; - } - - if (typeof graph == "undefined") { - return false; - } - - var graphDiv = document.createElement('div'); - graphDiv.classList.add(VMermaidDivClass); - graphDiv.innerHTML = graph; - - var preNode = code.parentNode; - preNode.parentNode.replaceChild(graphDiv, preNode); - return true; -}; - -var flowchartIdx = 0; - -// @className, the class name of the flowchart code block, such as 'lang-flowchart'. -var renderFlowchart = function(classNames) { - if (!VEnableFlowchart) { - return; - } - - var codes = document.getElementsByTagName('code'); - flowchartIdx = 0; - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - var matched = false; - for (var j = 0; j < classNames.length; ++j) { - if (code.classList.contains(classNames[j])) { - matched = true; - break; - } - } - - if (matched) { - if (renderFlowchartOne(code)) { - // replaceChild() will decrease codes.length. - --i; - } - } - } -}; - -// Render @code as Flowchart.js graph. -// Returns true if succeeded. -var renderFlowchartOne = function(code) { - // Flowchart code block. - flowchartIdx++; - try { - var graph = flowchart.parse(code.textContent); - } catch (err) { - content.setLog("err: " + err); - return false; - } - - if (typeof graph == "undefined") { - return false; - } - - var graphDiv = document.createElement('div'); - graphDiv.id = 'flowchart-diagram-' + flowchartIdx; - graphDiv.classList.add(VFlowchartDivClass); - var preNode = code.parentNode; - var preParentNode = preNode.parentNode; - preParentNode.replaceChild(graphDiv, preNode); - - // Draw on it after adding it to page. - try { - graph.drawSVG(graphDiv.id); - setupSVGToView(graphDiv.children[0], true); - } catch (err) { - content.setLog("err: " + err); - preParentNode.replaceChild(preNode, graphDiv); - delete graphDiv; - return false; - } - - return true; -}; - -var wavedromIdx = 0; - -var renderWavedrom = function(className) { - if (!VEnableWavedrom) { - return; - } - - var codes = document.getElementsByTagName('code'); - wavedromIdx = 0; - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.classList.contains(className)) { - if (renderWavedromOne(code)) { - // replaceChild() will decrease codes.length. - --i; - } - } - } -}; - -var renderWavedromOne = function(code) { - // Create a script element. - var script = document.createElement('script'); - script.setAttribute('type', 'WaveDrom'); - script.textContent = code.textContent; - script.setAttribute('id', 'WaveDrom_JSON_' + wavedromIdx); - - var preNode = code.parentNode; - preNode.parentNode.replaceChild(script, preNode); - - // Create a div element. - var div = document.createElement('div'); - div.setAttribute('id', 'WaveDrom_Display_' + wavedromIdx); - div.classList.add(VWavedromDivClass); - script.insertAdjacentElement('afterend', div); - - try { - WaveDrom.RenderWaveForm(wavedromIdx, - WaveDrom.eva(script.getAttribute('id')), - 'WaveDrom_Display_'); - } catch (err) { - wavedromIdx++; - content.setLog("err: " + err); - return false; - } - - script.parentNode.removeChild(script); - - wavedromIdx++; - return true; -}; - -var plantUMLIdx = 0; -var plantUMLCodeClass = 'plantuml_code_'; - -// @className, the class name of the PlantUML code block, such as 'lang-puml'. -var renderPlantUML = function(className) { - if (VPlantUMLMode == 0) { - return; - } - - plantUMLIdx = 0; - - var codes = document.getElementsByTagName('code'); - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.classList.contains(className)) { - if (VPlantUMLMode == 1) { - renderPlantUMLOneOnline(code); - } else { - renderPlantUMLOneLocal(code); - } - } - } -}; - -// Render @code as PlantUML graph asynchronously. -var renderPlantUMLOneOnline = function(code) { - ++asyncJobsCount; - code.classList.add(plantUMLCodeClass + plantUMLIdx); - - let data = { index: plantUMLIdx, - setupView: !VPreviewMode - }; - renderPlantUMLOnline(VPlantUMLServer, - VPlantUMLFormat, - code.textContent, - function(data, format, result) { - handlePlantUMLResultExt(data.index, 0, format, result, data.setupView); - }, - data); - plantUMLIdx++; -}; - -var renderPlantUMLOneLocal = function(code) { - ++asyncJobsCount; - code.classList.add(plantUMLCodeClass + plantUMLIdx); - content.processPlantUML(plantUMLIdx, VPlantUMLFormat, code.textContent); - plantUMLIdx++; -}; - -var graphvizIdx = 0; -var graphvizCodeClass = 'graphviz_code_'; - -// @className, the class name of the Graghviz code block, such as 'lang-dot'. -var renderGraphviz = function(className) { - if (!VEnableGraphviz) { - return; - } - - graphvizIdx = 0; - - var codes = document.getElementsByTagName('code'); - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.classList.contains(className)) { - renderGraphvizOneLocal(code); - } - } -}; - -var renderGraphvizOneLocal = function(code) { - ++asyncJobsCount; - code.classList.add(graphvizCodeClass + graphvizIdx); - content.processGraphviz(graphvizIdx, VGraphvizFormat, code.textContent); - graphvizIdx++; -}; - -var isImageBlock = function(img) { - var pn = img.parentNode; - return (pn.children.length == 1) && (pn.textContent == ''); -}; - -var isImageWithBr = function(img) { - var sibling = img.nextSibling; - while (sibling) { - if (sibling.nodeType == 8) { - // Comment node. - // Just continue. - sibling = sibling.nextSibling; - continue; - } else if (sibling.nodeType == 1) { - if (sibling.tagName == 'BR') { - break; - } - } - - return false; - } - - sibling = img.previousSibling; - while (sibling) { - if (sibling.nodeType == 8) { - // Comment node. - sibling = sibling.previousSibling; - continue; - } else if (sibling.nodeType == 1) { - // Element node. - if (sibling.tagName == 'BR') { - break; - } - } else if (sibling.nodeType == 3) { - // Text node. - if (sibling.nodeValue == '\n') { - var tmp = sibling.previousSibling; - if (tmp && tmp.tagName == 'BR') { - break; - } - } - } - - return false; - } - - return true; -}; - -var getImageType = function(img) { - var type = -1; - if (isImageBlock(img)) { - type = 0; - } else if (isImageWithBr(img)) { - type = 1; - } - - return type; -}; - -// Center the image block and insert the alt text as caption. -var insertImageCaption = function() { - if (!VEnableImageCaption) { - return; - } - - var imgs = document.getElementsByTagName('img'); - for (var i = 0; i < imgs.length; ++i) { - var img = imgs[i]; - - var type = getImageType(img); - - if (type == -1) { - continue; - } else if (type == 1) { - // Insert a div as the parent of the img. - var imgPack = document.createElement('div'); - img.insertAdjacentElement('afterend', imgPack); - imgPack.appendChild(img); - } - - // Make the parent img-package. - img.parentNode.classList.add(VImagePackageClass); - - // Make it center. - img.classList.add(VImageCenterClass); - - if (img.alt == '') { - continue; - } - - // Add caption. - var captionSpan = document.createElement('span'); - captionSpan.classList.add(VImageCaptionClass); - captionSpan.textContent = img.alt; - img.insertAdjacentElement('afterend', captionSpan); - } -}; - -var asyncJobsCount = 0; - -var finishOneAsyncJob = function() { - --asyncJobsCount; - finishLogics(); -}; - -// The renderer specific code should call this function once thay have finished -// markdown-specifi handle logics, such as Mermaid, MathJax. -var finishLogics = function() { - if (asyncJobsCount <= 0) { - content.finishLogics(); - calculateWordCount(); - } -}; - -// Escape @text to Html. -var escapeHtml = function(text) { - var map = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - return text.replace(/[&<>"']/g, function(m) { return map[m]; }); -}; - -// Return the topest level of @toc, starting from 1. -var baseLevelOfToc = function(p_toc) { - var level = -1; - for (i in p_toc) { - if (level == -1) { - level = p_toc[i].level; - } else if (level > p_toc[i].level) { - level = p_toc[i].level; - } - } - - if (level == -1) { - level = 1; - } - - return level; -}; - -// Handle wrong title levels, such as '#' followed by '###' -var toPerfectToc = function(p_toc, p_baseLevel) { - var i; - var curLevel = p_baseLevel - 1; - var perfToc = []; - for (i in p_toc) { - var item = p_toc[i]; - - // Insert empty header. - while (item.level > curLevel + 1) { - curLevel += 1; - var tmp = { level: curLevel, - anchor: '', - title: '[EMPTY]' - }; - perfToc.push(tmp); - } - - perfToc.push(item); - curLevel = item.level; - } - - return perfToc; -}; - -var itemToHtml = function(item) { - return '' + item.title + ''; -}; - -// Turn a perfect toc to a tree using
      -var tocToTree = function(p_toc, p_baseLevel) { - var i; - var front = '
    • '; - var ending = ['
    • ']; - var curLevel = p_baseLevel; - for (i in p_toc) { - var item = p_toc[i]; - if (item.level == curLevel) { - front += ''; - front += '
    • '; - front += itemToHtml(item); - } else if (item.level > curLevel) { - // assert(item.level - curLevel == 1) - front += '
        '; - ending.push('
      '); - front += '
    • '; - front += itemToHtml(item); - ending.push('
    • '); - curLevel = item.level; - } else { - while (item.level < curLevel) { - var ele = ending.pop(); - front += ele; - if (ele == '
    ') { - curLevel--; - } - } - front += ''; - front += '
  • '; - front += itemToHtml(item); - } - } - while (ending.length > 0) { - front += ending.pop(); - } - front = front.replace("
  • ", ""); - front = '
      ' + front + '
    '; - return front; -}; - -var handleToc = function(needToc) { - var baseLevel = baseLevelOfToc(toc); - var tocTree = tocToTree(toPerfectToc(toc, baseLevel), baseLevel); - content.setToc(tocTree, baseLevel); - - var removeToc = toc.length == 0; - - // Add it to html - if (needToc) { - var eles = document.getElementsByClassName('vnote-toc'); - for (var i = 0; i < eles.length; ++i) { - if (removeToc) { - eles[i].parentNode.removeChild(eles[i]); - } else { - eles[i].innerHTML = tocTree; - } - } - } -}; - -// Implement mouse drag with Ctrl and left button pressed to scroll. -var vds_oriMouseClientX = 0; -var vds_oriMouseClientY = 0; -var vds_readyToScroll = false; -var vds_scrolled = false; - -window.onmousedown = function(e) { - e = e || window.event; - var isCtrl = VOS == 'mac' ? e.metaKey : e.ctrlKey; - // Left button and Ctrl key. - if (e.buttons == 1 - && isCtrl - && window.getSelection().type != 'Range' - && !isViewingImage()) { - vds_oriMouseClientX = e.clientX; - vds_oriMouseClientY = e.clientY; - vds_readyToScroll = true; - vds_scrolled = false; - e.preventDefault(); - } else { - vds_readyToScroll = false; - vds_scrolled = false; - } -}; - -window.onmouseup = function(e) { - e = e || window.event; - if (vds_scrolled || vds_readyToScroll) { - // Have been scrolled, restore the cursor style. - document.body.style.cursor = "auto"; - e.preventDefault(); - } - - vds_readyToScroll = false; - vds_scrolled = false; -}; - -window.onmousemove = function(e) { - e = e || window.event; - if (vds_readyToScroll) { - deltaX = e.clientX - vds_oriMouseClientX; - deltaY = e.clientY - vds_oriMouseClientY; - - var threshold = 5; - if (Math.abs(deltaX) >= threshold || Math.abs(deltaY) >= threshold) { - vds_oriMouseClientX = e.clientX; - vds_oriMouseClientY = e.clientY; - - if (!vds_scrolled) { - vds_scrolled = true; - document.body.style.cursor = "all-scroll"; - } - - var scrollX = -deltaX; - var scrollY = -deltaY; - window.scrollBy(scrollX, scrollY); - } - - e.preventDefault(); - } -}; - -// @forward: jump forward or backward. -// @relativeLevel: 0 for the same level as current header; -// negative value for upper level; -// positive value is ignored. -var jumpTitle = function(forward, relativeLevel, repeat) { - var headers = document.querySelectorAll("h1, h2, h3, h4, h5, h6"); - if (headers.length == 0) { - return; - } - - if (currentHeaderIdx == -1) { - // At the beginning, before any headers. - if (relativeLevel < 0 || !forward) { - return; - } - } - - var targetIdx = -1; - // -1: skip level check. - var targetLevel = 0; - - var delta = 1; - if (!forward) { - delta = -1; - } - - var scrollTop = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset; - - var firstHeader = true; - for (targetIdx = (currentHeaderIdx == -1 ? 0 : currentHeaderIdx); - targetIdx >= 0 && targetIdx < headers.length; - targetIdx += delta) { - var header = headers[targetIdx]; - var level = parseInt(header.tagName.substr(1)); - if (targetLevel == 0) { - targetLevel = level; - if (relativeLevel < 0) { - targetLevel += relativeLevel; - if (targetLevel < 1) { - // Invalid level. - return false; - } - } else if (relativeLevel > 0) { - targetLevel = -1; - } - } - - if (targetLevel == -1 || level == targetLevel) { - if (targetIdx == currentHeaderIdx) { - // If current header is visible, skip it. - // Minus 2 to tolerate some margin. - if (forward || scrollTop - 2 <= headers[targetIdx].offsetTop) { - continue; - } - } - - if (--repeat == 0) { - break; - } - } else if (level < targetLevel) { - return; - } - - firstHeader = false; - } - - if (targetIdx < 0 || targetIdx >= headers.length) { - return; - } - - // Disable scroll temporarily. - g_muteScroll = true; - headers[targetIdx].scrollIntoView(); - flashAnchor(headers[targetIdx]); - currentHeaderIdx = targetIdx; - content.setHeader(headers[targetIdx].getAttribute("id")); - setTimeout("g_muteScroll = false", 100); -}; - -var renderCodeBlockLineNumber = function() { - if (!VEnableHighlightLineNumber) { - return; - } - - var codes = document.getElementsByTagName('code'); - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - var pare = code.parentElement; - if (pare.tagName.toLowerCase() == 'pre') { - if (VEnableMathjax && pare.classList.contains("lang-mathjax")) { - continue; - } - - hljs.lineNumbersBlock(code); - } - } - - if (VRenderer != 'marked') { - // Delete the last extra row. - var tables = document.getElementsByTagName('table'); - for (var i = 0; i < tables.length; ++i) { - var table = tables[i]; - if (table.classList.contains("hljs-ln")) { - var rowCount = table.rows.length; - table.deleteRow(rowCount - 1); - } - } - } -}; - -var addClassToCodeBlock = function() { - var codes = document.getElementsByTagName('code'); - var mathCodes = []; - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - var pare = code.parentElement; - if (pare.tagName.toLowerCase() == 'pre') { - code.classList.add(hljsClass); - - if (VEnableMathjax - && (code.classList.contains("lang-mathjax") - || code.classList.contains("language-mathjax"))) { - mathCodes.push(code); - } - } - } - - // Replace math codes with . - for (var i = mathCodes.length - 1; i >= 0; --i) { - var code = mathCodes[i]; - var pare = code.parentElement; - var xeqn = document.createElement('x-eqn'); - xeqn.classList.add("tex-to-render"); - xeqn.innerHTML = code.innerHTML; - pare.parentNode.replaceChild(xeqn, pare); - } -}; - -var addCopyButtonToCodeBlock = function() { - if (!VEnableCodeBlockCopyButton) { - return; - } - - var codes = document.getElementsByClassName(hljsClass); - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - var pare = code.parentElement; - pare.classList.add('vnote-snippet'); - - var btn = document.createElement('button'); - btn.innerHTML = '📋'; - btn.classList.add('vnote-btn'); - btn.classList.add('vnote-copy-clipboard-btn'); - btn.setAttribute('type', 'button'); - btn.setAttribute(VClipboardDataTextAttr, code.textContent); - code.insertAdjacentElement('beforebegin', btn); - } -}; - -var listContainsRegex = function(strs, exp) { - for (var i = 0, len = strs.length; i < len; ++i) { - if (exp.test(strs[i])) { - return true; - } - } - - return false; -}; - -var StylesToInline = null; - -var initStylesToInline = function() { - StylesToInline = new Map(); - - if (VStylesToInline.length == 0) { - return; - } - - var rules = VStylesToInline.split(','); - for (var i = 0; i < rules.length; ++i) { - var vals = rules[i].split('$'); - if (vals.length != 2) { - continue; - } - - var tags = vals[0].split(':'); - var pros = vals[1].split(':'); - for (var j = 0; j < tags.length; ++j) { - StylesToInline.set(tags[j].toLowerCase(), pros); - } - } -}; - -// Embed the CSS styles of @ele and all its children. -// StylesToInline need to be init before. -var embedInlineStyles = function(ele) { - var tagName = ele.tagName.toLowerCase(); - var props = StylesToInline.get(tagName); - if (!props) { - props = StylesToInline.get('all'); - - if (!props) { - return; - } - } - - // Embed itself. - var style = window.getComputedStyle(ele, null); - for (var i = 0; i < props.length; ++i) { - var pro = props[i]; - ele.style.setProperty(pro, style.getPropertyValue(pro)); - } - - // Embed children. - var children = ele.children; - for (var i = 0; i < children.length; ++i) { - embedInlineStyles(children[i]); - } -}; - -var getHtmlWithInlineStyles = function(container) { - if (!StylesToInline) { - initStylesToInline(); - } - - var children = container.children; - for (var i = 0; i < children.length; ++i) { - embedInlineStyles(children[i]); - } - - return container.innerHTML; -}; - -// Will be called after MathJax rendering finished. -// Make
    math
    to

    math

    -var postProcessMathJax = function() { - var all = Array.from(MathJax.startup.document.math); - for (var i = 0; i < all.length; ++i) { - var node = all[i].SourceElement().parentNode; - if (VRemoveMathjaxScript) { - // Remove the SourceElement. - try { - node.removeChild(all[i].SourceElement()); - } catch (err) { - content.setLog("err: " + err); - } - } - - if (node.tagName.toLowerCase() == 'code') { - var pre = node.parentNode; - var p = document.createElement('p'); - p.innerHTML = node.innerHTML; - pre.parentNode.replaceChild(p, pre); - } - } - - finishOneAsyncJob(); -}; - -function getNodeText(el) { - ret = ""; - var length = el.childNodes.length; - for(var i = 0; i < length; i++) { - var node = el.childNodes[i]; - if(node.nodeType != 8) { - ret += node.nodeType != 1 ? node.nodeValue : getNodeText(node); - } - } - - return ret; -} - -var calculateWordCount = function() { - var words = getNodeText(contentDiv); - - // Char without spaces. - var cns = 0; - var wc = 0; - var cc = words.length; - // 0 - not in word; - // 1 - in English word; - // 2 - in non-English word; - var state = 0; - - for (var i = 0; i < cc; ++i) { - var ch = words[i]; - if (/\s/.test(ch)) { - if (state != 0) { - state = 0; - } - - continue; - } else if (ch.charCodeAt() < 128) { - if (state != 1) { - state = 1; - ++wc; - } - } else { - state = 2; - ++wc; - } - - ++cns; - } - - content.updateWordCountInfo(wc, cns, cc); -}; - -// Whether it is a special code block, such as MathJax, Mermaid, or Flowchart. -var specialCodeBlock = function(lang) { - return (VEnableMathjax && lang == 'mathjax') - || (VEnableMermaid && lang == 'mermaid') - || (VEnableFlowchart && (lang == 'flowchart' || lang == 'flow')) - || (VPlantUMLMode != 0 && lang == 'puml') - || (VEnableGraphviz && lang == 'dot') - || (VEnableWavedrom && lang === 'wavedrom'); -}; - -var handlePlantUMLResult = function(id, timeStamp, format, result) { - handlePlantUMLResultExt(id, timeStamp, format, result, true); -}; - -var handlePlantUMLResultExt = function(id, timeStamp, format, result, isSetupView) { - var code = document.getElementsByClassName(plantUMLCodeClass + id)[0]; - if (code && result.length > 0) { - var obj = null; - if (format == 'svg') { - obj = document.createElement('div'); - obj.classList.add(VPlantUMLDivClass); - obj.innerHTML = result; - if (isSetupView) { - setupSVGToView(obj.children[0], true); - } - } else { - obj = document.createElement('img'); - obj.src = "data:image/" + format + ";base64, " + result; - if (isSetupView) { - setupIMGToView(obj); - } - } - - var preNode = code.parentNode; - preNode.parentNode.replaceChild(obj, preNode); - } - - finishOneAsyncJob(); -}; - -var handleGraphvizResult = function(id, timeStamp, format, result) { - var code = document.getElementsByClassName(graphvizCodeClass + id)[0]; - if (code && result.length > 0) { - var obj = null; - if (format == 'svg') { - obj = document.createElement('p'); - obj.innerHTML = result; - setupSVGToView(obj.children[0]); - } else { - obj = document.createElement('img'); - obj.src = "data:image/" + format + ";base64, " + result; - setupIMGToView(obj); - } - - var preNode = code.parentNode; - preNode.parentNode.replaceChild(obj, preNode); - } - - finishOneAsyncJob(); -}; - -var setPreviewEnabled = function(enabled) { - var hint = '
    ' + - '

    Live Preview for Graphs

    ' + - '

    Place the cursor on the definition of a graph to preview.

    ' + - '
    '; - - if (enabled) { - contentDiv.style.display = 'none'; - previewDiv.style.display = 'block'; - previewDiv.innerHTML = hint; - } else { - contentDiv.style.display = 'block'; - previewDiv.style.display = 'none'; - previewDiv.innerHTML = ''; - } - - VPreviewMode = enabled; - - clearMarkRectDivs(); -}; - -var previewCodeBlock = function(id, lang, text, isLivePreview) { - var div = isLivePreview ? previewDiv : inplacePreviewDiv; - div.innerHTML = ''; - div.className = ''; - - if (text.length == 0 - || (lang != 'flow' - && lang != 'flowchart' - && lang != 'mermaid' - && lang != 'wavedrom' - && (lang != 'puml' || VPlantUMLMode != 1 || !isLivePreview))) { - return; - } - - var pre = document.createElement('pre'); - var code = document.createElement('code'); - code.textContent = text; - - pre.appendChild(code); - div.appendChild(pre); - - if (lang == 'flow' || lang == 'flowchart') { - renderFlowchartOne(code); - } else if (lang == 'mermaid') { - renderMermaidOne(code); - } else if (lang == 'wavedrom') { - renderWavedromOne(code); - } else if (lang == 'puml') { - renderPlantUMLOneOnline(code); - } - - if (!isLivePreview) { - var children = div.children; - if (children.length > 0) { - content.previewCodeBlockCB(id, lang, children[0].innerHTML); - } - - div.innerHTML = ''; - div.className = ''; - } -}; - -var setPreviewContent = function(lang, html) { - previewDiv.innerHTML = html; - - // Treat plantUML and graphviz the same. - if (lang == "puml" || lang == "dot") { - previewDiv.classList = VPlantUMLDivClass; - } else { - previewDiv.className = ''; - } -}; - -var htmlToText = function(identifier, id, timeStamp, html) { - var splitString = function(str) { - var result = { leadingSpaces: '', - content: '', - trailingSpaces: '' - }; - if (!str) { - return result; - } - - var lRe = /^\s+/; - var ret = lRe.exec(str); - if (ret) { - result.leadingSpaces = ret[0]; - if (result.leadingSpaces.length == str.length) { - return result; - } - } - - var tRe = /\s+$/; - ret = tRe.exec(str); - if (ret) { - result.trailingSpaces = ret[0]; - } - - result.content = str.slice(result.leadingSpaces.length, - str.length - result.trailingSpaces.length); - return result; - }; - - turndownPluginGfm.options.autoHead = true; - - var ts = new TurndownService({ headingStyle: 'atx', - bulletListMarker: '-', - emDelimiter: '*', - hr: '***', - codeBlockStyle: 'fenced', - blankReplacement: function(content, node) { - if (node.nodeName == 'SPAN') { - return content; - } - - return node.isBlock ? '\n\n' : '' - } - }); - ts.use(turndownPluginGfm.gfm); - - ts.addRule('emspan', { - filter: 'span', - replacement: function(content, node, options) { - if (node.style.fontWeight == 'bold') { - var con = splitString(content); - if (!con.content) { - return content; - } - - return con.leadingSpaces + options.strongDelimiter - + con.content - + options.strongDelimiter + con.trailingSpaces; - } else if (node.style.fontStyle == 'italic') { - var con = splitString(content); - if (!con.content) { - return content; - } - - return con.leadingSpaces + options.emDelimiter - + con.content - + options.emDelimiter + con.trailingSpaces; - } else { - return content; - } - } - }); - ts.addRule('mark', { - filter: 'mark', - replacement: function(content, node, options) { - if (!content) { - return ''; - } - - return '' + content + ''; - } - }); - ts.addRule('emphasis_fix', { - filter: ['em', 'i'], - replacement: function (content, node, options) { - var con = splitString(content); - if (!con.content) { - return content; - } - - return con.leadingSpaces + options.emDelimiter - + con.content - + options.emDelimiter + con.trailingSpaces; - } - }); - ts.addRule('strong_fix', { - filter: ['strong', 'b'], - replacement: function (content, node, options) { - var con = splitString(content); - if (!con.content) { - return content; - } - - return con.leadingSpaces + options.strongDelimiter - + con.content - + options.strongDelimiter + con.trailingSpaces; - } - }); - - ts.remove(['head', 'style']); - - var subEnabled = false, supEnabled = false; - if (typeof VMarkdownitOption != "undefined") { - subEnabled = VMarkdownitOption.sub; - supEnabled = VMarkdownitOption.sup; - } - - ts.addRule('sub_fix', { - filter: 'sub', - replacement: function (content, node, options) { - if (!content) { - return ''; - } - - if (subEnabled) { - return '~' + content + '~'; - } else { - return '' + content + ''; - } - } - }); - - ts.addRule('sup_fix', { - filter: 'sup', - replacement: function (content, node, options) { - if (!content) { - return ''; - } - - if (supEnabled) { - return '^' + content + '^'; - } else { - return '' + content + ''; - } - } - }); - - ts.addRule('img_fix', { - filter: 'img', - replacement: function (content, node) { - var alt = node.alt || ''; - if (/[\r\n\[\]]/g.test(alt)) { - alt= ''; - } - - var src = node.getAttribute('src') || ''; - - var title = node.title || ''; - if (/[\r\n\)"]/g.test(title)) { - title = ''; - } - - var titlePart = title ? ' "' + title + '"' : ''; - return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : '' - } - }); - - var markdown = ts.turndown(html); - content.htmlToTextCB(identifier, id, timeStamp, markdown); -}; - -var printRect = function(rect) { - content.setLog('rect ' + rect.left + ' ' + rect.top + ' ' + rect.width + ' ' + rect.height); -}; - -var performSmartLivePreview = function(lang, text, hints, isRegex) { - if (previewDiv.style.display == 'none' - || document.getSelection().type == 'Range') { - return; - } - - if (lang != 'puml') { - return; - } - - var previewNode = previewDiv; - - // Accessing contentDocument will fail due to crossing orgin. - - // PlantUML. - var targetNode = null; - if (hints.indexOf('id') >= 0) { - // isRegex is ignored. - var result = findNodeWithText(previewNode, - text, - function (node, text) { - if (node.id && node.id == text) { - var res = { stop: true, - node: { node: node, - diff: 0 - } - }; - return res; - } - - return null; - }); - targetNode = result.node; - } - - if (!targetNode) { - var result; - if (isRegex) { - var nodeReg = new RegExp(text); - result = findNodeWithText(previewNode, - text, - function(node, text) { - var se = nodeReg.exec(node.textContent); - if (!se) { - return null; - } - - var diff = node.textContent.length - se[0].length; - var res = { stop: diff == 0, - node: { node: node, - diff: diff - } - }; - return res; - }); - } else { - result = findNodeWithText(previewNode, - text, - function(node, text) { - var idx = node.textContent.indexOf(text); - if (idx < 0) { - return null; - } - - var diff = node.textContent.length - text.length; - var res = { stop: diff == 0, - node: { node: node, - diff: diff - } - }; - return res; - }); - } - - targetNode = result.node; - } - - if (!targetNode) { - return; - } - - // (left, top) is relative to the viewport. - // Should add window.scrollX and window.scrollY to get the real content offset. - var trect = targetNode.getBoundingClientRect(); - - var vrect = { - left: document.documentElement.scrollLeft || document.body.scrollLeft || window.pageXOffset, - top: document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset, - width: document.documentElement.clientWidth || document.body.clientWidth, - height: document.documentElement.clientHeight || document.body.clientHeight - }; - - // Target node rect in the content. - var nrect = { - left: vrect.left + trect.left, - top: vrect.top + trect.top, - width: trect.width, - height: trect.height - }; - - var dx = 0, dy = 0; - - // If target is already in, do not scroll. - if (trect.left < 0 - || trect.left + trect.width > vrect.width) { - if (trect.width >= vrect.width) { - dx = trect.left; - } else { - dx = trect.left - (vrect.width - trect.width) / 2; - } - } - - if (trect.top < 0 - || trect.top + trect.height > vrect.height) { - if (trect.height >= vrect.height) { - dy = trect.top; - } else { - dy = trect.top - (vrect.height - trect.height) / 2; - } - } - - window.scrollBy(dx, dy); - - markNode(nrect); -} - -// isMatched() should return a strut or null: -// - null to indicates a mismatch; -// - { stop: whether continue search, -// node: { node: the matched node, -// diff: a value indicates the match quality (the lower the better) -// } -// } -var findNodeWithText = function(node, text, isMatched) { - var result = { - node: null, - diff: 999999 - }; - - findNodeWithTextInternal(node, text, isMatched, result); - return result; -} - -// Return true to stop search. -var findNodeWithTextInternal = function(node, text, isMatched, result) { - var children = node.children; - if (children.length > 0) { - for (var i = 0; i < children.length; ++i) { - var ret = findNodeWithTextInternal(children[i], text, isMatched, result); - if (ret) { - return ret; - } - } - } - - var res = isMatched(node, text); - if (res) { - if (res.node.diff < result.diff) { - result.node = res.node.node; - result.diff = res.node.diff; - } - - return res.stop; - } - - return false; -} - -// Draw a rectangle to mark @rect. -var markNode = function(rect) { - clearMarkRectDivs(); - - if (!rect) { - return; - } - - var div = document.createElement('div'); - div.id = 'markrect_' + Date.now(); - div.classList.add(VMarkRectDivClass); - - document.body.appendChild(div); - - var extraW = 8; - var extraH = 5; - div.style.left = (rect.left - extraW) + 'px'; - div.style.top = (rect.top - extraH) + 'px'; - div.style.width = (rect.width + extraW) + 'px'; - div.style.height = rect.height + 'px'; - - setTimeout('var node = document.getElementById("' + div.id + '");' - + 'if (node) { node.outerHTML = ""; delete node; }', - 3000); -}; - -var clearMarkRectDivs = function() { - var nodes = document.getElementsByClassName(VMarkRectDivClass); - while (nodes.length > 0) { - var n = nodes[0]; - n.outerHTML = ''; - delete n; - } -}; - -// Clean up before a fresh render. -var startFreshRender = function() { - skipScrollCheckRange = null; -}; diff --git a/src/resources/marked.js b/src/resources/marked.js deleted file mode 100644 index af010708..00000000 --- a/src/resources/marked.js +++ /dev/null @@ -1,112 +0,0 @@ -var renderer = new marked.Renderer(); -var toc = []; // Table of contents as a list -var nameCounter = 0; - -var VRenderer = 'marked'; - -renderer.heading = function(text, level) { - // Use number to avoid issues with Chinese - var escapedText = 'toc_' + nameCounter++; - var textHtml = escapeHtml(text); - toc.push({ - level: level, - anchor: escapedText, - title: textHtml - }); - return '' + textHtml + ''; -}; - -// Highlight.js to highlight code block -marked.setOptions({ - highlight: function(code, lang) { - if (lang && (!specialCodeBlock(lang) || highlightSpecialBlocks)) { - if (lang === 'wavedrom') { - lang = 'json'; - } - - if (hljs.getLanguage(lang)) { - return hljs.highlight(lang, code, true).value; - } else { - return hljs.highlightAuto(code).value; - } - } else { - return code; - } - } -}); - -var markdownToHtml = function(markdown, needToc) { - toc = []; - nameCounter = 0; - var html = marked(markdown, { renderer: renderer }); - if (needToc) { - return html.replace(/

    \[TOC\]<\/p>/ig, '

    '); - } else { - return html; - } -}; - -var mdHasTocSection = function(markdown) { - var n = markdown.search(/(\n|^)\[toc\]/i); - return n != -1; -}; - -var updateText = function(text) { - if (VAddTOC) { - text = "[TOC]\n\n" + text; - } - - startFreshRender(); - - // There is at least one async job for MathJax. - asyncJobsCount = 1; - - var needToc = mdHasTocSection(text); - var html = markdownToHtml(text, needToc); - contentDiv.innerHTML = html; - handleToc(needToc); - insertImageCaption(); - setupImageView(); - renderMermaid('language-mermaid'); - renderFlowchart(['language-flowchart', 'language-flow']); - renderWavedrom('language-wavedrom'); - renderPlantUML('language-puml'); - renderGraphviz('language-dot'); - addClassToCodeBlock(); - addCopyButtonToCodeBlock(); - renderCodeBlockLineNumber(); - - // If you add new logics after handling MathJax, please pay attention to - // finishLoading logic. - if (VEnableMathjax) { - MathJax.texReset(); - MathJax - .typesetPromise([contentDiv]) - .then(postProcessMathJax) - .catch(function (err) { - content.setLog("err: " + err); - finishOneAsyncJob(); - }); - } else { - finishOneAsyncJob(); - } -}; - -var highlightText = function(text, id, timeStamp) { - highlightSpecialBlocks = true; - var html = marked(text); - highlightSpecialBlocks = false; - content.highlightTextCB(html, id, timeStamp); -} - -var textToHtml = function(identifier, id, timeStamp, text, inlineStyle) { - var html = marked(text); - if (inlineStyle) { - var container = textHtmlDiv; - container.innerHTML = html; - html = getHtmlWithInlineStyles(container); - container.innerHTML = ""; - } - - content.textToHtmlCB(identifier, id, timeStamp, html); -} diff --git a/src/resources/mathjax_preview.js b/src/resources/mathjax_preview.js deleted file mode 100644 index 017280e3..00000000 --- a/src/resources/mathjax_preview.js +++ /dev/null @@ -1,269 +0,0 @@ -var channelInitialized = false; - -var contentDiv = document.getElementById('content-div'); - -var content; - -var VMermaidDivClass = 'mermaid-diagram'; -var VFlowchartDivClass = 'flowchart-diagram'; -var VWavedromDivClass = 'wavedrom-diagram'; -var VPlantUMLDivClass = 'plantuml-diagram'; - -if (typeof VPlantUMLServer == 'undefined') { - VPlantUMLServer = 'http://www.plantuml.com/plantuml'; -} - -new QWebChannel(qt.webChannelTransport, - function(channel) { - content = channel.objects.content; - - content.requestPreviewMathJax.connect(previewMathJax); - content.requestPreviewDiagram.connect(previewDiagram); - - channelInitialized = true; - }); - -var timeStamps = new Map(); - -var htmlToElement = function(html) { - var template = document.createElement('template'); - html = html.trim(); - template.innerHTML = html; - return template.content.firstChild; -}; - -var isEmptyMathJax = function(text) { - return text.replace(/\$/g, '').trim().length == 0; -}; - -var previewMathJax = function(identifier, id, timeStamp, text, isHtml) { - timeStamps.set(identifier, timeStamp); - - if (isEmptyMathJax(text)) { - content.mathjaxResultReady(identifier, id, timeStamp, 'png', ''); - return; - } - - var p = null; - if (isHtml) { - p = htmlToElement(text); - if (isEmptyMathJax(p.textContent)) { - p = null; - } else if (p.tagName.toLowerCase() != 'p') { - // Need to wrap it in a

    , or domtoimage won't work. - var tp = document.createElement('p'); - tp.appendChild(p); - p = tp; - } - } else { - p = document.createElement('p'); - p.textContent = text; - } - - if (!p) { - content.mathjaxResultReady(identifier, id, timeStamp, 'png', ''); - return; - } - - contentDiv.appendChild(p); - - var isBlock = false; - if (text.indexOf('$$') !== -1) { - isBlock = true; - } - MathJax.texReset(); - MathJax - .typesetPromise([p]) - .then(function () { - postProcessMathJax(identifier, id, timeStamp, p, isBlock); - }).catch(function (err) { - content.setLog("err: " + err); - content.mathjaxResultReady(identifier, id, timeStamp, 'png', ''); - contentDiv.removeChild(p); - delete p; - }); -}; - -var postProcessMathJax = function(identifier, id, timeStamp, container, isBlock) { - if (timeStamps.get(identifier) != timeStamp) { - contentDiv.removeChild(container); - delete container; - return; - } - - var hei = container.clientHeight * 1.5 + (isBlock ? 20 : 5); - domtoimage.toPng(container, { height: hei }).then(function (dataUrl) { - var png = dataUrl.substring(dataUrl.indexOf(',') + 1); - content.mathjaxResultReady(identifier, id, timeStamp, 'png', png); - - contentDiv.removeChild(container); - delete container; - }).catch(function (err) { - content.setLog("err: " + err); - content.mathjaxResultReady(identifier, id, timeStamp, 'png', ''); - contentDiv.removeChild(container); - delete container; - }); -}; - -var mermaidIdx = 0; - -var flowchartIdx = 0; - -var wavedromIdx = 0; - -var previewDiagram = function(identifier, id, timeStamp, lang, text) { - if (text.length == 0) { - return; - } - - var div = null; - if (lang == 'flow' || lang == 'flowchart') { - div = renderFlowchartOne(identifier, id, timeStamp, text); - } else if (lang === 'wavedrom') { - div = renderWavedromOne(identifier, id, timeStamp, text); - } else if (lang == 'mermaid') { - div = renderMermaidOne(identifier, id, timeStamp, text); - } else if (lang == 'puml') { - renderPlantUMLOne(identifier, id, timeStamp, text); - return; - } - - if (!div) { - content.diagramResultReady(identifier, id, timeStamp, 'png', ''); - return; - } - - // For Flowchart.js, we need to add addtitional height. - var dtiOpt = {}; - if (lang == 'flow' || lang == 'flowchart') { - dtiOpt = { height: div.clientHeight + 30 }; - } - - domtoimage.toPng(div, dtiOpt).then(function (dataUrl) { - var png = dataUrl.substring(dataUrl.indexOf(',') + 1); - content.diagramResultReady(identifier, id, timeStamp, 'png', png); - - contentDiv.removeChild(div); - delete div; - }).catch(function (err) { - content.setLog("err: " + err); - contentDiv.removeChild(div); - content.diagramResultReady(identifier, id, timeStamp, 'png', ''); - delete div; - }); -}; - -var renderMermaidOne = function(identifier, id, timeStamp, text) { - mermaidIdx++; - try { - // Do not increment mermaidIdx here. - var graph = mermaid.render('mermaid-diagram-' + mermaidIdx, - text, - function(){}); - } catch (err) { - content.setLog("err: " + err); - // Clean the container element, or mermaid won't render the graph with - // the same id. - var errGraph = document.getElementById('mermaid-diagram-' + mermaidIdx); - if (errGraph) { - var parentNode = errGraph.parentElement; - parentNode.outerHTML = ''; - delete parentNode; - } - return null; - } - - if (typeof graph == "undefined") { - return null; - } - - var div = document.createElement('div'); - div.classList.add(VMermaidDivClass); - div.innerHTML = graph; - contentDiv.appendChild(div); - return div; -}; - -var renderFlowchartOne = function(identifier, id, timeStamp, text) { - flowchartIdx++; - try { - var graph = flowchart.parse(text); - } catch (err) { - content.setLog("err: " + err); - return null; - } - - if (typeof graph == "undefined") { - return null; - } - - var div = document.createElement('div'); - div.id = 'flowchart-diagram-' + flowchartIdx; - div.classList.add(VFlowchartDivClass); - - contentDiv.appendChild(div); - - // Draw on it after adding it to page. - try { - graph.drawSVG(div.id); - } catch (err) { - content.setLog("err: " + err); - contentDiv.removeChild(div); - delete div; - return null; - } - - return div; -}; - -var renderWavedromOne = function(identifier, id, timeStamp, text) { - // Create a script element. - var script = document.createElement('script'); - script.setAttribute('type', 'WaveDrom'); - script.textContent = text; - script.setAttribute('id', 'WaveDrom_JSON_' + wavedromIdx); - - contentDiv.appendChild(script); - - // Create a div element. - var div = document.createElement('div'); - div.setAttribute('id', 'WaveDrom_Display_' + wavedromIdx); - div.classList.add(VWavedromDivClass); - script.insertAdjacentElement('afterend', div); - - try { - WaveDrom.RenderWaveForm(wavedromIdx, - WaveDrom.eva(script.getAttribute('id')), - 'WaveDrom_Display_'); - } catch (err) { - content.setLog("err: " + err); - contentDiv.removeChild(script); - contentDiv.removeChild(div); - wavedromIdx++; - return null; - } - - contentDiv.removeChild(script); - wavedromIdx++; - return div; -}; - -var renderPlantUMLOne = function(identifier, id, timeStamp, text) { - var data = { identifier: identifier, - id: id, - timeStamp: timeStamp - }; - - renderPlantUMLOnline(VPlantUMLServer, - 'svg', - text, - function(data, format, result) { - content.diagramResultReady(data.identifier, - data.id, - data.timeStamp, - format, - result); - }, - data); -}; diff --git a/src/resources/mathjax_preview_template.html b/src/resources/mathjax_preview_template.html deleted file mode 100644 index da07a7ee..00000000 --- a/src/resources/mathjax_preview_template.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - -

    - - diff --git a/src/resources/qwebchannel.js b/src/resources/qwebchannel.js deleted file mode 100644 index 1d84b8e7..00000000 --- a/src/resources/qwebchannel.js +++ /dev/null @@ -1,430 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebChannel module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "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. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** 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 -** OWNER 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." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -"use strict"; - -var QWebChannelMessageTypes = { - signal: 1, - propertyUpdate: 2, - init: 3, - idle: 4, - debug: 5, - invokeMethod: 6, - connectToSignal: 7, - disconnectFromSignal: 8, - setProperty: 9, - response: 10, -}; - -var QWebChannel = function(transport, initCallback) -{ - if (typeof transport !== "object" || typeof transport.send !== "function") { - console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." + - " Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send)); - return; - } - - var channel = this; - this.transport = transport; - - this.send = function(data) - { - if (typeof(data) !== "string") { - data = JSON.stringify(data); - } - channel.transport.send(data); - } - - this.transport.onmessage = function(message) - { - var data = message.data; - if (typeof data === "string") { - data = JSON.parse(data); - } - switch (data.type) { - case QWebChannelMessageTypes.signal: - channel.handleSignal(data); - break; - case QWebChannelMessageTypes.response: - channel.handleResponse(data); - break; - case QWebChannelMessageTypes.propertyUpdate: - channel.handlePropertyUpdate(data); - break; - default: - console.error("invalid message received:", message.data); - break; - } - } - - this.execCallbacks = {}; - this.execId = 0; - this.exec = function(data, callback) - { - if (!callback) { - // if no callback is given, send directly - channel.send(data); - return; - } - if (channel.execId === Number.MAX_VALUE) { - // wrap - channel.execId = Number.MIN_VALUE; - } - if (data.hasOwnProperty("id")) { - console.error("Cannot exec message with property id: " + JSON.stringify(data)); - return; - } - data.id = channel.execId++; - channel.execCallbacks[data.id] = callback; - channel.send(data); - }; - - this.objects = {}; - - this.handleSignal = function(message) - { - var object = channel.objects[message.object]; - if (object) { - object.signalEmitted(message.signal, message.args); - } else { - console.warn("Unhandled signal: " + message.object + "::" + message.signal); - } - } - - this.handleResponse = function(message) - { - if (!message.hasOwnProperty("id")) { - console.error("Invalid response message received: ", JSON.stringify(message)); - return; - } - channel.execCallbacks[message.id](message.data); - delete channel.execCallbacks[message.id]; - } - - this.handlePropertyUpdate = function(message) - { - for (var i in message.data) { - var data = message.data[i]; - var object = channel.objects[data.object]; - if (object) { - object.propertyUpdate(data.signals, data.properties); - } else { - console.warn("Unhandled property update: " + data.object + "::" + data.signal); - } - } - channel.exec({type: QWebChannelMessageTypes.idle}); - } - - this.debug = function(message) - { - channel.send({type: QWebChannelMessageTypes.debug, data: message}); - }; - - channel.exec({type: QWebChannelMessageTypes.init}, function(data) { - for (var objectName in data) { - var object = new QObject(objectName, data[objectName], channel); - } - // now unwrap properties, which might reference other registered objects - for (var objectName in channel.objects) { - channel.objects[objectName].unwrapProperties(); - } - if (initCallback) { - initCallback(channel); - } - channel.exec({type: QWebChannelMessageTypes.idle}); - }); -}; - -function QObject(name, data, webChannel) -{ - this.__id__ = name; - webChannel.objects[name] = this; - - // List of callbacks that get invoked upon signal emission - this.__objectSignals__ = {}; - - // Cache of all properties, updated when a notify signal is emitted - this.__propertyCache__ = {}; - - var object = this; - - // ---------------------------------------------------------------------- - - this.unwrapQObject = function(response) - { - if (response instanceof Array) { - // support list of objects - var ret = new Array(response.length); - for (var i = 0; i < response.length; ++i) { - ret[i] = object.unwrapQObject(response[i]); - } - return ret; - } - if (!response - || !response["__QObject*__"] - || response.id === undefined) { - return response; - } - - var objectId = response.id; - if (webChannel.objects[objectId]) - return webChannel.objects[objectId]; - - if (!response.data) { - console.error("Cannot unwrap unknown QObject " + objectId + " without data."); - return; - } - - var qObject = new QObject( objectId, response.data, webChannel ); - qObject.destroyed.connect(function() { - if (webChannel.objects[objectId] === qObject) { - delete webChannel.objects[objectId]; - // reset the now deleted QObject to an empty {} object - // just assigning {} though would not have the desired effect, but the - // below also ensures all external references will see the empty map - // NOTE: this detour is necessary to workaround QTBUG-40021 - var propertyNames = []; - for (var propertyName in qObject) { - propertyNames.push(propertyName); - } - for (var idx in propertyNames) { - delete qObject[propertyNames[idx]]; - } - } - }); - // here we are already initialized, and thus must directly unwrap the properties - qObject.unwrapProperties(); - return qObject; - } - - this.unwrapProperties = function() - { - for (var propertyIdx in object.__propertyCache__) { - object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]); - } - } - - function addSignal(signalData, isPropertyNotifySignal) - { - var signalName = signalData[0]; - var signalIndex = signalData[1]; - object[signalName] = { - connect: function(callback) { - if (typeof(callback) !== "function") { - console.error("Bad callback given to connect to signal " + signalName); - return; - } - - object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || []; - object.__objectSignals__[signalIndex].push(callback); - - if (!isPropertyNotifySignal && signalName !== "destroyed") { - // only required for "pure" signals, handled separately for properties in propertyUpdate - // also note that we always get notified about the destroyed signal - webChannel.exec({ - type: QWebChannelMessageTypes.connectToSignal, - object: object.__id__, - signal: signalIndex - }); - } - }, - disconnect: function(callback) { - if (typeof(callback) !== "function") { - console.error("Bad callback given to disconnect from signal " + signalName); - return; - } - object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || []; - var idx = object.__objectSignals__[signalIndex].indexOf(callback); - if (idx === -1) { - console.error("Cannot find connection of signal " + signalName + " to " + callback.name); - return; - } - object.__objectSignals__[signalIndex].splice(idx, 1); - if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) { - // only required for "pure" signals, handled separately for properties in propertyUpdate - webChannel.exec({ - type: QWebChannelMessageTypes.disconnectFromSignal, - object: object.__id__, - signal: signalIndex - }); - } - } - }; - } - - /** - * Invokes all callbacks for the given signalname. Also works for property notify callbacks. - */ - function invokeSignalCallbacks(signalName, signalArgs) - { - var connections = object.__objectSignals__[signalName]; - if (connections) { - connections.forEach(function(callback) { - callback.apply(callback, signalArgs); - }); - } - } - - this.propertyUpdate = function(signals, propertyMap) - { - // update property cache - for (var propertyIndex in propertyMap) { - var propertyValue = propertyMap[propertyIndex]; - object.__propertyCache__[propertyIndex] = propertyValue; - } - - for (var signalName in signals) { - // Invoke all callbacks, as signalEmitted() does not. This ensures the - // property cache is updated before the callbacks are invoked. - invokeSignalCallbacks(signalName, signals[signalName]); - } - } - - this.signalEmitted = function(signalName, signalArgs) - { - invokeSignalCallbacks(signalName, signalArgs); - } - - function addMethod(methodData) - { - var methodName = methodData[0]; - var methodIdx = methodData[1]; - object[methodName] = function() { - var args = []; - var callback; - for (var i = 0; i < arguments.length; ++i) { - if (typeof arguments[i] === "function") - callback = arguments[i]; - else - args.push(arguments[i]); - } - - webChannel.exec({ - "type": QWebChannelMessageTypes.invokeMethod, - "object": object.__id__, - "method": methodIdx, - "args": args - }, function(response) { - if (response !== undefined) { - var result = object.unwrapQObject(response); - if (callback) { - (callback)(result); - } - } - }); - }; - } - - function bindGetterSetter(propertyInfo) - { - var propertyIndex = propertyInfo[0]; - var propertyName = propertyInfo[1]; - var notifySignalData = propertyInfo[2]; - // initialize property cache with current value - // NOTE: if this is an object, it is not directly unwrapped as it might - // reference other QObject that we do not know yet - object.__propertyCache__[propertyIndex] = propertyInfo[3]; - - if (notifySignalData) { - if (notifySignalData[0] === 1) { - // signal name is optimized away, reconstruct the actual name - notifySignalData[0] = propertyName + "Changed"; - } - addSignal(notifySignalData, true); - } - - Object.defineProperty(object, propertyName, { - configurable: true, - get: function () { - var propertyValue = object.__propertyCache__[propertyIndex]; - if (propertyValue === undefined) { - // This shouldn't happen - console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__); - } - - return propertyValue; - }, - set: function(value) { - if (value === undefined) { - console.warn("Property setter for " + propertyName + " called with undefined value!"); - return; - } - object.__propertyCache__[propertyIndex] = value; - webChannel.exec({ - "type": QWebChannelMessageTypes.setProperty, - "object": object.__id__, - "property": propertyIndex, - "value": value - }); - } - }); - - } - - // ---------------------------------------------------------------------- - - data.methods.forEach(addMethod); - - data.properties.forEach(bindGetterSetter); - - data.signals.forEach(function(signal) { addSignal(signal, false); }); - - for (var name in data.enums) { - object[name] = data.enums[name]; - } -} - -//required for use with nodejs -if (typeof module === 'object') { - module.exports = { - QWebChannel: QWebChannel - }; -} diff --git a/src/resources/showdown.js b/src/resources/showdown.js deleted file mode 100644 index 1a22e8f7..00000000 --- a/src/resources/showdown.js +++ /dev/null @@ -1,183 +0,0 @@ -var VRenderer = 'showdown'; - -var renderer = new showdown.Converter({simplifiedAutoLink: 'true', - excludeTrailingPunctuationFromURLs: 'true', - strikethrough: 'true', - tables: 'true', - tasklists: 'true', - literalMidWordUnderscores: 'true', - extensions: ['headinganchor'] - }); - -var toc = []; // Table of contents as a list - -// Parse the html's headings and construct toc[]. -var parseHeadings = function(html) { - toc = []; - var parser = new DOMParser(); - var htmlDoc = parser.parseFromString(html, 'text/html'); - var eles = htmlDoc.querySelectorAll("h1, h2, h3, h4, h5, h6"); - - for (var i = 0; i < eles.length; ++i) { - var ele = eles[i]; - var level = parseInt(ele.tagName.substr(1)); - - toc.push({ - level: level, - anchor: ele.id, - title: escapeHtml(ele.textContent) - }); - } - - delete parser; -}; - -var markdownToHtml = function(markdown, needToc) { - var html = renderer.makeHtml(markdown); - - // Parse the html to init toc[]. - parseHeadings(html); - - if (needToc) { - return html.replace(/

    \[TOC\]<\/p>/ig, '

    '); - } else { - return html; - } -}; - -var mdHasTocSection = function(markdown) { - var n = markdown.search(/(\n|^)\[toc\]/i); - return n != -1; -}; - -var highlightCodeBlocks = function(doc, - enableMermaid, - enableFlowchart, - enableWavedrom, - enableMathJax, - enablePlantUML, - enableGraphviz) { - var codes = doc.getElementsByTagName('code'); - for (var i = 0; i < codes.length; ++i) { - var code = codes[i]; - if (code.parentElement.tagName.toLowerCase() == 'pre') { - if (code.classList.contains('language-wavedrom')) { - if (enableWavedrom) { - continue; - } else { - code.classList.remove('language-wavedrom'); - code.classList.add('language-json'); - } - } - - if (enableMermaid && code.classList.contains('language-mermaid')) { - // Mermaid code block. - continue; - } else if (enableFlowchart - && (code.classList.contains('language-flowchart') - || code.classList.contains('language-flow'))) { - // Flowchart code block. - continue; - } else if (enableWavedrom && code.classList.contains('language-wavedrom')) { - // Wavedrom code block. - continue; - } else if (enableMathJax && code.classList.contains('language-mathjax')) { - // MathJax code block. - continue; - } else if (enablePlantUML && code.classList.contains('language-puml')) { - // PlantUML code block. - continue; - } else if (enableGraphviz && code.classList.contains('language-dot')) { - // Graphviz code block. - continue; - } - - if (listContainsRegex(code.classList, /language-.*/)) { - hljs.highlightBlock(code); - } - } - } -}; - -var updateText = function(text) { - if (VAddTOC) { - text = "[TOC]\n\n" + text; - } - - startFreshRender(); - - // There is at least one async job for MathJax. - asyncJobsCount = 1; - - var needToc = mdHasTocSection(text); - var html = markdownToHtml(text, needToc); - contentDiv.innerHTML = html; - handleToc(needToc); - insertImageCaption(); - setupImageView(); - highlightCodeBlocks(document, - VEnableMermaid, - VEnableFlowchart, - VEnableWavedrom, - VEnableMathjax, - VPlantUMLMode != 0, - VEnableGraphviz); - renderMermaid('language-mermaid'); - renderFlowchart(['language-flowchart', 'language-flow']); - renderWavedrom('language-wavedrom'); - renderPlantUML('language-puml'); - renderGraphviz('language-dot'); - addClassToCodeBlock(); - addCopyButtonToCodeBlock(); - renderCodeBlockLineNumber(); - - // If you add new logics after handling MathJax, please pay attention to - // finishLoading logic. - if (VEnableMathjax) { - MathJax.texReset(); - MathJax - .typesetPromise([contentDiv]) - .then(postProcessMathJax) - .catch(function (err) { - content.setLog("err: " + err); - finishOneAsyncJob(); - }); - } else { - finishOneAsyncJob(); - } -}; - -var highlightText = function(text, id, timeStamp) { - var html = renderer.makeHtml(text); - - var parser = new DOMParser(); - var htmlDoc = parser.parseFromString("
    " + html + "
    ", 'text/html'); - highlightCodeBlocks(htmlDoc, false, false, false, false, false); - - html = htmlDoc.getElementById('showdown-container').innerHTML; - - delete parser; - - content.highlightTextCB(html, id, timeStamp); -} - -var textToHtml = function(identifier, id, timeStamp, text, inlineStyle) { - var html = renderer.makeHtml(text); - - var parser = new DOMParser(); - var htmlDoc = parser.parseFromString("
    " + html + "
    ", 'text/html'); - highlightCodeBlocks(htmlDoc, false, false, false, false, false); - - html = htmlDoc.getElementById('showdown-container').innerHTML; - - delete parser; - - if (inlineStyle) { - var container = textHtmlDiv; - container.innerHTML = html; - html = getHtmlWithInlineStyles(container); - container.innerHTML = ""; - } - - content.textToHtmlCB(identifier, id, timeStamp, html); -} diff --git a/src/resources/simple_template.html b/src/resources/simple_template.html deleted file mode 100644 index 16a31d7d..00000000 --- a/src/resources/simple_template.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/src/resources/themes/v_detorte/arrow_dropdown.svg b/src/resources/themes/v_detorte/arrow_dropdown.svg deleted file mode 100644 index 8a34dd3a..00000000 --- a/src/resources/themes/v_detorte/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_detorte/arrow_dropdown_disabled.svg b/src/resources/themes/v_detorte/arrow_dropdown_disabled.svg deleted file mode 100644 index 0cb3473f..00000000 --- a/src/resources/themes/v_detorte/arrow_dropdown_disabled.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_detorte/branch_closed.svg b/src/resources/themes/v_detorte/branch_closed.svg deleted file mode 100644 index 05c574c3..00000000 --- a/src/resources/themes/v_detorte/branch_closed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/branch_end.svg b/src/resources/themes/v_detorte/branch_end.svg deleted file mode 100644 index 176876b9..00000000 --- a/src/resources/themes/v_detorte/branch_end.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_detorte/branch_more.svg b/src/resources/themes/v_detorte/branch_more.svg deleted file mode 100644 index 3533019b..00000000 --- a/src/resources/themes/v_detorte/branch_more.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_detorte/branch_open.svg b/src/resources/themes/v_detorte/branch_open.svg deleted file mode 100644 index 7ad2a27c..00000000 --- a/src/resources/themes/v_detorte/branch_open.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/checkbox_checked.svg b/src/resources/themes/v_detorte/checkbox_checked.svg deleted file mode 100644 index 4b6956bf..00000000 --- a/src/resources/themes/v_detorte/checkbox_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_detorte/checkbox_checked_disabled.svg b/src/resources/themes/v_detorte/checkbox_checked_disabled.svg deleted file mode 100644 index 32f23968..00000000 --- a/src/resources/themes/v_detorte/checkbox_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_detorte/checkbox_unchecked.svg b/src/resources/themes/v_detorte/checkbox_unchecked.svg deleted file mode 100644 index e7cb1fa5..00000000 --- a/src/resources/themes/v_detorte/checkbox_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_detorte/checkbox_unchecked_disabled.svg b/src/resources/themes/v_detorte/checkbox_unchecked_disabled.svg deleted file mode 100644 index 8fe68498..00000000 --- a/src/resources/themes/v_detorte/checkbox_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_detorte/close.svg b/src/resources/themes/v_detorte/close.svg deleted file mode 100644 index 24c9694b..00000000 --- a/src/resources/themes/v_detorte/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_detorte/close_grey.svg b/src/resources/themes/v_detorte/close_grey.svg deleted file mode 100644 index 2c444084..00000000 --- a/src/resources/themes/v_detorte/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_detorte/down.svg b/src/resources/themes/v_detorte/down.svg deleted file mode 100644 index a2c7b0bf..00000000 --- a/src/resources/themes/v_detorte/down.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/down_disabled.svg b/src/resources/themes/v_detorte/down_disabled.svg deleted file mode 100644 index 1b75d32d..00000000 --- a/src/resources/themes/v_detorte/down_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/float.svg b/src/resources/themes/v_detorte/float.svg deleted file mode 100644 index ba96eefe..00000000 --- a/src/resources/themes/v_detorte/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_detorte/left.svg b/src/resources/themes/v_detorte/left.svg deleted file mode 100644 index 6f6626d9..00000000 --- a/src/resources/themes/v_detorte/left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/left_disabled.svg b/src/resources/themes/v_detorte/left_disabled.svg deleted file mode 100644 index e4974104..00000000 --- a/src/resources/themes/v_detorte/left_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/line.svg b/src/resources/themes/v_detorte/line.svg deleted file mode 100644 index a4f9b524..00000000 --- a/src/resources/themes/v_detorte/line.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 2 - - - diff --git a/src/resources/themes/v_detorte/menu_checkbox.svg b/src/resources/themes/v_detorte/menu_checkbox.svg deleted file mode 100644 index 4118811d..00000000 --- a/src/resources/themes/v_detorte/menu_checkbox.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_detorte/menu_radiobutton.svg b/src/resources/themes/v_detorte/menu_radiobutton.svg deleted file mode 100644 index fdcc1bbd..00000000 --- a/src/resources/themes/v_detorte/menu_radiobutton.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_detorte/radiobutton_checked.svg b/src/resources/themes/v_detorte/radiobutton_checked.svg deleted file mode 100644 index 486fde13..00000000 --- a/src/resources/themes/v_detorte/radiobutton_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_detorte/radiobutton_checked_disabled.svg b/src/resources/themes/v_detorte/radiobutton_checked_disabled.svg deleted file mode 100644 index 38191ad9..00000000 --- a/src/resources/themes/v_detorte/radiobutton_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_detorte/radiobutton_unchecked.svg b/src/resources/themes/v_detorte/radiobutton_unchecked.svg deleted file mode 100644 index 8e256997..00000000 --- a/src/resources/themes/v_detorte/radiobutton_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_detorte/radiobutton_unchecked_disabled.svg b/src/resources/themes/v_detorte/radiobutton_unchecked_disabled.svg deleted file mode 100644 index 0c3e3316..00000000 --- a/src/resources/themes/v_detorte/radiobutton_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_detorte/right.svg b/src/resources/themes/v_detorte/right.svg deleted file mode 100644 index 05c574c3..00000000 --- a/src/resources/themes/v_detorte/right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/right_disabled.svg b/src/resources/themes/v_detorte/right_disabled.svg deleted file mode 100644 index 8ee9e83c..00000000 --- a/src/resources/themes/v_detorte/right_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/up.svg b/src/resources/themes/v_detorte/up.svg deleted file mode 100644 index 89707ce2..00000000 --- a/src/resources/themes/v_detorte/up.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/up_disabled.svg b/src/resources/themes/v_detorte/up_disabled.svg deleted file mode 100644 index 6af13c38..00000000 --- a/src/resources/themes/v_detorte/up_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_detorte/v_detorte.css b/src/resources/themes/v_detorte/v_detorte.css deleted file mode 100644 index d77bd0e9..00000000 --- a/src/resources/themes/v_detorte/v_detorte.css +++ /dev/null @@ -1,357 +0,0 @@ -body { - margin: 0 auto; - font-family: "Segoe UI", Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Palatino, "Times New Roman", "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", Dengxian, "等线体", STXihei, "华文细黑", "Liberation Sans", "Droid Sans", NSimSun, "新宋体", SimSun, "宋体"; - color: #DADADA; - line-height: 1.5; - padding: 15px; - background: #444444; - font-size: 16px; -} - -h1, h2, h3, h4, h5, h6 { - color: #E0E0E0; - font-weight: bold; - margin-top: 20px; - margin-bottom: 10px; - padding: 0; -} - -p { - padding: 0; - margin-top: 16px; - margin-bottom: 16px; -} - -h1 { - font-size: 26px; -} - -h2 { - font-size: 24px; -} - -h3 { - font-size: 22px; -} - -h4 { - font-size: 20px; -} - -h5 { - font-size: 19px; -} - -h6 { - font-size: 18px; -} - -a { - color: #61AFEF; - margin: 0; - padding: 0; - vertical-align: baseline; - text-decoration: none; - word-break: break-word; -} - -a:hover { - text-decoration: underline; -} - -a:visited { - color: #BA68C8; -} - -ul, ol { - padding: 0; - padding-left: 24px; -} - -li { - line-height: 24px; -} - -li ul, li ol { - margin-left: 16px; -} - -p, ul, ol { - font-size: 16px; - line-height: 24px; -} - -mark { - color: #000000; - background-color: #D8D800; -} - -pre { - display: block; - overflow-y: hidden; - overflow-x: auto; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -code { - font-family: Consolas, Monaco, Monospace, Courier; - color: #98C379; - word-break: break-word; -} - -pre code { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #DADADA; - background-color: #4A4A4A; - border-left: .5em solid #865E1B; - line-height: 1.5; - font-family: Consolas, Monaco, Monospace, Courier; - white-space: pre; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -pre code.markdown-metadata { - border-left: .5em solid #D89F3E; -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - color: #BCBCBC; - background-color: #4A4A4A; - border-left: .5em solid #8A8A8A; - padding: 0 1em; - margin-left: 0; -} - -blockquote p { - color: #BCBCBC; -} - -hr { - display: block; - text-align: left; - margin: 1em 0; - border: none; - height: 2px; - background: #8A8A8A; -} - -table { - padding: 0; - margin: 1rem 0.5rem; - border-collapse: collapse; -} - -table tr { - border-top: 2px solid #8A8A8A; - margin: 0; - padding: 0; -} - -table tr th { - font-weight: bold; - border: 2px solid #8A8A8A; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 2px solid #8A8A8A; - margin: 0; - padding: 6px 13px; -} - -table tr th :first-child, table tr td :first-child { - margin-top: 0; -} - -table tr th :last-child, table tr td :last-child { - margin-bottom: 0; -} - -div.mermaid-diagram { - margin: 16px 0px 16px 0px; - overflow-y: hidden; - background: #949494; - color: #222222; -} - -div.flowchart-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; - background: #949494; - color: #222222; -} - -div.wavedrom-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; - background: #949494; - color: #222222; -} - -div.plantuml-diagram { - padding: 5px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; - background: #949494; - color: #222222; -} - -.img-package { - text-align: center; -} - -img.img-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -span.img-caption { - min-width: 20%; - max-width: 80%; - display: inline-block; - padding: 10px; - margin: 0 auto; - border-bottom: 1px solid #767676; - color: #BCBCBC; - text-align: center; - line-height: 1.5; -} - -.emoji_zero,.emoji_one,.emoji_two,.emoji_three,.emoji_four,.emoji_five,.emoji_six,.emoji_seven,.emoji_eight,.emoji_nine { - margin-left: 5px; - margin-right: 8px; -} - -div.preview-hint { - opacity: 0.5; - margin-top: 30%; - margin-bottom: 30%; - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; -} - -/* For Highlight.js Line Number */ -table.hljs-ln tr { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td.hljs-ln-numbers { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - text-align: center; - color: #767676; - border-right: 1px solid #767676; - vertical-align: top; - padding-right: 5px; - white-space: nowrap; -} - -table.hljs-ln tr td.hljs-ln-code { - padding-left: 10px; -} - -::-webkit-scrollbar { - background-color: #444444; - width: 14px; - height: 14px; - border: none; -} - -::-webkit-scrollbar-corner { - background-color: #444444; -} - -::-webkit-scrollbar-button { - /* This selector affects the styling of both the up & down and left & right buttons of a scrollbar */ - height: 14px; - width: 14px; - background-color: #444444; -} - -::-webkit-scrollbar-button:hover { - background-color: #666666; -} - -::-webkit-scrollbar-button:active { - background-color: #606060; -} - -::-webkit-scrollbar-track { - /* This selector affects the styling of the area in the scrollbar between the two buttons */ - background-color: #444444; -} - -::-webkit-scrollbar-thumb { - /* This selector affects the styling of draggable element of the scollbar */ - border: none; - background-color: #585858; -} - -::-webkit-scrollbar-thumb:hover { - background-color: #666666; -} - -::-webkit-scrollbar-thumb:active { - background-color: #606060; -} - -::-webkit-scrollbar-button:horizontal:increment { - background-image: url(right.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:horizontal:decrement { - background-image: url(left.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:increment { - background-image: url(down.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:decrement { - background-image: url(up.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::selection { - background: #8CBAE8; - color: #DADADA; -} diff --git a/src/resources/themes/v_detorte/v_detorte.mdhl b/src/resources/themes/v_detorte/v_detorte.mdhl deleted file mode 100644 index eda218a1..00000000 --- a/src/resources/themes/v_detorte/v_detorte.mdhl +++ /dev/null @@ -1,213 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Verdana, Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Times New Roman -font-size: 12 -foreground: dadada -background: 444444 -# [VNote] Style for trailing space -trailing-space: 666666 -# [VNote] Style for line number -line-number-background: 444444 -line-number-foreground: afaf5f -# [VNote] Style for selected word highlight -selected-word-foreground: 222222 -selected-word-background: dfdf00 -# [VNote] Style for searched word highlight -searched-word-foreground: 222222 -searched-word-background: 4db6ac -# [VNote] Style for searched word under cursor highlight -searched-word-cursor-foreground: 222222 -searched-word-cursor-background: 66bb6a -# [VNote] Style for incremental searched word highlight -incremental-searched-word-foreground: 222222 -incremental-searched-word-background: ce93d8 -# [VNote] Style for color column in fenced code block -color-column-background: c9302c -color-column-foreground: eeeeee -# [VNote] Style for preview image line -preview-image-line-foreground: 6f5799 -# [VNote] Style for preview image (useful for SVG in dark theme) -preview-image-background: 949494 - -editor-selection -foreground: dadada -background: 1976d2 - -editor-current-line -background: 363636 -# [VNote] Vim insert mode cursor line background -vim-insert-background: 363636 -# [VNote] Vim normal mode cursor line background -vim-normal-background: 545454 -# [VNote] Vim visual mode cursor line background -vim-visual-background: 484f5d -# [VNote] Vim replace mode cursor line background -vim-replace-background: 2f3377 - -H1 -foreground: e0e0e0 -font-style: bold -font-size: +6 - -H2 -foreground: e0e0e0 -font-style: bold -font-size: +5 - -H3 -foreground: e0e0e0 -font-style: bold -font-size: +4 - -H4 -foreground: e0e0e0 -font-style: bold -font-size: +3 - -H5 -foreground: e0e0e0 -font-style: bold -font-size: +2 - -H6 -foreground: e0e0e0 -font-style: bold -font-size: +1 - -HRULE -foreground: dadada -background: 614145 - -LIST_BULLET -foreground: e37c84 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: e37c84 - -LINK -foreground: 61afef - -AUTO_LINK_URL -foreground: 61afef - -AUTO_LINK_EMAIL -foreground: 61afef - -IMAGE -foreground: 7da8cb - -REFERENCE -foreground: 56b6c2 - -CODE -foreground: 98c379 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -EMPH -foreground: e0e0e0 -font-style: italic - -STRONG -foreground: e0e0e0 -font-style: bold - -HTML_ENTITY -foreground: d09a80 - -HTML -foreground: d09a80 - -HTMLBLOCK -foreground: d09a80 - -COMMENT -foreground: 9e9e9e - -VERBATIM -foreground: 98c379 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -FENCEDCODEBLOCK -foreground: 98c379 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color) -# The last occurence of the same attribute takes effect -# Could specify multiple attribute in one line -hljs-comment: af8787 -hljs-quote: af8787 -hljs-doctag: ccb24c -hljs-keyword: ccb24c -hljs-formula: ccb24c -hljs-section: e37c84 -hljs-name: e37c84 -hljs-selector-tag: e37c84 -hljs-deletion: e37c84 -hljs-subst: e37c84 -hljs-literal: 56b6c2 -hljs-string: f06292 -hljs-regexp: f06292 -hljs-addition: f06292 -hljs-attribute: f06292 -hljs-meta-string: f06292 -hljs-built_in: 80cbc4 -hljs-attr: ce93db -hljs-variable: ce93db -hljs-template-variable: ce93db -hljs-type: ce93db -hljs-selector-class: ce93db -hljs-selector-attr: ce93db -hljs-selector-pseudo: ce93db -hljs-number: ce93db -hljs-symbol: 84c0f2 -hljs-link: underlined, 84c0f2 -hljs-bullet: 84c0f2 -hljs-meta: 84c0f2 -hljs-selector-id: 84c0f2 -hljs-title: bold, 84c0f2 -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: ccb24c - -NOTE -foreground: b39ddb - -STRIKE -foreground: e57373 -font-style: strikeout - -FRONTMATTER -foreground: af8787 - -INLINEEQUATION -foreground: 93d3cc -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -DISPLAYFORMULA -foreground: 93d3cc -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -MARK -foreground: dadada -background: 802090 - -TABLE -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -TABLEBORDER -foreground: e37c84 -background: 4e4e4e diff --git a/src/resources/themes/v_detorte/v_detorte.palette b/src/resources/themes/v_detorte/v_detorte.palette deleted file mode 100644 index d86b8602..00000000 --- a/src/resources/themes/v_detorte/v_detorte.palette +++ /dev/null @@ -1,395 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. -; Fork from [detorte](https://github.com/tamlok/detorte). -; Le Tan (tamlokveer@gmail.com) - -[metadata] -qss_file=v_detorte.qss -mdhl_file=v_detorte.mdhl -css_file=v_detorte.css -codeblock_css_file=v_detorte_codeblock.css -mermaid_css_file=v_detorte_mermaid.css -version=15 - -; This mapping will be used to translate colors when the content of HTML is copied -; without background. You could just specify the foreground colors mapping here. -; It is useful for dark mode theme. '#aabbcc' or 'red' formats are supported. -; col1:col1_new,col2:col2_new -css_color_mapping=#dadada:#222222,#61afef:#0099ff,#98c379:#8e24aa,#bcbcbc:#666666,#8a8a8a:#7a7a7a,#767676:#aaaaaa,#af8787:#767676,#ccb24c:#0000ee,#e37c84:#880000,#56b6c2:#af00d7,#f06292:#bc6060,#80cbc4:#008700,#ce93db:#4d99bf,#84c0f2:#1f7199,#e4e4e4:#222222,#ba68c8:#6a1b9a,#e0e0e0:#222222 - -[phony] -; Abstract color attributes. -master_fg=#222222 -master_bg=#D89F3E -master_light_bg=#DFAF5F -master_dark_bg=#865E1B -master_focus_bg=#D5962e -master_hover_bg=#E2B76F -master_pressed_bg=#C88C28 - -base_fg=#DADADA -base_bg=#444444 - -main_fg=@base_fg -main_bg=@base_bg - -title_fg=@base_fg -title_bg=@base_bg - -disabled_fg=#808080 - -content_fg=@base_fg -content_bg=@base_bg - -border_bg=#585858 - -separator_bg=#666666 - -hover_fg=#EEEEEE -hover_bg=#666666 - -selected_fg=#E4E4E4 -selected_bg=#606060 - -active_fg=@selected_fg -active_bg=@selected_bg - -inactive_fg=@selected_fg -inactive_bg=#585858 - -focus_fg=@hover_fg -focus_bg=@hover_bg - -pressed_fg=@base_fg -pressed_bg=#515151 - -edit_fg=@base_fg -edit_bg=@base_bg -edit_focus_bg=#3A3A3A -edit_focus_border=@master_bg -edit_hover_bg=#494949 -edit_hover_border=@master_bg -edit_selection_fg=@edit_fg -edit_selection_bg=#666666 - -icon_fg=@base_fg -icon_disabled_fg=@disabled_fg - -danger_fg=#F5F5F5 -danger_bg=#C9302C -danger_focus_bg=#D9534F -danger_hover_bg=#DE6764 -danger_pressed_bg=#AC2925 - -[soft_defined] -; VAvatar. -; The foreground color of the avatar when Captain mode is triggered. -avatar_captain_mode_fg=@master_fg -; The background color of the avatar when Captain mode is triggered. -avatar_captain_mode_bg=@master_bg - -; Style of the label in Navigation mode. -navigation_label_fg=@master_fg -navigation_label_bg=@master_bg - -; Style of the bubble of VButtonWithWidget. -bubble_fg=@master_fg -bubble_bg=@master_bg - -; Icons' foreground. -danger_icon_fg=@danger_bg -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg -tab_indicator_tag_label_fg=#222222 -tab_indicator_tag_label_bg=#ce93db - -; Html template. -template_title_flash_light_fg=@master_light_bg -template_title_flash_dark_fg=@master_bg - -; Search hit items in list or tree view. -search_hit_item_fg=@selected_fg -search_hit_item_bg=@master_dark_bg - -; Universal Entry CMD Edit border color -ue_cmd_busy_border=#3F51B5 -ue_cmd_fail_border=@danger_bg - -; VListWidget/VTreeWidget separator. -item_separator_fg=@master_light_bg -item_separator_bg=@separator_bg - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Separator of dock widgets. -dock_separator_bg=@border_bg -dock_separator_hover_bg=@hover_bg -dock_separator_pressed_bg=@pressed_bg - -; Menubar. -menubar_bg=@main_bg -menubar_fg=@main_fg -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_bg=@base_bg -menu_fg=@base_fg -menu_border_bg=@border_bg -menu_item_disabled_fg=@disabled_fg -menu_item_selected_fg=@selected_fg -menu_item_selected_bg=@selected_bg -menu_separator_bg=@separator_bg -menu_icon_fg=@icon_fg -menu_icon_danger_fg=@danger_icon_fg - -; Tooltip. -tooltip_bg=@master_bg -tooltip_fg=@master_fg - -; Toolbar. -toolbar_bg=@main_bg -toolbar_separator_bg=@separator_bg -toolbar_extension_bg=@base_fg -toolbutton_hover_bg=@hover_bg -toolbutton_pressed_bg=@pressed_bg -toolbutton_checked_bg=@selected_bg -toolbutton_icon_fg=@icon_fg -toolbutton_icon_danger_fg=@danger_icon_fg - -buttonmenuitem_decoration_text_fg=@master_light_bg - -; Toolbox. -toolbox_icon_fg=@master_bg -toolbox_icon_active_fg=@master_fg -toolbox_title_border=@master_bg - -; Dockwidget. -dockwidget_bg=@base_bg -dockwidget_title_fg=@title_fg -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_fg=@base_fg -pushbutton_bg=transparent -pushbutton_border=@border_bg -pushbutton_pressed_bg=@pressed_bg -pushbutton_focus_bg=@focus_bg -pushbutton_checked_bg=@selected_bg -pushbutton_hover_bg=@hover_bg -pushbutton_default_border=@master_bg -pushbutton_disabled_fg=@disabled_fg -pushbutton_disabled_bg=@pushbutton_bg - -pushbutton_specialbtn_fg=@master_fg -pushbutton_specialbtn_bg=@master_bg -pushbutton_specialbtn_focus_bg=@master_focus_bg -pushbutton_specialbtn_hover_bg=@master_hover_bg -pushbutton_specialbtn_checked_bg=@master_focus_bg -pushbutton_specialbtn_pressed_bg=@master_pressed_bg - -pushbutton_titlebtn_bg=@title_bg - -pushbutton_dangerbtn_fg=@danger_fg -pushbutton_dangerbtn_bg=@danger_bg -pushbutton_dangerbtn_hover_bg=@danger_hover_bg -pushbutton_dangerbtn_focus_bg=@danger_focus_bg -pushbutton_dangerbtn_pressed_bg=@danger_pressed_bg - -pushbutton_toolboxbtn_active_fg=@master_fg -pushbutton_toolboxbtn_active_bg=@master_bg -pushbutton_toolboxbtn_active_focus_bg=@master_focus_bg -pushbutton_toolboxbtn_active_hover_bg=@master_hover_bg -pushbutton_toolboxbtn_active_pressed_bg=@master_pressed_bg - -button_icon_fg=@icon_fg -button_icon_danger_fg=@danger_icon_fg - -; ComboBox. -combobox_border=@border_bg -combobox_fg=@content_fg -combobox_bg=@content_bg -combobox_disabled_fg=@disabled_fg -combobox_view_border=@border_bg -combobox_view_selected_bg=@selected_bg -combobox_view_selected_fg=@selected_fg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@edit_focus_bg -combobox_focus_border=@edit_focus_border -combobox_hover_bg=@edit_hover_bg -combobox_hover_border=@edit_hover_border -combobox_item_icon_fg=@item_icon_fg - -combobox_notebookselector_fg=@master_bg -combobox_notebookselector_bg=@combobox_bg -combobox_notebookselector_border=@master_bg -combobox_notebookselector_hover_fg=@master_bg -combobox_notebookselector_hover_bg=@hover_bg -combobox_notebookselector_focus_fg=@master_bg -combobox_notebookselector_focus_bg=@focus_bg - -; Label. -label_fg=@base_fg -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@edit_fg -lineedit_bg=@edit_bg -lineedit_disabled_fg=@disabled_fg -lineedit_focus_bg=@edit_focus_bg -lineedit_focus_border=@edit_focus_border -lineedit_hover_bg=@edit_hover_bg -lineedit_hover_border=@edit_hover_border -lineedit_selection_fg=@edit_selection_fg -lineedit_selection_bg=@edit_selection_bg - -; TabWidget. -tabwidget_pane_border=@selected_bg - -; TabBar. -tabbar_fg=@base_fg -tabbar_bg=@base_bg -tabbar_border=@border_bg - -tabbar_selected_fg=@edit_fg -tabbar_selected_bg=@edit_bg -tabbar_selected_border=@border_bg - -tabbar_hover_fg=@hover_fg -tabbar_hover_bg=@hover_bg - -tabbar_icon_fg=@icon_fg -tabbar_icon_special_fg=@danger_bg - -; SelectorItem. -selectoritem_border=@master_bg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; TreeView. -treeview_fg=@content_fg -treeview_bg=@content_bg -treeview_item_border_bg=@border_bg -treeview_item_hover_fg=@hover_fg -treeview_item_hover_bg=@hover_bg -treeview_item_selected_fg=@selected_fg -treeview_item_selected_bg=@selected_bg -treeview_item_selected_avtive_fg=@active_fg -treeview_item_selected_avtive_bg=@active_bg -treeview_item_selected_inactive_fg=@inactive_fg -treeview_item_selected_inactive_bg=@inactive_bg -treeview_item_icon_fg=@item_icon_fg - -; ListView. -listview_fg=@content_fg -listview_bg=@content_bg -listview_item_hover_fg=@hover_fg -listview_item_hover_bg=@hover_bg -listview_item_selected_fg=@selected_fg -listview_item_selected_bg=@selected_bg -listview_item_selected_avtive_fg=@active_fg -listview_item_selected_avtive_bg=@active_bg -listview_item_selected_inactive_fg=@inactive_fg -listview_item_selected_inactive_bg=@inactive_bg - -; QAbstractItemView for TextEdit Completer. -abstractitemview_textedit_fg=#000000 -abstractitemview_textedit_bg=#BCBCBC -abstractitemview_textedit_item_hover_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_hover_bg=@master_hover_bg -abstractitemview_textedit_item_selected_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_selected_bg=@master_light_bg -abstractitemview_textedit_item_selected_avtive_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_selected_avtive_bg=@master_focus_bg -abstractitemview_textedit_item_selected_inactive_fg=@inactive_fg -abstractitemview_textedit_item_selected_inactive_bg=@inactive_bg - -; Splitter. -splitter_handle_bg=@border_bg -splitter_handle_pressed_bg=@pressed_bg - -; StatusBar. -statusbar_fg=@main_fg -statusbar_bg=@main_bg -statusbar_border=@border_bg - -; ScrollBar. -scrollbar_bg=@base_bg -scrollbar_page_bg=transparent -scrollbar_handle_bg=#585858 -scrollbar_handle_hover_bg=@hover_bg -scrollbar_handle_pressed_bg=@selected_bg - -; VEditWindow. -editwindow_corner_icon_fg=@master_bg -editwindow_corner_icon_inactive_fg=@icon_fg - -; CheckBox. -checkbox_disabled_fg=@disabled_fg -checkbox_indicator_focus_bg=@focus_bg -checkbox_indicator_hover_bg=@hover_bg -checkbox_indicator_pressed_bg=@pressed_bg - -; RadioButton. -radiobutton_disabled_fg=@disabled_fg -radiobutton_indicator_focus_bg=@focus_bg -radiobutton_indicator_hover_bg=@hover_bg -radiobutton_indicator_pressed_bg=@pressed_bg - -; SpinBox. -spinbox_fg=@edit_fg -spinbox_bg=@edit_bg -spinbox_border=@border_bg -spinbox_selection_fg=@edit_selection_fg -spinbox_selection_bg=@edit_selection_bg -spinbox_focus_border=@edit_focus_border -spinbox_focus_bg=@edit_focus_bg -spinbox_hover_border=@edit_hover_border -spinbox_hover_bg=@edit_hover_bg -spinbox_button_hover_bg=@hover_bg -spinbox_button_pressed_bg=@pressed_bg - -; HeaderView. -headerview_bg=#515151 -headerview_fg=@base_fg -headerview_border=#C2BFA5 -headerview_checked_fg=@selected_fg -headerview_checked_bg=@selected_bg - -; ProgressBar. -progressbar_bg=@edit_bg -progressbar_border_bg=@border_bg -progressbar_chunk_bg=@master_dark_bg - -universalentry_bg=@base_bg -universalentry_border_bg=@border_bg - -doublerowitem_second_row_label_fg=#9E9E9E - -; GroupBox. -groupbox_border=@border_bg -groupbox_title_fg=@base_fg - -; Slider. -slider_border_bg=@border_bg -slider_groove_bg=@edit_bg -slider_handle_bg=@master_bg -slider_subpage_bg=@master_dark_bg diff --git a/src/resources/themes/v_detorte/v_detorte.qss b/src/resources/themes/v_detorte/v_detorte.qss deleted file mode 100644 index b51bd7d0..00000000 --- a/src/resources/themes/v_detorte/v_detorte.qss +++ /dev/null @@ -1,1469 +0,0 @@ -QToolTip -{ - border: none; - background: @tooltip_bg; - color: @tooltip_fg; -} - -/* QMainWindow */ -QMainWindow { - color: @base_fg; - background: @base_bg; -} - -QMainWindow::separator { - background: @dock_separator_bg; - width: $2px; - height: $2px; -} - -QMainWindow::separator:hover { - background: @dock_separator_hover_bg; -} - -QMainWindow::separator:pressed { - background: @dock_separator_pressed_bg; -} -/* End QMainWindow */ - -QMenuBar { - border: none; - background: @menubar_bg; - color: @menubar_fg; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} - -/* QMenu */ -QMenu { - background: @menu_bg; - color: @menu_fg; - border: 2px solid @menu_border_bg; -} - -QMenu::icon { - margin: $5px; -} - -QMenu::item { - padding: $5px $30px $5px $30px; - border: $1px solid transparent; -} - -QMenu::item:selected { - color: @menu_item_selected_fg; - background: @menu_item_selected_bg; -} - -QMenu::item:disabled { - color: @menu_item_disabled_fg; -} - -QMenu::icon:checked { /* appearance of a 'checked' icon */ - border: $2px solid @menu_fg; -} - -QMenu::separator { - height: $2px; - background: @menu_separator_bg; - margin-left: $10px; - margin-right: $5px; -} - -QMenu::indicator { - width: $20px; - height: $20px; -} - -QMenu::indicator:non-exclusive:unchecked { - image: none; -} - -QMenu::indicator:non-exclusive:checked { - image: url(menu_checkbox.svg); -} - -QMenu::indicator:exclusive:unchecked { - image: none; -} - -QMenu::indicator:exclusive:checked { - image: url(menu_radiobutton.svg); -} -/* End QMenu */ - -QToolBar { - border: none; - background: @toolbar_bg; -} - -QToolBar::separator { - width: 1px; - height: 1px; - border: none; - background: @toolbar_separator_bg; -} - -/* QToolButton */ -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: $16px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: $10px; /* make way for the popup button */ -} - -QToolButton { - border: none; - background: transparent; - margin: 1px 3px 1px 3px; - padding: 0px; -} - -QToolButton:checked { - background: @toolbutton_checked_bg; -} - -QToolButton:hover { - border:none; - background: @toolbutton_hover_bg; -} - -QToolButton:pressed { - background: @toolbutton_pressed_bg; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: none; - width: $16px; -} - -QToolButton::menu-arrow { - image: url(arrow_dropdown.svg); - width: $16px; - height: $16px; -} - -QToolBarExtension { - background: @toolbar_extension_bg; -} -/* End QToolButton*/ - -/* DockWidget */ -QDockWidget { - color: @dockwidget_title_fg; - background: @dockwidget_bg; - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; - icon-size: $16px; - width: $16px; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} - -QDockWidget::close-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: 0px; bottom: 0px; -} - -QDockWidget::float-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: $18px; bottom: 0px; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton[SpecialBtn="true"] { - color: @pushbutton_specialbtn_fg; - background: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:focus { - background-color: @pushbutton_specialbtn_focus_bg; -} - -QPushButton[SpecialBtn="true"]:checked { - background-color: @pushbutton_specialbtn_checked_bg; -} - -QPushButton[SpecialBtn="true"]:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:pressed { - background-color: @pushbutton_specialbtn_pressed_bg; -} - -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; - min-width: -1; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"] { - color: @pushbutton_dangerbtn_fg; - border: none; - background-color: @pushbutton_dangerbtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_dangerbtn_bg; -} - -QPushButton[DangerBtn="true"]:focus { - background-color: @pushbutton_dangerbtn_focus_bg; -} - -QPushButton[DangerBtn="true"]:checked { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[DangerBtn="true"]:hover { - background-color: @pushbutton_dangerbtn_hover_bg; -} - -QPushButton[DangerBtn="true"]:pressed { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"] { - padding: 4px 10px 4px 4px; - margin: 0px; - border: none; - font-weight: bold; - color: @pushbutton_toolboxbtn_active_fg; - background-color: @pushbutton_toolboxbtn_active_bg; - min-width: -1; -} - -QPushButton[ToolBoxActiveBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_toolboxbtn_active_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:focus { - background-color: @pushbutton_toolboxbtn_active_focus_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:hover { - background-color: @pushbutton_toolboxbtn_active_hover_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:pressed { - background-color: @pushbutton_toolboxbtn_active_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[AvatarBtn="true"] { - padding: 2px 4px 2px 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton { - color: @pushbutton_fg; - background: @pushbutton_bg; - border: 1px solid @pushbutton_border; - padding: 3px; - min-width: 80px; -} - -QPushButton:default { - border: 1px solid @pushbutton_default_border; -} - -QPushButton:focus { - background-color: @pushbutton_focus_bg; -} - -QPushButton:checked { - background-color: @pushbutton_checked_bg; -} - -QPushButton:flat { - border: none; -} - -QPushButton:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:pressed { - background-color: @pushbutton_pressed_bg; -} - -QPushButton:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton::menu-indicator { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - min-width: -1; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox#NotebookSelector { - border: none; - font-size: 12pt; - padding-top: 5px; - padding-bottom: 5px; - icon-size: $24px; - font-weight: bold; - color: @combobox_notebookselector_fg; - background: @combobox_notebookselector_bg; -} - -QComboBox#NotebookSelector:focus, QComboBox#NotebookSelector:on { - color: @combobox_notebookselector_focus_fg; - background: @combobox_notebookselector_focus_bg; -} - -QComboBox#NotebookSelector:hover { - color: @combobox_notebookselector_hover_fg; - background: @combobox_notebookselector_hover_bg; -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 12pt; - font-weight: normal; - icon-size: $24px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: $5px; - padding-bottom: $5px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} - -QComboBox { - padding: 3px; - color: @combobox_fg; - background: @combobox_bg; - border: 1px solid @combobox_border; -} - -QComboBox:focus, QComboBox:on { - background-color: @combobox_focus_bg; - border: 2px solid @combobox_focus_border; -} - -QComboBox:hover { - background-color: @combobox_hover_bg; - border: 2px solid @combobox_hover_border; -} - -QComboBox:disabled { - color: @combobox_disabled_fg; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: $20px; - border: none; - background: transparent; -} - -QComboBox::down-arrow { - image: url(arrow_dropdown.svg); - width: $20px; - height: $20px; -} - -QComboBox::down-arrow:disabled { - image: url(arrow_dropdown_disabled.svg); - width: $20px; - height: $20px; -} - -QComboBox QAbstractItemView { - padding: 2px; - border: 1px solid @combobox_view_border; - background: @combobox_bg; - selection-color: @combobox_view_selected_fg; - selection-background-color: @combobox_view_selected_bg; -} - -QComboBox QAbstractItemView::item { - background: transparent; - padding: 3px; -} - -QComboBox QAbstractItemView::item:hover { - color: @combobox_view_item_hover_fg; - background: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #00796B; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -QLabel[TagLabel="true"] { - padding-left: $5px; - padding-right: $5px; - color: @tab_indicator_tag_label_fg; - background-color: @tab_indicator_tag_label_bg; -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: $2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VDoubleRowItemWidget QLabel[FirstRowLabel="true"] { - border: none; - font-size: 10pt; -} - -VDoubleRowItemWidget QLabel[SecondRowLabel="true"] { - border: none; - font-size: 9pt; - color: @doublerowitem_second_row_label_fg; -} - -QLabel { - border: none; - color: @label_fg; - background: transparent; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} - -QLineEdit[VimCommandLine="true"]:focus { - border: none; - background: @lineedit_focus_bg; -} - -QLineEdit[VimCommandLine="true"]:hover { - border: none; - background: @lineedit_hover_bg; -} - -QLineEdit[EmbeddedEdit="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: transparent; -} - -QLineEdit[EmbeddedEdit="true"]:focus { - background: @lineedit_focus_bg; - border: none; -} - -QLineEdit[EmbeddedEdit="true"]:hover { - background: @lineedit_hover_bg; - border: none; -} - -QLineEdit { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QLineEdit:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QLineEdit:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} - -QLineEdit:disabled { - color: @lineedit_disabled_fg; -} -/* End QLineEdit */ - -/* QPlainTextEdit QTextEdit */ -QPlainTextEdit[LineEdit="true"], QTextEdit[LineEdit="true"] { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QPlainTextEdit[LineEdit="true"]:focus, QTextEdit[LineEdit="true"]:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QPlainTextEdit[LineEdit="true"]:hover, QTextEdit[LineEdit="true"]:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} -/* End QPlainTextEdit QTextEdit */ - -/* QTabWidget */ -QTabWidget { - border: none; -} - -QTabWidget::pane { - border: none; -} - -QTabWidget::tab-bar { - alignment: left; -} -/* End QTabWidget */ - -/* QTabBar */ -QTabBar::tab { - color: @tabbar_fg; - background: @tabbar_bg; - border: none; -} - -QTabBar::tab:top, QTabBar::tab:bottom { - border-top: $2px solid transparent; - border-right: $1px solid @tabbar_border; - /* MUST leave right and left padding 0px. */ - padding: $2px 0px $2px 0px; - height: $20px; -} - -QTabBar::tab:right { - border-left: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:left { - border-right: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:hover { - color: @tabbar_hover_fg; - background: @tabbar_hover_bg; -} - -QTabBar::tab:selected { - color: @tabbar_selected_fg; - background: @tabbar_selected_bg; -} - -QTabBar::tab:top:selected, QTabBar::tab:bottom:selected { - border-top: $2px solid @master_bg; -} - -QTabBar::tab:right:selected { - border-left: $3px solid @master_bg; -} - -QTabBar::tab:left:selected { - border-right: $3px solid @master_bg; -} - -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:focus { - image: url(close.svg); -} - -QTabBar::close-button:hover { - image: url(close.svg); -} - -QTabBar::scroller { - width: $20px; -} - -QTabBar QToolButton { - border: none; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(right.svg); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(left.svg); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(right_disabled.svg); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(left_disabled.svg); -} -/* End QTabBar */ - -/* QTreeView */ -QTreeView[ItemBorder="true"]::item { - padding-top: 5px; - padding-bottom: 5px; - border-bottom: $1px solid @treeview_item_border_bg; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-children:!has-siblings:closed, -QTreeView[PlainTree="true"]::branch:closed:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView[PlainTree="true"]::branch:open:has-children:!has-siblings, -QTreeView[PlainTree="true"]::branch:open:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView { - color: @treeview_fg; - background: @treeview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QTreeView::item:hover { - color: @treeview_item_hover_fg; - background: @treeview_item_hover_bg; -} - -QTreeView::item:selected { - color: @treeview_item_selected_fg; - background: @treeview_item_selected_bg; -} - -QTreeView::item:selected:active { - color: @treeview_item_selected_active_fg; - background: @treeview_item_selected_active_bg; -} - -QTreeView::item:selected:!active { - color: @treeview_item_selected_inactive_fg; - background: @treeview_item_selected_inactive_bg; -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(line.svg) 0; -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(branch_more.svg) 0; -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(branch_end.svg) 0; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(branch_closed.svg); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(branch_open.svg); -} -/* End QTreeView */ - -/* QListView */ -QListView { - color: @listview_fg; - background: @listview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QListView::item:hover { - color: @listview_item_hover_fg; - background: @listview_item_hover_bg; -} - -QListView::item:selected { - color: @listview_item_selected_fg; - background: @listview_item_selected_bg; -} - -QListView::item:selected:active { - color: @listview_item_selected_active_fg; - background: @listview_item_selected_active_bg; -} - -QListView::item:selected:!active { - color: @listview_item_selected_inactive_fg; - background: @listview_item_selected_inactive_bg; -} - -QListView::item:disabled { - background: transparent; -} -/* End QListView */ - -/* QAbstractItemView for TextEdit Completer popup*/ -QAbstractItemView[TextEdit="true"] { - color: @abstractitemview_textedit_fg; - background: @abstractitemview_textedit_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QAbstractItemView[TextEdit="true"]::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QAbstractItemView[TextEdit="true"]::item:hover { - color: @abstractitemview_textedit_item_hover_fg; - background: @abstractitemview_textedit_item_hover_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected { - color: @abstractitemview_textedit_item_selected_fg; - background: @abstractitemview_textedit_item_selected_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:active { - color: @abstractitemview_textedit_item_selected_active_fg; - background: @abstractitemview_textedit_item_selected_active_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:!active { - color: @abstractitemview_textedit_item_selected_inactive_fg; - background: @abstractitemview_textedit_item_selected_inactive_bg; -} - -QAbstractItemView[TextEdit="true"]::item:disabled { - background: transparent; -} -/* End QAbstractItemView */ - -/* QSplitter */ -QSplitter#MainSplitter { - border: none; - margin-left: $3px; -} - -QSplitter { - border: none; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:pressed { - background-color: @splitter_handle_pressed_bg; -} - -QSplitter::handle:vertical { - height: $2px; -} - -QSplitter::handle:horizontal { - width: $2px; -} -/* End QSplitter */ - -/* QStatusBar */ -QStatusBar { - color: @statusbar_fg; - background: @statusbar_bg; - border-top: 1px solid @statusbar_border; -} -/* End QStatusBar */ - -QDialog { - color: @base_fg; - background: @base_bg; -} - -/* QScrollBar */ -QScrollBar::add-page, QScrollBar::sub-page { - background: @scrollbar_page_bg; -} - -QScrollBar:vertical { - background: @scrollbar_bg; - width: $16px; - margin: $16px 0px $16px 0px; - padding: 0px $2px 0px $2px; - border: none; -} - -QScrollBar::handle:vertical { - background: @scrollbar_handle_bg; - min-height: $16px; -} - -QScrollBar::handle:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::down-arrow:vertical { - image: url(down.svg); - width: $16px; - height: $16px; -} - -QScrollBar::up-arrow:vertical { - image: url(up.svg); - width: $16px; - height: $16px; -} - -QScrollBar:horizontal { - background: @scrollbar_bg; - height: $16px; - margin: 0px $16px 0px $16px; - padding: $2px 0px $2px 0px; - border: none; -} - -QScrollBar::handle:horizontal { - background: @scrollbar_handle_bg; - min-width: $16px; -} - -QScrollBar::handle:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::right-arrow:horizontal { - image: url(right.svg); - width: $16px; - height: $16px; -} - -QScrollBar::left-arrow:horizontal { - image: url(left.svg); - width: $16px; - height: $16px; -} -/* End QScrollBar */ - -/* QCheckBox */ -QCheckBox { - spacing: $5px; -} - -QCheckBox:disabled { - color: @checkbox_disabled_fg; -} - -QCheckBox::indicator:unchecked { - image: url(checkbox_unchecked.svg); -} - -QCheckBox::indicator:unchecked:disabled { - image: url(checkbox_unchecked_disabled.svg); -} - -QCheckBox::indicator:checked { - image: url(checkbox_checked.svg); -} - -QCheckBox::indicator:checked:disabled { - image: url(checkbox_checked_disabled.svg); -} - -QCheckBox::indicator { - width: $20px; - height: $20px; -} - -QCheckBox::indicator:focus { - background: @checkbox_indicator_focus_bg; -} - -QCheckBox::indicator:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:pressed { - background: @checkbox_indicator_pressed_bg; -} -/* End QCheckBox */ - -/* QRadioButton */ -QRadioButton { - spacing: $5px; -} - -QRadioButton:disabled { - color: @radiobutton_disabled_fg; -} - -QRadioButton::indicator:unchecked { - image: url(radiobutton_unchecked.svg); -} - -QRadioButton::indicator:unchecked:disabled { - image: url(radiobutton_unchecked_disabled.svg); -} - -QRadioButton::indicator:checked { - image: url(radiobutton_checked.svg); -} - -QRadioButton::indicator:checked:disabled { - image: url(radiobutton_checked_disabled.svg); -} - -QRadioButton::indicator { - width: $20px; - height: $20px; -} - -QRadioButton::indicator:focus { - background: @radiobutton_indicator_focus_bg; -} - -QRadioButton::indicator:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:pressed { - background: @radiobutton_indicator_pressed_bg; -} -/* End QRadioButton */ - -/* QSpinBox */ -QSpinBox, QDoubleSpinBox { - border: 1px solid @spinbox_border; - color: @spinbox_fg; - background: @spinbox_bg; - padding-right: $25px; - min-height: $25px; - selection-color: @spinbox_selection_fg; - selection-background-color: @spinbox_selection_bg; -} - -QSpinBox:focus, QDoubleSpinBox::focus { - border: 2px solid @spinbox_focus_border; - background: @spinbox_focus_bg; -} - -QSpinBox:hover, QDoubleSpinBox::hover { - border: 2px solid @spinbox_hover_border; - background: @spinbox_hover_bg; -} - -QSpinBox::up-button, QDoubleSpinBox::up-button { - subcontrol-origin: border; - subcontrol-position: top right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} - -QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off, QDoubleSpinBox::up-arrow:disabled, QDoubleSpinBox::up-arrow:off { - image: url(up_disabled.svg); -} - -QSpinBox::down-button, QDoubleSpinBox::down-button { - subcontrol-origin: border; - subcontrol-position: bottom right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off, QDoubleSpinBox::down-arrow:disabled, QDoubleSpinBox::down-arrow:off { - image: url(down_disabled.svg); -} -/* End QSpinBox */ - -/* QHeaderView */ -QHeaderView::section { - background: @headerview_bg; - color: @headerview_fg; - padding-left: 4px; - border: none; - border-left: 1px solid @headerview_border; - border-bottom: 1px solid @headerview_border; -} - -QHeaderView::section:checked -{ - color: @headerview_checked_fg; - background: @headerview_checked_bg; -} - -/* style the sort indicator */ -QHeaderView::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QHeaderView::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} -/* End QHeaderView */ - -QAbstractScrollArea::corner { - background: @scrollbar_bg; - border: none; -} - -/* QProgressBar */ -QProgressBar { - background: @progressbar_bg; - border: $1px solid @progressbar_border_bg; - text-align: center; -} - -QProgressBar::chunk { - background-color: @progressbar_chunk_bg; - width: $20px; -} -/* End QProgressBar */ - -/* QGroupBox */ -QGroupBox { - border: 2px solid @groupbox_border; - border-radius: 5px; - margin-top: 2ex; -} - -QGroupBox::title { - color: @groupbox_title_fg; - subcontrol-origin: margin; - subcontrol-position: top left; - position: absolute; - padding: 0 $3px; - top: 0px; left: $10px; bottom: 0px; -} -/* End QGroupBox */ - -/* QSlider */ -QSlider::groove:horizontal { - border: $1px solid @slider_border_bg; - height: $8px; - background: @slider_groove_bg; - margin: $2px 0; -} - -QSlider::handle:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - width: $18px; - margin: $-2px 0; -} - -QSlider::add-page:horizontal { - background: transparent; -} - -QSlider::sub-page:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: $2px 0; -} - -QSlider::groove:vertical { - border: $1px solid @slider_border_bg; - width: $8px; - background: @slider_groove_bg; - margin: 0 $2px; -} - -QSlider::handle:vertical { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - height: $18px; - margin: 0 $-2px; -} - -QSlider::add-page:vertical { - background: transparent; -} - -QSlider::sub-page:vertical { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: 0 $2px; -} -/* End QSlider */ - -/* QWidget */ -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} - -QWidget[ToolBoxTitle="true"] { - border-bottom: 2px solid @toolbox_title_border; -} - -QWidget[ToolBoxTitle="true"] QPushButton[ToolBoxTitleBtn="true"] { - height: $20px; -} - -QWidget[MainEditor="true"] { - border: none; -} - -QWidget -{ - color: @widget_fg; - font-family: "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", "Dengxian", "等线体", "STXihei", "华文细黑", "Liberation Sans", "Droid Sans", "NSimSun", "新宋体", "SimSun", "宋体", "Helvetica", "sans-serif", "Tahoma", "Arial", "Verdana", "Geneva", "Georgia", "Times New Roman"; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} - -VUniversalEntry { - background: transparent; - border: 1px solid @universalentry_border_bg; -} -/* End QWidget */ diff --git a/src/resources/themes/v_detorte/v_detorte_codeblock.css b/src/resources/themes/v_detorte/v_detorte_codeblock.css deleted file mode 100644 index 25d9965f..00000000 --- a/src/resources/themes/v_detorte/v_detorte_codeblock.css +++ /dev/null @@ -1,75 +0,0 @@ -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #dadada; - background: #4a4a4a; -} - -.hljs-comment, -.hljs-quote { - color: #af8787; -} - -.hljs-doctag, -.hljs-keyword, -.hljs-formula { - color: #ccb24c; -} - -.hljs-section, -.hljs-name, -.hljs-selector-tag, -.hljs-deletion, -.hljs-subst { - color: #e37c84; -} - -.hljs-literal { - color: #56b6c2; -} - -.hljs-string, -.hljs-regexp, -.hljs-addition, -.hljs-attribute, -.hljs-meta-string { - color: #f06292; -} - -.hljs-built_in, -.hljs-class .hljs-title { - color: #80cbc4; -} - -.hljs-attr, -.hljs-variable, -.hljs-template-variable, -.hljs-type, -.hljs-selector-class, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-number { - color: #ce93db; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link, -.hljs-meta, -.hljs-selector-id, -.hljs-title { - color: #84c0f2; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-link { - text-decoration: underline; -} diff --git a/src/resources/themes/v_detorte/v_detorte_mermaid.css b/src/resources/themes/v_detorte/v_detorte_mermaid.css deleted file mode 100644 index 04400586..00000000 --- a/src/resources/themes/v_detorte/v_detorte_mermaid.css +++ /dev/null @@ -1,416 +0,0 @@ -/* Flowchart variables */ -/* Sequence Diagram variables */ -/* Gantt chart variables */ -.mermaid-diagram .mermaid .label { - font-family: 'trebuchet ms', verdana, arial; - color: #333; -} - -.mermaid-diagram .node rect, -.mermaid-diagram .node circle, -.mermaid-diagram .node ellipse, -.mermaid-diagram .node polygon { - fill: #cde498; - stroke: #13540c; - stroke-width: 1px; -} - -.mermaid-diagram .edgePath .path { - stroke: green; - stroke-width: 1.5px; -} - -.mermaid-diagram .edgeLabel { - background-color: #e8e8e8; -} - -.mermaid-diagram .cluster rect { - fill: #cdffb2 !important; - rx: 4 !important; - stroke: #6eaa49 !important; - stroke-width: 1px !important; -} - -.mermaid-diagram .cluster text { - fill: #333; -} - -.mermaid-diagram .actor { - stroke: #13540c; - fill: #cde498; -} - -.mermaid-diagram text.actor { - fill: black; - stroke: none; -} - -.mermaid-diagram .actor-line { - stroke: blue; -} - -.mermaid-diagram .messageLine0 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #333; -} - -.mermaid-diagram .messageLine1 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - stroke: #333; -} - -.mermaid-diagram #arrowhead { - fill: #333; -} - -.mermaid-diagram #crosshead path { - fill: #333 !important; - stroke: #333 !important; -} - -.mermaid-diagram .messageText { - fill: #333; - stroke: none; -} - -.mermaid-diagram .labelBox { - stroke: #326932; - fill: #cde498; -} - -.mermaid-diagram .labelText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopLine { - stroke-width: 2; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #326932; -} - -.mermaid-diagram .note { - stroke: #6eaa49; - fill: #fff5ad; -} - -.mermaid-diagram .noteText { - fill: black; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -/** Section styling */ -.mermaid-diagram .section { - stroke: none; - opacity: 0.2; -} - -.mermaid-diagram .section0 { - fill: #6eaa49; -} - -.mermaid-diagram .section2 { - fill: #6eaa49; -} - -.mermaid-diagram .section1, -.mermaid-diagram .section3 { - fill: white; - opacity: 0.2; -} - -.mermaid-diagram .sectionTitle0 { - fill: #333; -} - -.mermaid-diagram .sectionTitle1 { - fill: #333; -} - -.mermaid-diagram .sectionTitle2 { - fill: #333; -} - -.mermaid-diagram .sectionTitle3 { - fill: #333; -} - -.mermaid-diagram .sectionTitle { - text-anchor: start; - font-size: 11px; - text-height: 14px; -} - -/* Grid and axis */ -.mermaid-diagram .grid .tick { - stroke: lightblue; - opacity: 0.3; - shape-rendering: crispEdges; -} - -.mermaid-diagram .grid path { - stroke-width: 0; -} - -/* Today line */ -.mermaid-diagram .today { - fill: none; - stroke: red; - stroke-width: 2px; -} - -/* Task styling */ -/* Default task */ -.mermaid-diagram .task { - stroke-width: 2; -} - -.mermaid-diagram .taskText { - text-anchor: middle; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideRight { - fill: black; - text-anchor: start; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideLeft { - fill: black; - text-anchor: end; - font-size: 11px; -} - -/* Specific task settings for the sections*/ -.mermaid-diagram .taskText0, -.mermaid-diagram .taskText1, -.mermaid-diagram .taskText2, -.mermaid-diagram .taskText3 { - fill: white; -} - -.mermaid-diagram .task0, -.mermaid-diagram .task1, -.mermaid-diagram .task2, -.mermaid-diagram .task3 { - fill: #487e3a; - stroke: #13540c; -} - -.mermaid-diagram .taskTextOutside0, -.mermaid-diagram .taskTextOutside2 { - fill: black; -} - -.mermaid-diagram .taskTextOutside1, -.mermaid-diagram .taskTextOutside3 { - fill: black; -} - -/* Active task */ -.mermaid-diagram .active0, -.mermaid-diagram .active1, -.mermaid-diagram .active2, -.mermaid-diagram .active3 { - fill: #cde498; - stroke: #13540c; -} - -.mermaid-diagram .activeText0, -.mermaid-diagram .activeText1, -.mermaid-diagram .activeText2, -.mermaid-diagram .activeText3 { - fill: black !important; -} - -/* Completed task */ -.mermaid-diagram .done0, -.mermaid-diagram .done1, -.mermaid-diagram .done2, -.mermaid-diagram .done3 { - stroke: blue; - fill: lightblue; - stroke-width: 2; -} - -.mermaid-diagram .doneText0, -.mermaid-diagram .doneText1, -.mermaid-diagram .doneText2, -.mermaid-diagram .doneText3 { - fill: black !important; -} - -/* Tasks on the critical line */ -.mermaid-diagram .crit0, -.mermaid-diagram .crit1, -.mermaid-diagram .crit2, -.mermaid-diagram .crit3 { - stroke: #ff8888; - fill: red; - stroke-width: 2; -} - -.mermaid-diagram .activeCrit0, -.mermaid-diagram .activeCrit1, -.mermaid-diagram .activeCrit2, -.mermaid-diagram .activeCrit3 { - stroke: #ff8888; - fill: #cde498; - stroke-width: 2; -} - -.mermaid-diagram .doneCrit0, -.mermaid-diagram .doneCrit1, -.mermaid-diagram .doneCrit2, -.mermaid-diagram .doneCrit3 { - stroke: #ff8888; - fill: lightblue; - stroke-width: 2; - cursor: pointer; - shape-rendering: crispEdges; -} - -.mermaid-diagram .doneCritText0, -.mermaid-diagram .doneCritText1, -.mermaid-diagram .doneCritText2, -.mermaid-diagram .doneCritText3 { - fill: black !important; -} - -.mermaid-diagram .activeCritText0, -.mermaid-diagram .activeCritText1, -.mermaid-diagram .activeCritText2, -.mermaid-diagram .activeCritText3 { - fill: black !important; -} - -.mermaid-diagram .titleText { - text-anchor: middle; - font-size: 18px; - fill: black; -} - -.mermaid-diagram g.classGroup text { - fill: #13540c; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -.mermaid-diagram g.classGroup rect { - fill: #cde498; - stroke: #13540c; -} - -.mermaid-diagram g.classGroup line { - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram svg .classLabel .box { - stroke: none; - stroke-width: 0; - fill: #cde498; - opacity: 0.5; -} - -.mermaid-diagram svg .classLabel .label { - fill: #13540c; -} - -.mermaid-diagram .relation { - stroke: #13540c; - stroke-width: 1; - fill: none; -} - -.mermaid-diagram .composition { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #compositionStart { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #compositionEnd { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram .aggregation { - fill: #cde498; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #aggregationStart { - fill: #cde498; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #aggregationEnd { - fill: #cde498; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #dependencyStart { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #dependencyEnd { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #extensionStart { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #extensionEnd { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram .node text { - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -.mermaid-diagram div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: 'trebuchet ms', verdana, arial; - font-size: 12px; - background: #cdffb2; - border: 1px solid #6eaa49; - border-radius: 2px; - pointer-events: none; - z-index: 100; -} diff --git a/src/resources/themes/v_moonlight/arrow_dropdown.svg b/src/resources/themes/v_moonlight/arrow_dropdown.svg deleted file mode 100644 index b831fa00..00000000 --- a/src/resources/themes/v_moonlight/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_moonlight/arrow_dropdown_disabled.svg b/src/resources/themes/v_moonlight/arrow_dropdown_disabled.svg deleted file mode 100644 index a09037cf..00000000 --- a/src/resources/themes/v_moonlight/arrow_dropdown_disabled.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_moonlight/branch_closed.svg b/src/resources/themes/v_moonlight/branch_closed.svg deleted file mode 100644 index 796782cb..00000000 --- a/src/resources/themes/v_moonlight/branch_closed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/branch_open.svg b/src/resources/themes/v_moonlight/branch_open.svg deleted file mode 100644 index 3212fbf9..00000000 --- a/src/resources/themes/v_moonlight/branch_open.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/checkbox_checked.svg b/src/resources/themes/v_moonlight/checkbox_checked.svg deleted file mode 100644 index 6efbccc4..00000000 --- a/src/resources/themes/v_moonlight/checkbox_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_moonlight/checkbox_checked_disabled.svg b/src/resources/themes/v_moonlight/checkbox_checked_disabled.svg deleted file mode 100644 index 69dadc72..00000000 --- a/src/resources/themes/v_moonlight/checkbox_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_moonlight/checkbox_unchecked.svg b/src/resources/themes/v_moonlight/checkbox_unchecked.svg deleted file mode 100644 index c9a55295..00000000 --- a/src/resources/themes/v_moonlight/checkbox_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/checkbox_unchecked_disabled.svg b/src/resources/themes/v_moonlight/checkbox_unchecked_disabled.svg deleted file mode 100644 index 19e54451..00000000 --- a/src/resources/themes/v_moonlight/checkbox_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/close.svg b/src/resources/themes/v_moonlight/close.svg deleted file mode 100644 index 2ff42f1a..00000000 --- a/src/resources/themes/v_moonlight/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_moonlight/close_grey.svg b/src/resources/themes/v_moonlight/close_grey.svg deleted file mode 100644 index 0e2cd92c..00000000 --- a/src/resources/themes/v_moonlight/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_moonlight/down.svg b/src/resources/themes/v_moonlight/down.svg deleted file mode 100644 index 56f2a45d..00000000 --- a/src/resources/themes/v_moonlight/down.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/down_disabled.svg b/src/resources/themes/v_moonlight/down_disabled.svg deleted file mode 100644 index e6cb5fa8..00000000 --- a/src/resources/themes/v_moonlight/down_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/float.svg b/src/resources/themes/v_moonlight/float.svg deleted file mode 100644 index 28cc666a..00000000 --- a/src/resources/themes/v_moonlight/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_moonlight/left.svg b/src/resources/themes/v_moonlight/left.svg deleted file mode 100644 index 0e339476..00000000 --- a/src/resources/themes/v_moonlight/left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/left_disabled.svg b/src/resources/themes/v_moonlight/left_disabled.svg deleted file mode 100644 index fd4937e8..00000000 --- a/src/resources/themes/v_moonlight/left_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/menu_checkbox.svg b/src/resources/themes/v_moonlight/menu_checkbox.svg deleted file mode 100644 index 3acab8ad..00000000 --- a/src/resources/themes/v_moonlight/menu_checkbox.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/menu_radiobutton.svg b/src/resources/themes/v_moonlight/menu_radiobutton.svg deleted file mode 100644 index fcb32f20..00000000 --- a/src/resources/themes/v_moonlight/menu_radiobutton.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/radiobutton_checked.svg b/src/resources/themes/v_moonlight/radiobutton_checked.svg deleted file mode 100644 index 50642a94..00000000 --- a/src/resources/themes/v_moonlight/radiobutton_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_moonlight/radiobutton_checked_disabled.svg b/src/resources/themes/v_moonlight/radiobutton_checked_disabled.svg deleted file mode 100644 index f12828f7..00000000 --- a/src/resources/themes/v_moonlight/radiobutton_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_moonlight/radiobutton_unchecked.svg b/src/resources/themes/v_moonlight/radiobutton_unchecked.svg deleted file mode 100644 index eccd8165..00000000 --- a/src/resources/themes/v_moonlight/radiobutton_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/radiobutton_unchecked_disabled.svg b/src/resources/themes/v_moonlight/radiobutton_unchecked_disabled.svg deleted file mode 100644 index dc6a604b..00000000 --- a/src/resources/themes/v_moonlight/radiobutton_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_moonlight/right.svg b/src/resources/themes/v_moonlight/right.svg deleted file mode 100644 index 796782cb..00000000 --- a/src/resources/themes/v_moonlight/right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/right_disabled.svg b/src/resources/themes/v_moonlight/right_disabled.svg deleted file mode 100644 index 175f2ff3..00000000 --- a/src/resources/themes/v_moonlight/right_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/up.svg b/src/resources/themes/v_moonlight/up.svg deleted file mode 100644 index cb37cc73..00000000 --- a/src/resources/themes/v_moonlight/up.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/up_disabled.svg b/src/resources/themes/v_moonlight/up_disabled.svg deleted file mode 100644 index 68f1d067..00000000 --- a/src/resources/themes/v_moonlight/up_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_moonlight/v_moonlight.css b/src/resources/themes/v_moonlight/v_moonlight.css deleted file mode 100644 index 973b74b1..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight.css +++ /dev/null @@ -1,355 +0,0 @@ -body { - margin: 0 auto; - font-family: "Segoe UI", Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Palatino, "Times New Roman", "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", Dengxian, "等线体", STXihei, "华文细黑", "Liberation Sans", "Droid Sans", NSimSun, "新宋体", SimSun, "宋体"; - color: #ABB2BF; - line-height: 1.5; - padding: 15px; - background: #282C34; - font-size: 16px; -} - -h1, h2, h3, h4, h5, h6 { - color: #E06C75; - font-weight: bold; - margin-top: 20px; - margin-bottom: 10px; - padding: 0; -} - -p { - padding: 0; - margin-top: 16px; - margin-bottom: 16px; -} - -h1 { - font-size: 26px; -} - -h2 { - font-size: 24px; -} - -h3 { - font-size: 22px; -} - -h4 { - font-size: 20px; -} - -h5 { - font-size: 19px; -} - -h6 { - font-size: 18px; -} - -a { - color: #61AFEF; - margin: 0; - padding: 0; - vertical-align: baseline; - text-decoration: none; - word-break: break-word; -} - -a:hover { - text-decoration: underline; -} - -a:visited { - color: #BA68C8; -} - -ul, ol { - padding: 0; - padding-left: 24px; -} - -li { - line-height: 24px; -} - -li ul, li ol { - margin-left: 16px; -} - -p, ul, ol { - font-size: 16px; - line-height: 24px; -} - -mark { - color: #000000; - background-color: #C4C400; -} - -pre { - display: block; - overflow-y: hidden; - overflow-x: auto; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -code { - font-family: Consolas, Monaco, Monospace, Courier; - color: #98C379; - word-break: break-word; -} - -pre code { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #98C379; - background-color: #343A45; - line-height: 1.5; - font-family: Consolas, Monaco, Monospace, Courier; - white-space: pre; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -pre code.markdown-metadata { - border-left: .5em solid #3F51B5; -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - color: #5C6370; - border-left: .5em solid #5C6370; - padding: 0 1em; - margin-left: 0; -} - -blockquote p { - color: #5C6370; -} - -hr { - display: block; - text-align: left; - margin: 1em 0; - border: none; - height: 2px; - background: #373E47; -} - -table { - padding: 0; - margin: 1rem 0.5rem; - border-collapse: collapse; -} - -table tr { - border-top: 2px solid #373E47; - margin: 0; - padding: 0; -} - -table tr th { - font-weight: bold; - border: 2px solid #373E47; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 2px solid #373E47; - margin: 0; - padding: 6px 13px; -} - -table tr th :first-child, table tr td :first-child { - margin-top: 0; -} - -table tr th :last-child, table tr td :last-child { - margin-bottom: 0; -} - -div.mermaid-diagram { - margin: 16px 0px 16px 0px; - overflow-y: hidden; - background: #B0BEC5; - color: #6C6C6C; -} - -div.flowchart-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; - background: #B0BEC5; - color: #6C6C6C; -} - -div.wavedrom-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; - background: #B0BEC5; - color: #6C6C6C; -} - -div.plantuml-diagram { - padding: 5px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; - background: #B0BEC5; - color: #6C6C6C; -} - -.img-package { - text-align: center; -} - -img.img-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -span.img-caption { - min-width: 20%; - max-width: 80%; - display: inline-block; - padding: 10px; - margin: 0 auto; - border-bottom: 1px solid #373E47; - color: #ABB2BF; - text-align: center; - line-height: 1.5; -} - -.emoji_zero,.emoji_one,.emoji_two,.emoji_three,.emoji_four,.emoji_five,.emoji_six,.emoji_seven,.emoji_eight,.emoji_nine { - margin-left: 5px; - margin-right: 8px; -} - -div.preview-hint { - opacity: 0.5; - margin-top: 30%; - margin-bottom: 30%; - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; -} - -/* For Highlight.js Line Number */ -table.hljs-ln tr { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td.hljs-ln-numbers { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - text-align: center; - color: #5C6370; - border-right: 1px solid #373E47; - vertical-align: top; - padding-right: 5px; - white-space: nowrap; -} - -table.hljs-ln tr td.hljs-ln-code { - padding-left: 10px; -} - -::-webkit-scrollbar { - background-color: #21252B; - width: 14px; - height: 14px; - border: none; -} - -::-webkit-scrollbar-corner { - background-color: #21252B; -} - -::-webkit-scrollbar-button { - /* This selector affects the styling of both the up & down and left & right buttons of a scrollbar */ - height: 14px; - width: 14px; - background-color: #21252B; -} - -::-webkit-scrollbar-button:hover { - background-color: #424A56; -} - -::-webkit-scrollbar-button:active { - background-color: #31363F; -} - -::-webkit-scrollbar-track { - /* This selector affects the styling of the area in the scrollbar between the two buttons */ - background-color: #21252B; -} - -::-webkit-scrollbar-thumb { - /* This selector affects the styling of draggable element of the scollbar */ - border: none; - background-color: #353B45; -} - -::-webkit-scrollbar-thumb:hover { - background-color: #424A56; -} - -::-webkit-scrollbar-thumb:active { - background-color: #31363F; -} - -::-webkit-scrollbar-button:horizontal:increment { - background-image: url(right.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:horizontal:decrement { - background-image: url(left.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:increment { - background-image: url(down.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:decrement { - background-image: url(up.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::selection { - background: #8CBAE8; - color: #D0D0D0; -} diff --git a/src/resources/themes/v_moonlight/v_moonlight.mdhl b/src/resources/themes/v_moonlight/v_moonlight.mdhl deleted file mode 100644 index 0a727634..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight.mdhl +++ /dev/null @@ -1,212 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Verdana, Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Times New Roman -font-size: 12 -foreground: abb2bf -background: 282c34 -# [VNote] Style for trailing space -trailing-space: 636d81 -# [VNote] Style for line number -line-number-background: 2c313a -line-number-foreground: 6e7686 -# [VNote] Style for selected word highlight -selected-word-foreground: 222222 -selected-word-background: dfdf00 -# [VNote] Style for searched word highlight -searched-word-foreground: 222222 -searched-word-background: 4db6ac -# [VNote] Style for searched word under cursor highlight -searched-word-cursor-foreground: 222222 -searched-word-cursor-background: 66bb6a -# [VNote] Style for incremental searched word highlight -incremental-searched-word-foreground: 222222 -incremental-searched-word-background: ce93d8 -# [VNote] Style for color column in fenced code block -color-column-background: c9302c -color-column-foreground: eeeeee -# [VNote] Style for preview image line -preview-image-line-foreground: 6f5799 -# [VNote] Style for preview image (useful for SVG in dark theme) -preview-image-background: b0bec5 - -editor-selection -foreground: bcbcbc -background: 1976d2 - -editor-current-line -background: 353d49 -# [VNote] Vim insert mode cursor line background -vim-insert-background: 353d49 -# [VNote] Vim normal mode cursor line background -vim-normal-background: 373c47 -# [VNote] Vim visual mode cursor line background -vim-visual-background: 0d47a1 -# [VNote] Vim replace mode cursor line background -vim-replace-background: 2f3377 - -H1 -foreground: e06c75 -font-style: bold -font-size: +6 - -H2 -foreground: e06c75 -font-style: bold -font-size: +5 - -H3 -foreground: e06c75 -font-style: bold -font-size: +4 - -H4 -foreground: e06c75 -font-style: bold -font-size: +3 - -H5 -foreground: e06c75 -font-style: bold -font-size: +2 - -H6 -foreground: e06c75 -font-style: bold -font-size: +1 - -HRULE -foreground: abb2bf -background: 493134 - -LIST_BULLET -foreground: e06c75 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: e06c75 - -LINK -foreground: 61afef - -AUTO_LINK_URL -foreground: 61afef - -AUTO_LINK_EMAIL -foreground: 61afef - -IMAGE -foreground: 4883b3 - -REFERENCE -foreground: 56b6c2 - -CODE -foreground: 98c379 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -EMPH -font-style: italic - -STRONG -font-style: bold - -HTML_ENTITY -foreground: c07855 - -HTML -foreground: c07855 - -HTMLBLOCK -foreground: c07855 - -COMMENT -foreground: 6e7686 - -VERBATIM -foreground: 98c379 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -FENCEDCODEBLOCK -foreground: 98c379 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color) -# The last occurence of the same attribute takes effect -# Could specify multiple attribute in one line -hljs-comment: 6e7686 -hljs-quote: 6e7686 -hljs-doctag: c678dd -hljs-keyword: c678dd -hljs-formula: c678dd -hljs-section: e06c75 -hljs-name: e06c75 -hljs-selector-tag: e06c75 -hljs-deletion: e06c75 -hljs-subst: e06c75 -hljs-literal: 56b6c2 -hljs-string: 98c379 -hljs-regexp: 98c379 -hljs-addition: 98c379 -hljs-attribute: 98c379 -hljs-meta-string: 98c379 -hljs-built_in: e6c07b -hljs-class: e6c07b -hljs-attr: d19a66 -hljs-variable: d19a66 -hljs-template-variable: d19a66 -hljs-type: d19a66 -hljs-selector-class: d19a66 -hljs-selector-attr: d19a66 -hljs-selector-pseudo: d19a66 -hljs-number: d19a66 -hljs-symbol: 61aeee -hljs-link: underlined, 61aeee -hljs-bullet: 61aeee -hljs-meta: 61aeee -hljs-selector-id: 61aeee -hljs-title: bold, 61aeee -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: 6e7686 - -NOTE -foreground: 9575cd - -STRIKE -foreground: e57373 -font-style: strikeout - -FRONTMATTER -foreground: 6e7686 - -INLINEEQUATION -foreground: 4db6ac -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -DISPLAYFORMULA -foreground: 4db6ac -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -MARK -foreground: abb2bf -background: 551560 - -TABLE -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -TABLEBORDER -foreground: e06c75 -background: 393f4a diff --git a/src/resources/themes/v_moonlight/v_moonlight.palette b/src/resources/themes/v_moonlight/v_moonlight.palette deleted file mode 100644 index 0388bd6c..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight.palette +++ /dev/null @@ -1,393 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. - -[metadata] -qss_file=v_moonlight.qss -mdhl_file=v_moonlight.mdhl -css_file=v_moonlight.css -codeblock_css_file=v_moonlight_codeblock.css -mermaid_css_file=v_moonlight_mermaid.css -version=26 - -; This mapping will be used to translate colors when the content of HTML is copied -; without background. You could just specify the foreground colors mapping here. -; It is useful for dark mode theme. '#aabbcc' or 'red' formats are supported. -; col1:col1_new,col2:col2_new -css_color_mapping=#abb2bf:#222222,#282c34:#f5f5f5,#61afef:#0099ff,#98c379:#8e24aa,#343a45:#e0e0e0,#6e7686:#666666,#373e47:#999999,#6c6c6c:#444444,#c678dd:#0000ee,#e06c75:#880000,#56b6c2:#af00d7,#e6c07b:#008700,#d19a66:#bc6060,#61aeee:#bc6060,#ba68c8:#6a1b9a - -[phony] -; Abstract color attributes. -master_fg=@edit_fg -master_bg=#5768c4 -master_light_bg=#7482CF -master_dark_bg=#3F51B5 -master_focus_bg=#3A4AA6 -master_hover_bg=#6575CA -master_pressed_bg=#354498 - -base_fg=#9DA5B4 -base_bg=#21252B - -main_fg=@base_fg -main_bg=@base_bg - -title_fg=@base_fg -title_bg=@base_bg - -disabled_fg=#4D5765 - -content_fg=@base_fg -content_bg=@base_bg - -border_bg=#4e5666 - -separator_bg=#576071 - -hover_fg=#C9CED6 -hover_bg=#31363F - -selected_fg=#C9CED6 -selected_bg=#3A3F4B - -active_fg=@selected_fg -active_bg=@selected_bg - -inactive_fg=@hover_fg -inactive_bg=#4D5465 - -focus_fg=@hover_fg -focus_bg=@hover_bg - -pressed_fg=@hover_fg -pressed_bg=#2C303A - -edit_fg=#D7DAE0 -edit_bg=#282C34 -edit_focus_bg=#1B1D23 -edit_focus_border=@master_bg -edit_hover_bg=#313338 -edit_hover_border=@master_bg -edit_selection_fg=@edit_fg -edit_selection_bg=#4D5565 - -icon_fg=#9EA5B4 -icon_disabled_fg=@disabled_fg - -danger_fg=#F5F5F5 -danger_bg=#C9302C -danger_focus_bg=#D9534F -danger_hover_bg=#DE6764 -danger_pressed_bg=#AC2925 - -[soft_defined] -; VAvatar. -; The foreground color of the avatar when Captain mode is triggered. -avatar_captain_mode_fg=@master_fg -; The background color of the avatar when Captain mode is triggered. -avatar_captain_mode_bg=@master_bg - -; Style of the label in Navigation mode. -navigation_label_fg=@master_fg -navigation_label_bg=@master_bg - -; Style of the bubble of VButtonWithWidget. -bubble_fg=@master_fg -bubble_bg=@master_bg - -; Icons' foreground. -danger_icon_fg=@danger_bg -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg -tab_indicator_tag_label_fg=#222222 -tab_indicator_tag_label_bg=#ce93db - -; Html template. -template_title_flash_light_fg=@master_light_bg -template_title_flash_dark_fg=@master_bg - -; Search hit items in list or tree view. -search_hit_item_fg=@selected_fg -search_hit_item_bg=@master_dark_bg - -; Universal Entry CMD Edit border color -ue_cmd_busy_border=#3F51B5 -ue_cmd_fail_border=@danger_bg - -; VListWidget/VTreeWidget separator. -item_separator_fg=@master_light_bg -item_separator_bg=@separator_bg - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Separator of dock widgets. -dock_separator_bg=@border_bg -dock_separator_hover_bg=@hover_bg -dock_separator_pressed_bg=@pressed_bg - -; Menubar. -menubar_bg=@main_bg -menubar_fg=@main_fg -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_bg=@base_bg -menu_fg=@base_fg -menu_border_bg=@border_bg -menu_item_disabled_fg=@disabled_fg -menu_item_selected_fg=@selected_fg -menu_item_selected_bg=@selected_bg -menu_separator_bg=@separator_bg -menu_icon_fg=@icon_fg -menu_icon_danger_fg=@danger_icon_fg - -; Tooltip. -tooltip_bg=@master_bg -tooltip_fg=@master_fg - -; Toolbar. -toolbar_bg=@main_bg -toolbar_separator_bg=@separator_bg -toolbar_extension_bg=@base_fg -toolbutton_hover_bg=@hover_bg -toolbutton_pressed_bg=@pressed_bg -toolbutton_checked_bg=@selected_bg -toolbutton_icon_fg=@icon_fg -toolbutton_icon_danger_fg=@danger_icon_fg - -buttonmenuitem_decoration_text_fg=@master_light_bg - -; Toolbox. -toolbox_icon_fg=@master_bg -toolbox_icon_active_fg=@master_fg -toolbox_title_border=@master_bg - -; Dockwidget. -dockwidget_bg=@base_bg -dockwidget_title_fg=@title_fg -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_fg=@base_fg -pushbutton_bg=transparent -pushbutton_border=@border_bg -pushbutton_pressed_bg=@pressed_bg -pushbutton_focus_bg=@focus_bg -pushbutton_checked_bg=@selected_bg -pushbutton_hover_bg=@hover_bg -pushbutton_default_border=@master_bg -pushbutton_disabled_fg=@disabled_fg -pushbutton_disabled_bg=@pushbutton_bg - -pushbutton_specialbtn_fg=@master_fg -pushbutton_specialbtn_bg=@master_bg -pushbutton_specialbtn_focus_bg=@master_focus_bg -pushbutton_specialbtn_hover_bg=@master_hover_bg -pushbutton_specialbtn_checked_bg=@master_focus_bg -pushbutton_specialbtn_pressed_bg=@master_pressed_bg - -pushbutton_titlebtn_bg=@title_bg - -pushbutton_dangerbtn_fg=@danger_fg -pushbutton_dangerbtn_bg=@danger_bg -pushbutton_dangerbtn_hover_bg=@danger_hover_bg -pushbutton_dangerbtn_focus_bg=@danger_focus_bg -pushbutton_dangerbtn_pressed_bg=@danger_pressed_bg - -pushbutton_toolboxbtn_active_fg=@master_fg -pushbutton_toolboxbtn_active_bg=@master_bg -pushbutton_toolboxbtn_active_focus_bg=@master_focus_bg -pushbutton_toolboxbtn_active_hover_bg=@master_hover_bg -pushbutton_toolboxbtn_active_pressed_bg=@master_pressed_bg - -button_icon_fg=@icon_fg -button_icon_danger_fg=@danger_icon_fg - -; ComboBox. -combobox_border=@border_bg -combobox_fg=@content_fg -combobox_bg=@content_bg -combobox_disabled_fg=@disabled_fg -combobox_view_border=@border_bg -combobox_view_selected_bg=@selected_bg -combobox_view_selected_fg=@selected_fg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@edit_focus_bg -combobox_focus_border=@edit_focus_border -combobox_hover_bg=@edit_hover_bg -combobox_hover_border=@edit_hover_border -combobox_item_icon_fg=@item_icon_fg - -combobox_notebookselector_fg=@master_bg -combobox_notebookselector_bg=@combobox_bg -combobox_notebookselector_border=@master_bg -combobox_notebookselector_hover_fg=@master_bg -combobox_notebookselector_hover_bg=@hover_bg -combobox_notebookselector_focus_fg=@master_bg -combobox_notebookselector_focus_bg=@focus_bg - -; Label. -label_fg=@base_fg -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@edit_fg -lineedit_bg=@edit_bg -lineedit_disabled_fg=@disabled_fg -lineedit_focus_bg=@edit_focus_bg -lineedit_focus_border=@edit_focus_border -lineedit_hover_bg=@edit_hover_bg -lineedit_hover_border=@edit_hover_border -lineedit_selection_fg=@edit_selection_fg -lineedit_selection_bg=@edit_selection_bg - -; TabWidget. -tabwidget_pane_border=@selected_bg - -; TabBar. -tabbar_fg=@base_fg -tabbar_bg=@base_bg -tabbar_border=@border_bg - -tabbar_selected_fg=@edit_fg -tabbar_selected_bg=@edit_bg -tabbar_selected_border=@border_bg - -tabbar_hover_fg=@hover_fg -tabbar_hover_bg=@hover_bg - -tabbar_icon_fg=@icon_fg -tabbar_icon_special_fg=@danger_bg - -; SelectorItem. -selectoritem_border=@master_bg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; TreeView. -treeview_fg=@content_fg -treeview_bg=@content_bg -treeview_item_border_bg=@border_bg -treeview_item_hover_fg=@hover_fg -treeview_item_hover_bg=@hover_bg -treeview_item_selected_fg=@selected_fg -treeview_item_selected_bg=@selected_bg -treeview_item_selected_avtive_fg=@active_fg -treeview_item_selected_avtive_bg=@active_bg -treeview_item_selected_inactive_fg=@inactive_fg -treeview_item_selected_inactive_bg=@inactive_bg -treeview_item_icon_fg=@item_icon_fg - -; ListView. -listview_fg=@content_fg -listview_bg=@content_bg -listview_item_hover_fg=@hover_fg -listview_item_hover_bg=@hover_bg -listview_item_selected_fg=@selected_fg -listview_item_selected_bg=@selected_bg -listview_item_selected_avtive_fg=@active_fg -listview_item_selected_avtive_bg=@active_bg -listview_item_selected_inactive_fg=@inactive_fg -listview_item_selected_inactive_bg=@inactive_bg - -; QAbstractItemView for TextEdit Completer. -abstractitemview_textedit_fg=@content_fg -abstractitemview_textedit_bg=#323841 -abstractitemview_textedit_item_hover_fg=@master_fg -abstractitemview_textedit_item_hover_bg=@master_hover_bg -abstractitemview_textedit_item_selected_fg=@master_fg -abstractitemview_textedit_item_selected_bg=@master_bg -abstractitemview_textedit_item_selected_avtive_fg=@master_fg -abstractitemview_textedit_item_selected_avtive_bg=@master_focus_bg -abstractitemview_textedit_item_selected_inactive_fg=@inactive_fg -abstractitemview_textedit_item_selected_inactive_bg=@inactive_bg - -; Splitter. -splitter_handle_bg=@border_bg -splitter_handle_pressed_bg=@pressed_bg - -; StatusBar. -statusbar_fg=@main_fg -statusbar_bg=@main_bg -statusbar_border=@border_bg - -; ScrollBar. -scrollbar_bg=@base_bg -scrollbar_page_bg=transparent -scrollbar_handle_bg=#353B45 -scrollbar_handle_hover_bg=#424A56 -scrollbar_handle_pressed_bg=@hover_bg - -; VEditWindow. -editwindow_corner_icon_fg=@master_bg -editwindow_corner_icon_inactive_fg=@icon_fg - -; CheckBox. -checkbox_disabled_fg=@disabled_fg -checkbox_indicator_focus_bg=@focus_bg -checkbox_indicator_hover_bg=@hover_bg -checkbox_indicator_pressed_bg=@pressed_bg - -; RadioButton. -radiobutton_disabled_fg=@disabled_fg -radiobutton_indicator_focus_bg=@focus_bg -radiobutton_indicator_hover_bg=@hover_bg -radiobutton_indicator_pressed_bg=@pressed_bg - -; SpinBox. -spinbox_fg=@edit_fg -spinbox_bg=@edit_bg -spinbox_border=@border_bg -spinbox_selection_fg=@edit_selection_fg -spinbox_selection_bg=@edit_selection_bg -spinbox_focus_border=@edit_focus_border -spinbox_focus_bg=@edit_focus_bg -spinbox_hover_border=@edit_hover_border -spinbox_hover_bg=@edit_hover_bg -spinbox_button_hover_bg=@hover_bg -spinbox_button_pressed_bg=@pressed_bg - -; HeaderView. -headerview_bg=#30333D -headerview_fg=@base_fg -headerview_border=@border_bg -headerview_checked_fg=@selected_fg -headerview_checked_bg=@selected_bg - -; ProgressBar. -progressbar_bg=@edit_bg -progressbar_border_bg=@border_bg -progressbar_chunk_bg=@master_dark_bg - -universalentry_bg=@base_bg -universalentry_border_bg=@border_bg - -doublerowitem_second_row_label_fg=#808080 - -; GroupBox. -groupbox_border=@border_bg -groupbox_title_fg=@base_fg - -; Slider. -slider_border_bg=@border_bg -slider_groove_bg=@edit_bg -slider_handle_bg=@master_bg -slider_subpage_bg=@master_dark_bg diff --git a/src/resources/themes/v_moonlight/v_moonlight.qss b/src/resources/themes/v_moonlight/v_moonlight.qss deleted file mode 100644 index caa8022a..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight.qss +++ /dev/null @@ -1,1469 +0,0 @@ -QToolTip -{ - border: none; - background: @tooltip_bg; - color: @tooltip_fg; -} - -/* QMainWindow */ -QMainWindow { - color: @base_fg; - background: @base_bg; -} - -QMainWindow::separator { - background: @dock_separator_bg; - width: $2px; - height: $2px; -} - -QMainWindow::separator:hover { - background: @dock_separator_hover_bg; -} - -QMainWindow::separator:pressed { - background: @dock_separator_pressed_bg; -} -/* End QMainWindow */ - -QMenuBar { - border: none; - background: @menubar_bg; - color: @menubar_fg; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} - -/* QMenu */ -QMenu { - background: @menu_bg; - color: @menu_fg; - border: $2px solid @menu_border_bg; -} - -QMenu::icon { - margin: $5px; -} - -QMenu::item { - padding: $5px $30px $5px $30px; - border: $1px solid transparent; -} - -QMenu::item:selected { - color: @menu_item_selected_fg; - background: @menu_item_selected_bg; -} - -QMenu::item:disabled { - color: @menu_item_disabled_fg; -} - -QMenu::icon:checked { /* appearance of a 'checked' icon */ - border: $2px solid @menu_fg; -} - -QMenu::separator { - height: $2px; - background: @menu_separator_bg; - margin-left: $10px; - margin-right: $5px; -} - -QMenu::indicator { - width: $20px; - height: $20px; -} - -QMenu::indicator:non-exclusive:unchecked { - image: none; -} - -QMenu::indicator:non-exclusive:checked { - image: url(menu_checkbox.svg); -} - -QMenu::indicator:exclusive:unchecked { - image: none; -} - -QMenu::indicator:exclusive:checked { - image: url(menu_radiobutton.svg); -} -/* End QMenu */ - -QToolBar { - border: none; - background: @toolbar_bg; -} - -QToolBar::separator { - width: 1px; - height: 1px; - border: none; - background: @toolbar_separator_bg; -} - -/* QToolButton */ -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: $16px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: $10px; /* make way for the popup button */ -} - -QToolButton { - border: none; - background: transparent; - margin: 1px 3px 1px 3px; - padding: 0px; -} - -QToolButton:checked { - background: @toolbutton_checked_bg; -} - -QToolButton:hover { - border:none; - background: @toolbutton_hover_bg; -} - -QToolButton:pressed { - background: @toolbutton_pressed_bg; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: none; - width: $16px; -} - -QToolButton::menu-arrow { - image: url(arrow_dropdown.svg); - width: $16px; - height: $16px; -} - -QToolBarExtension { - background: @toolbar_extension_bg; -} -/* End QToolButton*/ - -/* DockWidget */ -QDockWidget { - color: @dockwidget_title_fg; - background: @dockwidget_bg; - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; - icon-size: $16px; - width: $16px; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} - -QDockWidget::close-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: 0px; bottom: 0px; -} - -QDockWidget::float-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: $18px; bottom: 0px; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton[SpecialBtn="true"] { - color: @pushbutton_specialbtn_fg; - background: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:focus { - background-color: @pushbutton_specialbtn_focus_bg; -} - -QPushButton[SpecialBtn="true"]:checked { - background-color: @pushbutton_specialbtn_checked_bg; -} - -QPushButton[SpecialBtn="true"]:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:pressed { - background-color: @pushbutton_specialbtn_pressed_bg; -} - -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; - min-width: -1; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"] { - color: @pushbutton_dangerbtn_fg; - border: none; - background-color: @pushbutton_dangerbtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_dangerbtn_bg; -} - -QPushButton[DangerBtn="true"]:focus { - background-color: @pushbutton_dangerbtn_focus_bg; -} - -QPushButton[DangerBtn="true"]:checked { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[DangerBtn="true"]:hover { - background-color: @pushbutton_dangerbtn_hover_bg; -} - -QPushButton[DangerBtn="true"]:pressed { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"] { - padding: 4px 10px 4px 4px; - margin: 0px; - border: none; - font-weight: bold; - color: @pushbutton_toolboxbtn_active_fg; - background-color: @pushbutton_toolboxbtn_active_bg; - min-width: -1; -} - -QPushButton[ToolBoxActiveBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_toolboxbtn_active_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:focus { - background-color: @pushbutton_toolboxbtn_active_focus_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:hover { - background-color: @pushbutton_toolboxbtn_active_hover_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:pressed { - background-color: @pushbutton_toolboxbtn_active_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[AvatarBtn="true"] { - padding: 2px 4px 2px 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton { - color: @pushbutton_fg; - background: @pushbutton_bg; - border: 1px solid @pushbutton_border; - padding: 3px; - min-width: 80px; -} - -QPushButton:default { - border: 1px solid @pushbutton_default_border; -} - -QPushButton:focus { - background-color: @pushbutton_focus_bg; -} - -QPushButton:checked { - background-color: @pushbutton_checked_bg; -} - -QPushButton:flat { - border: none; -} - -QPushButton:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:pressed { - background-color: @pushbutton_pressed_bg; -} - -QPushButton:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton::menu-indicator { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - min-width: -1; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox#NotebookSelector { - border: none; - font-size: 12pt; - padding-top: 5px; - padding-bottom: 5px; - icon-size: $24px; - font-weight: bold; - color: @combobox_notebookselector_fg; - background: @combobox_notebookselector_bg; -} - -QComboBox#NotebookSelector:focus, QComboBox#NotebookSelector:on { - color: @combobox_notebookselector_focus_fg; - background: @combobox_notebookselector_focus_bg; -} - -QComboBox#NotebookSelector:hover { - color: @combobox_notebookselector_hover_fg; - background: @combobox_notebookselector_hover_bg; -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 12pt; - font-weight: normal; - icon-size: $24px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: $5px; - padding-bottom: $5px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} - -QComboBox { - padding: 3px; - color: @combobox_fg; - background: @combobox_bg; - border: 1px solid @combobox_border; -} - -QComboBox:focus, QComboBox:on { - background-color: @combobox_focus_bg; - border: 2px solid @combobox_focus_border; -} - -QComboBox:hover { - background-color: @combobox_hover_bg; - border: 2px solid @combobox_hover_border; -} - -QComboBox:disabled { - color: @combobox_disabled_fg; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: $20px; - border: none; - background: transparent; -} - -QComboBox::down-arrow { - image: url(arrow_dropdown.svg); - width: $20px; - height: $20px; -} - -QComboBox::down-arrow:disabled { - image: url(arrow_dropdown_disabled.svg); - width: $20px; - height: $20px; -} - -QComboBox QAbstractItemView { - padding: 2px; - border: 1px solid @combobox_view_border; - background: @combobox_bg; - selection-color: @combobox_view_selected_fg; - selection-background-color: @combobox_view_selected_bg; -} - -QComboBox QAbstractItemView::item { - background: transparent; - padding: 3px; -} - -QComboBox QAbstractItemView::item:hover { - color: @combobox_view_item_hover_fg; - background: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #00796B; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -QLabel[TagLabel="true"] { - padding-left: $5px; - padding-right: $5px; - color: @tab_indicator_tag_label_fg; - background-color: @tab_indicator_tag_label_bg; -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: $2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VDoubleRowItemWidget QLabel[FirstRowLabel="true"] { - border: none; - font-size: 10pt; -} - -VDoubleRowItemWidget QLabel[SecondRowLabel="true"] { - border: none; - font-size: 9pt; - color: @doublerowitem_second_row_label_fg; -} - -QLabel { - border: none; - color: @label_fg; - background: transparent; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} - -QLineEdit[VimCommandLine="true"]:focus { - border: none; - background: @lineedit_focus_bg; -} - -QLineEdit[VimCommandLine="true"]:hover { - border: none; - background: @lineedit_hover_bg; -} - -QLineEdit[EmbeddedEdit="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: transparent; -} - -QLineEdit[EmbeddedEdit="true"]:focus { - background: @lineedit_focus_bg; - border: none; -} - -QLineEdit[EmbeddedEdit="true"]:hover { - background: @lineedit_hover_bg; - border: none; -} - -QLineEdit { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QLineEdit:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QLineEdit:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} - -QLineEdit:disabled { - color: @lineedit_disabled_fg; -} -/* End QLineEdit */ - -/* QPlainTextEdit QTextEdit */ -QPlainTextEdit[LineEdit="true"], QTextEdit[LineEdit="true"] { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QPlainTextEdit[LineEdit="true"]:focus, QTextEdit[LineEdit="true"]:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QPlainTextEdit[LineEdit="true"]:hover, QTextEdit[LineEdit="true"]:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} -/* End QPlainTextEdit QTextEdit */ - -/* QTabWidget */ -QTabWidget { - border: none; -} - -QTabWidget::pane { - border: none; -} - -QTabWidget::tab-bar { - alignment: left; -} -/* End QTabWidget */ - -/* QTabBar */ -QTabBar::tab { - color: @tabbar_fg; - background: @tabbar_bg; - border: none; -} - -QTabBar::tab:top, QTabBar::tab:bottom { - border-top: $2px solid transparent; - border-right: $1px solid @tabbar_border; - /* MUST leave right and left padding 0px. */ - padding: $2px 0px $2px 0px; - height: $20px; -} - -QTabBar::tab:right { - border-left: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:left { - border-right: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:hover { - color: @tabbar_hover_fg; - background: @tabbar_hover_bg; -} - -QTabBar::tab:selected { - color: @tabbar_selected_fg; - background: @tabbar_selected_bg; -} - -QTabBar::tab:top:selected, QTabBar::tab:bottom:selected { - border-top: $2px solid @master_bg; -} - -QTabBar::tab:right:selected { - border-left: $3px solid @master_bg; -} - -QTabBar::tab:left:selected { - border-right: $3px solid @master_bg; -} - -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:focus { - image: url(close.svg); -} - -QTabBar::close-button:hover { - image: url(close.svg); -} - -QTabBar::scroller { - width: $20px; -} - -QTabBar QToolButton { - border: none; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(right.svg); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(left.svg); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(right_disabled.svg); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(left_disabled.svg); -} -/* End QTabBar */ - -/* QTreeView */ -QTreeView[ItemBorder="true"]::item { - padding-top: 5px; - padding-bottom: 5px; - border-bottom: $1px solid @treeview_item_border_bg; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-children:!has-siblings:closed, -QTreeView[PlainTree="true"]::branch:closed:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView[PlainTree="true"]::branch:open:has-children:!has-siblings, -QTreeView[PlainTree="true"]::branch:open:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView { - color: @treeview_fg; - background: @treeview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QTreeView::item:hover { - color: @treeview_item_hover_fg; - background: @treeview_item_hover_bg; -} - -QTreeView::item:selected { - color: @treeview_item_selected_fg; - background: @treeview_item_selected_bg; -} - -QTreeView::item:selected:active { - color: @treeview_item_selected_active_fg; - background: @treeview_item_selected_active_bg; -} - -QTreeView::item:selected:!active { - color: @treeview_item_selected_inactive_fg; - background: @treeview_item_selected_inactive_bg; -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(branch_closed.svg); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(branch_open.svg); -} -/* End QTreeView */ - -/* QListView */ -QListView { - color: @listview_fg; - background: @listview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QListView::item:hover { - color: @listview_item_hover_fg; - background: @listview_item_hover_bg; -} - -QListView::item:selected { - color: @listview_item_selected_fg; - background: @listview_item_selected_bg; -} - -QListView::item:selected:active { - color: @listview_item_selected_active_fg; - background: @listview_item_selected_active_bg; -} - -QListView::item:selected:!active { - color: @listview_item_selected_inactive_fg; - background: @listview_item_selected_inactive_bg; -} - -QListView::item:disabled { - background: transparent; -} -/* End QListView */ - -/* QAbstractItemView for TextEdit Completer popup*/ -QAbstractItemView[TextEdit="true"] { - color: @abstractitemview_textedit_fg; - background: @abstractitemview_textedit_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QAbstractItemView[TextEdit="true"]::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QAbstractItemView[TextEdit="true"]::item:hover { - color: @abstractitemview_textedit_item_hover_fg; - background: @abstractitemview_textedit_item_hover_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected { - color: @abstractitemview_textedit_item_selected_fg; - background: @abstractitemview_textedit_item_selected_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:active { - color: @abstractitemview_textedit_item_selected_active_fg; - background: @abstractitemview_textedit_item_selected_active_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:!active { - color: @abstractitemview_textedit_item_selected_inactive_fg; - background: @abstractitemview_textedit_item_selected_inactive_bg; -} - -QAbstractItemView[TextEdit="true"]::item:disabled { - background: transparent; -} -/* End QAbstractItemView */ - -/* QSplitter */ -QSplitter#MainSplitter { - border: none; - margin-left: $3px; -} - -QSplitter { - border: none; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:pressed { - background-color: @splitter_handle_pressed_bg; -} - -QSplitter::handle:vertical { - height: $2px; -} - -QSplitter::handle:horizontal { - width: $2px; -} -/* End QSplitter */ - -/* QStatusBar */ -QStatusBar { - color: @statusbar_fg; - background: @statusbar_bg; - border-top: 1px solid @statusbar_border; -} -/* End QStatusBar */ - -QDialog { - color: @base_fg; - background: @base_bg; -} - -/* QScrollBar */ -QScrollBar::add-page, QScrollBar::sub-page { - background: @scrollbar_page_bg; -} - -QScrollBar:vertical { - background: @scrollbar_bg; - width: $16px; - margin: $16px 0px $16px 0px; - padding: 0px $2px 0px $2px; - border: none; -} - -QScrollBar::handle:vertical { - background: @scrollbar_handle_bg; - min-height: $16px; -} - -QScrollBar::handle:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::down-arrow:vertical { - image: url(down.svg); - width: $16px; - height: $16px; -} - -QScrollBar::up-arrow:vertical { - image: url(up.svg); - width: $16px; - height: $16px; -} - -QScrollBar:horizontal { - background: @scrollbar_bg; - height: $16px; - margin: 0px $16px 0px $16px; - padding: $2px 0px $2px 0px; - border: none; -} - -QScrollBar::handle:horizontal { - background: @scrollbar_handle_bg; - min-width: $16px; -} - -QScrollBar::handle:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::right-arrow:horizontal { - image: url(right.svg); - width: $16px; - height: $16px; -} - -QScrollBar::left-arrow:horizontal { - image: url(left.svg); - width: $16px; - height: $16px; -} -/* End QScrollBar */ - -/* QCheckBox */ -QCheckBox { - spacing: $5px; -} - -QCheckBox:disabled { - color: @checkbox_disabled_fg; -} - -QCheckBox::indicator:unchecked { - image: url(checkbox_unchecked.svg); -} - -QCheckBox::indicator:unchecked:disabled { - image: url(checkbox_unchecked_disabled.svg); -} - -QCheckBox::indicator:checked { - image: url(checkbox_checked.svg); -} - -QCheckBox::indicator:checked:disabled { - image: url(checkbox_checked_disabled.svg); -} - -QCheckBox::indicator { - width: $20px; - height: $20px; -} - -QCheckBox::indicator:focus { - background: @checkbox_indicator_focus_bg; -} - -QCheckBox::indicator:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:pressed { - background: @checkbox_indicator_pressed_bg; -} -/* End QCheckBox */ - -/* QRadioButton */ -QRadioButton { - spacing: $5px; -} - -QRadioButton:disabled { - color: @radiobutton_disabled_fg; -} - -QRadioButton::indicator:unchecked { - image: url(radiobutton_unchecked.svg); -} - -QRadioButton::indicator:unchecked:disabled { - image: url(radiobutton_unchecked_disabled.svg); -} - -QRadioButton::indicator:checked { - image: url(radiobutton_checked.svg); -} - -QRadioButton::indicator:checked:disabled { - image: url(radiobutton_checked_disabled.svg); -} - -QRadioButton::indicator { - width: $20px; - height: $20px; -} - -QRadioButton::indicator:focus { - background: @radiobutton_indicator_focus_bg; -} - -QRadioButton::indicator:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:pressed { - background: @radiobutton_indicator_pressed_bg; -} -/* End QRadioButton */ - -/* QSpinBox */ -QSpinBox, QDoubleSpinBox { - border: 1px solid @spinbox_border; - color: @spinbox_fg; - background: @spinbox_bg; - padding-right: $25px; - min-height: $25px; - selection-color: @spinbox_selection_fg; - selection-background-color: @spinbox_selection_bg; -} - -QSpinBox:focus, QDoubleSpinBox::focus { - border: 2px solid @spinbox_focus_border; - background: @spinbox_focus_bg; -} - -QSpinBox:hover, QDoubleSpinBox::hover { - border: 2px solid @spinbox_hover_border; - background: @spinbox_hover_bg; -} - -QSpinBox::up-button, QDoubleSpinBox::up-button { - subcontrol-origin: border; - subcontrol-position: top right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} - -QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off, QDoubleSpinBox::up-arrow:disabled, QDoubleSpinBox::up-arrow:off { - image: url(up_disabled.svg); -} - -QSpinBox::down-button, QDoubleSpinBox::down-button { - subcontrol-origin: border; - subcontrol-position: bottom right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off, QDoubleSpinBox::down-arrow:disabled, QDoubleSpinBox::down-arrow:off { - image: url(down_disabled.svg); -} -/* End QSpinBox */ - -/* QHeaderView */ -QHeaderView::section { - background: @headerview_bg; - color: @headerview_fg; - padding-left: 4px; - border: none; - border-left: 1px solid @headerview_border; - border-bottom: 1px solid @headerview_border; -} - -QHeaderView::section:checked -{ - color: @headerview_checked_fg; - background: @headerview_checked_bg; -} - -/* style the sort indicator */ -QHeaderView::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QHeaderView::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} -/* End QHeaderView */ - -QAbstractScrollArea::corner { - background: @scrollbar_bg; - border: none; -} - -/* QProgressBar */ -QProgressBar { - background: @progressbar_bg; - border: $1px solid @progressbar_border_bg; - text-align: center; -} - -QProgressBar::chunk { - background-color: @progressbar_chunk_bg; - width: $20px; -} -/* End QProgressBar */ - -/* QGroupBox */ -QGroupBox { - border: 2px solid @groupbox_border; - border-radius: 5px; - margin-top: 2ex; -} - -QGroupBox::title { - color: @groupbox_title_fg; - subcontrol-origin: margin; - subcontrol-position: top left; - position: absolute; - padding: 0 $3px; - top: 0px; left: $10px; bottom: 0px; -} -/* End QGroupBox */ - -/* QSlider */ -QSlider::groove:horizontal { - border: $1px solid @slider_border_bg; - height: $8px; - background: @slider_groove_bg; - margin: $2px 0; -} - -QSlider::handle:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - width: $18px; - margin: $-2px 0; -} - -QSlider::add-page:horizontal { - background: transparent; -} - -QSlider::sub-page:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: $2px 0; -} - -QSlider::groove:vertical { - border: $1px solid @slider_border_bg; - width: $8px; - background: @slider_groove_bg; - margin: 0 $2px; -} - -QSlider::handle:vertical { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - height: $18px; - margin: 0 $-2px; -} - -QSlider::add-page:vertical { - background: transparent; -} - -QSlider::sub-page:vertical { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: 0 $2px; -} -/* End QSlider */ - -/* QWidget */ -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} - -QWidget[ToolBoxTitle="true"] { - border-bottom: 2px solid @toolbox_title_border; -} - -QWidget[ToolBoxTitle="true"] QPushButton[ToolBoxTitleBtn="true"] { - height: $20px; -} - -QWidget[MainEditor="true"] { - border: none; -} - -QWidget -{ - color: @widget_fg; - font-family: "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", "Dengxian", "等线体", "STXihei", "华文细黑", "Liberation Sans", "Droid Sans", "NSimSun", "新宋体", "SimSun", "宋体", "Helvetica", "sans-serif", "Tahoma", "Arial", "Verdana", "Geneva", "Georgia", "Times New Roman"; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} - -VUniversalEntry { - background: transparent; - border: 1px solid @universalentry_border_bg; -} -/* End QWidget */ diff --git a/src/resources/themes/v_moonlight/v_moonlight_codeblock.css b/src/resources/themes/v_moonlight/v_moonlight_codeblock.css deleted file mode 100644 index 2fbd2b1e..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight_codeblock.css +++ /dev/null @@ -1,96 +0,0 @@ -/* - -Atom One Dark by Daniel Gamage -Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax - -base: #343a45 -mono-1: #abb2bf -mono-2: #818896 -mono-3: #5c6370 -hue-1: #56b6c2 -hue-2: #61aeee -hue-3: #c678dd -hue-4: #98c379 -hue-5: #e06c75 -hue-5-2: #be5046 -hue-6: #d19a66 -hue-6-2: #e6c07b - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #abb2bf; - background: #343a45; -} - -.hljs-comment, -.hljs-quote { - color: #6e7686; - font-style: italic; -} - -.hljs-doctag, -.hljs-keyword, -.hljs-formula { - color: #c678dd; -} - -.hljs-section, -.hljs-name, -.hljs-selector-tag, -.hljs-deletion, -.hljs-subst { - color: #e06c75; -} - -.hljs-literal { - color: #56b6c2; -} - -.hljs-string, -.hljs-regexp, -.hljs-addition, -.hljs-attribute, -.hljs-meta-string { - color: #98c379; -} - -.hljs-built_in, -.hljs-class .hljs-title { - color: #e6c07b; -} - -.hljs-attr, -.hljs-variable, -.hljs-template-variable, -.hljs-type, -.hljs-selector-class, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-number { - color: #d19a66; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link, -.hljs-meta, -.hljs-selector-id, -.hljs-title { - color: #61aeee; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-link { - text-decoration: underline; -} diff --git a/src/resources/themes/v_moonlight/v_moonlight_mermaid.css b/src/resources/themes/v_moonlight/v_moonlight_mermaid.css deleted file mode 100644 index 04400586..00000000 --- a/src/resources/themes/v_moonlight/v_moonlight_mermaid.css +++ /dev/null @@ -1,416 +0,0 @@ -/* Flowchart variables */ -/* Sequence Diagram variables */ -/* Gantt chart variables */ -.mermaid-diagram .mermaid .label { - font-family: 'trebuchet ms', verdana, arial; - color: #333; -} - -.mermaid-diagram .node rect, -.mermaid-diagram .node circle, -.mermaid-diagram .node ellipse, -.mermaid-diagram .node polygon { - fill: #cde498; - stroke: #13540c; - stroke-width: 1px; -} - -.mermaid-diagram .edgePath .path { - stroke: green; - stroke-width: 1.5px; -} - -.mermaid-diagram .edgeLabel { - background-color: #e8e8e8; -} - -.mermaid-diagram .cluster rect { - fill: #cdffb2 !important; - rx: 4 !important; - stroke: #6eaa49 !important; - stroke-width: 1px !important; -} - -.mermaid-diagram .cluster text { - fill: #333; -} - -.mermaid-diagram .actor { - stroke: #13540c; - fill: #cde498; -} - -.mermaid-diagram text.actor { - fill: black; - stroke: none; -} - -.mermaid-diagram .actor-line { - stroke: blue; -} - -.mermaid-diagram .messageLine0 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #333; -} - -.mermaid-diagram .messageLine1 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - stroke: #333; -} - -.mermaid-diagram #arrowhead { - fill: #333; -} - -.mermaid-diagram #crosshead path { - fill: #333 !important; - stroke: #333 !important; -} - -.mermaid-diagram .messageText { - fill: #333; - stroke: none; -} - -.mermaid-diagram .labelBox { - stroke: #326932; - fill: #cde498; -} - -.mermaid-diagram .labelText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopLine { - stroke-width: 2; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #326932; -} - -.mermaid-diagram .note { - stroke: #6eaa49; - fill: #fff5ad; -} - -.mermaid-diagram .noteText { - fill: black; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -/** Section styling */ -.mermaid-diagram .section { - stroke: none; - opacity: 0.2; -} - -.mermaid-diagram .section0 { - fill: #6eaa49; -} - -.mermaid-diagram .section2 { - fill: #6eaa49; -} - -.mermaid-diagram .section1, -.mermaid-diagram .section3 { - fill: white; - opacity: 0.2; -} - -.mermaid-diagram .sectionTitle0 { - fill: #333; -} - -.mermaid-diagram .sectionTitle1 { - fill: #333; -} - -.mermaid-diagram .sectionTitle2 { - fill: #333; -} - -.mermaid-diagram .sectionTitle3 { - fill: #333; -} - -.mermaid-diagram .sectionTitle { - text-anchor: start; - font-size: 11px; - text-height: 14px; -} - -/* Grid and axis */ -.mermaid-diagram .grid .tick { - stroke: lightblue; - opacity: 0.3; - shape-rendering: crispEdges; -} - -.mermaid-diagram .grid path { - stroke-width: 0; -} - -/* Today line */ -.mermaid-diagram .today { - fill: none; - stroke: red; - stroke-width: 2px; -} - -/* Task styling */ -/* Default task */ -.mermaid-diagram .task { - stroke-width: 2; -} - -.mermaid-diagram .taskText { - text-anchor: middle; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideRight { - fill: black; - text-anchor: start; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideLeft { - fill: black; - text-anchor: end; - font-size: 11px; -} - -/* Specific task settings for the sections*/ -.mermaid-diagram .taskText0, -.mermaid-diagram .taskText1, -.mermaid-diagram .taskText2, -.mermaid-diagram .taskText3 { - fill: white; -} - -.mermaid-diagram .task0, -.mermaid-diagram .task1, -.mermaid-diagram .task2, -.mermaid-diagram .task3 { - fill: #487e3a; - stroke: #13540c; -} - -.mermaid-diagram .taskTextOutside0, -.mermaid-diagram .taskTextOutside2 { - fill: black; -} - -.mermaid-diagram .taskTextOutside1, -.mermaid-diagram .taskTextOutside3 { - fill: black; -} - -/* Active task */ -.mermaid-diagram .active0, -.mermaid-diagram .active1, -.mermaid-diagram .active2, -.mermaid-diagram .active3 { - fill: #cde498; - stroke: #13540c; -} - -.mermaid-diagram .activeText0, -.mermaid-diagram .activeText1, -.mermaid-diagram .activeText2, -.mermaid-diagram .activeText3 { - fill: black !important; -} - -/* Completed task */ -.mermaid-diagram .done0, -.mermaid-diagram .done1, -.mermaid-diagram .done2, -.mermaid-diagram .done3 { - stroke: blue; - fill: lightblue; - stroke-width: 2; -} - -.mermaid-diagram .doneText0, -.mermaid-diagram .doneText1, -.mermaid-diagram .doneText2, -.mermaid-diagram .doneText3 { - fill: black !important; -} - -/* Tasks on the critical line */ -.mermaid-diagram .crit0, -.mermaid-diagram .crit1, -.mermaid-diagram .crit2, -.mermaid-diagram .crit3 { - stroke: #ff8888; - fill: red; - stroke-width: 2; -} - -.mermaid-diagram .activeCrit0, -.mermaid-diagram .activeCrit1, -.mermaid-diagram .activeCrit2, -.mermaid-diagram .activeCrit3 { - stroke: #ff8888; - fill: #cde498; - stroke-width: 2; -} - -.mermaid-diagram .doneCrit0, -.mermaid-diagram .doneCrit1, -.mermaid-diagram .doneCrit2, -.mermaid-diagram .doneCrit3 { - stroke: #ff8888; - fill: lightblue; - stroke-width: 2; - cursor: pointer; - shape-rendering: crispEdges; -} - -.mermaid-diagram .doneCritText0, -.mermaid-diagram .doneCritText1, -.mermaid-diagram .doneCritText2, -.mermaid-diagram .doneCritText3 { - fill: black !important; -} - -.mermaid-diagram .activeCritText0, -.mermaid-diagram .activeCritText1, -.mermaid-diagram .activeCritText2, -.mermaid-diagram .activeCritText3 { - fill: black !important; -} - -.mermaid-diagram .titleText { - text-anchor: middle; - font-size: 18px; - fill: black; -} - -.mermaid-diagram g.classGroup text { - fill: #13540c; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -.mermaid-diagram g.classGroup rect { - fill: #cde498; - stroke: #13540c; -} - -.mermaid-diagram g.classGroup line { - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram svg .classLabel .box { - stroke: none; - stroke-width: 0; - fill: #cde498; - opacity: 0.5; -} - -.mermaid-diagram svg .classLabel .label { - fill: #13540c; -} - -.mermaid-diagram .relation { - stroke: #13540c; - stroke-width: 1; - fill: none; -} - -.mermaid-diagram .composition { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #compositionStart { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #compositionEnd { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram .aggregation { - fill: #cde498; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #aggregationStart { - fill: #cde498; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #aggregationEnd { - fill: #cde498; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #dependencyStart { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #dependencyEnd { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #extensionStart { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram #extensionEnd { - fill: #13540c; - stroke: #13540c; - stroke-width: 1; -} - -.mermaid-diagram .node text { - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -.mermaid-diagram div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: 'trebuchet ms', verdana, arial; - font-size: 12px; - background: #cdffb2; - border: 1px solid #6eaa49; - border-radius: 2px; - pointer-events: none; - z-index: 100; -} diff --git a/src/resources/themes/v_native/arrow_dropdown.svg b/src/resources/themes/v_native/arrow_dropdown.svg deleted file mode 100644 index 97f5c1dd..00000000 --- a/src/resources/themes/v_native/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_native/arrow_dropdown_disabled.svg b/src/resources/themes/v_native/arrow_dropdown_disabled.svg deleted file mode 100644 index 6739d7de..00000000 --- a/src/resources/themes/v_native/arrow_dropdown_disabled.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_native/close.svg b/src/resources/themes/v_native/close.svg deleted file mode 100644 index aa6b81c1..00000000 --- a/src/resources/themes/v_native/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_native/close_grey.svg b/src/resources/themes/v_native/close_grey.svg deleted file mode 100644 index 24bddd4e..00000000 --- a/src/resources/themes/v_native/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_native/float.svg b/src/resources/themes/v_native/float.svg deleted file mode 100644 index 3c29db9a..00000000 --- a/src/resources/themes/v_native/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_native/v_native.css b/src/resources/themes/v_native/v_native.css deleted file mode 100644 index a2b3adf2..00000000 --- a/src/resources/themes/v_native/v_native.css +++ /dev/null @@ -1,292 +0,0 @@ -body { - margin: 0 auto; - font-family: "Segoe UI", Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Palatino, "Times New Roman", "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", Dengxian, "等线体", STXihei, "华文细黑", "Liberation Sans", "Droid Sans", NSimSun, "新宋体", SimSun, "宋体"; - color: #222222; - line-height: 1.5; - padding: 15px; - font-size: 16px; -} - -h1, h2, h3, h4, h5, h6 { - color: #222222; - font-weight: bold; - margin-top: 20px; - margin-bottom: 10px; - padding: 0; -} - -p { - padding: 0; - margin-top: 16px; - margin-bottom: 16px; -} - -h1 { - font-size: 26px; -} - -h2 { - font-size: 24px; -} - -h3 { - font-size: 22px; -} - -h4 { - font-size: 20px; -} - -h5 { - font-size: 19px; -} - -h6 { - font-size: 18px; -} - -a { - color: #0099ff; - margin: 0; - padding: 0; - vertical-align: baseline; - text-decoration: none; - word-break: break-word; -} - -a:hover { - text-decoration: underline; - color: #ff6600; -} - -a:visited { - color: purple; -} - -ul, ol { - padding: 0; - padding-left: 24px; -} - -li { - line-height: 24px; -} - -li ul, li ol { - margin-left: 16px; -} - -p, ul, ol { - font-size: 16px; - line-height: 24px; -} - -pre { - display: block; - overflow-y: hidden; - overflow-x: auto; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -code { - font-family: Consolas, Monaco, Monospace, Courier; - color: #8E24AA; - word-break: break-word; -} - -pre code { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #222222; - background-color: #E0E0E0; - line-height: 1.5; - font-family: Consolas, Monaco, Monospace, Courier; - white-space: pre; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -pre code.markdown-metadata { - border-left: .5em solid #00897B; -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - color: #666; - border-left: .5em solid #7A7A7A; - padding: 0 1em; - margin-left: 0; -} - -blockquote p { - color: #666; -} - -hr { - display: block; - text-align: left; - margin: 1em 0; - border: none; - height: 2px; - background: #999; -} - -table { - padding: 0; - margin: 1rem 0.5rem; - border-collapse: collapse; -} - -table tr { - border-top: 2px solid #cccccc; - background-color: white; - margin: 0; - padding: 0; -} - -table tr:nth-child(2n) { - background-color: #f8f8f8; -} - -table tr th { - font-weight: bold; - border: 2px solid #cccccc; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 2px solid #cccccc; - margin: 0; - padding: 6px 13px; -} - -table tr th :first-child, table tr td :first-child { - margin-top: 0; -} - -table tr th :last-child, table tr td :last-child { - margin-bottom: 0; -} - -div.mermaid-diagram { - margin: 16px 0px 16px 0px; - overflow-y: hidden; -} - -div.flowchart-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -div.wavedrom-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -div.plantuml-diagram { - padding: 5px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -.img-package { - text-align: center; -} - -img.img-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -span.img-caption { - min-width: 20%; - max-width: 80%; - display: inline-block; - padding: 10px; - margin: 0 auto; - border-bottom: 1px solid #c0c0c0; - color: #6c6c6c; - text-align: center; - line-height: 1.5; -} - -.emoji_zero,.emoji_one,.emoji_two,.emoji_three,.emoji_four,.emoji_five,.emoji_six,.emoji_seven,.emoji_eight,.emoji_nine { - margin-left: 5px; - margin-right: 8px; -} - -div.preview-hint { - opacity: 0.5; - margin-top: 30%; - margin-bottom: 30%; - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; -} - -/* For Highlight.js Line Number */ -table.hljs-ln tr { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td.hljs-ln-numbers { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - text-align: center; - color: #AAA; - border-right: 1px solid #CCC; - vertical-align: top; - padding-right: 5px; - white-space: nowrap; -} - -table.hljs-ln tr td.hljs-ln-code { - padding-left: 10px; -} - -::selection { - background: #1976D2; - color: white; -} - -.modal-box { - background-color: rgb(245, 245, 245); - background-color: rgba(245, 245, 245, 0.95); -} - -span.modal-close { - color: #666666; -} - -span.modal-close:hover, -span.modal-close:focus { - color: #222222; -} diff --git a/src/resources/themes/v_native/v_native.mdhl b/src/resources/themes/v_native/v_native.mdhl deleted file mode 100644 index 52bde867..00000000 --- a/src/resources/themes/v_native/v_native.mdhl +++ /dev/null @@ -1,208 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Verdana, Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Times New Roman -font-size: 12 -foreground: 363636 -# [VNote] Style for trailing space -trailing-space: a8a8a8 -# [VNote] Style for line number -line-number-background: f5f5f5 -line-number-foreground: 424242 -# [VNote] Style for selected word highlight -selected-word-foreground: 222222 -selected-word-background: dfdf00 -# [VNote] Style for searched word highlight -searched-word-foreground: 222222 -searched-word-background: 4db6ac -# [VNote] Style for searched word under cursor highlight -searched-word-cursor-foreground: 222222 -searched-word-cursor-background: 66bb6a -# [VNote] Style for incremental searched word highlight -incremental-searched-word-foreground: 222222 -incremental-searched-word-background: ce93d8 -# [VNote] Style for color column in fenced code block -color-column-background: dd0000 -color-column-foreground: ffff00 -# [VNote] Style for preview image line -preview-image-line-foreground: 9575cd - -editor-selection -foreground: ffffff -background: 1976d2 - -editor-current-line -background: c5cae9 -# [VNote] Vim insert mode cursor line background -vim-insert-background: c5cae9 -# [VNote] Vim normal mode cursor line background -vim-normal-background: e0e0e0 -# [VNote] Vim visual mode cursor line background -vim-visual-background: ffe0b2 -# [VNote] Vim replace mode cursor line background -vim-replace-background: f8bbd0 - -H1 -foreground: 363636 -font-style: bold -font-size: +6 - -H2 -foreground: 363636 -font-style: bold -font-size: +5 - -H3 -foreground: 363636 -font-style: bold -font-size: +4 - -H4 -foreground: 363636 -font-style: bold -font-size: +3 - -H5 -foreground: 363636 -font-style: bold -font-size: +2 - -H6 -foreground: 363636 -font-style: bold -font-size: +1 - -HRULE -foreground: 363636 -background: dac7c9 - -LIST_BULLET -foreground: d33682 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: 0000ff - -LINK -foreground: 005fff - -AUTO_LINK_URL -foreground: 005fff - -AUTO_LINK_EMAIL -foreground: 005fff - -IMAGE -foreground: 616161 - -REFERENCE -foreground: 826200 - -CODE -foreground: 8e24aa -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -EMPH -font-style: italic - -STRONG -font-style: bold - -HTML_ENTITY -foreground: 8900b5 - -HTML -foreground: 8900b5 - -HTMLBLOCK -foreground: 8900b5 - -COMMENT -foreground: 93a1a1 - -VERBATIM -foreground: 673ab7 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -FENCEDCODEBLOCK -foreground: 673ab7 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color) -# The last occurence of the same attribute takes effect -hljs-comment: 6c6c6c -hljs-keyword: 0000ee -hljs-attribute: 0000ee -hljs-selector-tag: 0000ee -hljs-meta-keyword: 0000ee -hljs-doctag: 0000ee -hljs-name: 0000ee -hljs-type: 880000 -hljs-string: 880000 -hljs-number: 880000 -hljs-selector-id: 880000 -hljs-selector-class: 880000 -hljs-quote: 880000 -hljs-template-tag: 880000 -hljs-deletion: 880000 -# Could specify multiple attribute in one line -hljs-title: bold, 880000 -hljs-section: bold, 880000 -hljs-regexp: bc6060 -hljs-symbol: bc6060 -hljs-variable: bc6060 -hljs-template-variable: bc6060 -hljs-link: bc6060 -hljs-selector-attr: bc6060 -hljs-selector-pseudo: bc6060 -hljs-literal: af00d7 -hljs-built_in: 008700 -hljs-bullet: 008700 -hljs-code: 008700 -hljs-addition: 008700 -hljs-meta: 1f7199 -hljs-meta-string: 4d99bf -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: 00af00 - -NOTE -foreground: 0087b5 - -STRIKE -foreground: b71c1c -font-style: strikeout - -FRONTMATTER -foreground: 6c6c6c - -INLINEEQUATION -foreground: 00897b -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -DISPLAYFORMULA -foreground: 00897b -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -MARK -foreground: 363636 -background: ffff76 - -TABLE -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -TABLEBORDER -foreground: d33682 -background: eeeeee diff --git a/src/resources/themes/v_native/v_native.palette b/src/resources/themes/v_native/v_native.palette deleted file mode 100644 index 004974c7..00000000 --- a/src/resources/themes/v_native/v_native.palette +++ /dev/null @@ -1,176 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. - -[metadata] -qss_file=v_native.qss -mdhl_file=v_native.mdhl -css_file=v_native.css -codeblock_css_file=v_native_codeblock.css -mermaid_css_file=v_native_mermaid.css -version=24 - -[phony] -; Abstract color attributes. -base_fg=#000000 -base_bg=#F5F5F5 - -title_fg=@base_fg -title_bg=transparent - -hover_fg=#000000 -hover_bg=#C0C0C0 - -selected_fg=#000000 -selected_bg=#BCBCBC - -focus_fg=#000000 -focus_bg=#A9A9A9 - -pressed_fg=#000000 -pressed_bg=#808080 - -disabled_fg=#BCBCBC - -separator_bg=#C0C0C0 - -border_bg=#C0C0C0 - -content_fg=#000000 -content_bg=#FFFFFF - -icon_fg=#222222 -icon_disabled_fg=@disabled_fg - -danger_fg=#F5F5F5 -danger_bg=#C9302C -danger_focus_bg=#D9534F -danger_hover_bg=#D9534F -danger_pressed_bg=#AC2925 - -[soft_defined] -; VAvatar. -; The foreground color of the avatar when Captain mode is triggered. -avatar_captain_mode_fg=@base_bg -; The background color of the avatar when Captain mode is triggered. -avatar_captain_mode_bg=#6C6C6C - -; Style of the label in Navigation mode. -navigation_label_fg=#4D4D4D -navigation_label_bg=#F4F4F4 - -; Style of the bubble of VButtonWithWidget. -bubble_fg=#FFFFFF -bubble_bg=#616161 - -; Icons' foreground. -danger_icon_fg=@danger_bg -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg -tab_indicator_tag_label_fg=#222222 -tab_indicator_tag_label_bg=#ce93db - -; Html template. -template_title_flash_light_fg=#80CBC4 -template_title_flash_dark_fg=#00897B - -; Search hit items in list or tree view. -search_hit_item_fg=@selected_fg -search_hit_item_bg=#80CBC4 - -; Universal Entry CMD Edit border color -ue_cmd_busy_border=#3F51B5 -ue_cmd_fail_border=@danger_bg - -; VListWidget/VTreeWidget separator. -item_separator_fg=@content_fg -item_separator_bg=@separator_bg - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Menubar. -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_separator_bg=@separator_bg - -; Toolbar. -toolbutton_hover_bg=@hover_bg - -; Dockwidget. -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_default_border=#424242 -pushbutton_disabled_fg=@disabled_fg -pushbutton_disabled_bg=@pushbutton_bg - -pushbutton_cornerbtn_hover_bg=@hover_bg -pushbutton_cornerbtn_focus_bg=@focus_bg -pushbutton_cornerbtn_pressed_bg=@pressed_bg - -pushbutton_statusbtn_hover_bg=@hover_bg -pushbutton_statusbtn_focus_bg=@focus_bg -pushbutton_statusbtn_pressed_bg=@pressed_bg - -pushbutton_avatarbtn_hover_bg=@hover_bg -pushbutton_avatarbtn_focus_bg=@focus_bg -pushbutton_avatarbtn_pressed_bg=@pressed_bg - -pushbutton_flatbtn_hover_bg=@hover_bg -pushbutton_flatbtn_focus_bg=@focus_bg -pushbutton_flatbtn_pressed_bg=@pressed_bg - -pushbutton_selectionbtn_hover_bg=@hover_bg -pushbutton_selectionbtn_focus_bg=@focus_bg -pushbutton_selectionbtn_pressed_bg=@pressed_bg - -pushbutton_titlebtn_bg=@title_bg -pushbutton_titlebtn_hover_bg=@hover_bg -pushbutton_titlebtn_focus_bg=@focus_bg -pushbutton_titlebtn_pressed_bg=@pressed_bg - -pushbutton_dangerbtn_fg=@danger_fg -pushbutton_dangerbtn_bg=@danger_bg -pushbutton_dangerbtn_hover_bg=@danger_hover_bg -pushbutton_dangerbtn_focus_bg=@danger_focus_bg -pushbutton_dangerbtn_pressed_bg=@danger_pressed_bg - -; ComboBox. -combobox_bg=@content_bg -combobox_view_border=@border_bg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@focus_bg - -; Label. -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@content_fg -lineedit_bg=@content_bg - -; SelectorItem. -selectoritem_border=@base_fg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; Splitter. -splitter_handle_bg=@title_bg diff --git a/src/resources/themes/v_native/v_native.qss b/src/resources/themes/v_native/v_native.qss deleted file mode 100644 index 0a0a8c12..00000000 --- a/src/resources/themes/v_native/v_native.qss +++ /dev/null @@ -1,554 +0,0 @@ -/* QMenuBar */ -QMenuBar { - border: none; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} -/* End QMenuBar */ - -QToolBar { - border: none; -} - -QToolButton:hover { - background: @toolbutton_hover_bg; -} - -/* DockWidget */ -QDockWidget { - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; - icon-size: $16px; - width: $16px; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} - -QDockWidget::close-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: 0px; bottom: 0px; -} - -QDockWidget::float-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: $18px; bottom: 0px; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[CornerBtn="true"]:focus { - background-color: @pushbutton_cornerbtn_focus_bg; -} - -QPushButton[CornerBtn="true"]:hover { - background-color: @pushbutton_cornerbtn_hover_bg; -} - -QPushButton[CornerBtn="true"]:pressed { - background-color: @pushbutton_cornerbtn_pressed_bg; -} - -QPushButton[CornerBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[CornerBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: transparent; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; -} - -QPushButton[StatusBtn="true"]:focus { - background-color: @pushbutton_statusbtn_focus_bg;; -} - -QPushButton[StatusBtn="true"]:hover { - background-color: @pushbutton_statusbtn_hover_bg; -} - -QPushButton[StatusBtn="true"]:pressed { - background-color: @pushbutton_statusbtn_pressed_bg; -} - -QPushButton[StatusBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[StatusBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: transparent; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; -} - -QPushButton[FlatBtn="true"]:focus { - background-color: @pushbutton_flatbtn_focus_bg; -} - -QPushButton[FlatBtn="true"]:hover { - background-color: @pushbutton_flatbtn_hover_bg; -} - -QPushButton[FlatBtn="true"]:pressed { - background-color: @pushbutton_flatbtn_pressed_bg; -} - -QPushButton[FlatBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[FlatBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: transparent; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; -} - -QPushButton[SelectionBtn="true"]:focus { - background-color: @pushbutton_selectionbtn_focus_bg; -} - -QPushButton[SelectionBtn="true"]:hover { - background-color: @pushbutton_selectionbtn_hover_bg; -} - -QPushButton[SelectionBtn="true"]:pressed { - background-color: @pushbutton_selectionbtn_pressed_bg; -} - -QPushButton[SelectionBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[SelectionBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: transparent; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; -} - -QPushButton[TitleBtn="true"]:focus { - background-color: @pushbutton_titlebtn_focus_bg; -} - -QPushButton[TitleBtn="true"]:hover { - background-color: @pushbutton_titlebtn_hover_bg; -} - -QPushButton[TitleBtn="true"]:pressed { - background-color: @pushbutton_titlebtn_pressed_bg; -} - -QPushButton[TitleBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[TitleBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_titlebtn_bg; -} - -QPushButton[DangerBtn="true"] { - padding: 3px 20px 3px 20px; - color: @pushbutton_dangerbtn_fg; - border: none; - background-color: @pushbutton_dangerbtn_bg; -} - -QPushButton[DangerBtn="true"]:focus { - background-color: @pushbutton_dangerbtn_focus_bg; -} - -QPushButton[DangerBtn="true"]:hover { - background-color: @pushbutton_dangerbtn_hover_bg; -} - -QPushButton[DangerBtn="true"]:pressed { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[DangerBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[DangerBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_dangerbtn_bg; -} - -QPushButton[AvatarBtn="true"] { - padding: 2px 4px 2px 4px; - margin: 0px; - border: none; - background-color: transparent; -} - -QPushButton[AvatarBtn="true"]:focus { - background-color: @pushbutton_avatarbtn_focus_bg;; -} - -QPushButton[AvatarBtn="true"]:hover { - background-color: @pushbutton_avatarbtn_hover_bg; -} - -QPushButton[AvatarBtn="true"]:pressed { - background-color: @pushbutton_avatarbtn_pressed_bg; -} - -QPushButton[AvatarBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[AvatarBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: transparent; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox#NotebookSelector { - border: none; - font-size: 12pt; - padding-top: 5px; - padding-bottom: 5px; - icon-size: $24px; - background: @combobox_bg; -} - -QComboBox#NotebookSelector:focus { - background-color: @combobox_focus_bg; -} - -QComboBox#NotebookSelector::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: $20px; - border: none; - background: transparent; -} - -QComboBox#NotebookSelector::down-arrow { - image: url(arrow_dropdown.svg); - width: $20px; - height: $20px; -} - -QComboBox#NotebookSelector::down-arrow:disabled { - image: url(arrow_dropdown_disabled.svg); - width: $20px; - height: $20px; -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 12pt; - icon-size: $24px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: $5px; - padding-bottom: $5px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #00796B; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -QLabel[TagLabel="true"] { - padding-left: $5px; - padding-right: $5px; - color: @tab_indicator_tag_label_fg; - background-color: @tab_indicator_tag_label_bg; -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: $2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VDoubleRowItemWidget QLabel[FirstRowLabel="true"] { - font: bold; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} - -QLineEdit[EmbeddedEdit="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: transparent; -} - -VUniversalEntry VMetaWordLineEdit { - border: 1px solid @lineedit_border; -} -/* End QLineEdit */ - -/* QTabBar */ -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:focus { - image: url(close.svg); - background-color: @tabbar_closebutton_focus_bg; -} - -QTabBar::close-button:hover { - image: url(close.svg); - background-color: @tabbar_closebutton_hover_bg; -} -/* End QTabBar */ - -/* QTreeView */ -QTreeView { - border: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} -/* End QTreeView */ - -/* QListView */ -QListView { - border: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} -/* End QListView */ - -/* QAbstractItemView for TextEdit Completer popup*/ -QAbstractItemView[TextEdit="true"] { - border: 1px solid @border_bg; -} -/* End QAbstractItemView */ - -/* QSplitter */ -QSplitter { - border: none; - margin-left: $3px; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:vertical { - height: $2px; -} - -QSplitter::handle:horizontal { - width: $2px; -} -/* End QSplitter */ - -/* QWidget */ -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} - -QWidget -{ - color: @widget_fg; - font-family: "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", "Dengxian", "等线体", "STXihei", "华文细黑", "Liberation Sans", "Droid Sans", "NSimSun", "新宋体", "SimSun", "宋体", "Helvetica", "sans-serif", "Tahoma", "Arial", "Verdana", "Geneva", "Georgia", "Times New Roman"; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} -/* End QWidget */ diff --git a/src/resources/themes/v_native/v_native_codeblock.css b/src/resources/themes/v_native/v_native_codeblock.css deleted file mode 100644 index fdf954d5..00000000 --- a/src/resources/themes/v_native/v_native_codeblock.css +++ /dev/null @@ -1,99 +0,0 @@ -/* - -Original highlight.js style (c) Ivan Sagalaev - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #E0E0E0; -} - - -/* Base color: saturation 0; */ - -.hljs, -.hljs-subst { - color: #363636; -} - -.hljs-comment { - color: #767676; -} - -.hljs-keyword, -.hljs-attribute, -.hljs-selector-tag, -.hljs-meta-keyword, -.hljs-doctag, -.hljs-name { - color: #0000ee; -} - - -/* User color: hue: 0 */ - -.hljs-type, -.hljs-string, -.hljs-number, -.hljs-selector-id, -.hljs-selector-class, -.hljs-quote, -.hljs-template-tag, -.hljs-deletion { - color: #880000; -} - -.hljs-title, -.hljs-section { - color: #880000; - font-weight: bold; -} - -.hljs-regexp, -.hljs-symbol, -.hljs-variable, -.hljs-template-variable, -.hljs-link, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #BC6060; -} - - -/* Language color: hue: 90; */ - -.hljs-literal { - color: #af00d7; -} - -.hljs-built_in, -.hljs-bullet, -.hljs-code, -.hljs-addition { - color: #008700; -} - - -/* Meta color: hue: 200 */ - -.hljs-meta { - color: #1f7199; -} - -.hljs-meta-string { - color: #4d99bf; -} - - -/* Misc effects */ - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/src/resources/themes/v_native/v_native_mermaid.css b/src/resources/themes/v_native/v_native_mermaid.css deleted file mode 100644 index 3d808780..00000000 --- a/src/resources/themes/v_native/v_native_mermaid.css +++ /dev/null @@ -1,320 +0,0 @@ -/* Flowchart variables */ -/* Sequence Diagram variables */ -/* Gantt chart variables */ -.mermaid-diagram .mermaid .label { - color: #333; -} - -.mermaid-diagram .node rect, -.mermaid-diagram .node circle, -.mermaid-diagram .node ellipse, -.mermaid-diagram .node polygon { - fill: #ECECFF; - stroke: #CCCCFF; - stroke-width: 1px; -} - -.mermaid-diagram .edgePath .path { - stroke: #333333; -} - -.mermaid-diagram .edgeLabel { - background-color: #e8e8e8; -} - -.mermaid-diagram .cluster rect { - fill: #ffffde !important; - rx: 4 !important; - stroke: #aaaa33 !important; - stroke-width: 1px !important; -} - -.mermaid-diagram .cluster text { - fill: #333; -} - -.mermaid-diagram .actor { - stroke: #CCCCFF; - fill: #ECECFF; -} - -.mermaid-diagram text.actor { - fill: black; - stroke: none; -} - -.mermaid-diagram .actor-line { - stroke: grey; -} - -.mermaid-diagram .messageLine0 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #333; -} - -.mermaid-diagram .messageLine1 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - stroke: #333; -} - -.mermaid-diagram #arrowhead { - fill: #333; -} - -.mermaid-diagram #crosshead path { - fill: #333 !important; - stroke: #333 !important; -} - -.mermaid-diagram .messageText { - fill: #333; - stroke: none; -} - -.mermaid-diagram .labelBox { - stroke: #CCCCFF; - fill: #ECECFF; -} - -.mermaid-diagram .labelText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopLine { - stroke-width: 2; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #CCCCFF; -} - -.mermaid-diagram .note { - stroke: #aaaa33; - fill: #fff5ad; -} - -.mermaid-diagram .noteText { - fill: black; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -/** Section styling */ -.mermaid-diagram .section { - stroke: none; - opacity: 0.2; -} - -.mermaid-diagram .section0 { - fill: rgba(102, 102, 255, 0.49); -} - -.mermaid-diagram .section2 { - fill: #fff400; -} - -.mermaid-diagram .section1, -.mermaid-diagram .section3 { - fill: white; - opacity: 0.2; -} - -.mermaid-diagram .sectionTitle0 { - fill: #333; -} - -.mermaid-diagram .sectionTitle1 { - fill: #333; -} - -.mermaid-diagram .sectionTitle2 { - fill: #333; -} - -.mermaid-diagram .sectionTitle3 { - fill: #333; -} - -.mermaid-diagram .sectionTitle { - text-anchor: start; - font-size: 11px; - text-height: 14px; -} - -/* Grid and axis */ -.mermaid-diagram .grid .tick { - stroke: lightgrey; - opacity: 0.3; - shape-rendering: crispEdges; -} - -.mermaid-diagram .grid path { - stroke-width: 0; -} - -/* Today line */ -.mermaid-diagram .today { - fill: none; - stroke: red; - stroke-width: 2px; -} - -/* Task styling */ -/* Default task */ -.mermaid-diagram .task { - stroke-width: 2; -} - -.mermaid-diagram .taskText { - text-anchor: middle; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideRight { - fill: black; - text-anchor: start; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideLeft { - fill: black; - text-anchor: end; - font-size: 11px; -} - -/* Specific task settings for the sections*/ -.mermaid-diagram .taskText0, -.mermaid-diagram .taskText1, -.mermaid-diagram .taskText2, -.mermaid-diagram .taskText3 { - fill: white; -} - -.mermaid-diagram .task0, -.mermaid-diagram .task1, -.mermaid-diagram .task2, -.mermaid-diagram .task3 { - fill: #8a90dd; - stroke: #534fbc; -} - -.mermaid-diagram .taskTextOutside0, -.mermaid-diagram .taskTextOutside2 { - fill: black; -} - -.mermaid-diagram .taskTextOutside1, -.mermaid-diagram .taskTextOutside3 { - fill: black; -} - -/* Active task */ -.mermaid-diagram .active0, -.mermaid-diagram .active1, -.mermaid-diagram .active2, -.mermaid-diagram .active3 { - fill: #bfc7ff; - stroke: #534fbc; -} - -.mermaid-diagram .activeText0, -.mermaid-diagram .activeText1, -.mermaid-diagram .activeText2, -.mermaid-diagram .activeText3 { - fill: black !important; -} - -/* Completed task */ -.mermaid-diagram .done0, -.mermaid-diagram .done1, -.mermaid-diagram .done2, -.mermaid-diagram .done3 { - stroke: grey; - fill: lightgrey; - stroke-width: 2; -} - -.mermaid-diagram .doneText0, -.mermaid-diagram .doneText1, -.mermaid-diagram .doneText2, -.mermaid-diagram .doneText3 { - fill: black !important; -} - -/* Tasks on the critical line */ -.mermaid-diagram .crit0, -.mermaid-diagram .crit1, -.mermaid-diagram .crit2, -.mermaid-diagram .crit3 { - stroke: #ff8888; - fill: red; - stroke-width: 2; -} - -.mermaid-diagram .activeCrit0, -.mermaid-diagram .activeCrit1, -.mermaid-diagram .activeCrit2, -.mermaid-diagram .activeCrit3 { - stroke: #ff8888; - fill: #bfc7ff; - stroke-width: 2; -} - -.mermaid-diagram .doneCrit0, -.mermaid-diagram .doneCrit1, -.mermaid-diagram .doneCrit2, -.mermaid-diagram .doneCrit3 { - stroke: #ff8888; - fill: lightgrey; - stroke-width: 2; - cursor: pointer; - shape-rendering: crispEdges; -} - -.mermaid-diagram .doneCritText0, -.mermaid-diagram .doneCritText1, -.mermaid-diagram .doneCritText2, -.mermaid-diagram .doneCritText3 { - fill: black !important; -} - -.mermaid-diagram .activeCritText0, -.mermaid-diagram .activeCritText1, -.mermaid-diagram .activeCritText2, -.mermaid-diagram .activeCritText3 { - fill: black !important; -} - -.mermaid-diagram .titleText { - text-anchor: middle; - font-size: 18px; - fill: black; -} - -.mermaid-diagram .node text { - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -.mermaid-diagram div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: 'trebuchet ms', verdana, arial; - font-size: 12px; - background: #ffffde; - border: 1px solid #aaaa33; - border-radius: 2px; - pointer-events: none; - z-index: 100; -} diff --git a/src/resources/themes/v_next/arrow_dropdown.svg b/src/resources/themes/v_next/arrow_dropdown.svg deleted file mode 100644 index 8b465de9..00000000 --- a/src/resources/themes/v_next/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_next/arrow_dropdown_disabled.svg b/src/resources/themes/v_next/arrow_dropdown_disabled.svg deleted file mode 100644 index 7add5e54..00000000 --- a/src/resources/themes/v_next/arrow_dropdown_disabled.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_next/branch_closed.svg b/src/resources/themes/v_next/branch_closed.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_next/branch_closed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/branch_end.svg b/src/resources/themes/v_next/branch_end.svg deleted file mode 100644 index baa0c23f..00000000 --- a/src/resources/themes/v_next/branch_end.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_next/branch_more.svg b/src/resources/themes/v_next/branch_more.svg deleted file mode 100644 index cb0fecad..00000000 --- a/src/resources/themes/v_next/branch_more.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_next/branch_open.svg b/src/resources/themes/v_next/branch_open.svg deleted file mode 100644 index c1e8e141..00000000 --- a/src/resources/themes/v_next/branch_open.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/checkbox_checked.svg b/src/resources/themes/v_next/checkbox_checked.svg deleted file mode 100644 index f017b5b4..00000000 --- a/src/resources/themes/v_next/checkbox_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_next/checkbox_checked_disabled.svg b/src/resources/themes/v_next/checkbox_checked_disabled.svg deleted file mode 100644 index 39c47873..00000000 --- a/src/resources/themes/v_next/checkbox_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_next/checkbox_unchecked.svg b/src/resources/themes/v_next/checkbox_unchecked.svg deleted file mode 100644 index 5167523e..00000000 --- a/src/resources/themes/v_next/checkbox_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_next/checkbox_unchecked_disabled.svg b/src/resources/themes/v_next/checkbox_unchecked_disabled.svg deleted file mode 100644 index 35788230..00000000 --- a/src/resources/themes/v_next/checkbox_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_next/close.svg b/src/resources/themes/v_next/close.svg deleted file mode 100644 index 26cbf713..00000000 --- a/src/resources/themes/v_next/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_next/close_grey.svg b/src/resources/themes/v_next/close_grey.svg deleted file mode 100644 index 24bddd4e..00000000 --- a/src/resources/themes/v_next/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_next/down.svg b/src/resources/themes/v_next/down.svg deleted file mode 100644 index 386ac7f8..00000000 --- a/src/resources/themes/v_next/down.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/down_disabled.svg b/src/resources/themes/v_next/down_disabled.svg deleted file mode 100644 index 2a53e0f0..00000000 --- a/src/resources/themes/v_next/down_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/float.svg b/src/resources/themes/v_next/float.svg deleted file mode 100644 index e4a198f3..00000000 --- a/src/resources/themes/v_next/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_next/left.svg b/src/resources/themes/v_next/left.svg deleted file mode 100644 index aee69f4a..00000000 --- a/src/resources/themes/v_next/left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/left_disabled.svg b/src/resources/themes/v_next/left_disabled.svg deleted file mode 100644 index 3cabd4b5..00000000 --- a/src/resources/themes/v_next/left_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/line.svg b/src/resources/themes/v_next/line.svg deleted file mode 100644 index 8c981419..00000000 --- a/src/resources/themes/v_next/line.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 2 - - - diff --git a/src/resources/themes/v_next/menu_checkbox.svg b/src/resources/themes/v_next/menu_checkbox.svg deleted file mode 100644 index 0aeb35a1..00000000 --- a/src/resources/themes/v_next/menu_checkbox.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_next/menu_radiobutton.svg b/src/resources/themes/v_next/menu_radiobutton.svg deleted file mode 100644 index aafaa309..00000000 --- a/src/resources/themes/v_next/menu_radiobutton.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_next/radiobutton_checked.svg b/src/resources/themes/v_next/radiobutton_checked.svg deleted file mode 100644 index c9834cc5..00000000 --- a/src/resources/themes/v_next/radiobutton_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_next/radiobutton_checked_disabled.svg b/src/resources/themes/v_next/radiobutton_checked_disabled.svg deleted file mode 100644 index b67faef0..00000000 --- a/src/resources/themes/v_next/radiobutton_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_next/radiobutton_unchecked.svg b/src/resources/themes/v_next/radiobutton_unchecked.svg deleted file mode 100644 index 7cd0863a..00000000 --- a/src/resources/themes/v_next/radiobutton_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_next/radiobutton_unchecked_disabled.svg b/src/resources/themes/v_next/radiobutton_unchecked_disabled.svg deleted file mode 100644 index 8308f78b..00000000 --- a/src/resources/themes/v_next/radiobutton_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_next/right.svg b/src/resources/themes/v_next/right.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_next/right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/right_disabled.svg b/src/resources/themes/v_next/right_disabled.svg deleted file mode 100644 index c0c83ba8..00000000 --- a/src/resources/themes/v_next/right_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/up.svg b/src/resources/themes/v_next/up.svg deleted file mode 100644 index 52be26da..00000000 --- a/src/resources/themes/v_next/up.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/up_disabled.svg b/src/resources/themes/v_next/up_disabled.svg deleted file mode 100644 index 36e54158..00000000 --- a/src/resources/themes/v_next/up_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_next/v_next.css b/src/resources/themes/v_next/v_next.css deleted file mode 100644 index 59a4d705..00000000 --- a/src/resources/themes/v_next/v_next.css +++ /dev/null @@ -1,408 +0,0 @@ -*, -*:before, -*:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -body { - font-family: "Microsoft YaHei", "Helvetica Neue", "Microsoft YaHei UI", Arial, "Times New Roman", "Hiragino Sans GB", "STHeiti", "WenQuanYi Micro Hei", SimSun, Song, sans-serif; - color: #555; - line-height: 2em; - font-size: 16px; - max-width: 800px; - margin: 20px auto; - padding: 0 10px; - background-color: #FFF; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - font-weight: bold; - line-height: 1.2em; - margin: 1.2em 0 0.6em 0; -} - -p { - display: block; - margin: 0 0 1.1em; - letter-spacing: 0.04em; - /*text-align: justify;*/ - /*margin-block-start: 1em; - margin-block-end: 1em; - margin-inline-start: 0px; - margin-inline-end: 0px;*/ -} - -h1 { - /*font-size: 41.6px;*/ - font-size: 2.2em; -} - -h2 { - /*font-size: 34.4px;*/ - font-size: 1.7em; -} - -h3 { - /*font-size: 27.2px;*/ - font-size: 1.4em; -} - -h4 { - /*font-size: 20px;*/ - font-size: 1.2em; -} - -h5 { - /*font-size: 18px;*/ - font-size: 1.08em; -} - -h6 { - /*font-size: 16px;*/ - font-size: 1em; -} - -a { - color: #1980e6; - text-decoration: none; - transition: background-color ease-in-out .15s, color ease-in-out .15s, border-color ease-in-out .15s; - -webkit-transition: background-color ease-in-out .15s, color ease-in-out .15s, border-color ease-in-out .15s; -} - -a:hover, -a:focus { - color: #0f4d8a; - text-decoration: underline -} - -a:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px -} - -ul, -ol { - /*line-height: 1.6em;*/ - /*margin-top: 0;*/ - /*margin-bottom: 1.1em;*/ - margin: 0 0 1.4em 1.4em; - padding-left: 0; -} - -li { - /*line-height: 1.6em;*/ -} - -pre, code { - font-family: "Source Code Pro","YaHei Consolas Hybrid","Microsoft YaHei Mono",Consolas,monospace; -} - -pre { - display: block; - overflow-x: auto; - overflow-y: hidden; - white-space: nowrap; - padding: 0; - border: 0; - margin: 0 0 10.5px; -} - -code { - color: #c7254e; - background-color: #f9f2f4; - border-radius: 4px; - white-space: normal; - padding: 2px 4px; - font-size: 90%; -} - -pre code { - padding: 1em 1em !important; - border-radius: 0; - white-space: pre; - background-color: transparent; - line-height: 1.5em; -} - -pre code.markdown-metadata { - /*border-left: .5em solid #80CBC4;*/ - border-left: 0; -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - border-left: 10px solid rgba(102,128,153,0.075); - background-color: rgba(102,128,153,0.05); - border-top-right-radius: 5px; - border-bottom-right-radius: 5px; - padding: 10px 15px; - margin-left: 0; -} - -blockquote p { - /*color: #666;*/ - margin-bottom: 1.1em; - font-size: 1em; - font-weight: 300; -} - -blockquote p:last-child { - margin-bottom: 0; -} - -hr { - margin: 2em 0; - border: 0; - border-top: 1px solid rgba(102,128,153,0.1); - box-sizing: content-box; - height: 0; - /*display: block; - text-align: left; - margin: 1em 0; - border: none; - height: 2px; - background: #999;*/ -} - -table { - margin-bottom: 20px; - border-collapse: collapse; - max-width: 100%; - background-color: transparent; - /*padding: 0; - border-collapse: collapse;*/ -} - -table tr { - border-top: 1px solid #ddd; - background-color: transparent; - margin: 0; - padding: 0; -} - -table tr:nth-child(2n) { - background-color: #f8f8f8; -} - -table tr th { - font-weight: bold; - border: 1px solid #ddd; - margin: 0; - padding: 0.5em; - background-color: #f8f8f8; -} - -table tr td { - border: 1px solid #ddd; - margin: 0; - padding: 0.5em; -} - -table tr th :first-child, -table tr td :first-child { - margin-top: 0; -} - -table tr th :last-child, -table tr td :last-child { - margin-bottom: 0; -} - -div.mermaid-diagram { - margin: 16px 0px 16px 0px; - overflow-y: hidden; -} - -div.flowchart-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -div.plantuml-diagram { - padding: 5px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -.img-package { - text-align: center; -} - -img.img-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -div.img-caption { - min-width: 20%; - max-width: 80%; - display: inline-block; - padding: 10px; - margin: 0 auto; - border-bottom: 1px solid #c0c0c0; - color: #6c6c6c; - text-align: center; - line-height: 1.5; -} - -.emoji_zero, -.emoji_one, -.emoji_two, -.emoji_three, -.emoji_four, -.emoji_five, -.emoji_six, -.emoji_seven, -.emoji_eight, -.emoji_nine { - margin-left: 5px; - margin-right: 8px; -} - -div.preview-hint { - opacity: 0.5; - margin-top: 30%; - margin-bottom: 30%; - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; -} - - -/* For Highlight.js Line Number */ - -table.hljs-ln tr { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td.hljs-ln-numbers { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - text-align: center; - color: #AAA; - border-right: 1px solid #CCC; - vertical-align: top; - padding-right: 5px; - white-space: nowrap; -} - -table.hljs-ln tr td.hljs-ln-code { - padding-left: 10px; -} - -::-webkit-scrollbar { - background-color: #EAEAEA; - width: 14px; - height: 14px; - border: none; -} - -::-webkit-scrollbar-corner { - background-color: #EAEAEA; -} - -::-webkit-scrollbar-button { - /* This selector affects the styling of both the up & down and left & right buttons of a scrollbar */ - height: 14px; - width: 14px; - background-color: #EAEAEA; -} - -::-webkit-scrollbar-button:hover { - background-color: #D0D0D0; -} - -::-webkit-scrollbar-button:active { - background-color: #B2B2B2; -} - -::-webkit-scrollbar-track { - /* This selector affects the styling of the area in the scrollbar between the two buttons */ - background-color: #EAEAEA; -} - -::-webkit-scrollbar-thumb { - /* This selector affects the styling of draggable element of the scollbar */ - border: none; - background-color: #DADADA; -} - -::-webkit-scrollbar-thumb:hover { - background-color: #D0D0D0; -} - -::-webkit-scrollbar-thumb:active { - background-color: #B2B2B2; -} - -::-webkit-scrollbar-button:horizontal:increment { - background-image: url(right.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:horizontal:decrement { - background-image: url(left.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:increment { - background-image: url(down.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:decrement { - background-image: url(up.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::selection { - background: #1976D2; - color: #F5F5F5; -} - -.modal-box { - background-color: rgb(234, 234, 234); - background-color: rgba(234, 234, 234, 0.95); -} - -span.modal-close { - color: #666666; -} - -span.modal-close:hover, -span.modal-close:focus { - color: #2f2f2f; -} diff --git a/src/resources/themes/v_next/v_next.mdhl b/src/resources/themes/v_next/v_next.mdhl deleted file mode 100644 index a8c54cf3..00000000 --- a/src/resources/themes/v_next/v_next.mdhl +++ /dev/null @@ -1,202 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Verdana, Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Times New Roman -font-size: 12 -foreground: 222222 -background: f5f5f5 -# [VNote] Style for trailing space -trailing-space: a8a8a8 -# [VNote] Style for line number -line-number-background: eaeaea -line-number-foreground: 424242 -# [VNote] Style for selected word highlight -selected-word-foreground: 222222 -selected-word-background: dfdf00 -# [VNote] Style for searched word highlight -searched-word-foreground: 222222 -searched-word-background: 4db6ac -# [VNote] Style for searched word under cursor highlight -searched-word-cursor-foreground: 222222 -searched-word-cursor-background: 66bb6a -# [VNote] Style for incremental searched word highlight -incremental-searched-word-foreground: 222222 -incremental-searched-word-background: ce93d8 -# [VNote] Style for color column in fenced code block -color-column-background: dd0000 -color-column-foreground: ffff00 -# [VNote] Style for preview image line -preview-image-line-foreground: 9575cd - -editor-selection -foreground: f5f5f5 -background: 1976d2 - -editor-current-line -background: c5cae9 -# [VNote] Vim insert mode cursor line background -vim-insert-background: c5cae9 -# [VNote] Vim normal mode cursor line background -vim-normal-background: e0e0e0 -# [VNote] Vim visual mode cursor line background -vim-visual-background: ffe0b2 -# [VNote] Vim replace mode cursor line background -vim-replace-background: f8bbd0 - -H1 -foreground: 222222 -font-style: bold -font-size: +6 - -H2 -foreground: 222222 -font-style: bold -font-size: +5 - -H3 -foreground: 222222 -font-style: bold -font-size: +4 - -H4 -foreground: 222222 -font-style: bold -font-size: +3 - -H5 -foreground: 222222 -font-style: bold -font-size: +2 - -H6 -foreground: 222222 -font-style: bold -font-size: +1 - -HRULE -foreground: 222222 -background: dac7c9 - -LIST_BULLET -foreground: d33682 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: 0000ff - -LINK -foreground: 005fff - -AUTO_LINK_URL -foreground: 005fff - -AUTO_LINK_EMAIL -foreground: 005fff - -IMAGE -foreground: 616161 - -REFERENCE -foreground: 826200 - -CODE -foreground: 8e24aa -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New - -EMPH -font-style: italic - -STRONG -font-style: bold - -HTML_ENTITY -foreground: 8900b5 - -HTML -foreground: 8900b5 - -HTMLBLOCK -foreground: 8900b5 - -COMMENT -foreground: 93a1a1 - -VERBATIM -foreground: 673ab7 -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New - -FENCEDCODEBLOCK -foreground: 673ab7 -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color) -# The last occurence of the same attribute takes effect -# Could specify multiple attribute in one line -hljs-comment: 6c6c6c -hljs-keyword: 0000ee -hljs-attribute: 0000ee -hljs-selector-tag: 0000ee -hljs-meta-keyword: 0000ee -hljs-doctag: 0000ee -hljs-name: 0000ee -hljs-type: 880000 -hljs-string: 880000 -hljs-number: 880000 -hljs-selector-id: 880000 -hljs-selector-class: 880000 -hljs-quote: 880000 -hljs-template-tag: 880000 -hljs-deletion: 880000 -hljs-title: bold, 880000 -hljs-section: bold, 880000 -hljs-regexp: bc6060 -hljs-symbol: bc6060 -hljs-variable: bc6060 -hljs-template-variable: bc6060 -hljs-link: bc6060 -hljs-selector-attr: bc6060 -hljs-selector-pseudo: bc6060 -hljs-literal: af00d7 -hljs-built_in: 008700 -hljs-bullet: 008700 -hljs-code: 008700 -hljs-addition: 008700 -hljs-meta: 1f7199 -hljs-meta-string: 4d99bf -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: 00af00 - -NOTE -foreground: 0087b5 - -STRIKE -foreground: b71c1c -font-style: strikeout - -FRONTMATTER -foreground: 6c6c6c - -INLINEEQUATION -foreground: 00897b -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New - -DISPLAYFORMULA -foreground: 00897b -font-family: Consolas, Monaco, Andale Mono, Monospace, Courier New - -MARK -foreground: 222222 -background: ffff76 diff --git a/src/resources/themes/v_next/v_next.palette b/src/resources/themes/v_next/v_next.palette deleted file mode 100644 index b2594577..00000000 --- a/src/resources/themes/v_next/v_next.palette +++ /dev/null @@ -1,388 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. - -[metadata] -qss_file=v_next.qss -mdhl_file=v_next.mdhl -css_file=v_next.css -codeblock_css_file=v_next_codeblock.css -mermaid_css_file=v_next_mermaid.css -version=22 - -[phony] -; Abstract color attributes. -master_fg=#000 -master_bg=#D0D0D0 -master_light_bg=#FFFFFF -master_dark_bg=#000 -master_focus_bg=#FFFFFF -master_hover_bg=#D0D0D0 -master_pressed_bg=#FFFFFF - -base_fg=#222222 -base_bg=#FFFFFF - -active_fg=#FC6423 -active_bg=#EBEDEF - -main_fg=@base_fg -main_bg=@base_bg - -title_fg=@base_fg -title_bg=@base_bg - -disabled_fg=#9E9E9E - -content_fg=@base_fg -content_bg=@base_bg - -; border_bg=#DADADA -border_bg=#F5F7F9 -separator_bg=#F5F7F9 - -; hover_bg=#D0D0D0 -hover_fg=@base_fg -hover_bg=@active_bg - -; selected_fg=@base_fg -; selected_bg=#7BBAB9 -selected_fg=@active_fg -selected_bg=@active_bg - -; inactive_fg=@selected_fg -; inactive_bg=#99CFCA - -focus_fg=@base_fg -focus_bg=#BDBDBD - -pressed_fg=@base_fg -pressed_bg=#B2B2B2 - -edit_fg=#222222 -edit_bg=#F5F5F5 -edit_focus_bg=@active_bg -edit_focus_border=@active_fg -edit_hover_bg=@active_bg -edit_hover_border=@active_fg -edit_selection_fg=@edit_fg -edit_selection_bg=@active_bg - -icon_fg=#222222 -icon_disabled_fg=@disabled_fg - -danger_fg=#F5F5F5 -danger_bg=#C9302C -danger_focus_bg=#D9534F -danger_hover_bg=#DE6764 -danger_pressed_bg=#AC2925 - -[soft_defined] -; VAvatar. -; The foreground color of the avatar when Captain mode is triggered. -avatar_captain_mode_fg=@active_fg -; The background color of the avatar when Captain mode is triggered. -avatar_captain_mode_bg=@active_bg - -; Style of the label in Navigation mode. -navigation_label_fg=@active_fg -navigation_label_bg=@active_bg - -; Style of the bubble of VButtonWithWidget. -bubble_fg=@base_fg -bubble_bg=@base_bg - -; Icons' foreground. -danger_icon_fg=@danger_bg -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg -tab_indicator_tag_label_fg=#222222 -tab_indicator_tag_label_bg=#ce93db - -; Html template. -template_title_flash_light_fg=@active_fg -template_title_flash_dark_fg=@active_fg - -; Search hit items in list or tree view. -search_hit_item_fg=@selected_fg -search_hit_item_bg=#CCE7E4 - -; Universal Entry CMD Edit border color -ue_cmd_busy_border=#3F51B5 -ue_cmd_fail_border=@danger_bg - -; VListWidget/VTreeWidget separator. -item_separator_fg=@master_dark_bg -item_separator_bg=@separator_bg - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Separator of dock widgets. -dock_separator_bg=@separator_bg -dock_separator_hover_bg=@hover_bg -dock_separator_pressed_bg=@pressed_bg - -; Menubar. -menubar_bg=@main_bg -menubar_fg=@main_fg -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_bg=@base_bg -menu_fg=@base_fg -menu_border_bg=@border_bg -menu_item_disabled_fg=@disabled_fg -menu_item_selected_fg=@base_fg -menu_item_selected_bg=@selected_bg -menu_separator_bg=@separator_bg -menu_icon_fg=@icon_fg -menu_icon_danger_fg=@danger_icon_fg - -; Tooltip. -tooltip_bg=@base_bg -tooltip_fg=@base_fg - -; Toolbar. -toolbar_bg=@main_bg -toolbar_separator_bg=@separator_bg -toolbutton_hover_bg=@hover_bg -toolbutton_pressed_bg=@pressed_bg -toolbutton_checked_bg=@selected_bg -toolbutton_icon_fg=@icon_fg -toolbutton_icon_danger_fg=@danger_icon_fg - -; Toolbox. -toolbox_icon_fg=@base_fg -toolbox_icon_active_fg=@active_fg -toolbox_title_border=@active_bg - -; Dockwidget. -dockwidget_bg=@base_bg -dockwidget_title_fg=@title_fg -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_fg=@base_fg -pushbutton_bg=@base_bg -pushbutton_border=@border_bg -pushbutton_pressed_bg=@pressed_bg -pushbutton_focus_bg=@base_bg -pushbutton_checked_bg=@selected_bg -pushbutton_hover_bg=@hover_bg -pushbutton_default_border=@active_fg -pushbutton_disabled_fg=@disabled_fg -pushbutton_disabled_bg=@pushbutton_bg - -pushbutton_specialbtn_fg=@active_fg -pushbutton_specialbtn_bg=@base_bg -pushbutton_specialbtn_focus_bg=@base_bg -pushbutton_specialbtn_hover_bg=@hover_bg -pushbutton_specialbtn_checked_bg=#3F51B5 -pushbutton_specialbtn_pressed_bg=@master_pressed_bg - -pushbutton_titlebtn_bg=@title_bg - -pushbutton_dangerbtn_fg=@danger_fg -pushbutton_dangerbtn_bg=@danger_bg -pushbutton_dangerbtn_hover_bg=@danger_hover_bg -pushbutton_dangerbtn_focus_bg=@danger_focus_bg -pushbutton_dangerbtn_pressed_bg=@danger_pressed_bg - -pushbutton_toolboxbtn_active_fg=@active_fg -pushbutton_toolboxbtn_active_bg=@active_bg -pushbutton_toolboxbtn_active_focus_bg=@focus_bg -pushbutton_toolboxbtn_active_hover_bg=@hover_bg -pushbutton_toolboxbtn_active_pressed_bg=@master_pressed_bg - -button_icon_fg=@icon_fg -button_icon_danger_fg=@danger_icon_fg - -buttonmenuitem_decoration_text_fg=@master_dark_bg - -; ComboBox. -combobox_border=@border_bg -combobox_fg=@content_fg -combobox_bg=@content_bg -combobox_disabled_fg=@disabled_fg -combobox_view_border=@border_bg -combobox_view_selected_bg=@selected_bg -combobox_view_selected_fg=@selected_fg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@edit_focus_bg -combobox_focus_border=@edit_focus_border -combobox_hover_bg=@edit_hover_bg -combobox_hover_border=@edit_hover_border -combobox_item_icon_fg=@item_icon_fg - -combobox_notebookselector_fg=@base_fg -combobox_notebookselector_bg=@base_bg -combobox_notebookselector_border=@base_bg -combobox_notebookselector_hover_fg=@hover_fg -combobox_notebookselector_hover_bg=@active_bg -combobox_notebookselector_focus_fg=@active_fg -combobox_notebookselector_focus_bg=@active_bg - -; Label. -label_fg=@base_fg -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@edit_fg -lineedit_bg=@edit_bg -lineedit_disabled_fg=@disabled_fg -lineedit_focus_bg=@edit_focus_bg -lineedit_focus_border=@edit_focus_border -lineedit_hover_bg=@edit_hover_bg -lineedit_hover_border=@edit_hover_border -lineedit_selection_fg=@edit_selection_fg -lineedit_selection_bg=@edit_selection_bg - -; TabWidget. -tabwidget_pane_border=@border_bg - -; TabBar. -tabbar_fg=@base_fg -tabbar_bg=@base_bg -tabbar_border=@border_bg - -tabbar_selected_fg=@selected_fg -tabbar_selected_bg=@selected_bg -tabbar_selected_border=@selected_fg - -tabbar_hover_fg=@hover_fg -tabbar_hover_bg=@hover_bg - -tabbar_icon_fg=@icon_fg -tabbar_icon_special_fg=@danger_bg - -; SelectorItem. -selectoritem_border=@base_fg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; TreeView. -treeview_fg=@content_fg -treeview_bg=@content_bg -treeview_item_border_bg=@border_bg -treeview_item_hover_fg=@hover_fg -treeview_item_hover_bg=@hover_bg -treeview_item_selected_fg=@selected_fg -treeview_item_selected_bg=@selected_bg -treeview_item_selected_avtive_fg=@active_fg -treeview_item_selected_avtive_bg=@active_bg -treeview_item_selected_inactive_fg=@inactive_fg -treeview_item_selected_inactive_bg=@inactive_bg -treeview_item_icon_fg=@item_icon_fg - -; ListView. -listview_fg=@content_fg -listview_bg=@content_bg -listview_item_hover_fg=@hover_fg -listview_item_hover_bg=@hover_bg -listview_item_selected_fg=@selected_fg -listview_item_selected_bg=@selected_bg -listview_item_selected_avtive_fg=@active_fg -listview_item_selected_avtive_bg=@active_bg -listview_item_selected_inactive_fg=@inactive_fg -listview_item_selected_inactive_bg=@inactive_bg - -; QAbstractItemView for TextEdit Completer. -abstractitemview_textedit_fg=@content_fg -abstractitemview_textedit_bg=#DADADA -abstractitemview_textedit_item_hover_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_hover_bg=@master_hover_bg -abstractitemview_textedit_item_selected_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_selected_bg=@master_light_bg -abstractitemview_textedit_item_selected_avtive_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_selected_avtive_bg=@master_focus_bg -abstractitemview_textedit_item_selected_inactive_fg=@inactive_fg -abstractitemview_textedit_item_selected_inactive_bg=@inactive_bg - -; Splitter. -splitter_handle_bg=@border_bg -splitter_handle_pressed_bg=@pressed_bg - -; StatusBar. -statusbar_fg=@border_fg -statusbar_bg=@border_bg - -; ScrollBar. -scrollbar_bg=@base_bg -scrollbar_page_bg=transparent -scrollbar_handle_bg=#DADADA -scrollbar_handle_hover_bg=@hover_bg -scrollbar_handle_pressed_bg=@pressed_bg - -; VEditWindow. -editwindow_corner_icon_fg=@base_fg -editwindow_corner_icon_inactive_fg=#D3D3D3 - -; CheckBox. -checkbox_disabled_fg=@disabled_fg -checkbox_indicator_focus_bg=@focus_bg -checkbox_indicator_hover_bg=@hover_bg -checkbox_indicator_pressed_bg=@pressed_bg - -; RadioButton. -radiobutton_disabled_fg=@disabled_fg -radiobutton_indicator_focus_bg=@focus_bg -radiobutton_indicator_hover_bg=@hover_bg -radiobutton_indicator_pressed_bg=@pressed_bg - -; SpinBox. -spinbox_fg=@edit_fg -spinbox_bg=@edit_bg -spinbox_border=@border_bg -spinbox_selection_fg=@edit_selection_fg -spinbox_selection_bg=@edit_selection_bg -spinbox_focus_border=@edit_focus_border -spinbox_focus_bg=@edit_focus_bg -spinbox_hover_border=@edit_hover_border -spinbox_hover_bg=@edit_hover_bg -spinbox_button_hover_bg=@hover_bg -spinbox_button_pressed_bg=@pressed_bg - -; HeaderView. -headerview_bg=#E0E0E0 -headerview_fg=@base_fg -headerview_border=@border_bg -headerview_checked_fg=@selected_fg -headerview_checked_bg=@selected_bg - -; ProgressBar. -progressbar_bg=@edit_bg -progressbar_border_bg=@border_bg -progressbar_chunk_bg=@master_light_bg - -universalentry_bg=@base_bg -universalentry_border_bg=@border_bg - -doublerowitem_second_row_label_fg=#6C6C6C - -; GroupBox. -groupbox_border=@border_bg -groupbox_title_fg=@base_fg - -; Slider. -slider_border_bg=@border_bg -slider_groove_bg=@edit_bg -slider_handle_bg=@base_fg -slider_subpage_bg=@master_light_bg diff --git a/src/resources/themes/v_next/v_next.qss b/src/resources/themes/v_next/v_next.qss deleted file mode 100644 index 757b723e..00000000 --- a/src/resources/themes/v_next/v_next.qss +++ /dev/null @@ -1,1460 +0,0 @@ -QToolTip -{ - border: none; - background: @tooltip_bg; - color: @tooltip_fg; -} - -/* QMainWindow */ -QMainWindow { - color: @base_fg; - background: @base_bg; -} - -QMainWindow::separator { - background: @dock_separator_bg; - width: $2px; - height: $2px; -} - -QMainWindow::separator:hover { - background: @dock_separator_hover_bg; -} - -QMainWindow::separator:pressed { - background: @dock_separator_pressed_bg; -} -/* End QMainWindow */ - -QMenuBar { - border: none; - background: @menubar_bg; - color: @menubar_fg; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} - -/* QMenu */ -QMenu { - background: @menu_bg; - color: @menu_fg; - border: $2px solid @menu_border_bg; -} - -QMenu::icon { - margin: $5px; -} - -QMenu::item { - padding: $5px $30px $5px $30px; - border: $1px solid transparent; -} - -QMenu::item:selected { - color: @menu_item_selected_fg; - background: @menu_item_selected_bg; -} - -QMenu::item:disabled { - color: @menu_item_disabled_fg; -} - -QMenu::icon:checked { /* appearance of a 'checked' icon */ - border: $2px solid @menu_fg; -} - -QMenu::separator { - height: $2px; - background: @menu_separator_bg; - margin-left: $10px; - margin-right: $5px; -} - -QMenu::indicator { - width: $20px; - height: $20px; -} - -QMenu::indicator:non-exclusive:unchecked { - image: none; -} - -QMenu::indicator:non-exclusive:checked { - image: url(menu_checkbox.svg); -} - -QMenu::indicator:exclusive:unchecked { - image: none; -} - -QMenu::indicator:exclusive:checked { - image: url(menu_radiobutton.svg); -} -/* End QMenu */ - -QToolBar { - border: none; - background: @toolbar_bg; -} - -QToolBar::separator { - width: 1px; - height: 1px; - border: none; - background: @toolbar_separator_bg; -} - -/* QToolButton */ -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: $16px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: $10px; /* make way for the popup button */ -} - -QToolButton { - border: none; - background: transparent; - margin: 1px 3px 1px 3px; - padding: 0px; -} - -QToolButton:checked { - background: @toolbutton_checked_bg; -} - -QToolButton:hover { - border:none; - background: @toolbutton_hover_bg; -} - -QToolButton:pressed { - background: @toolbutton_pressed_bg; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: none; - width: $16px; -} - -QToolButton::menu-arrow { - image: url(arrow_dropdown.svg); - width: $16px; - height: $16px; -} -/* End QToolButton*/ - -/* DockWidget */ -QDockWidget { - color: @dockwidget_title_fg; - background: @dockwidget_bg; - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; - icon-size: $16px; - width: $16px; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} - -QDockWidget::close-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: 0px; bottom: 0px; -} - -QDockWidget::float-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: $18px; bottom: 0px; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton[SpecialBtn="true"] { - color: @pushbutton_specialbtn_fg; - background: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:focus { - background-color: @pushbutton_specialbtn_focus_bg; -} - -QPushButton[SpecialBtn="true"]:checked { - background-color: @pushbutton_specialbtn_checked_bg; -} - -QPushButton[SpecialBtn="true"]:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:pressed { - background-color: @pushbutton_specialbtn_pressed_bg; -} - -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; - min-width: -1; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"] { - color: @pushbutton_dangerbtn_fg; - border: none; - background-color: @pushbutton_dangerbtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_dangerbtn_bg; -} - -QPushButton[DangerBtn="true"]:focus { - background-color: @pushbutton_dangerbtn_focus_bg; -} - -QPushButton[DangerBtn="true"]:checked { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[DangerBtn="true"]:hover { - background-color: @pushbutton_dangerbtn_hover_bg; -} - -QPushButton[DangerBtn="true"]:pressed { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"] { - padding: 4px 10px 4px 4px; - margin: 0px; - border: none; - font-weight: bold; - color: @pushbutton_toolboxbtn_active_fg; - background-color: @pushbutton_toolboxbtn_active_bg; - min-width: -1; -} - -QPushButton[ToolBoxActiveBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_toolboxbtn_active_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:focus { - background-color: @pushbutton_toolboxbtn_active_focus_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:hover { - background-color: @pushbutton_toolboxbtn_active_hover_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:pressed { - background-color: @pushbutton_toolboxbtn_active_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[AvatarBtn="true"] { - padding: 2px 4px 2px 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton { - color: @pushbutton_fg; - background: @pushbutton_bg; - border: 1px solid @pushbutton_border; - padding: 3px; - min-width: 80px; -} - -QPushButton:focus { - background-color: @pushbutton_focus_bg; -} - -QPushButton:checked { - background-color: @pushbutton_checked_bg; -} - -QPushButton:flat { - border: none; -} - -QPushButton:default { - border: 1px solid @pushbutton_default_border; -} - -QPushButton:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:pressed { - background-color: @pushbutton_pressed_bg; -} - -QPushButton:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton::menu-indicator { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - min-width: -1; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox#NotebookSelector { - border: none; - font-size: 12pt; - padding-top: 5px; - padding-bottom: 5px; - icon-size: $24px; - font-weight: bold; - color: @combobox_notebookselector_fg; - background: @combobox_notebookselector_bg; -} - -QComboBox#NotebookSelector:focus, QComboBox#NotebookSelector:on { - color: @combobox_notebookselector_focus_fg; - background: @combobox_notebookselector_focus_bg; -} - -QComboBox#NotebookSelector:hover { - color: @combobox_notebookselector_hover_fg; - background: @combobox_notebookselector_hover_bg; -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 12pt; - font-weight: normal; - icon-size: $24px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: $5px; - padding-bottom: $5px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} - -QComboBox { - padding: 3px; - color: @combobox_fg; - background: @combobox_bg; - border: 1px solid @combobox_border; -} - -QComboBox:focus, QComboBox:on { - background-color: @combobox_focus_bg; - border: 2px solid @combobox_focus_border; -} - -QComboBox:hover { - background-color: @combobox_hover_bg; - border: 2px solid @combobox_hover_border; -} - -QComboBox:disabled { - color: @combobox_disabled_fg; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: $20px; - border: none; - background: transparent; -} - -QComboBox::down-arrow { - image: url(arrow_dropdown.svg); - width: $20px; - height: $20px; -} - -QComboBox::down-arrow:disabled { - image: url(arrow_dropdown_disabled.svg); - width: $20px; - height: $20px; -} - -QComboBox QAbstractItemView { - padding: 2px; - border: 1px solid @combobox_view_border; - background: @combobox_bg; - selection-color: @combobox_view_selected_fg; - selection-background-color: @combobox_view_selected_bg; -} - -QComboBox QAbstractItemView::item { - background: transparent; - padding: 3px; -} - -QComboBox QAbstractItemView::item:hover { - color: @combobox_view_item_hover_fg; - background: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #00796B; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -QLabel[TagLabel="true"] { - padding-left: $5px; - padding-right: $5px; - color: @tab_indicator_tag_label_fg; - background-color: @tab_indicator_tag_label_bg; -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: $2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VDoubleRowItemWidget QLabel[FirstRowLabel="true"] { - border: none; - font-size: 10pt; -} - -VDoubleRowItemWidget QLabel[SecondRowLabel="true"] { - border: none; - font-size: 9pt; - color: @doublerowitem_second_row_label_fg; -} - -QLabel { - border: none; - color: @label_fg; - background: transparent; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} - -QLineEdit[VimCommandLine="true"]:focus { - background: @lineedit_focus_bg; - border: none; -} - -QLineEdit[VimCommandLine="true"]:hover { - background: @lineedit_hover_bg; - border: none; -} - -QLineEdit[EmbeddedEdit="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: transparent; -} - -QLineEdit[EmbeddedEdit="true"]:focus { - background: @lineedit_focus_bg; - border: none; -} - -QLineEdit[EmbeddedEdit="true"]:hover { - background: @lineedit_hover_bg; - border: none; -} - -QLineEdit { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QLineEdit:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QLineEdit:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} - -QLineEdit:disabled { - color: @lineedit_disabled_fg; -} -/* End QLineEdit */ - -/* QPlainTextEdit QTextEdit */ -QPlainTextEdit[LineEdit="true"], QTextEdit[LineEdit="true"] { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QPlainTextEdit[LineEdit="true"]:focus, QTextEdit[LineEdit="true"]:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QPlainTextEdit[LineEdit="true"]:hover, QTextEdit[LineEdit="true"]:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} -/* End QPlainTextEdit QTextEdit */ - -/* QTabWidget */ -QTabWidget { - border: none; -} - -QTabWidget::pane { - border: none; -} -/* End QTabWidget */ - -/* QTabBar */ -QTabBar::tab { - color: @tabbar_fg; - background: @tabbar_bg; - border: none; -} - -QTabBar::tab:top, QTabBar::tab:bottom { - border-top: $2px solid transparent; - border-right: $1px solid @tabbar_border; - /* MUST leave right and left padding 0px. */ - padding: $2px 0px $2px 0px; - height: $20px; -} - -QTabBar::tab:right { - border-left: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:left { - border-right: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:hover { - color: @tabbar_hover_fg; - background: @tabbar_hover_bg; -} - -QTabBar::tab:selected { - color: @tabbar_selected_fg; - background: @tabbar_selected_bg; -} - -QTabBar::tab:top:selected, QTabBar::tab:bottom:selected { - border-top: $2px solid @tabbar_selected_border; -} - -QTabBar::tab:right:selected { - border-left: $3px solid @tabbar_selected_border; -} - -QTabBar::tab:left:selected { - border-right: $3px solid @tabbar_selected_border; -} - -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:focus { - image: url(close.svg); -} - -QTabBar::close-button:hover { - image: url(close.svg); -} - -QTabBar::scroller { - width: $20px; -} - -QTabBar QToolButton { - border: none; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(right.svg); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(left.svg); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(right_disabled.svg); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(left_disabled.svg); -} -/* End QTabBar */ - -/* QTreeView */ -QTreeView[ItemBorder="true"]::item { - padding-top: 5px; - padding-bottom: 5px; - border-bottom: $1px solid @treeview_item_border_bg; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-children:!has-siblings:closed, -QTreeView[PlainTree="true"]::branch:closed:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView[PlainTree="true"]::branch:open:has-children:!has-siblings, -QTreeView[PlainTree="true"]::branch:open:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView { - color: @treeview_fg; - background: @treeview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QTreeView::item:hover { - color: @treeview_item_hover_fg; - background: @treeview_item_hover_bg; -} - -QTreeView::item:selected { - color: @treeview_item_selected_fg; - background: @treeview_item_selected_bg; -} - -QTreeView::item:selected:active { - color: @treeview_item_selected_active_fg; - background: @treeview_item_selected_active_bg; -} - -QTreeView::item:selected:!active { - color: @treeview_item_selected_inactive_fg; - background: @treeview_item_selected_inactive_bg; -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(line.svg) 0; -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(branch_more.svg) 0; -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(branch_end.svg) 0; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(branch_closed.svg); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(branch_open.svg); -} -/* End QTreeView */ - -/* QListView */ -QListView { - color: @listview_fg; - background: @listview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QListView::item:hover { - color: @listview_item_hover_fg; - background: @listview_item_hover_bg; -} - -QListView::item:selected { - color: @listview_item_selected_fg; - background: @listview_item_selected_bg; -} - -QListView::item:selected:active { - color: @listview_item_selected_active_fg; - background: @listview_item_selected_active_bg; -} - -QListView::item:selected:!active { - color: @listview_item_selected_inactive_fg; - background: @listview_item_selected_inactive_bg; -} - -QListView::item:disabled { - background: transparent; -} -/* End QListView */ - -/* QAbstractItemView for TextEdit Completer popup*/ -QAbstractItemView[TextEdit="true"] { - color: @abstractitemview_textedit_fg; - background: @abstractitemview_textedit_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QAbstractItemView[TextEdit="true"]::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QAbstractItemView[TextEdit="true"]::item:hover { - color: @abstractitemview_textedit_item_hover_fg; - background: @abstractitemview_textedit_item_hover_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected { - color: @abstractitemview_textedit_item_selected_fg; - background: @abstractitemview_textedit_item_selected_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:active { - color: @abstractitemview_textedit_item_selected_active_fg; - background: @abstractitemview_textedit_item_selected_active_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:!active { - color: @abstractitemview_textedit_item_selected_inactive_fg; - background: @abstractitemview_textedit_item_selected_inactive_bg; -} - -QAbstractItemView[TextEdit="true"]::item:disabled { - background: transparent; -} -/* End QAbstractItemView */ - -/* QSplitter */ -QSplitter#MainSplitter { - border: none; - margin-left: $3px; -} - -QSplitter { - border: none; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:pressed { - background-color: @splitter_handle_pressed_bg; -} - -QSplitter::handle:vertical { - height: $2px; -} - -QSplitter::handle:horizontal { - width: $2px; -} -/* End QSplitter */ - -/* QStatusBar */ -QStatusBar { - color: @statusbar_fg; - background: @statusbar_bg; -} -/* End QStatusBar */ - -QDialog { - color: @base_fg; - background: @base_bg; -} - -/* QScrollBar */ -QScrollBar::add-page, QScrollBar::sub-page { - background: @scrollbar_page_bg; -} - -QScrollBar:vertical { - background: @scrollbar_bg; - width: $16px; - margin: $16px 0px $16px 0px; - padding: 0px $2px 0px $2px; - border: none; -} - -QScrollBar::handle:vertical { - background: @scrollbar_handle_bg; - min-height: $16px; -} - -QScrollBar::handle:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::down-arrow:vertical { - image: url(down.svg); - width: $16px; - height: $16px; -} - -QScrollBar::up-arrow:vertical { - image: url(up.svg); - width: $16px; - height: $16px; -} - -QScrollBar:horizontal { - background: @scrollbar_bg; - height: $16px; - margin: 0px $16px 0px $16px; - padding: $2px 0px $2px 0px; - border: none; -} - -QScrollBar::handle:horizontal { - background: @scrollbar_handle_bg; - min-width: $16px; -} - -QScrollBar::handle:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::right-arrow:horizontal { - image: url(right.svg); - width: $16px; - height: $16px; -} - -QScrollBar::left-arrow:horizontal { - image: url(left.svg); - width: $16px; - height: $16px; -} -/* End QScrollBar */ - -/* QCheckBox */ -QCheckBox { - spacing: $5px; -} - -QCheckBox:disabled { - color: @checkbox_disabled_fg; -} - -QCheckBox::indicator:unchecked { - image: url(checkbox_unchecked.svg); -} - -QCheckBox::indicator:unchecked:disabled { - image: url(checkbox_unchecked_disabled.svg); -} - -QCheckBox::indicator:checked { - image: url(checkbox_checked.svg); -} - -QCheckBox::indicator:checked:disabled { - image: url(checkbox_checked_disabled.svg); -} - -QCheckBox::indicator { - width: $20px; - height: $20px; -} - -QCheckBox::indicator:focus { - background: @checkbox_indicator_focus_bg; -} - -QCheckBox::indicator:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:pressed { - background: @checkbox_indicator_pressed_bg; -} -/* End QCheckBox */ - -/* QRadioButton */ -QRadioButton { - spacing: $5px; -} - -QRadioButton:disabled { - color: @radiobutton_disabled_fg; -} - -QRadioButton::indicator:unchecked { - image: url(radiobutton_unchecked.svg); -} - -QRadioButton::indicator:unchecked:disabled { - image: url(radiobutton_unchecked_disabled.svg); -} - -QRadioButton::indicator:checked { - image: url(radiobutton_checked.svg); -} - -QRadioButton::indicator:checked:disabled { - image: url(radiobutton_checked_disabled.svg); -} - -QRadioButton::indicator { - width: $20px; - height: $20px; -} - -QRadioButton::indicator:focus { - background: @radiobutton_indicator_focus_bg; -} - -QRadioButton::indicator:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:pressed { - background: @radiobutton_indicator_pressed_bg; -} -/* End QRadioButton */ - -/* QSpinBox */ -QSpinBox, QDoubleSpinBox { - border: 1px solid @spinbox_border; - color: @spinbox_fg; - background: @spinbox_bg; - padding-right: $25px; - min-height: $25px; - selection-color: @spinbox_selection_fg; - selection-background-color: @spinbox_selection_bg; -} - -QSpinBox:focus, QDoubleSpinBox::focus { - border: 2px solid @spinbox_focus_border; - background: @spinbox_focus_bg; -} - -QSpinBox:hover, QDoubleSpinBox::hover { - border: 2px solid @spinbox_hover_border; - background: @spinbox_hover_bg; -} - -QSpinBox::up-button, QDoubleSpinBox::up-button { - subcontrol-origin: border; - subcontrol-position: top right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} - -QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off, QDoubleSpinBox::up-arrow:disabled, QDoubleSpinBox::up-arrow:off { - image: url(up_disabled.svg); -} - -QSpinBox::down-button, QDoubleSpinBox::down-button { - subcontrol-origin: border; - subcontrol-position: bottom right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off, QDoubleSpinBox::down-arrow:disabled, QDoubleSpinBox::down-arrow:off { - image: url(down_disabled.svg); -} -/* End QSpinBox */ - -/* QHeaderView */ -QHeaderView::section { - background: @headerview_bg; - color: @headerview_fg; - padding-left: 4px; - border: none; - border-left: 1px solid @headerview_border; - border-bottom: 1px solid @headerview_border; -} - -QHeaderView::section:checked -{ - color: @headerview_checked_fg; - background: @headerview_checked_bg; -} - -/* style the sort indicator */ -QHeaderView::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QHeaderView::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} -/* End QHeaderView */ - -QAbstractScrollArea::corner { - background: @scrollbar_bg; - border: none; -} - -/* QProgressBar */ -QProgressBar { - background: @progressbar_bg; - border: $1px solid @progressbar_border_bg; - text-align: center; -} - -QProgressBar::chunk { - background-color: @progressbar_chunk_bg; - width: $20px; -} -/* End QProgressBar */ - -/* QGroupBox */ -QGroupBox { - border: 2px solid @groupbox_border; - border-radius: 5px; - margin-top: 2ex; -} - -QGroupBox::title { - color: @groupbox_title_fg; - subcontrol-origin: margin; - subcontrol-position: top left; - position: absolute; - padding: 0 $3px; - top: 0px; left: $10px; bottom: 0px; -} -/* End QGroupBox */ - -/* QSlider */ -QSlider::groove:horizontal { - border: $1px solid @slider_border_bg; - height: $8px; - background: @slider_groove_bg; - margin: $2px 0; -} - -QSlider::handle:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - width: $18px; - margin: $-2px 0; -} - -QSlider::add-page:horizontal { - background: transparent; -} - -QSlider::sub-page:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: $2px 0; -} - -QSlider::groove:vertical { - border: $1px solid @slider_border_bg; - width: $8px; - background: @slider_groove_bg; - margin: 0 $2px; -} - -QSlider::handle:vertical { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - height: $18px; - margin: 0 $-2px; -} - -QSlider::add-page:vertical { - background: transparent; -} - -QSlider::sub-page:vertical { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: 0 $2px; -} -/* End QSlider */ - -/* QWidget */ -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} - -QWidget[ToolBoxTitle="true"] { - border-bottom: $2px solid @toolbox_title_border; -} - -QWidget[ToolBoxTitle="true"] QPushButton[ToolBoxTitleBtn="true"] { - height: $20px; -} - -QWidget[MainEditor="true"] { - border: none; -} - -QWidget -{ - color: @widget_fg; - font-family: "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", "Dengxian", "等线体", "STXihei", "华文细黑", "Liberation Sans", "Droid Sans", "NSimSun", "新宋体", "SimSun", "宋体", "Helvetica", "sans-serif", "Tahoma", "Arial", "Verdana", "Geneva", "Georgia", "Times New Roman"; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} - -VUniversalEntry { - background: @universalentry_bg; - border: 1px solid @universalentry_border_bg; -} -/* End QWidget */ diff --git a/src/resources/themes/v_next/v_next_codeblock.css b/src/resources/themes/v_next/v_next_codeblock.css deleted file mode 100644 index 20f9dfd6..00000000 --- a/src/resources/themes/v_next/v_next_codeblock.css +++ /dev/null @@ -1,67 +0,0 @@ -/** - * highlight.js tomorrow style - */ - -.hljs-comment, -.hljs-quote { - color: #8e908c -} - -.hljs-variable, -.hljs-template-variable, -.hljs-tag, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class, -.hljs-regexp, -.hljs-deletion { - color: #c82829 -} - -.hljs-number, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params, -.hljs-meta, -.hljs-link { - color: #f5871f -} - -.hljs-attribute { - color: #eab700 -} - -.hljs-string, -.hljs-symbol, -.hljs-bullet, -.hljs-addition { - color: #718c00 -} - -.hljs-title, -.hljs-section { - color: #4271ae -} - -.hljs-keyword, -.hljs-selector-tag { - color: #8959a8 -} - -.hljs { - display: block; - overflow-x: auto; - background: #F7F7F7; - color: #4d4d4c; - padding: 0.5em -} - -.hljs-emphasis { - font-style: italic -} - -.hljs-strong { - font-weight: bold -} diff --git a/src/resources/themes/v_next/v_next_mermaid.css b/src/resources/themes/v_next/v_next_mermaid.css deleted file mode 100644 index 3d808780..00000000 --- a/src/resources/themes/v_next/v_next_mermaid.css +++ /dev/null @@ -1,320 +0,0 @@ -/* Flowchart variables */ -/* Sequence Diagram variables */ -/* Gantt chart variables */ -.mermaid-diagram .mermaid .label { - color: #333; -} - -.mermaid-diagram .node rect, -.mermaid-diagram .node circle, -.mermaid-diagram .node ellipse, -.mermaid-diagram .node polygon { - fill: #ECECFF; - stroke: #CCCCFF; - stroke-width: 1px; -} - -.mermaid-diagram .edgePath .path { - stroke: #333333; -} - -.mermaid-diagram .edgeLabel { - background-color: #e8e8e8; -} - -.mermaid-diagram .cluster rect { - fill: #ffffde !important; - rx: 4 !important; - stroke: #aaaa33 !important; - stroke-width: 1px !important; -} - -.mermaid-diagram .cluster text { - fill: #333; -} - -.mermaid-diagram .actor { - stroke: #CCCCFF; - fill: #ECECFF; -} - -.mermaid-diagram text.actor { - fill: black; - stroke: none; -} - -.mermaid-diagram .actor-line { - stroke: grey; -} - -.mermaid-diagram .messageLine0 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #333; -} - -.mermaid-diagram .messageLine1 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - stroke: #333; -} - -.mermaid-diagram #arrowhead { - fill: #333; -} - -.mermaid-diagram #crosshead path { - fill: #333 !important; - stroke: #333 !important; -} - -.mermaid-diagram .messageText { - fill: #333; - stroke: none; -} - -.mermaid-diagram .labelBox { - stroke: #CCCCFF; - fill: #ECECFF; -} - -.mermaid-diagram .labelText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopLine { - stroke-width: 2; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #CCCCFF; -} - -.mermaid-diagram .note { - stroke: #aaaa33; - fill: #fff5ad; -} - -.mermaid-diagram .noteText { - fill: black; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -/** Section styling */ -.mermaid-diagram .section { - stroke: none; - opacity: 0.2; -} - -.mermaid-diagram .section0 { - fill: rgba(102, 102, 255, 0.49); -} - -.mermaid-diagram .section2 { - fill: #fff400; -} - -.mermaid-diagram .section1, -.mermaid-diagram .section3 { - fill: white; - opacity: 0.2; -} - -.mermaid-diagram .sectionTitle0 { - fill: #333; -} - -.mermaid-diagram .sectionTitle1 { - fill: #333; -} - -.mermaid-diagram .sectionTitle2 { - fill: #333; -} - -.mermaid-diagram .sectionTitle3 { - fill: #333; -} - -.mermaid-diagram .sectionTitle { - text-anchor: start; - font-size: 11px; - text-height: 14px; -} - -/* Grid and axis */ -.mermaid-diagram .grid .tick { - stroke: lightgrey; - opacity: 0.3; - shape-rendering: crispEdges; -} - -.mermaid-diagram .grid path { - stroke-width: 0; -} - -/* Today line */ -.mermaid-diagram .today { - fill: none; - stroke: red; - stroke-width: 2px; -} - -/* Task styling */ -/* Default task */ -.mermaid-diagram .task { - stroke-width: 2; -} - -.mermaid-diagram .taskText { - text-anchor: middle; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideRight { - fill: black; - text-anchor: start; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideLeft { - fill: black; - text-anchor: end; - font-size: 11px; -} - -/* Specific task settings for the sections*/ -.mermaid-diagram .taskText0, -.mermaid-diagram .taskText1, -.mermaid-diagram .taskText2, -.mermaid-diagram .taskText3 { - fill: white; -} - -.mermaid-diagram .task0, -.mermaid-diagram .task1, -.mermaid-diagram .task2, -.mermaid-diagram .task3 { - fill: #8a90dd; - stroke: #534fbc; -} - -.mermaid-diagram .taskTextOutside0, -.mermaid-diagram .taskTextOutside2 { - fill: black; -} - -.mermaid-diagram .taskTextOutside1, -.mermaid-diagram .taskTextOutside3 { - fill: black; -} - -/* Active task */ -.mermaid-diagram .active0, -.mermaid-diagram .active1, -.mermaid-diagram .active2, -.mermaid-diagram .active3 { - fill: #bfc7ff; - stroke: #534fbc; -} - -.mermaid-diagram .activeText0, -.mermaid-diagram .activeText1, -.mermaid-diagram .activeText2, -.mermaid-diagram .activeText3 { - fill: black !important; -} - -/* Completed task */ -.mermaid-diagram .done0, -.mermaid-diagram .done1, -.mermaid-diagram .done2, -.mermaid-diagram .done3 { - stroke: grey; - fill: lightgrey; - stroke-width: 2; -} - -.mermaid-diagram .doneText0, -.mermaid-diagram .doneText1, -.mermaid-diagram .doneText2, -.mermaid-diagram .doneText3 { - fill: black !important; -} - -/* Tasks on the critical line */ -.mermaid-diagram .crit0, -.mermaid-diagram .crit1, -.mermaid-diagram .crit2, -.mermaid-diagram .crit3 { - stroke: #ff8888; - fill: red; - stroke-width: 2; -} - -.mermaid-diagram .activeCrit0, -.mermaid-diagram .activeCrit1, -.mermaid-diagram .activeCrit2, -.mermaid-diagram .activeCrit3 { - stroke: #ff8888; - fill: #bfc7ff; - stroke-width: 2; -} - -.mermaid-diagram .doneCrit0, -.mermaid-diagram .doneCrit1, -.mermaid-diagram .doneCrit2, -.mermaid-diagram .doneCrit3 { - stroke: #ff8888; - fill: lightgrey; - stroke-width: 2; - cursor: pointer; - shape-rendering: crispEdges; -} - -.mermaid-diagram .doneCritText0, -.mermaid-diagram .doneCritText1, -.mermaid-diagram .doneCritText2, -.mermaid-diagram .doneCritText3 { - fill: black !important; -} - -.mermaid-diagram .activeCritText0, -.mermaid-diagram .activeCritText1, -.mermaid-diagram .activeCritText2, -.mermaid-diagram .activeCritText3 { - fill: black !important; -} - -.mermaid-diagram .titleText { - text-anchor: middle; - font-size: 18px; - fill: black; -} - -.mermaid-diagram .node text { - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -.mermaid-diagram div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: 'trebuchet ms', verdana, arial; - font-size: 12px; - background: #ffffde; - border: 1px solid #aaaa33; - border-radius: 2px; - pointer-events: none; - z-index: 100; -} diff --git a/src/resources/themes/v_pure/arrow_dropdown.svg b/src/resources/themes/v_pure/arrow_dropdown.svg deleted file mode 100644 index 8b465de9..00000000 --- a/src/resources/themes/v_pure/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_pure/arrow_dropdown_disabled.svg b/src/resources/themes/v_pure/arrow_dropdown_disabled.svg deleted file mode 100644 index 7add5e54..00000000 --- a/src/resources/themes/v_pure/arrow_dropdown_disabled.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_pure/branch_closed.svg b/src/resources/themes/v_pure/branch_closed.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_pure/branch_closed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/branch_end.svg b/src/resources/themes/v_pure/branch_end.svg deleted file mode 100644 index baa0c23f..00000000 --- a/src/resources/themes/v_pure/branch_end.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_pure/branch_more.svg b/src/resources/themes/v_pure/branch_more.svg deleted file mode 100644 index cb0fecad..00000000 --- a/src/resources/themes/v_pure/branch_more.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_pure/branch_open.svg b/src/resources/themes/v_pure/branch_open.svg deleted file mode 100644 index c1e8e141..00000000 --- a/src/resources/themes/v_pure/branch_open.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/checkbox_checked.svg b/src/resources/themes/v_pure/checkbox_checked.svg deleted file mode 100644 index f017b5b4..00000000 --- a/src/resources/themes/v_pure/checkbox_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_pure/checkbox_checked_disabled.svg b/src/resources/themes/v_pure/checkbox_checked_disabled.svg deleted file mode 100644 index 39c47873..00000000 --- a/src/resources/themes/v_pure/checkbox_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_pure/checkbox_unchecked.svg b/src/resources/themes/v_pure/checkbox_unchecked.svg deleted file mode 100644 index 5167523e..00000000 --- a/src/resources/themes/v_pure/checkbox_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/checkbox_unchecked_disabled.svg b/src/resources/themes/v_pure/checkbox_unchecked_disabled.svg deleted file mode 100644 index 35788230..00000000 --- a/src/resources/themes/v_pure/checkbox_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/close.svg b/src/resources/themes/v_pure/close.svg deleted file mode 100644 index 26cbf713..00000000 --- a/src/resources/themes/v_pure/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_pure/close_grey.svg b/src/resources/themes/v_pure/close_grey.svg deleted file mode 100644 index 24bddd4e..00000000 --- a/src/resources/themes/v_pure/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_pure/down.svg b/src/resources/themes/v_pure/down.svg deleted file mode 100644 index 386ac7f8..00000000 --- a/src/resources/themes/v_pure/down.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/down_disabled.svg b/src/resources/themes/v_pure/down_disabled.svg deleted file mode 100644 index 2a53e0f0..00000000 --- a/src/resources/themes/v_pure/down_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/float.svg b/src/resources/themes/v_pure/float.svg deleted file mode 100644 index e4a198f3..00000000 --- a/src/resources/themes/v_pure/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_pure/left.svg b/src/resources/themes/v_pure/left.svg deleted file mode 100644 index aee69f4a..00000000 --- a/src/resources/themes/v_pure/left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/left_disabled.svg b/src/resources/themes/v_pure/left_disabled.svg deleted file mode 100644 index 3cabd4b5..00000000 --- a/src/resources/themes/v_pure/left_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/line.svg b/src/resources/themes/v_pure/line.svg deleted file mode 100644 index 8c981419..00000000 --- a/src/resources/themes/v_pure/line.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 2 - - - diff --git a/src/resources/themes/v_pure/menu_checkbox.svg b/src/resources/themes/v_pure/menu_checkbox.svg deleted file mode 100644 index 0aeb35a1..00000000 --- a/src/resources/themes/v_pure/menu_checkbox.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/menu_radiobutton.svg b/src/resources/themes/v_pure/menu_radiobutton.svg deleted file mode 100644 index aafaa309..00000000 --- a/src/resources/themes/v_pure/menu_radiobutton.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/radiobutton_checked.svg b/src/resources/themes/v_pure/radiobutton_checked.svg deleted file mode 100644 index c9834cc5..00000000 --- a/src/resources/themes/v_pure/radiobutton_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_pure/radiobutton_checked_disabled.svg b/src/resources/themes/v_pure/radiobutton_checked_disabled.svg deleted file mode 100644 index b67faef0..00000000 --- a/src/resources/themes/v_pure/radiobutton_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_pure/radiobutton_unchecked.svg b/src/resources/themes/v_pure/radiobutton_unchecked.svg deleted file mode 100644 index 7cd0863a..00000000 --- a/src/resources/themes/v_pure/radiobutton_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/radiobutton_unchecked_disabled.svg b/src/resources/themes/v_pure/radiobutton_unchecked_disabled.svg deleted file mode 100644 index 8308f78b..00000000 --- a/src/resources/themes/v_pure/radiobutton_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_pure/right.svg b/src/resources/themes/v_pure/right.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_pure/right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/right_disabled.svg b/src/resources/themes/v_pure/right_disabled.svg deleted file mode 100644 index c0c83ba8..00000000 --- a/src/resources/themes/v_pure/right_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/up.svg b/src/resources/themes/v_pure/up.svg deleted file mode 100644 index 52be26da..00000000 --- a/src/resources/themes/v_pure/up.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/up_disabled.svg b/src/resources/themes/v_pure/up_disabled.svg deleted file mode 100644 index 36e54158..00000000 --- a/src/resources/themes/v_pure/up_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_pure/v_pure.css b/src/resources/themes/v_pure/v_pure.css deleted file mode 100644 index ec291a07..00000000 --- a/src/resources/themes/v_pure/v_pure.css +++ /dev/null @@ -1,363 +0,0 @@ -body { - margin: 0 auto; - font-family: "Segoe UI", Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Palatino, "Times New Roman", "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", Dengxian, "等线体", STXihei, "华文细黑", "Liberation Sans", "Droid Sans", NSimSun, "新宋体", SimSun, "宋体"; - color: #222222; - line-height: 1.5; - padding: 15px; - background: #EEEEEE; - font-size: 16px; -} - -h1, h2, h3, h4, h5, h6 { - color: #222222; - font-weight: bold; - margin-top: 20px; - margin-bottom: 10px; - padding: 0; -} - -p { - padding: 0; - margin-top: 16px; - margin-bottom: 16px; -} - -h1 { - font-size: 26px; -} - -h2 { - font-size: 24px; -} - -h3 { - font-size: 22px; -} - -h4 { - font-size: 20px; -} - -h5 { - font-size: 19px; -} - -h6 { - font-size: 18px; -} - -a { - color: #0099ff; - margin: 0; - padding: 0; - vertical-align: baseline; - text-decoration: none; - word-break: break-word; -} - -a:hover { - text-decoration: underline; - color: #ff6600; -} - -a:visited { - color: purple; -} - -ul, ol { - padding: 0; - padding-left: 24px; -} - -li { - line-height: 24px; -} - -li ul, li ol { - margin-left: 16px; -} - -p, ul, ol { - font-size: 16px; - line-height: 24px; -} - -pre { - display: block; - overflow-y: hidden; - overflow-x: auto; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -code { - font-family: Consolas, Monaco, Monospace, Courier; - color: #8E24AA; - word-break: break-word; -} - -pre code { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #222222; - background-color: #E0E0E0; - border-left: .5em solid #00897B; - line-height: 1.5; - font-family: Consolas, Monaco, Monospace, Courier; - white-space: pre; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -pre code.markdown-metadata { - border-left: .5em solid #80CBC4; -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - color: #666; - border-left: .5em solid #7a7a7a; - padding: 0 1em; - margin-left: 0; -} - -blockquote p { - color: #666; -} - -hr { - display: block; - text-align: left; - margin: 1em 0; - border: none; - height: 2px; - background: #999; -} - -table { - padding: 0; - margin: 1rem 0.5rem; - border-collapse: collapse; -} - -table tr { - border-top: 2px solid #cccccc; - background-color: white; - margin: 0; - padding: 0; -} - -table tr:nth-child(2n) { - background-color: #f8f8f8; -} - -table tr th { - font-weight: bold; - border: 2px solid #cccccc; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 2px solid #cccccc; - margin: 0; - padding: 6px 13px; -} - -table tr th :first-child, table tr td :first-child { - margin-top: 0; -} - -table tr th :last-child, table tr td :last-child { - margin-bottom: 0; -} - -div.mermaid-diagram { - margin: 16px 0px 16px 0px; - overflow-y: hidden; -} - -div.flowchart-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -div.wavedrom-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -div.plantuml-diagram { - padding: 5px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -.img-package { - text-align: center; -} - -img.img-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -span.img-caption { - min-width: 20%; - max-width: 80%; - display: inline-block; - padding: 10px; - margin: 0 auto; - border-bottom: 1px solid #c0c0c0; - color: #6c6c6c; - text-align: center; - line-height: 1.5; -} - -.emoji_zero,.emoji_one,.emoji_two,.emoji_three,.emoji_four,.emoji_five,.emoji_six,.emoji_seven,.emoji_eight,.emoji_nine { - margin-left: 5px; - margin-right: 8px; -} - -div.preview-hint { - opacity: 0.5; - margin-top: 30%; - margin-bottom: 30%; - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; -} - -/* For Highlight.js Line Number */ -table.hljs-ln tr { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td.hljs-ln-numbers { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - text-align: center; - color: #AAA; - border-right: 1px solid #CCC; - vertical-align: top; - padding-right: 5px; - white-space: nowrap; -} - -table.hljs-ln tr td.hljs-ln-code { - padding-left: 10px; -} - -::-webkit-scrollbar { - background-color: #EAEAEA; - width: 14px; - height: 14px; - border: none; -} - -::-webkit-scrollbar-corner { - background-color: #EAEAEA; -} - -::-webkit-scrollbar-button { - /* This selector affects the styling of both the up & down and left & right buttons of a scrollbar */ - height: 14px; - width: 14px; - background-color: #EAEAEA; -} - -::-webkit-scrollbar-button:hover { - background-color: #D0D0D0; -} - -::-webkit-scrollbar-button:active { - background-color: #B2B2B2; -} - -::-webkit-scrollbar-track { - /* This selector affects the styling of the area in the scrollbar between the two buttons */ - background-color: #EAEAEA; -} - -::-webkit-scrollbar-thumb { - /* This selector affects the styling of draggable element of the scollbar */ - border: none; - background-color: #DADADA; -} - -::-webkit-scrollbar-thumb:hover { - background-color: #D0D0D0; -} - -::-webkit-scrollbar-thumb:active { - background-color: #B2B2B2; -} - -::-webkit-scrollbar-button:horizontal:increment { - background-image: url(right.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:horizontal:decrement { - background-image: url(left.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:increment { - background-image: url(down.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:decrement { - background-image: url(up.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::selection { - background: #1976D2; - color: #EEEEEE; -} - -.modal-box { - background-color: rgb(234, 234, 234); - background-color: rgba(234, 234, 234, 0.95); -} - -span.modal-close { - color: #666666; -} - -span.modal-close:hover, -span.modal-close:focus { - color: #222222; -} diff --git a/src/resources/themes/v_pure/v_pure.mdhl b/src/resources/themes/v_pure/v_pure.mdhl deleted file mode 100644 index 6a3fe4b9..00000000 --- a/src/resources/themes/v_pure/v_pure.mdhl +++ /dev/null @@ -1,209 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Verdana, Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Times New Roman -font-size: 12 -foreground: 222222 -background: eeeeee -# [VNote] Style for trailing space -trailing-space: a8a8a8 -# [VNote] Style for line number -line-number-background: eeeeee -line-number-foreground: 666666 -# [VNote] Style for selected word highlight -selected-word-foreground: 222222 -selected-word-background: dfdf00 -# [VNote] Style for searched word highlight -searched-word-foreground: 222222 -searched-word-background: 4db6ac -# [VNote] Style for searched word under cursor highlight -searched-word-cursor-foreground: 222222 -searched-word-cursor-background: 66bb6a -# [VNote] Style for incremental searched word highlight -incremental-searched-word-foreground: 222222 -incremental-searched-word-background: ce93d8 -# [VNote] Style for color column in fenced code block -color-column-background: dd0000 -color-column-foreground: ffff00 -# [VNote] Style for preview image line -preview-image-line-foreground: 9575cd - -editor-selection -foreground: eeeeee -background: 1976d2 - -editor-current-line -background: c5cae9 -# [VNote] Vim insert mode cursor line background -vim-insert-background: c5cae9 -# [VNote] Vim normal mode cursor line background -vim-normal-background: e0e0e0 -# [VNote] Vim visual mode cursor line background -vim-visual-background: ffe0b2 -# [VNote] Vim replace mode cursor line background -vim-replace-background: f8bbd0 - -H1 -foreground: 222222 -font-style: bold -font-size: +6 - -H2 -foreground: 222222 -font-style: bold -font-size: +5 - -H3 -foreground: 222222 -font-style: bold -font-size: +4 - -H4 -foreground: 222222 -font-style: bold -font-size: +3 - -H5 -foreground: 222222 -font-style: bold -font-size: +2 - -H6 -foreground: 222222 -font-style: bold -font-size: +1 - -HRULE -foreground: 222222 -background: dac7c9 - -LIST_BULLET -foreground: d33682 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: 0000ff - -LINK -foreground: 005fff - -AUTO_LINK_URL -foreground: 005fff - -AUTO_LINK_EMAIL -foreground: 005fff - -IMAGE -foreground: 616161 - -REFERENCE -foreground: 826200 - -CODE -foreground: 8e24aa -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -EMPH -font-style: italic - -STRONG -font-style: bold - -HTML_ENTITY -foreground: 8900b5 - -HTML -foreground: 8900b5 - -HTMLBLOCK -foreground: 8900b5 - -COMMENT -foreground: 93a1a1 - -VERBATIM -foreground: 673ab7 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -FENCEDCODEBLOCK -foreground: 673ab7 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color) -# The last occurence of the same attribute takes effect -# Could specify multiple attribute in one line -hljs-comment: 6c6c6c -hljs-keyword: 0000ee -hljs-attribute: 0000ee -hljs-selector-tag: 0000ee -hljs-meta-keyword: 0000ee -hljs-doctag: 0000ee -hljs-name: 0000ee -hljs-type: 880000 -hljs-string: 880000 -hljs-number: 880000 -hljs-selector-id: 880000 -hljs-selector-class: 880000 -hljs-quote: 880000 -hljs-template-tag: 880000 -hljs-deletion: 880000 -hljs-title: bold, 880000 -hljs-section: bold, 880000 -hljs-regexp: bc6060 -hljs-symbol: bc6060 -hljs-variable: bc6060 -hljs-template-variable: bc6060 -hljs-link: bc6060 -hljs-selector-attr: bc6060 -hljs-selector-pseudo: bc6060 -hljs-literal: af00d7 -hljs-built_in: 008700 -hljs-bullet: 008700 -hljs-code: 008700 -hljs-addition: 008700 -hljs-meta: 1f7199 -hljs-meta-string: 4d99bf -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: 00af00 - -NOTE -foreground: 0087b5 - -STRIKE -foreground: b71c1c -font-style: strikeout - -FRONTMATTER -foreground: 6c6c6c - -INLINEEQUATION -foreground: 00897b -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -DISPLAYFORMULA -foreground: 00897b -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -MARK -foreground: 222222 -background: ffff76 - -TABLE -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -TABLEBORDER -foreground: d33682 -background: e0e0e0 diff --git a/src/resources/themes/v_pure/v_pure.palette b/src/resources/themes/v_pure/v_pure.palette deleted file mode 100644 index 4e9cd52e..00000000 --- a/src/resources/themes/v_pure/v_pure.palette +++ /dev/null @@ -1,385 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. - -[metadata] -qss_file=v_pure.qss -mdhl_file=v_pure.mdhl -css_file=v_pure.css -codeblock_css_file=v_pure_codeblock.css -mermaid_css_file=v_pure_mermaid.css -version=27 - -[phony] -; Abstract color attributes. -master_fg=#F5F5F5 -master_bg=#00897B -master_light_bg=#80CBC4 -master_dark_bg=#00796B -master_focus_bg=#009688 -master_hover_bg=#009688 -master_pressed_bg=#00796B - -base_fg=#222222 -base_bg=#EAEAEA - -main_fg=@base_fg -main_bg=@base_bg - -title_fg=@base_fg -title_bg=@base_bg - -disabled_fg=#9E9E9E - -content_fg=@base_fg -content_bg=@base_bg - -border_bg=#D3D3D3 - -separator_bg=#D3D3D3 - -hover_fg=@base_fg -hover_bg=#D0D0D0 - -selected_fg=@base_fg -selected_bg=#7BBAB9 - -active_fg=@selected_fg -active_bg=@selected_bg - -inactive_fg=@selected_fg -inactive_bg=#99CFCA - -focus_fg=@base_fg -focus_bg=#BDBDBD - -pressed_fg=@base_fg -pressed_bg=#B2B2B2 - -edit_fg=#222222 -edit_bg=#EEEEEE -edit_focus_bg=#E0F2F1 -edit_focus_border=@master_bg -edit_hover_bg=#F2FAF9 -edit_hover_border=@master_bg -edit_selection_fg=@edit_fg -edit_selection_bg=@master_light_bg - -icon_fg=#222222 -icon_disabled_fg=@disabled_fg - -danger_fg=#F5F5F5 -danger_bg=#C9302C -danger_focus_bg=#D9534F -danger_hover_bg=#DE6764 -danger_pressed_bg=#AC2925 - -[soft_defined] -; VAvatar. -; The foreground color of the avatar when Captain mode is triggered. -avatar_captain_mode_fg=@master_fg -; The background color of the avatar when Captain mode is triggered. -avatar_captain_mode_bg=@master_bg - -; Style of the label in Navigation mode. -navigation_label_fg=@master_fg -navigation_label_bg=@master_bg - -; Style of the bubble of VButtonWithWidget. -bubble_fg=@master_fg -bubble_bg=@master_bg - -; Icons' foreground. -danger_icon_fg=@danger_bg -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg -tab_indicator_tag_label_fg=#222222 -tab_indicator_tag_label_bg=#ce93db - -; Html template. -template_title_flash_light_fg=@master_light_bg -template_title_flash_dark_fg=@master_bg - -; Search hit items in list or tree view. -search_hit_item_fg=@selected_fg -search_hit_item_bg=#CCE7E4 - -; Universal Entry CMD Edit border color -ue_cmd_busy_border=#3F51B5 -ue_cmd_fail_border=@danger_bg - -; VListWidget/VTreeWidget separator. -item_separator_fg=@master_dark_bg -item_separator_bg=@separator_bg - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Separator of dock widgets. -dock_separator_bg=@separator_bg -dock_separator_hover_bg=@hover_bg -dock_separator_pressed_bg=@pressed_bg - -; Menubar. -menubar_bg=@main_bg -menubar_fg=@main_fg -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_bg=@base_bg -menu_fg=@base_fg -menu_border_bg=@border_bg -menu_item_disabled_fg=@disabled_fg -menu_item_selected_fg=@selected_fg -menu_item_selected_bg=@selected_bg -menu_separator_bg=@separator_bg -menu_icon_fg=@icon_fg -menu_icon_danger_fg=@danger_icon_fg - -; Tooltip. -tooltip_bg=@master_bg -tooltip_fg=@master_fg - -; Toolbar. -toolbar_bg=@main_bg -toolbar_separator_bg=@separator_bg -toolbutton_hover_bg=@hover_bg -toolbutton_pressed_bg=@pressed_bg -toolbutton_checked_bg=@selected_bg -toolbutton_icon_fg=@icon_fg -toolbutton_icon_danger_fg=@danger_icon_fg - -; Toolbox. -toolbox_icon_fg=@master_bg -toolbox_icon_active_fg=@master_fg -toolbox_title_border=@master_bg - -; Dockwidget. -dockwidget_bg=@base_bg -dockwidget_title_fg=@title_fg -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_fg=@base_fg -pushbutton_bg=transparent -pushbutton_border=@border_bg -pushbutton_pressed_bg=@pressed_bg -pushbutton_focus_bg=@focus_bg -pushbutton_checked_bg=@selected_bg -pushbutton_hover_bg=@hover_bg -pushbutton_default_border=@master_bg -pushbutton_disabled_fg=@disabled_fg -pushbutton_disabled_bg=@pushbutton_bg - -pushbutton_specialbtn_fg=@master_fg -pushbutton_specialbtn_bg=@master_bg -pushbutton_specialbtn_focus_bg=@master_focus_bg -pushbutton_specialbtn_hover_bg=@master_hover_bg -pushbutton_specialbtn_checked_bg=#3F51B5 -pushbutton_specialbtn_pressed_bg=@master_pressed_bg - -pushbutton_titlebtn_bg=@title_bg - -pushbutton_dangerbtn_fg=@danger_fg -pushbutton_dangerbtn_bg=@danger_bg -pushbutton_dangerbtn_hover_bg=@danger_hover_bg -pushbutton_dangerbtn_focus_bg=@danger_focus_bg -pushbutton_dangerbtn_pressed_bg=@danger_pressed_bg - -pushbutton_toolboxbtn_active_fg=@master_fg -pushbutton_toolboxbtn_active_bg=@master_bg -pushbutton_toolboxbtn_active_focus_bg=@master_focus_bg -pushbutton_toolboxbtn_active_hover_bg=@master_hover_bg -pushbutton_toolboxbtn_active_pressed_bg=@master_pressed_bg - -button_icon_fg=@icon_fg -button_icon_danger_fg=@danger_icon_fg - -buttonmenuitem_decoration_text_fg=@master_dark_bg - -; ComboBox. -combobox_border=@border_bg -combobox_fg=@content_fg -combobox_bg=@content_bg -combobox_disabled_fg=@disabled_fg -combobox_view_border=@border_bg -combobox_view_selected_bg=@selected_bg -combobox_view_selected_fg=@selected_fg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@edit_focus_bg -combobox_focus_border=@edit_focus_border -combobox_hover_bg=@edit_hover_bg -combobox_hover_border=@edit_hover_border -combobox_item_icon_fg=@item_icon_fg - -combobox_notebookselector_fg=@master_dark_bg -combobox_notebookselector_bg=@combobox_bg -combobox_notebookselector_border=@master_bg -combobox_notebookselector_hover_fg=@master_bg -combobox_notebookselector_hover_bg=@hover_bg -combobox_notebookselector_focus_fg=@master_bg -combobox_notebookselector_focus_bg=@focus_bg - -; Label. -label_fg=@base_fg -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@edit_fg -lineedit_bg=@edit_bg -lineedit_disabled_fg=@disabled_fg -lineedit_focus_bg=@edit_focus_bg -lineedit_focus_border=@edit_focus_border -lineedit_hover_bg=@edit_hover_bg -lineedit_hover_border=@edit_hover_border -lineedit_selection_fg=@edit_selection_fg -lineedit_selection_bg=@edit_selection_bg - -; TabWidget. -tabwidget_pane_border=@selected_bg - -; TabBar. -tabbar_fg=@base_fg -tabbar_bg=@base_bg -tabbar_border=@border_bg - -tabbar_selected_fg=@edit_fg -tabbar_selected_bg=@edit_bg -tabbar_selected_border=@border_bg - -tabbar_hover_fg=@hover_fg -tabbar_hover_bg=@hover_bg - -tabbar_icon_fg=@icon_fg -tabbar_icon_special_fg=@danger_bg - -; SelectorItem. -selectoritem_border=@master_bg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; TreeView. -treeview_fg=@content_fg -treeview_bg=@content_bg -treeview_item_border_bg=@border_bg -treeview_item_hover_fg=@hover_fg -treeview_item_hover_bg=@hover_bg -treeview_item_selected_fg=@selected_fg -treeview_item_selected_bg=@selected_bg -treeview_item_selected_avtive_fg=@active_fg -treeview_item_selected_avtive_bg=@active_bg -treeview_item_selected_inactive_fg=@inactive_fg -treeview_item_selected_inactive_bg=@inactive_bg -treeview_item_icon_fg=@item_icon_fg - -; ListView. -listview_fg=@content_fg -listview_bg=@content_bg -listview_item_hover_fg=@hover_fg -listview_item_hover_bg=@hover_bg -listview_item_selected_fg=@selected_fg -listview_item_selected_bg=@selected_bg -listview_item_selected_avtive_fg=@active_fg -listview_item_selected_avtive_bg=@active_bg -listview_item_selected_inactive_fg=@inactive_fg -listview_item_selected_inactive_bg=@inactive_bg - -; QAbstractItemView for TextEdit Completer. -abstractitemview_textedit_fg=@content_fg -abstractitemview_textedit_bg=#DADADA -abstractitemview_textedit_item_hover_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_hover_bg=@master_hover_bg -abstractitemview_textedit_item_selected_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_selected_bg=@master_light_bg -abstractitemview_textedit_item_selected_avtive_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_selected_avtive_bg=@master_focus_bg -abstractitemview_textedit_item_selected_inactive_fg=@inactive_fg -abstractitemview_textedit_item_selected_inactive_bg=@inactive_bg - -; Splitter. -splitter_handle_bg=@border_bg -splitter_handle_pressed_bg=@pressed_bg - -; StatusBar. -statusbar_fg=@main_fg -statusbar_bg=@main_bg - -; ScrollBar. -scrollbar_bg=@base_bg -scrollbar_page_bg=transparent -scrollbar_handle_bg=#DADADA -scrollbar_handle_hover_bg=@hover_bg -scrollbar_handle_pressed_bg=@pressed_bg - -; VEditWindow. -editwindow_corner_icon_fg=@master_bg -editwindow_corner_icon_inactive_fg=#D3D3D3 - -; CheckBox. -checkbox_disabled_fg=@disabled_fg -checkbox_indicator_focus_bg=@focus_bg -checkbox_indicator_hover_bg=@hover_bg -checkbox_indicator_pressed_bg=@pressed_bg - -; RadioButton. -radiobutton_disabled_fg=@disabled_fg -radiobutton_indicator_focus_bg=@focus_bg -radiobutton_indicator_hover_bg=@hover_bg -radiobutton_indicator_pressed_bg=@pressed_bg - -; SpinBox. -spinbox_fg=@edit_fg -spinbox_bg=@edit_bg -spinbox_border=@border_bg -spinbox_selection_fg=@edit_selection_fg -spinbox_selection_bg=@edit_selection_bg -spinbox_focus_border=@edit_focus_border -spinbox_focus_bg=@edit_focus_bg -spinbox_hover_border=@edit_hover_border -spinbox_hover_bg=@edit_hover_bg -spinbox_button_hover_bg=@hover_bg -spinbox_button_pressed_bg=@pressed_bg - -; HeaderView. -headerview_bg=#E0E0E0 -headerview_fg=@base_fg -headerview_border=@border_bg -headerview_checked_fg=@selected_fg -headerview_checked_bg=@selected_bg - -; ProgressBar. -progressbar_bg=@edit_bg -progressbar_border_bg=@border_bg -progressbar_chunk_bg=@master_light_bg - -universalentry_bg=@base_bg -universalentry_border_bg=@border_bg - -doublerowitem_second_row_label_fg=#6C6C6C - -; GroupBox. -groupbox_border=@border_bg -groupbox_title_fg=@base_fg - -; Slider. -slider_border_bg=@border_bg -slider_groove_bg=@edit_bg -slider_handle_bg=@master_bg -slider_subpage_bg=@master_light_bg diff --git a/src/resources/themes/v_pure/v_pure.qss b/src/resources/themes/v_pure/v_pure.qss deleted file mode 100644 index 1d678a20..00000000 --- a/src/resources/themes/v_pure/v_pure.qss +++ /dev/null @@ -1,1464 +0,0 @@ -QToolTip -{ - border: none; - background: @tooltip_bg; - color: @tooltip_fg; -} - -/* QMainWindow */ -QMainWindow { - color: @base_fg; - background: @base_bg; -} - -QMainWindow::separator { - background: @dock_separator_bg; - width: $2px; - height: $2px; -} - -QMainWindow::separator:hover { - background: @dock_separator_hover_bg; -} - -QMainWindow::separator:pressed { - background: @dock_separator_pressed_bg; -} -/* End QMainWindow */ - -QMenuBar { - border: none; - background: @menubar_bg; - color: @menubar_fg; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} - -/* QMenu */ -QMenu { - background: @menu_bg; - color: @menu_fg; - border: $2px solid @menu_border_bg; -} - -QMenu::icon { - margin: $5px; -} - -QMenu::item { - padding: $5px $30px $5px $30px; - border: $1px solid transparent; -} - -QMenu::item:selected { - color: @menu_item_selected_fg; - background: @menu_item_selected_bg; -} - -QMenu::item:disabled { - color: @menu_item_disabled_fg; -} - -QMenu::icon:checked { /* appearance of a 'checked' icon */ - border: $2px solid @menu_fg; -} - -QMenu::separator { - height: $2px; - background: @menu_separator_bg; - margin-left: $10px; - margin-right: $5px; -} - -QMenu::indicator { - width: $20px; - height: $20px; -} - -QMenu::indicator:non-exclusive:unchecked { - image: none; -} - -QMenu::indicator:non-exclusive:checked { - image: url(menu_checkbox.svg); -} - -QMenu::indicator:exclusive:unchecked { - image: none; -} - -QMenu::indicator:exclusive:checked { - image: url(menu_radiobutton.svg); -} -/* End QMenu */ - -QToolBar { - border: none; - background: @toolbar_bg; -} - -QToolBar::separator { - width: 1px; - height: 1px; - border: none; - background: @toolbar_separator_bg; -} - -/* QToolButton */ -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: $16px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: $10px; /* make way for the popup button */ -} - -QToolButton { - border: none; - background: transparent; - margin: 1px 3px 1px 3px; - padding: 0px; -} - -QToolButton:checked { - background: @toolbutton_checked_bg; -} - -QToolButton:hover { - border:none; - background: @toolbutton_hover_bg; -} - -QToolButton:pressed { - background: @toolbutton_pressed_bg; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: none; - width: $16px; -} - -QToolButton::menu-arrow { - image: url(arrow_dropdown.svg); - width: $16px; - height: $16px; -} -/* End QToolButton*/ - -/* DockWidget */ -QDockWidget { - color: @dockwidget_title_fg; - background: @dockwidget_bg; - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; - icon-size: $16px; - width: $16px; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} - -QDockWidget::close-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: 0px; bottom: 0px; -} - -QDockWidget::float-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: $18px; bottom: 0px; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton[SpecialBtn="true"] { - color: @pushbutton_specialbtn_fg; - background: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:focus { - background-color: @pushbutton_specialbtn_focus_bg; -} - -QPushButton[SpecialBtn="true"]:checked { - background-color: @pushbutton_specialbtn_checked_bg; -} - -QPushButton[SpecialBtn="true"]:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:pressed { - background-color: @pushbutton_specialbtn_pressed_bg; -} - -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; - min-width: -1; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"] { - color: @pushbutton_dangerbtn_fg; - border: none; - background-color: @pushbutton_dangerbtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_dangerbtn_bg; -} - -QPushButton[DangerBtn="true"]:focus { - background-color: @pushbutton_dangerbtn_focus_bg; -} - -QPushButton[DangerBtn="true"]:checked { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[DangerBtn="true"]:hover { - background-color: @pushbutton_dangerbtn_hover_bg; -} - -QPushButton[DangerBtn="true"]:pressed { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"] { - padding: 4px 10px 4px 4px; - margin: 0px; - border: none; - font-weight: bold; - color: @pushbutton_toolboxbtn_active_fg; - background-color: @pushbutton_toolboxbtn_active_bg; - min-width: -1; -} - -QPushButton[ToolBoxActiveBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_toolboxbtn_active_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:focus { - background-color: @pushbutton_toolboxbtn_active_focus_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:hover { - background-color: @pushbutton_toolboxbtn_active_hover_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:pressed { - background-color: @pushbutton_toolboxbtn_active_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[AvatarBtn="true"] { - padding: 2px 4px 2px 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton { - color: @pushbutton_fg; - background: @pushbutton_bg; - border: 1px solid @pushbutton_border; - padding: 3px; - min-width: 80px; -} - -QPushButton:focus { - background-color: @pushbutton_focus_bg; -} - -QPushButton:checked { - background-color: @pushbutton_checked_bg; -} - -QPushButton:flat { - border: none; -} - -QPushButton:default { - border: 1px solid @pushbutton_default_border; -} - -QPushButton:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:pressed { - background-color: @pushbutton_pressed_bg; -} - -QPushButton:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton::menu-indicator { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - min-width: -1; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox#NotebookSelector { - border: none; - font-size: 12pt; - padding-top: 5px; - padding-bottom: 5px; - icon-size: $24px; - font-weight: bold; - color: @combobox_notebookselector_fg; - background: @combobox_notebookselector_bg; -} - -QComboBox#NotebookSelector:focus, QComboBox#NotebookSelector:on { - color: @combobox_notebookselector_focus_fg; - background: @combobox_notebookselector_focus_bg; -} - -QComboBox#NotebookSelector:hover { - color: @combobox_notebookselector_hover_fg; - background: @combobox_notebookselector_hover_bg; -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 12pt; - font-weight: normal; - icon-size: $24px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: $5px; - padding-bottom: $5px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} - -QComboBox { - padding: 3px; - color: @combobox_fg; - background: @combobox_bg; - border: 1px solid @combobox_border; -} - -QComboBox:focus, QComboBox:on { - background-color: @combobox_focus_bg; - border: 2px solid @combobox_focus_border; -} - -QComboBox:hover { - background-color: @combobox_hover_bg; - border: 2px solid @combobox_hover_border; -} - -QComboBox:disabled { - color: @combobox_disabled_fg; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: $20px; - border: none; - background: transparent; -} - -QComboBox::down-arrow { - image: url(arrow_dropdown.svg); - width: $20px; - height: $20px; -} - -QComboBox::down-arrow:disabled { - image: url(arrow_dropdown_disabled.svg); - width: $20px; - height: $20px; -} - -QComboBox QAbstractItemView { - padding: 2px; - border: 1px solid @combobox_view_border; - background: @combobox_bg; - selection-color: @combobox_view_selected_fg; - selection-background-color: @combobox_view_selected_bg; -} - -QComboBox QAbstractItemView::item { - background: transparent; - padding: 3px; -} - -QComboBox QAbstractItemView::item:hover { - color: @combobox_view_item_hover_fg; - background: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #00796B; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -QLabel[TagLabel="true"] { - padding-left: $5px; - padding-right: $5px; - color: @tab_indicator_tag_label_fg; - background-color: @tab_indicator_tag_label_bg; -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: $2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VDoubleRowItemWidget QLabel[FirstRowLabel="true"] { - border: none; - font-size: 10pt; -} - -VDoubleRowItemWidget QLabel[SecondRowLabel="true"] { - border: none; - font-size: 9pt; - color: @doublerowitem_second_row_label_fg; -} - -QLabel { - border: none; - color: @label_fg; - background: transparent; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} - -QLineEdit[VimCommandLine="true"]:focus { - background: @lineedit_focus_bg; - border: none; -} - -QLineEdit[VimCommandLine="true"]:hover { - background: @lineedit_hover_bg; - border: none; -} - -QLineEdit[EmbeddedEdit="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: transparent; -} - -QLineEdit[EmbeddedEdit="true"]:focus { - background: @lineedit_focus_bg; - border: none; -} - -QLineEdit[EmbeddedEdit="true"]:hover { - background: @lineedit_hover_bg; - border: none; -} - -QLineEdit { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QLineEdit:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QLineEdit:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} - -QLineEdit:disabled { - color: @lineedit_disabled_fg; -} -/* End QLineEdit */ - -/* QPlainTextEdit QTextEdit */ -QPlainTextEdit[LineEdit="true"], QTextEdit[LineEdit="true"] { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QPlainTextEdit[LineEdit="true"]:focus, QTextEdit[LineEdit="true"]:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QPlainTextEdit[LineEdit="true"]:hover, QTextEdit[LineEdit="true"]:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} -/* End QPlainTextEdit QTextEdit */ - -/* QTabWidget */ -QTabWidget { - border: none; -} - -QTabWidget::pane { - border: none; -} - -QTabWidget::tab-bar { - alignment: left; -} -/* End QTabWidget */ - -/* QTabBar */ -QTabBar::tab { - color: @tabbar_fg; - background: @tabbar_bg; - border: none; -} - -QTabBar::tab:top, QTabBar::tab:bottom { - border-top: $2px solid transparent; - border-right: $1px solid @tabbar_border; - /* MUST leave right and left padding 0px. */ - padding: $2px 0px $2px 0px; - height: $20px; -} - -QTabBar::tab:right { - border-left: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:left { - border-right: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:hover { - color: @tabbar_hover_fg; - background: @tabbar_hover_bg; -} - -QTabBar::tab:selected { - color: @tabbar_selected_fg; - background: @tabbar_selected_bg; -} - -QTabBar::tab:top:selected, QTabBar::tab:bottom:selected { - border-top: $2px solid @master_bg; -} - -QTabBar::tab:right:selected { - border-left: $3px solid @master_bg; -} - -QTabBar::tab:left:selected { - border-right: $3px solid @master_bg; -} - -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:focus { - image: url(close.svg); -} - -QTabBar::close-button:hover { - image: url(close.svg); -} - -QTabBar::scroller { - width: $20px; -} - -QTabBar QToolButton { - border: none; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(right.svg); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(left.svg); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(right_disabled.svg); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(left_disabled.svg); -} -/* End QTabBar */ - -/* QTreeView */ -QTreeView[ItemBorder="true"]::item { - padding-top: 5px; - padding-bottom: 5px; - border-bottom: $1px solid @treeview_item_border_bg; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-children:!has-siblings:closed, -QTreeView[PlainTree="true"]::branch:closed:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView[PlainTree="true"]::branch:open:has-children:!has-siblings, -QTreeView[PlainTree="true"]::branch:open:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView { - color: @treeview_fg; - background: @treeview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QTreeView::item:hover { - color: @treeview_item_hover_fg; - background: @treeview_item_hover_bg; -} - -QTreeView::item:selected { - color: @treeview_item_selected_fg; - background: @treeview_item_selected_bg; -} - -QTreeView::item:selected:active { - color: @treeview_item_selected_active_fg; - background: @treeview_item_selected_active_bg; -} - -QTreeView::item:selected:!active { - color: @treeview_item_selected_inactive_fg; - background: @treeview_item_selected_inactive_bg; -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(line.svg) 0; -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(branch_more.svg) 0; -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(branch_end.svg) 0; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(branch_closed.svg); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(branch_open.svg); -} -/* End QTreeView */ - -/* QListView */ -QListView { - color: @listview_fg; - background: @listview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QListView::item:hover { - color: @listview_item_hover_fg; - background: @listview_item_hover_bg; -} - -QListView::item:selected { - color: @listview_item_selected_fg; - background: @listview_item_selected_bg; -} - -QListView::item:selected:active { - color: @listview_item_selected_active_fg; - background: @listview_item_selected_active_bg; -} - -QListView::item:selected:!active { - color: @listview_item_selected_inactive_fg; - background: @listview_item_selected_inactive_bg; -} - -QListView::item:disabled { - background: transparent; -} -/* End QListView */ - -/* QAbstractItemView for TextEdit Completer popup*/ -QAbstractItemView[TextEdit="true"] { - color: @abstractitemview_textedit_fg; - background: @abstractitemview_textedit_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QAbstractItemView[TextEdit="true"]::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QAbstractItemView[TextEdit="true"]::item:hover { - color: @abstractitemview_textedit_item_hover_fg; - background: @abstractitemview_textedit_item_hover_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected { - color: @abstractitemview_textedit_item_selected_fg; - background: @abstractitemview_textedit_item_selected_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:active { - color: @abstractitemview_textedit_item_selected_active_fg; - background: @abstractitemview_textedit_item_selected_active_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:!active { - color: @abstractitemview_textedit_item_selected_inactive_fg; - background: @abstractitemview_textedit_item_selected_inactive_bg; -} - -QAbstractItemView[TextEdit="true"]::item:disabled { - background: transparent; -} -/* End QAbstractItemView */ - -/* QSplitter */ -QSplitter#MainSplitter { - border: none; - margin-left: $3px; -} - -QSplitter { - border: none; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:pressed { - background-color: @splitter_handle_pressed_bg; -} - -QSplitter::handle:vertical { - height: $2px; -} - -QSplitter::handle:horizontal { - width: $2px; -} -/* End QSplitter */ - -/* QStatusBar */ -QStatusBar { - color: @statusbar_fg; - background: @statusbar_bg; -} -/* End QStatusBar */ - -QDialog { - color: @base_fg; - background: @base_bg; -} - -/* QScrollBar */ -QScrollBar::add-page, QScrollBar::sub-page { - background: @scrollbar_page_bg; -} - -QScrollBar:vertical { - background: @scrollbar_bg; - width: $16px; - margin: $16px 0px $16px 0px; - padding: 0px $2px 0px $2px; - border: none; -} - -QScrollBar::handle:vertical { - background: @scrollbar_handle_bg; - min-height: $16px; -} - -QScrollBar::handle:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::down-arrow:vertical { - image: url(down.svg); - width: $16px; - height: $16px; -} - -QScrollBar::up-arrow:vertical { - image: url(up.svg); - width: $16px; - height: $16px; -} - -QScrollBar:horizontal { - background: @scrollbar_bg; - height: $16px; - margin: 0px $16px 0px $16px; - padding: $2px 0px $2px 0px; - border: none; -} - -QScrollBar::handle:horizontal { - background: @scrollbar_handle_bg; - min-width: $16px; -} - -QScrollBar::handle:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::right-arrow:horizontal { - image: url(right.svg); - width: $16px; - height: $16px; -} - -QScrollBar::left-arrow:horizontal { - image: url(left.svg); - width: $16px; - height: $16px; -} -/* End QScrollBar */ - -/* QCheckBox */ -QCheckBox { - spacing: $5px; -} - -QCheckBox:disabled { - color: @checkbox_disabled_fg; -} - -QCheckBox::indicator:unchecked { - image: url(checkbox_unchecked.svg); -} - -QCheckBox::indicator:unchecked:disabled { - image: url(checkbox_unchecked_disabled.svg); -} - -QCheckBox::indicator:checked { - image: url(checkbox_checked.svg); -} - -QCheckBox::indicator:checked:disabled { - image: url(checkbox_checked_disabled.svg); -} - -QCheckBox::indicator { - width: $20px; - height: $20px; -} - -QCheckBox::indicator:focus { - background: @checkbox_indicator_focus_bg; -} - -QCheckBox::indicator:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:pressed { - background: @checkbox_indicator_pressed_bg; -} -/* End QCheckBox */ - -/* QRadioButton */ -QRadioButton { - spacing: $5px; -} - -QRadioButton:disabled { - color: @radiobutton_disabled_fg; -} - -QRadioButton::indicator:unchecked { - image: url(radiobutton_unchecked.svg); -} - -QRadioButton::indicator:unchecked:disabled { - image: url(radiobutton_unchecked_disabled.svg); -} - -QRadioButton::indicator:checked { - image: url(radiobutton_checked.svg); -} - -QRadioButton::indicator:checked:disabled { - image: url(radiobutton_checked_disabled.svg); -} - -QRadioButton::indicator { - width: $20px; - height: $20px; -} - -QRadioButton::indicator:focus { - background: @radiobutton_indicator_focus_bg; -} - -QRadioButton::indicator:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:pressed { - background: @radiobutton_indicator_pressed_bg; -} -/* End QRadioButton */ - -/* QSpinBox */ -QSpinBox, QDoubleSpinBox { - border: 1px solid @spinbox_border; - color: @spinbox_fg; - background: @spinbox_bg; - padding-right: $25px; - min-height: $25px; - selection-color: @spinbox_selection_fg; - selection-background-color: @spinbox_selection_bg; -} - -QSpinBox:focus, QDoubleSpinBox::focus { - border: 2px solid @spinbox_focus_border; - background: @spinbox_focus_bg; -} - -QSpinBox:hover, QDoubleSpinBox::hover { - border: 2px solid @spinbox_hover_border; - background: @spinbox_hover_bg; -} - -QSpinBox::up-button, QDoubleSpinBox::up-button { - subcontrol-origin: border; - subcontrol-position: top right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} - -QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off, QDoubleSpinBox::up-arrow:disabled, QDoubleSpinBox::up-arrow:off { - image: url(up_disabled.svg); -} - -QSpinBox::down-button, QDoubleSpinBox::down-button { - subcontrol-origin: border; - subcontrol-position: bottom right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off, QDoubleSpinBox::down-arrow:disabled, QDoubleSpinBox::down-arrow:off { - image: url(down_disabled.svg); -} -/* End QSpinBox */ - -/* QHeaderView */ -QHeaderView::section { - background: @headerview_bg; - color: @headerview_fg; - padding-left: 4px; - border: none; - border-left: 1px solid @headerview_border; - border-bottom: 1px solid @headerview_border; -} - -QHeaderView::section:checked -{ - color: @headerview_checked_fg; - background: @headerview_checked_bg; -} - -/* style the sort indicator */ -QHeaderView::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QHeaderView::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} -/* End QHeaderView */ - -QAbstractScrollArea::corner { - background: @scrollbar_bg; - border: none; -} - -/* QProgressBar */ -QProgressBar { - background: @progressbar_bg; - border: $1px solid @progressbar_border_bg; - text-align: center; -} - -QProgressBar::chunk { - background-color: @progressbar_chunk_bg; - width: $20px; -} -/* End QProgressBar */ - -/* QGroupBox */ -QGroupBox { - border: 2px solid @groupbox_border; - border-radius: 5px; - margin-top: 2ex; -} - -QGroupBox::title { - color: @groupbox_title_fg; - subcontrol-origin: margin; - subcontrol-position: top left; - position: absolute; - padding: 0 $3px; - top: 0px; left: $10px; bottom: 0px; -} -/* End QGroupBox */ - -/* QSlider */ -QSlider::groove:horizontal { - border: $1px solid @slider_border_bg; - height: $8px; - background: @slider_groove_bg; - margin: $2px 0; -} - -QSlider::handle:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - width: $18px; - margin: $-2px 0; -} - -QSlider::add-page:horizontal { - background: transparent; -} - -QSlider::sub-page:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: $2px 0; -} - -QSlider::groove:vertical { - border: $1px solid @slider_border_bg; - width: $8px; - background: @slider_groove_bg; - margin: 0 $2px; -} - -QSlider::handle:vertical { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - height: $18px; - margin: 0 $-2px; -} - -QSlider::add-page:vertical { - background: transparent; -} - -QSlider::sub-page:vertical { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: 0 $2px; -} -/* End QSlider */ - -/* QWidget */ -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} - -QWidget[ToolBoxTitle="true"] { - border-bottom: $2px solid @toolbox_title_border; -} - -QWidget[ToolBoxTitle="true"] QPushButton[ToolBoxTitleBtn="true"] { - height: $20px; -} - -QWidget[MainEditor="true"] { - border: none; -} - -QWidget -{ - color: @widget_fg; - font-family: "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", "Dengxian", "等线体", "STXihei", "华文细黑", "Liberation Sans", "Droid Sans", "NSimSun", "新宋体", "SimSun", "宋体", "Helvetica", "sans-serif", "Tahoma", "Arial", "Verdana", "Geneva", "Georgia", "Times New Roman"; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} - -VUniversalEntry { - background: @universalentry_bg; - border: 1px solid @universalentry_border_bg; -} -/* End QWidget */ diff --git a/src/resources/themes/v_pure/v_pure_codeblock.css b/src/resources/themes/v_pure/v_pure_codeblock.css deleted file mode 100644 index fdf954d5..00000000 --- a/src/resources/themes/v_pure/v_pure_codeblock.css +++ /dev/null @@ -1,99 +0,0 @@ -/* - -Original highlight.js style (c) Ivan Sagalaev - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #E0E0E0; -} - - -/* Base color: saturation 0; */ - -.hljs, -.hljs-subst { - color: #363636; -} - -.hljs-comment { - color: #767676; -} - -.hljs-keyword, -.hljs-attribute, -.hljs-selector-tag, -.hljs-meta-keyword, -.hljs-doctag, -.hljs-name { - color: #0000ee; -} - - -/* User color: hue: 0 */ - -.hljs-type, -.hljs-string, -.hljs-number, -.hljs-selector-id, -.hljs-selector-class, -.hljs-quote, -.hljs-template-tag, -.hljs-deletion { - color: #880000; -} - -.hljs-title, -.hljs-section { - color: #880000; - font-weight: bold; -} - -.hljs-regexp, -.hljs-symbol, -.hljs-variable, -.hljs-template-variable, -.hljs-link, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #BC6060; -} - - -/* Language color: hue: 90; */ - -.hljs-literal { - color: #af00d7; -} - -.hljs-built_in, -.hljs-bullet, -.hljs-code, -.hljs-addition { - color: #008700; -} - - -/* Meta color: hue: 200 */ - -.hljs-meta { - color: #1f7199; -} - -.hljs-meta-string { - color: #4d99bf; -} - - -/* Misc effects */ - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/src/resources/themes/v_pure/v_pure_mermaid.css b/src/resources/themes/v_pure/v_pure_mermaid.css deleted file mode 100644 index 3d808780..00000000 --- a/src/resources/themes/v_pure/v_pure_mermaid.css +++ /dev/null @@ -1,320 +0,0 @@ -/* Flowchart variables */ -/* Sequence Diagram variables */ -/* Gantt chart variables */ -.mermaid-diagram .mermaid .label { - color: #333; -} - -.mermaid-diagram .node rect, -.mermaid-diagram .node circle, -.mermaid-diagram .node ellipse, -.mermaid-diagram .node polygon { - fill: #ECECFF; - stroke: #CCCCFF; - stroke-width: 1px; -} - -.mermaid-diagram .edgePath .path { - stroke: #333333; -} - -.mermaid-diagram .edgeLabel { - background-color: #e8e8e8; -} - -.mermaid-diagram .cluster rect { - fill: #ffffde !important; - rx: 4 !important; - stroke: #aaaa33 !important; - stroke-width: 1px !important; -} - -.mermaid-diagram .cluster text { - fill: #333; -} - -.mermaid-diagram .actor { - stroke: #CCCCFF; - fill: #ECECFF; -} - -.mermaid-diagram text.actor { - fill: black; - stroke: none; -} - -.mermaid-diagram .actor-line { - stroke: grey; -} - -.mermaid-diagram .messageLine0 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #333; -} - -.mermaid-diagram .messageLine1 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - stroke: #333; -} - -.mermaid-diagram #arrowhead { - fill: #333; -} - -.mermaid-diagram #crosshead path { - fill: #333 !important; - stroke: #333 !important; -} - -.mermaid-diagram .messageText { - fill: #333; - stroke: none; -} - -.mermaid-diagram .labelBox { - stroke: #CCCCFF; - fill: #ECECFF; -} - -.mermaid-diagram .labelText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopLine { - stroke-width: 2; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #CCCCFF; -} - -.mermaid-diagram .note { - stroke: #aaaa33; - fill: #fff5ad; -} - -.mermaid-diagram .noteText { - fill: black; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -/** Section styling */ -.mermaid-diagram .section { - stroke: none; - opacity: 0.2; -} - -.mermaid-diagram .section0 { - fill: rgba(102, 102, 255, 0.49); -} - -.mermaid-diagram .section2 { - fill: #fff400; -} - -.mermaid-diagram .section1, -.mermaid-diagram .section3 { - fill: white; - opacity: 0.2; -} - -.mermaid-diagram .sectionTitle0 { - fill: #333; -} - -.mermaid-diagram .sectionTitle1 { - fill: #333; -} - -.mermaid-diagram .sectionTitle2 { - fill: #333; -} - -.mermaid-diagram .sectionTitle3 { - fill: #333; -} - -.mermaid-diagram .sectionTitle { - text-anchor: start; - font-size: 11px; - text-height: 14px; -} - -/* Grid and axis */ -.mermaid-diagram .grid .tick { - stroke: lightgrey; - opacity: 0.3; - shape-rendering: crispEdges; -} - -.mermaid-diagram .grid path { - stroke-width: 0; -} - -/* Today line */ -.mermaid-diagram .today { - fill: none; - stroke: red; - stroke-width: 2px; -} - -/* Task styling */ -/* Default task */ -.mermaid-diagram .task { - stroke-width: 2; -} - -.mermaid-diagram .taskText { - text-anchor: middle; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideRight { - fill: black; - text-anchor: start; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideLeft { - fill: black; - text-anchor: end; - font-size: 11px; -} - -/* Specific task settings for the sections*/ -.mermaid-diagram .taskText0, -.mermaid-diagram .taskText1, -.mermaid-diagram .taskText2, -.mermaid-diagram .taskText3 { - fill: white; -} - -.mermaid-diagram .task0, -.mermaid-diagram .task1, -.mermaid-diagram .task2, -.mermaid-diagram .task3 { - fill: #8a90dd; - stroke: #534fbc; -} - -.mermaid-diagram .taskTextOutside0, -.mermaid-diagram .taskTextOutside2 { - fill: black; -} - -.mermaid-diagram .taskTextOutside1, -.mermaid-diagram .taskTextOutside3 { - fill: black; -} - -/* Active task */ -.mermaid-diagram .active0, -.mermaid-diagram .active1, -.mermaid-diagram .active2, -.mermaid-diagram .active3 { - fill: #bfc7ff; - stroke: #534fbc; -} - -.mermaid-diagram .activeText0, -.mermaid-diagram .activeText1, -.mermaid-diagram .activeText2, -.mermaid-diagram .activeText3 { - fill: black !important; -} - -/* Completed task */ -.mermaid-diagram .done0, -.mermaid-diagram .done1, -.mermaid-diagram .done2, -.mermaid-diagram .done3 { - stroke: grey; - fill: lightgrey; - stroke-width: 2; -} - -.mermaid-diagram .doneText0, -.mermaid-diagram .doneText1, -.mermaid-diagram .doneText2, -.mermaid-diagram .doneText3 { - fill: black !important; -} - -/* Tasks on the critical line */ -.mermaid-diagram .crit0, -.mermaid-diagram .crit1, -.mermaid-diagram .crit2, -.mermaid-diagram .crit3 { - stroke: #ff8888; - fill: red; - stroke-width: 2; -} - -.mermaid-diagram .activeCrit0, -.mermaid-diagram .activeCrit1, -.mermaid-diagram .activeCrit2, -.mermaid-diagram .activeCrit3 { - stroke: #ff8888; - fill: #bfc7ff; - stroke-width: 2; -} - -.mermaid-diagram .doneCrit0, -.mermaid-diagram .doneCrit1, -.mermaid-diagram .doneCrit2, -.mermaid-diagram .doneCrit3 { - stroke: #ff8888; - fill: lightgrey; - stroke-width: 2; - cursor: pointer; - shape-rendering: crispEdges; -} - -.mermaid-diagram .doneCritText0, -.mermaid-diagram .doneCritText1, -.mermaid-diagram .doneCritText2, -.mermaid-diagram .doneCritText3 { - fill: black !important; -} - -.mermaid-diagram .activeCritText0, -.mermaid-diagram .activeCritText1, -.mermaid-diagram .activeCritText2, -.mermaid-diagram .activeCritText3 { - fill: black !important; -} - -.mermaid-diagram .titleText { - text-anchor: middle; - font-size: 18px; - fill: black; -} - -.mermaid-diagram .node text { - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -.mermaid-diagram div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: 'trebuchet ms', verdana, arial; - font-size: 12px; - background: #ffffde; - border: 1px solid #aaaa33; - border-radius: 2px; - pointer-events: none; - z-index: 100; -} diff --git a/src/resources/themes/v_simple/arrow_dropdown.svg b/src/resources/themes/v_simple/arrow_dropdown.svg deleted file mode 100644 index 8b465de9..00000000 --- a/src/resources/themes/v_simple/arrow_dropdown.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_simple/arrow_dropdown_disabled.svg b/src/resources/themes/v_simple/arrow_dropdown_disabled.svg deleted file mode 100644 index 7add5e54..00000000 --- a/src/resources/themes/v_simple/arrow_dropdown_disabled.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/src/resources/themes/v_simple/branch_closed.svg b/src/resources/themes/v_simple/branch_closed.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_simple/branch_closed.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/branch_end.svg b/src/resources/themes/v_simple/branch_end.svg deleted file mode 100644 index baa0c23f..00000000 --- a/src/resources/themes/v_simple/branch_end.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_simple/branch_more.svg b/src/resources/themes/v_simple/branch_more.svg deleted file mode 100644 index cb0fecad..00000000 --- a/src/resources/themes/v_simple/branch_more.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 2 - - - - diff --git a/src/resources/themes/v_simple/branch_open.svg b/src/resources/themes/v_simple/branch_open.svg deleted file mode 100644 index c1e8e141..00000000 --- a/src/resources/themes/v_simple/branch_open.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/checkbox_checked.svg b/src/resources/themes/v_simple/checkbox_checked.svg deleted file mode 100644 index f017b5b4..00000000 --- a/src/resources/themes/v_simple/checkbox_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_simple/checkbox_checked_disabled.svg b/src/resources/themes/v_simple/checkbox_checked_disabled.svg deleted file mode 100644 index 39c47873..00000000 --- a/src/resources/themes/v_simple/checkbox_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_simple/checkbox_unchecked.svg b/src/resources/themes/v_simple/checkbox_unchecked.svg deleted file mode 100644 index 5167523e..00000000 --- a/src/resources/themes/v_simple/checkbox_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_simple/checkbox_unchecked_disabled.svg b/src/resources/themes/v_simple/checkbox_unchecked_disabled.svg deleted file mode 100644 index 35788230..00000000 --- a/src/resources/themes/v_simple/checkbox_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_simple/close.svg b/src/resources/themes/v_simple/close.svg deleted file mode 100644 index 26cbf713..00000000 --- a/src/resources/themes/v_simple/close.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_simple/close_grey.svg b/src/resources/themes/v_simple/close_grey.svg deleted file mode 100644 index 24bddd4e..00000000 --- a/src/resources/themes/v_simple/close_grey.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/resources/themes/v_simple/down.svg b/src/resources/themes/v_simple/down.svg deleted file mode 100644 index 386ac7f8..00000000 --- a/src/resources/themes/v_simple/down.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/down_disabled.svg b/src/resources/themes/v_simple/down_disabled.svg deleted file mode 100644 index 2a53e0f0..00000000 --- a/src/resources/themes/v_simple/down_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/float.svg b/src/resources/themes/v_simple/float.svg deleted file mode 100644 index e4a198f3..00000000 --- a/src/resources/themes/v_simple/float.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - diff --git a/src/resources/themes/v_simple/left.svg b/src/resources/themes/v_simple/left.svg deleted file mode 100644 index aee69f4a..00000000 --- a/src/resources/themes/v_simple/left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/left_disabled.svg b/src/resources/themes/v_simple/left_disabled.svg deleted file mode 100644 index 3cabd4b5..00000000 --- a/src/resources/themes/v_simple/left_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/line.svg b/src/resources/themes/v_simple/line.svg deleted file mode 100644 index 8c981419..00000000 --- a/src/resources/themes/v_simple/line.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 2 - - - diff --git a/src/resources/themes/v_simple/menu_checkbox.svg b/src/resources/themes/v_simple/menu_checkbox.svg deleted file mode 100644 index 0aeb35a1..00000000 --- a/src/resources/themes/v_simple/menu_checkbox.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_simple/menu_radiobutton.svg b/src/resources/themes/v_simple/menu_radiobutton.svg deleted file mode 100644 index aafaa309..00000000 --- a/src/resources/themes/v_simple/menu_radiobutton.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_simple/radiobutton_checked.svg b/src/resources/themes/v_simple/radiobutton_checked.svg deleted file mode 100644 index c9834cc5..00000000 --- a/src/resources/themes/v_simple/radiobutton_checked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_simple/radiobutton_checked_disabled.svg b/src/resources/themes/v_simple/radiobutton_checked_disabled.svg deleted file mode 100644 index b67faef0..00000000 --- a/src/resources/themes/v_simple/radiobutton_checked_disabled.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - Layer 1 - - - - diff --git a/src/resources/themes/v_simple/radiobutton_unchecked.svg b/src/resources/themes/v_simple/radiobutton_unchecked.svg deleted file mode 100644 index 7cd0863a..00000000 --- a/src/resources/themes/v_simple/radiobutton_unchecked.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_simple/radiobutton_unchecked_disabled.svg b/src/resources/themes/v_simple/radiobutton_unchecked_disabled.svg deleted file mode 100644 index 8308f78b..00000000 --- a/src/resources/themes/v_simple/radiobutton_unchecked_disabled.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - Layer 1 - - - diff --git a/src/resources/themes/v_simple/right.svg b/src/resources/themes/v_simple/right.svg deleted file mode 100644 index c524ab79..00000000 --- a/src/resources/themes/v_simple/right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/right_disabled.svg b/src/resources/themes/v_simple/right_disabled.svg deleted file mode 100644 index c0c83ba8..00000000 --- a/src/resources/themes/v_simple/right_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/up.svg b/src/resources/themes/v_simple/up.svg deleted file mode 100644 index 52be26da..00000000 --- a/src/resources/themes/v_simple/up.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/up_disabled.svg b/src/resources/themes/v_simple/up_disabled.svg deleted file mode 100644 index 36e54158..00000000 --- a/src/resources/themes/v_simple/up_disabled.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - Layer 1 - - - - - diff --git a/src/resources/themes/v_simple/v_simple.css b/src/resources/themes/v_simple/v_simple.css deleted file mode 100644 index bfd336d0..00000000 --- a/src/resources/themes/v_simple/v_simple.css +++ /dev/null @@ -1,430 +0,0 @@ -body { - margin: 0 auto; - font-family: ".萍方-简", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans; - color: #222222; - line-height: 1.5; - padding: 15px; - background: #FFF; - font-size: 16px; - width: 80%; -} - -kbd { - padding: 0 .29412em; - border-radius: .3rem; - border: .1rem solid #c9c9c9; - border-bottom-color: #bcbcbc; - background-color: #fcfcfc; - color: #555; - font-size: 85%; - box-shadow: 0 0.1rem 0 #b0b0b0; - word-break: break-word; -} - -.MathJax span { - display: inline; - position: static; - border: 0; - padding: 0; - margin: 0; - vertical-align: 0; - line-height: normal; - text-decoration: none; - font-size: 18px; -} - -h1, h2, h3, h4, h5, h6 { - font-family: ".萍方-简", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans; - -webkit-font-smoothing: initial; - font-weight: 100; - color: var(--text-color); - line-height: 1.35; - font-variant-numeric: lining-nums; - font-weight: bold; - padding: 0; - margin-top: 1.2em; - margin-bottom: 0.6em; - line-height: 1.35; - color: #000; -} - -p { - font-family: ".萍方-简", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans; - padding: 0; - margin-top: 16px; - margin-bottom: 16px; -} - -h1 { - text-align: center; - font-size: 2.4em; - padding-bottom: 1em; - border-bottom: 3px double #eee; -} -h1::after { - border-bottom: 2px solid #232323; - content: ""; - width: 100px; - display: block; - margin: 0px auto; - height: 1px; - position: relative; - right: 16px; -} - -h2 { - text-align: center; - font-size: 1.8em; -} - -h2::after { - border-bottom: 1px solid #232323; - content: ""; - width: 80px; - display: block; - margin: 0px auto; - height: 1px; - position: relative; - right: 10px; -} - -h3 { - font-size: 1.6em; -} - -h4 { - font-size: 1.4em; -} - -h5 { - font-size: 1.2em; -} - -h6 { - font-size: 1.2em; -} - -a { - color: #40ccab; - margin: 0; - padding: 0; - vertical-align: baseline; - text-decoration: none; - word-break: break-word; -} - -a:hover { - color: #66ccff; -} - -a:visited { - color: purple; -} - -ul, ol { - padding: 0; - padding-left: 24px; -} - -li { - font-family: ".萍方-简", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans; - line-height: 24px; -} - -li ul, li ol { - margin-left: 16px; -} - -p, ul, ol { - font-family: ".萍方-简", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans; - font-size: 16px; - line-height: 30px; -} - -pre { - display: block; - overflow-y: hidden; - overflow-x: auto; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -code { - font-family: Courier, 'Courier New', monospace; - word-break: break-word; - color: #314659; - line-height: 1; - vertical-align: middle; - margin: 0 3px; - background: #f2f4f5; - font-size: 14px!important; - padding: .2em .3em!important; - border-radius: 3px!important; - border: 1px solid #eee!important; -} - -pre code { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #222222; - background-color: #FFFFFF; - line-height: 1.5; - font-family: Monaco, Monospace; - white-space: pre; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; -} - -pre code.markdown-metadata { - border-left: .5em solid #80CBC4; -} - -aside { - display: block; - float: right; - width: 390px; -} - -blockquote { - color: #666; - border-left: .5em solid #7a7a7a; - padding: 0 1em; - margin-left: 0; -} - -blockquote p { - color: #666; -} - -hr { - display: block; - text-align: left; - margin: 1em 0; - border: none; - height: 1px; - background: #999; -} - -table { - padding: 0; - margin: 1rem 0.5rem; - border-collapse: collapse; -} - -table tr { - border-top: 1px solid #ddd; - background-color: white; - margin: 0; - padding: 0; -} - -table tr:nth-child(2n) { - background-color: #FFF; -} - -table tr th { - font-weight: 100!important; - background-color: #F1F1F1; - border: 1px solid #ddd; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 1px solid #ddd; - margin: 0; - padding: 6px 13px; -} - -table tr th :first-child, table tr td :first-child { - margin-top: 0; -} - -table tr th :last-child, table tr td :last-child { - margin-bottom: 0; -} - -div.mermaid-diagram { - margin: 16px 0px 16px 0px; - overflow-y: hidden; -} - -div.flowchart-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -div.wavedrom-diagram { - padding: 0px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -div.plantuml-diagram { - padding: 5px 5px 0px 5px; - margin: 16px 0px 16px 0px; - width: fit-content; - overflow: hidden; -} - -.img-package { - text-align: center; -} - -img.img-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -span.img-caption { - min-width: 20%; - max-width: 80%; - display: inline-block; - padding: 10px; - margin: 0 auto; - border-bottom: 1px solid #c0c0c0; - color: #6c6c6c; - text-align: center; - line-height: 1.5; -} - -.emoji_zero,.emoji_one,.emoji_two,.emoji_three,.emoji_four,.emoji_five,.emoji_six,.emoji_seven,.emoji_eight,.emoji_nine { - margin-left: 5px; - margin-right: 8px; -} - -div.preview-hint { - opacity: 0.5; - margin-top: 30%; - margin-bottom: 30%; - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; -} - -/* For Highlight.js Line Number */ -table.hljs-ln tr { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td { - border: none; - background-color: transparent; -} - -table.hljs-ln tr td.hljs-ln-numbers { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - - text-align: center; - color: #AAA; - border-right: 1px solid #DDD; - vertical-align: top; - padding-right: 5px; - white-space: nowrap; -} - -table.hljs-ln tr td.hljs-ln-code { - padding-left: 10px; -} - -::-webkit-scrollbar { - background-color: #EAEAEA; - width: 14px; - height: 14px; - border: none; -} - -::-webkit-scrollbar-corner { - background-color: #EAEAEA; -} - -::-webkit-scrollbar-button { - /* This selector affects the styling of both the up & down and left & right buttons of a scrollbar */ - height: 14px; - width: 14px; - background-color: #EAEAEA; -} - -::-webkit-scrollbar-button:hover { - background-color: #D0D0D0; -} - -::-webkit-scrollbar-button:active { - background-color: #B2B2B2; -} - -::-webkit-scrollbar-track { - /* This selector affects the styling of the area in the scrollbar between the two buttons */ - background-color: #EAEAEA; -} - -::-webkit-scrollbar-thumb { - /* This selector affects the styling of draggable element of the scollbar */ - border: none; - background-color: #DADADA; -} - -::-webkit-scrollbar-thumb:hover { - background-color: #D0D0D0; -} - -::-webkit-scrollbar-thumb:active { - background-color: #B2B2B2; -} - -::-webkit-scrollbar-button:horizontal:increment { - background-image: url(right.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:horizontal:decrement { - background-image: url(left.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:increment { - background-image: url(down.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::-webkit-scrollbar-button:vertical:decrement { - background-image: url(up.svg); - background-repeat: no-repeat; - background-size: contain; -} - -::selection { - background: #1976D2; - color: #EEEEEE; -} - -.modal-box { - background-color: rgb(234, 234, 234); - background-color: rgba(234, 234, 234, 0.95); -} - -span.modal-close { - color: #666666; -} - -span.modal-close:hover, -span.modal-close:focus { - color: #222222; -} diff --git a/src/resources/themes/v_simple/v_simple.mdhl b/src/resources/themes/v_simple/v_simple.mdhl deleted file mode 100644 index 04b4b7a2..00000000 --- a/src/resources/themes/v_simple/v_simple.mdhl +++ /dev/null @@ -1,202 +0,0 @@ -# This is the default markdown styles used for Peg-Markdown-Highlight -# created by Le Tan(tamlokveer@gmail.com). -# For a complete description of the syntax, please refer to the original -# documentation of the style parser -# [The Syntax of PEG Markdown Highlight Stylesheets](http://hasseg.org/peg-markdown-highlight/docs/stylesheet_syntax.html). -# VNote adds some styles in the syntax which will be marked [VNote] in the comment. -# -# Note: Empty lines within a section is NOT allowed. -# Note: Do NOT modify this file directly. Copy it and tune your own style! - -editor -# QTextEdit just choose the first available font, so specify the Chinese fonts first -# Do not use "" to quote the name -font-family: .萍方-简, Hiragino Sans GB, 冬青黑体, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, WenQuanYi Micro Hei, 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, Liberation Sans, Droid Sans, NSimSun, 新宋体, SimSun, 宋体, Verdana, Helvetica, sans-serif, Tahoma, Arial, Geneva, Georgia, Times New Roman -font-size: 12 -foreground: 222222 -background: ffffff -# [VNote] Style for trailing space -trailing-space: a8a8a8 -# [VNote] Style for line number -line-number-background: ffffff -line-number-foreground: 666666 -# [VNote] Style for selected word highlight -selected-word-foreground: 222222 -selected-word-background: b4addf -# [VNote] Style for searched word highlight -searched-word-foreground: 222222 -searched-word-background: 4db6ac -# [VNote] Style for searched word under cursor highlight -searched-word-cursor-foreground: 222222 -searched-word-cursor-background: abecae -# [VNote] Style for incremental searched word highlight -incremental-searched-word-foreground: 222222 -incremental-searched-word-background: ce93d8 -# [VNote] Style for color column in fenced code block -color-column-background: dd0000 -color-column-foreground: ffff00 -# [VNote] Style for preview image line -preview-image-line-foreground: 9575cd - -editor-selection -foreground: eeeeee -background: 6d6d6d - -editor-current-line -background: c5cae9 -# [VNote] Vim insert mode cursor line background -vim-insert-background: c5cae9 -# [VNote] Vim normal mode cursor line background -vim-normal-background: e0e0e0 -# [VNote] Vim visual mode cursor line background -vim-visual-background: ffffff -# [VNote] Vim replace mode cursor line background -vim-replace-background: f8bbd0 - -H1 -foreground: 222222 -font-size: +5 - -H2 -foreground: 222222 -font-size: +4 - -H3 -foreground: 222222 -font-size: +3 - -H4 -foreground: 222222 -font-size: +2 - -H5 -foreground: 222222 -font-size: +1 - -H6 -foreground: 222222 - -HRULE -foreground: 222222 -background: dac7c9 - -LIST_BULLET -foreground: d33682 -font-style: bold -font-size: +2 - -LIST_ENUMERATOR -foreground: 0000ff - -LINK -foreground: 40ccab - -AUTO_LINK_URL -foreground: 40ccab - -AUTO_LINK_EMAIL -foreground: 40ccab - -IMAGE -foreground: 40ccab - -REFERENCE -foreground: 826200 - -CODE -foreground: 8e24aa -font-family: Monaco, Monospace, Courier New - -EMPH -font-style: italic - -STRONG -font-style: bold - -HTML_ENTITY -foreground: 8900b5 - -HTML -foreground: 8900b5 - -HTMLBLOCK -foreground: 8900b5 - -COMMENT -foreground: 93a1a1 - -VERBATIM -foreground: 673ab7 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -FENCEDCODEBLOCK -foreground: 673ab7 -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New -# [VNote] Codeblock sylte from HighlightJS (bold, italic, underlined, strikeout, color) -# The last occurence of the same attribute takes effect -# Could specify multiple attribute in one line -hljs-comment: 6c6c6c -hljs-keyword: 0000ee -hljs-attribute: 0000ee -hljs-selector-tag: 0000ee -hljs-meta-keyword: 0000ee -hljs-doctag: 0000ee -hljs-name: 0000ee -hljs-type: 880000 -hljs-string: 880000 -hljs-number: 880000 -hljs-selector-id: 880000 -hljs-selector-class: 880000 -hljs-quote: 880000 -hljs-template-tag: 880000 -hljs-deletion: 880000 -hljs-title: bold, 880000 -hljs-section: bold, 880000 -hljs-regexp: bc6060 -hljs-symbol: bc6060 -hljs-variable: bc6060 -hljs-template-variable: bc6060 -hljs-link: bc6060 -hljs-selector-attr: bc6060 -hljs-selector-pseudo: bc6060 -hljs-literal: af00d7 -hljs-built_in: 008700 -hljs-bullet: 008700 -hljs-code: 008700 -hljs-addition: 008700 -hljs-meta: 1f7199 -hljs-meta-string: 4d99bf -hljs-emphasis: italic -hljs-strong: bold - -BLOCKQUOTE -foreground: 00af00 - -NOTE -foreground: black - -STRIKE -foreground: b71c1c -font-style: strikeout - -FRONTMATTER -foreground: 6c6c6c - -INLINEEQUATION -foreground: 00897b -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -DISPLAYFORMULA -foreground: 00897b -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -MARK -foreground: 222222 -background: ffff76 - -TABLE -font-family: YaHei Consolas Hybrid, Consolas, Monaco, Andale Mono, Monospace, Courier New - -TABLEBORDER -foreground: d33682 -background: e0e0e0 diff --git a/src/resources/themes/v_simple/v_simple.palette b/src/resources/themes/v_simple/v_simple.palette deleted file mode 100644 index c8466150..00000000 --- a/src/resources/themes/v_simple/v_simple.palette +++ /dev/null @@ -1,385 +0,0 @@ -; File path could be absolute path or relative path (related to this file). -; Use @color_tag to reference a style. - -[metadata] -qss_file=v_simple.qss -mdhl_file=v_simple.mdhl -css_file=v_simple.css -codeblock_css_file=v_simple_codeblock.css -mermaid_css_file=v_simple_mermaid.css -version=27 - -[phony] -; Abstract color attributes. -master_fg=#000 -master_bg=#D0D0D0 -master_light_bg=#FFFFFF -master_dark_bg=#000 -master_focus_bg=#FFFFFF -master_hover_bg=#D0D0D0 -master_pressed_bg=#FFFFFF - -base_fg=#000 -base_bg=#FFF - -main_fg=@base_fg -main_bg=@base_bg - -title_fg=@base_fg -title_bg=@base_bg - -disabled_fg=#9E9E9E - -content_fg=@base_fg -content_bg=@base_bg - -border_bg=#D3D3D3 - -separator_bg=#D3D3D3 - -hover_fg=@base_fg -hover_bg=#EEE - -selected_fg=@base_fg -selected_bg=#D0D0D0 - -active_fg=@selected_fg -active_bg=@selected_bg - -inactive_fg=@selected_fg -inactive_bg=#EEE - -focus_fg=@base_fg -focus_bg=#BDBDBD - -pressed_fg=@base_fg -pressed_bg=#B2B2B2 - -edit_fg=#222222 -edit_bg=#FFFFFF -edit_focus_bg=#FFFFFF -edit_focus_border=@master_bg -edit_hover_bg=#FFF -edit_hover_border=@master_bg -edit_selection_fg=@edit_fg -edit_selection_bg=@master_light_bg - -icon_fg=#000 -icon_disabled_fg=@disabled_fg - -danger_fg=#000 -danger_bg=#C9302C -danger_focus_bg=#D9534F -danger_hover_bg=#DE6764 -danger_pressed_bg=#AC2925 - -[soft_defined] -; VAvatar. -; The foreground color of the avatar when Captain mode is triggered. -avatar_captain_mode_fg=@master_fg -; The background color of the avatar when Captain mode is triggered. -avatar_captain_mode_bg=@master_bg - -; Style of the label in Navigation mode. -navigation_label_fg=@master_fg -navigation_label_bg=@master_bg - -; Style of the bubble of VButtonWithWidget. -bubble_fg=@master_fg -bubble_bg=@master_bg - -; Icons' foreground. -danger_icon_fg=@danger_bg -item_icon_fg=@icon_fg -title_icon_fg=@icon_fg - -; VVimIndicator. -vim_indicator_key_label_fg=@base_fg -vim_indicator_mode_label_fg=@base_fg -vim_indicator_cmd_edit_pending_bg=@selected_bg - -; VTabIndicator. -tab_indicator_label_fg=@base_fg -tab_indicator_tag_label_fg=#222222 -tab_indicator_tag_label_bg=#ce93db - -; Html template. -template_title_flash_light_fg=@master_light_bg -template_title_flash_dark_fg=@master_bg - -; Search hit items in list or tree view. -search_hit_item_fg=@selected_fg -search_hit_item_bg=#D0D0D0 - -; Universal Entry CMD Edit border color -ue_cmd_busy_border=#3F51B5 -ue_cmd_fail_border=@danger_bg - -; VListWidget/VTreeWidget separator. -item_separator_fg=@master_dark_bg -item_separator_bg=@separator_bg - -[widgets] -; Widget color attributes. - -; QWidget. -widget_fg=@base_fg - -; Separator of dock widgets. -dock_separator_bg=@separator_bg -dock_separator_hover_bg=@hover_bg -dock_separator_pressed_bg=@pressed_bg - -; Menubar. -menubar_bg=@main_bg -menubar_fg=@main_fg -menubar_item_selected_bg=@selected_bg - -; Menu. -menu_bg=@base_bg -menu_fg=@base_fg -menu_border_bg=@border_bg -menu_item_disabled_fg=@disabled_fg -menu_item_selected_fg=@selected_fg -menu_item_selected_bg=@selected_bg -menu_separator_bg=@separator_bg -menu_icon_fg=@icon_fg -menu_icon_danger_fg=@danger_icon_fg - -; Tooltip. -tooltip_bg=@master_bg -tooltip_fg=@master_fg - -; Toolbar. -toolbar_bg=@main_bg -toolbar_separator_bg=@separator_bg -toolbutton_hover_bg=@hover_bg -toolbutton_pressed_bg=@pressed_bg -toolbutton_checked_bg=@selected_bg -toolbutton_icon_fg=@icon_fg -toolbutton_icon_danger_fg=@danger_icon_fg - -; Toolbox. -toolbox_icon_fg=@master_bg -toolbox_icon_active_fg=@master_fg -toolbox_title_border=@master_bg - -; Dockwidget. -dockwidget_bg=@base_bg -dockwidget_title_fg=@title_fg -dockwidget_title_bg=@title_bg -dockwidget_button_hover_bg=@hover_bg - -; PushButton. -pushbutton_fg=@base_fg -pushbutton_bg=transparent -pushbutton_border=@border_bg -pushbutton_pressed_bg=@pressed_bg -pushbutton_focus_bg=@focus_bg -pushbutton_checked_bg=@selected_bg -pushbutton_hover_bg=@hover_bg -pushbutton_default_border=@master_bg -pushbutton_disabled_fg=@disabled_fg -pushbutton_disabled_bg=@pushbutton_bg - -pushbutton_specialbtn_fg=@master_fg -pushbutton_specialbtn_bg=@master_bg -pushbutton_specialbtn_focus_bg=@master_focus_bg -pushbutton_specialbtn_hover_bg=@master_hover_bg -pushbutton_specialbtn_checked_bg=#3F51B5 -pushbutton_specialbtn_pressed_bg=@master_pressed_bg - -pushbutton_titlebtn_bg=@title_bg - -pushbutton_dangerbtn_fg=@danger_fg -pushbutton_dangerbtn_bg=@danger_bg -pushbutton_dangerbtn_hover_bg=@danger_hover_bg -pushbutton_dangerbtn_focus_bg=@danger_focus_bg -pushbutton_dangerbtn_pressed_bg=@danger_pressed_bg - -pushbutton_toolboxbtn_active_fg=@master_fg -pushbutton_toolboxbtn_active_bg=@master_bg -pushbutton_toolboxbtn_active_focus_bg=@master_focus_bg -pushbutton_toolboxbtn_active_hover_bg=@master_hover_bg -pushbutton_toolboxbtn_active_pressed_bg=@master_pressed_bg - -button_icon_fg=@icon_fg -button_icon_danger_fg=@danger_icon_fg - -buttonmenuitem_decoration_text_fg=@master_dark_bg - -; ComboBox. -combobox_border=@border_bg -combobox_fg=@content_fg -combobox_bg=@content_bg -combobox_disabled_fg=@disabled_fg -combobox_view_border=@border_bg -combobox_view_selected_bg=@selected_bg -combobox_view_selected_fg=@selected_fg -combobox_view_item_hover_fg=@hover_fg -combobox_view_item_hover_bg=@hover_bg -combobox_focus_bg=@edit_focus_bg -combobox_focus_border=@edit_focus_border -combobox_hover_bg=@edit_hover_bg -combobox_hover_border=@edit_hover_border -combobox_item_icon_fg=@item_icon_fg - -combobox_notebookselector_fg=@master_dark_bg -combobox_notebookselector_bg=@combobox_bg -combobox_notebookselector_border=@master_bg -combobox_notebookselector_hover_fg=@master_bg -combobox_notebookselector_hover_bg=@hover_bg -combobox_notebookselector_focus_fg=@master_bg -combobox_notebookselector_focus_bg=@focus_bg - -; Label. -label_fg=@base_fg -label_titlelabel_fg=@title_fg -label_titlelabel_bg=@title_bg - -; LineEdit. -lineedit_border=@border_bg -lineedit_fg=@edit_fg -lineedit_bg=@edit_bg -lineedit_disabled_fg=@disabled_fg -lineedit_focus_bg=@edit_focus_bg -lineedit_focus_border=@edit_focus_border -lineedit_hover_bg=@edit_hover_bg -lineedit_hover_border=@edit_hover_border -lineedit_selection_fg=@edit_selection_fg -lineedit_selection_bg=@edit_selection_bg - -; TabWidget. -tabwidget_pane_border=@selected_bg - -; TabBar. -tabbar_fg=@base_fg -tabbar_bg=@base_bg -tabbar_border=@border_bg - -tabbar_selected_fg=@edit_fg -tabbar_selected_bg=@edit_bg -tabbar_selected_border=@border_bg - -tabbar_hover_fg=@hover_fg -tabbar_hover_bg=@hover_bg - -tabbar_icon_fg=@icon_fg -tabbar_icon_special_fg=@danger_bg - -; SelectorItem. -selectoritem_border=@master_bg -selectoritem_fg=@base_fg -selectoritem_bg=@base_bg - -; InsertSelector. -insertselector_bg=@base_bg - -; TreeView. -treeview_fg=@content_fg -treeview_bg=@content_bg -treeview_item_border_bg=@border_bg -treeview_item_hover_fg=@hover_fg -treeview_item_hover_bg=@hover_bg -treeview_item_selected_fg=@selected_fg -treeview_item_selected_bg=@selected_bg -treeview_item_selected_avtive_fg=@active_fg -treeview_item_selected_avtive_bg=@active_bg -treeview_item_selected_inactive_fg=@inactive_fg -treeview_item_selected_inactive_bg=@inactive_bg -treeview_item_icon_fg=@item_icon_fg - -; ListView. -listview_fg=@content_fg -listview_bg=@content_bg -listview_item_hover_fg=@hover_fg -listview_item_hover_bg=@hover_bg -listview_item_selected_fg=@selected_fg -listview_item_selected_bg=@selected_bg -listview_item_selected_avtive_fg=@active_fg -listview_item_selected_avtive_bg=@active_bg -listview_item_selected_inactive_fg=@inactive_fg -listview_item_selected_inactive_bg=@inactive_bg - -; QAbstractItemView for TextEdit Completer. -abstractitemview_textedit_fg=@content_fg -abstractitemview_textedit_bg=#DADADA -abstractitemview_textedit_item_hover_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_hover_bg=@master_hover_bg -abstractitemview_textedit_item_selected_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_selected_bg=@master_light_bg -abstractitemview_textedit_item_selected_avtive_fg=@abstractitemview_textedit_fg -abstractitemview_textedit_item_selected_avtive_bg=@master_focus_bg -abstractitemview_textedit_item_selected_inactive_fg=@inactive_fg -abstractitemview_textedit_item_selected_inactive_bg=@inactive_bg - -; Splitter. -splitter_handle_bg=@border_bg -splitter_handle_pressed_bg=@pressed_bg - -; StatusBar. -statusbar_fg=@main_fg -statusbar_bg=@main_bg - -; ScrollBar. -scrollbar_bg=@base_bg -scrollbar_page_bg=transparent -scrollbar_handle_bg=#DADADA -scrollbar_handle_hover_bg=@hover_bg -scrollbar_handle_pressed_bg=@pressed_bg - -; VEditWindow. -editwindow_corner_icon_fg=@master_bg -editwindow_corner_icon_inactive_fg=#D3D3D3 - -; CheckBox. -checkbox_disabled_fg=@disabled_fg -checkbox_indicator_focus_bg=@focus_bg -checkbox_indicator_hover_bg=@hover_bg -checkbox_indicator_pressed_bg=@pressed_bg - -; RadioButton. -radiobutton_disabled_fg=@disabled_fg -radiobutton_indicator_focus_bg=@focus_bg -radiobutton_indicator_hover_bg=@hover_bg -radiobutton_indicator_pressed_bg=@pressed_bg - -; SpinBox. -spinbox_fg=@edit_fg -spinbox_bg=@edit_bg -spinbox_border=@border_bg -spinbox_selection_fg=@edit_selection_fg -spinbox_selection_bg=@edit_selection_bg -spinbox_focus_border=@edit_focus_border -spinbox_focus_bg=@edit_focus_bg -spinbox_hover_border=@edit_hover_border -spinbox_hover_bg=@edit_hover_bg -spinbox_button_hover_bg=@hover_bg -spinbox_button_pressed_bg=@pressed_bg - -; HeaderView. -headerview_bg=#E0E0E0 -headerview_fg=@base_fg -headerview_border=@border_bg -headerview_checked_fg=@selected_fg -headerview_checked_bg=@selected_bg - -; ProgressBar. -progressbar_bg=@edit_bg -progressbar_border_bg=@border_bg -progressbar_chunk_bg=@master_light_bg - -universalentry_bg=@base_bg -universalentry_border_bg=@border_bg - -doublerowitem_second_row_label_fg=#6C6C6C - -; GroupBox. -groupbox_border=@border_bg -groupbox_title_fg=@base_fg - -; Slider. -slider_border_bg=@border_bg -slider_groove_bg=@edit_bg -slider_handle_bg=@master_bg -slider_subpage_bg=@master_light_bg diff --git a/src/resources/themes/v_simple/v_simple.qss b/src/resources/themes/v_simple/v_simple.qss deleted file mode 100644 index 50ba455d..00000000 --- a/src/resources/themes/v_simple/v_simple.qss +++ /dev/null @@ -1,1464 +0,0 @@ -QToolTip -{ - border: none; - background: @tooltip_bg; - color: @tooltip_fg; -} - -/* QMainWindow */ -QMainWindow { - color: @base_fg; - background: @base_bg; -} - -QMainWindow::separator { - background: @dock_separator_bg; - width: $2px; - height: $2px; -} - -QMainWindow::separator:hover { - background: @dock_separator_hover_bg; -} - -QMainWindow::separator:pressed { - background: @dock_separator_pressed_bg; -} -/* End QMainWindow */ - -QMenuBar { - border: none; - background: @menubar_bg; - color: @menubar_fg; -} - -QMenuBar::item:selected { - background: @menubar_item_selected_bg; -} - -/* QMenu */ -QMenu { - background: @menu_bg; - color: @menu_fg; - border: $2px solid @menu_border_bg; -} - -QMenu::icon { - margin: $5px; -} - -QMenu::item { - padding: $5px $30px $5px $30px; - border: $1px solid transparent; -} - -QMenu::item:selected { - color: @menu_item_selected_fg; - background: @menu_item_selected_bg; -} - -QMenu::item:disabled { - color: @menu_item_disabled_fg; -} - -QMenu::icon:checked { /* appearance of a 'checked' icon */ - border: $2px solid @menu_fg; -} - -QMenu::separator { - height: $2px; - background: @menu_separator_bg; - margin-left: $10px; - margin-right: $5px; -} - -QMenu::indicator { - width: $20px; - height: $20px; -} - -QMenu::indicator:non-exclusive:unchecked { - image: none; -} - -QMenu::indicator:non-exclusive:checked { - image: url(menu_checkbox.svg); -} - -QMenu::indicator:exclusive:unchecked { - image: none; -} - -QMenu::indicator:exclusive:checked { - image: url(menu_radiobutton.svg); -} -/* End QMenu */ - -QToolBar { - border: none; - background: @toolbar_bg; -} - -QToolBar::separator { - width: 1px; - height: 1px; - border: none; - background: @toolbar_separator_bg; -} - -/* QToolButton */ -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: $16px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for InstantPopup */ - padding-right: $10px; /* make way for the popup button */ -} - -QToolButton { - border: none; - background: transparent; - margin: 1px 3px 1px 3px; - padding: 0px; -} - -QToolButton:checked { - background: @toolbutton_checked_bg; -} - -QToolButton:hover { - border:none; - background: @toolbutton_hover_bg; -} - -QToolButton:pressed { - background: @toolbutton_pressed_bg; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: none; - width: $16px; -} - -QToolButton::menu-arrow { - image: url(arrow_dropdown.svg); - width: $16px; - height: $16px; -} -/* End QToolButton*/ - -/* DockWidget */ -QDockWidget { - color: @dockwidget_title_fg; - background: @dockwidget_bg; - titlebar-close-icon: url(close.svg); - titlebar-normal-icon: url(float.svg); -} - -QDockWidget::Title { - background: @dockwidget_title_bg; - text-align: center left; -} - -QDockWidget::close-button, QDockWidget::float-button { - border: none; - icon-size: $16px; - width: $16px; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: @dockwidget_button_hover_bg; -} - -QDockWidget::close-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: 0px; bottom: 0px; -} - -QDockWidget::float-button { - subcontrol-position: top right; - subcontrol-origin: margin; - position: absolute; - top: 0px; right: $18px; bottom: 0px; -} -/* End DockWidget */ - -/* QPushButton */ -QPushButton[SpecialBtn="true"] { - color: @pushbutton_specialbtn_fg; - background: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_specialbtn_bg; -} - -QPushButton[SpecialBtn="true"]:focus { - background-color: @pushbutton_specialbtn_focus_bg; -} - -QPushButton[SpecialBtn="true"]:checked { - background-color: @pushbutton_specialbtn_checked_bg; -} - -QPushButton[SpecialBtn="true"]:hover { - background-color: @pushbutton_specialbtn_hover_bg; -} - -QPushButton[SpecialBtn="true"]:pressed { - background-color: @pushbutton_specialbtn_pressed_bg; -} - -QPushButton[CornerBtn="true"] { - padding: 4px -2px 4px -2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[CornerBtn="true"]::menu-indicator { - image: none; -} - -QPushButton[StatusBtn="true"] { - font: bold; - padding: 0px 2px 0px 2px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[FlatBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton[SelectionBtn="true"] { - padding: 4px 10px 4px 10px; - border: none; - background-color: transparent; - font-size: 15pt; - text-align: left; - min-width: -1; -} - -QPushButton[TitleBtn="true"] { - padding: 4px; - margin: 0px; - border: none; - background-color: @pushbutton_titlebtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"] { - color: @pushbutton_dangerbtn_fg; - border: none; - background-color: @pushbutton_dangerbtn_bg; - min-width: -1; -} - -QPushButton[DangerBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_dangerbtn_bg; -} - -QPushButton[DangerBtn="true"]:focus { - background-color: @pushbutton_dangerbtn_focus_bg; -} - -QPushButton[DangerBtn="true"]:checked { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[DangerBtn="true"]:hover { - background-color: @pushbutton_dangerbtn_hover_bg; -} - -QPushButton[DangerBtn="true"]:pressed { - background-color: @pushbutton_dangerbtn_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"] { - padding: 4px 10px 4px 4px; - margin: 0px; - border: none; - font-weight: bold; - color: @pushbutton_toolboxbtn_active_fg; - background-color: @pushbutton_toolboxbtn_active_bg; - min-width: -1; -} - -QPushButton[ToolBoxActiveBtn="true"]:default { - border: 1px solid @pushbutton_default_border; - background-color: @pushbutton_toolboxbtn_active_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:focus { - background-color: @pushbutton_toolboxbtn_active_focus_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:hover { - background-color: @pushbutton_toolboxbtn_active_hover_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:pressed { - background-color: @pushbutton_toolboxbtn_active_pressed_bg; -} - -QPushButton[ToolBoxActiveBtn="true"]:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton[AvatarBtn="true"] { - padding: 2px 4px 2px 4px; - margin: 0px; - border: none; - background-color: transparent; - min-width: -1; -} - -QPushButton { - color: @pushbutton_fg; - background: @pushbutton_bg; - border: 1px solid @pushbutton_border; - padding: 3px; - min-width: 80px; -} - -QPushButton:focus { - background-color: @pushbutton_focus_bg; -} - -QPushButton:checked { - background-color: @pushbutton_checked_bg; -} - -QPushButton:flat { - border: none; -} - -QPushButton:default { - border: 1px solid @pushbutton_default_border; -} - -QPushButton:hover { - background-color: @pushbutton_hover_bg; -} - -QPushButton:pressed { - background-color: @pushbutton_pressed_bg; -} - -QPushButton:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} - -QPushButton::menu-indicator { - image: url(arrow_dropdown.svg); - width: 16px; - height: 16px; -} - -VButtonMenuItem { - padding: 5px; - padding-right: 30px; - border: 1px solid transparent; - background-color: transparent; - min-width: -1; - text-align: left; -} - -VButtonMenuItem[Heading1="true"] { - font-size: 22pt; -} - -VButtonMenuItem[Heading2="true"] { - font-size: 20pt; -} - -VButtonMenuItem[Heading3="true"] { - font-size: 18pt; -} - -VButtonMenuItem[Heading4="true"] { - font-size: 16pt; -} - -VButtonMenuItem[Heading5="true"] { - font-size: 14pt; -} - -VButtonMenuItem[Heading6="true"] { - font-size: 14pt; -} - -VButtonMenuItem:focus { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:hover { - background-color: @menubar_item_selected_bg; -} - -VButtonMenuItem:disabled { - color: @pushbutton_disabled_fg; - background-color: @pushbutton_disabled_bg; -} -/* End QPushButton*/ - -/* QComboBox */ -QComboBox#NotebookSelector { - border: none; - font-size: 12pt; - padding-top: 5px; - padding-bottom: 5px; - icon-size: $24px; - font-weight: bold; - color: @combobox_notebookselector_fg; - background: @combobox_notebookselector_bg; -} - -QComboBox#NotebookSelector:focus, QComboBox#NotebookSelector:on { - color: @combobox_notebookselector_focus_fg; - background: @combobox_notebookselector_focus_bg; -} - -QComboBox#NotebookSelector:hover { - color: @combobox_notebookselector_hover_fg; - background: @combobox_notebookselector_hover_bg; -} - -QComboBox#NotebookSelector QListWidget { - border: 1px solid @combobox_view_border; - background-color: @combobox_bg; - font-size: 12pt; - font-weight: normal; - icon-size: $24px; -} - -QComboBox#NotebookSelector QListWidget::item { - padding-top: $5px; - padding-bottom: $5px; -} - -QComboBox#NotebookSelector QListWidget::item:hover { - color: @combobox_view_item_hover_fg; - background-color: @combobox_view_item_hover_bg; -} - -QComboBox { - padding: 3px; - color: @combobox_fg; - background: @combobox_bg; - border: 1px solid @combobox_border; -} - -QComboBox:focus, QComboBox:on { - background-color: @combobox_focus_bg; - border: 2px solid @combobox_focus_border; -} - -QComboBox:hover { - background-color: @combobox_hover_bg; - border: 2px solid @combobox_hover_border; -} - -QComboBox:disabled { - color: @combobox_disabled_fg; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: $20px; - border: none; - background: transparent; -} - -QComboBox::down-arrow { - image: url(arrow_dropdown.svg); - width: $20px; - height: $20px; -} - -QComboBox::down-arrow:disabled { - image: url(arrow_dropdown_disabled.svg); - width: $20px; - height: $20px; -} - -QComboBox QAbstractItemView { - padding: 2px; - border: 1px solid @combobox_view_border; - background: @combobox_bg; - selection-color: @combobox_view_selected_fg; - selection-background-color: @combobox_view_selected_bg; -} - -QComboBox QAbstractItemView::item { - background: transparent; - padding: 3px; -} - -QComboBox QAbstractItemView::item:hover { - color: @combobox_view_item_hover_fg; - background: @combobox_view_item_hover_bg; -} -/* End QComboBox */ - -/* QLabel */ -QLabel[TitleLabel="true"] { - padding-top: 5px; - padding-bottom: 5px; - color: @label_titlelabel_fg; - background-color: @label_titlelabel_bg; -} - -QLabel[ColorRedLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #D32F2F; -} - -QLabel[ColorGreenLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #388E3C; -} - -QLabel[ColorGreyLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #616161; -} - -QLabel[ColorTealLabel="true"] { - padding-left: 5px; - padding-right: 5px; - font: bold; - color: white; - border-radius: 2px; - background-color: #808080; -} - -QLabel[MenuSeparator="true"] { - padding-top: 5px; - padding-bottom: 5px; - margin-top: 3px; - font: italic; - border-top: 1px solid @menu_separator_bg -} - -QLabel[TagLabel="true"] { - padding-left: $5px; - padding-right: $5px; - color: @tab_indicator_tag_label_fg; - background-color: @tab_indicator_tag_label_bg; -} - -VVimIndicator QLabel[VimIndicatorKeyLabel="true"] { - font: bold; - color: @vim_indicator_key_label_fg; - background: transparent; -} - -VVimIndicator QLabel[VimIndicatorModeLabel="true"] { - padding: 0px 2px 0px 2px; - font: bold; - color: @vim_indicator_mode_label_fg; - /* background color will be controlled by the code. */ -} - -VTabIndicator QLabel[TabIndicatorLabel="true"] { - color: @tab_indicator_label_fg; - background: transparent; -} - -VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] { - font: bold; - border: $2px solid @selectoritem_border; - padding: 3px; - border-radius: 5px; - background-color: @selectoritem_bg; - color: @selectoritem_fg; -} - -VDoubleRowItemWidget QLabel[FirstRowLabel="true"] { - border: none; - font-size: 10pt; -} - -VDoubleRowItemWidget QLabel[SecondRowLabel="true"] { - border: none; - font-size: 9pt; - color: @doublerowitem_second_row_label_fg; -} - -QLabel { - border: none; - color: @label_fg; - background: transparent; -} -/* End QLabel */ - -/* QLineEdit */ -QLineEdit[VimCommandLine="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: @lineedit_bg; -} - -QLineEdit[VimCommandLine="true"]:focus { - background: @lineedit_focus_bg; - border: none; -} - -QLineEdit[VimCommandLine="true"]:hover { - background: @lineedit_hover_bg; - border: none; -} - -QLineEdit[EmbeddedEdit="true"] { - padding: 0px; - margin: 0px; - border: none; - color: @lineedit_fg; - background: transparent; -} - -QLineEdit[EmbeddedEdit="true"]:focus { - background: @lineedit_focus_bg; - border: none; -} - -QLineEdit[EmbeddedEdit="true"]:hover { - background: @lineedit_hover_bg; - border: none; -} - -QLineEdit { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QLineEdit:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QLineEdit:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} - -QLineEdit:disabled { - color: @lineedit_disabled_fg; -} -/* End QLineEdit */ - -/* QPlainTextEdit QTextEdit */ -QPlainTextEdit[LineEdit="true"], QTextEdit[LineEdit="true"] { - border: 1px solid @lineedit_border; - padding: 3px; - color: @lineedit_fg; - background: @lineedit_bg; - selection-color: @lineedit_selection_fg; - selection-background-color: @lineedit_selection_bg; -} - -QPlainTextEdit[LineEdit="true"]:focus, QTextEdit[LineEdit="true"]:focus { - border: 2px solid @lineedit_focus_border; - background: @lineedit_focus_bg; -} - -QPlainTextEdit[LineEdit="true"]:hover, QTextEdit[LineEdit="true"]:hover { - border: 2px solid @lineedit_hover_border; - background: @lineedit_hover_bg; -} -/* End QPlainTextEdit QTextEdit */ - -/* QTabWidget */ -QTabWidget { - border: none; -} - -QTabWidget::pane { - border: none; -} - -QTabWidget::tab-bar { - alignment: left; -} -/* End QTabWidget */ - -/* QTabBar */ -QTabBar::tab { - color: @tabbar_fg; - background: @tabbar_bg; - border: none; -} - -QTabBar::tab:top, QTabBar::tab:bottom { - border-top: $2px solid transparent; - border-right: $1px solid @tabbar_border; - /* MUST leave right and left padding 0px. */ - padding: $2px 0px $2px 0px; - height: $20px; -} - -QTabBar::tab:right { - border-left: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:left { - border-right: $3px solid transparent; - border-bottom: $1px solid @tabbar_border; - padding: $5px $2px $5px $2px; - min-width: $20px; -} - -QTabBar::tab:hover { - color: @tabbar_hover_fg; - background: @tabbar_hover_bg; -} - -QTabBar::tab:selected { - color: @tabbar_selected_fg; - background: @tabbar_selected_bg; -} - -QTabBar::tab:top:selected, QTabBar::tab:bottom:selected { - border-top: $2px solid @master_bg; -} - -QTabBar::tab:right:selected { - border-left: $3px solid @master_bg; -} - -QTabBar::tab:left:selected { - border-right: $3px solid @master_bg; -} - -QTabBar::close-button { - image: url(close_grey.svg); -} - -QTabBar::close-button:focus { - image: url(close.svg); -} - -QTabBar::close-button:hover { - image: url(close.svg); -} - -QTabBar::scroller { - width: $20px; -} - -QTabBar QToolButton { - border: none; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(right.svg); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(left.svg); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(right_disabled.svg); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(left_disabled.svg); -} -/* End QTabBar */ - -/* QTreeView */ -QTreeView[ItemBorder="true"]::item { - padding-top: 5px; - padding-bottom: 5px; - border-bottom: $1px solid @treeview_item_border_bg; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:!adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:!has-children:!has-siblings:adjoins-item { - border-image: none; -} - -QTreeView[PlainTree="true"]::branch:has-children:!has-siblings:closed, -QTreeView[PlainTree="true"]::branch:closed:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView[PlainTree="true"]::branch:open:has-children:!has-siblings, -QTreeView[PlainTree="true"]::branch:open:has-children:has-siblings { - border-image: none; - image: none; -} - -QTreeView { - color: @treeview_fg; - background: @treeview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QTreeView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QTreeView::item:hover { - color: @treeview_item_hover_fg; - background: @treeview_item_hover_bg; -} - -QTreeView::item:selected { - color: @treeview_item_selected_fg; - background: @treeview_item_selected_bg; -} - -QTreeView::item:selected:active { - color: @treeview_item_selected_active_fg; - background: @treeview_item_selected_active_bg; -} - -QTreeView::item:selected:!active { - color: @treeview_item_selected_inactive_fg; - background: @treeview_item_selected_inactive_bg; -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(line.svg) 0; -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(branch_more.svg) 0; -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(branch_end.svg) 0; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(branch_closed.svg); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(branch_open.svg); -} -/* End QTreeView */ - -/* QListView */ -QListView { - color: @listview_fg; - background: @listview_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QListView::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QListView::item:hover { - color: @listview_item_hover_fg; - background: @listview_item_hover_bg; -} - -QListView::item:selected { - color: @listview_item_selected_fg; - background: @listview_item_selected_bg; -} - -QListView::item:selected:active { - color: @listview_item_selected_active_fg; - background: @listview_item_selected_active_bg; -} - -QListView::item:selected:!active { - color: @listview_item_selected_inactive_fg; - background: @listview_item_selected_inactive_bg; -} - -QListView::item:disabled { - background: transparent; -} -/* End QListView */ - -/* QAbstractItemView for TextEdit Completer popup*/ -QAbstractItemView[TextEdit="true"] { - color: @abstractitemview_textedit_fg; - background: @abstractitemview_textedit_bg; - show-decoration-selected: 0; - border: none; - selection-background-color: transparent; - outline: none; -} - -QAbstractItemView[TextEdit="true"]::item { - padding-top: 5px; - padding-bottom: 5px; -} - -QAbstractItemView[TextEdit="true"]::item:hover { - color: @abstractitemview_textedit_item_hover_fg; - background: @abstractitemview_textedit_item_hover_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected { - color: @abstractitemview_textedit_item_selected_fg; - background: @abstractitemview_textedit_item_selected_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:active { - color: @abstractitemview_textedit_item_selected_active_fg; - background: @abstractitemview_textedit_item_selected_active_bg; -} - -QAbstractItemView[TextEdit="true"]::item:selected:!active { - color: @abstractitemview_textedit_item_selected_inactive_fg; - background: @abstractitemview_textedit_item_selected_inactive_bg; -} - -QAbstractItemView[TextEdit="true"]::item:disabled { - background: transparent; -} -/* End QAbstractItemView */ - -/* QSplitter */ -QSplitter#MainSplitter { - border: none; - margin-left: $3px; -} - -QSplitter { - border: none; -} - -QSplitter::handle { - background-color: @splitter_handle_bg; -} - -QSplitter::handle:pressed { - background-color: @splitter_handle_pressed_bg; -} - -QSplitter::handle:vertical { - height: $2px; -} - -QSplitter::handle:horizontal { - width: $2px; -} -/* End QSplitter */ - -/* QStatusBar */ -QStatusBar { - color: @statusbar_fg; - background: @statusbar_bg; -} -/* End QStatusBar */ - -QDialog { - color: @base_fg; - background: @base_bg; -} - -/* QScrollBar */ -QScrollBar::add-page, QScrollBar::sub-page { - background: @scrollbar_page_bg; -} - -QScrollBar:vertical { - background: @scrollbar_bg; - width: $16px; - margin: $16px 0px $16px 0px; - padding: 0px $2px 0px $2px; - border: none; -} - -QScrollBar::handle:vertical { - background: @scrollbar_handle_bg; - min-height: $16px; -} - -QScrollBar::handle:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:vertical { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:vertical:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::down-arrow:vertical { - image: url(down.svg); - width: $16px; - height: $16px; -} - -QScrollBar::up-arrow:vertical { - image: url(up.svg); - width: $16px; - height: $16px; -} - -QScrollBar:horizontal { - background: @scrollbar_bg; - height: $16px; - margin: 0px $16px 0px $16px; - padding: $2px 0px $2px 0px; - border: none; -} - -QScrollBar::handle:horizontal { - background: @scrollbar_handle_bg; - min-width: $16px; -} - -QScrollBar::handle:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::handle:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::add-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::add-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::sub-line:horizontal { - border: none; - background: @scrollbar_bg; - width: $16px; - height: $16px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover { - background: @scrollbar_handle_hover_bg; -} - -QScrollBar::sub-line:horizontal:pressed { - background: @scrollbar_handle_pressed_bg; -} - -QScrollBar::right-arrow:horizontal { - image: url(right.svg); - width: $16px; - height: $16px; -} - -QScrollBar::left-arrow:horizontal { - image: url(left.svg); - width: $16px; - height: $16px; -} -/* End QScrollBar */ - -/* QCheckBox */ -QCheckBox { - spacing: $5px; -} - -QCheckBox:disabled { - color: @checkbox_disabled_fg; -} - -QCheckBox::indicator:unchecked { - image: url(checkbox_unchecked.svg); -} - -QCheckBox::indicator:unchecked:disabled { - image: url(checkbox_unchecked_disabled.svg); -} - -QCheckBox::indicator:checked { - image: url(checkbox_checked.svg); -} - -QCheckBox::indicator:checked:disabled { - image: url(checkbox_checked_disabled.svg); -} - -QCheckBox::indicator { - width: $20px; - height: $20px; -} - -QCheckBox::indicator:focus { - background: @checkbox_indicator_focus_bg; -} - -QCheckBox::indicator:hover { - background: @checkbox_indicator_hover_bg; -} - -QCheckBox::indicator:pressed { - background: @checkbox_indicator_pressed_bg; -} -/* End QCheckBox */ - -/* QRadioButton */ -QRadioButton { - spacing: $5px; -} - -QRadioButton:disabled { - color: @radiobutton_disabled_fg; -} - -QRadioButton::indicator:unchecked { - image: url(radiobutton_unchecked.svg); -} - -QRadioButton::indicator:unchecked:disabled { - image: url(radiobutton_unchecked_disabled.svg); -} - -QRadioButton::indicator:checked { - image: url(radiobutton_checked.svg); -} - -QRadioButton::indicator:checked:disabled { - image: url(radiobutton_checked_disabled.svg); -} - -QRadioButton::indicator { - width: $20px; - height: $20px; -} - -QRadioButton::indicator:focus { - background: @radiobutton_indicator_focus_bg; -} - -QRadioButton::indicator:hover { - background: @radiobutton_indicator_hover_bg; -} - -QRadioButton::indicator:pressed { - background: @radiobutton_indicator_pressed_bg; -} -/* End QRadioButton */ - -/* QSpinBox */ -QSpinBox, QDoubleSpinBox { - border: 1px solid @spinbox_border; - color: @spinbox_fg; - background: @spinbox_bg; - padding-right: $25px; - min-height: $25px; - selection-color: @spinbox_selection_fg; - selection-background-color: @spinbox_selection_bg; -} - -QSpinBox:focus, QDoubleSpinBox::focus { - border: 2px solid @spinbox_focus_border; - background: @spinbox_focus_bg; -} - -QSpinBox:hover, QDoubleSpinBox::hover { - border: 2px solid @spinbox_hover_border; - background: @spinbox_hover_bg; -} - -QSpinBox::up-button, QDoubleSpinBox::up-button { - subcontrol-origin: border; - subcontrol-position: top right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} - -QSpinBox::up-arrow:disabled, QSpinBox::up-arrow:off, QDoubleSpinBox::up-arrow:disabled, QDoubleSpinBox::up-arrow:off { - image: url(up_disabled.svg); -} - -QSpinBox::down-button, QDoubleSpinBox::down-button { - subcontrol-origin: border; - subcontrol-position: bottom right; /* position at the top right corner */ - width: $25px; - border: none; - background: transparent; -} - -QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover { - background: @spinbox_button_hover_bg; -} - -QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed { - background: @spinbox_button_pressed_bg; -} - -QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QSpinBox::down-arrow:disabled, QSpinBox::down-arrow:off, QDoubleSpinBox::down-arrow:disabled, QDoubleSpinBox::down-arrow:off { - image: url(down_disabled.svg); -} -/* End QSpinBox */ - -/* QHeaderView */ -QHeaderView::section { - background: @headerview_bg; - color: @headerview_fg; - padding-left: 4px; - border: none; - border-left: 1px solid @headerview_border; - border-bottom: 1px solid @headerview_border; -} - -QHeaderView::section:checked -{ - color: @headerview_checked_fg; - background: @headerview_checked_bg; -} - -/* style the sort indicator */ -QHeaderView::down-arrow { - image: url(down.svg); - width: $12px; - height: $12px; -} - -QHeaderView::up-arrow { - image: url(up.svg); - width: $12px; - height: $12px; -} -/* End QHeaderView */ - -QAbstractScrollArea::corner { - background: @scrollbar_bg; - border: none; -} - -/* QProgressBar */ -QProgressBar { - background: @progressbar_bg; - border: $1px solid @progressbar_border_bg; - text-align: center; -} - -QProgressBar::chunk { - background-color: @progressbar_chunk_bg; - width: $20px; -} -/* End QProgressBar */ - -/* QGroupBox */ -QGroupBox { - border: 2px solid @groupbox_border; - border-radius: 5px; - margin-top: 2ex; -} - -QGroupBox::title { - color: @groupbox_title_fg; - subcontrol-origin: margin; - subcontrol-position: top left; - position: absolute; - padding: 0 $3px; - top: 0px; left: $10px; bottom: 0px; -} -/* End QGroupBox */ - -/* QSlider */ -QSlider::groove:horizontal { - border: $1px solid @slider_border_bg; - height: $8px; - background: @slider_groove_bg; - margin: $2px 0; -} - -QSlider::handle:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - width: $18px; - margin: $-2px 0; -} - -QSlider::add-page:horizontal { - background: transparent; -} - -QSlider::sub-page:horizontal { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: $2px 0; -} - -QSlider::groove:vertical { - border: $1px solid @slider_border_bg; - width: $8px; - background: @slider_groove_bg; - margin: 0 $2px; -} - -QSlider::handle:vertical { - border: $1px solid @slider_border_bg; - background: @slider_handle_bg; - height: $18px; - margin: 0 $-2px; -} - -QSlider::add-page:vertical { - background: transparent; -} - -QSlider::sub-page:vertical { - border: $1px solid @slider_border_bg; - background: @slider_subpage_bg; - margin: 0 $2px; -} -/* End QSlider */ - -/* QWidget */ -QWidget#FindReplaceTitleWidget { - background: @title_bg; -} - -QWidget[ToolBoxTitle="true"] { - border-bottom: $2px solid @toolbox_title_border; -} - -QWidget[ToolBoxTitle="true"] QPushButton[ToolBoxTitleBtn="true"] { - height: $20px; -} - -QWidget[MainEditor="true"] { - border: none; -} - -QWidget -{ - color: @widget_fg; - font-family: "Hiragino Sans GB", "冬青黑体", "Microsoft YaHei", "微软雅黑", "Microsoft YaHei UI", "WenQuanYi Micro Hei", "文泉驿雅黑", "Dengxian", "等线体", "STXihei", "华文细黑", "Liberation Sans", "Droid Sans", "NSimSun", "新宋体", "SimSun", "宋体", "Helvetica", "sans-serif", "Tahoma", "Arial", "Verdana", "Geneva", "Georgia", "Times New Roman"; -} - -VInsertSelector { - border: none; - background: @insertselector_bg; -} - -VUniversalEntry { - background: @universalentry_bg; - border: 1px solid @universalentry_border_bg; -} -/* End QWidget */ diff --git a/src/resources/themes/v_simple/v_simple_codeblock.css b/src/resources/themes/v_simple/v_simple_codeblock.css deleted file mode 100644 index 0152d5d5..00000000 --- a/src/resources/themes/v_simple/v_simple_codeblock.css +++ /dev/null @@ -1,62 +0,0 @@ -/*Original highlight.js style (c) Ivan Sagalaev */ -.hljs -{ - background: #23241f; - font-family:Monospace!important; - border-radius: 5px!important; - display:block; - overflow-x:auto; - padding:0.5em; - background:#23241feb !important; - color:#FFF; - white-space:pre; - word-break:normal; -} -.hljs,.hljs-tag,.hljs-subst -{ - color:#f8f8f2; -} -.hljs-strong,.hljs-emphasis -{ - color:#a8a8a2; -} -.hljs-bullet,.hljs-quote,.hljs-number,.hljs-regexp,.hljs-literal,.hljs-link -{ - color:#ae81ff; -} -.hljs-code,.hljs-title,.hljs-section,.hljs-selector-class -{ - color:#a6e22e; -} -.hljs-strong -{ - font-weight:bold; -} -.hljs-emphasis -{ - font-style:italic; -} -.hljs-keyword,.hljs-selector-tag,.hljs-name,.hljs-attr -{ - color:#f92672; -} -.hljs-symbol,.hljs-attribute -{ - color:#66d9ef; -} -.hljs-params,.hljs-class .hljs-title -{ - color:#f8f8f2; -} -.hljs-string,.hljs-type,.hljs-built_in,.hljs-builtin-name,.hljs-selector-id,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-addition,.hljs-variable,.hljs-template-variable -{ - color:#e6db74; -} -.hljs-comment,.hljs-deletion,.hljs-meta -{ - color:#948a5c; -} -.cnblogs-markdown .hljs -{ - font-size:14px!important; -} diff --git a/src/resources/themes/v_simple/v_simple_mermaid.css b/src/resources/themes/v_simple/v_simple_mermaid.css deleted file mode 100644 index 3d808780..00000000 --- a/src/resources/themes/v_simple/v_simple_mermaid.css +++ /dev/null @@ -1,320 +0,0 @@ -/* Flowchart variables */ -/* Sequence Diagram variables */ -/* Gantt chart variables */ -.mermaid-diagram .mermaid .label { - color: #333; -} - -.mermaid-diagram .node rect, -.mermaid-diagram .node circle, -.mermaid-diagram .node ellipse, -.mermaid-diagram .node polygon { - fill: #ECECFF; - stroke: #CCCCFF; - stroke-width: 1px; -} - -.mermaid-diagram .edgePath .path { - stroke: #333333; -} - -.mermaid-diagram .edgeLabel { - background-color: #e8e8e8; -} - -.mermaid-diagram .cluster rect { - fill: #ffffde !important; - rx: 4 !important; - stroke: #aaaa33 !important; - stroke-width: 1px !important; -} - -.mermaid-diagram .cluster text { - fill: #333; -} - -.mermaid-diagram .actor { - stroke: #CCCCFF; - fill: #ECECFF; -} - -.mermaid-diagram text.actor { - fill: black; - stroke: none; -} - -.mermaid-diagram .actor-line { - stroke: grey; -} - -.mermaid-diagram .messageLine0 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #333; -} - -.mermaid-diagram .messageLine1 { - stroke-width: 1.5; - stroke-dasharray: "2 2"; - stroke: #333; -} - -.mermaid-diagram #arrowhead { - fill: #333; -} - -.mermaid-diagram #crosshead path { - fill: #333 !important; - stroke: #333 !important; -} - -.mermaid-diagram .messageText { - fill: #333; - stroke: none; -} - -.mermaid-diagram .labelBox { - stroke: #CCCCFF; - fill: #ECECFF; -} - -.mermaid-diagram .labelText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopText { - fill: black; - stroke: none; -} - -.mermaid-diagram .loopLine { - stroke-width: 2; - stroke-dasharray: "2 2"; - marker-end: "url(#arrowhead)"; - stroke: #CCCCFF; -} - -.mermaid-diagram .note { - stroke: #aaaa33; - fill: #fff5ad; -} - -.mermaid-diagram .noteText { - fill: black; - stroke: none; - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -/** Section styling */ -.mermaid-diagram .section { - stroke: none; - opacity: 0.2; -} - -.mermaid-diagram .section0 { - fill: rgba(102, 102, 255, 0.49); -} - -.mermaid-diagram .section2 { - fill: #fff400; -} - -.mermaid-diagram .section1, -.mermaid-diagram .section3 { - fill: white; - opacity: 0.2; -} - -.mermaid-diagram .sectionTitle0 { - fill: #333; -} - -.mermaid-diagram .sectionTitle1 { - fill: #333; -} - -.mermaid-diagram .sectionTitle2 { - fill: #333; -} - -.mermaid-diagram .sectionTitle3 { - fill: #333; -} - -.mermaid-diagram .sectionTitle { - text-anchor: start; - font-size: 11px; - text-height: 14px; -} - -/* Grid and axis */ -.mermaid-diagram .grid .tick { - stroke: lightgrey; - opacity: 0.3; - shape-rendering: crispEdges; -} - -.mermaid-diagram .grid path { - stroke-width: 0; -} - -/* Today line */ -.mermaid-diagram .today { - fill: none; - stroke: red; - stroke-width: 2px; -} - -/* Task styling */ -/* Default task */ -.mermaid-diagram .task { - stroke-width: 2; -} - -.mermaid-diagram .taskText { - text-anchor: middle; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideRight { - fill: black; - text-anchor: start; - font-size: 11px; -} - -.mermaid-diagram .taskTextOutsideLeft { - fill: black; - text-anchor: end; - font-size: 11px; -} - -/* Specific task settings for the sections*/ -.mermaid-diagram .taskText0, -.mermaid-diagram .taskText1, -.mermaid-diagram .taskText2, -.mermaid-diagram .taskText3 { - fill: white; -} - -.mermaid-diagram .task0, -.mermaid-diagram .task1, -.mermaid-diagram .task2, -.mermaid-diagram .task3 { - fill: #8a90dd; - stroke: #534fbc; -} - -.mermaid-diagram .taskTextOutside0, -.mermaid-diagram .taskTextOutside2 { - fill: black; -} - -.mermaid-diagram .taskTextOutside1, -.mermaid-diagram .taskTextOutside3 { - fill: black; -} - -/* Active task */ -.mermaid-diagram .active0, -.mermaid-diagram .active1, -.mermaid-diagram .active2, -.mermaid-diagram .active3 { - fill: #bfc7ff; - stroke: #534fbc; -} - -.mermaid-diagram .activeText0, -.mermaid-diagram .activeText1, -.mermaid-diagram .activeText2, -.mermaid-diagram .activeText3 { - fill: black !important; -} - -/* Completed task */ -.mermaid-diagram .done0, -.mermaid-diagram .done1, -.mermaid-diagram .done2, -.mermaid-diagram .done3 { - stroke: grey; - fill: lightgrey; - stroke-width: 2; -} - -.mermaid-diagram .doneText0, -.mermaid-diagram .doneText1, -.mermaid-diagram .doneText2, -.mermaid-diagram .doneText3 { - fill: black !important; -} - -/* Tasks on the critical line */ -.mermaid-diagram .crit0, -.mermaid-diagram .crit1, -.mermaid-diagram .crit2, -.mermaid-diagram .crit3 { - stroke: #ff8888; - fill: red; - stroke-width: 2; -} - -.mermaid-diagram .activeCrit0, -.mermaid-diagram .activeCrit1, -.mermaid-diagram .activeCrit2, -.mermaid-diagram .activeCrit3 { - stroke: #ff8888; - fill: #bfc7ff; - stroke-width: 2; -} - -.mermaid-diagram .doneCrit0, -.mermaid-diagram .doneCrit1, -.mermaid-diagram .doneCrit2, -.mermaid-diagram .doneCrit3 { - stroke: #ff8888; - fill: lightgrey; - stroke-width: 2; - cursor: pointer; - shape-rendering: crispEdges; -} - -.mermaid-diagram .doneCritText0, -.mermaid-diagram .doneCritText1, -.mermaid-diagram .doneCritText2, -.mermaid-diagram .doneCritText3 { - fill: black !important; -} - -.mermaid-diagram .activeCritText0, -.mermaid-diagram .activeCritText1, -.mermaid-diagram .activeCritText2, -.mermaid-diagram .activeCritText3 { - fill: black !important; -} - -.mermaid-diagram .titleText { - text-anchor: middle; - font-size: 18px; - fill: black; -} - -.mermaid-diagram .node text { - font-family: 'trebuchet ms', verdana, arial; - font-size: 14px; -} - -.mermaid-diagram div.mermaidTooltip { - position: absolute; - text-align: center; - max-width: 200px; - padding: 2px; - font-family: 'trebuchet ms', verdana, arial; - font-size: 12px; - background: #ffffde; - border: 1px solid #aaaa33; - border-radius: 2px; - pointer-events: none; - z-index: 100; -} diff --git a/src/resources/typewriter.css b/src/resources/typewriter.css deleted file mode 100644 index 7f7de22c..00000000 --- a/src/resources/typewriter.css +++ /dev/null @@ -1,16 +0,0 @@ -.typewriter h3 { - font-family: monospace; - padding: 4px 0px 4px 4px; - display: inline-block; - overflow: hidden; - border-right: 0.5em solid #00897B; - white-space: nowrap; - margin: 0 auto; - animation: - blink-caret 1s step-end infinite; -} - -@keyframes blink-caret { - from, to { border-color: transparent } - 50% { border-color: #00897B } -} diff --git a/src/resources/view_image.js b/src/resources/view_image.js deleted file mode 100644 index 843eaf78..00000000 --- a/src/resources/view_image.js +++ /dev/null @@ -1,201 +0,0 @@ -var imageViewDiv = document.getElementById('image-view-div'); - -var viewImage = function(imgSrc, background = 'transparent') { - viewBoxImageMouseDown = false; - - imageViewDiv.style.display = 'block'; - - var boxImage = document.getElementById('image-view'); - boxImage.src = imgSrc; - boxImage.style.backgroundColor = background; - - // Restore image-view. - boxImage.style.width = ''; - boxImage.style.position = ''; - boxImage.style.zIndex = ''; -}; - -var viewIMG = function(imgNode) { - viewImage(imgNode.src); -}; - -var viewSVG = function(svgNode, background = 'transparent') { - var svg = svgNode.outerHTML.replace(/#/g, '%23').replace(/[\r\n]/g, ''); - var src = 'data:image/svg+xml;utf8,' + svg; - - viewImage(src, background); -}; - -var viewBoxImageMouseDown = false; -var viewBoxImageOffsetToMouse = [0, 0]; - -var closeImageViewBox = function() { - imageViewDiv.style.display = "none"; -}; - -var initImageViewBox = function() { - // Left and top in pixel. - var moveImage = function(img, left, top) { - if (img.style.position != 'absolute') { - img.style.position = 'absolute'; - img.style.zIndex = parseInt(document.getElementById('image-view-close').style.zIndex) - 1; - } - - img.style.left = left + 'px'; - img.style.top = top + 'px'; - }; - - // View box. - imageViewDiv.onclick = function(e) { - e = e || window.event; - var boxImage = document.getElementById('image-view'); - if (e.target.id != boxImage.id) { - // Click outside the image to close the box. - closeImageViewBox(); - } - - e.preventDefault(); - }; - - imageViewDiv.onwheel = function(e) { - e = e || window.event; - var ctrl = !!e.ctrlKey; - if (ctrl) { - return; - } - - var target = e.target; - if (!target || target.id != 'image-view') { - return; - } - - var rect = target.getBoundingClientRect(); - var centerX = e.clientX - rect.left; - var centerY = e.clientY - rect.top; - - var oriWidth = target.getAttribute('oriWidth'); - var oriHeight = target.getAttribute('oriWidth'); - if (!oriWidth) { - oriWidth = rect.width; - oriHeight = rect.height; - - target.setAttribute('oriWidth', oriWidth); - target.setAttribute('oriHeight', oriHeight); - } - - var step = Math.floor(oriWidth / 4); - - var value = e.wheelDelta || -e.detail; - // delta >= 0 is up, which will trigger zoom in. - var delta = Math.max(-1, Math.min(1, value)); - - var newWidth = rect.width + (delta < 0 ? -step : step); - if (newWidth < 200) { - e.preventDefault(); - return; - } - - var factor = newWidth / rect.width; - - target.style.width = newWidth + 'px'; - - // Adjust the image around the center point. - moveImage(target, e.clientX - centerX * factor, e.clientY - centerY * factor); - - e.preventDefault(); - }; - - // Content image. - var boxImage = document.getElementById('image-view'); - boxImage.onmousedown = function(e) { - e = e || window.event; - var target = this || e.target; - viewBoxImageMouseDown = true; - viewBoxImageOffsetToMouse = [ - target.offsetLeft - e.clientX, - target.offsetTop - e.clientY - ]; - e.preventDefault(); - }; - - boxImage.onmouseup = function(e) { - e = e || window.event; - viewBoxImageMouseDown = false; - e.preventDefault(); - }; - - boxImage.onmousemove = function(e) { - e = e || window.event; - var target = this || e.target; - if (viewBoxImageMouseDown) { - moveImage(target, e.clientX + viewBoxImageOffsetToMouse[0], e.clientY + viewBoxImageOffsetToMouse[1]); - } - - e.preventDefault(); - }; - - // Close button. - document.getElementById('image-view-close').onclick = closeImageViewBox; -}; - -initImageViewBox(); - -var setupImageView = function() { - closeImageViewBox(); - - var imgs = document.getElementsByTagName('img'); - for (var i = 0; i < imgs.length; ++i) { - if (imgs[i].id == 'image-view') { - continue; - } - - setupIMGToView(imgs[i]); - } -}; - -var isViewingImage = function() { - return imageViewDiv.style.display == 'block'; -}; - -var onSVGDoubleClick = function(forceBackground, e) { - e = e || window.event; - var name = e.target.nodeName.toLowerCase(); - if (name != 'text' && name != 'tspan') { - if (forceBackground) { - // Use 's parent's background color. - var svgNode = e.target; - while (svgNode && svgNode.nodeName.toLowerCase() != 'svg') { - svgNode = svgNode.parentNode; - } - - if (svgNode) { - var style = window.getComputedStyle(svgNode.parentNode, null); - viewSVG(this, style.backgroundColor); - } - } else { - viewSVG(this); - } - - e.preventDefault(); - } -}; - -var setupSVGToView = function(node, forceBackground = false) { - if (!node || node.nodeName.toLowerCase() != 'svg') { - return; - } - - node.classList.add('view-svg'); - node.ondblclick = onSVGDoubleClick.bind(node, forceBackground); -}; - -var setupIMGToView = function(node) { - if (!node || node.nodeName.toLowerCase() != 'img') { - return; - } - - node.classList.add('view-image'); - node.ondblclick = function() { - viewIMG(this); - }; -}; diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini deleted file mode 100644 index c714fab6..00000000 --- a/src/resources/vnote.ini +++ /dev/null @@ -1,592 +0,0 @@ -[global] -; Github Image Hosting -github_personal_access_token= -github_repos_name= -github_user_name= -github_keep_img_scale= -github_do_not_replace_link= -; Gitee Image Hosting -gitee_personal_access_token= -gitee_repos_name= -gitee_user_name= -gitee_keep_img_scale= -gitee_do_not_replace_link= -; Wechat Image Hosting -wechat_appid= -wechat_secret= -wechat_markdown_to_wechat_tool_url= -wechat_keep_img_scale= -wechat_do_not_replace_link= -; Tencent Image Hosting -tencent_access_domain_name= -tencent_secret_id= -tencent_secret_key= -tencent_keep_img_scale= -tencent_do_not_replace_link= - -; Theme name -theme=v_pure - -; CSS style name for Markdown template -; Empty to use theme's css style -css_style= - -; Code block CSS style for Markdown template -; Empty to use theme's css style -code_block_css_style= - -; Editor style name -; Empty to use theme's editor style -editor_style= - -current_notebook=0 -tab_stop_width=4 -is_expand_tab=true - -; Whether highlight cursor line -highlight_cursor_line=true - -highlight_selected_word=true -highlight_searched_word=true - -current_background_color=System -current_render_background_color=System -language=System - -; 0 - Hoedown, 1 - Marked, 2 - Markdown-it, 3 - Showdown -markdown_converter=2 - -; Enable Mermaid diagram -enable_mermaid=false - -; Enable MathJax -enable_mathjax=false - -; Enable Flowchart.js -enable_flowchart=false - -; Enable PlantUML -; 0 - disable PlantUML -; 1 - online PlantUML -; 2 - local PlantUML -plantuml_mode=0 - -; Enable Graphviz -enable_graphviz=false - -; -1 - calculate the factor -web_zoom_factor=-1 - -; Delta font size of the editor -editor_zoom_delta=0 - -; Syntax highlight within code blocks in edit mode -enable_code_block_highlight=true - -; Enable image preview in edit mode -enable_preview_images=true - -; Enable image preview constraint in edit mode to constrain the width of the preview -enable_preview_image_constraint=false - -; Enable image constraint in read mode to constrain the width of the image -enable_image_constraint=false - -; Center image and add the alt text as caption -enable_image_caption=false - -; Image folder name for the notes -image_folder=_v_images - -; Image folder name for the external files -external_image_folder=_v_images - -; Attachment folder name for the notes -attachment_folder=_v_attachments - -; Enable trailing space highlight -enable_trailing_space_highlight=true - -; Display an area besides the editor area to show line number -; 0 - None, 1 - Absolute, 2 - Relative, 3 - CodeBlock -editor_line_number=1 - -; Whether minimize to system tray when closing the app -; -1: uninitialized, prompt user for the behavior -; 0: do not minimize to system tray -; 1: minimize to system tray -minimize_to_system_tray=-1 - -; Suffixes list of Markdown files separated by , -; Case-insensitive -markdown_suffix=md,markdown,mkd - -; Markdown highlight timer interval (milliseconds) -markdown_highlight_interval=400 - -; Adds specified height between lines (in pixels) -line_distance_height=3 - -; Whether insert the note name as a title when creating a new note -insert_title_from_note_name=true - -; Default open mode when opening a note -; 0 - Read, 1 - Edit -note_open_mode=0 - -; Whether auto generate heading sequence -; 0 - Disabled, 1 - Enabled, 2 - Enabled only for notes -heading_sequence_type=0 - -; Heading sequence base level -heading_sequence_base_level=1 - -; Style the xth column in fenced code block -; 0 - no color column -color_column=0 - -; Whether display line number of code block in read mode -enable_code_block_line_number=false - -; The icon size of tool bar (in pixels) -tool_bar_icon_size=20 - -; Default name of the recycle bin of notebook -recycle_bin_folder=_v_recycle_bin - -; Default name of the recycle bin of external files -external_recycle_bin_folder=_v_recycle_bin - -; Confirm before deleting unused images -confirm_images_clean_up=true - -; Confirm before reloading folder from disk -confirm_reload_folder=true - -; Whether double click on a tab to close it -double_click_close_tab=true - -; Whether middle click on a tab to close it -middle_click_close_tab=true - -; Whether enable tools dock widget -tools_dock_checked=true - -; Whether enable search dock widget -search_dock_checked=false - -; Whether show menu bar -menu_bar_checked=true - -; Whether show tool bar -tool_bar_checked=true - -; Pages to open on startup -; 0 - none; 1 - Continue where you left off; 2 - specific pages -startup_page_type=1 - -; Specific pages to open on startup when startup_page_type is 2 -; A list of file path separated by , -; Notice: should escape \ by \\ -; C:\users\vnote\vnote.md -> C:\\users\\vnote\\vnote.md -startup_pages= - -; Timer interval to check file modification or save file to tmp file in milliseconds -file_timer_interval=2000 - -; Whether enable auto save file -enable_auto_save=false - -; Directory for the backup file -; A directory "." means to put the backup file in the same directory as the edited file -backup_directory=. - -; String which is appended to a file name to make the name of the backup file -backup_extension=.vswp - -; Enable backup file -enable_backup_file=true - -; Skipped keys in Vim mode -; c: Ctrl+C -; v: Ctrl+V -; x: Ctrl+X -vim_exemption_keys=cvx - -; Path of the flash page, related to the configuration folder -; Could be absolute path -flash_page=flash_page.md - -; Path of the quick access note, related to the configuration folder -; Could be absolute path -quick_access= - -; Whether close note before editting with external editor -close_before_external_editor=true - -; Custom color list to be used in VNote, such as background color -; Separated by , -; Each item is in the form "Name:Color" -custom_colors=White:#FFFFFF,LightGrey:#EEEEEE - -; Single click to open a file then close previous tab -single_click_close_previous_tab=false - -; Whether enable auto wildcard match in simple search like list and tree widgets -enable_wildcard_in_simple_search=true - -; Search options -; scope,object,target,engine,option,pattern -search_options=4,2,7,0,0,"" - -; Number of items in history -; 0 to disable history -history_size=100 - -; View order of note list -; 0 - configuration file -; 1 - name -; 2 - name reverse -; 3 - created time -; 4 - created time reverse -; 5 - modified time -; 6 - modified time reverse -note_list_view_order=0 - -; Level of the heading the outline should be expanded to -; 1 - 6 -outline_expanded_level=6 - -; [optional] Prefix of the name of inserted images -image_name_prefix= - -; MainWindow panel view state -; 0 - ExpandMode -; 1 - HorizontalMode (Not Implemented) -; 2 - VerticalMode -panel_view_state=2 - -; Max length of the text to display in tag label -; <= 0 indicates no limit to the length -max_tag_label_length=10 - -; Max number of tag labels to display -max_num_of_tag_labels=3 - -; Smart live preview -; 0 - disable smart live preview -; 1 - editor to web -; 2 - web to editor -smart_live_preview=3 - -; Whether insert new note in front -insert_new_note_in_front=false - -; Whether highlight matches in page when activating a search result item -highlight_matches_in_page=false - -; Incremental search in page -find_incremental_search=true - -; Additional Qt::Key_XXX which will be mapped in different layouts -; List of integer values. -keyboard_layout_mapping_keys= - -; Chosen keyboard layout mapping from keyboard_layouts.ini -keyboard_layout= - -; Whether split file list out of the notebook panel -split_file_list=false - -; Whether split file list out of the tag explorer -split_tag_file_list=false - -; OpenGL option for Windows -; 0 - no set; -; 1 - desktop; -; 2 - angle; -; 3 - software; -windows_opengl=0 - -; Whether allow VNote to send request for couting users -allow_user_track=false - -; Whether auto locate to current tab in note list -sync_note_list_to_current_tab=false - -[editor] -; Auto indent as previous line -auto_indent=true - -; Auto add list marker -auto_list=true - -; Auto add block quote marker -auto_quote=true - -; 0 - normal mode -; 1 - Vim mode -key_mode=0 - -; Enable smart input method in Vim mode (disable IM in non-Insert modes) -enable_smart_im_in_vim_mode=true - -; Leader key in Vim mode -; Should be one character long -vim_leader_key=" " - -; Enable tab highlight -enable_tab_highlight=false - -; Download images in parsed HTML text -parse_paste_local_image=true - -; Enable extra buffer at the bottom of the editor to avoid placing -; cursor at the bottom -enable_extra_buffer=true - -; Auto scroll cursor line when it is at the bottom part of the content -; Need enable_extra_buffer to be enabled -; 0 - disabled -; 1 - end of doc -; 2 - always -auto_scroll_cursor_line=1 - -; Editor font family to override the value set by the style -editor_font_family= - -; Whether enable smart table -enable_smart_table=true - -; Interval (milliseconds) to format table -table_format_interval=2000 - -[export] -; Path of the wkhtmltopdf tool -wkhtmltopdf=wkhtmltopdf - -; Additional arguments to wkhtmltopdf -; Double quotes to enclose arguments with spaces -wkhtmltopdfArgs= - -; A string list separated by , -; SourceFormat,OutputSuffix,CMD -; SourceFormat: 0 for Markdown, 1 for HTML -; OutputSuffix: suffix WITHOUT the preceding dot -; CMD: command to execute, %0 for the input file, %1 for the output file -custom_export= - -[web] -; String list containing options for Markdown-it -; html: enable HTML tags in source -; break: convert '\n' in paragraphs into
    -; linkify: auto-convert URL-like text to links -; sub: subscript -; sup: superscript -; metadata: metadata aware -; emoji: emoji and emoticon -markdownit_opt=html,break,linkify,metadata - -; Location and configuration for Mathjax -mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.0.1/es5/tex-mml-chtml.js - -; Styles to be removed when copied -; style1,style2,style3 -styles_to_remove_when_copied= - -; Styles when transform to -style_of_span_for_mark="background-color: #FFFF00;" - -; CSS properties to embed as inline styles when copied in edit mode -; tag1:tag2:tag3$property1:property2:property3,tag4:tag5$property2:property3 -; "all" for all tags not specified explicitly -styles_to_inline_when_copied=all$border:color:display:font-family:font-size:font-style:white-space:word-spacing:line-height:text-align:text-indent:padding-top:padding-bottom:margin-top:margin-bottom:background-color:font-weight,code$font-family:font-size:line-height:color:display:overfow-x:background-color:font-weight,li$line-height:background-color:font-weight,a$color:vertical-align:background-color:font-weight,pre$display:overflow-y:overflow-x:color:font-size:font-style:font-weight:letter-spacing:text-align:text-indent:word-spacing:background-color - -; Define targets the copied content will be pasted into -; target_name$action1:action2:action3,targeet_name2$action2:action3 -; Available actions: -; s - add surrounding tags -; e - add surrounding tags -; b(tag1|tag2) - remove background color of all tags except tag1 and tag2 -; c(tag1|tag2) - translate colors using palette defined mapping except tag1 and tag2 -; i - fix local relative -; m(tag1|tag2) - remove margin/margin-left/margin-right/padding/padding-left/padding-right of all tags except tag1 and tag2 -; r - raw html with all styles removed -; a - transform to -; x(tag1|tag2) - remove styles specified in [styles_to_remove_when_copied] of all tags except tag1 and tag2 -; p - replace the background color of
     with that of its child 
    -; n - replace the \n in 
     with 
    -; g - replace local relative/absolute tag with a warning label -; d - add to which is not inside
    -; f - replace " with ' in font-family style
    -; h - replace  tag with 
    -; j - fix XHTML tag like  and 
    -copy_targets="Without Background"$s:b(mark):c:i:x,Evernote$e:p:b(mark|pre):c(pre):g:m:a:x:n:j,OneNote$e:b(mark):c:i:m:a:x,"Microsoft Word"$s:p:b(mark|pre):c(pre):i:m:a:x,"WeChat Public Account"$s:p:b(mark|pre):c(pre):g:m:x:n:f,"Web Editor"$s:p:b(mark|pre):c(pre):m:x:n,"Raw HTML"$r:x - -enable_flash_anchor=true - -; PlantUML server to convert UML script online -plantuml_server=http://www.plantuml.com/plantuml - -; PlantUML JAR location -plantuml_jar= - -; Additional PlantUML arguments -; Double quotes to enclose arguments with spaces -plantuml_args= - -; Custom PlantUML command to execute to convert a PlantUML diagram in local PlantUML -; Read data definition from stdin and output diagram result to stdout -; When set, other local PlantUML related settings are ignored -; %0 will be replaced with the format string like svg or png -; plantuml_cmd=/bin/sh -c \"cat | java -jar /opt/plantuml/plantuml.jar -charset UTF-8 -nbthread 4 -pipe -t%0\" -plantuml_cmd= - -; Graphviz Dot location -graphviz_dot= - -; Whether enable copy button in code block -enable_code_block_copy_button=false - -[shortcuts] -; Define shortcuts here, with each item in the form "operation=keysequence". -; Leave keysequence empty to disable the shortcut of an operation. -; Customized shortcuts may conflict with some key bindings in edit mode or Vim mode. -; Ctrl+Q is reserved for quitting VNote. - -; Leader key of Captain mode -CaptainMode=Ctrl+E -; Create a note in current folder -NewNote=Ctrl+Alt+N -; Create a subfolder in current folder -NewSubfolder=Ctrl+Alt+S -; Save current note -SaveNote=Ctrl+S -; Edit or read note -EditReadNote=Ctrl+T -; Close current note -CloseNote= -; Open file/replace dialog -Find=Ctrl+F -; Find next occurence -FindNext=F3 -; Find previous occurence -FindPrevious=Shift+F3 -; Jump to next match of last find -NextMatch=Ctrl+8 -; Jump to previous match of last find -PreviousMatch=Ctrl+9 -; Advanced find -AdvancedFind=Ctrl+Alt+F -; Recover last closed file -LastClosedFile=Ctrl+Shift+T -; Activate next tab -ActivateNextTab=Ctrl+Tab -; Activate previous tab -ActivatePreviousTab=Ctrl+Shift+Tab -; Activate flash page -FlashPage=Ctrl+Alt+L -; Quick access note -QuickAccess=Ctrl+Alt+I -; Open via system's default program -OpenViaDefaultProgram=F12 -; Full screen -FullScreen=F11 -; Universal Entry -UniversalEntry=Ctrl+G -; Paste as plain text -PastePlainText=Ctrl+Shift+V - -[captain_mode_shortcuts] -; Define shortcuts in Captain mode here. -; There shortcuts are the sub-sequence after the CaptainMode key sequence -; in [shortcuts]. - -; Enter Navigation mode -NavigationMode=W -; Show attachment list of current note -AttachmentList=A -; Locate to the folder of current note -LocateCurrentFile=D -; Toggle Expand mode -ExpandMode=E -; Discard changes and enter read mode -DiscardAndRead=Q -; Toggle Tools dock widget -ToolsDock=T -; Toggle Search dock widget -SearchDock=C -; Toggle tool bar -ToolBar=Shift+# -; Close current note -CloseNote=X -; Show shortcuts help document -ShortcutsHelp=Shift+? -; Flush the log file -FlushLogFile=";" -; Show opened files list -OpenedFileList=F -; Activate the ith tab -ActivateTab1=1 -ActivateTab2=2 -ActivateTab3=3 -ActivateTab4=4 -ActivateTab5=5 -ActivateTab6=6 -ActivateTab7=7 -ActivateTab8=8 -ActivateTab9=9 -; Alternate between current and last tab -AlternateTab=0 -; Activate next tab -ActivateNextTab=J -; Activate previous tab -ActivatePreviousTab=K -; Activate the window split on the left -ActivateSplitLeft=H -; Activate the window split on the right -ActivateSplitRight=L -; Move current tab one split left -MoveTabSplitLeft=Shift+H -; Move current tab one split right -MoveTabSplitRight=Shift+L -; Create a vertical split -VerticalSplit=V -; Remove current split -RemoveSplit=R -; Maximize current split -MaximizeSplit=Shift+| -; Distribute all the splits evenly -DistributeSplits== -; Evaluate selected text or cursor word as magic words -MagicWord=M -; Prompt for user to apply a snippet -ApplySnippet=S -; Open export dialog -Export=O -; Toggle live preview -LivePreview=I -; Expand or restore live preview area -ExpandLivePreview=U -; Focus edit area -FocusEditArea=Y -; Parse HTML and paste -ParseAndPaste=P -; View note info of current edit tab -CurrentNoteInfo=N - -[external_editors] -; Define external editors which could be called to edit notes -; One program per line with the format name="program \"%0\" arg1 arg2", -; in which %0 will be replaced with the note file path (so it is better to enclose it -; with double quotes) -; Shortcut could be empty -; Need to escape \ and ", use double quotes to quote paths/arguments with spaces -; SHOULD defined in user config file, not here - -[markdown] -; Enable WaveDrom -enable_wavedrom=false - -; Prepend a dot in relative path of images and attachments -prepend_dot_in_relative_path=false diff --git a/src/src.pro b/src/src.pro deleted file mode 100644 index c26f0ff4..00000000 --- a/src/src.pro +++ /dev/null @@ -1,406 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-10-01T11:03:59 -# -#------------------------------------------------- - -QT += core gui webenginewidgets webchannel network svg printsupport - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -# Enable message log in release build -DEFINES += QT_MESSAGELOGCONTEXT - -TARGET = VNote -TEMPLATE = app - -CONFIG -= qtquickcompiler - -RC_ICONS = resources/icons/vnote.ico -ICON = resources/icons/vnote.icns - -TRANSLATIONS += translations/vnote_zh_CN.ts \ - translations/vnote_ja.ts - -*-g++ { - QMAKE_CFLAGS_WARN_ON += -Wno-class-memaccess - QMAKE_CXXFLAGS_WARN_ON += -Wno-class-memaccess - QMAKE_CFLAGS += -Wno-class-memaccess - QMAKE_CXXFLAGS += -Wno-class-memaccess -} - -SOURCES += main.cpp\ - vapplication.cpp \ - vimagehosting.cpp \ - vmainwindow.cpp \ - vdirectorytree.cpp \ - vnote.cpp \ - vnotebook.cpp \ - dialog/vnewdirdialog.cpp \ - vconfigmanager.cpp \ - vfilelist.cpp \ - dialog/vnewfiledialog.cpp \ - vedit.cpp \ - vdocument.cpp \ - utils/vutils.cpp \ - vpreviewpage.cpp \ - vstyleparser.cpp \ - dialog/vnewnotebookdialog.cpp \ - vmarkdownconverter.cpp \ - dialog/vnotebookinfodialog.cpp \ - dialog/vdirinfodialog.cpp \ - dialog/vfileinfodialog.cpp \ - veditoperations.cpp \ - vmdeditoperations.cpp \ - dialog/vinsertimagedialog.cpp \ - vdownloader.cpp \ - veditarea.cpp \ - veditwindow.cpp \ - vedittab.cpp \ - voutline.cpp \ - vsingleinstanceguard.cpp \ - vdirectory.cpp \ - vfile.cpp \ - vnotebookselector.cpp \ - vnofocusitemdelegate.cpp \ - vmdedit.cpp \ - dialog/vfindreplacedialog.cpp \ - dialog/vsettingsdialog.cpp \ - dialog/vdeletenotebookdialog.cpp \ - dialog/vselectdialog.cpp \ - vcaptain.cpp \ - vopenedlistmenu.cpp \ - vnavigationmode.cpp \ - vorphanfile.cpp \ - vcodeblockhighlighthelper.cpp \ - vwebview.cpp \ - vmdtab.cpp \ - vhtmltab.cpp \ - utils/vvim.cpp \ - utils/veditutils.cpp \ - vvimindicator.cpp \ - vbuttonwithwidget.cpp \ - vtabindicator.cpp \ - dialog/vupdater.cpp \ - dialog/vorphanfileinfodialog.cpp \ - vtextblockdata.cpp \ - utils/vpreviewutils.cpp \ - dialog/vconfirmdeletiondialog.cpp \ - vnotefile.cpp \ - vattachmentlist.cpp \ - dialog/vsortdialog.cpp \ - vfilesessioninfo.cpp \ - vtableofcontent.cpp \ - utils/vmetawordmanager.cpp \ - vmetawordlineedit.cpp \ - dialog/vinsertlinkdialog.cpp \ - vplaintextedit.cpp \ - vimageresourcemanager.cpp \ - vlinenumberarea.cpp \ - veditor.cpp \ - vmdeditor.cpp \ - veditconfig.cpp \ - vpreviewmanager.cpp \ - vimageresourcemanager2.cpp \ - vtextdocumentlayout.cpp \ - vtextedit.cpp \ - vsnippetlist.cpp \ - vsnippet.cpp \ - dialog/veditsnippetdialog.cpp \ - utils/vimnavigationforwidget.cpp \ - vtoolbox.cpp \ - vinsertselector.cpp \ - utils/vclipboardutils.cpp \ - vpalette.cpp \ - vbuttonmenuitem.cpp \ - utils/viconutils.cpp \ - lineeditdelegate.cpp \ - dialog/vtipsdialog.cpp \ - dialog/vcopytextashtmldialog.cpp \ - vwaitingwidget.cpp \ - utils/vwebutils.cpp \ - vlineedit.cpp \ - vcart.cpp \ - vvimcmdlineedit.cpp \ - vlistwidget.cpp \ - vsimplesearchinput.cpp \ - vstyleditemdelegate.cpp \ - vtreewidget.cpp \ - dialog/vexportdialog.cpp \ - vexporter.cpp \ - vsearcher.cpp \ - vsearch.cpp \ - vsearchresulttree.cpp \ - vsearchengine.cpp \ - vuniversalentry.cpp \ - vlistwidgetdoublerows.cpp \ - vdoublerowitemwidget.cpp \ - vsearchue.cpp \ - voutlineue.cpp \ - vhelpue.cpp \ - vlistfolderue.cpp \ - dialog/vfixnotebookdialog.cpp \ - vplantumlhelper.cpp \ - vgraphvizhelper.cpp \ - vlivepreviewhelper.cpp \ - vmathjaxpreviewhelper.cpp \ - vmathjaxwebdocument.cpp \ - vmathjaxinplacepreviewhelper.cpp \ - vhistorylist.cpp \ - vexplorer.cpp \ - vlistue.cpp \ - vuetitlecontentpanel.cpp \ - utils/vprocessutils.cpp \ - vtagpanel.cpp \ - valltagspanel.cpp \ - vtaglabel.cpp \ - vtagexplorer.cpp \ - pegmarkdownhighlighter.cpp \ - pegparser.cpp \ - peghighlighterresult.cpp \ - vtexteditcompleter.cpp \ - utils/vkeyboardlayoutmanager.cpp \ - dialog/vkeyboardlayoutmappingdialog.cpp \ - vfilelistwidget.cpp \ - widgets/vcombobox.cpp \ - vtablehelper.cpp \ - vtable.cpp \ - dialog/vinserttabledialog.cpp \ - utils/vSync.cpp - -HEADERS += vmainwindow.h \ - vapplication.h \ - vdirectorytree.h \ - vimagehosting.h \ - vnote.h \ - vnotebook.h \ - dialog/vnewdirdialog.h \ - vconfigmanager.h \ - vfilelist.h \ - dialog/vnewfiledialog.h \ - vedit.h \ - vconstants.h \ - vdocument.h \ - utils/vutils.h \ - vpreviewpage.h \ - vstyleparser.h \ - dialog/vnewnotebookdialog.h \ - vmarkdownconverter.h \ - dialog/vnotebookinfodialog.h \ - dialog/vdirinfodialog.h \ - dialog/vfileinfodialog.h \ - veditoperations.h \ - vmdeditoperations.h \ - dialog/vinsertimagedialog.h \ - vdownloader.h \ - veditarea.h \ - veditwindow.h \ - vedittab.h \ - voutline.h \ - vsingleinstanceguard.h \ - vdirectory.h \ - vfile.h \ - vnotebookselector.h \ - vnofocusitemdelegate.h \ - vmdedit.h \ - dialog/vfindreplacedialog.h \ - dialog/vsettingsdialog.h \ - dialog/vdeletenotebookdialog.h \ - dialog/vselectdialog.h \ - vcaptain.h \ - vopenedlistmenu.h \ - vnavigationmode.h \ - vorphanfile.h \ - vcodeblockhighlighthelper.h \ - vwebview.h \ - vmdtab.h \ - vhtmltab.h \ - utils/vvim.h \ - utils/veditutils.h \ - vvimindicator.h \ - vbuttonwithwidget.h \ - vedittabinfo.h \ - vtabindicator.h \ - dialog/vupdater.h \ - dialog/vorphanfileinfodialog.h \ - vtextblockdata.h \ - utils/vpreviewutils.h \ - dialog/vconfirmdeletiondialog.h \ - vnotefile.h \ - vattachmentlist.h \ - dialog/vsortdialog.h \ - vfilesessioninfo.h \ - vtableofcontent.h \ - utils/vmetawordmanager.h \ - vmetawordlineedit.h \ - dialog/vinsertlinkdialog.h \ - vplaintextedit.h \ - vimageresourcemanager.h \ - vlinenumberarea.h \ - veditor.h \ - vmdeditor.h \ - veditconfig.h \ - vpreviewmanager.h \ - vimageresourcemanager2.h \ - vtextdocumentlayout.h \ - vtextedit.h \ - vsnippetlist.h \ - vsnippet.h \ - dialog/veditsnippetdialog.h \ - utils/vimnavigationforwidget.h \ - vtoolbox.h \ - vinsertselector.h \ - utils/vclipboardutils.h \ - vpalette.h \ - vbuttonmenuitem.h \ - utils/viconutils.h \ - lineeditdelegate.h \ - dialog/vtipsdialog.h \ - dialog/vcopytextashtmldialog.h \ - vwaitingwidget.h \ - utils/vwebutils.h \ - vlineedit.h \ - vcart.h \ - vvimcmdlineedit.h \ - vlistwidget.h \ - vsimplesearchinput.h \ - vstyleditemdelegate.h \ - vtreewidget.h \ - dialog/vexportdialog.h \ - vexporter.h \ - vwordcountinfo.h \ - vsearcher.h \ - vsearch.h \ - vsearchresulttree.h \ - isearchengine.h \ - vsearchconfig.h \ - vsearchengine.h \ - vuniversalentry.h \ - iuniversalentry.h \ - vlistwidgetdoublerows.h \ - vdoublerowitemwidget.h \ - vsearchue.h \ - voutlineue.h \ - vhelpue.h \ - vlistfolderue.h \ - dialog/vfixnotebookdialog.h \ - vplantumlhelper.h \ - vgraphvizhelper.h \ - vlivepreviewhelper.h \ - vmathjaxpreviewhelper.h \ - vmathjaxwebdocument.h \ - vmathjaxinplacepreviewhelper.h \ - markdownitoption.h \ - vhistorylist.h \ - vhistoryentry.h \ - vexplorer.h \ - vexplorerentry.h \ - vlistue.h \ - vuetitlecontentpanel.h \ - utils/vprocessutils.h \ - vtagpanel.h \ - valltagspanel.h \ - vtaglabel.h \ - vtagexplorer.h \ - markdownhighlighterdata.h \ - pegmarkdownhighlighter.h \ - pegparser.h \ - peghighlighterresult.h \ - vtexteditcompleter.h \ - vtextdocumentlayoutdata.h \ - utils/vkeyboardlayoutmanager.h \ - dialog/vkeyboardlayoutmappingdialog.h \ - vfilelistwidget.h \ - widgets/vcombobox.h \ - vtablehelper.h \ - vtable.h \ - dialog/vinserttabledialog.h \ - utils/vSync.h - -RESOURCES += \ - vnote.qrc \ - translations.qrc - -macx { - LIBS += -L/usr/local/lib - INCLUDEPATH += /usr/local/include -} - -INCLUDEPATH += $$PWD/../peg-highlight -DEPENDPATH += $$PWD/../peg-highlight - -INCLUDEPATH += $$PWD/../hoedown -DEPENDPATH += $$PWD/../hoedown - -win32-g++:CONFIG(release, debug|release) { - LIBS += $$OUT_PWD/../peg-highlight/release/libpeg-highlight.a - LIBS += $$OUT_PWD/../hoedown/release/libhoedown.a - - # Explicitly listing dependent static libraries. - PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/release/libpeg-highlight.a - PRE_TARGETDEPS += $$OUT_PWD/../hoedown/release/libhoedown.a -} else:win32-g++:CONFIG(debug, debug|release) { - LIBS += $$OUT_PWD/../peg-highlight/debug/libpeg-highlight.a - LIBS += $$OUT_PWD/../hoedown/debug/libhoedown.a - - PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/debug/libpeg-highlight.a - PRE_TARGETDEPS += $$OUT_PWD/../hoedown/debug/libhoedown.a -} else:win32:!win32-g++:CONFIG(release, debug|release) { - LIBS += $$OUT_PWD/../peg-highlight/release/peg-highlight.lib - LIBS += $$OUT_PWD/../hoedown/release/hoedown.lib - - PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/release/peg-highlight.lib - PRE_TARGETDEPS += $$OUT_PWD/../hoedown/release/hoedown.lib -} else:win32:!win32-g++:CONFIG(debug, debug|release) { - LIBS += $$OUT_PWD/../peg-highlight/debug/peg-highlight.lib - LIBS += $$OUT_PWD/../hoedown/debug/hoedown.lib - - PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/debug/peg-highlight.lib - PRE_TARGETDEPS += $$OUT_PWD/../hoedown/debug/hoedown.lib -} else:unix { - LIBS += $$OUT_PWD/../peg-highlight/libpeg-highlight.a - LIBS += $$OUT_PWD/../hoedown/libhoedown.a - - PRE_TARGETDEPS += $$OUT_PWD/../peg-highlight/libpeg-highlight.a - PRE_TARGETDEPS += $$OUT_PWD/../hoedown/libhoedown.a -} - -## INSTALLS -unix:!macx { - isEmpty(PREFIX): PREFIX = /usr - DATADIR = $${PREFIX}/share - - # install desktop file - desktop.path = $${DATADIR}/applications - desktop.files += vnote.desktop - - # install icons - icon16.path = $${DATADIR}/icons/hicolor/16x16/apps - icon16.files = resources/icons/16x16/vnote.png - - icon32.path = $${DATADIR}/icons/hicolor/32x32/apps - icon32.files = resources/icons/32x32/vnote.png - - icon48.path = $${DATADIR}/icons/hicolor/48x48/apps - icon48.files = resources/icons/48x48/vnote.png - - icon64.path = $${DATADIR}/icons/hicolor/64x64/apps - icon64.files = resources/icons/64x64/vnote.png - - icon128.path = $${DATADIR}/icons/hicolor/128x128/apps - icon128.files = resources/icons/128x128/vnote.png - - icon256.path = $${DATADIR}/icons/hicolor/256x256/apps - icon256.files = resources/icons/256x256/vnote.png - - iconsvg.path = $${DATADIR}/icons/hicolor/scalable/apps - iconsvg.files = resources/icons/vnote.svg - - target.path = $${PREFIX}/bin - - lntarget.path = $${PREFIX}/bin - lntarget.extra = $(SYMLINK) $(QMAKE_TARGET) $(INSTALL_ROOT)$${PREFIX}/bin/vnote - - INSTALLS += target lntarget desktop icon16 icon32 icon48 icon64 icon128 icon256 iconsvg - message("VNote will be installed in prefix $${PREFIX}") -} diff --git a/src/translations.qrc b/src/translations.qrc deleted file mode 100644 index 2e15995c..00000000 --- a/src/translations.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - translations/vnote_zh_CN.qm - translations/vnote_ja.qm - - diff --git a/src/translations/qdialogbuttonbox_zh_CN.qm b/src/translations/qdialogbuttonbox_zh_CN.qm deleted file mode 100644 index 43ffbeee..00000000 Binary files a/src/translations/qdialogbuttonbox_zh_CN.qm and /dev/null differ diff --git a/src/translations/qdialogbuttonbox_zh_CN.ts b/src/translations/qdialogbuttonbox_zh_CN.ts deleted file mode 100644 index bb248a85..00000000 --- a/src/translations/qdialogbuttonbox_zh_CN.ts +++ /dev/null @@ -1,79 +0,0 @@ - - - - - QPlatformTheme - - OK - 确定 - - - Save - 保存 - - - Save All - 全部保存 - - - Open - 打开 - - - &Yes - 是 (&Y) - - - Yes to &All - 全部选择是 (&A) - - - &No - 否 (&N) - - - N&o to All - 全部选择否 (&O) - - - Abort - 终止 - - - Retry - 重试 - - - Ignore - 忽略 - - - Close - 关闭 - - - Cancel - 取消 - - - Discard - 放弃 - - - Help - 帮助 - - - Apply - 应用 - - - Reset - 重置 - - - Restore Defaults - 恢复默认 - - - diff --git a/src/translations/qt_zh_CN.qm b/src/translations/qt_zh_CN.qm deleted file mode 100644 index b88b5034..00000000 Binary files a/src/translations/qt_zh_CN.qm and /dev/null differ diff --git a/src/translations/qt_zh_CN.ts b/src/translations/qt_zh_CN.ts deleted file mode 100644 index 966254c9..00000000 --- a/src/translations/qt_zh_CN.ts +++ /dev/null @@ -1,6337 +0,0 @@ - - - - - MAC_APPLICATION_MENU - - Services - 服务 - - - Hide %1 - 隐藏%1 - - - Hide Others - 隐藏其他 - - - Show All - 全部显示 - - - Preferences... - 偏好设置… - - - Quit %1 - 退出 %1 - - - About %1 - 关于 %1 - - - - AudioOutput - - <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> - <html>音频回放设备 <b>%1</b> 没有工作。<br/>回滚到 <b>%2</b>。</html> - - - <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> - <html>切换到音频回放设备 <b>%1</b>,<br/>它刚刚变为可用并且具有更高的优先级。</html> - - - Revert back to device '%1' - 恢复到设备“%1” - - - - CloseButton - - Close Tab - 关闭标签页 - - - - Phonon:: - - Notifications - 通知 - - - Music - 音乐 - - - Video - 视频 - - - Communication - 通讯 - - - Games - 游戏 - - - Accessibility - 无障碍环境 - - - - Phonon::Gstreamer::Backend - - Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. - Some video features have been disabled. - 警告:看起来,您没有安装 gstreamer0.10-plugins-good 包。 - 一些视频特性已经被关闭。 - - - Warning: You do not seem to have the base GStreamer plugins installed. - All audio and video support has been disabled - 警告:看起来,您没有安装基础的 GStreamer 插件。 - 所有的音频和视频支持都已经被关闭。 - - - - Phonon::Gstreamer::MediaObject - - Cannot start playback. - -Check your Gstreamer installation and make sure you -have libgstreamer-plugins-base installed. - 不能开始回放。 - -请检查您的 Gstreamer 安装并且确认您 -已经安装 libgstreamer-plugins-base。 - - - A required codec is missing. You need to install the following codec(s) to play this content: %0 - 缺少一个需要的解码器。您需要安装如下解码器来播放这个内容:%0 - - - Could not open media source. - 不能打开媒体源。 - - - Invalid source type. - 无效的源类型。 - - - Could not locate media source. - 不能定位媒体源。 - - - Could not open audio device. The device is already in use. - 不能打开音频设备。这个设备正在被使用。 - - - Could not decode media source. - 不能解码媒体源。 - - - - Phonon::VolumeSlider - - Volume: %1% - 音量:%1% - - - Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% - 请使用这个滑块调节音量。最左为%0,最右为%1% - - - - Q3Accel - - %1, %2 not defined - %1,%2未定义 - - - Ambiguous %1 not handled - 不明确的%1没有被处理 - - - - Q3DataTable - - True - - - - False - - - - Insert - 插入 - - - Update - 更新 - - - Delete - 删除 - - - - Q3FileDialog - - Copy or Move a File - 复制或者移动一个文件 - - - Read: %1 - 读取:%1 - - - Write: %1 - 写入:%1 - - - Cancel - 取消 - - - All Files (*) - 所有文件 (*) - - - Name - 名称 - - - Size - 大小 - - - Type - 类型 - - - Date - 日期 - - - Attributes - 属性 - - - &OK - 确定(&O) - - - Look &in: - 查找范围(&I): - - - File &name: - 文件名称(&N): - - - File &type: - 文件类型(&T): - - - Back - 后退 - - - One directory up - 向上一级 - - - Create New Folder - 创建新文件夹 - - - List View - 列表视图 - - - Detail View - 详细视图 - - - Preview File Info - 预览文件信息 - - - Preview File Contents - 预览文件内容 - - - Read-write - 读写 - - - Read-only - 只读 - - - Write-only - 只写 - - - Inaccessible - 不可访问的 - - - Symlink to File - 文件的系统链接 - - - Symlink to Directory - 目录的系统链接 - - - Symlink to Special - 特殊的系统链接 - - - File - 文件 - - - Dir - 目录 - - - Special - 特殊 - - - Open - 打开 - - - Save As - 另存为 - - - &Open - 打开(&O) - - - &Save - 保存(&S) - - - &Rename - 重命名(&R) - - - &Delete - 删除(&D) - - - R&eload - 重新载入(&E) - - - Sort by &Name - 按名称排列(&N) - - - Sort by &Size - 按大小排列(&S) - - - Sort by &Date - 按日期排列(&D) - - - &Unsorted - 未排列的(&U) - - - Sort - 排列 - - - Show &hidden files - 显示隐藏文件(&H) - - - the file - 文件 - - - the directory - 目录 - - - the symlink - 系统链接 - - - Delete %1 - 删除%1 - - - <qt>Are you sure you wish to delete %1 "%2"?</qt> - <qt>你确认你想删除%1,“%2”?</qt> - - - &Yes - 是(&Y) - - - &No - 否(&N) - - - New Folder 1 - 新建文件夹1 - - - New Folder - 新建文件夹 - - - New Folder %1 - 新建文件夹%1 - - - Find Directory - 查找目录 - - - Directories - 目录 - - - Directory: - 目录: - - - Error - 错误 - - - %1 -File not found. -Check path and filename. - 文件%1 -未找到。 -请检查路径和文件名。 - - - - All Files (*.*) - 所有文件 (*.*) - - - Open - 打开 - - - Select a Directory - 选择一个目录 - - - - Q3LocalFs - - Could not read directory -%1 - 不能读取目录 -%1 - - - Could not create directory -%1 - 不能创建目录 -%1 - - - Could not remove file or directory -%1 - 不能移除文件或者目录 -%1 - - - Could not rename -%1 -to -%2 - 不能把 -%1 -重命名为 -%2 - - - Could not open -%1 - 不能打开 -%1 - - - Could not write -%1 - 不能写入 -%1 - - - - Q3MainWindow - - Line up - 排列 - - - Customize... - 自定义... - - - - Q3NetworkProtocol - - Operation stopped by the user - 操作被用户停止 - - - - Q3ProgressDialog - - Cancel - 取消 - - - - Q3TabDialog - - OK - 确认 - - - Apply - 应用 - - - Help - 帮助 - - - Defaults - 默认 - - - Cancel - 取消 - - - - Q3TextEdit - - &Undo - 撤消(&U) - - - &Redo - 恢复(&R) - - - Cu&t - 剪切(&T) - - - &Copy - 复制(&C) - - - &Paste - 粘贴(&P) - - - Clear - 清空 - - - Select All - 选择全部 - - - - Q3TitleBar - - System - 系统 - - - Restore up - 向上恢复 - - - Minimize - 最小化 - - - Restore down - 向下恢复 - - - Maximize - 最大化 - - - Close - 关闭 - - - Contains commands to manipulate the window - 包含操作窗口的命令。 - - - Puts a minimized back to normal - 把一个最小化窗口恢复为普通状态 - - - Moves the window out of the way - 把窗口移到外面 - - - Puts a maximized window back to normal - 把一个最大化窗口恢复为普通状态 - - - Makes the window full screen - 窗口全屏化 - - - Closes the window - 关闭窗口 - - - Displays the name of the window and contains controls to manipulate it - 显示窗口名称并且包含维护它的控件 - - - - Q3ToolBar - - More... - 更多... - - - - Q3UrlOperator - - The protocol `%1' is not supported - 协议“%1”不被支持 - - - The protocol `%1' does not support listing directories - 协议“%1”不支持列出目录 - - - The protocol `%1' does not support creating new directories - 协议“%1”不支持创建新目录 - - - The protocol `%1' does not support removing files or directories - 协议“%1”不支持移除文件或者目录 - - - The protocol `%1' does not support renaming files or directories - 协议“%1”不支持重命名文件或者目录 - - - The protocol `%1' does not support getting files - 协议“%1”不支持获取文件 - - - The protocol `%1' does not support putting files - 协议“%1”不支持上传文件 - - - The protocol `%1' does not support copying or moving files or directories - 协议“%1”不支持复制或者移动文件或者目录 - - - (unknown) - (未知的) - - - - Q3Wizard - - &Cancel - 取消(&C) - - - < &Back - < 上一步(&B) - - - &Next > - 下一步(&N) > - - - &Finish - 完成(&F) - - - &Help - 帮助(&H) - - - - QAbstractSocket - - Host not found - 主机未找到 - - - Connection refused - 连接被拒绝 - - - Connection timed out - 连接超时 - - - Operation on socket is not supported - Socket操作不被支持 - - - Socket operation timed out - 套接字操作超时 - - - Socket is not connected - 套接字没有被连接 - - - Network unreachable - 网络不能访问 - - - - QAbstractSpinBox - - &Step up - 增加(&S) - - - Step &down - 减少(&D) - - - &Select All - 选择全部(&S) - - - - QApplication - - Activate - 激活 - - - Executable '%1' requires Qt %2, found Qt %3. - 执行“%1”需要Qt %2,只找到了Qt %3。 - - - Incompatible Qt Library Error - 不兼容的Qt错误 - - - Activates the program's main window - 激活这个程序的主窗口 - - - - QAxSelect - - Select ActiveX Control - 选择ActiveX控件 - - - OK - 确定 - - - &Cancel - 取消(&C) - - - COM &Object: - COM对象(&O): - - - - QCheckBox - - Uncheck - 取消选中 - - - Check - 选中 - - - Toggle - 切换 - - - - QColorDialog - - Hu&e: - 色调(&E): - - - &Sat: - 饱和度(&S): - - - &Val: - 亮度(&V): - - - &Red: - 红色(&R): - - - &Green: - 绿色(&G): - - - Bl&ue: - 蓝色(&U): - - - A&lpha channel: - Alpha通道(&A): - - - Select Color - 选择颜色 - - - &Basic colors - 基本颜色(&B) - - - &Custom colors - 自定义颜色(&C) - - - &Add to Custom Colors - 添加到自定义颜色(&A) - - - Select color - 选择颜色 - - - - QComboBox - - Open - 打开 - - - False - - - - True - - - - Close - 关闭 - - - - QCoreApplication - - %1: permission denied - QSystemSemaphore - %1:权限被拒绝 - - - %1: already exists - QSystemSemaphore - %1:已经存在 - - - %1: doesn't exists - QSystemSemaphore - %1:不存在 - - - %1: out of resources - QSystemSemaphore - %1:资源耗尽了 - - - %1: unknown error %2 - QSystemSemaphore - %1:未知错误 %2 - - - %1: key is empty - QSystemSemaphore - %1:键是空的 - - - %1: unable to make key - QSystemSemaphore - %1:不能制造键 - - - %1: ftok failed - QSystemSemaphore - %1:ftok 失败 - - - - QDB2Driver - - Unable to connect - 不能连接 - - - Unable to commit transaction - 不能提交事务 - - - Unable to rollback transaction - 不能回滚事务 - - - Unable to set autocommit - 不能设置自动提交 - - - - QDB2Result - - Unable to execute statement - 不能执行语句 - - - Unable to prepare statement - 不能准备语句 - - - Unable to bind variable - 不能帮定变量 - - - Unable to fetch record %1 - 不能获取记录%1 - - - Unable to fetch next - 不能获取下一个 - - - Unable to fetch first - 不能获取第一个 - - - - QDateTimeEdit - - AM - AM - - - am - am - - - PM - PM - - - pm - pm - - - - QDial - - QDial - QDial - - - SpeedoMeter - SpeedoMeter - - - SliderHandle - SliderHandle - - - - QDialog - - What's This? - 这是什么? - - - Done - 完成 - - - - QDialogButtonBox - - OK - 确定 - - - Save - 保存 - - - &Save - 保存(&S) - - - Open - 打开 - - - Cancel - 取消 - - - &Cancel - 取消(&C) - - - Close - 关闭 - - - &Close - 关闭(&C) - - - Apply - 应用 - - - Reset - 重置 - - - Help - 帮助 - - - Don't Save - 不保存 - - - Discard - 抛弃 - - - &Yes - 是(&Y) - - - Yes to &All - 全部是(&A) - - - &No - 否(&N) - - - N&o to All - 全部否(&O) - - - Save All - 保存全部 - - - Abort - 放弃 - - - Retry - 重试 - - - Ignore - 忽略 - - - Restore Defaults - 恢复默认 - - - Close without Saving - 不保存关闭 - - - &OK - 确定(&O) - - - - QDirModel - - Name - 名称 - - - Size - 大小 - - - Kind - Match OS X Finder - 类型 - - - Type - All other platforms - 类型 - - - Date Modified - 日期被修改 - - - - QDockWidget - - Close - 关闭 - - - Dock - 锚接 - - - Float - 浮动 - - - - QDoubleSpinBox - - More - 更多 - - - Less - 更少 - - - - QErrorMessage - - Debug Message: - 调试消息: - - - Warning: - 警告: - - - Fatal Error: - 致命错误: - - - &Show this message again - 再次显示这个消息(&S) - - - &OK - 确定(&O) - - - - QFile - - Destination file exists - 目标文件已存在 - - - Cannot remove source file - - - - Cannot open %1 for input - 无法输入 %1 - - - Cannot open for output - 无法输出 - - - Failure to write block - 写块失败 - - - Cannot create %1 for output - 无法创建 %1 - - - - QFileDialog - - All Files (*) - 所有文件 (*) - - - Directories - 目录 - - - &Open - 打开(&O) - - - &Save - 保存(&S) - - - Open - 打开 - - - %1 already exists. -Do you want to replace it? - %1已经存在。 -你想要替换它么? - - - %1 -File not found. -Please verify the correct file name was given. - 文件%1 -没有找到。 -请核实已给定正确文件名。 - - - My Computer - 我的计算机 - - - &Rename - 重命名(&R) - - - &Delete - 删除(&D) - - - Show &hidden files - 显示隐藏文件(&H) - - - Back - 后退 - - - Parent Directory - 父目录 - - - List View - 列表视图 - - - Detail View - 详细视图 - - - Files of type: - 文件类型: - - - Directory: - 目录: - - - %1 -Directory not found. -Please verify the correct directory name was given. - 目录%1 -没有找到。 -请核实已给定正确目录名。 - - - '%1' is write protected. -Do you want to delete it anyway? - “%1“是写保护的。 -你还是想删除它么? - - - Are sure you want to delete '%1'? - 你确认你想删除“%1“? - - - Could not delete directory. - 不能删除目录。 - - - Recent Places - 最近的地方 - - - Save As - 另存为 - - - Drive - 驱动器 - - - File - 文件 - - - Unknown - 未知的 - - - Find Directory - 查找目录 - - - Show - 显示 - - - Forward - 前进 - - - New Folder - 新建文件夹 - - - &New Folder - 新建文件夹(&N) - - - &Choose - 选择(&C) - - - Remove - 移除 - - - File &name: - 文件名称(&N): - - - Look in: - 查看: - - - Create New Folder - 创建新文件夹 - - - All Files (*.*) - 所有文件 (*.*) - - - - QFileSystemModel - - %1 TB - %1 TB - - - %1 GB - %1 GB - - - %1 MB - %1 MB - - - %1 KB - %1千字节 - - - %1 bytes - %1字节 - - - Invalid filename - 无效文件名 - - - <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. - <b>名称“%1“不能被使用。</b><p>请使用另外一个包含更少字符或者不含有标点符号的名称。 - - - Name - 名称 - - - Size - 大小 - - - Kind - Match OS X Finder - 类型 - - - Type - All other platforms - 类型 - - - Date Modified - 日期被修改 - - - My Computer - 我的计算机 - - - Computer - 计算机 - - - - QFontDatabase - - Normal - 普通 - - - Bold - 粗体 - - - Demi Bold - 半粗体 - - - Black - 黑体 - - - Demi - 半体 - - - Light - 轻体 - - - Italic - 意大利体 - - - Oblique - 斜体 - - - Any - 任意 - - - Latin - 拉丁文 - - - Greek - 希腊文 - - - Cyrillic - 西里尔文 - - - Armenian - 亚美尼亚文 - - - Hebrew - 希伯来文 - - - Arabic - 阿拉伯文 - - - Syriac - 叙利亚文 - - - Thaana - 马尔代夫文 - - - Devanagari - 梵文 - - - Bengali - 孟加拉文 - - - Gurmukhi - 旁遮普文 - - - Gujarati - 古吉拉特文 - - - Oriya - 奥里雅文 - - - Tamil - 泰米尔文 - - - Telugu - 泰卢固文 - - - Kannada - 埃纳德文 - - - Malayalam - 马拉亚拉姆文 - - - Sinhala - 僧伽罗文 - - - Thai - 泰国文 - - - Lao - 老挝文 - - - Tibetan - 藏文 - - - Myanmar - 缅甸文 - - - Georgian - 格鲁吉亚文 - - - Khmer - 谷美尔文 - - - Simplified Chinese - 简体中文 - - - Traditional Chinese - 繁体中文 - - - Japanese - 日文 - - - Korean - 韩文 - - - Vietnamese - 越南文 - - - Symbol - 符号 - - - Ogham - 欧甘文 - - - Runic - 古北欧文 - - - - QFontDialog - - &Font - 字体(&F) - - - Font st&yle - 字体风格(&Y) - - - &Size - 大小(&S) - - - Effects - 效果 - - - Stri&keout - 删除线(&K) - - - &Underline - 下划线(&U) - - - Sample - 实例 - - - Wr&iting System - 书写系统(&I) - - - Select Font - 选择字体 - - - - QFtp - - Not connected - 没有连接 - - - Host %1 not found - 主机%1没有找到 - - - Connection refused to host %1 - 连接被主机 %1 拒绝 - - - Connection timed out to host %1 - 主机%1连接超时 - - - Connected to host %1 - 连接到主机%1了 - - - Connection refused for data connection - 因为数据连接而被拒绝连接 - - - Unknown error - 未知的错误 - - - Connecting to host failed: -%1 - 连接主机失败: -%1 - - - Login failed: -%1 - 登录失败: -%1 - - - Listing directory failed: -%1 - 列出目录失败: -%1 - - - Changing directory failed: -%1 - 改变目录失败: -%1 - - - Downloading file failed: -%1 - 下载文件失败: -%1 - - - Uploading file failed: -%1 - 上传文件失败: -%1 - - - Removing file failed: -%1 - 移除文件失败: -%1 - - - Creating directory failed: -%1 - 创建目录失败: -%1 - - - Removing directory failed: -%1 - 移除目录失败: -%1 - - - Connection closed - 连接关闭了 - - - Host %1 found - 主机%1找到了 - - - Connection to %1 closed - 到%1的连接关闭了 - - - Host found - 主机找到了 - - - Connected to host - 连接到主机了 - - - - QGuiApplication - - QT_LAYOUT_DIRECTION - Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. - LTR - - - - QHostInfo - - Unknown error - 未知的错误 - - - - QHostInfoAgent - - Host not found - 主机未找到 - - - Unknown address type - 未知的地址类型 - - - Unknown error - 未知的错误 - - - - QHttp - - Unknown error - 未知的错误 - - - Request aborted - 请求被放弃了 - - - No server set to connect to - 没有设置要连接的服务器 - - - Wrong content length - 错误的内容长度 - - - Server closed connection unexpectedly - 服务器异常地关闭了连接 - - - Unknown authentication method - - - - Error writing response to device - 向设备中进行写回复时发生错误 - - - Connection refused - 连接被拒绝 - - - Host %1 not found - 主机%1没有找到 - - - HTTP request failed - HTTP请求失败 - - - Invalid HTTP response header - 无效的HTTP响应头 - - - Invalid HTTP chunked body - 无效的HTTP臃肿体 - - - Host %1 found - 主机%1找到了 - - - Connected to host %1 - 连接到%1主机了 - - - Connection to %1 closed - 到%1的连接关闭了 - - - Host found - 主机找到了 - - - Connected to host - 连接到主机了 - - - Connection closed - 连接关闭了 - - - Proxy authentication required - 代理需要认证 - - - Authentication required - 需要认证 - - - Connection refused (or timed out) - 连接被拒绝(或者超时) - - - Proxy requires authentication - 代理需要验证 - - - Host requires authentication - 主机需要验证 - - - Data corrupted - 数据错误 - - - Unknown protocol specified - 所指定的协议是未知的 - - - SSL handshake failed - SSL 握手失败 - - - HTTPS connection requested but SSL support not compiled in - HTTPS 连接需要 SSL,但它没有被编译进来 - - - - QHttpSocketEngine - - Did not receive HTTP response from proxy - 未收到代理的HTTP响应 - - - Error parsing authentication request from proxy - 解析代理的认证请求出错 - - - Authentication required - 需要认证 - - - Proxy denied connection - 代理拒绝连接 - - - Error communicating with HTTP proxy - 和HTTP代理通讯时发生错误 - - - Proxy server not found - 未找到代理服务器 - - - Proxy connection refused - 代理连接被拒绝 - - - Proxy server connection timed out - 代理服务器连接超时 - - - Proxy connection closed prematurely - 代理连接过早关闭 - - - - QIBaseDriver - - Error opening database - 打开数据库错误 - - - Could not start transaction - 不能开始事务 - - - Unable to commit transaction - 不能提交事务 - - - Unable to rollback transaction - 不能回滚事务 - - - - QIBaseResult - - Unable to create BLOB - 不能创建BLOB - - - Unable to write BLOB - 不能写入BLOB - - - Unable to open BLOB - 不能打开BLOB - - - Unable to read BLOB - 不能读取BLOB - - - Could not find array - 不能找到数组 - - - Could not get array data - 不能得到数组数据 - - - Could not get query info - 不能得到查询信息 - - - Could not start transaction - 不能开始事务 - - - Unable to commit transaction - 不能提交事务 - - - Could not allocate statement - 不能分配语句 - - - Could not prepare statement - 不能准备语句 - - - Could not describe input statement - 不能描述输入语句 - - - Could not describe statement - 不能描述语句 - - - Unable to close statement - 不能关闭语句 - - - Unable to execute query - 不能执行查询 - - - Could not fetch next item - 不能获取下一项 - - - Could not get statement info - 不能得到语句信息 - - - - QIODevice - - Permission denied - 权限被拒绝 - - - Too many open files - 太多打开的文件 - - - No such file or directory - 没有这个文件或者目录 - - - No space left on device - 设备上没有空间了 - - - Unknown error - 未知的错误 - - - - QInputContext - - XIM - XIM - - - XIM input method - XIM输入法 - - - Windows input method - Windows输入法 - - - Mac OS X input method - Mac OS X输入法 - - - - QInputDialog - - Enter a value: - 输入一个值: - - - - QLibrary - - QLibrary::load_sys: Cannot load %1 (%2) - QLibrary::load_sys: 不能载入%1 (%2) - - - QLibrary::unload_sys: Cannot unload %1 (%2) - QLibrary::unload_sys:不能卸载%1 (%2) - - - QLibrary::resolve_sys: Symbol "%1" undefined in %2 (%3) - QLibrary::resolve_sys: 符号“%1”在%2(%3)没有被定义 - - - Could not mmap '%1': %2 - 不能映射”%1“:%2 - - - Plugin verification data mismatch in '%1' - “%1“中的插件验证数据不匹配 - - - Could not unmap '%1': %2 - 不能取消映射“%1“:%2 - - - The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] - 插件“%1”使用了不兼容的Qt库。(%2.%3.%4) [%5] - - - The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" - 插件“%1“使用了不兼容的Qt库。期待的构建键是“%2“,得到的却是”%3“ - - - Unknown error - 未知的错误 - - - The shared library was not found. - 共享库没有被找到。 - - - The file '%1' is not a valid Qt plugin. - 文件“%1“不是有效的Qt插件。 - - - The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) - 插件“%1“使用了不兼容的Qt库。(不能混合使用库的调试版本和发布版本。) - - - Cannot load library %1: %2 - 无法加载库%1:%2 - - - Cannot unload library %1: %2 - 无法卸载库%1:%2 - - - Cannot resolve symbol "%1" in %2: %3 - 无法解析%2中的符号“%1”:%3 - - - - QLineEdit - - &Undo - 撤消(&U) - - - &Redo - 恢复(&R) - - - Cu&t - 剪切(&T) - - - &Copy - 复制(&C) - - - &Paste - 粘贴(&P) - - - Delete - 删除 - - - Select All - 选择全部 - - - - QLocalServer - - %1: Name error - %1: 名称错误 - - - %1: Permission denied - %1:权限被拒绝 - - - %1: Address in use - %1:地址正在被使用 - - - %1: Unknown error %2 - %1:未知错误 %2 - - - - QLocalSocket - - %1: Connection refused - %1:连接被拒绝 - - - %1: Remote closed - %1:远程已关闭 - - - %1: Invalid name - %1:无效名称 - - - %1: Socket access error - %1:套接字访问错误 - - - %1: Socket resource error - %1:套接字资源错误 - - - %1: Socket operation timed out - %1:套接字操作超时 - - - %1: Datagram too large - %1:数据报太大 - - - %1: Connection error - %1:连接错误 - - - %1: The socket operation is not supported - %1:套接字操作不被支持 - - - %1: Unknown error - %1:未知错误 - - - %1: Unknown error %2 - %1:未知错误 %2 - - - - QMYSQLDriver - - Unable to open database ' - 不能打开数据库 - - - Unable to connect - 不能连接 - - - Unable to begin transaction - 不能开始事务 - - - Unable to commit transaction - 不能提交事务 - - - Unable to rollback transaction - 不能回滚事务 - - - - QMYSQLResult - - Unable to fetch data - 不能获取数据 - - - Unable to execute query - 不能执行查询 - - - Unable to store result - 不能存储结果 - - - Unable to prepare statement - 不能准备语句 - - - Unable to reset statement - 不能重置语句 - - - Unable to bind value - 不能绑定值 - - - Unable to execute statement - 不能执行语句 - - - Unable to bind outvalues - 不能绑定外值 - - - Unable to store statement results - 不能存储语句结果 - - - Unable to execute next query - 不能执行下一个查询 - - - Unable to store next result - 不能存储下一个结果 - - - - QMdiArea - - (Untitled) - (未命名的) - - - - QMdiSubWindow - - %1 - [%2] - %1 - [%2] - - - Close - 关闭 - - - Minimize - 最小化 - - - Restore Down - 向下恢复 - - - &Restore - 恢复(&R) - - - &Move - 移动(&M) - - - &Size - 大小(&S) - - - Mi&nimize - 最小化(&N) - - - Ma&ximize - 最大化(&X) - - - Stay on &Top - 总在最前(&T) - - - &Close - 关闭(&C) - - - - [%1] - - [%1] - - - Maximize - 最大化 - - - Unshade - 取消遮蔽 - - - Shade - 遮蔽 - - - Restore - 恢复 - - - Help - 帮助 - - - Menu - 菜单 - - - - QMenu - - Close - 关闭 - - - Open - 打开 - - - Execute - 执行 - - - - QMenuBar - - About - 关于 - - - Config - 配置 - - - Preference - 首选项 - - - Options - 选项 - - - Setting - 设置 - - - Setup - 安装 - - - Quit - 退出 - - - Exit - 退出 - - - About %1 - 关于%1 - - - About Qt - 关于Qt - - - Preferences - 首选项 - - - Quit %1 - 退出%1 - - - - QMessageBox - - Help - 帮助 - - - OK - 确定 - - - About Qt - 关于Qt - - - <p>This program uses Qt version %1.</p> - <p>这个程序使用的是Qt %1版。</p> - - - Show Details... - 显示细节…… - - - Hide Details... - 隐藏细节…… - - - <h3>About Qt</h3><p>This program uses Qt version %1.</p><p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://qt.nokia.com/products/licensing">qt.nokia.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> - <h3>关于Qt</h3>%1<p>Qt是一个用于跨平台应用程序开发的C++工具包。</p><p>对于MS&nbsp;Windows、Mac&nbsp;OS&nbsp;X、Linux和所有主流商业Unix,Qt提供了单一源程序的可移植性。Qt对于嵌入式平台也是可用的,在嵌入式平台上它被称为Qt Embedded。</p><p>Qt是Trolltech的产品。有关更多信息,请参考<a href="http://qt.nokia.com/">qt.nokia.com</a>。</p> - - - <h3>About Qt</h3>%1<p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is a Nokia product. See <a href="http://qt.nokia.com/">qt.nokiae.com</a> for more information.</p> - <h3>关于Qt</h3>%1<p>Qt是一个用于跨平台应用程序开发的C++工具包。</p><p>对于MS&nbsp;Windows、Mac&nbsp;OS&nbsp;X、Linux和所有主流商业Unix,Qt提供了单一源程序的可移植性。Qt也有用于嵌入式Linux和Windows CE的版本。</p><p>Qt是Nokia的产品。有关更多信息,请参考<a href="http://qt.nokia.com/">qt.nokia.com</a>。</p> - - - <p>This program uses Qt Open Source Edition version %1.</p><p>Qt Open Source Edition is intended for the development of Open Source applications. You need a commercial Qt license for development of proprietary (closed source) applications.</p><p>Please see <a href="http://qt.nokia.com/company/model/">qt.nokia.com/company/model/</a> for an overview of Qt licensing.</p> - <p>这个程序使用了Qt %1开源版本。</p><p>Qt开源版本只用于开源应用程序的开发。如果要开发私有(闭源)软件,你需要一个商业的Qt协议。</p><p>有关Qt协议的概览,请参考<a href="http://qt.nokia.com/company/model/">qt.nokia.com/company/model/</a>。</p> - - - <h3>About Qt</h3>%1<p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt Embedded.</p><p>Qt is a Trolltech product. See <a href="http://qt.nokia.com/">qt.nokia.com</a> for more information.</p> - <h3>关于Qt</h3>%1<p>Qt是一个用于跨平台应用程序开发的C++工具包。</p><p>对于MS&nbsp;Windows、Mac&nbsp;OS&nbsp;X、Linux和所有主流商业Unix,Qt提供了单一源程序的可移植性。Qt对于嵌入式平台也是可用的,在嵌入式平台上它被称为Qt Embedded。</p><p>Qt是Trolltech的产品。有关更多信息,请参考<a href="http://qt.nokia.com/">qt.nokia.com</a>。</p> - - - - QMultiInputContext - - Select IM - 选择输入法 - - - - QMultiInputContextPlugin - - Multiple input method switcher - 多输入法切换器 - - - Multiple input method switcher that uses the context menu of the text widgets - 使用文本窗口部件上下文菜单的多输入法切换器 - - - - QNativeSocketEngine - - The remote host closed the connection - 远端主机关闭了这个连接 - - - Network operation timed out - 网络操作超时 - - - Out of resources - 资源耗尽了 - - - Unsupported socket operation - 不被支持的套接字操作 - - - Protocol type not supported - 协议类型不被支持 - - - Invalid socket descriptor - 无效的套接字描述符 - - - Network unreachable - 网络不能访问 - - - Permission denied - 权限被拒绝 - - - Connection timed out - 连接超时 - - - Connection refused - 连接被拒绝 - - - The bound address is already in use - 要启用的地址已经被使用 - - - The address is not available - 这个地址不可用 - - - The address is protected - 这个地址被保护了 - - - Unable to send a message - 不能发送一个消息 - - - Unable to receive a message - 不能接收一个消息 - - - Unable to write - 不能写入 - - - Network error - 网络错误 - - - Another socket is already listening on the same port - 另一个套接字已经正在监听同一端口 - - - Unable to initialize non-blocking socket - 不能初始化非阻塞套接字 - - - Unable to initialize broadcast socket - 不能初始化广播套接字 - - - Attempt to use IPv6 socket on a platform with no IPv6 support - 试图在不支持IPv6支持的平台上使用IPv6套接字 - - - Host unreachable - 主机不能访问 - - - Datagram was too large to send - 不能发送过大的数据报 - - - Operation on non-socket - 对非套接字操作 - - - Unknown error - 未知的错误 - - - The proxy type is invalid for this operation - 对于这个操作代理类型是无效的。 - - - - QNetworkAccessCacheBackend - - Error opening %1 - 打开%1发生错误 - - - - QNetworkAccessFileBackend - - Request for opening non-local file %1 - 正在打开非本地文件 %1 的请求 - - - Error opening %1: %2 - 打开 %1 错误:%2 - - - Write error writing to %1: %2 - 写入 %1 错误:%2 - - - Cannot open %1: Path is a directory - 无法打开 %1:路径是一个目录 - - - Read error reading from %1: %2 - 读取 %1 错误:%2 - - - - QNetworkAccessFtpBackend - - No suitable proxy found - 未找到合适的代理 - - - Cannot open %1: is a directory - 无法读取 %1:是一个目录 - - - Logging in to %1 failed: authentication required - 登入 %1 失败:需要验证 - - - Error while downloading %1: %2 - 下载 %1 时错误:%2 - - - Error while uploading %1: %2 - 上载 %1 时错误:%2 - - - - QNetworkAccessHttpBackend - - No suitable proxy found - 未找到合适的代理 - - - - QNetworkReply - - Error downloading %1 - server replied: %2 - 下载 %1 错误 - 服务器回复:%2 - - - Protocol "%1" is unknown - 协议“%1”是未知的 - - - - QNetworkReplyImpl - - Operation canceled - 操作被取消 - - - - QOCIDriver - - Unable to logon - 不能登录 - - - Unable to initialize - QOCIDriver - 不能初始化 - - - Unable to begin transaction - 不能开始事务 - - - Unable to commit transaction - 不能提交事务 - - - Unable to rollback transaction - 不能回滚事务 - - - - QOCIResult - - Unable to bind column for batch execute - 不能绑定批处理执行的列 - - - Unable to execute batch statement - 不能执行批处理语句 - - - Unable to goto next - 不能进入下一个 - - - Unable to alloc statement - 不能分配语句 - - - Unable to prepare statement - 不能准备语句 - - - Unable to bind value - 不能绑定值 - - - Unable to execute select statement - 不能执行选择语句 - - - Unable to execute statement - 不能执行语句 - - - - QODBCDriver - - Unable to connect - 不能连接 - - - Unable to connect - Driver doesn't support all needed functionality - 不能连接—驱动程序不支持所有功能 - - - Unable to disable autocommit - 不能禁止自动提交 - - - Unable to commit transaction - 不能提交事务 - - - Unable to rollback transaction - 不能回滚事务 - - - Unable to enable autocommit - 不能打开自动提交 - - - - QODBCResult - - QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration - QODBCResult::reset: 不能把“SQL_CURSOR_STATIC”设置为语句属性。请检查你的ODBC驱动程序设置。 - - - Unable to execute statement - 不能执行语句 - - - Unable to fetch next - 不能获取下一个 - - - Unable to prepare statement - 不能准备语句 - - - Unable to bind variable - 不能帮定变量 - - - Unable to fetch last - 不能获取最后一个 - - - Unable to fetch - 不能获取 - - - Unable to fetch first - 不能获取第一个 - - - Unable to fetch previous - 不能获取上一个 - - - - QObject - - Home - - - - Operation not supported on %1 - 在 %1 上不被支持的操作 - - - Invalid URI: %1 - 无效的 URI:%1 - - - Write error writing to %1: %2 - 写入 %1 错误:%2 - - - Read error reading from %1: %2 - 读取 %1 错误:%2 - - - Socket error on %1: %2 - %1 上的套接字错误:%2 - - - Remote host closed the connection prematurely on %1 - 远程主机过早地关闭了在 %1 上的这个连接 - - - Protocol error: packet of size 0 received - 协议错误:收到了大小为 0 的包 - - - No host name given - 未指定主机名 - - - - QPPDOptionsModel - - Name - 名称 - - - Value - - - - - QPSQLDriver - - Unable to connect - 不能连接 - - - Could not begin transaction - 不能开始事务 - - - Could not commit transaction - 不能提交事务 - - - Could not rollback transaction - 不能回滚事务 - - - Unable to subscribe - 不能订阅 - - - Unable to unsubscribe - 不能取消订阅 - - - - QPSQLResult - - Unable to create query - 不能创建查询 - - - Unable to prepare statement - 不能准备语句 - - - - QPageSetupWidget - - Centimeters (cm) - 厘米 (cm) - - - Millimeters (mm) - 毫米 (mm) - - - Inches (in) - 英寸 (in) - - - Points (pt) - 点 (pt) - - - Form - 窗体 - - - Paper - 纸张 - - - Page size: - 纸张大小: - - - Width: - 宽度: - - - Height: - 高度: - - - Paper source: - 纸张源: - - - Orientation - 方向 - - - Portrait - 纵向 - - - Landscape - 横向 - - - Reverse landscape - 反向横向 - - - Reverse portrait - 反向纵向 - - - Margins - 边距 - - - top margin - 上边距 - - - left margin - 左边距 - - - right margin - 右边距 - - - bottom margin - 下边距 - - - - QPluginLoader - - Unknown error - 未知的错误 - - - The plugin was not loaded. - 插件没有被载入。 - - - - QPrintDialog - - locally connected - 本地已经连接的 - - - Aliases: %1 - 别名:%1 - - - unknown - 未知的 - - - Print all - 打印全部 - - - Print selection - 打印选择 - - - Print range - 打印范围 - - - A0 (841 x 1189 mm) - A0 (841 x 1189 毫米) - - - A1 (594 x 841 mm) - A1 (594 x 841 毫米) - - - A2 (420 x 594 mm) - A2 (420 x 594 毫米) - - - A3 (297 x 420 mm) - A3 (297 x 420 毫米) - - - A4 (210 x 297 mm, 8.26 x 11.7 inches) - A4 (210 x 297 毫米,8.26 x 11.7 英寸) - - - A5 (148 x 210 mm) - A5 (148 x 210 毫米) - - - A6 (105 x 148 mm) - A6 (105 x 148 毫米) - - - A7 (74 x 105 mm) - A7 (74 x 105 毫米) - - - A8 (52 x 74 mm) - A8 (52 x 74 毫米) - - - A9 (37 x 52 mm) - A9 (37 x 52 毫米) - - - B0 (1000 x 1414 mm) - B0 (1000 x 1414 毫米) - - - B1 (707 x 1000 mm) - B1 (707 x 1000 毫米) - - - B2 (500 x 707 mm) - B2 (500 x 707 毫米) - - - B3 (353 x 500 mm) - B3 (353 x 500 毫米) - - - B4 (250 x 353 mm) - B4 (250 x 353 毫米) - - - B5 (176 x 250 mm, 6.93 x 9.84 inches) - B5 (176 x 250 毫米,6.93 x 9.84 英寸) - - - B6 (125 x 176 mm) - B6 (125 x 176 毫米) - - - B7 (88 x 125 mm) - B7 (88 x 125 毫米) - - - B8 (62 x 88 mm) - B8 (62 x 88 毫米) - - - B9 (44 x 62 mm) - B9 (44 x 62 毫米) - - - B10 (31 x 44 mm) - B10 (31 x 44 毫米) - - - C5E (163 x 229 mm) - C5E (163 x 229 毫米) - - - DLE (110 x 220 mm) - DLE (110 x 220 毫米) - - - Executive (7.5 x 10 inches, 191 x 254 mm) - Executive (7.5 x 10 英寸,191 x 254 毫米) - - - Folio (210 x 330 mm) - Folio (210 x 330 毫米) - - - Ledger (432 x 279 mm) - Ledger (432 x 279 毫米) - - - Legal (8.5 x 14 inches, 216 x 356 mm) - Legal (8.5 x 14 英寸,216 x 356 毫米) - - - Letter (8.5 x 11 inches, 216 x 279 mm) - Letter (8.5 x 11 英寸,216 x 279 毫米) - - - Tabloid (279 x 432 mm) - Tabloid (279 x 432 毫米) - - - US Common #10 Envelope (105 x 241 mm) - 美国普通10号信封 (105 x 241 毫米) - - - OK - 确定 - - - Print - 打印 - - - Print To File ... - 打印到文件…… - - - File %1 is not writable. -Please choose a different file name. - 文件%1不可写。 -请选择一个不同的文件名。 - - - %1 already exists. -Do you want to overwrite it? - %1已经存在。 -你想覆盖它么? - - - File exists - 文件存在 - - - <qt>Do you want to overwrite it?</qt> - <qt>你想覆盖它么?</qt> - - - %1 is a directory. -Please choose a different file name. - %1是目录。 -请选择一个不同的文件名。 - - - The 'From' value cannot be greater than the 'To' value. - “从”的数值不能大于“到”的数值。 - - - A0 - A0 - - - A1 - A1 - - - A2 - A2 - - - A3 - A3 - - - A4 - A4 - - - A5 - A5 - - - A6 - A6 - - - A7 - A7 - - - A8 - A8 - - - A9 - A9 - - - B0 - B0 - - - B1 - B1 - - - B2 - B2 - - - B3 - B3 - - - B4 - B4 - - - B5 - B5 - - - B6 - B6 - - - B7 - B7 - - - B8 - B8 - - - B9 - B9 - - - B10 - B10 - - - C5E - C5E - - - DLE - DLE - - - Executive - 决策文书 - - - Folio - 对开纸 - - - Ledger - 帐页 - - - Legal - 法律文书 - - - Letter - 信纸 - - - Tabloid - 小型报纸 - - - US Common #10 Envelope - 美国普通10号信封 - - - Custom - 自定义 - - - &Options >> - 选项(&O) >> - - - &Print - 打印(&P) - - - &Options << - 选项(&O) << - - - Print to File (PDF) - 打印到文件(PDF) - - - Print to File (Postscript) - 打印到文件(Postscript) - - - Local file - 本地文件 - - - Write %1 file - 写入 %1 文件 - - - - QPrintPreviewDialog - - Page Setup - 页面设置 - - - %1% - %1% - - - Print Preview - 打印预览 - - - Next page - 下一页 - - - Previous page - 上一页 - - - First page - 第一页 - - - Last page - 最后一页 - - - Fit width - 适应宽度 - - - Fit page - 适应页面 - - - Zoom in - 放大 - - - Zoom out - 缩小 - - - Portrait - 纵向 - - - Landscape - 横向 - - - Show single page - 显示单页 - - - Show facing pages - 显示当前页 - - - Show overview of all pages - 显示所有页的概览 - - - Print - 打印 - - - Page setup - 打印设置 - - - Close - 关闭 - - - Export to PDF - 导出为PDF - - - Export to PostScript - 导出为PostScript - - - - QPrintPropertiesWidget - - Form - 窗体 - - - Page - - - - Advanced - 高级 - - - - QPrintSettingsOutput - - Form - 窗体 - - - Copies - 拷贝 - - - Print range - 打印范围 - - - Print all - 打印全部 - - - Pages from - 页数从 - - - to - - - - Selection - 选择 - - - Output Settings - 输出设置 - - - Copies: - 备份: - - - Collate - 校对 - - - Reverse - 反向 - - - Options - 选项 - - - Color Mode - 彩色模式 - - - Color - 彩色 - - - Grayscale - 灰度 - - - Duplex Printing - 两部分打印 - - - None - - - - Long side - 长侧 - - - Short side - 短侧 - - - - QPrintWidget - - Form - 窗体 - - - Printer - 打印机 - - - &Name: - 名称(&N): - - - P&roperties - 属性(&R) - - - Location: - 位置: - - - Preview - 预览 - - - Type: - 类型: - - - Output &file: - 输出文件(&F): - - - ... - ... - - - - QProcess - - Could not open input redirection for reading - 无法打开用于读取的输入重定向 - - - Could not open output redirection for writing - 无法打开用于写入的输出重定向 - - - Resource error (fork failure): %1 - 资源错误(fork失败):%1 - - - Process operation timed out - 进程处理超时 - - - Error reading from process - 从进程中读取时发生错误 - - - Error writing to process - 向进程写入时发生错误 - - - Process crashed - 进程已崩溃 - - - No program defined - - - - Process failed to start - 启动进程失败 - - - - QProgressDialog - - Cancel - 撤消 - - - - QPushButton - - Open - 打开 - - - - QRadioButton - - Check - 选中 - - - - QRegExp - - no error occurred - 没有错误发生 - - - disabled feature used - 使用了失效的特效 - - - bad char class syntax - 错误的字符类语法 - - - bad lookahead syntax - 错误的预测语法 - - - bad repetition syntax - 错误的重复语法 - - - invalid octal value - 无效的八进制数值 - - - missing left delim - 找不到左分隔符 - - - unexpected end - 意外的终止 - - - met internal limit - 遇到内部限制 - - - - QSQLite2Driver - - Error to open database - 打开数据库错误 - - - Unable to begin transaction - 不能开始事务 - - - Unable to commit transaction - 不能提交事务 - - - Unable to rollback Transaction - 不能回滚事务 - - - - QSQLite2Result - - Unable to fetch results - 不能获取结果 - - - Unable to execute statement - 不能执行语句 - - - - QSQLiteDriver - - Error opening database - 打开数据库错误 - - - Error closing database - 关闭数据库错误 - - - Unable to begin transaction - 不能开始事务 - - - Unable to commit transaction - 不能提交事务 - - - Unable to rollback transaction - 不能回滚事务 - - - - QSQLiteResult - - Unable to fetch row - 不能获取行 - - - Unable to execute statement - 不能执行语句 - - - Unable to reset statement - 不能重置语句 - - - Unable to bind parameters - 不能绑定参数 - - - Parameter count mismatch - 参数数量不匹配 - - - No query - 没有查询 - - - - QScrollBar - - Scroll here - 滚动到这里 - - - Left edge - 左边缘 - - - Top - 顶部 - - - Right edge - 右边缘 - - - Bottom - 底部 - - - Page left - 左一页 - - - Page up - 上一页 - - - Page right - 右一页 - - - Page down - 下一页 - - - Scroll left - 向左滚动 - - - Scroll up - 向上滚动 - - - Scroll right - 向右滚动 - - - Scroll down - 向下滚动 - - - Line up - 向上排列 - - - Position - 位置 - - - Line down - 向下排列 - - - - QSharedMemory - - %1: unable to set key on lock - %1:无法设置锁定的键 - - - %1: create size is less then 0 - %1:创建的大小小于 0 - - - %1: unable to lock - %1:无法锁定 - - - %1: unable to unlock - %1:无法取消锁定 - - - %1: permission denied - %1:权限被拒绝 - - - %1: already exists - %1:已经存在 - - - %1: doesn't exists - %1:不存在 - - - %1: out of resources - %1:资源耗尽了 - - - %1: unknown error %2 - %1:未知错误 %2 - - - %1: key is empty - %1:键是空的 - - - %1: unix key file doesn't exists - %1:Unix 键文件不存在 - - - %1: ftok failed - %1:ftok 失败 - - - %1: unable to make key - %1:不能制造键 - - - %1: system-imposed size restrictions - %1:系统预设大小限制 - - - %1: not attached - %1:没有附加 - - - %1: invalid size - %1:无效大小 - - - %1: key error - %1: 键错误 - - - %1: size query failed - %1:大小查询失败 - - - - QShortcut - - Space - 空格 - - - Esc - Esc - - - Tab - Tab - - - Backtab - Backtab - - - Backspace - Backspace - - - Return - Return - - - Enter - Enter - - - Ins - Ins - - - Del - Del - - - Pause - Pause - - - Print - Print - - - SysReq - SysReq - - - Home - Home - - - End - End - - - Left - Left - - - Up - Up - - - Right - Right - - - Down - Down - - - PgUp - PgUp - - - PgDown - PgDown - - - CapsLock - CapsLock - - - NumLock - NumLock - - - ScrollLock - ScrollLock - - - Menu - Menu - - - Help - Help - - - Back - 后退 - - - Forward - 前进 - - - Stop - 停止 - - - Refresh - 刷新 - - - Volume Down - 调小音量 - - - Volume Mute - 静音 - - - Volume Up - 调大音量 - - - Bass Boost - 低音增强 - - - Bass Up - 调大低音 - - - Bass Down - 调小低音 - - - Treble Up - 调大高音 - - - Treble Down - 调小高音 - - - Media Play - 多媒体播放 - - - Media Stop - 多媒体停止 - - - Media Previous - 上一个多媒体 - - - Media Next - 下一个多媒体 - - - Media Record - 多媒体记录 - - - Favorites - 最喜爱的 - - - Search - 搜索 - - - Standby - 等待 - - - Open URL - 打开URL - - - Launch Mail - 启动邮件 - - - Launch Media - 启动多媒体 - - - Launch (0) - 启动 (0) - - - Launch (1) - 启动 (1) - - - Launch (2) - 启动 (2) - - - Launch (3) - 启动 (3) - - - Launch (4) - 启动 (4) - - - Launch (5) - 启动 (5) - - - Launch (6) - 启动 (6) - - - Launch (7) - 启动 (7) - - - Launch (8) - 启动 (8) - - - Launch (9) - 启动 (9) - - - Launch (A) - 启动 (A) - - - Launch (B) - 启动 (B) - - - Launch (C) - 启动 (C) - - - Launch (D) - 启动 (D) - - - Launch (E) - 启动 (E) - - - Launch (F) - 启动 (F) - - - Print Screen - Print Screen - - - Page Up - Page Up - - - Page Down - Page Down - - - Caps Lock - Caps Lock - - - Num Lock - Num Lock - - - Number Lock - Number Lock - - - Scroll Lock - Scroll Lock - - - Insert - Insert - - - Delete - Delete - - - Escape - Escape - - - System Request - System Request - - - Select - 选择 - - - Yes - - - - No - - - - Context1 - 上下文1 - - - Context2 - 上下文2 - - - Context3 - 上下文3 - - - Context4 - 上下文4 - - - Call - 呼叫 - - - Hangup - 挂起 - - - Flip - 翻转 - - - Ctrl - Ctrl - - - Shift - Shift - - - Alt - Alt - - - Meta - Meta - - - + - + - - - F%1 - F%1 - - - Home Page - 主页 - - - - QSlider - - Page left - 左一页 - - - Page up - 上一页 - - - Position - 位置 - - - Page right - 右一页 - - - Page down - 下一页 - - - - QSocks5SocketEngine - - Connection to proxy refused - 代理拒绝连接 - - - Connection to proxy closed prematurely - 代理连接过早关闭 - - - Proxy host not found - 代理主机未找到 - - - Connection to proxy timed out - 代理连接超时 - - - Proxy authentication failed - 代理认证失败 - - - Proxy authentication failed: %1 - 代理认证失败: %1 - - - SOCKS version 5 protocol error - SOCKS版本5协议错误 - - - General SOCKSv5 server failure - 常规服务器失败 - - - Connection not allowed by SOCKSv5 server - 连接不被SOCKSv5服务器允许 - - - TTL expired - TTL已过期 - - - SOCKSv5 command not supported - 不支持的SOCKSv5命令 - - - Address type not supported - 不支持的地址类型 - - - Unknown SOCKSv5 proxy error code 0x%1 - 未知SOCKSv5代理,错误代码 0x%1 - - - Socks5 timeout error connecting to socks server - 连接到套接字服务器的时候,Socks5超时错误 - - - Network operation timed out - 网络操作超时 - - - - QSpinBox - - More - 更多 - - - Less - 更少 - - - - QSql - - Delete - 删除 - - - Delete this record? - 删除这条记录? - - - Yes - - - - No - - - - Insert - 插入 - - - Update - 更新 - - - Save edits? - 保存编辑? - - - Cancel - 取消 - - - Confirm - 确认 - - - Cancel your edits? - 取消您的编辑? - - - - QSslSocket - - Unable to write data: %1 - 不能写入数据:%1 - - - Error while reading: %1 - 读取时错误:%1 - - - Error during SSL handshake: %1 - SSL握手错误:%1 - - - Error creating SSL context (%1) - 创建SSL上下文错误(%1) - - - Invalid or empty cipher list (%1) - 无效或者空白的密码列表(%1) - - - Error creating SSL session, %1 - 创建SSL会话错误,%1 - - - Error creating SSL session: %1 - 创建SSL会话错误:%1 - - - Cannot provide a certificate with no key, %1 - 不能提供没有键的证书,%1 - - - Error loading local certificate, %1 - 不能载入本地证书,%1 - - - Error loading private key, %1 - 不能载入私有键,%1 - - - Private key does not certificate public key, %1 - 私有键不能验证公有键,%1 - - - - QSystemSemaphore - - %1: out of resources - %1:资源耗尽了 - - - %1: permission denied - %1:权限被拒绝 - - - %1: already exists - %1:已经存在 - - - %1: does not exist - %1:不存在 - - - %1: unknown error %2 - %1:未知错误 %2 - - - - QTDSDriver - - Unable to open connection - 不能打开连接 - - - Unable to use database - 不能使用数据库 - - - - QTabBar - - Scroll Left - 向左滚动 - - - Scroll Right - 向右滚动 - - - - QTcpServer - - Operation on socket is not supported - socket操作不被支持 - - - - QTextControl - - &Undo - 撤消(&U) - - - &Redo - 恢复(&R) - - - Cu&t - 剪切(&T) - - - &Copy - 复制(&C) - - - Copy &Link Location - 复制链接位置(&L) - - - &Paste - 粘贴(&P) - - - Delete - 删除 - - - Select All - 选择全部 - - - - QToolButton - - Press - 按下 - - - Open - 打开 - - - - QUdpSocket - - This platform does not support IPv6 - 这个平台不支持IPv6 - - - - QUndoGroup - - Undo - 撤销 - - - Redo - 恢复 - - - - QUndoModel - - <empty> - <空白> - - - - QUndoStack - - Undo - 撤销 - - - Redo - 恢复 - - - - QUnicodeControlCharacterMenu - - LRM Left-to-right mark - LRM 从左到右标记 - - - RLM Right-to-left mark - RLM 从右向左标记 - - - ZWJ Zero width joiner - ZWJ 零宽度连接器 - - - ZWNJ Zero width non-joiner - ZWNJ 零宽度非连接器 - - - ZWSP Zero width space - ZWSP 零宽度空格 - - - LRE Start of left-to-right embedding - LRE 开始从左到右嵌入 - - - RLE Start of right-to-left embedding - RLE 开始从右向左嵌入 - - - LRO Start of left-to-right override - LRO 开始从左向右覆盖 - - - RLO Start of right-to-left override - RLO 开始从右向左覆盖 - - - PDF Pop directional formatting - PDF 弹出方向格式 - - - Insert Unicode control character - 插入Unicode控制字符 - - - - QWebFrame - - Request cancelled - 请求被取消了 - - - Request blocked - 请求被阻塞了 - - - Cannot show URL - 无法显示 URL - - - Frame load interruped by policy change - 因为策略调整打断了桢的加载 - - - Cannot show mimetype - 无法显示 MIMETYPE - - - File does not exist - 文件不存在 - - - - QWebPage - - Bad HTTP request - 错误的 HTTP 请求 - - - Submit - default label for Submit buttons in forms on web pages - 提交 - - - Submit - Submit (input element) alt text for <input> elements with no alt, title, or value - 提交 - - - Reset - default label for Reset buttons in forms on web pages - 重置 - - - This is a searchable index. Enter search keywords: - text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' - 这是一个可以搜索的索引。请输入要搜索的关键字: - - - Choose File - title for file button used in HTML forms - 选择文件 - - - No file selected - text to display in file button used in HTML forms when no file is selected - 没有文件被选择 - - - Open in New Window - Open in New Window context menu item - 在新窗口中打开 - - - Save Link... - Download Linked File context menu item - 保存链接... - - - Copy Link - Copy Link context menu item - 复制链接 - - - Open Image - Open Image in New Window context menu item - 打开图片 - - - Save Image - Download Image context menu item - 保存图片 - - - Copy Image - Copy Link context menu item - 复制图片 - - - Open Frame - Open Frame in New Window context menu item - 打开框架 - - - Copy - Copy context menu item - 复制 - - - Go Back - Back context menu item - 后退 - - - Go Forward - Forward context menu item - 前进 - - - Stop - Stop context menu item - 停止 - - - Reload - Reload context menu item - 重新载入 - - - Cut - Cut context menu item - 剪切 - - - Paste - Paste context menu item - 粘贴 - - - No Guesses Found - No Guesses Found context menu item - 没有找到猜测 - - - Ignore - Ignore Spelling context menu item - 忽略 - - - Add To Dictionary - Learn Spelling context menu item - 添加到字典 - - - Search The Web - Search The Web context menu item - 搜索网页 - - - Look Up In Dictionary - Look Up in Dictionary context menu item - 在字典中查找 - - - Open Link - Open Link context menu item - 打开链接 - - - Ignore - Ignore Grammar context menu item - 忽略 - - - Spelling - Spelling and Grammar context sub-menu item - 拼写 - - - Show Spelling and Grammar - menu item title - 显示拼写和语法 - - - Hide Spelling and Grammar - menu item title - 隐藏拼写和语法 - - - Check Spelling - Check spelling context menu item - 检查拼写 - - - Check Spelling While Typing - Check spelling while typing context menu item - 在输入时检查拼写 - - - Check Grammar With Spelling - Check grammar with spelling context menu item - 检查语法和拼写 - - - Fonts - Font context sub-menu item - 字体 - - - Bold - Bold context menu item - 粗体 - - - Italic - Italic context menu item - 意大利体 - - - Underline - Underline context menu item - 下划线 - - - Outline - Outline context menu item - 轮廓 - - - Direction - Writing direction context sub-menu item - 方向 - - - Text Direction - Text direction context sub-menu item - 文本方向 - - - Default - Default writing direction context menu item - 默认 - - - LTR - Left to Right context menu item - LTR - - - RTL - Right to Left context menu item - RTL - - - Inspect - Inspect Element context menu item - 检查 - - - No recent searches - Label for only item in menu that appears when clicking on the search field image, when no searches have been performed - 没有最近的搜索 - - - Recent searches - label for first item in the menu that appears when clicking on the search field image, used as embedded menu title - 最近的搜索 - - - Clear recent searches - menu item in Recent Searches menu that empties menu's contents - 清除最近的搜索 - - - Unknown - Unknown filesize FTP directory listing item - 未知的 - - - %1 (%2x%3 pixels) - Title string for images - %1 (%2x%3 像素) - - - Web Inspector - %2 - 网页检查员 - %2 - - - Scroll here - 滚动到这里 - - - Left edge - 左边缘 - - - Top - 顶部 - - - Right edge - 右边缘 - - - Bottom - 底部 - - - Page left - 左一页 - - - Page up - 上一页 - - - Page right - 右一页 - - - Page down - 下一页 - - - Scroll left - 向左滚动 - - - Scroll up - 向上滚动 - - - Scroll right - 向右滚动 - - - Scroll down - 向下滚动 - - - %n file(s) - number of chosen file - - %n 个文件 - - - - JavaScript Alert - %1 - JavaScript警告 - %1 - - - JavaScript Confirm - %1 - JavaScript确认 - %1 - - - JavaScript Prompt - %1 - JavaScript提示 - %1 - - - Move the cursor to the next character - 移动光标到下一个字符 - - - Move the cursor to the previous character - 移动光标到上一个字符 - - - Move the cursor to the next word - 移动光标到下一个单词 - - - Move the cursor to the previous word - 移动光标到上一个单词 - - - Move the cursor to the next line - 移动光标到下一行 - - - Move the cursor to the previous line - 移动光标到上一行 - - - Move the cursor to the start of the line - 移动光标到行首 - - - Move the cursor to the end of the line - 移动光标到行尾 - - - Move the cursor to the start of the block - 移动光标到块首 - - - Move the cursor to the end of the block - 移动光标到块尾 - - - Move the cursor to the start of the document - 移动光标到文件开头 - - - Move the cursor to the end of the document - 移动光标到文件末尾 - - - Select all - - - - Select to the next character - 选中到下一个字符 - - - Select to the previous character - 选中到上一个字符 - - - Select to the next word - 选中到下一个单词 - - - Select to the previous word - 选中到上一个单词 - - - Select to the next line - 选中到下一行 - - - Select to the previous line - 选中到上一行 - - - Select to the start of the line - 选中到行首 - - - Select to the end of the line - 选中到行尾 - - - Select to the start of the block - 选中到块首 - - - Select to the end of the block - 选中到块尾 - - - Select to the start of the document - 选中到文件首 - - - Select to the end of the document - 选中到文件尾 - - - Delete to the start of the word - 删除到单词首 - - - Delete to the end of the word - 删除到单词尾 - - - Insert a new paragraph - - - - Insert a new line - - - - - QWhatsThisAction - - What's This? - 这是什么? - - - - QWidget - - * - * - - - - QWizard - - Go Back - 返回 - - - Continue - 继续 - - - Commit - 提交 - - - Done - 完成 - - - Quit - 退出 - - - Help - 帮助 - - - < &Back - < 上一步(&B) - - - &Finish - 完成(&F) - - - Cancel - 取消 - - - &Help - 帮助(&H) - - - &Next - 下一步(&N) - - - &Next > - 下一步(&N) > - - - - QWorkspace - - &Restore - 恢复(&R) - - - &Move - 移动(&M) - - - &Size - 大小(&S) - - - Mi&nimize - 最小化(&N) - - - Ma&ximize - 最大化(&X) - - - &Close - 关闭(&C) - - - Stay on &Top - 总在最前(&T) - - - Sh&ade - 卷起(&A) - - - %1 - [%2] - %1 - [%2] - - - Minimize - 最小化 - - - Restore Down - 恢复 - - - Close - 关闭 - - - &Unshade - 展开(&U) - - - - QXml - - no error occurred - 没有错误发生 - - - error triggered by consumer - 由消费者出发的错误 - - - unexpected end of file - 意外的文件终止 - - - more than one document type definition - 多于一个的文档类型定义 - - - error occurred while parsing element - 在解析元素的时候发生错误 - - - tag mismatch - 标记不匹配 - - - error occurred while parsing content - 在解析内容的时候发生错误 - - - unexpected character - 意外的字符 - - - invalid name for processing instruction - 无效的处理指令名称 - - - version expected while reading the XML declaration - 在读取XML声明的时候,版本被期待 - - - wrong value for standalone declaration - 错误的独立声明的值 - - - encoding declaration or standalone declaration expected while reading the XML declaration - 在读取XML声明的时候,编码声明或者独立声明被期待 - - - standalone declaration expected while reading the XML declaration - 在读取XML声明的时候,独立声明被期待 - - - error occurred while parsing document type definition - 在解析文档类型定义的时候发生错误 - - - letter is expected - 字符被期待 - - - error occurred while parsing comment - 在解析注释的时候发生错误 - - - error occurred while parsing reference - 在解析参考的时候发生错误 - - - internal general entity reference not allowed in DTD - 在DTD中不允许使用内部解析的通用实体参考 - - - external parsed general entity reference not allowed in attribute value - 在属性值中不允许使用外部解析的通用实体参考 - - - external parsed general entity reference not allowed in DTD - 在DTD中不允许使用外部解析的通用实体参考 - - - unparsed entity reference in wrong context - 没有解析的错误上下文中的实体参考 - - - recursive entities - 嵌套实体 - - - error in the text declaration of an external entity - 在一个外部实体的文本声明里有错误 - - - - QXmlStream - - Extra content at end of document. - 文档末尾有额外内容。 - - - Invalid entity value. - 无效的实体值。 - - - Invalid XML character. - 无效的XML字符。 - - - Sequence ']]>' not allowed in content. - 内容中不允许有“]]>“序列。 - - - Namespace prefix '%1' not declared - 命名空间的”%1“前缀没有被声明 - - - Attribute redefined. - 属性重复定义。 - - - Unexpected character '%1' in public id literal. - 在公有标识文本中有意外的字符”%1“。 - - - Invalid XML version string. - 无效的XML版本字符串。 - - - Unsupported XML version. - 不被支持的XML版本。 - - - %1 is an invalid encoding name. - %1是无效的编码名称。 - - - Encoding %1 is unsupported - 编码%1不被支持。 - - - Standalone accepts only yes or no. - 独立运行只允许是或者否。 - - - Invalid attribute in XML declaration. - 在XML声明中无效的属性。 - - - Premature end of document. - 文档过早的结束。 - - - Invalid document. - 无效的文档。 - - - Expected - 期待的 - - - , but got ' - ,但是得到的是“ - - - Unexpected ' - 意外的“ - - - Expected character data. - 期待的字符数据。 - - - Recursive entity detected. - 检测到嵌套实体。 - - - Start tag expected. - 开始期待的标记。 - - - XML declaration not at start of document. - XML声明没有在文档的开始位置。 - - - NDATA in parameter entity declaration. - 在参数实体声明中有NDATA。 - - - %1 is an invalid processing instruction name. - %1 是无效的处理指令名称。 - - - Invalid processing instruction name. - 无效的处理指令名称。 - - - Illegal namespace declaration. - 非法的命名空间声明。 - - - Invalid XML name. - 无效的XML名称。 - - - Opening and ending tag mismatch. - 开始标记和结束标记不匹配。 - - - Reference to unparsed entity '%1'. - 未解析实体“%1“的引用。 - - - Entity '%1' not declared. - 实体”%1“没有被声明。 - - - Reference to external entity '%1' in attribute value. - 在属性值中的外部实体“%1”的引用。 - - - Invalid character reference. - 无效的字符引用。 - - - Encountered incorrectly encoded content. - 遇到不正确的编码内容。 - - - The standalone pseudo attribute must appear after the encoding. - 独立运行伪属性必须出现在编码之后。 - - - %1 is an invalid PUBLIC identifier. - %1是一个无效的公有(PUBLIC)标识符。 - - - - QtXmlPatterns - - An %1-attribute with value %2 has already been declared. - 带有值 %2 的 %1 属性已经声明过了。 - - - An %1-attribute must have a valid %2 as value, which %3 isn't. - 一个 %1 属性必须带有一个有效的 %2 作为值,但 %3 却不是。 - - - Network timeout. - 网络超时。 - - - Element %1 can't be serialized because it appears outside the document element. - 元素 %1 不能被串行化,因为它出现在文档元素之外。 - - - Attribute element %1 can't be serialized because it appears at the top level. - 属性元素 %1 不能被串行化,因为它出现在最顶层。 - - - Year %1 is invalid because it begins with %2. - %1 年是无效的,因为应该从 %2 开始。 - - - Day %1 is outside the range %2..%3. - %1 日是在 %2...%3 范围之外的。 - - - Month %1 is outside the range %2..%3. - %1 月是在 %2...%3 范围之外的。 - - - Overflow: Can't represent date %1. - 溢出:无法呈现数据 %1。 - - - Day %1 is invalid for month %2. - %1 日对于 %2 月是无效的。 - - - Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; - 时间 24:%1:%2.%3 是无效的。小时是 24,但是分钟、秒和毫秒不全为 0; - - - Time %1:%2:%3.%4 is invalid. - 时间 %1:%2:%3.%4 是无效的。 - - - Overflow: Date can't be represented. - 溢出:数据无法被呈现。 - - - At least one component must be present. - 至少有一个组件被呈现。 - - - At least one time component must appear after the %1-delimiter. - 至少一个时间组件必须出现在这个 %1 界限之后。 - - - No operand in an integer division, %1, can be %2. - 在整数除法中没有操作数,%1,可以是 %2。 - - - The first operand in an integer division, %1, cannot be infinity (%2). - 除法中的第一个操作数,%1,不能是无穷(%2)。 - - - The second operand in a division, %1, cannot be zero (%2). - 除法中的第二个操作数,%1,不能是零(%2)。 - - - %1 is not a valid value of type %2. - %1 不是类型为 %2 的有效值。 - - - When casting to %1 from %2, the source value cannot be %3. - 当从 %2 抛出到 %1 时,源值不能是 %3。 - - - Integer division (%1) by zero (%2) is undefined. - 整数除法(%1)除零(%2)是未定义的。 - - - Division (%1) by zero (%2) is undefined. - 除法(%1)除零(%2)是未定义的。 - - - Modulus division (%1) by zero (%2) is undefined. - 求模除法(%1)除零(%2)是未定义的。 - - - Dividing a value of type %1 by %2 (not-a-number) is not allowed. - 一个类型为 %1 的值除以 %2(不是一个数值)是不允许的。 - - - Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. - 一个类型为 %1 的值除以 %2 或者 %3(正负零)是不允许的。 - - - Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. - 一个类型为 %1 的值乘以 %2 或者 %3(正负无穷)是不允许的。 - - - A value of type %1 cannot have an Effective Boolean Value. - 一个类型为 %1 的值不能是一个有效的布尔值(Effective Boolean Value)。 - - - Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. - 有效的布尔值(Effective Boolean Value)不能被用于计算一个包含两个或者更多原子值的序列。 - - - Value %1 of type %2 exceeds maximum (%3). - 类型为 %2 的值 %1 超过了最大值(%3)。 - - - Value %1 of type %2 is below minimum (%3). - 类型为 %2 的值 %1 超过了最小值(%3)。 - - - A value of type %1 must contain an even number of digits. The value %2 does not. - 类型为 %1 的值必须包含偶数个数字。值 %2 不是这样的。 - - - %1 is not valid as a value of type %2. - %1 不是类型为 %2 的有效值。 - - - Operator %1 cannot be used on type %2. - 操作符 %1 不能被用于类型 %2。 - - - Operator %1 cannot be used on atomic values of type %2 and %3. - 操作符 %1 不能被用于类型为 %2 和 %3 的原子值。 - - - The namespace URI in the name for a computed attribute cannot be %1. - 一个被计算的属性的名称中的命名空间 URI 不能是 %1。 - - - The name for a computed attribute cannot have the namespace URI %1 with the local name %2. - 一个被计算的属性的名称不能使用带有本地名称 %2 的命名空间 URI %1。 - - - Type error in cast, expected %1, received %2. - 抛出类型错误,期望的是 %1,收到的是 %2。 - - - When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. - 当抛出到 %1 或者它的派生类时,源类型必须是同一类型,或者它必须是一个字符串类型。类型 %2 是不被允许的。 - - - No casting is possible with %1 as the target type. - 无法以 %1 为目标类型进行抛出。 - - - It is not possible to cast from %1 to %2. - 无法从 %1 抛出到 %2。 - - - Casting to %1 is not possible because it is an abstract type, and can therefore never be instantiated. - 无法抛出到 %1,因为它是一个抽象类型,并且因此无法被实例化。 - - - It's not possible to cast the value %1 of type %2 to %3 - 无法从类型为 %2 的值 %1 抛出到 %3 - - - Failure when casting from %1 to %2: %3 - 从 %2 抛出到 %1 失败:%3 - - - A comment cannot contain %1 - 注释不能包含 %1 - - - A comment cannot end with a %1. - 注释不能以 %1 结尾。 - - - No comparisons can be done involving the type %1. - 对于类型 %1 不能进行比较。 - - - Operator %1 is not available between atomic values of type %2 and %3. - 在类型 %2 和 %3 的原子值之间,操作符 %1 是不可用的。 - - - An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. - 一个属性节点不能是一个文档节点的子节点。因此,这个属性 %1 所在位置是不合适的。 - - - A library module cannot be evaluated directly. It must be imported from a main module. - 一个库模块不能被直接评估。它必须从一个主模块中导入。 - - - No template by name %1 exists. - 没有名为 %1 的模板存在。 - - - A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. - 类型为 %1 的值不能被判断。一个判断必须是数值类型或者一个有效的布尔值(Effective Boolean Value)类型。 - - - A positional predicate must evaluate to a single numeric value. - 一个定位判断必须评估一个单一数值。 - - - The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, is %2 invalid. - 一个处理指令中的目标名称不能是任何大小写混合的 %1。因此,%2 是无效的。 - - - %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. - %1 不是处理指令的有效目标名称。它必须是值 %2,例如 %3。 - - - The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. - 一个路径中的最后一步必须包含节点或者原子值。它不能是两者的一个组合。 - - - The data of a processing instruction cannot contain the string %1 - 处理指令的数据不能包含字符串 %1 - - - No namespace binding exists for the prefix %1 - 对于前缀 %1,没有存在绑定的命名空间。 - - - No namespace binding exists for the prefix %1 in %2 - 对于 %2 中的前缀 %1,没有存在绑定的命名空间。 - - - %1 is an invalid %2 - %1 是一个无效的 %2。 - - - %1 takes at most %n argument(s). %2 is therefore invalid. - - %1 最多可以有 %n 个参数。因此 %2 是无效的。 - - - - %1 requires at least %n argument(s). %2 is therefore invalid. - - %1 需要至少 %n 个参数。因此 %2 是无效的。 - - - - The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. - %1 的第一个参数不能是类型 %2 的。它必须是数字类型的,xs:yearMonthDuration 或者 xs:dayTimeDuration。 - - - The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. - %1 的第一个参数不能是类型 %2 的。它必须是类型 %3、%4 或者 %5 的。 - - - The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. - %1 的第二个参数不能是类型 %2 的。它必须是类型 %3、%4 或者 %5 的。 - - - %1 is not a valid XML 1.0 character. - %1 不是一个有效的 XML 1.0 字符。 - - - The first argument to %1 cannot be of type %2. - %1 的第一个参数不能是类型 %2 的。 - - - If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. - 如果两个值都有区偏移(zone offset),它们必须拥有相同的区偏移。%1 和 %2 的区偏移是不同的。 - - - %1 was called. - %1 被调用了。 - - - %1 must be followed by %2 or %3, not at the end of the replacement string. - %1 必须被 %2 或者 %3 跟随,不能在替换字符串的末尾。 - - - In the replacement string, %1 must be followed by at least one digit when not escaped. - 在这个替换字符串中,%1 在没有被转义的时候必须被至少一个数字跟随。 - - - In the replacement string, %1 can only be used to escape itself or %2, not %3 - 在这个替换字符串中,%1 只能被用于转义它本身或者 %2,而不是 %3 - - - %1 matches newline characters - %1 匹配了换行符 - - - %1 and %2 match the start and end of a line. - %1 和 %2 匹配了一行的头和尾。 - - - Matches are case insensitive - 匹配是大小写不敏感的 - - - Whitespace characters are removed, except when they appear in character classes - 空白字符被移除了,除非当它们出现在字符类中 - - - %1 is an invalid regular expression pattern: %2 - %1 是正则表达式中的一个无效模式:%2 - - - %1 is an invalid flag for regular expressions. Valid flags are: - %1 是正则表达式中的一个无效标记。有效标记为: - - - If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. - 如果第一个参数是空序列或者零长度字符串(无命名空间),那么就不能指定前缀。前缀 %1 被指定了。 - - - It will not be possible to retrieve %1. - 将不能获取 %1。 - - - The root node of the second argument to function %1 must be a document node. %2 is not a document node. - 函数 %1 的第二个参数的根节点必须是一个文档节点。%2 不是一个文档节点。 - - - The default collection is undefined - 默认收集(collection)是未定义的 - - - %1 cannot be retrieved - 无法获取 %1 - - - The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). - 不支持正规化(normalization)表单 %1。被支持的表单是 %2、%3、%4 和 %5,以及无,例如空字符串(无正规化)。 - - - A zone offset must be in the range %1..%2 inclusive. %3 is out of range. - 区偏移(zone offset)必须在 %1...%2 范围之内。%3 是在范围之外的。 - - - %1 is not a whole number of minutes. - %1 不是分钟的整数。 - - - Required cardinality is %1; got cardinality %2. - 所需要的表间关系是 %1;得到的表间关系却是 %2。 - - - The item %1 did not match the required type %2. - 项 %1 和所需的类型 %2 不匹配。 - - - %1 is an unknown schema type. - %1 是一个未知的方案类型。 - - - Only one %1 declaration can occur in the query prolog. - 只有一个 %1 的声明可以出现在查询序言中。 - - - The initialization of variable %1 depends on itself - 变量 %1 的初始化依赖于它本身 - - - No variable by name %1 exists - 没有名称为 %1 的变量存在。 - - - The variable %1 is unused - 变量 %1 没有被使用 - - - Version %1 is not supported. The supported XQuery version is 1.0. - 不支持版本 %1。被支持的 XQuery 版本是 1.0。 - - - The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. - 编码方式 %1 是无效的。它必须只包含拉丁字符,必须不包含空白符号,并且必须和正则表达式 %2 匹配。 - - - No function with signature %1 is available - 没有签名为 %1 的可用函数。 - - - A default namespace declaration must occur before function, variable, and option declarations. - 默认命名空间声明必须出现在函数、变量和选项声明之前。 - - - Namespace declarations must occur before function, variable, and option declarations. - 命名空间声明必须出现在函数、变量和选项声明之前。 - - - Module imports must occur before function, variable, and option declarations. - 模块导入不能出现在函数、变量和选项声明之前。 - - - It is not possible to redeclare prefix %1. - 不能重复声明前缀 %1。 - - - Only the prefix %1 can be declared to bind the namespace %2. By default, it is already bound to the prefix %1. - 至于前缀 %1 可以被声明为和命名空间 %2 绑定。默认情况下,它已经被绑定到前缀 %1。 - - - Prefix %1 is already declared in the prolog. - 前缀 %1 在序言中已经声明过了。 - - - The name of an option must have a prefix. There is no default namespace for options. - 一个选项的名称必须带有前缀。对于选项没有默认命名空间。 - - - The Schema Import feature is not supported, and therefore %1 declarations cannot occur. - 不支持方案导入(Schema Import)特性,并且因此 %1 声明不能出现。 - - - The target namespace of a %1 cannot be empty. - %1 的目标命名空间不能为空。 - - - The module import feature is not supported - 不支持模块导入特性 - - - A variable by name %1 has already been declared in the prolog. - 名称为 %1 的变量已经在序言中声明过了。 - - - No value is available for the external variable by name %1. - 名称为 %1 的外部变量并没有可用的值。 - - - The namespace for a user defined function cannot be empty(try the predefined prefix %1 which exists for cases like this) - 用户定义的函数的命名空间不能为空(请试试预定义的前缀 %1,它就是用于这种情况的)。 - - - A construct was encountered which only is allowed in XQuery. - 遇到了一个只允许在XQuery中出现的构造。 - - - A template by name %1 has already been declared. - 模板%1已被声明 - - - The keyword %1 cannot occur with any other mode name. - 任何其他模式名称不能出现关键字%1。 - - - The value of attribute %1 must of type %2, which %3 isn't. - 属性%1的值必须是类型%2,但%3不是。 - - - The prefix %1 can not be bound. By default, it is already bound to the namespace %2. - 前缀%1不能被绑定。默认的,它已被绑定到名字空间%2。 - - - A variable by name %1 has already been declared. - 变量%1已被声明。 - - - A stylesheet function must have a prefixed name. - 样式表函数必须有一个前缀名。 - - - The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) - 用户定义函数的名字空间不能为空(试用为这种情况而存在的预定义前缀%1) - - - The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. - 命名空间 %1 是保留的;因此用户定义的函数不能使用它。请试试预定义的前缀 %2,它就是用于这种情况的。 - - - The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 - 用户在一个库模块中定义的函数的命名空间必须和这个模块的命名空间一致。也就是说,它应该是 %1,而不是 %2 - - - A function already exists with the signature %1. - 一个带有签名 %1 的函数已经存在。 - - - No external functions are supported. All supported functions can be used directly, without first declaring them as external - 不支持外部函数。所有支持的函数必须可以被直接使用,不能把它们声明为外部的 - - - An argument by name %1 has already been declared. Every argument name must be unique. - 名称为 %1 的参数已经被声明了。每个参数名称必须唯一。 - - - When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. - 当函数%1被用于样式匹配时,参数必须是变量参考或者字符串。 - - - In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. - 在XSL-T样式中,函数%1的第一个参数必须是字符串,以便用于匹配。 - - - In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. - 在XSL-T样式中,函数%1的第一个参数必须是文字或者变量参考,以便用于匹配。 - - - In an XSL-T pattern, function %1 cannot have a third argument. - 在XSL-T样式中,函数%1不能有第三个参数。 - - - In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. - 在XSL-T样式中,只用函数%1和%2可以用于匹配,%3不可以。 - - - In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. - 在XSL-T仰视中,不能使用%1轴,只能使用%2轴或者%3轴。 - - - %1 is an invalid template mode name. - %1不是一个合法的模板模式名称。 - - - The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. - 一个在 for 表达式中绑定的变量的名称必须和这个定位变量不同。因此,这两个名称为 %1 的变量冲突。 - - - The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. - 不支持方案验证特性(Schema Validation Feature)。因此,也许不能使用 %1 表达式。 - - - None of the pragma expressions are supported. Therefore, a fallback expression must be present - 不支持任何编译指示表达式(pragma expression)。因此,必须呈现一个回调表达式(fallback expression)。 - - - Each name of a template parameter must be unique; %1 is duplicated. - 每一个模板参数的名称都必须是唯一的;%2是重复的。 - - - The %1-axis is unsupported in XQuery - 这个 %1 轴在 XQuery 中是不被支持的。 - - - %1 is not a valid name for a processing-instruction. - %1不是一个处理指令的合法名称。 - - - %1 is not a valid numeric literal. - %1 不是一个有效的数字语义。 - - - No function by name %1 is available. - 没有名称为 %1 的可用函数。 - - - The namespace URI cannot be the empty string when binding to a prefix, %1. - 当这个命名空间 URI 被绑定到一个前缀 %1 时,它不能是空字符串。 - - - %1 is an invalid namespace URI. - %1 是一个无效的命名空间 URI。 - - - It is not possible to bind to the prefix %1 - 无法绑定到这个前缀 %1。 - - - Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). - 命名空间 %1 只能和 %2 绑定(并且如果是这种情况,需要提前声明)。 - - - Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). - 前缀 %1 只能和 %2 绑定(并且如果是这种情况,需要提前声明)。 - - - Two namespace declaration attributes have the same name: %1. - 两个命名空间声明属性使用了相同的名称:%1。 - - - The namespace URI must be a constant and cannot use enclosed expressions. - 命名空间 URI 必须是一个常量并且不能使用封闭的表达式。 - - - An attribute by name %1 has already appeared on this element. - 一个名称为 %1 的属性已经出现在这个元素中了。 - - - A direct element constructor is not well-formed. %1 is ended with %2. - 一个直接元素构造器没有很好地形成。%1 后面跟着 %2。 - - - The name %1 does not refer to any schema type. - 名称 %1 没有指向任何方案类型。 - - - %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. - %1 是一个复杂类型。无法抛出到复杂类型。因此,抛出到例如 %2 这样的原子类型是可以的。 - - - %1 is not an atomic type. Casting is only possible to atomic types. - %1 不是原子类型。只能抛出到原子类型。 - - - %1 is not a valid name for a processing-instruction. Therefore this name test will never match. - %1 不是处理指令的有效名称。因此这个名称测试永远不会匹配。 - - - %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. - %1 不是范围内属性声明。注意方案导入特性是不被支持的。 - - - The name of an extension expression must be in a namespace. - 一个扩展表达式的名称必须在一个命名空间中。 - - - empty - 空白 - - - zero or one - 零或者一 - - - exactly one - 确切地一 - - - one or more - 一或者更多 - - - zero or more - 零或者更多 - - - Required type is %1, but %2 was found. - 需要的类型是 %1,但是找到的是 %2。 - - - Promoting %1 to %2 may cause loss of precision. - 把 %1 升级为 %2 会导致精度的损失。 - - - The focus is undefined. - 焦点未定义。 - - - It's not possible to add attributes after any other kind of node. - 不能在任何其它类型节点后添加属性。 - - - An attribute by name %1 has already been created. - 一个名称为 %1 的属性已经被创建。 - - - Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. - 只支持 Unicode 代码点校验(Unicode Codepoint Collation)(%1)。%2 是不被支持的。 - - - Attribute %1 can't be serialized because it appears at the top level. - 属性 %1 不能被串行化,因为它出现在最顶层。 - - - %1 is an unsupported encoding. - %1 是不被支持的编码。 - - - %1 contains octets which are disallowed in the requested encoding %2. - %1包含了在请求编码%2中不允许的八进位值。 - - - The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. - 在使用编码%3的%2中出现的代码点%1不是一个有效的XML字符。 - - - Ambiguous rule match. - 含糊规则匹配。 - - - In a namespace constructor, the value for a namespace value cannot be an empty string. - 在一个命名空间构造中,命名空间的值不能为空字符串。 - - - In a namespace constructor, the value for a namespace cannot be an empty string. - - - - The prefix must be a valid %1, which %2 is not. - 前缀必须是有效的%1,而%2不是。 - - - The prefix %1 cannot be bound. - 前缀%1不能被绑定。 - - - Only the prefix %1 can be bound to %2 and vice versa. - 只有前缀%1可以绑定到%2,反之也一样 - - - Circularity detected - 检测到环 - - - The parameter %1 is required, but no corresponding %2 is supplied. - 需要参数%1,但是没有提供对应的%2。 - - - The parameter %1 is passed, but no corresponding %2 exists. - 参数%1已传递,但没有相应的%2存在。 - - - The URI cannot have a fragment - URI不能有片段 - - - Element %1 is not allowed at this location. - 元素%1不能在这个位置。 - - - Text nodes are not allowed at this location. - 文本节点不能在这个位置。 - - - Parse error: %1 - 解析错误:%1 - - - The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. - XSL-T版本属性的值必须是%1类型的值,而%2不是。 - - - Running an XSL-T 1.0 stylesheet with a 2.0 processor. - 在XSL-T 2.0处理器中运行一个1.0的样式表。 - - - Unknown XSL-T attribute %1. - 未知的XSL-T属性%1。 - - - Attribute %1 and %2 are mutually exclusive. - 属性%1和%2彼此互斥。 - - - In a simplified stylesheet module, attribute %1 must be present. - 在一个简化样式表模块中,属性%1必须存在。 - - - If element %1 has no attribute %2, it cannot have attribute %3 or %4. - 如果元素%1没有属性%2,那么它也不能有属性%3或者%4。 - - - Element %1 must have at least one of the attributes %2 or %3. - 元素%1必须至少有属性%2或者%3其中一个。 - - - At least one mode must be specified in the %1-attribute on element %2. - 在元素%2的%1属性中至少要指定一个模式。 - - - Attribute %1 cannot appear on the element %2. Only the standard attributes can appear. - 属性%1不能出现在元素%2上。只有标准属性可以出现。 - - - Attribute %1 cannot appear on the element %2. Only %3 is allowed, and the standard attributes. - 属性%1不能出现在元素%2上。只有%3和标准属性是允许的。 - - - Attribute %1 cannot appear on the element %2. Allowed is %3, %4, and the standard attributes. - 属性%1不能出现在元素%2上。只有%3、%4和标准属性是允许的。 - - - Attribute %1 cannot appear on the element %2. Allowed is %3, and the standard attributes. - 属性%1不能出现在元素%2上。只有%3和标准属性是允许的。 - - - XSL-T attributes on XSL-T elements must be in the null namespace, not in the XSL-T namespace which %1 is. - XSL-T元素中的XSL-T属性必须放在空(null)命名空间中,而不是在XSL-T命名空间中,%1却是这个样子。 - - - The attribute %1 must appear on element %2. - 属性%1必须出现在元素%2中。 - - - The element with local name %1 does not exist in XSL-T. - 有本地名称%1的元素在XSL-T中不存在。 - - - Element %1 must come last. - 元素%1必须最后出现。 - - - At least one %1-element must occur before %2. - 至少一个元素%1要出现在%2之前。 - - - Only one %1-element can appear. - 只能出现一个元素%1。 - - - At least one %1-element must occur inside %2. - 至少一个元素%1要出现在%2之内。 - - - When attribute %1 is present on %2, a sequence constructor cannot be used. - 当属性%1出现在%2中时,不能使用顺序构造。 - - - Element %1 must have either a %2-attribute or a sequence constructor. - 元素%1必须有在一个%2属性或者顺序构造。 - - - When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. - 当需要参数时,不能通过属性%1或者顺序构造提供默认值。 - - - Element %1 cannot have children. - 元素%1不能有子元素。 - - - Element %1 cannot have a sequence constructor. - 元素%1不能有顺序构造。 - - - The attribute %1 cannot appear on %2, when it is a child of %3. - 属性%1不能出现在%2中,因为它是%3的子元素。 - - - A parameter in a function cannot be declared to be a tunnel. - 函数内的参数不能被声明为通道(tunnel)。 - - - This processor is not Schema-aware and therefore %1 cannot be used. - 这个处理器不能感知Schema,因此%1不能被使用。 - - - Top level stylesheet elements must be in a non-null namespace, which %1 isn't. - 顶级样式表元素必须是在非空命名空间中的,而%1不是。 - - - The value for attribute %1 on element %2 must either be %3 or %4, not %5. - 元素%2中属性%1的值必须是%3或者%4,而不是%5。 - - - Attribute %1 cannot have the value %2. - 属性%1的值不能是%2。 - - - The attribute %1 can only appear on the first %2 element. - 属性%1只能出现在前%2个元素中。 - - - At least one %1 element must appear as child of %2. - %2必须至少又一个子元素%1。 - - - - VolumeSlider - - Muted - 已静音 - - - Volume: %1% - 音量:%1% - - - - WebCore::PlatformScrollbar - - Scroll here - 滚动到这里 - - - Left edge - 左边缘 - - - Top - 顶部 - - - Right edge - 右边缘 - - - Bottom - 底部 - - - Page left - 左一页 - - - Page up - 上一页 - - - Page right - 右一页 - - - Page down - 下一页 - - - Scroll left - 向左滚动 - - - Scroll up - 向上滚动 - - - Scroll right - 向右滚动 - - - Scroll down - 向下滚动 - - - diff --git a/src/translations/qwebengine_zh_CN.qm b/src/translations/qwebengine_zh_CN.qm deleted file mode 100644 index 6efc3afa..00000000 Binary files a/src/translations/qwebengine_zh_CN.qm and /dev/null differ diff --git a/src/translations/qwebengine_zh_CN.ts b/src/translations/qwebengine_zh_CN.ts deleted file mode 100644 index 3770fb5b..00000000 --- a/src/translations/qwebengine_zh_CN.ts +++ /dev/null @@ -1,159 +0,0 @@ - - - - - QWebEnginePage - - Back - 后退 - - - Forward - 前进 - - - Stop - 停止 - - - Reload - 重新加载 - - - Reload and Bypass Cache - 忽略缓存重新加载 - - - Cut - 剪切 - - - Copy - 复制 - - - Paste - 粘贴 - - - Undo - 撤销 - - - Redo - 恢复 - - - Select All - 选择全部 - - - Paste and Match Style - 粘贴并匹配样式 - - - Open Link in This Window - 在当前窗口打开链接 - - - Open Link in New Window - 在新窗口打开链接 - - - Open Link in New Tab - 在新标签页打开链接 - - - Open Link in New Background Tab - 在后台新标签页打开链接 - - - Copy Link URL - 复制链接地址 - - - Save Link - 保存链接 - - - Copy Image - 复制图片 - - - Copy Image URL - 复制图片地址 - - - Save Image - 保存图片 - - - Copy Media URL - 复制媒体地址 - - - Toggle Media Controls - 切换媒体控件 - - - Toggle Looping - 切换循环 - - - Toggle Play/Pause - 切换播放/暂停 - - - Toggle Mute - 切换静音 - - - Save Media - 保存媒体 - - - Inspect Element - 查看元素 - - - Exit Full Screen Mode - 退出全屏模式 - - - Close Page - 关闭页面 - - - Unselect - 取消选择 - - - Save &Page - 保存页面 (&P) - - - Are you sure you want to leave this page? - 确认离开本页面? - - - Follow Link - 打开链接 - - - &Back - 后退 (&B) - - - &Forward - 前进 (&F) - - - &Reload - 重新加载 (&R) - - - Select folder to upload - 选择文件夹上传 - - - diff --git a/src/translations/vnote_ja.qm b/src/translations/vnote_ja.qm deleted file mode 100644 index bf1b4f46..00000000 Binary files a/src/translations/vnote_ja.qm and /dev/null differ diff --git a/src/translations/vnote_ja.ts b/src/translations/vnote_ja.ts deleted file mode 100644 index 9fc1625b..00000000 --- a/src/translations/vnote_ja.ts +++ /dev/null @@ -1,8159 +0,0 @@ - - - - - QObject - - - All magic words: - 全てのマジックワード: - - - - Information - 情報 - - - - Please re-open current opened tabs to make it work. - 現在のタブを再開すると機能させることができます。 - - - - - Illegal name. Please try again: - 不正な名前。再実施してください: - - - - - Name already exists. Please try again: - 名前は既に使われています。再実施してください: - - - - Insert_Image_HERE - Insert_Image_HERE - - - - - - Insert Link - リンクの挿入。 - - - - - No match found - 一致するものが見つかりません - - - - - Match found: %1 of %2 - %2中%1この一致が見つかりました - - - - Replace %1 %2 - %1 %2を置換 - - - - occurences - 検索結果 - - - - occurence - 検索結果 - - - - Set base font point size %1 - 基本フォントサイズを %1 ポイントに設定 - - - - PlainText - 平文 - - - - Html - Html - - - - Invalid - 不正な - - - - QWebEnginePage - - - Save &Page - ページを保存(&P) - - - - &Back - 戻る(&B) - - - - &Forward - 勧む(&F) - - - - &Reload - 再読み込み(&R) - - - - VAttachmentList - - - Add - 追加 - - - - Clear - クリア - - - - - - - - - Warning - 警告 - - - - Are you sure to clear attachments of note <span style="%1">%2</span>? - ほんとうにノート<span style="%1">%2</span>の添付を削除してよいですか? - - - - <span style="%1">WARNING</span>: VNote will delete all the files in directory <span style="%2">%3</span>.Deleted files could be found in the recycle bin of this note.<br>The operation is IRREVERSIBLE! - <span style="%1">警告</span>:VNoteは、ディレクトリ<span style="%2">%3</span>内のすべてのファイルを削除します。削除したファイルはこのノートのゴミ箱にいきます。<br>操作は取消できません! - - - - Fail to clear attachments of note <span style="%1">%2</span>. - ノートの添付の削除に失敗<span style="%1">%2</span> - - - - - - Please check the attachments folder and maintain the configuration file manually. - 添付フォルダーをチェックして、設定ファイルの調整を手動でおこなってください。 - - - - Open Folder - フォルダを開く - - - - %1 %2 - %1 %2 - - - - Files - ファイル - - - - File - ファイル - - - - Select Files As Attachments - 添付するファイルを選択 - - - - Fail to add attachment %1 for note <span style="%2">%3</span>. - ノート<span style="%2">%3</span>の添付ファイル%1を追加できません。 - - - - %1 %2 added as attachments - %1 %2 は添付ファイルとして追加されました - - - - files - ファイル - - - - file - ファイル - - - - &Open - 開く(&O) - - - - Open current attachment file - 現在の添付ファイルを開く - - - - &Delete - 削除(&D) - - - - Delete selected attachments - 選択した添付ファイルを削除する - - - - &Sort - 整列(&S) - - - - Sort attachments manually - 添付ファイルを手動で整列 - - - - Copy File Path - ファイルパスをコピー - - - - &Info (Rename) %1 - 情報(名前変更)(&I) %1 - - - - View and edit current attachment's information - 添付ファイル情報の閲覧と編集 - - - - Are you sure to delete these attachments of note <span style="%1">%2</span>? - ほんとうにノート<span style="%1">%2</span>のこれらの添付を削除してよいですか? - - - - Deleted files could be found in the recycle bin of this note.<br>Click "Cancel" to leave them untouched. - 削除したファイルはこのノートのゴミ箱にいきます。<br>"キャンセル"をクリックすると、そのままにします。 - - - - - Confirm Deleting Attachments - 削除する添付ファイルの確認 - - - - - Fail to delete attachments of note <span style="%1">%2</span>. - ノート<span style="%1">%2</span>の添付の削除に失敗しました。 - - - - Sort Attachments - 添付の整列 - - - - Sort attachments of note <span style="%1">%2</span> in the configuration file. - 構成ファイル内のノート<span style="%1">%2</span>の添付ファイルをソートします。 - - - - Name - 名前 - - - - Fail to sort attachments of note <span style="%1">%2</span>. - ノート<span style="%1">%2</span>の添付のソートに失敗しました。 - - - - Rename Attachment - 添付ファイルの名前を変更 - - - - - Fail to rename attachment <span style="%1">%2</span>. - 添付ファイル<span style="%1">%2</span>の名前変更に失敗しました。 - - - - VNote detects that these attachments of note <span style="%1">%2</span> are missing in disk. Would you like to remove them from the note? - VNoteは、ノート <span style="%1">%2</span>の添付ファイルがディスク上に無いことにきづきました。ノートからこれらを削除しますか? - - - - Click "Cancel" to leave them untouched. - "キャンセル"をクリックすると、そのままにします。 - - - - - Attachment Information - 添付ファイル情報 - - - - Rename attachment (%1): - 添付ファイルの名前変更(%1): - - - - Attachment file path copied %1 - 添付ファイルパスがコピーされました%1 - - - - VCaptain - - - NavigationMode - ナビゲーションモード - - - - VCart - - - Clear - クリア - - - - Warning - 警告 - - - - Are you sure to clear Cart? - カートをクリアしますか? - - - - &Open - 開く(&O) - - - - Open selected notes - 選択されたノートを開く - - - - &Locate To Folder - フォルダへ移動(&L) - - - - Locate the folder of current note - 現在のノートのフォルダを指定します。 - - - - &Delete - 削除(&D) - - - - Delete selected items from Cart - カートから選択したアイテムを削除 - - - - &Sort - 整列(&S) - - - - Sort items in Cart - カートのアイテムをソート - - - - Sort Cart - カートのソート - - - - Sort items in Cart. - カートのアイテムをソートする。 - - - - Name - 名前 - - - - %1 %2 - %1 %2 - - - - Items - 項目 - - - - Item - 項目 - - - - VConfirmDeletionDialog - - - Do not ask for confirmation again - 今後、再確認しない。 - - - - %1/%2 Items - %1/%2アイテム - - - - VCopyTextAsHtmlDialog - - - Text: - テキスト: - - - - HTML: - HTML: - - - - Converting text to HTML ... - テキストをHTMlに変換... - - - - Copy Text As HTML (%1) - テキストをHTMlとしてコピー(%1) - - - - HTML has been copied. Will be closed in 3 seconds. - HTMLがコピーされました。3秒以内に閉じます。 - - - - VDeleteNotebookDialog - - - Are you sure to delete notebook <span style="%1">%2</span>? - ほんとうにノートブック <span style="%1">%2</span>を削除してよいですか? - - - - Delete files from disk - ディスクからファイルを削除 - - - - When checked, VNote will delete all files (including Recycle Bin) of this notebook from disk - チェックすると、VNoteは、ノートブックの(ゴミ箱を含め)全てのファイルをディスクから削除します。 - - - - VNote won't delete files in directory <span style="%1">%2</span>. - VNoteは、ディレクトリ <span style="%1">%2</span>のファイル削除をしません。 - - - - <span style="%1">WARNING</span>: VNote may delete <b>ANY</b> files in directory <span style="%2">%3</span> and directory <span style="%2">%4</span>!<br>VNote will try to delete all the root folders within this notebook one by one.<br>It may be UNRECOVERABLE! - <span style="%1">WARNING</span>: VNoteはディレクトリ<span style="%2">%3</span>およびディレクトリ<span style="%2">%4</span>の<b>あらゆる</b>ファイルを削除します。<br>VNoteはこのノートブック内のすべてのルートフォルダを一つずつ削除しようとします<br>復旧はできません! - - - - VDirInfoDialog - - - Folder &name: - フォルダ名(&N): - - - - Created time: - 作成日時: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>: 名前(大文字と小文字を区別しない)<span style="%2">%3</span>は既に存在しています。別の名前を選択してください。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>: 名前<span style="%2">%3</span>には、不正な文字が含まれています(マジックワード評価の後)。 - - - - VDirectory - - - Fail to open folder %1. - フォルダ%1を開くことができません。 - - - - %1 already exists in directory %2. - %1はすでにディレクトリ%2に存在します。 - - - - Fail to create folder in %1. - %1にフォルダを作成できません。 - - - - - - Fail to write configuration of folder %1. - フォルダ%1の構成を書き込めません。 - - - - Fail to delete the directory %1. - ディレクトリ%1の削除に失敗しました。 - - - - Fail to remove the folder from the folder configuration. - フォルダの設定からフォルダを削除できません。 - - - - Fail to open target folder. - ターゲットフォルダを開くことができません。 - - - - cut - 切り取り - - - - copy - コピー - - - - Fail to %1 the folder. - フォルダの%1に失敗しました。 - - - - Fail to add the folder to target folder's configuration. - フォルダをターゲットフォルダの設定に追加できません。 - - - - Skip file %1. - ファイル%1をスキップします。 - - - - Skip folder %1. - フォルダ%1をスキップします。 - - - - VDirectoryTree - - - - - - - - - - - - - - Warning - 警告 - - - - - Fail to open notebook <span style="%1">%2</span>. - ノートブック<span style="%1">%2</span>を開くことができません。 - - - - Please check if the notebook's root folder <span style="%1">%2</span> exists. - ノートブックのルートフォルダ<span style="%1">%2</span>が存在するかどうかを確認してください。 - - - - Fail to open folder <span style="%1">%2</span>. - フォルダ<span style="%1">%2</span>を開くことができません。 - - - - Please check if directory <span style="%1">%2</span> exists. - ディレクトリ<span style="%1">%2</span>が存在するかどうかを確認してください。 - - - - New &Root Folder - 新しいルートフォルダ(&R) - - - - Create a root folder in current notebook - 現在のノートブックにルートフォルダを作成する - - - - &Sort - 整列(&S) - - - - Sort folders in this folder/notebook manually - このフォルダ/ノートブック内のフォルダを手動で並べ替える - - - - New &Note - 新規ノート(&N) - - - - Create a note in selected folder - 選択したフォルダでノートを作成する - - - New &Subfolder - 新規フォルダ(&S) - - - - Create a subfolder - フォルダを作成する - - - - &Delete - 削除(&D) - - - - Delete selected folder - 選択したフォルダを削除 - - - - &Copy %1 - コピー(%1)(&P) - - - - Copy selected folders - 選択したフォルダをコピーする - - - - C&ut %1 - %1を切り取り(&u) - - - - Cut selected folders - 選択したフォルダを切り取り - - - - &Paste %1 - 貼り付け(%1)(&P) - - - - Paste folders in this folder - フォルダ内のフォルダを貼り付ける - - - - Reload From Disk - ディスクから再ロード - - - - Reload the content of this folder (or notebook) from disk - このフォルダ(またはノートブック)の内容をディスクから再ロードします。 - - - &Open Folder Location - フォルダの場所を開く(&O) - - - - New Si&bling Folder - - - - - Create a folder in the same parent folder - - - - - New Sub&folder - - - - - Open Folder &Location - - - - - Explore this folder in operating system - オペレーティング・システムでこのフォルダを表示します。 - - - - Pin To History - 履歴に固定 - - - - Pin selected folder to History - 選択したフォルダを履歴にピンで固定 - - - - &Info (Rename) %1 - 情報(名前変更)(&I) %1 - - - - View and edit current folder's information - 現在のフォルダの情報を表示および編集する - - - - Create a subfolder in <span style="%1">%2</span>. - <span style="%1">%2</span>にサブフォルダを作成します。 - - - - Create Folder - フォルダを作成 - - - - Fail to create subfolder <span style="%1">%2</span>. - サブフォルダ<span style="%1">%2</span>の作成に失敗しました。 - - - - Create a root folder in notebook <span style="%1">%2</span>. - ノートブック<span style="%1">%2</span>にルートフォルダを作成します。 - - - - Create Root Folder - ルートフォルダを作成 - - - - Fail to create root folder <span style="%1">%2</span>. - ルートフォルダ<span style="%1">%2</span>の作成に失敗しました。 - - - - Are you sure to delete folder <span style="%1">%2</span>? - フォルダ<span style="%1">%2</span>を削除してもよろしいですか? - - - - <span style="%1">WARNING</span>: VNote will delete the whole directory <span style="%2">%3</span>.Deleted files could be found in the recycle bin of this folder.<br>The operation is IRREVERSIBLE! - <span style="%1">警告</span>:VNoteは、ディレクトリ<span style="%2">%3</span>内のすべてのファイルを削除します。削除したファイルはこのフォルダのゴミ箱にいきます。<br>操作は取消できません! - - - - Fail to delete folder <span style="%1">%2</span>.<br>Please check <span style="%1">%3</span> and manually delete it. - フォルダ<span style="%1">%2</span>を削除できません。<br><span style="%1">%3</span>を確認して、手動で削除してください。 - - - - %1 %2 deleted - %1%2が削除されました - - - - - - folders - フォルダ - - - - - - - - folder - フォルダ - - - - Folder Information - フォルダ情報 - - - - Fail to rename folder <span style="%1">%2</span>. - フォルダ<span style="%1">%2</span>の名前変更に失敗しました。 - - - - Are you sure to reload folder <span style="%1">%2</span>? - フォルダ<span style="%1">%2</span>を再ロードしますか? - - - - Folder %1 reloaded from disk - フォルダ%1がディスクから再ロードされました - - - - Are you sure to reload notebook <span style="%1">%2</span>? - ノートブック<span style="%1">%2</span>を再ロードしますか? - - - - Notebook %1 reloaded from disk - ノートブック%1がディスクから再ロードされました - - - - Information - 情報 - - - - VNote will close all the related notes before reload. - VNoteは、リロードする前に関連するすべてのノートを閉じます。 - - - - Please check if path <span style="%1">%2</span> exists. - パス<span style="%1">%2</span>が存在するかどうかを確認してください。 - - - - %1 %2 %3 - %1 %2 %3 - - - - cut - 切り取り - - - - copied - コピーされた - - - - Fail to paste folder <span style="%1">%2</span>. - フォルダ<span style="%1">%2</span>の貼り付けに失敗しました。 - - - - VNote could not find this folder in any notebook. - このフォルダにはノートブックが見つかりませんでした。 - - - - Fail to copy folder <span style="%1">%2</span>. - フォルダ<span style="%1">%2</span>のコピーに失敗しました。 - - - - %1 %2 pasted - %1 %2貼り付けられました - - - - Sort Folders - フォルダの並べ替え - - - - Sort folders in %1 <span style="%2">%3</span> in the configuration file. - 構成ファイル内の%1<span style="%2">%3</span>のフォルダをソートします。 - - - - - notebook - ノートブック - - - - Name - 名前 - - - - Created Time - 作成日時間 - - - - Fail to sort folders in %1 <span style="%2">%3</span>. - %1<span style="%2">%3</span>内のフォルダを並べ替えることができません。 - - - - 1 folder pinned to History - 履歴に固定された1フォルダ - - - - Please drop it on a folder item. - フォルダにドラッグ&&ドロップしてください。 - - - - VEdit - - - Insert Link - リンクの挿入。 - - - - Found no match - 一致するものが見つかりません - - - - Found %1 %2 - %1 %2が見つかりました - - - - matches - 一致 - - - - match - 一致 - - - - Replace %1 %2 - %1 %2を置換 - - - - occurences - 検索結果 - - - - occurence - 検索結果 - - - - &Save Changes And Read - 変更を保存して読み込み(&S) - - - - Save changes and exit edit mode - 変更を保存して編集モードを終了する - - - - &Discard Changes And Read - 変更を破棄して読み込み(&D) - - - - Discard changes and exit edit mode - 変更を破棄して編集モードを終了する - - - - &Edit - 編集(&E) - - - - Edit current note - 現在のノートを編集 - - - - VEditArea - - - ActivateTab1 - ActivateTab1 - - - - ActivateTab2 - ActivateTab2 - - - - ActivateTab3 - ActivateTab3 - - - - ActivateTab4 - ActivateTab4 - - - - ActivateTab5 - ActivateTab5 - - - - ActivateTab6 - ActivateTab6 - - - - ActivateTab7 - ActivateTab7 - - - - ActivateTab8 - ActivateTab8 - - - - ActivateTab9 - ActivateTab9 - - - - AlternateTab - AlternateTab - - - - OpenedFileList - OpenedFileList - - - - ActivateSplitLeft - ActivateSplitLeft - - - - ActivateSplitRight - ActivateSplitRight - - - - MoveTabSplitLeft - MoveTabSplitLeft - - - - MoveTabSplitRight - MoveTabSplitRight - - - - ActivateNextTab - ActivateNextTab - - - - ActivatePreviousTab - ActivatePreviousTab - - - - VerticalSplit - VerticalSplit - - - - RemoveSplit - RemoveSplit - - - - MaximizeSplit - MaximizeSplit - - - - DistributeSplits - DistributeSplits - - - - MagicWord - MagicWord - - - - ApplySnippet - ApplySnippet - - - - LivePreview - LivePreview - - - - ExpandLivePreview - ExpandLivePreview - - - - ParseAndPaste - ParseAndPaste - - - - VEditSnippetDialog - - - None - なし - - - - String in the content to mark the cursor position - カーソル位置をマークするコンテンツ内の文字列 - - - - String in the content to be replaced with selected text - 選択されたテキストで置換されるコンテンツの文字列 - - - - Auto indent - 自動インデント - - - - Auto indent the content according to the first line - 最初の行に従ってコンテンツを自動インデントします。 - - - - Snippet &name: - スニペット名: - - - - Snippet &type: - スニペットタイプ(&T): - - - - Shortc&ut: - ショートカット(&U): - - - - Cursor &mark: - カーソルマーク(&M): - - - - &Selection mark: - 選択マーク(&S): - - - - &Content: - コンテンツ(&C): - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>: 名前(大文字と小文字を区別しない)<span style="%2">%3</span>は既に存在しています。別の名前を選択してください。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>: 名前<span style="%2">%3</span>には、不正な文字が含まれています(マジックワード評価の後)。 - - - - <span style="%1">WARNING</span>: Cursor mark <span style="%2">%3</span> occurs more than once in the content (after magic word evaluation). Please choose another mark. - <span style="%1">警告</span>:カーソル・マーク<span style="%2">%3</span>は、(マジック・ワード評価後)コンテンツ内で複数回発生します。別のマークを選んでください。 - - - - <span style="%1">WARNING</span>: Cursor mark <span style="%2">%3</span> conflicts with selection mark. Please choose another mark. - <span style="%1">警告</span>:カーソル・マーク<span style="%2">%3</span>は選択マークと競合します。別のマークを選んでください。 - - - - VEditTab - - - Information - 情報 - - - - Note <span style="%1">%2</span> has been modified by another program. - ノート<span style="%1">%2</span>が他のプログラムから変更されました。 - - - - Do you want to reload it? - 再ロードしますか? - - - - Warning - 警告 - - - - Fail to reload note <span style="%1">%2</span>. - ノート<span style="%1">%2</span>を再ロードできません。 - - - - Please check if file %1 exists. - ファイル%1が存在するかどうかを確認してください。 - - - - VEditWindow - - - Opened Notes List - 開いているノート一覧 - - - - Menu - メニュー - - - - Remove Split - 分割終了 - - - - Remove current split window - 現在の分割ウインドウを削除する - - - - &Recycle Bin - ごみ箱(&R) - - - - Open the recycle bin of this note - このノートのゴミ箱を開く - - - - Open Note Location - ノートの場所を開く - - - - Explore the folder containing this note in operating system - オペレーティング・システムでこのノートのあるフォルダを表示します。 - - - - Reload From Disk - ディスクから再ロード - - - - Reload the content of this note from disk - このノートの内容をディスクから再ロードします。 - - - - Add To Cart - カートに追加 - - - - Add this note to Cart for further processing - このノートをカートに追加して、さらに処理を行います。 - - - - 1 note added to Cart - カートに追加された1ノート - - - - Pin To History - 履歴に固定 - - - - Pin this note to History - このノートを履歴にピンで固定する - - - - 1 note pinned to History - 履歴に固定された1ノート - - - - Set As Quick Access - クイックアクセスとして設定する - - - - Set this note as quick access - このノートをクイックアクセスに設定します。 - - - - Quick access: %1 - クイックアクセス:%1 - - - - Note Info - ノート情報 - - - - View and edit information of the note - ノートの情報を表示および編集する - - - - Locate To Folder - フォルダを指定 - - - - Locate the folder of current note - 現在のノートのフォルダを指定します。 - - - - Move One Split Left - Move One Split Left - - - - Move current tab to the split on the left - 現在のタブを左側の分割ウインドウへ移動する - - - - Move One Split Right - Move One Split Right - - - - Move current tab to the split on the right - 現在のタブを右側の分割ウインドウへ移動する - - - - Close Tab - タブを閉じる - - - - Close current note tab - 現在のノートタブを閉じる - - - - Close Other Tabs - その他のタブを閉じる - - - - Close all other note tabs - 他のすべてのノートタブを閉じる - - - - Close Tabs To The Right - 右側のタブを閉じる - - - - Close all the note tabs to the right of current tab - 現在のタブの右側の全てのノートを閉じる。 - - - - Close All Tabs - すべてのタブを閉じる - - - - Close all the note tabs - すべてのノートタブを閉じる - - - - Split - 分割 - - - - Split current window vertically - 現在のウィンドウを縦に分割 - - - - Maximize Split - 分割の最大化 - - - - Maximize current split window - 現在の分割ウィンドウを最大化する - - - - Distribute Splits - 分割を整列する - - - - Distribute all the split windows evenly - 全ての分割ウインドウを平等に整列する。 - - - - VExplorer - - - Directory - ディレクトリ - - - - Open - 開く - - - - Select Root Directory To Explore - エクスプローラのルートディレクトリを選択 - - - - Up - - - - - Open Directory Location - ディレクトリの場所を開く - - - - - Star - スターをつける - - - - Path of the root directory to explore - 探索するルートディレクトリのパス - - - - Root path to explore - 探索するルートパス - - - - Image Folder - 画像フォルダ - - - - Use global configuration (%1) - グローバル構成を使用(%1) - - - - Set the path of the image folder to store images of files within the root directory. -If absolute path is used, VNote will not manage those images.(empty to use global configuration) - 画像フォルダのパスを設定して、ルートディレクトリ内のファイルの画像を保存します。 -絶対パスを使用した場合、VNoteはそれらのイメージを管理しません(グローバル構成を使用するには空にします)。 - - - - - - New File - 新規ファイル - - - - - - New Folder - 新規フォルダ - - - - Warning - 警告 - - - - Fail to open directory <span style="%1">%2</span>. - ディレクトリ<span style="%1">%2</span>を開くことができません。 - - - - Please check if the directory exists. - ディレクトリが存在するかどうかを確認してください。 - - - - Unstar - スターをはずす - - - - Set As Root - ルートに設定 - - - - Set current folder as the root directory to explore - 現在のフォルダを探索するルートディレクトリに設定する - - - - Open Folder Location - フォルダの場所を開く - - - - Explore this folder in operating system - オペレーティング・システムでこのフォルダを表示します。 - - - - - &Info (Rename) %1 - 情報(名前変更)(&I) %1 - - - - View and edit current folder's information - 現在のフォルダの情報を表示および編集する - - - - Open In Read Mode - 読み取りモードで開く - - - - Open selected files in read mode - 選択したファイルを読み取りモードで開く - - - - Open In Edit Mode - 編集モードで開く - - - - Open selected files in edit mode - 選択したファイルを編集モードで開く - - - - Open File Location - ファイルの場所を開く - - - - Explore the folder containing this file in operating system - オペレーティング・システムでこのファイルのあるフォルダを表示します。 - - - - Add To Cart - カートに追加 - - - - Add selected files to Cart for further processing - 後続処理のために、選択したフィアルをカートに追加します - - - - %1 %2 added to Cart - %1カートに%2が追加されました - - - - - files - ファイル - - - - - file - ファイル - - - - Pin To History - 履歴に固定 - - - - Pin selected files to History - 選択したファイルを履歴にピンで固定 - - - - %1 %2 pinned to History - %1 %2は履歴に固定されています - - - - View and edit current file's information - 現在のファイルの情報を表示および編集する - - - - File name (%1): - ファイル名(%1): - - - - Fail to create file <span style="%1">%2</span>. - ファイル<span style="%1">%2</span>の作成に失敗しました。 - - - - Folder name (%1): - フォルダ名(%1): - - - - Fail to create folder <span style="%1">%2</span>. - フォルダ<span style="%1">%2</span>の作成に失敗しました。 - - - - - File Information - ファイル情報 - - - - Rename file (%1): - ファイル名の変更(%1): - - - - Fail to rename file <span style="%1">%2</span>. - ファイル<span style="%1">%2</span>の名前変更に失敗しました。 - - - - VExportDialog - - - Choose notes to export - エクスポートするノートを選択 - - - - Choose target format to export as - エクスポートするターゲット・フォーマットを選択します。 - - - - Choose converter to render Markdown - Markdownをレンダリングするコンバーターを選択 - - - - Choose rendering background color for Markdown - Markdownの背景色のレンダリングを選択してください - - - - Choose rendering style for Markdown - Markdownのレンダリングスタイルを選択してください - - - - Choose rendering code block style for Markdown - Markdownのレンダリングコードブロックスタイルを選択してください - - - - - &Browse - ブラウズ(&B) - - - - Information - 情報 - - - - Advanced Settings - 詳細設定 - - - - Output logs will be shown here - 出力ログが表示されます。 - - - - - Export - エキスポート - - - - Open Directory - ディレクトリを開く - - - - Open output directory - 出力ディレクトリを開く - - - - Copy Content - コンテンツをコピー - - - - Copy the content of the exported file - エクスポートされたファイルの内容をコピーする - - - - Cancelling the export... - エクスポートをキャンセルしています... - - - - Copied content of file %1 - ファイル%1のコピーされたコンテンツ - - - - Fail to copy content of file %1 - ファイル%1のコンテンツをコピーできません - - - - Notes to export: - エクスポートするノート: - - - - Target format: - ターゲットフォーマット: - - - - Markdown renderer: - Markdownレンダラ: - - - - Markdown rendering background: - Markdownレンダリング背景: - - - - Markdown rendering style: - Markdownレンダリングスタイル: - - - - Markdown rendering code block style: - Markdownレンダリングのコードブロックスタイル: - - - - Output directory: - 出力ディレクトリ: - - - - Settings - 設定 - - - - Enable Table Of Contents - 目次を有効にする - - - - Add a table of contents to the document - ドキュメントに目次を追加する - - - - Use wkhtmltopdf - wkhtmltopdfを使用 - - - - Use wkhtmltopdf tool to generate PDF (wkhtmltopdf needed to be installed) - PDF (wkhtmltopdf のインストールが必要)生成にwkhtmltopdf ツールを使用する - - - - Download wkhtmltopdf - wkhtmltopdfをダウンロード - - - - Tell VNote where to find wkhtmltopdf tool - wkhtmltopdf ツールの場所をVNoteに指示する - - - - - - Empty to use the name of the first source file - 最初のソースファイルの名前をつかうには、空にします。 - - - - Title of the generated PDF file - 生成されたPDFファイルのタイトル - - - - Name of the generated PDF file - 生成されたPDFファイルの名前 - - - - Enable background - バックグラウンドを有効にする - - - - Enable background when printing - 印刷時にバックグラウンドを有効にする - - - - Append page number as footer - ページ番号をフッターとして追加する - - - - Additional global options passed to wkhtmltopdf - wkhtmltopdfに追加のグローバルオプションをわたす - - - - Use " to enclose options containing spaces - オプションの値に空白文字が含まれるときは、" で囲んでください。 - - - - Page layout: - ページレイアウト: - - - - wkhtmltopdf path: - wkhtmltopdf パス: - - - - Title: - タイトル: - - - - - Output file name: - 出力ファイル名: - - - - Page number: - ページ番号: - - - - Additional options: - 追加オプション: - - - - Embed CSS styles - 埋め込みCSSスタイル: - - - - Embed CSS styles in HTML file - HTMLファイルにCSSスタイルをうめこむ - - - - Embed images - 画像の埋め込み - - - - Embed images as data URI - 画像をデータURIとして埋め込み - - - - Complete page - 完全なページ - - - - Export the whole web page along with pictures which may not keep the HTML link structure of the original page - 元ページのHTMLリンク構造を保持しない可能性のある画像とともに、Webページ全体をエクスポートします。 - - - - MIME HTML - MIME HTML - - - - Export as a complete web page in MIME HTML format - MIME HTML形式での完全なWebページとしてのエクスポート - - - - Enable outline panel - アウトライン・パネルの有効化 - - - - Add an outline panel in HTML file - HTMLファイルにアウトライン・パネルを追加する - - - - Process subfolders - サブフォルダを処理する - - - - Process subfolders recursively - サブフォルダを再帰的に処理する - - - - Current Note (%1) - [現在のノート](%1) - - - - Current Folder (%1) - 現在のフォルダ(%1) - - - - Current Notebook (%1) - 現在のノートブック(%1) - - - - Cart (%1) - カート(%1) - - - - - Markdown - Markdown - - - - - HTML - HTML - - - - PDF - PDF - - - - PDF (All In One) - PDF(オールインワン) - - - - Custom - カスタム - - - - Hoedown - Hoedown - - - - Marked - Marked - - - - Markdown-it - Markdown-it - - - - Showdown - Showdown - - - - System - システム - - - - Transparent - 透明 - - - - None - なし - - - - Left - - - - - Center - 中心 - - - - Right - - - - - Fail to start wkhtmltopdf (%1). - wkhtmltopdf (%1)の実行に失敗しました。 - - - - wkhtmltopdf crashed (%1). - wkhtmltopdf がクラッシュ(%1)。 - - - - Use %1 (%2). - %1を使用する(%2) - - - - Export to %1. - %1にエクスポートします。 - - - - Invalid configurations for custom export. - カスタムエクスポートの設定が無効です。 - - - - User cancelled the export. Aborted! - ユーザーがエクスポートをキャンセルしました。中止しました! - - - - Warning - 警告 - - - - Errors found during export. - エクスポート中にエラーが検出されました。 - - - - %1 notes exported. - %1 個のノートが書き出されました。 - - - - Select Output Directory To Export To - エクスポート先の出力ディレクトリを選択 - - - - Executable (*.exe) - 実行可能ファイル(*.exe) - - - - Select wkhtmltopdf Executable - wkhtmltopdfの実行ファイルを選択 - - - - Exporting note %1. - ノート%1をエクスポートしています。 - - - - Fail to open folder %1. - フォルダ%1を開くことができません。 - - - - - - - - - - - Fail to create directory %1. - ディレクトリ%1の作成に失敗しました。 - - - - Fail to open notebook %1. - ノートブック%1を開くことができません。 - - - - Fail to open file %1. - ファイル%1を開くことができません。 - - - - Skip exporting non-Markdown file %1 as Markdown. - 非Markdownファイル%1の Markdown形式でのエクスポートをスキップします。 - - - - Fail to copy the note file %1. - ノートファイル%1のコピーに失敗しました。 - - - - Fail to copy images of note %1. - ノート%1の画像をコピーできません。 - - - - Fail to copy attachments folder %1 to %2. - 添付ファイルのフォルダ%1を%2にコピーできません。 - - - - - - - Note %1 exported to %2. - ノート%1は%2にエクスポートされました。 - - - - Skip exporting non-Markdown file %1 as PDF. - 非Markdownファイル%1のPDF形式でのエクスポートをスキップします。 - - - - - - Fail to export note %1. - ノート%1をエクスポートできません。 - - - - Skip exporting non-Markdown file %1 as HTML. - 非Markdownファイル%1のHTML形式でのエクスポートをスキップします。 - - - - Skip exporting non-Markdown file %1. - 非Markdownファイル%1のエクスポートをスキップします。 - - - - Portrait - 縦長書式 - - - - Landscape - 横長書式 - - - - - %1 notes exported to %2. - %1個のノートが、%2にエクスポートされました。 - - - - Fail to export %1 notes in one PDF. - %1 個のノートを一つのPDFへエキスポートするのに失敗しました。 - - - - Fail to export %1 notes in one. - %1 個のノートを一つにエキスポートするのに失敗しました。 - - - - Choose format of the input - 入力フォーマットを選択 - - - - Without the preceding dot - 先頭のドット文字なし - - - - Suffix of the output file without the preceding dot - 先頭のドット文字なしの出力ファイルの拡張子 - - - - <span><span style="font-weight:bold;">%0</span> for the input file; <span style="font-weight:bold;">%1</span> for the output file; <span style="font-weight:bold;">%2</span> for the rendering CSS style file; <span style="font-weight:bold;">%3</span> for the input file directory; <span style="font-weight:bold;">%4</span> for the rendering code block CSS style file.</span> - <span><span style="font-weight:bold;">%0</span> for the input file; <span style="font-weight:bold;">%1</span> for the output file; <span style="font-weight:bold;">%2</span> for the rendering CSS style file; <span style="font-weight:bold;">%3</span> for the input file directory; <span style="font-weight:bold;">%4</span> for the rendering code block CSS style file.</span> - - - - Enable All In One - オールインワンを有効にする - - - - Pass a list of input files to the custom command - カスタムコマンドへ入力ファイルのリストを渡す - - - - PDF-Like - PDF-Like - - - - Treat the exported file as PDF, such as wrapping line - 行の折り返しなどで、エクスポートしたファイルをPDFのように扱う - - - - - Separator to concatenate input files directories - 入力ファイルのディレクトリを連結する区切り文字 - - - - Name of the generated All-In-One file - 生成されるオールインワンファイルの名前 - - - - Custom command to be executed - 実行するカスタムコマンド - - - - Source format: - ソースのフォーマット: - - - - Output suffix: - 出力ファイルの拡張子: - - - - Input directories separator: - 入力ディレクトリ区切り文字: - - - - VExporter - - - Fail to start wkhtmltopdf (%1). - wkhtmltopdf (%1)の実行に失敗しました。 - - - - wkhtmltopdf crashed (%1). - wkhtmltopdf がクラッシュ(%1)。 - - - - Fail to start custom command (%1). - カスタムコマンド(%1)の実行に失敗しました。 - - - - Custom command crashed (%1). - カスタムコマンド(%1)がクラッシュしました。 - - - - QProcess error %1. - QProcessエラー %1 - - - - VFileInfoDialog - - - Will be assigned when adding attachments - 添付ファイルを追加するときに割り当てられる - - - - The folder to hold attachments of this note - このノートの添付ファイルを保持するフォルダ - - - - Last modified time within VNote - VNote内での最終更新日時 - - - - Tags of this note separated by , - カンマ(,)区切りの、このノートに付与するタグ - - - - Note &name: - ノート名(&N): - - - - File path: - ファイルパス: - - - - Attachment folder: - 添付ファイルフォルダ: - - - - Created time: - 作成日時: - - - - Modified time: - 修正された時刻: - - - - Tags: - タグ: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>: 名前(大文字と小文字を区別しない)<span style="%2">%3</span>は既に存在しています。別の名前を選択してください。 - - - - <span style="%1">WARNING</span>: Changing type of the note is not supported. Please use the same suffix as the old one. - <span style="%1">警告</span>:ノートのタイプ変更はサポートされません。。古いものと同じサフィックスを使ってください。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>: 名前<span style="%2">%3</span>には、不正な文字が含まれています(マジックワード評価の後)。 - - - - VFileList - - - Notes - ノート - - - - View - 表示 - - - - Split - 分割 - - - - %1 %2 added to Cart - %1カートに%2が追加されました - - - - - - - - notes - ノート - - - - - - - - note - ノート - - - - %1 %2 pinned to History - %1 %2は履歴に固定されています - - - - Quick access: %1 - クイックアクセス:%1 - - - - Note Information - ノート情報 - - - - - - - - - - Warning - 警告 - - - - Fail to rename note <span style="%1">%2</span>. - ノート<span style="%1">%2</span>の名前変更に失敗しました。 - - - - %1 - -Created Time: %2 -Modified Time: %3 - 作成された日時: %2 -修正された日時: %3 - - - - Create a note in <span style="%1">%2</span>. - <span style="%1">%2</span>にノートを作成します。 - - - - Note with name ending with "%1" will be treated as Markdown type. - "%1"でおわる名前のノートは、Markdownタイプとして扱われます。 - - - - Create Note - ノートを作成 - - - - Fail to create note <span style="%1">%2</span>. - ノート<span style="%1">%2</span>の作成に失敗しました。 - - - - Are you sure to delete these notes? - これらのノートを削除しますか? - - - - <span style="%1">WARNING</span>: VNote will delete notes as well as all their images and attachments managed by VNote. Deleted files could be found in the recycle bin of these notes.<br>Click "Cancel" to leave them untouched.<br>The operation is IRREVERSIBLE! - <span style="%1">警告</span>:VNoteは、VNoteが管理するすべての画像と添付ファイルをノートとともに削除します。削除したファイルはこれらのノートのゴミ箱にいきます。<br>"キャンセル"をクリックすると、そのままにします。<br>復旧はできません! - - - - Confirm Deleting Notes - 削除するノートの確認 - - - - Fail to delete note <span style="%1">%2</span>.<br>Please check <span style="%1">%3</span> and manually delete it. - ノート<span style="%1">%2</span>を削除できません。<br><span style="%1">%3</span>を確認して、手動で削除してください。 - - - - %1 %2 deleted - %1%2が削除されました - - - - &Open In Read Mode - 読み取りモードで開く(&O) - - - - Open current note in read mode - 現在のノートを読み取りモードで開く - - - - Open In &Edit Mode - 編集モードで開く(&E) - - - - Open current note in edit mode - 現在のノートを編集モードで開く - - - - &New Note - 新しいノート(&N) - - - - Create a note in current folder - 現在のフォルダにノートを作成する - - - - &Sort - 整列(&S) - - - - Sort notes in this folder manually - このフォルダ内のノートを手動で並べ替える - - - - &Delete - 削除(&D) - - - - Delete selected note - 選択されたノートを削除 - - - - &Copy %1 - コピー(%1)(&P) - - - - Copy selected notes - 選択されたノートをコピーする - - - - C&ut %1 - %1を切り取り(&u) - - - - Cut selected notes - 選択したノートを切り取る - - - - &Paste %1 - 貼り付け(%1)(&P) - - - - Paste notes in current folder - 現在のフォルダにノートを貼り付ける - - - &Open Note Location - ノートの場所を開く(&O) - - - - Explore the folder containing this note in operating system - オペレーティング・システムでこのノートのあるフォルダを表示します。 - - - Copy File Path - ファイルパスをコピー - - - - Open Note &Location - - - - - Copy File &Path - - - - - File path copied %1 - ファイルパスを、 %1 へコピー - - - - Add To Cart - カートに追加 - - - - Add selected notes to Cart for further processing - 追加処理のために、選択したノートをカートに追加します - - - - Pin To History - 履歴に固定 - - - - Pin selected notes to History - 選択したノートを履歴に固定します - - - - Set As Quick Access - クイックアクセスとして設定する - - - - Set current note as quick access - 現在のノートをクイックアクセスに設定します。 - - - - &Info (Rename) %1 - 情報(名前変更)(&I) %1 - - - - View and edit current note's information - 現在のノート情報を表示および編集する - - - - Skip importing non-exist file %1. - 存在しないファイル %1 のインポートをスキップします。 - - - - Skip importing file %1. A note with the same name (case-insensitive) in the same directory already exists. - ファイル %1 のインポートをスキップ同じ名前(大文字、小文字区別なし)のノートが同じディレクトリに既に存在しています。 - - - - Fail to copy file %1 as %2. - ファイル %1 の %2へのコピーに失敗 - - - - Fail to add the note %1 to target folder's configuration. - ノート %1 をターゲットフォルダの設定へ追加できません。 - - - - %1 %2 %3 - %1 %2 %3 - - - - cut - 切り取り - - - - copied - コピーされた - - - - Fail to paste note <span style="%1">%2</span>. - ノート<span style="%1">%2</span>の貼り付けに失敗しました。 - - - - VNote could not find this note in any notebook. - どのノートブックにも、このノートが見つかりません。 - - - - - Fail to copy note <span style="%1">%2</span>. - ノート<span style="%1">%2</span>のコピーに失敗しました。 - - - - VNote does not allow copy and paste notes with internal images in the same folder. - VNoteでは、同じフォルダ内の画像つきのノートを、コピー&ペーストすることはできません。 - - - - %1 %2 pasted - %1 %2貼り付けられました - - - - Sort Notes - ノートの整列 - - - - Sort notes in folder <span style="%1">%2</span> in the configuration file. - 構成ファイル内のフォルダ<span style="%1">%2</span>のノートを整列します。 - - - - Name - 名前 - - - - Created Time - 作成日時間 - - - - Modified Time - 修正日時 - - - - Fail to sort notes in folder <span style="%1">%2</span>. - フォルダ<span style="%1">%2</span>内のノートを並べ替えることができませんでした。 - - - - Open With - 指定して開く - - - - Open current note with %1 - 現在のノートを %1 を用いて開く - - - - System's Default Program - システム既定のプログラム - - - - Open current note with system's default program - 現在のノートをシステム既定のプログラムで開く - - - - - Add External Program - 外部プログラムを追加 - - - - Add external program - 外部プログラムを追加します - - - - %1 %2 - %1 %2 - - - - Items - 項目 - - - - Item - 項目 - - - - View By Configuration File - 構成ファイル毎の表示 - - - - View By Name - 名前順による表示 - - - - View By Name (Reverse) - 名前順による表示(逆順) - - - - View By Created Time - 作成日時順の表示 - - - - View By Created Time (Reverse) - 作成日時順の表示(逆順) - - - - View By Modified Time - 修正日時順の表示 - - - - View By Modified Time (Reverse) - 修正日時順の表示(逆順) - - - - VFindReplaceDialog - - - Find/Replace - 検索/置換 - - - - Find: - 検索: - - - - Enter text to search - 検索するテキストを入力してください - - - - Find &Next - 次を検索(&N) - - - - Find &Previous - 前を検索(&P) - - - - &Replace with: - 置換(&R): - - - - \1, \2 for back reference in regular expression - \1, \2 for back reference in regular expression - - - - Replace - 置換 - - - - Replace && Fin&d - Replace && Fin&d - - - - Replace A&ll - 全てを置換(&A) - - - - - &Advanced >>> - 詳細(&A)>>> - - - - &Case sensitive - 大文字と小文字を区別(&C) - - - - &Whole word only - 単語全体のみ(&W) - - - - Re&gular expression - 正規表現(&G) - - - - &Incremental search - インクリメンタル検索(&I) - - - - B&asic <<< - 基本&B) <<< - - - - VFixNotebookDialog - - - VNote could not find the root folder of notebook <span style="%1">%2</span>. Please specify the new path to the root folder if you moved it somewhere, or VNote will just remove this notebook. - Vnoteはノートブック<span style="%1">%2</span>のルートフォルダを見つけることができませんでした。ルートフォルダをどこかに移動した場合、またはVNoteでこのノートブックを削除した場合は、ルートフォルダへの新しいパスを指定してください。 - - - - &Browse - ブラウズ(&B) - - - - Use relative path - 相対パスを使用 - - - - Use relative path (to VNote's executable) in configuration file - 構成ファイル内で、(Vnoteの実行可能ファイルに対する)相対パスを使用します。 - - - - Notebook name: - ノートブック名: - - - - Notebook root folder: - ノートブックルートフォルダ: - - - - Fix Notebook - ノートブックの固定 - - - - Select Root Folder Of The Notebook - ノートブックのルートフォルダを選択 - - - - <span style="%1">WARNING</span>: The folder chosen is NOT a valid root folder of a notebook. - <span style="%1">警告</span>:選択されたフォルダは、ノートブックの有効なルートフォルダではありません。 - - - - <span style="%1">WARNING</span>: Please specify absolute path. - <span style="%1">警告</span>: 絶対パスを指定してください。 - - - - <span style="%1">WARNING</span>: The folder chosen has already been a root folder of existing notebook <span style="%2">%3</span> in VNote. - <span style="%1">警告</span>: 選択したフォルダは、VNoteで作成された既存のノートブック<span style="%2">%3</span>です。 - - - - <span style="%1">WARNING</span>: Please choose a folder in the same drive as <span style="%2">%3</span> when relative path is enabled. - <span style="%1">警告</span>: 相対パスが有効なときは、<span style="%2">%3</span>と同じドライブのフォルダを選択してください。 - - - - VGeneralTab - - - Choose the language of VNote interface - VNoteインタフェースの言語を選択します。 - - - - - System - システム - - - - System tray - システムトレイ - - - - Minimized to the system tray after closing VNote (not supported in macOS) - VNoteを閉じた後、システムトレイに最小化されます(macOSではサポートされていません)。 - - - - Path of file to quick access - ファイルのパスがすばやくアクセスできるようにする - - - - Set the path of a file to quick access (absolute or relative to configuration folder) - ファイルのパスをクイックアクセス(設定フォルダに対して絶対または相対)するように設定します。 - - - - - Browse - ブラウズ - - - - Select File To Quick Access - クイックアクセスにファイルを選択 - - - - Choose the keyboard layout mapping to use in shortcuts - ショートカットで使用するキーボードレイアウトマッピングを選択します。 - - - - Choose the OpenGL implementation to load (restart VNote to make it work) - ロードするOpenGLの実装を選択する(VNoteを動作させるために再起動します) - - - - Edit - 編集 - - - - Language: - 言語: - - - - Startup pages: - スタートアップページ: - - - - Quick access: - クイックアクセス: - - - - Keyboard layout mapping: - キーボードレイアウトのマッピング: - - - - OpenGL: - OpenGL: - - - - Restore tabs or open specific notes on startup - 起動時に、タブを復元するか、特定のノートを開く - - - - - None - なし - - - - Continue where you left off - 終了時の状態を継続 - - - - Open specific pages - 特定のページを開く - - - - Absolute path of the notes to open on startup (one note per line) - 起動時に開くノートの絶対パス(各行毎にノートのファイル名) - - - - Select files to add as startup pages - スタートアップページとして追加するファイルを選択してください - - - - Select Files As Startup Pages - スタートアップページとしてファイルを選択 - - - - DesktopOpenGL - DesktopOpenGL - - - - OpenGLES - OpenGLES - - - - SoftwareOpenGL - SoftwareOpenGL - - - - VHelpUE - - - View help information about Universal Entry - ユニバーサルエントリに関するヘルプ情報を表示する - - - - Esc or Ctrl+[: Hide Universal Entry - Esc or Ctrl+[: ユニバーサルエントリを隠す - - - - Ctrl+U: Clear the command input - Ctrl+U: コマンド入力をクリアします。 - - - - Ctrl+E: Clear the command input except the entry key - Ctrl+E: 入力キー以外のコマンド入力をクリアします。 - - - - Ctrl+F: Select the entry key to change - Ctrl+F: 変更するエントリキーを選択します。 - - - - Ctrl+D: Cancel the command - Ctrl+D:コマンドをキャンセルします。 - - - - Ctrl+J: Go to next item - Ctrl+J: 次の項目に移動します。 - - - - Ctrl+K: Go to previous item - Ctrl+K: 前の項目に移動します。 - - - - Ctrl+L: Go to current item's parent item - Ctrl+L: 現在の項目の親アイテムに移動します。 - - - - Ctrl+I: Expand/Collapse current item - Ctrl+I: 現在の項目の展開/折り畳み - - - - Ctrl+B: Expand/Collapse all items - Ctrl+B: 全ての項目の展開/折り畳み - - - - Ctrl+S: Sort items - Ctrl+S: 項目のソート - - - - Enter: Activate current item - Enter: 現在の項目をアクティブにします。 - - - - Ctrl+M: Browse current item folder or the folder containing current item - Ctrl+M: 現在の項目フォルダまたはその項目を含むフォルダを参照します。 - - - - Magic Switches: - マジックスイッチ: - - - - \c or \C: Case insensitive or sensitive - \c または \C: 大文字/小文字の区別の切り替え - - - - \r or \R: Disable or enable regular expression - \rまたは\R:正規表現を無効または有効にします。 - - - - \f or \F: Disable or enable fuzzy search - \fまたは\f:ファジー検索を無効または有効にします。 - - - - \w or \W: Disable or enable whole word only - \wまたは\W:単語全体を無効または有効にしますか? - - - - VHistoryList - - - Clear - クリア - - - - Warning - 警告 - - - - Are you sure to clear History? - 履歴をクリアしますか? - - - - Pinned - 固定 - - - - Today - 本日 - - - - Yesterday - 昨日 - - - - Last 7 Days - 過去7日間 - - - - Older - より古い - - - - &Open - 開く(&O) - - - - Open selected notes - 選択されたノートを開く - - - - &Locate To Folder - フォルダへ移動(&L) - - - - Locate the folder of current note - 現在のノートのフォルダを指定します。 - - - - Pin - ピン - - - - Pin selected notes in History - 履歴で選択されたノートをピンに固定する - - - - Unpin - 固定解除 - - - - Unpin selected notes in History - 履歴で選択されたノートをピン解除する - - - - Add To Cart - カートに追加 - - - - Add selected notes to Cart for further processing - 追加処理のために、選択したノートをカートに追加します - - - - %1 %2 added to Cart - %1カートに%2が追加されました - - - - notes - ノート - - - - note - ノート - - - - VHtmlTab - - - Information - 情報 - - - - Note <span style="%1">%2</span> has been modified. - ノート<span style="%1">%2</span>が変更されました。 - - - - Do you want to save your changes? - 変更を保存しますか? - - - - - - Warning - 警告 - - - - Could not modify a read-only note <span style="%1">%2</span>. - 読み取り専用のノート<span style="%1">%2</span>を変更できませんでした。 - - - - Please save your changes to other notes manually. - 手動で変更を他のノートとして保存してください。 - - - - - Fail to save note. - ノートを保存できません。 - - - - File <span style="%1">%2</span> being written has been removed. - 書き込み中のファイル<span style="%1">%2</span>は削除されました。 - - - - Fail to write to disk when saving a note. Please try it again. - ノートを保存するときにディスクへの書き込みに失敗しました。もう一度試してみてください。 - - - - VInsertImageDialog - - - &Browse - ブラウズ(&B) - - - - From: - From: - - - - Title: - タイトル: - - - - Scaling width: - スケール幅: - - - - Select The Image To Be Inserted - 挿入する画像を選択 - - - - Images (*.png *.xpm *.jpg *.bmp *.gif *.svg) - 画像(*.png*.xpm*.jpg*.bmp*.gif*.svg) - - - - VInsertLinkDialog - - - Absolute or relative path of the link - リンクの絶対パスまたは相対パス - - - - &Text: - テキスト(&T): - - - - &URL: - &URL: - - - - VInsertTableDialog - - - Number of rows of the table body - テーブル本体の行数 - - - - Number of columns of the table - テーブルの列数 - - - - None - なし - - - - Left - - - - - Center - 中心 - - - - Right - - - - - Row: - 行: - - - - Column: - 列: - - - - Alignment: - 整列: - - - - Insert Table - 表を挿入 - - - - VKeyboardLayoutMappingDialog - - - Manage keybaord layout mappings to used in shortcuts. - ショートカットで使用するキーバーレイアウトマッピングを管理します。 - - - - Double click an item to set mapping key. - アイテムをダブルクリックすると、マッピングキーが設定されます。 - - - - New Mapping - 新規マッピング - - - - Delete Mapping - マッピングを削除 - - - - Keyboard layout mapping: - キーボードレイアウトのマッピング: - - - - Name: - 名前: - - - - Key - キー - - - - New Key - 新規キー - - - - Mapping Information - マッピング情報 - - - - Keyboard Layout Mappings - キーボードレイアウトのマッピング - - - - - - - - Warning - 警告 - - - - Fail to add mapping <span style="%1">%2</span>. - マッピング<span style="%1">%2</span>の追加に失敗しました。 - - - - - - - Please check the configuration file and try again. - 構成ファイルを確認してからもう一度実行してください。 - - - - Are you sure to delete mapping <span style="%1">%2</span>? - マッピング<span style="%1">%2</span>?を削除してもよろしいですか? - - - - Fail to delete mapping <span style="%1">%2</span>. - マッピング<span style="%1">%2</span>の削除に失敗しました。 - - - - Fail to rename mapping <span style="%1">%2</span>. - マッピング<span style="%1">%2</span>の名前変更に失敗しました。 - - - - Fail to update mapping <span style="%1">%2</span>. - マッピング<span style="%1">%2</span>の更新に失敗しました。 - - - - Press key to set mapping - キーを押してマッピングを設定する - - - - VListFolderUE - - - List and search the folders and notes of current folder - カレントフォルダのフォルダやノートを一覧表示して検索します。 - - - - VListUE - - - List and search history - リストと検索履歴 - - - - Invalid ID %1 - 無効なID%1 - - - - History - 履歴 - - - - VLookTab - - - Icon size in pixel of tool bar (restart VNote to make it work) - ツールバーのピクセル単位のアイコンサイズ(動作するためにVNoteを再起動します) - - - - Tool bar icon size: - ツールバーのアイコンサイズ: - - - - VMainWindow - - - AttachmentList - AttachmentList - - - - LocateCurrentFile - LocateCurrentFile - - - - ExpandMode - ExpandMode - - - - CurrentNoteInfo - - - - - DiscardAndRead - DiscardAndRead - - - - ToolBar - ツールバー - - - - ToolsDock - ツールドック - - - - SearchDock - 検索ドック - - - - CloseNote - CloseNote - - - - ShortcutsHelp - ショートカットヘルプ - - - - FlushLogFile - FlushLogFile - - - - Export - エキスポート - - - - FocusEditArea - FocusEditArea - - - - Notebooks - ノートブック - - - - History - 履歴 - - - - Explorer - エキスプローラー - - - - Tags - タグ - - - - Folders - フォルダ - - - - View - 表示 - - - - Full Screen - フルスクリーン - - - - Full Screen %1 - フルスクリーン %1 - - - - Toggle full screen - 全画面表示切り替え - - - - Stay On Top - 最上面に維持 - - - - Toggle stay-on-top - 最上面に留まる - - - - Menu Bar - メニューバー - - - - Toggle menu bar - メニューバーの切り替え - - - - Expand Edit Area - 編集領域の拡大 - - - - Expand the edit area - 編集領域を拡大する - - - - Edit Toolbar - ツールバーを編集 - - - - Heading Sequence - 見出しシーケンス: - - - - Enable heading sequence in current note in edit mode - 編集モードで現在のノートの見出しシーケンスを有効にする - - - - Bold %1 - 太字 %1 - - - - Insert bold text or change selected text to bold - 太字のテキストを挿入するか、選択したテキストを太字に変更 - - - - Italic %1 - イタリック %1 - - - - Insert italic text or change selected text to italic - 斜体のテキストを挿入するか、選択されたテキストを斜体に変更します - - - - Strikethrough %1 - 取消線 %1 - - - - Insert strikethrough text or change selected text to strikethroughed - 取り消し線つきテキストを挿入するか、選択されたテキストを取り消し線つきに変更します - - - - Inline Code %1 - Inline Code %1 - - - - Insert inline-code text or change selected text to inline-coded - インライン・コードのテキストを挿入するか、選択されたテキストをインライン・コード化します。 - - - - Code Block %1 - コードブロック%1 - - - - Insert fenced code block text or wrap selected text into a fenced code block - 囲み付きコードブロックのテキストを挿入するか、選択されたテキストをフェンス付きコードブロックにラップします - - - - Table %1 - 表 %1 - - - - Insert a table - 表の挿入 - - - - Link %1 - リンク %1 - - - - Insert a link - リンクの挿入 - - - - Image %1 - 画像 %1 - - - - Insert an image from file or URL - ファイルまたはURLからイメージを挿入する - - - - Note Toolbar - ノート・ツールバー - - - - Attachments (drag files here to add attachments) - 添付ファイル(添付ファイルを追加するにはここにファイルをドラッグします) - - - - Flash Page - 一時メモ(FlasH) ページ - - - - Open the Flash Page to edit - 一時メモ (Flash) ページを開き、編集する - - - - Flash Page %1 - 一時メモ(Flash)ページ %1 - - - - Quick Access - クイックアクセス - - - - Open quick access note - クイックアクセスノートを開く - - - - Quick Access %1 - クイックアクセス %1 - - - - Universal Entry - ユニバーサルエントリ - - - - Activate Universal Entry - ユニバーサルエントリをアクティブにする - - - - Universal Entry %1 - ユニバーサルエントリ %1 - - - - Note - ノート - - - - Log In (Not Implemented Yet) - ログイン(まだ実装されていません) - - - - New Root Folder - 新しいルートフォルダ - - - - Create a root folder in current notebook - 現在のノートブックにルートフォルダを作成する - - - - New Note - 新規ノート - - - - Create a note in current folder - 現在のフォルダにノートを作成する - - - - New Note %1 - 新しいノート %1 - - - - Note Info - ノート情報 - - - - View and edit current note's information - 現在のノート情報を表示および編集する - - - - Delete Note - ノートを削除 - - - - Delete current note - 現在のノートを削除 - - - - Discard Changes And Read - 変更を破棄して読み取り - - - - Discard changes and exit edit mode - 変更を破棄して編集モードを終了する - - - - Save - 保存 - - - - Save changes to current note - 現在のノートへ変更を保存する - - - - Save %1 - %1を保存 - - - - &Help - ヘルプ(&H) - - - - View &Log - ログを表示(&L) - - - - View VNote's debug log (%1) - VNoteのデバッグログ(%1)を表示します。 - - - - &Shortcuts Help - ショートカットヘルプ(&S) - - - - View information about shortcut keys - ショートカットキーに関する情報を表示する - - - - &Markdown Guide - マークダウンガイド(&M) - - - - A quick guide of Markdown syntax - Mark down構文のクイック・ガイド - - - - &Documentation - ドキュメント(&D) - - - - View VNote's documentation - VNoteのドキュメントを表示する - - - - Do&nate - 寄付(&n) - - - - Donate to VNote or view the donate list - VNoteに寄付するか、寄付リストを表示する - - - - Check For &Updates - 更新を確認(&U) - - - - Check for updates of VNote - VNoteの更新を確認します - - - - Star VNote on &GitHub - &GitHubでVNoteにスターをつける - - - - Give a star to VNote on GitHub project - GitHubプロジェクトのVNoteにスターをつける - - - - &Feedback - フィードバック(&F) - - - - Open an issue on GitHub - GitHubで課題を開く - - - - &About VNote - VNoteについて(&A) - - - - View information about VNote - VNoteに関する情報を表示する - - - - About &Qt - Qtについて(&Q) - - - - View information about Qt - Qtに関する情報を表示する - - - - &Markdown - Markdown(&M) - - - - Constrain The Width Of Images - イメージの幅を制限する - - - - Constrain the width of images to the window in read mode (re-open current tabs to make it work) - 読み取りモードで画像表示をウィンドウ幅に制限します(現在のタブを再開して有効にします)。 - - - - Enable Image Caption - イメージキャプションを有効にする - - - - Center the images and display the alt text as caption (re-open current tabs to make it work) - イメージを中央に配置し、代替テキストを表示します(現在のタブを再開して有効にします)。 - - - - Highlight Code Blocks In Edit Mode - 編集モードでコードブロックを強調表示する - - - - Enable syntax highlight within code blocks in edit mode - 編集モードのコードブロック内で構文の強調表示を有効にする - - - - Display Line Number In Code Blocks - コードブロック内のライン番号を表示する - - - - Enable line number in code blocks in read mode - 読み取りモードでのコードブロック内のライン番号を有効にする - - - - In-Place Preview - インプレイスプレビュー - - - - Enable in-place preview (images, diagrams, and formulas) in edit mode (re-open current tabs to make it work) - 編集モードでインプレイスプレビュー(イメージ、図、数式)を有効にする(現在のタブを再開して機能させる) - - - - Constrain The Width Of In-Place Preview - インプレイスプレビューの幅を制約する - - - - Constrain the width of in-place preview to the edit window in edit mode - 編集モードでインプレイスプレビューの幅を編集ウィンドウに制約する - - - - &View - 表示(&V) - - - - Tool Bar - ツールバー - - - - Toogle the tool bar - ツールバー表示/非表示 - - - - &File - ファイル(&F) - - - - &Open - 開く(&O) - - - - Open external file to edit - 編集する外部ファイルを開く - - - - Select External Files To Open - 外部ファイルを選択して開く - - - - &New Notes From Files - ファイルから新しいノートを作成(&N) - - - - Create notes from external files in current folder (will copy files if they do not locate in current folder) - 現在のフォルダにある外部ファイルからノートを作成します(現在のフォルダに見つからない場合は、ファイルをコピーします)。 - - - - E&xport - エキスポート(&X) - - - - Export notes - ノートをエクスポートする - - - - &Print - 印刷(&P) - - - - Print current note - 現在のノートを印刷する - - - - &Settings - 設定(&S) - - - - View and change settings for VNote - VNoteの設定の表示および変更をする - - - - Open Configuration Folder - 設定フォルダを開く - - - - Open configuration folder of VNote - VNoteの設定フォルダを開く - - - - - Customize Shortcuts - ショートカットのカスタマイズ - - - - Customize some standard shortcuts - 一部の標準ショートカットをカスタマイズする - - - - Restart - 再起動 - - - - &Quit - 終了(&Q) - - - - Quit VNote - VNoteを終了 - - - - &Edit - 編集(&E) - - - - - Find/Replace - 検索/置換 - - - - Open Find/Replace dialog to search in current note - [検索/置換]ダイアログを開き、現在のノートを検索します。 - - - - Advanced Find - 高度な検索 - - - - Advanced find within VNote - VNote内の高度な検索 - - - - Find Next - 次を検索 - - - - Find next occurence - 次を検索 - - - - Find Previous - 前を検索 - - - - Find previous occurence - 前を検索 - - - - Replace - 置換 - - - - Replace current occurence - 現在のヒットを置換 - - - - Replace && Find - 検索と置換 - - - - Replace current occurence and find the next one - 現在の検索位置を置換し、次を検索します - - - - Replace All - すべて置換 - - - - Replace all occurences in current note - 現在のノートのすべてのヒットを置換する - - - - Highlight Searched Pattern - 検索されたパターンを強調表示 - - - - Highlight all occurences of searched pattern - 検索されたパターンのすべての出現を強調表示する - - - - &Expand Tab - タブを展開(&E) - - - - Expand entered Tab to spaces - 入力されたタブをスペースに展開 - - - - 2 Spaces - 2つのスペース - - - - Expand Tab to 2 spaces - タブを2つのスペースに展開 - - - - 4 Spaces - 4つのスペース - - - - Expand Tab to 4 spaces - タブを4つのスペースに展開 - - - - 8 Spaces - 8つのスペース - - - - Expand Tab to 8 spaces - タブを8つのスペースに展開 - - - - Auto Indent - 自動インデント - - - - Indent automatically when inserting a new line - 新しい行を挿入するときに自動的にインデントする - - - - Auto List - 自動リスト - - - - Continue the list automatically when inserting a new line - 新しい行を挿入するときに、リストを自動的に続行する - - - - Highlight Cursor Line - カーソル行を強調表示 - - - - Highlight current cursor line - 現在のカーソル行を強調表示 - - - - Highlight Selected Words - 選択された単語を強調表示 - - - - Highlight all occurences of selected words - 選択された単語のすべての出現を強調表示する - - - - Highlight Trailing Spaces - 末尾のスペースを強調表示 - - - - Highlight all the spaces at the end of a line - 線の端にあるすべてのスペースを強調表示します。 - - - - Highlight Tabs - タブを強調表示 - - - - Highlight all the tabs - すべてのタブを強調表示する - - - - Tab Stop Width - タブ位置の幅 - - - - Smart Table - スマートテーブル - - - - Format table automatically - テーブルの自動フォーマット - - - - Tools - ツール - - - - Outline - アウトライン - - - - Snippets - スニペット - - - - Cart - カート - - - - Toggle the tools dock widget - ツールドックウィジェットを切り替える - - - - Search - 検索 - - - - Toggle the search dock widget - 検索ドックウィジェットを切り替える - - - - Select Files To Create Notes - ノートを作成するファイルを選択 - - - - Warning - 警告 - - - - Fail to create notes for all the files. - すべてのファイルに対してノートを作成できません。 - - - - %1 %2 created from external files - %1 %2は外部ファイルから作成されました - - - - notes - ノート - - - - note - ノート - - - - - VNote - VNote - - - - Version: %1 - バージョン:%1 - - - - Author: Le Tan (tamlok) - 作者:Le Tan (tamlok) - - - - VNote is a free and open source note-taking application that knows programmers and Markdown better. - VNoteは、プログラマーとMarkdownをよく理解できるフリー&オープンソースのノート作成アプリケーションです。 - - - - Please visit <a href="https://tamlok.github.io/vnote">VNote</a> for more information. - 詳細については、<a href="https://tamlok.github.io/vnote">VNote</a>を参照してください。 - - - - About VNote - VNoteについて - - - - &Renderer - レンダラー(&R) - - - - Marked - Marked - - - - Use Marked to convert Markdown to HTML (re-open current tabs to make it work) - Markedを使用して、MarkdownをHTMLに変換します(現在のタブを再開すると機能させることができます)。 - - - - Hoedown - Hoedown - - - - Use Hoedown to convert Markdown to HTML (re-open current tabs to make it work) - Hoedownを使用して、MarkdownをHTMLに変換します(現在のタブを再開すると機能させることができます)。 - - - - Markdown-it - Markdown-it - - - - Use Markdown-it to convert Markdown to HTML (re-open current tabs to make it work) - Markdown-itを使用して、MarkdownをHTMLに変換します(現在のタブを再開すると機能させることができます)。 - - - - Showdown - Showdown - - - - Use Showdown to convert Markdown to HTML (re-open current tabs to make it work) - Showdownを使用して、MarkdownをHTMLに変換します(現在のタブを再開すると機能させることができます)。 - - - - Markdown-it Options - Markdown-itのオプション - - - - HTML - HTML - - - - Enable HTML tags in source (re-open current tabs to make it work) - ソース中のHTMLタグを有効にします。(現在のタブを再開すると機能させることができます)。 - - - - Line Break - 改行 - - - - Convert '\n' in paragraphs into line break (re-open current tabs to make it work) - 段落の'\n'を改行に変換します(現在のタブを再開して機能を有効にします)。 - - - - Linkify - リンク変換 - - - - Convert URL-like text into links (re-open current tabs to make it work) - URL形式のテキストをリンクに変換します(現在のタブを再開して機能を有効にします)。 - - - - Superscript - 上付き文字 - - - - Enable superscript like ^vnote^ (re-open current tabs to make it work) - ^vnote^のような上付き文字を有効にします。(現在のタブを再開すると機能させることができます)。 - - - - Subscript - 下付き文字 - - - - Enable subscript like ~vnote~ (re-open current tabs to make it work) - ~vnote~のような下付き文字を有効にします。(現在のタブを再開すると機能させることができます)。 - - - - Metadata Aware - Metadata Aware - - - - Be aware of metadata in YAML format (re-open current tabs to make it work) - YAML形式のメタデータを認識する(現在のタブを再開すると機能させることができます)。 - - - - Emoji - 絵文字 - - - - Enable emoji and emoticon (re-open current tabs to make it work) - 絵文字とEmoticonを有効にします。(現在のタブを再開すると機能させることができます)。 - - - - Extensions - 拡張機能 - - - - &Mermaid - &Mermaid - - - - Enable Mermaid for graph and diagram (re-open current tabs to make it work) - グラフと図を作成するために、Mermaidを有効にします(現在のタブを再開して機能を有効にします)。 - - - - &Flowchart.js - &Flowchart.js - - - - Enable Flowchart.js for flowchart diagram (re-open current tabs to make it work) - フローチャート図を作成するために、Flowchart.jsを有効にします(現在のタブを再開して機能を有効にします)。 - - - - Math&Jax - Math&Jax - - - - Enable MathJax for math support in Markdown (re-open current tabs to make it work) - Mark downの数学サポートのMathJaxを有効にする(現在のタブを再開して機能を有効にします) - - - - &WaveDrom - &WaveDrom - - - - Enable WaveDrom for digital timing diagram (re-open current tabs to make it work) - デジタルタイミング図を作成するために、WaveDromを有効にします(現在のタブを再開して機能を有効にします)。 - - - - &Rendering Background - 背景レンダリング(&R) - - - - - System - システム - - - - Use system's background color configuration for Markdown rendering - Mark downレンダリングにシステムの背景色設定を使用します。 - - - - Transparent - 透明 - - - - Use a transparent background for Markdown rendering - Markdownのレンダリングに透明な背景を使用する - - - - Set as the background color for Markdown rendering (re-open current tabs to make it work) - Markdownレンダリングの背景色として設定します(現在のタブを再開すると機能させることができます)。 - - - - Rendering &Style - レンダリングスタイル(&S) - - - - - - - - - Add Style - スタイルを追加 - - - - Add custom style of read mode - 読み取りモードのカスタムスタイルを追加する - - - - Set as the CSS style for Markdown rendering (re-open current tabs to make it work) - マークダウンレンダリングのCSSスタイルとして設定します(現在のタブを再開すると機能させることができます)。 - - - - Code Block Style - コードブロックのスタイル - - - - Add custom style of code block in read mode - 読み取りモードでコードブロックのカスタムスタイル追加 - - - - Set as the code block CSS style for Markdown rendering (re-open current tabs to make it work) - Mark downレンダリングのコードブロックCSSスタイルとして設定します(現在のタブを再開すると機能させることができます)。 - - - - &Background Color - 背景色(&B) - - - - Use system's background color configuration for editor - エディタでシステムの背景色設定を使用する - - - - Set as the background color for editor (re-open current tabs to make it work) - エディタの背景色として設定します(現在のタブを再開すると機能させることができます)。 - - - - Line Number - 行番号 - - - - None - なし - - - - Do not display line number in edit mode - 編集モードで行番号を表示しない - - - - Absolute - 絶対行番号 - - - - Display absolute line number in edit mode - 編集モードでの絶対行番号を表示する - - - - Relative - 相対 - - - - Display line number relative to current cursor line in edit mode - 編集モードで現在のカーソル行を基準にして行番号を表示する - - - - CodeBlock - コードブロック - - - - Display line number in code block in edit mode (for Markdown only) - 編集モードのコードブロック内の行番号を表示(Markdownのみ) - - - - Editor &Style - エディタとスタイル(&S) - - - - Add custom style of editor - エディタのカスタムスタイルを追加する - - - - Set as the editor style (re-open current tabs to make it work) - エディタのスタイルとして設定します(現在のタブを再開すると機能させることができます)。 - - - - Auto Scroll Cursor Line - 自動スクロールカーソル行 - - - - Disabled - 無効 - - - - End Of Document - ドキュメントの末尾 - - - - Scroll cursor line into the center when it locates at the end of document - カーソル行を文書の末尾に配置するときに、中央にスクロールします。 - - - - Always - 常に - - - - Always scroll cursor line into the center - カーソル行を常に中心にスクロールする - - - - Close VNote - VNoteを閉じる - - - - Do you want to minimize VNote to system tray instead of quitting it when closing VNote? - VNoteを終了するときに、Vnoteを終了する代わりに、システムトレイに対してVNoteを最小化しますか? - - - - You could change the option in Settings later. - [設定]のオプションは、後で変更することができます。 - - - - Print Note - ノートを印刷 - - - - Show VNote - VNoteを表示 - - - - Quit - 終了 - - - - Information - 情報 - - - - Quick Access is not set. - クイックアクセスが設定されていません。 - - - - Please specify the note for Quick Access in the settings dialog or the context menu of a note. - Please specify the note for Quick Access in the settings dialog or the context menu of a note. - - - - Headings - 見出し - - - - Heading %1 - 見出し%1 - - - - Heading %1 %2 - 見出し%1 %2 - - - - Clear - クリア - - - - Clear %1 - クリア %1 - - - - Theme - テーマ - - - - - Add Theme - テーマを追加 - - - - Add custom theme - カスタムテーマを追加する - - - - Set as the theme of VNote (restart VNote to make it work) - VNoteのテーマとして設定します(有効にするにはVNoteを再起動します)。 - - - - Edit %1 - 編集 %1 - - - - Save Changes And Read %1 - 変更を保存して読み取り %1 - - - - Edit - 編集 - - - - Save Changes And Read - 変更を保存して読み取り - - - - Edit current note - 現在のノートを編集 - - - - Save changes and exit edit mode - 変更を保存して編集モードを終了する - - - - Collect User Statistics - Collect User Statistics - - - - VNote would like to send a request to count active users.Do you allow this request? - VNote would like to send a request to count active users.Do you allow this request? - - - - A request to https://tamlok.github.io/user_track/vnote.html will be sent if allowed. - - - - - Notices for Windows Users - - - - - OpenGL requried by VNote may not work well on Windows by default.You may update your display card driver or set another openGL option in VNote's Settings dialog.Check <a href="https://github.com/tamlok/vnote/issues/853">GitHub issue</a> for details. - - - - - Strange behaviors include:<br/>* Interface freezes and does not response;<br/>* Widgets are out of order after maximizing and restoring the main window;<br/>* No cursor in edit mode;<br/>* Menus are not clickable in full screen mode. - - - - - Restart Needed - - - - - Do you want to restart VNote now? - - - - - VNote needs to restart to apply new configurations. - - - - A request to https://tajs.qq.com/stats will be sent if allowed. - A request to https://tajs.qq.com/stats will be sent if allowed. - - - - VMarkdownTab - - - Default mode to open a file - ファイルを開くときの既定モード - - - - Read Mode - 読み取りモード - - - - Edit Mode - 編集モード - - - - Enable auto sequence for all headings (in the form like 1.2.3.4.) - すべての見出しに対して自動シーケンスを有効にします(1.2.3.4のような形式で)。 - - - - - Disabled - 無効 - - - - Enabled - 有効 - - - - Enabled for internal notes only - 内部ノートのみ有効にしました - - - - Base level to start heading sequence - ヘッダ・シーケンスを開始する基底レベル - - - - 1 - 1 - - - - 2 - 2 - - - - 3 - 3 - - - - 4 - 4 - - - - 5 - 5 - - - - 6 - 6 - - - - Specify the screen column in fenced code block which will be highlighted - 強調表示される囲み付きコードブロック内のスクリーン列を指定します。 - - - - Color column: - 色列: - - - - Location of MathJax JavaScript and its configuration (restart VNote to make it work in in-place preview) - MathJax Java Scriptの場所とその構成(インプレイスでのプレビューで機能するようにVNoteを再起動します) - - - - Need to prepend "file://" to local path - ローカルパスに"file://"を付加する必要があります - - - - Enable PlantUML support in Markdown - MarkdownでのPlantUMLサポートの有効化 - - - - Online Service - オンライン・サービス - - - - Local JAR - ローカルJAR - - - - Server address for online PlantUML - オンラインPlantUMLのサーバー・アドレス - - - - Location to the PlantUML JAR executable for local PlantUML - ローカルPlantUML用のPlantUML JAR実行可能ファイルの場所 - - - - - Test - テスト - - - - Test PlantUML JAR configuration - PlantUML JAR構成をテスト - - - - - Warning - 警告 - - - - The JAR file specified does not exist. - 指定されたJARファイルは存在しません。 - - - - Please input the right absolute file path to the JAR file. - JARファイルへの正しい絶対ファイルパスを入力してください。 - - - - Please specify the absolute file path to the JAR file. - JARファイルへの絶対ファイルパスを指定してください。 - - - - It should be something like "/path/to/plantuml.jar". - "/path/to/plantuml.jar"のようになります。 - - - - - Information - 情報 - - - - - Test %1. - %1をテストします。 - - - - - succeeded - 成功しました - - - - - failed - 失敗しました - - - - Graphviz - Graphviz - - - - Enable Graphviz for drawing graph - グラフ描画するGraphviz対応を有効にする - - - - Empty to detect automatically - 自動的に検出するときは、空にしておいてください - - - - Location to the GraphViz dot executable - GraphVizの実行ファイルの位置 - - - - Test Graphviz executable configuration - Graphviz実行ファイルの設定をテストする - - - - Open mode: - オープンモード: - - - - Heading sequence: - 見出しシーケンス: - - - - MathJax configuration: - MathJaxの構成: - - - - PlantUML: - PlantUML: - - - - PlantUML server: - PlantUMLサーバ: - - - - PlantUML JAR: - PlantUML JAR: - - - - Graphviz executable: - Graphviz実行可能ファイル: - - - - VMdEdit - - - Insert From Clipboard - クリップボードから挿入 - - - - Insert As Image - イメージとして挿入 - - - - Insert As Text - テキストとして挿入 - - - - Following images seems not to be used in this note anymore. Please confirm the deletion of these images. - このノートでは、次のイメージは使用されないようです。これらの画像の削除を確認してください。 - - - - Deleted files could be found in the recycle bin of this note.<br>Click "Cancel" to leave them untouched. - 削除したファイルはこのノートのゴミ箱にいきます。<br>"キャンセル"をクリックすると、そのままにします。 - - - - Confirm Cleaning Up Unused Images - 未使用画像のクリーンアップを確認する - - - - VMdEditOperations - - - Insert Image From Clipboard - クリップボードからイメージを挿入 - - - - - Fail to create image folder <span style="%1">%2</span>. - イメージフォルダ<span style="%1">%2</span>の作成に失敗しました。 - - - - Fail to save image <span style="%1">%2</span>. - 画像<span style="%1">%2</span>の保存に失敗しました。 - - - - - Warning - 警告 - - - - - Fail to insert image <span style="%1">%2</span>. - 画像<span style="%1">%2</span>の挿入に失敗しました。 - - - - Fail to copy image <span style="%1">%2</span>. - 画像<span style="%1">%2</span>のコピーに失敗しました。 - - - - Insert Image From File - ファイルから画像を挿入 - - - - Insert Image From Network - ネットワークから画像を挿入 - - - - Insert Image - 画像を挿入 - - - - VMdEditor - - - Paste As Plain Text - プレーンテキストとして貼り付け - - - - &Save Changes And Read - 変更を保存して読み込み(&S) - - - - Save changes and exit edit mode - 変更を保存して編集モードを終了する - - - - &Discard Changes And Read - 変更を破棄して読み込み(&D) - - - - Discard changes and exit edit mode - 変更を破棄して編集モードを終了する - - - - Live Preview For Graphs - グラフのライブプレビュー - - - - Toggle live preview panel for graphs - グラフのライブプレビューパネルを切り替えます - - - - Following images seems not to be used in this note anymore. Please confirm the deletion of these images. - このノートでは、次のイメージは使用されないようです。これらの画像の削除を確認してください。 - - - - Deleted files could be found in the recycle bin of this note.<br>Click "Cancel" to leave them untouched. - 削除したファイルはこのノートのゴミ箱にいきます。<br>"キャンセル"をクリックすると、そのままにします。 - - - - Confirm Cleaning Up Unused Images - 未使用画像のクリーンアップを確認する - - - - - - - Warning - 警告 - - - - Fail to move unsaved inserted image %1 to %2. - 保存されていない挿入されたイメージ%1を%2に移動できません。 - - - - Please check it manually to avoid image loss. - 画像の損失を避けるために、手動で確認してください。 - - - - Inserting parsed Markdown text - 解析されたMarkdownテキストの挿入 - - - - Parsed Markdown text inserted - 構文解析されたマークダウンテキストが挿入されました - - - - Copy HTML As - HTMLをコピー - - - - Copy selected content as HTML using rules specified by target %1 - 選択されたコンテンツを、ターゲット%1によって指定されたルールを使用してHTMLとしてコピーします - - - - Paste As Block &Quote - ブロック引用として貼り付け(&Q) - - - - Paste text from clipboard as block quote - クリップボードからのテキストをブロック引用として貼り付けます - - - - Paste Parsed &Markdown Text - Markdownとしてテキストを解析して貼り付け(&M) - - - - Parse HTML to Markdown text and paste - HTMLをMark downテキストに解析してペーストする - - - - Insert Image Link - 画像のリンクを挿入 - - - - View Image - 画像表示 - - - - Copy Image URL - 画像のURLをコピー - - - - Copy Image Path - 画像のパスをコピー - - - - Copy Image - 画像のコピー - - - - View Link - リンクを表示 - - - - Copy Link URL - URLをコピー - - - - Copy Link Path - リンクのパスをコピー - - - - Copy In-Place Preview - インプレイスプレビューをコピー - - - - Copy Graph - グラフをコピー - - - - PNG - PNG - - - - Export graph as PNG to a temporary file and copy - グラフをPNG形式で一時ファイルにエクスポートしてコピーする - - - - SVG - SVG - - - - Export graph as SVG to a temporary file and copy - グラフをSVGとして一時ファイルにエクスポートしてコピーする - - - - Fail to open a temporary file for export. - エクスポート用の一時ファイルを開くことができません。 - - - - Exporting graph - グラフのエクスポート - - - - Fail to export graph. - グラフのエクスポートに失敗しました。 - - - - Graph exported and copied - エクスポートされてコピーされたグラフ - - - - Fail to read exported image: %1 - エクスポートされたイメージの読み取りに失敗しました:%1 - - - - - - Insert From Clipboard - クリップボードから挿入 - - - - Insert From URL - URLから挿入 - - - - Insert From Image Data - イメージデータから挿入 - - - - - - Insert As Image Link - イメージリンクとして挿入 - - - - - Insert As Image - イメージとして挿入 - - - - - Insert As Text - テキストとして挿入 - - - - Insert As Relative Image Link - 相対イメージリンクとして挿入 - - - - Insert As Link - リンクとして挿入 - - - - Insert As Relative Link - 相対リンクとして挿入 - - - - Attach And Insert Link - リンクをアタッチして挿入 - - - - Insert File Content - ファイルの内容を挿入 - - - - Fail to add attachment %1 for note <span style="%2">%3</span>. - ノート<span style="%2">%3</span>の添付ファイル%1を追加できません。 - - - - 1 file added as attachment - 添付ファイルとして1ファイルが追加されました - - - - Fetching images to local folder... - ローカルフォルダへのイメージの取り込み中... - - - - Abort - 中止 - - - - Fetching Images To Local Folder - ローカルフォルダにイメージを取り込む - - - - Fetching image: %1 - イメージ%1を取得しています - - - - Link To Attachment - m - - - - VMdTab - - - - - - Warning - 警告 - - - - Fail to open note <span style="%1">%2</span>. - ノート<span style="%1">%2</span>を開くことができません。 - - - - Please check if file %1 exists. - ファイル%1が存在するかどうかを確認してください。 - - - - Information - 情報 - - - - Note <span style="%1">%2</span> has been modified. - ノート<span style="%1">%2</span>が変更されました。 - - - - Do you want to save your changes? - 変更を保存しますか? - - - - Could not modify a read-only note <span style="%1">%2</span>. - 読み取り専用のノート<span style="%1">%2</span>を変更できませんでした。 - - - - Please save your changes to other notes manually. - 手動で変更を他のノートとして保存してください。 - - - - - Fail to save note. - ノートを保存できません。 - - - - File <span style="%1">%2</span> being written has been removed. - 書き込み中のファイル<span style="%1">%2</span>は削除されました。 - - - - Fail to write to disk when saving a note. Please try it again. - ノートを保存するときにディスクへの書き込みに失敗しました。もう一度試してみてください。 - - - - Snippet applied - 適用されたスニペット - - - - Snippet %1 is not applicable - スニペット%1は適用されません - - - - Snippets are not applicable - スニペットは適用されません - - - - No available snippets defined with shortcuts - ショートカットで定義された使用可能なスニペットはありません - - - - Backup File Found - バックアップファイルが見つかりました - - - - Found backup file <span style="%1">%2</span> when opening note <span style="%1">%3</span>. - ノート<span style="%1">%3</span>を開くときにバックアップファイル<span style="%1">%2</span> が見付かりました。 - - - - VNote may crash while editing this note before.<br/>Please choose to recover from the backup file or delete it.<br/><br/>Note file last modified: <span style="%1">%2</span><br/>Backup file last modified: <span style="%1">%3</span> - VNoteが以前このノートを編集したときにクラッシュしたようです。<br/>バックアップから復旧するか、バックアップファイルを削除するか選択してください。<br/><br/>ノートファイルの最終編集日時: <span style="%1">%2</span><br/>バックアップファイルの最終編集日時: <span style="%1">%3</span> - - - - Recover From Backup File - バックアップファイルから復旧 - - - - Discard Backup File - バックアップファイルの削除 - - - - Cancel - キャンセル - - - - Quit - 終了 - - - - Not an editor command: %1 - エディタのコマンドではありません:%1 - - - - Page saved to %1 - ページは%1の保存されました - - - - Fail to save page to %1 - ページの%1への保存に失敗しました - - - - Single HTML (*.html) - 単一HTML(*.html) - - - - Complete HTML (*.html) - 完全なHTML(*.html) - - - - MIME HTML (*.mht) - MIME HTML(*.mht) - - - - Save Page - ページを保存 - - - - Saving page to %1 - %1にページを保存しています - - - - VMetaWordManager - - - the day as number without a leading zero (`1` to `31`) - 数字の日付(先頭0はつけない)(「1」から「31」) - - - - the day as number with a leading zero (`01` to `31`) - 数字の日付(先頭0あり)(「01」から「31」) - - - - the abbreviated localized day name (e.g. `Mon` to `Sun`) - 曜日の日本語での短縮形(例: `月`から`日`) - - - - the long localized day name (e.g. `Monday` to `Sunday`) - 日本語での曜日名(例: `月曜日`から`金曜日`) - - - - the month as number without a leading zero (`1` to `12`) - 月のローマ数字表記(頭の0なし) (`1` to `12`) - - - - the month as number with a leading zero (`01` to `12`) - 月のローマ数字表記(頭の0あり) (`01` to `12`) - - - - the abbreviated localized month name (e.g. `Jan` to `Dec`) - 月の日本語での短縮形(例: `1月`から`12月`) - - - - the long localized month name (e.g. `January` to `December`) - 月の日本語での表記(例: `1月`から`12月`) - - - - the year as two digit number (`00` to `99`) - 西暦年の二桁表記(`00`から`99`) - - - - the year as four digit number - 西暦年の四桁表記 - - - - the hour without a leading zero (`0` to `23` or `1` to `12` if AM/PM display) - あたまに0をつけない時刻(時) (`0` to `23`またはAM/PM表記の場合は`1` to `12`) - - - - the hour with a leading zero (`00` to `23` or `01` to `12` if AM/PM display) - あたまに0をつける時刻(時) (`00` to `23`またはAM/PM表記の場合は`01` to `12`) - - - - the hour without a leading zero (`0` to `23` even with AM/PM display) - あたまに0をつけない時刻(時) (`0` to `23` AM/PM表記の場合も同様) - - - - the hour with a leading zero (`00` to `23` even with AM/PM display) - あたまに0をつける時刻(時) (`00` to `23` AM/PM表記の場合も同様) - - - - the minute without a leading zero (`0` to `59`) - あたまに0をつけない時刻(分)(`0` to `59`) - - - - the minute with a leading zero (`00` to `59`) - あたまに0をつける時刻(分)(`00` to `59`) - - - - the second without a leading zero (`0` to `59`) - あたまに0をつけない時刻(秒)(`0` to `59`) - - - - the second with a leading zero (`00` to `59`) - あたまに0をつける時刻(秒)(`00` to `59`) - - - - the milliseconds without leading zeroes (`0` to `999`) - あたまに0をつけない時刻(ミリ秒)(`0` to `999`) - - - - the milliseconds with leading zeroes (`000` to `999`) - あたまに0をつける時刻(ミリ秒)(`000` to `999`) - - - - - use AM/PM display (`AM` or `PM`) - AM/PM表示(`AM'または`PM`)を使用 - - - - - use am/pm display (`am` or `pm`) - am/pm表示(`am'または`pm`)を使用 - - - - the timezone (e.g. `CEST`) - タイムゾーン(e.g. `CEST`) - - - - a random number - ランダムな数字 - - - - dynamic version of `random` - 「ランダム」の動的なバージョン - - - - name of current note - 現在のノートの名前 - - - - complete base name of current note - 現在の注記の完全なベース名 - - - - relative path of current note's attachment folder - 現在のノートの添付フォルダの相対パス - - - - the week number (`1` to `53`) - 週番号(`1'から`53'まで) - - - - information about all defined magic words - 定義されたすべてのマジックワードに関する情報 - - - - VMiscTab - - - Highlight matches of a full-text search in page - 全文検索の一致をページ内で強調表示 - - - - VNewDirDialog - - - Folder &name: - フォルダ名(&N): - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>: 名前(大文字と小文字を区別しない)<span style="%2">%3</span>は既に存在しています。別の名前を選択してください。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>: 名前<span style="%2">%3</span>には、不正な文字が含まれています(マジックワード評価の後)。 - - - - VNewFileDialog - - - Choose a template (magic word supported) - テンプレートの選択(マジックワードをサポート) - - - - Manage Templates - テンプレートの管理 - - - - Insert note name as title (for Markdown only) - タイトルとしてノート名を挿入(Markdownのみ) - - - - Insert note name into the new note as a title - 新しいノートにノート名をタイトルとして挿入します - - - - Note &name: - ノート名(&N): - - - - Template: - テンプレート: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>: 名前(大文字と小文字を区別しない)<span style="%2">%3</span>は既に存在しています。別の名前を選択してください。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>: 名前<span style="%2">%3</span>には、不正な文字が含まれています(マジックワード評価の後)。 - - - - None - なし - - - - VNewNotebookDialog - - - Notebook &name: - ノートブック名(&N): - - - - Notebook &root folder: - ノートブックのルートフォルダ(&R): - - - - &Browse - ブラウズ(&B) - - - - Use relative path - 相対パスを使用 - - - - Use relative path (to VNote's executable) in configuration file - 構成ファイル内で、(Vnoteの実行可能ファイルに対する)相対パスを使用します。 - - - - &Image folder: - 画像フォルダ(&I): - - - - - Use global configuration (%1) - グローバル構成を使用(%1) - - - - Set the name of the folder to hold images of all the notes in this notebook (empty to use global configuration) - このノートブックにすべてのノートのイメージを保持するフォルダの名前を設定します(グローバル構成を使用するには空です)。 - - - - &Attachment folder: - 添付ファイルフォルダ(&A): - - - - Set the name of the folder to hold attachments of all the notes in this notebook (empty to use global configuration, read-only once created) - このノートブックにすべてのノートの添付ファイルを保持するフォルダの名前を設定します(グローバル構成を使用するには空で、作成後は読み取り専用になります)。 - - - - Select Root Folder Of The Notebook - ノートブックのルートフォルダを選択 - - - - <span style="%1">WARNING</span>: Please specify absolute path. - <span style="%1">警告</span>: 絶対パスを指定してください。 - - - - <span style="%1">INFO</span>: The folder chosen seems to be a root folder of a notebook created by VNote before. VNote will try to import it by reading the configuration file. - <span style="%1">情報</span>: 選択したフォルダはあ、以前VNoteで作成されノートブックのルートフォルダです。VNoteは、構成ファイルを読み込んでインポートしようとします。 - - - - <span style="%1">WARNING</span>: The folder chosen is NOT empty! It is highly recommended to use an EMPTY and EXCLUSIVE folder for a new notebook. If continue, VNote will try to create a notebook based on existing folders and files recursively. - <span style="%1">警告</span>:選択されたフォルダは空ではありません!新しいノートブックには、空で排他的に利用できるフォルダを使用することを強くお勧めします。継続すると、VNoteは、既存のフォルダとファイルを再帰的に探索して、ノートブックを作成します。 - - - - <span style="%1">WARNING</span>: The path seems to be illegal. Please choose another one. - <span style="%1">警告</span>: このパスは不正のようです。別のパスを選択してください。 - - - - <span style="%1">WARNING</span>: The folder chosen has already been a root folder of existing notebook <span style="%2">%3</span> in VNote. - <span style="%1">警告</span>: 選択したフォルダは、VNoteで作成された既存のノートブック<span style="%2">%3</span>です。 - - - - <span style="%1">WARNING</span>: Please choose a folder in the same drive as <span style="%2">%3</span> when relative path is enabled. - <span style="%1">警告</span>: 相対パスが有効なときは、<span style="%2">%3</span>と同じドライブのフォルダを選択してください。 - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>: 名前(大文字と小文字を区別しない)<span style="%2">%3</span>は既に存在しています。別の名前を選択してください。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>: 名前<span style="%2">%3</span>には、不正な文字が含まれています(マジックワード評価の後)。 - - - - VNoteFile - - - Fail to delete images of this note. - このノートの画像を削除できません。 - - - - Fail to delete attachments of this note. - このノートの添付ファイルを削除できません。 - - - - Fail to delete the note file. - ノートファイルの削除に失敗しました。 - - - - Fail to remove the note from the folder configuration. - フォルダ構成からノートを削除できません。 - - - - Fail to open target folder. - ターゲットフォルダを開くことができません。 - - - - - cut - 切り取り - - - - - copy - コピー - - - - Fail to %1 the note file. - ノートファイルの%1に失敗しました。 - - - - Fail to add the note to target folder's configuration. - フォルダをターゲットフォルダのノートに追加できません。 - - - - Fail to %1 attachments folder %2 to %3. Please manually maintain it. - 添付ファイルフォルダ%2を%3に%1できません。手動で実施してください。 - - - - Fail to update configuration of note %1. - ノート%1の構成を更新できません。 - - - - Source image %1 does not exist. - ソース画像%1は存在しません。 - - - - Skip image with the same source and target path %1. - 同じソースパスとターゲットパス%1である画像をスキップします。 - - - - Fail to %1 image %2 to %3. Please manually %1 it and modify the note. - 画像%2を%3の %1 に失敗しました。手動で%1を実行し、ノートを修正してください。 - - - - VNoteManagementTab - - - Notes - ノート - - - - External Files - 外部ファイル - - - - - Custom image folder - カスタムイメージフォルダ - - - - Set the global name of the image folder to hold images of notes (restart VNote to make it work) - ノートの画像を保持するイメージフォルダのグローバル名を設定します(再起動するにはVNoteを再起動します)。 - - - - - Name of the image folder - 画像フォルダの名前 - - - - Custom attachment folder - カスタム添付ファイルフォルダ - - - - Set the global name of the attachment folder to hold attachments of notes (restart VNote to make it work) - 添付ファイルを保持する添付ファイルフォルダのグローバル名を設定します(再起動するには、Vnoteを再起動してください)。 - - - - Name of the attachment folder - 添付フォルダの名前 - - - - Single click to open a note in current tab - クリックすると、現在のタブにノートが表示されます。 - - - - Single click a note in the notes list to open it in current tab, double click to open it in a new tab - ノートの一覧でメモをクリックして、現在のタブで開き、ダブルクリックして新しいタブで開きます。 - - - - Set the path of the global image folder to hold images of external files (restart VNote to make it work). -You could use both absolute or relative path here. If absolute path is used, VNote will not manage -those images, so you need to clean up unused images manually. - グローバル画像フォルダのパスを設定して、外部ファイルの画像を保持します(VNoteを再起動して動作させます)。 -絶対パスと相対パスの両方をここで使用できます。絶対パスが使用されている場合、VNoteは管理されません -これらの画像は、未使用画像を手動でクリーンアップする必要があります。 - - - - VNotebook - - - Fail to write notebook configuration file. - ノートブック構成ファイルの書き込みに失敗しました。 - - - - VNotebookInfoDialog - - - - Use global configuration (%1) - グローバル構成を使用(%1) - - - - Set the name of the folder to hold images of all the notes in this notebook (empty to use global configuration) - このノートブックにすべてのノートのイメージを保持するフォルダの名前を設定します(グローバル構成を使用するには空です)。 - - - - The folder to hold attachments of all the notes in this notebook - このノートブックに含まれるすべてのノートの添付ファイルを格納するフォルダ - - - - The folder to hold deleted files from within VNote of all the notes in this notebook - このノートブック内のすべてのノートのVNote内から削除されたファイルを格納するフォルダ - - - - Notebook &name: - ノートブック名(&N): - - - - Notebook &root folder: - ノートブックのルートフォルダ(&R): - - - - &Image folder: - 画像フォルダ(&I): - - - - Attachment folder: - 添付ファイルフォルダ: - - - - Recycle bin folder: - ごみ箱フォルダ: - - - - Created time: - 作成日時: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>: 名前(大文字と小文字を区別しない)<span style="%2">%3</span>は既に存在しています。別の名前を選択してください。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>: 名前<span style="%2">%3</span>には、不正な文字が含まれています(マジックワード評価の後)。 - - - - VNotebookSelector - - - - Add Notebook - ノートブックを追加 - - - - Create or import a notebook - ノートブックを作成またはインポートする - - - - View and edit notebooks - ノートブックを表示、編集する - - - - Please type the name of the notebook and choose a folder as the Root Folder of the notebook. - ノートブックの名前を入力し、ノートブックのルートフォルダとしてフォルダを選択してください。 - - - - * The root folder should be used EXCLUSIVELY by VNote and it is recommended to be EMPTY. - *ルートフォルダはVNoteによって排他的に使用される必要があり、空にすることをお勧めします。 - - - - * A previously created notebook could be imported into VNote by choosing its root folder. - *以前に作成されたノートブックは、ルートフォルダを選択してVNoteにインポートできます。 - - - - * When a non-empty folder is chosen, VNote will create a notebook based on the folders and files in it recursively. - *空でないフォルダを選択すると、VNoteは、そのフォルダとファイルを再帰的に探索して、ノートブックを作成します。 - - - - Successfully build notebook recursively (%1). - 再帰的にノートブック(%1)を構築しました。 - - - - Fail to build notebook recursively. - ノートブックを再帰的に構築できません。 - - - - - Information - 情報 - - - - - - Warning - 警告 - - - - Fail to create notebook <span style="%1">%2</span> in <span style="%1">%3</span>. - <span style="%1">%3</span>に、ノートブック<span style="%1">%2</span>の作成に失敗しました。 - - - - Delete Notebook - ノートブックの削除 - - - - Delete Notebook Folder From Disk - ディスクからノートブックのフォルダを削除 - - - - Fail to delete the root folder of notebook <span style="%1">%2</span> from disk. You may open the folder and check it manually. - ディスクからノートブック <span style="%1">%2</span>のフォルダの削除に失敗しました。フォルダを手動で開いて - - - - Notebook Information - ノートブック情報 - - - - &Delete - 削除(&D) - - - - Delete current notebook - 現在のノートブックを削除 - - - - &Recycle Bin - ごみ箱(&R) - - - - Open the recycle bin of this notebook - このノートブックのごみ箱を開きます - - - - &Empty Recycle Bin - ごみ箱を空にする(&E) - - - - Empty the recycle bin of this notebook - このノートブックのごみ箱を空にする - - - - Are you sure to empty recycle bin of notebook <span style="%1">%2</span>? - ノートブック<span style="%1">%2</span>のごみ箱を空にしますか? - - - - <span style="%1">WARNING</span>: VNote will delete all the files in directory <span style="%2">%3</span>.<br>It may be UNRECOVERABLE! - <span style="%1">警告</span>:VNoteは、ディレクトリ<span style="%2">%3</span>内のすべてのファイルを削除します。<br>復旧はできません! - - - - Successfully emptied recycle bin of notebook <span style="%1">%2</span>! - ノートブック<span style="%1">%2</span>のごみ箱を空にしました! - - - - Fail to empty recycle bin of notebook <span style="%1">%2</span>! - ノートブック<span style="%1">%2</span>のごみ箱を空にすることができません! - - - - &Open Notebook Location - ノートブックの場所を開く(&O) - - - - Explore the root folder of this notebook in operating system - オペレーティング・システムでこのノートブックのルート・フォルダを表示します。 - - - - &Info (Rename) - 情報(名前変更)(&I) - - - - View and edit current notebook's information - 現在のノートブックの情報を表示および編集する - - - - VOrphanFileInfoDialog - - - File: - ファイル: - - - - Use global configuration (%1) - グローバル構成を使用(%1) - - - - Set the path of the image folder to store images of this file. -If absolute path is used, VNote will not manage those images.(empty to use global configuration) - 画像フォルダのパスを設定して、このファイルの画像を保存します。 -絶対パスを使用した場合、VNoteはそれらのイメージを管理しません(グローバル構成を使用するには空にします)。 - - - - &Image folder: - 画像フォルダ(&I): - - - - External File Information - 外部ファイル情報 - - - - VOutline - - - Decrease Expanded Level - 拡張レベルの縮小 - - - - - Set Outline Expanded Level to %1 - アウトライン拡張レベルを%1に設定します - - - - Increase Expanded Level - 拡張レベルの向上 - - - - VOutlineUE - - - List and search the outline of current note - 現在の注記のアウトラインをリストおよび検索します。 - - - - VReadEditTab - - - Read Mode (For Markdown Only) - 読み取りモード(マークダウンのみ) - - - - Edit Mode - 編集モード - - - - Custom Web zoom factor - カスタムWebズーム倍率 - - - - Set the zoom factor of the Web page when reading - 読み込むときのWebページのズーム倍率を設定します。 - - - - Flash current heading - 一時メモ(Flash) 現在の見出し - - - - Flash current heading on change - 変更時に現在の見出しをflash - - - Swap file - スワップファイル - - - - Automatically save changes to a swap file for backup - バックアップするために、変更をスワップ・ファイルへ自動的に保存する - - - Auto save - 自動保存 - - - Automatically save the note when editing - 自動的に編集したノートを保存 - - - - Swap file (Recommended) - - - - - Auto save (Buggy) - - - - - Automatically save the note when editing (may DELETE images on save) - - - - - Choose the key mode in editor - エディタのキーモードを選択する - - - - Normal - 通常 - - - - Vim - Vim - - - - Smart input method in Vim mode - Vimモードのスマート入力メソッド - - - - Disable input method when leaving Insert mode in Vim mode - VImモードで入力モードをぬけるときに入力メソッドを無効にする - - - - Custom editor font - エディターのフォントをカスタマイズ - - - - Set the font of editor to override style configuration - スタイル設定を上書きして、エディタのフォントを設定します。 - - - - Set the zoom delta of the editor font - エディタフォントのズームデルタを設定します。 - - - - Key mode: - キーモード: - - - - Editor zoom delta: - エディタのズーム・デルタ: - - - - It's recommended to enable "Swap file" or "Auto save", not both - 「スワップファイル」または「自動保存」を有効にすることをお勧めします。両方ではありません。 - - - - VSearchEngineWorker - - - Skip binary file %1. - バイナリファイル%1をスキップします。 - - - - VSearchResultTree - - - &Open - 開く(&O) - - - - Open selected notes - 選択されたノートを開く - - - - &Locate To Folder - フォルダへ移動(&L) - - - - Locate the folder of current note - 現在のノートのフォルダを指定します。 - - - - Add To Cart - カートに追加 - - - - Add selected notes to Cart for further processing - 追加処理のために、選択したノートをカートに追加します - - - - Pin To History - 履歴に固定 - - - - Pin selected notes to History - 選択したノートを履歴に固定します - - - - Expand/Collapse All %1 - すべての%1を展開/集約 - - - - %1 %2 added to Cart - %1カートに%2が追加されました - - - - - notes - ノート - - - - - note - ノート - - - - %1 %2 pinned to History - %1 %2は履歴に固定されています - - - - VSearchUE - - - List and search all the notebooks - 全てのノートブックを検索 - - - - Search the name of folders/notes in all the notebooks - 全てのノートブックのフォルダ名とノート名を検索 - - - - Search the content of notes in all the notebooks - 全てのノートブックのコンテツを検索 - - - - Search the tags of notes in all the notebooks - すべてのノートブックからノートのタグを検索 - - - - Search the name of folders/notes in current notebook - 現在のノートブックからフォルダ名/ノート名を検索 - - - - Search the content of notes in current notebook - 現在のノートブックからノートのコンテンツを検索 - - - - Search the tags of notes in current notebook - 現在のノートブックからノートのタグを検索 - - - - Search the name of folders/notes in current folder - 現在のフォルダのフォルダ名/ノート名を検索 - - - - Search the content of notes in current folder - 現在のフォルダのノートのコンテンツを検索 - - - - Search the tags of notes in current folder - 現在のフォルダのノートのタグを検索 - - - - List and search the name of opened notes in buffer - バッファ内の開いているノートの名前を一覧表示して検索 - - - - Search the content of opened notes in buffer - バッファ内の開いているノートの内容を検索 - - - - Search the outline of opened notes in buffer - バッファ内の開いたノートのアウトラインを検索 - - - - Search the path of folders/notes in all the notebooks - すべてのノートブックのフォルダ/ノートのパスを検索 - - - - Search the path of folders/notes in current notebook - 現在のノートブック内のフォルダ/ノートのパスを検索 - - - - Search the content of notes in Explorer root directory - エクスプローラのルートディレクトリにあるノートの内容を検索 - - - - Invalid ID %1 - 無効なID%1 - - - - VSearcher - - - Search - 検索 - - - - Clear Results - 結果のクリア - - - - Advanced Settings - 詳細設定 - - - - Console - コンソール - - - - Keywords to search for - 検索するキーワード - - - - Supports space, &&, and || - 空白文字、&&, || をサポート - - - - Scope to search - 検索対象範囲 - - - - Object to search - 検索するオブジェクト - - - - Target to search - 検索対象 - - - - Wildcard pattern to filter the files to be searched - 検索対象のファイルをワイルドカードパターンで指定 - - - - Engine to execute the search - 検索を実行するエンジン - - - - &Case sensitive - 大文字と小文字を区別(&C) - - - - &Whole word only - 単語全体のみ(&W) - - - - &Fuzzy search - ファジー検索(&F) - - - - Not available for content search - コンテンツ検索では利用できません - - - - Re&gular expression - 正規表現(&G) - - - - File pattern: - ファイルパターン: - - - - Engine: - エンジン: - - - - Cancel - キャンセル - - - - Cancelling the search... - 検索をキャンセルしています... - - - - Output logs will be shown here - 出力ログが表示されます。 - - - - Keywords: - キーワード: - - - - Scope: - 範囲: - - - - Object: - オブジェクト: - - - - Target: - ターゲット: - - - - Opened Notes - 開いているノート - - - - Current Folder - 現在のフォルダ - - - - Current Notebook - 現在のノートブック - - - - All Notebooks - すべてのノートブック - - - - Explorer Directory - Explorer Directory - - - - Name - 名前 - - - - Content - コンテンツ - - - - Tag - タグ - - - - Path - パス - - - - Note - ノート - - - - Folder - フォルダ - - - - Notebook - ノートブック - - - - Note/Folder/Notebook - ノート/フォルダ/ノートブック - - - - Internal - Internal - - - - Search started. - 検索開始。 - - - - Search current note %1. - 現在のノート%1を検索します。 - - - - Search current folder %1. - 現在のフォルダ%1を検索します。 - - - - Search current notebook %1. - 現在のノートブック%1を検索します。 - - - - Search Explorer directory %1. - エクスプローラディレクトリ%1を検索します。 - - - - Search is on going. - 検索は進行中です。 - - - - Search succeeded. - 検索が成功しました。 - - - - - Search failed. - 検索に失敗しました。 - - - - - Warning - 警告 - - - - User cancelled the search. Aborted! - ユーザーにより検索がキャンセルされました。中止しました! - - - - Errors found during search. - 検索中にエラーが検出されました。 - - - - %1 Items - %1項目 - - - - VSelectDialog - - - Cancel - キャンセル - - - - VSettingsDialog - - - Reset VNote - VNoteをリセット - - - - Reset all the configurations of VNote - VNoteのすべての設定をリセットします。 - - - - Reset Layout - レイアウトをリセット - - - - Reset layout of VNote - VNoteのレイアウトをリセット - - - - Settings - 設定 - - - - General - 一般 - - - - Appearance - 外観 - - - - Read/Edit - 読み取り/編集 - - - - Note Management - ノート管理 - - - - Markdown - Markdown - - - - Misc - その他 - - - - - - - Warning - 警告 - - - - Are you sure to reset VNote? - VNoteをリセットしますか? - - - - All configurations (except notebooks information) will be reset to default values. It is UNRECOVERABLE! - すべての構成(ノートブック情報を除く)は、既定値にリセットされます。復旧できません! - - - - - Information - 情報 - - - - - Please restart VNote to make it work. - 有効にするには、VNoteを再起動してください。 - - - - - Any change to VNote before restart will be lost! - 再起動前のVNoteへの変更は失われます! - - - - Are you sure to reset the layout of VNote? - VNoteのレイアウトをリセットしてもよろしいですか? - - - - The view and layout mode will be reset. It is UNRECOVERABLE! - ビューとレイアウトモードがリセットされます。復旧できません! - - - - Fail to load configuration. - 設定のロードに失敗しました。 - - - - Fail to save configuration. Please try it again. - 設定を保存できません。もう一度試してみてください。 - - - - VSimpleSearchInput - - - Type to search - 検索するタイプ - - - - %1/%2 - %1/%2 - - - - VSnippetList - - - New Snippet - 新しいスニペット - - - - Open Folder - フォルダを開く - - - - - Magic words are supported in the content of the snippet. - マジックワードは、スニペットのコンテンツでサポートされています。 - - - - Create Snippet - スニペットを作成 - - - - - - - - Warning - 警告 - - - - Fail to create snippet <span style="%1">%2</span>. - スニペット<span style="%1">%2</span>の作成に失敗しました。 - - - - &Apply - 適用(&A) - - - - Insert this snippet in editor - このスニペットをエディタに挿入する - - - - &Info (Rename) %1 - 情報(名前変更)(&I) %1 - - - - View and edit snippet's information - スニペットの情報を表示および編集する - - - - &Delete - 削除(&D) - - - - Delete selected snippets - 選択されたスニペットを削除 - - - - &Sort - 整列(&S) - - - - Sort snippets manually - スニペットを手動でソートする - - - - Are you sure to delete these snippets? - これらのスニペットを削除しますか? - - - - Click "Cancel" to leave them untouched. - "キャンセル"をクリックすると、そのままにします。 - - - - Confirm Deleting Snippets - スニペットを削除する - - - - Fail to delete snippets. - スニペットを削除できません。 - - - - Sort Snippets - スニペットをソート - - - - Sort snippets in the configuration file. - 構成ファイル内のスニペットをソートします。 - - - - Name - 名前 - - - - Fail to sort snippets. - スニペットのソートに失敗しました。 - - - - Snippet Information - スニペット情報 - - - - - - - Fail to write snippets configuration file. - スニペット設定ファイルの書き込みに失敗しました。 - - - - Fail to update information of snippet <span style="%1">%2</span>. - スニペット<span style="%1">%2</span>の情報を更新できません。 - - - - Fail to add write the snippet file %1. - スニペットファイル%1の書き込みを追加できません。 - - - - Fail to remove snippet file %1. - スニペットファイル%1の削除に失敗しました。 - - - - %1 %2 - %1 %2 - - - - Items - 項目 - - - - Item - 項目 - - - - Fail to read snippets from <span style="%1">%2</span>. - <span style="%1">%2</span>からスニペットを読み取ることができません。 - - - - VSortDialog - - - &Top - 最上部(&T) - - - - Move selected items to top - 選択したアイテムを最上部へ移動 - - - - &Up - 上へ(&U) - - - - Move selected items up - 選択したアイテムを上へ移動 - - - - &Down - 下へ(&D) - - - - Move selected items down - 選択したアイテムを下へ移動 - - - - &Bottom - 最下部(&B) - - - - Move selected items to bottom - 選択したアイテム最下部へ移動 - - - - VTabIndicator - - - The type of the file - ファイルの種類 - - - - ReadOnly - 読み込み専用 - - - - This file is read-only - このファイルは読み込み専用です - - - - Standalone - スタンドアロン - - - - This file is not managed by any notebook or folder - このファイルは、任意のノートブックまたはフォルダでは管理されません - - - - System - システム - - - - This file is a system file - このファイルはシステムファイルです。 - - - - - [W] - [W] - - - - Word Count Information - ワードカウント情報 - - - - Line: %1 - %2(%3%) Col: %4 - 行: %1 -%2(%3%) %4 文字目 - - - - [%1]%2 - [%1]%2 - - - - C - C - - - - W - W - - - - VTagExplorer - - - - Tags - タグ - - - - - Notes - ノート - - - - Split - 分割 - - - - Tags (%1) - タグ(%1) - - - - Notes (%1) - ノート(%1) - - - - Searching for tag "%1" - タグ"%1"を検索しています - - - - Invalid busy state when searching for tag - タグを検索するときに無効なビジー状態です - - - - Search for tag succeeded - タグの検索に成功しました - - - - Search for tag failed - タグの検索に失敗しました - - - - Search for tag calcelled - タグの検索をキャンセルしました - - - - &Open - 開く(&O) - - - - Open selected notes - 選択されたノートを開く - - - - &Locate To Folder - フォルダへ移動(&L) - - - - Locate the folder of current note - 現在のノートのフォルダを指定します。 - - - - Add To Cart - カートに追加 - - - - Add selected notes to Cart for further processing - 追加処理のために、選択したノートをカートに追加します - - - - Pin To History - 履歴に固定 - - - - Pin selected notes to History - 選択したノートを履歴に固定します - - - - %1 %2 added to Cart - %1カートに%2が追加されました - - - - - notes - ノート - - - - - note - ノート - - - - %1 %2 pinned to History - %1 %2は履歴に固定されています - - - - Warning - 警告 - - - - Empty tag detected! Do you want to remove it? - 空のタグが検出されました!削除しますか? - - - - The tag <span style="%1">%2</span> seems not to be assigned to any note currently. - タグ<span style="%1">%2</span>は現在、どのノートにも割り当てられていません。 - - - - VTagLabel - - - Remove - 削除 - - - - VTagPanel - - - View and edit tags of current note - 現在のノートのタグを表示および編集する - - - - Press Enter to add a tag - [Enter]を押してタグを追加する - - - - Add a tag - タグを追加する - - - - Tag "%1" added - タグ"%1"が追加されました - - - - Tag "%1" removed - タグ"%1"は削除されました - - - - VTipsDialog - - - VNote Tips - VNoteのヒント - - - - VUniversalEntry - - - Universal Entry, reach anything by typing - ユニバーサルエントリ、入力することで何かに到達する - - - - VUpdater - - - Current Version: v%1 - 現在のバージョン:v%1 - - - - - Checking for updates... - 更新を確認しています. - - - - VNote Update - VNoteアップデート - - - - :( Fail to check for updates. -Please try it later. - :(更新を確認できませんでした。 -後で試してみてください。 - - - - Current Version: v%1 -Latest Version: v%2 - 現在のバージョン:v%1 最新バージョン:v%2 - - - - <span style="font-weight: bold;">Updates Available!</span><br/>Please visit <a href="%1">GitHub Releases</a> to download the latest version. - <span style="font-weight: bold;">更新版があります!</span><br/><br/><br/><a href="%1">GitHub Releases</a>から最新版をダウンロードしてください。 - - - - VNote is already the latest version. - VNoteは既に最新バージョンです。 - - - - VVim - - - - - - %1 %2 changed - %1%2が変更されました - - - - - - - - - - - - - - - - - lines - lines - - - - - - - - - - - - - - - - - line - line - - - - Mark not set - Mark not set - - - - - - %1 fewer %2 - %1 fewer %2 - - - - - - %1 %2 yanked - %1 %2 yanked - - - - %1 more %2 - %1 more %2 - - - - - - %1 %2 %3ed 1 time - %1 %2 %3ed 1 time - - - - Undo %1 %2 - Undo %1 %2 - - - - - changes - changes - - - - - change - change - - - - Redo %1 %2 - Redo %1 %2 - - - - Mark has invalid line number - マークに無効な行番号があります - - - - - Note has been saved - 保存されました - - - - - Quit - 終了 - - - - - Quit with note having been saved - ノートを保存して終了します - - - - Not an editor command: %1 - エディタのコマンドではありません:%1 - - - - VVimIndicator - - - Register - Register - - - - Value - Value - - - - Registers - Registers - - - - Mark - Mark - - - - Line - Line - - - - Column - Column - - - - Text - Text - - - - Marks - Marks - - - - Normal - 通常 - - - - Insert - Insert - - - - Visual - Visual - - - - VisualLine - VisualLine - - - - Replace - 置換 - - - - Unknown - Unknown - - - - VWebView - - - Expand/Restore Preview Area - プレビュー領域の展開/復元 - - - - &Edit - 編集(&E) - - - - Edit current note - 現在のノートを編集 - - - - Copy As - Copy As - - - - Copy selected content using rules specified by target %1 - ターゲット%1で指定されたルールを使用して選択されたコンテンツをコピーします - - - - Copy All As - すべてコピー - - - - Copy all content using rules specified by target %1 - ターゲット%1で指定されたルールを使用してすべてのコンテンツをコピーします - - - - Live Preview Tunnel - ライブプレビュートンネル - - - - Disabled - 無効 - - - - Editor -> Preview - エディタ->プレビュー - - - - Preview -> Editor - プレビュー->エディタ(Preview->Editor) - - - - Bidirectional - 双方向 - - - - VWordCountPanel - - - - Words - 単語 - - - - - Characters (no spaces) - 文字(空白ふくまず) - - - - - Characters (with spaces) - 文字(空白ふくむ) - - - - Read - 読み取り - - - - Edit - 編集 - - - - Word Count - ワード数 - - - diff --git a/src/translations/vnote_zh_CN.qm b/src/translations/vnote_zh_CN.qm deleted file mode 100644 index 8d9e599e..00000000 Binary files a/src/translations/vnote_zh_CN.qm and /dev/null differ diff --git a/src/translations/vnote_zh_CN.ts b/src/translations/vnote_zh_CN.ts deleted file mode 100644 index 9f79fa84..00000000 --- a/src/translations/vnote_zh_CN.ts +++ /dev/null @@ -1,8932 +0,0 @@ - - - - - QObject - - - All magic words: - 所有幻词: - - - - - - Insert Link - 插入链接 - - - - - No match found - 没有找到匹配 - - - - - Match found: %1 of %2 - 找到匹配: %1/%2 - - - - Replace %1 %2 - 替换了 %1 %2 - - - - occurences - 处匹配 - - - - occurence - 处匹配 - - - - PlainText - 纯文本 - - - - Html - Html - - - - Invalid - 无效 - - - - Insert_Image_HERE - 这里插入图片 - - - - Information - 信息 - - - - Please re-open current opened tabs to make it work. - 请重新打开当前打开页面以生效。 - - - - - Illegal name. Please try again: - 非法名字。请重试: - - - - - Name already exists. Please try again: - 名字已存在。请重试: - - - - Set base font point size %1 - 当前字体大小为 %1 - - - - QWebEnginePage - - - Save &Page - - - - - &Back - - - - - &Forward - - - - - &Reload - - - - - VAttachmentList - - - Add - 添加 - - - - Clear - 清空 - - - - - - - - - Warning - 警告 - - - - Are you sure to clear attachments of note <span style="%1">%2</span>? - 确认删除笔记 <span style="%1">%2</span> 的所有附件? - - - - <span style="%1">WARNING</span>: VNote will delete all the files in directory <span style="%2">%3</span>.Deleted files could be found in the recycle bin of this note.<br>The operation is IRREVERSIBLE! - <span style="%1">警告</span>:VNote会删除位于目录 <span style="%2">%3</span> 中的所有文件。被删除的文件可以在该笔记的回收站中找回。<br>该操作是不可逆的! - - - - Fail to clear attachments of note <span style="%1">%2</span>. - 清空笔记 <span style="%1">%2</span> 的附件失败。 - - - - - - Please check the attachments folder and maintain the configuration file manually. - 请检查附件文件夹并手动维护配置文件。 - - - - Open Folder - 打开所在文件夹 - - - - &Open - 打开 (&O) - - - - Open current attachment file - 打开当前附件文件 - - - - &Delete - 删除 (&D) - - - - Delete selected attachments - 删除选定附件 - - - - &Sort - 排序 (&S) - - - - Sort attachments manually - 对附件进行手动排序 - - - - View and edit current attachment's information - 查看并编辑当前附件的信息 - - - - %1 %2 - %1 %2 - - - - Files - 文件 - - - - File - 文件 - - - - Select Files As Attachments - 选择文件作为附件 - - - - Fail to add attachment %1 for note <span style="%2">%3</span>. - 为笔记 <span style="%2">%3</span> 添加附件 %1 失败。 - - - - %1 %2 added as attachments - %1个%2添加为附件 - - - - files - 文件 - - - - file - 文件 - - - - Copy File Path - 复制文件路径 - - - - &Info (Rename) %1 - 信息 (重命名)(&I) %1 - - - - Are you sure to delete these attachments of note <span style="%1">%2</span>? - 确认删除笔记 <span style="%1">%2</span> 的这些附件? - - - - Deleted files could be found in the recycle bin of this note.<br>Click "Cancel" to leave them untouched. - 被删除的文件可以在该笔记的回收站中找回。<br>点击“取消”以终止操作。 - - - - - Confirm Deleting Attachments - 确认删除附件 - - - - - Fail to delete attachments of note <span style="%1">%2</span>. - 删除笔记 <span style="%1">%2</span> 的附件失败。 - - - - Sort Attachments - 排序附件 - - - - Sort attachments of note <span style="%1">%2</span> in the configuration file. - 对笔记 <span style="%1">%2</span> 的附件在配置文件中进行排序。 - - - - Name - 名字 - - - - Fail to sort attachments of note <span style="%1">%2</span>. - 对笔记 <span style="%1">%2</span> 的附件的排序失败。 - - - - Rename Attachment - 重命名附件 - - - - - Fail to rename attachment <span style="%1">%2</span>. - 重命名附件 <span style="%1">%2</span> 失败。 - - - - VNote detects that these attachments of note <span style="%1">%2</span> are missing in disk. Would you like to remove them from the note? - VNote无法在磁盘中找到笔记 <span style="%1">%2</span> 的这些附件。是否需要将这些附件从笔记中移除? - - - - Click "Cancel" to leave them untouched. - 点击“取消”以终止操作。 - - - - - Attachment Information - 附件信息 - - - - Rename attachment (%1): - 重命名附件 (%1): - - - - Attachment file path copied %1 - 附件文件路径已复制 %1 - - - - VCaptain - - - NavigationMode - 展览模式 - - - - VCart - - - Clear - 清空 - - - - Warning - 警告 - - - - Are you sure to clear Cart? - 确认清空小推车? - - - - &Open - 打开 (&O) - - - - Open selected notes - 打开选定笔记 - - - - &Locate To Folder - 定位所在文件夹 (&L) - - - - Locate the folder of current note - 定位到当前笔记所在的文件夹 - - - - &Delete - 删除 (&D) - - - - Delete selected items from Cart - 从小推车中删除所选项 - - - - &Sort - 排序 (&S) - - - - Sort items in Cart - 对小推车中的项目排序 - - - - %1 %2 - %1 %2 - - - - Items - - - - - Item - - - - - Sort Cart - 排序小推车 - - - - Sort items in Cart. - 对小推车中的项目排序。 - - - - Name - 名字 - - - - VConfirmDeletionDialog - - - Do not ask for confirmation again - 不要再次询问 - - - - %1/%2 Items - %1/%2 项 - - - - VCopyTextAsHtmlDialog - - - Text: - 文本: - - - - HTML: - HTML: - - - - Converting text to HTML ... - 正在将文本转换为HTML ... - - - - Copy Text As HTML (%1) - 复制文本为HTML (%1) - - - - HTML has been copied. Will be closed in 3 seconds. - HTML已复制。将会在3秒内关闭。 - - - - VDeleteNotebookDialog - - - Are you sure to delete notebook <span style="%1">%2</span>? - 确认删除笔记本 <span style="%1">%2</span>? - - - - Delete files from disk - 从磁盘中删除文件 - - - - When checked, VNote will delete all files (including Recycle Bin) of this notebook from disk - 选中后,VNote会从磁盘中删除该笔记本内的所有文件(包括回收站) - - - - <span style="%1">WARNING</span>: VNote may delete <b>ANY</b> files in directory <span style="%2">%3</span> and directory <span style="%2">%4</span>!<br>VNote will try to delete all the root folders within this notebook one by one.<br>It may be UNRECOVERABLE! - <span style="%1">警告</span>:VNote可能会删除位于目录 <span style="%2">%3</span> 和 <span style="%2">%4</span> 中的<b>所有</b>文件!<br>VNote会尝试逐个删除该笔记本下的所有根文件夹。<br>该操作可能是不可恢复的! - - - - VNote won't delete files in directory <span style="%1">%2</span>. - VNote不会删除位于目录 <span style="%1">%2</span> 中的文件。 - - - - VDirInfoDialog - - - Folder &name: - 文件夹名 (&N): - - - - Created time: - 创建时间: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - VDirectory - - - Fail to open folder %1. - 打开文件夹 %1 失败。 - - - - %1 already exists in directory %2. - %1 已经存在于目录 %2 中。 - - - - Fail to create folder in %1. - 在 %1 中新建文件夹失败。 - - - - - - Fail to write configuration of folder %1. - 写入文件夹 %1 的配置失败。 - - - - Fail to delete the directory %1. - 删除目录 %1 失败。 - - - - Fail to remove the folder from the folder configuration. - 从文件夹配置中移除文件夹失败。 - - - - Fail to open target folder. - 打开目标文件夹失败。 - - - - cut - 剪切 - - - - copy - 复制 - - - - Fail to %1 the folder. - %1文件夹失败。 - - - - Fail to add the folder to target folder's configuration. - 将该文件夹添加到目标文件夹的配置失败。 - - - - Skip file %1. - 跳过文件 %1。 - - - - Skip folder %1. - 跳过文件夹 %1。 - - - - VDirectoryTree - - - &Delete - 删除 (&D) - - - - New &Root Folder - 新建根文件夹 (&R) - - - - Delete selected folder - 删除选定文件夹 - - - - View and edit current folder's information - 查看并编辑当前文件夹的信息 - - - - &Copy %1 - 复制 (&C) %1 - - - - Copy selected folders - 复制选定文件夹 - - - - C&ut %1 - 剪切 (&U) %1 - - - - Cut selected folders - 剪切选定文件夹 - - - - &Paste %1 - 粘贴 (&P) %1 - - - - Paste folders in this folder - 在当前文件夹中粘贴所复制的文件夹 - - - &Open Folder Location - 打开文件夹所在位置 (&O) - - - - Reload the content of this folder (or notebook) from disk - 从磁盘中重新加载该文件夹(或笔记本)的内容 - - - - &Sort - 排序 (&S) - - - - Sort folders in this folder/notebook manually - 对该文件夹或笔记本中的文件夹进行手动排序 - - - - - - - - - - - - - - - Warning - 警告 - - - - - Fail to open notebook <span style="%1">%2</span>. - 打开笔记本 <span style="%1">%2</span> 失败。 - - - - Please check if the notebook's root folder <span style="%1">%2</span> exists. - 请检查该笔记本的根文件夹 <span style="%1">%2</span> 是否存在。 - - - - Fail to open folder <span style="%1">%2</span>. - 打开文件夹 <span style="%1">%2</span> 失败。 - - - - Please check if directory <span style="%1">%2</span> exists. - 请检查目录 <span style="%1">%2</span> 是否存在。 - - - - New Sub&folder - 新建子文件夹 (&F) - - - - Create a subfolder in <span style="%1">%2</span>. - 在文件夹 <span style="%1">%2</span> 中新建子文件夹。 - - - - Fail to create subfolder <span style="%1">%2</span>. - 新建子文件夹 <span style="%1">%2</span> 失败。 - - - - Fail to create root folder <span style="%1">%2</span>. - 新建根文件夹 <span style="%1">%2</span> 失败。 - - - - <span style="%1">WARNING</span>: VNote will delete the whole directory <span style="%2">%3</span>.Deleted files could be found in the recycle bin of this folder.<br>The operation is IRREVERSIBLE! - <span style="%1">警告</span>:VNote会删除整个目录 <span style="%2">%3</span>。被删除的文件可以在该文件夹的回收站中找回。<br>该操作是不可逆的! - - - - %1 %2 pasted - 粘贴了%1个%2 - - - - Sort Folders - 排序文件夹 - - - - Sort folders in %1 <span style="%2">%3</span> in the configuration file. - 对%1 <span style="%2">%3</span> 的文件夹在配置文件中进行排序。 - - - - - notebook - 笔记本 - - - - Name - 名字 - - - - Created Time - 创建时间 - - - - Fail to sort folders in %1 <span style="%2">%3</span>. - 对%1 <span style="%2">%3</spacn> 的文件夹排序失败。 - - - - Create Folder - 新建文件夹 - - - S&ort - 排序 (&S) - - - - New &Note - 新建笔记 (&N) - - - - Create a note in selected folder - 在选定文件夹中新建笔记 - - - - New Si&bling Folder - 新建同级文件夹 (&B) - - - - Create a folder in the same parent folder - 在同一父文件夹下新建文件夹 - - - New &Subfolder - 新建子文件夹 (&S) - - - - Reload From Disk - 从磁盘中重新加载 - - - - Open Folder &Location - 打开文件夹所在位置 (&L) - - - - Explore this folder in operating system - 在操作系统中浏览该文件夹 - - - - Pin To History - 钉到历史中 - - - - Pin selected folder to History - 将选定文件夹钉到历史中 - - - - &Info (Rename) %1 - 信息 (重命名)(&I) %1 - - - - Create a root folder in notebook <span style="%1">%2</span>. - 在笔记本 <span style="%1">%2</span> 中新建根文件夹。 - - - - Create Root Folder - 新建根文件夹 - - - - Are you sure to delete folder <span style="%1">%2</span>? - 确认删除文件夹 <span style="%1">%2</span>? - - - - Fail to delete folder <span style="%1">%2</span>.<br>Please check <span style="%1">%3</span> and manually delete it. - 删除文件夹 <span style="%1">%2</span> 失败。<br>请检查 <span style="%1">%3</span> 并手动删除。 - - - - %1 %2 deleted - 删除了%1个%2 - - - - - - folders - 文件夹 - - - - - - - - folder - 文件夹 - - - - Folder Information - 文件夹信息 - - - - Fail to rename folder <span style="%1">%2</span>. - 重命名文件夹 <span style="%1">%2</span> 失败。 - - - - Are you sure to reload folder <span style="%1">%2</span>? - 确认重新加载文件夹 <span style="%1">%2</span>? - - - - Folder %1 reloaded from disk - 文件夹 %1 已从磁盘中重新加载 - - - - Are you sure to reload notebook <span style="%1">%2</span>? - 确认重新加载笔记本 <span style="%1">%2</span>? - - - - Notebook %1 reloaded from disk - 笔记本 %1 已从磁盘中重新加载 - - - - Information - 注意 - - - - VNote will close all the related notes before reload. - VNote会在重新加载前关闭所有相关笔记。 - - - - Please check if path <span style="%1">%2</span> exists. - 请检查路径 <span style="%1">%2</span> 是否存在。 - - - - %1 %2 %3 - %3了%1个%2 - - - - cut - 剪切 - - - - copied - 复制 - - - - Fail to paste folder <span style="%1">%2</span>. - 粘贴文件夹 <span style="%1">%2</span> 失败。 - - - - VNote could not find this folder in any notebook. - VNote无法在任何笔记本中找到该文件夹。 - - - - Fail to copy folder <span style="%1">%2</span>. - 复制文件夹 <span style="%1">%2</span> 失败。 - - - - 1 folder pinned to History - 1个文件夹被钉到历史中 - - - - Please drop it on a folder item. - 请在一个文件夹项上释放。 - - - - Create a root folder in current notebook - 在当前笔记本中新建根文件夹 - - - - Create a subfolder - 新建子文件夹 - - - - VEdit - - - Insert Link - 插入链接 - - - - Found no match - 没有找到匹配项 - - - - Found %1 %2 - 找到 %1 %2 - - - - matches - 处匹配 - - - - match - 处匹配 - - - - Replace %1 %2 - 替换了 %1 %2 - - - - occurences - 处匹配 - - - - occurence - 处匹配 - - - - &Save Changes And Read - 保存更改并阅读 (&S) - - - - Save changes and exit edit mode - 保存对当前笔记的更改并退出编辑模式 - - - - &Discard Changes And Read - 放弃更改并阅读 (&D) - - - - Discard changes and exit edit mode - 放弃对当前笔记的更改并退出编辑模式 - - - - &Edit - 编辑 (&E) - - - - Edit current note - 编辑当前笔记 - - - - VEditArea - - - ActivateTab1 - 激活标签页1 - - - - ActivateTab2 - 激活标签页2 - - - - ActivateTab3 - 激活标签页3 - - - - ActivateTab4 - 激活标签页4 - - - - ActivateTab5 - 激活标签页5 - - - - ActivateTab6 - 激活标签页6 - - - - ActivateTab7 - 激活标签页7 - - - - ActivateTab8 - 激活标签页8 - - - - ActivateTab9 - 激活标签页9 - - - - AlternateTab - 轮换标签页 - - - - OpenedFileList - 已打开笔记列表 - - - - ActivateSplitLeft - 激活左分割 - - - - ActivateSplitRight - 激活右分割 - - - - MoveTabSplitLeft - 左移标签页一个分割窗口 - - - - MoveTabSplitRight - 右移标签页一个分割窗口 - - - - ActivateNextTab - 激活下一个标签页 - - - - ActivatePreviousTab - 激活上一个标签页 - - - - VerticalSplit - 垂直分割 - - - - RemoveSplit - 移除分割 - - - - MaximizeSplit - 最大化分割 - - - - DistributeSplits - 分布分割 - - - - MagicWord - 幻词 - - - - ApplySnippet - 应用片段 - - - - LivePreview - 实时预览 - - - - ExpandLivePreview - 扩展实时预览 - - - - ParseAndPaste - 解析并粘贴 - - - - VEditSnippetDialog - - - None - - - - - String in the content to mark the cursor position - 在片段内容中用于表示光标位置的文本 - - - - String in the content to be replaced with selected text - 在片段内容中用于表示所选文本的文本 - - - - Auto indent - 自动缩进 - - - - Auto indent the content according to the first line - 按照第一行自动缩进片段内容 - - - - Snippet &name: - 片段名字 (&N): - - - - Snippet &type: - 片段类型 (&T): - - - - Shortc&ut: - 快捷键 (&U): - - - - Cursor &mark: - 光标标记 (&M): - - - - &Selection mark: - 选择标记 (&S): - - - - &Content: - 内容 (&C): - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - <span style="%1">WARNING</span>: Cursor mark <span style="%2">%3</span> occurs more than once in the content (after magic word evaluation). Please choose another mark. - <span style="%1">警告</span>:光标标记 <span style="%2">%3</span> 在片段内容中出现了多次(解析幻词之后)。请选择另一个标记。 - - - - <span style="%1">WARNING</span>: Cursor mark <span style="%2">%3</span> conflicts with selection mark. Please choose another mark. - <span style="%1">警告</span>:光标标记 <span style="%2">%3</span> 和选择标记冲突。请选择另一个标记。 - - - - VEditTab - - - Information - 注意 - - - - Note <span style="%1">%2</span> has been modified by another program. - 笔记 <span style="%1">%2</span> 已经被另一个程序更改。 - - - - Do you want to reload it? - 是否重新载入? - - - - Warning - 警告 - - - - Fail to reload note <span style="%1">%2</span>. - 重新加载笔记 <span style="%1">%2</span> 失败。 - - - - Please check if file %1 exists. - 请检查文件 %1 是否存在。 - - - - VEditWindow - - - Locate To Folder - 定位所在文件夹 - - - - Locate the folder of current note - 定位到当前笔记所在的文件夹 - - - - Move One Split Left - 左移一个分割窗口 - - - - Move current tab to the split on the left - 将当前标签页往左移动一个分割窗口 - - - - Move One Split Right - 右移一个分割窗口 - - - - Move current tab to the split on the right - 将当前标签页往右移动一个分割窗口 - - - - Close Tab - 关闭标签页 - - - - Close current note tab - 关闭当前标签页 - - - - Close Other Tabs - 关闭其他标签页 - - - - Close all other note tabs - 关闭其他所有标签页 - - - - Close All Tabs - 关闭所有标签页 - - - - Close all the note tabs - 关闭所有标签页 - - - - Maximize Split - 最大化分割 - - - - Maximize current split window - 最大化当前分割窗口 - - - - Distribute Splits - 分布分割 - - - - Distribute all the split windows evenly - 均等分布所有分割窗口 - - - - Close Tabs To The Right - 关闭右侧标签页 - - - - Close all the note tabs to the right of current tab - 关闭当前标签页右侧所有标签页 - - - - Note Info - 笔记信息 - - - - View and edit information of the note - 查看并编辑笔记的信息 - - - - Add To Cart - 添加到小推车 - - - - Explore the folder containing this note in operating system - 在操作系统中浏览包含该笔记的文件夹 - - - - Add this note to Cart for further processing - 将该笔记添加到小推车以进一步处理 - - - - 1 note added to Cart - 1个笔记添加到小推车 - - - - Open Note Location - 打开笔记所在位置 - - - - Reload From Disk - 从磁盘中重新加载 - - - - Reload the content of this note from disk - 从磁盘中重新加载该笔记的内容 - - - - &Recycle Bin - 回收站 (&R) - - - - Open the recycle bin of this note - 打开该笔记的回收站 - - - - Opened Notes List - 已打开笔记列表 - - - - Remove Split - 移除分割 - - - - Pin To History - 钉到历史中 - - - - Pin this note to History - 将该笔记钉到历史中 - - - - 1 note pinned to History - 1个笔记被钉到历史中 - - - - Set As Quick Access - 设为快速访问 - - - - Set this note as quick access - 将该笔记设为快速访问 - - - - Quick access: %1 - 快速访问: %1 - - - - Split - 分割 - - - - Split current window vertically - 垂直分割当前窗口 - - - - Remove current split window - 移除当前分割窗口 - - - - Menu - 菜单 - - - - VExplorer - - - Directory - 目录 - - - - Open - 打开 - - - - Select Root Directory To Explore - 选择浏览的根目录 - - - - Up - 向上 - - - - Open Directory Location - 打开目录所在位置 - - - - - Star - 收藏 - - - - Path of the root directory to explore - 浏览的根目录的路径 - - - - Root path to explore - 浏览根路径 - - - - Image Folder - 图片文件夹 - - - - Use global configuration (%1) - 使用全局配置 (%1) - - - - Set the path of the image folder to store images of files within the root directory. -If absolute path is used, VNote will not manage those images.(empty to use global configuration) - 设置根目录下的文件的图片文件夹的路径以保存相关图片。 -如果使用绝对路径,VNote不会管理这些图片。(为空则使用全局配置) - - - - - - New File - 新建文件 - - - - - - New Folder - 新建文件夹 - - - - Warning - 警告 - - - - Fail to open directory <span style="%1">%2</span>. - 打开目录 <span style="%1">%2</span> 失败。 - - - - Please check if the directory exists. - 请检查目录是否存在。 - - - - Unstar - 取消收藏 - - - - Set As Root - 设为根目录 - - - - Set current folder as the root directory to explore - 设置当前文件夹为浏览根目录 - - - - Open Folder Location - 打开文件夹所在位置 - - - - Explore this folder in operating system - 在操作系统中浏览该文件夹 - - - - - &Info (Rename) %1 - 信息 (重命名)(&I) %1 - - - - View and edit current folder's information - 查看并编辑当前文件夹的信息 - - - - Open In Read Mode - 以阅读模式打开 - - - - Open selected files in read mode - 以阅读模式打开选定笔记 - - - - Open In Edit Mode - 以编辑模式打开 - - - - Open selected files in edit mode - 以编辑模式打开选定笔记 - - - - Open File Location - 打开文件所在位置 - - - - Explore the folder containing this file in operating system - 在操作系统中浏览包含该文件的文件夹 - - - - Add To Cart - 添加到小推车 - - - - Add selected files to Cart for further processing - 将所选文件添加到小推车以进一步处理 - - - - %1 %2 added to Cart - %1个%2添加到小推车 - - - - - files - 文件 - - - - - file - 文件 - - - - Pin To History - 钉到历史中 - - - - Pin selected files to History - 将选定文件钉到历史中 - - - - %1 %2 pinned to History - %1个%2被钉到历史中 - - - - View and edit current file's information - 查看并编辑当前文件的信息 - - - - File name (%1): - 文件名 (%1): - - - - Fail to create file <span style="%1">%2</span>. - 新建文件 <span style="%1">%2</span> 失败。 - - - - Folder name (%1): - 文件夹名 (%1): - - - - Fail to create folder <span style="%1">%2</span>. - 新建文件夹 <span style="%1">%2</span> 失败。 - - - - - File Information - 文件信息 - - - - Rename file (%1): - 重命名文件 (%1): - - - - Fail to rename file <span style="%1">%2</span>. - 重命名文件 <span style="%1">%2</span> 失败。 - - - - VExportDialog - - - Choose notes to export - 选择需要导出的笔记 - - - - Choose target format to export as - 选择导出的目标格式 - - - - Choose converter to render Markdown - 选择渲染Markdown的渲染器 - - - - Choose rendering background color for Markdown - 选择Markdown的渲染背景色 - - - - Choose rendering style for Markdown - 选择Markdown的渲染样式 - - - - Choose rendering code block style for Markdown - 选择Markdown的代码块渲染样式 - - - - - &Browse - 浏览文件 (&B) - - - - Information - 信息 - - - - Advanced Settings - 高级设置 - - - - Output logs will be shown here - 输出日志会显示在这里 - - - - - Export - 导出 - - - - Cancelling the export... - 正在取消导出... - - - - Notes to export: - 导出笔记: - - - - Target format: - 目标格式: - - - - Markdown renderer: - Markdown渲染器: - - - - Markdown rendering background: - Markdown渲染背景色: - - - - Markdown rendering style: - Markdown渲染样式: - - - - Markdown rendering code block style: - Markdown代码块渲染样式: - - - - Output directory: - 输出目录: - - - - Settings - 设置 - - - - Enable Table Of Contents - 启用目录 - - - - Add a table of contents to the document - 添加一个目录到文档中 - - - - Use wkhtmltopdf - 使用wkhtmltopdf - - - - Use wkhtmltopdf tool to generate PDF (wkhtmltopdf needed to be installed) - 使用wkhtmltopdf工具创建PDF(需要安装wkhtmltopdf) - - - - Download wkhtmltopdf - 下载wkhtmltopdf - - - - Tell VNote where to find wkhtmltopdf tool - 告诉VNote在哪里找到wkhtmltopdf工具 - - - - - - Empty to use the name of the first source file - 为空则使用第一个源文件的名字 - - - - Title of the generated PDF file - 创建的PDF文件的标题 - - - - Name of the generated PDF file - 创建的PDF文件的名字 - - - - Enable background - 启用背景 - - - - Enable background when printing - 打印渲染的时候启用背景 - - - - Append page number as footer - 添加页码作为页脚 - - - - Additional global options passed to wkhtmltopdf - 传给wkhtmltopdf的额外全局选项 - - - - Use " to enclose options containing spaces - 使用"来引用包含空格的选项 - - - - Page layout: - 页面布局: - - - - wkhtmltopdf path: - wkhtmltopdf路径: - - - - Title: - 标题: - - - - - Output file name: - 输出文件名: - - - - Page number: - 页码: - - - - Additional options: - 其他参数: - - - - Embed CSS styles - 嵌入CSS样式 - - - - Embed CSS styles in HTML file - 在HTML中嵌入CSS样式 - - - - Embed images - 嵌入图片 - - - - Embed images as data URI - 将图片作为URI嵌入 - - - - Complete page - 完整页面 - - - - Export the whole web page along with pictures which may not keep the HTML link structure of the original page - 导出包括图片在内的整个网络页面(可能会更改原来页面的HTML链接结构) - - - - MIME HTML - MIME HTML - - - - Export as a complete web page in MIME HTML format - 作为MIME HTML格式导出为一个完整网页 - - - - Enable outline panel - 启用大纲侧栏 - - - - Add an outline panel in HTML file - 在HTML文件里面添加一个大纲侧边栏 - - - - Process subfolders - 处理子文件夹 - - - - Process subfolders recursively - 递归处理子文件夹 - - - - Current Note (%1) - 当前笔记 (%1) - - - - Fail to start wkhtmltopdf (%1). - 启动wkhtmltopdf失败 (%1)。 - - - - wkhtmltopdf crashed (%1). - wkhtmltopdf崩溃 (%1)。 - - - - Use %1 (%2). - 使用%1 (%2)。 - - - - - %1 notes exported to %2. - 导出了 %1 个笔记为 %2。 - - - - Fail to export %1 notes in one PDF. - 导出 %1 个笔记为一个PDF失败。 - - - - Fail to export %1 notes in one. - 导出 %1 个笔记为一个文件失败。 - - - - Choose format of the input - 选择输入的格式 - - - - Without the preceding dot - 去掉前导点号(.) - - - - Suffix of the output file without the preceding dot - 输出文件的后缀名,不包括前导点号(.) - - - - Enable All In One - 启用多合一 - - - - Pass a list of input files to the custom command - 传递一个输入文件列表给自定义命令 - - - - PDF-Like - 类PDF - - - - Treat the exported file as PDF, such as wrapping line - 将导出的文件作为PDF处理,例如自动换行 - - - - - Separator to concatenate input files directories - 用于连接输入文件所在目录的分隔符 - - - - Name of the generated All-In-One file - 创建的多合一文件的名字 - - - - Custom command to be executed - 需要执行的自定义命令 - - - - Source format: - 源格式: - - - - Output suffix: - 输出后缀名: - - - - Input directories separator: - 输入文件所在目录分隔符: - - - - Open Directory - 打开目录 - - - - Open output directory - 打开输出目录 - - - - Copy Content - 复制内容 - - - - Copy the content of the exported file - 复制导出文件的内容 - - - - Copied content of file %1 - 已经复制文件 %1 内容 - - - - Fail to copy content of file %1 - 复制文件 %1 内容失败 - - - - Current Folder (%1) - 当前文件夹 (%1) - - - - Current Notebook (%1) - 当前笔记本 (%1) - - - - Cart (%1) - 小推车 (%1) - - - - - Markdown - Markdown - - - - - HTML - HTML - - - - PDF - PDF - - - - PDF (All In One) - PDF (多合一) - - - - Custom - 自定义 - - - - Hoedown - Hoedown - - - - Marked - Marked - - - - Markdown-it - Markdown-it - - - - Showdown - Showdown - - - - System - 默认 - - - - Transparent - 透明 - - - - None - - - - - Left - 居左 - - - - Center - 居中 - - - - Right - 居右 - - - - Export to %1. - 导出到 %1 。 - - - - Invalid configurations for custom export. - 非法的自定义导出配置。 - - - - User cancelled the export. Aborted! - 用户取消导出。终止! - - - - Warning - 警告 - - - - Errors found during export. - 导出过程中发生错误。 - - - - %1 notes exported. - 导出了 %1 个笔记。 - - - - Select Output Directory To Export To - 选择导出输出目录 - - - - Executable (*.exe) - 可执行文件 (*.exe) - - - - Select wkhtmltopdf Executable - 选择wkhtmltopdf可执行文件 - - - - Exporting note %1. - 正在导出笔记 %1 。 - - - - Fail to open folder %1. - 打开文件夹 %1 失败。 - - - - - - - - - - - Fail to create directory %1. - 创建目录 %1 失败。 - - - - Fail to open notebook %1. - 打开笔记本 %1 失败。 - - - - Fail to open file %1. - 打开文件 %1 失败。 - - - - Skip exporting non-Markdown file %1 as Markdown. - 跳过非Markdown文件 %1 。 - - - - Fail to copy the note file %1. - 复制笔记文件 %1 失败。 - - - - Fail to copy images of note %1. - 复制笔记的图片 %1 失败。 - - - - Fail to copy attachments folder %1 to %2. - 复制附件文件夹 %1 到 %2 失败。 - - - - - - - Note %1 exported to %2. - 笔记 %1 导出为 %2 。 - - - - Skip exporting non-Markdown file %1 as PDF. - 跳过非Markdown文件 %1 。 - - - - - - Fail to export note %1. - 导出笔记 %1 失败。 - - - - Skip exporting non-Markdown file %1 as HTML. - 跳过非Markdown文件 %1 。 - - - - Skip exporting non-Markdown file %1. - 跳过非Markdown文件 %1 。 - - - - Portrait - 纵向 - - - - Landscape - 横向 - - - - <span><span style="font-weight:bold;">%0</span> for the input file; <span style="font-weight:bold;">%1</span> for the output file; <span style="font-weight:bold;">%2</span> for the rendering CSS style file; <span style="font-weight:bold;">%3</span> for the input file directory; <span style="font-weight:bold;">%4</span> for the rendering code block CSS style file.</span> - <span><span style="font-weight:bold;">%0</span> 表示输入文件; <span style="font-weight:bold;">%1</span> 表示输出文件; <span style="font-weight:bold;">%2</span> 表示渲染的CSS样式文件; <span style="font-weight:bold;">%3</span> 表示输入文件所在目录; <span style="font-weight:bold;">%4</span> 表示渲染的代码块CSS样式文件。</span> - - - - VExporter - - - Fail to start wkhtmltopdf (%1). - 启动wkhtmltopdf失败 (%1)。 - - - - wkhtmltopdf crashed (%1). - wkhtmltopdf崩溃 (%1)。 - - - - Fail to start custom command (%1). - 启动自定义命令失败 (%1)。 - - - - Custom command crashed (%1). - 自定义命令崩溃 (%1)。 - - - - QProcess error %1. - QProcess错误 %1 。 - - - - VFileInfoDialog - - - Will be assigned when adding attachments - 添加附件时分配 - - - - The folder to hold attachments of this note - 保存该笔记的附件的文件夹 - - - - Last modified time within VNote - 在VNote中的最近修改时间 - - - Tags of this note separated by , - 该笔记的标签,由逗号,分隔 - - - - Add tags to a note at the right bottom status bar when it is opened - 打开笔记后在状态栏右下角添加标签 - - - - Tags of this note separated by , (%1) - 该笔记的标签,由逗号,分隔 (%1) - - - - Note &name: - 笔记名 (&N): - - - - File path: - 文件路径: - - - - Attachment folder: - 附件文件夹: - - - - Created time: - 创建时间: - - - - Modified time: - 修改时间: - - - - Tags: - 标签: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - <span style="%1">WARNING</span>: Changing type of the note is not supported. Please use the same suffix as the old one. - <span style="%1">警告</span>:不支持修改笔记的类型。请使用原来的后缀名。 - - - - VFileList - - - &New Note - 新建笔记 (&N) - - - - &Open In Read Mode - 以阅读模式打开 (&O) - - - - Open current note in read mode - 以阅读模式打开当前笔记 - - - - Open In &Edit Mode - 以编辑模式打开 (&E) - - - - Open current note in edit mode - 以编辑模式打开当前笔记 - - - - &Delete - 删除 (&D) - - - - Delete selected note - 删除选定笔记 - - - - &Sort - 排序 (&S) - - - - Sort notes in this folder manually - 对该文件夹中的笔记进行手动排序 - - - - Are you sure to delete these notes? - 确认删除这些笔记? - - - - <span style="%1">WARNING</span>: VNote will delete notes as well as all their images and attachments managed by VNote. Deleted files could be found in the recycle bin of these notes.<br>Click "Cancel" to leave them untouched.<br>The operation is IRREVERSIBLE! - <span style="%1">警告</span>:VNote会删除这些笔记以及这些笔记所有由VNote管理的图片和附件。被删除的文件可以在这些笔记的回收站中找回。<br>点击“取消”终止操作。<br>该操作是不可逆的! - - - - Confirm Deleting Notes - 确认删除笔记 - - - - Fail to delete note <span style="%1">%2</span>.<br>Please check <span style="%1">%3</span> and manually delete it. - 删除笔记 <span style="%1">%2</span> 失败。<br>请检查 <span style="%1">%3</span> 并手动删除。 - - - - %1 %2 deleted - 删除了%1个%2 - - - - - - - - notes - 笔记 - - - - Notes - 笔记 - - - - Add To Cart - 添加到小推车 - - - - Add selected notes to Cart for further processing - 将所选笔记添加到小推车以进一步处理 - - - - %1 %2 added to Cart - %1个%2添加到小推车 - - - - View - 查看 - - - - Split - 分割 - - - - - - - - note - 笔记 - - - - %1 %2 pinned to History - %1个%2被钉到历史中 - - - - Quick access: %1 - 快速访问: %1 - - - - %1 - -Created Time: %2 -Modified Time: %3 - %1 - -创建时间: %2 -修改时间: %3 - - - - Open Note &Location - 打开笔记所在位置 (&L) - - - - Explore the folder containing this note in operating system - 在操作系统中浏览包含该笔记的文件夹 - - - Copy File Path - 复制文件路径 - - - - File path copied %1 - 文件路径已复制 %1 - - - - Pin To History - 钉到历史中 - - - - Pin selected notes to History - 将选定笔记钉到历史中 - - - - Set As Quick Access - 设为快速访问 - - - - Set current note as quick access - 将当前笔记设为快速访问 - - - - &Info (Rename) %1 - 信息 (重命名)(&I) %1 - - - - Skip importing non-exist file %1. - 跳过导入不存在的文件 %1。 - - - - Skip importing file %1. A note with the same name (case-insensitive) in the same directory already exists. - 跳过导入文件 %1 。在该文件同目录下已经存在一个同名笔记(不区分大小写)。 - - - - Fail to copy file %1 as %2. - 复制文件 %1 为 %2 失败。 - - - - Fail to add the note %1 to target folder's configuration. - 将该笔记 %1 添加到目标文件夹的配置失败。 - - - - %1 %2 %3 - %3了%1个%2 - - - - cut - 剪切 - - - - copied - 复制 - - - - Fail to paste note <span style="%1">%2</span>. - 粘贴笔记 <span style="%1">%2</span> 失败。 - - - - VNote could not find this note in any notebook. - VNote无法在任何笔记本中找到该笔记。 - - - - VNote does not allow copy and paste notes with internal images in the same folder. - VNote不允许在同一个文件夹中复制并粘贴带有内部图片的笔记。 - - - - %1 %2 pasted - 粘贴了%1个%2 - - - - Sort Notes - 排序笔记 - - - - Sort notes in folder <span style="%1">%2</span> in the configuration file. - 对文件夹 <span style="%1">%2</span> 的笔记在配置文件中进行排序。 - - - - Name - 名字 - - - - Created Time - 创建时间 - - - - Modified Time - 修改时间 - - - - Fail to sort notes in folder <span style="%1">%2</span>. - 对文件夹 <span style="%1">%2</spacn> 的笔记排序失败。 - - - - Open With - 其他打开方式 - - - - Open current note with %1 - 使用 %1 打开当前笔记 - - - - System's Default Program - 系统默认程序 - - - - Open current note with system's default program - 使用系统默认程序打开当前笔记 - - - - - Add External Program - 添加外部程序 - - - - Add external program - 添加外部程序 - - - - %1 %2 - %1 %2 - - - - Items - - - - - Item - - - - - View By Configuration File - 按配置文件查看 - - - - View By Name - 按名字查看 - - - - View By Name (Reverse) - 按名字查看(倒序) - - - - View By Created Time - 按创建时间查看 - - - - View By Created Time (Reverse) - 按创建时间查看(倒序) - - - - View By Modified Time - 按修改时间查看 - - - - View By Modified Time (Reverse) - 按修改时间查看(倒序) - - - - View and edit current note's information - 查看并编辑当前笔记的信息 - - - - Copy selected notes - 复制选定笔记 - - - - Cut selected notes - 剪切选定笔记 - - - - Note Information - 笔记信息 - - - - Fail to rename note <span style="%1">%2</span>. - 重命名笔记 <span style="%1">%2</span> 失败。 - - - - Create a note in <span style="%1">%2</span>. - 在目录 <span style="%1">%2</span> 中新建笔记。 - - - - Note with name ending with "%1" will be treated as Markdown type. - 名字后缀为“%1”的笔记是Markdown笔记。 - - - - Fail to create note <span style="%1">%2</span>. - 新建笔记 <span style="%1">%2</span> 失败。 - - - - Copy File &Path - 复制文件路径 (&P) - - - - - Fail to copy note <span style="%1">%2</span>. - 复制笔记 <span style="%1">%2</span> 失败。 - - - - Create a note in current folder - 在当前文件夹中新建笔记 - - - - &Copy %1 - 复制 (&C) %1 - - - - C&ut %1 - 剪切 (&U) %1 - - - - &Paste %1 - 粘贴 (&P) %1 - - - - Paste notes in current folder - 在当前文件夹中粘贴笔记 - - - &Open Note Location - 打开笔记所在位置 (&O) - - - - Create Note - 新建笔记 - - - - - - - - - - Warning - 警告 - - - - VFindReplaceDialog - - - Find/Replace - 查找/替换 - - - - Find: - 查找: - - - - Enter text to search - 输入要查找的文本 - - - - Find &Next - 查找下一个 (&N) - - - - Find &Previous - 查找上一个 (&P) - - - - &Replace with: - 替换 (&R): - - - - \1, \2 for back reference in regular expression - 使用\1,\2作为正则表达式中的向后引用 - - - - - &Advanced >>> - 高级 (&A) >>> - - - - B&asic <<< - 基本 (&A) <<< - - - - Replace - 替换 - - - - Replace && Fin&d - 替换并查找 (&D) - - - - Replace A&ll - 全部替换 (&L) - - - - &Case sensitive - 区分大小写 (&C) - - - - &Whole word only - 完整字词匹配 (&W) - - - - Re&gular expression - 正则表达式 (&G) - - - - &Incremental search - 增量查找 (&I) - - - - VFixNotebookDialog - - - VNote could not find the root folder of notebook <span style="%1">%2</span>. Please specify the new path to the root folder if you moved it somewhere, or VNote will just remove this notebook. - VNote无法找到笔记本<span style="%1">%2</span>的根文件夹。如果您迁移了该笔记本,请指定根文件夹的新路径,否则VNote会移除该笔记本。 - - - - &Browse - 浏览文件 (&B) - - - - Use relative path - 使用相对路径 - - - - Use relative path (to VNote's executable) in configuration file - 在配置文件中使用相对路径(相对于VNote的可执行文件) - - - - Notebook name: - 笔记本名: - - - - Notebook root folder: - 笔记本根文件夹: - - - - Fix Notebook - 修复笔记本 - - - - Select Root Folder Of The Notebook - 选择笔记本根文件夹 - - - - <span style="%1">WARNING</span>: The folder chosen is NOT a valid root folder of a notebook. - <span style="%1">警告</span>:所选择的文件夹并不是一个有效的笔记本根文件夹。 - - - - <span style="%1">WARNING</span>: Please specify absolute path. - <span style="%1">警告</span>:请使用一个绝对路径。 - - - - <span style="%1">WARNING</span>: The folder chosen has already been a root folder of existing notebook <span style="%2">%3</span> in VNote. - <span style="%1">警告</span>:所选的文件夹已经是当前VNote中一个笔记本 <span style="%2">%3</span> 的根文件夹。 - - - - <span style="%1">WARNING</span>: Please choose a folder in the same drive as <span style="%2">%3</span> when relative path is enabled. - <span style="%1">警告</span>:使用相对路径时,请选择一个和 <span style="%2">%3</span> 在同一驱动器的文件夹。 - - - - VGeneralTab - - - Choose the language of VNote interface - 选择VNote界面语言 - - - - - System - 默认 - - - - Path of file to quick access - 快速访问文件路径 - - - - Set the path of a file to quick access (absolute or relative to configuration folder) - 设置一个文件路径以快速访问(绝对路径或者相对于配置文件夹的相对路径) - - - - Select File To Quick Access - 选择文件以快速访问 - - - - Choose the keyboard layout mapping to use in shortcuts - 选择在快捷键中使用的键盘布局映射 - - - - Choose the OpenGL implementation to load (restart VNote to make it work) - 选择需要加载的OpenGL实现(重启VNote生效) - - - - Edit - 编辑 - - - - Language: - 语言: - - - - Startup pages: - 启动页面: - - - - Quick access: - 快速访问: - - - - Keyboard layout mapping: - 键盘布局映射: - - - - OpenGL: - OpenGL: - - - - Restore tabs or open specific notes on startup - 在启动时恢复标签页或打开指定笔记 - - - - - None - - - - - Continue where you left off - 继续上次退出时的页面 - - - - Open specific pages - 打开指定页面 - - - - Absolute path of the notes to open on startup (one note per line) - 需要在启动时打开的笔记的绝对路径(一行一个笔记) - - - - DesktopOpenGL - DesktopOpenGL - - - - OpenGLES - OpenGLES - - - - SoftwareOpenGL - SoftwareOpenGL - - - - - Browse - 浏览文件 - - - - Select files to add as startup pages - 选择文件添加为启动页面 - - - - Select Files As Startup Pages - 选择文件作为启动页面 - - - - System tray - 系统托盘 - - - - Minimized to the system tray after closing VNote (not supported in macOS) - 关闭VNote后最小化到系统托盘(不支持macOS) - - - - VGiteeImageHosting - - - - - - - - - - - - - Gitee Image Hosting - Gitee图床 - - - - - Please configure the Gitee image hosting first! - 请先配置Gitee图床! - - - - Uploading images to Gitee... - 正在上传图片到Gitee ... - - - - Abort - 终止 - - - - Uploading Images To Gitee - 正在上传图片到Gitee - - - - - Unsupported type: - 不支持的类型: - - - - No local images to upload: %1 - 没有需要上传的本地图片: %1 - - - - Authentication failed: - 验证失败: - - - - - -Please check your Gitee Image Hosting parameters! - - -请检查Gitee图床参数! - - - - Network error: - 网络错误: - - - - - -Please check your network! - - -请检查网络! - - - - Uploading image: %1 - 正在上传图片: %1 - - - - The picture does not exist in this path: - 图片不存在: - - - - JSON decode error. Please contact the developer. - JSON解析错误。请联系开发者。 - - - - Gitee status code != 201. Please contact the developer. - Gitee返回代码不是201。请联系开发者。 - - - - Uploading - 正在上传 - - - - - -Network error: - - -网络错误: - - - - - -Please check the network or image size - - -请检查网络或图片尺寸 - - - - Copied contents with new image links - 已复制替换新图片链接的内容 - - - - VGithubImageHosting - - - - Please configure the GitHub image hosting first! - 请先配置GitHub图床! - - - - - - - - - - - - - - GitHub Image Hosting - GitHub图床 - - - - Bad credentials! - 凭证无效! - - - - Please check your GitHub Image Hosting parameters! - 请检查GitHub图床参数! - - - - Uploading images to GitHub... - 正在上传图片到GitHub ... - - - - Abort - 终止 - - - - Uploading Images To Github - 正在上传图片到GitHub - - - - - Unsupported type: - 不支持的类型: - - - - No local images to upload: %1 - 没有需要上传的本地图片: %1 - - - - Network error: - 网络错误: - - - - - -Please check your network! - - -请检查网络! - - - - Uploading image: %1 - 正在上传图片: %1 - - - - The picture does not exist in this path: - 图片不存在: - - - - JSON decode error. Please contact the developer. - JSON解析错误。请联系开发者。 - - - - GitHub status code != 201. Please contact the developer. - GitHub返回代码不是201。请联系开发者。 - - - - Uploading - 正在上传 - - - - - -Network error: - - -网络错误: - - - - - -Please check the network or image size - - -请检查网络或图片尺寸 - - - - Copied contents with new image links - 已复制替换新图片链接的内容 - - - - VHelpUE - - - View help information about Universal Entry - 查看通用入口的帮助信息 - - - - Esc or Ctrl+[: Hide Universal Entry - Esc或Ctrl+[: 隐藏通用入口 - - - - Ctrl+U: Clear the command input - Ctrl+U: 清除命令输入 - - - - Ctrl+E: Clear the command input except the entry key - Ctrl+E: 清除命令输入但保留入口键 - - - - Ctrl+F: Select the entry key to change - Ctrl+F: 选取入口键文本以修改 - - - - Ctrl+D: Cancel the command - Ctrl+D: 取消命令 - - - - Ctrl+J: Go to next item - Ctrl+J: 跳转到下一项 - - - - Ctrl+K: Go to previous item - Ctrl+K: 跳转到上一项 - - - - Ctrl+L: Go to current item's parent item - Ctrl+L: 跳转到当前项的父项 - - - - Ctrl+I: Expand/Collapse current item - Ctrl+I: 展开/折叠当前项 - - - - Ctrl+B: Expand/Collapse all items - Ctrl+B: 展开/折叠全部 - - - - Ctrl+S: Sort items - Ctrl+S: 排序 - - - - Enter: Activate current item - Enter: 激活当前项 - - - - Ctrl+M: Browse current item folder or the folder containing current item - Ctrl+M: 浏览当前文件夹项或包含当前项的文件夹 - - - - Magic Switches: - 魔幻开关: - - - - \c or \C: Case insensitive or sensitive - \c或\C: 大小写不敏感或敏感 - - - - \r or \R: Disable or enable regular expression - \r或\R: 禁用或启用正则表达式 - - - - \f or \F: Disable or enable fuzzy search - \f或\F: 禁用或启用模糊搜索 - - - - \w or \W: Disable or enable whole word only - \w或\W: 禁用或启用完整字词匹配 - - - - VHistoryList - - - Clear - 清空 - - - - Warning - 警告 - - - - Are you sure to clear History? - 确认清空历史? - - - - Pinned - 钉住的 - - - - Today - 今天 - - - - Yesterday - 昨天 - - - - Last 7 Days - 过去7天 - - - - Older - 更旧的 - - - - &Open - 打开 (&O) - - - - Open selected notes - 打开选定笔记 - - - - &Locate To Folder - 定位所在文件夹 (&L) - - - - Locate the folder of current note - 定位到当前笔记所在的文件夹 - - - - Pin - 钉住 - - - - Pin selected notes in History - 将选定笔记钉到历史中 - - - - Unpin - 取消钉住 - - - - Unpin selected notes in History - 在历史中取消钉住选定笔记 - - - - Add To Cart - 添加到小推车 - - - - Add selected notes to Cart for further processing - 将所选笔记添加到小推车以进一步处理 - - - - %1 %2 added to Cart - %1个%2添加到小推车 - - - - notes - 笔记 - - - - note - 笔记 - - - - VHtmlTab - - - Information - 注意 - - - - Note <span style="%1">%2</span> has been modified. - 笔记 <span style="%1">%2</span> 已经被更改。 - - - - Do you want to save your changes? - 是否保存更改? - - - - - - Warning - 警告 - - - - Could not modify a read-only note <span style="%1">%2</span>. - 无法修改只读笔记 <span style="%1">%2</span>。 - - - - Please save your changes to other notes manually. - 请手动保存更改到其他笔记。 - - - - - Fail to save note. - 保存笔记失败。 - - - - File <span style="%1">%2</span> being written has been removed. - 将要写入的文件 <span style="%1">%2</span> 已经被移除。 - - - - Fail to write to disk when saving a note. Please try it again. - 保存笔记时,写入文件失败。请稍后再试。 - - - - VImageHostingTab - - - GitHub - GitHub - - - - Gitee - Gitee - - - - WeChat - 微信 - - - - Tencent Cloud - 腾讯云 - - - - GitHub personal access token - GitHub个人访问令牌 - - - - Name of GitHub repository for image hosting - GitHub图床仓库名字 - - - - User name of GitHub - GitHub用户名 - - - - - - - Keep image scale(such as '=100x') - 保留图片缩放(如 '=100x') - - - - - - - Copy the new content instead of replacing - 复制而非替换新内容 - - - - - Personal access token: - 个人访问令牌: - - - - - Repo name: - 仓库名: - - - - - User name: - 用户名: - - - - Gitee personal access token - Gitee个人访问令牌 - - - - Name of Gitee repository for image hosting - Gitee图床仓库名字 - - - - User name of Gitee - Gitee用户名 - - - - AppId: - - - - - AppSecret: - - - - - markdown2WechatToolUrl: - - - - - Tencent access domain name - - - - - Access domain name: - - - - - SecretId: - - - - - SecretKey: - - - - - VInsertImageDialog - - - &Browse - 浏览文件 (&B) - - - - From: - 图片源: - - - - Title: - 标题: - - - - Scaling width: - 缩放宽度: - - - - Select The Image To Be Inserted - 选择要插入的图片 - - - - Images (*.png *.xpm *.jpg *.bmp *.gif *.svg) - 图片 (*.png *.xpm *.jpg *.bmp *.gif *.svg) - - - - VInsertLinkDialog - - - Absolute or relative path of the link - 链接的绝对或相对路径 - - - - &Text: - 文本 (&T): - - - - &URL: - URL (&U): - - - - VInsertTableDialog - - - Number of rows of the table body - 表格正文行数 - - - - Number of columns of the table - 表格列数 - - - - None - - - - - Left - 居左 - - - - Center - 居中 - - - - Right - 居右 - - - - Row: - 行: - - - - Column: - 列: - - - - Alignment: - 对齐: - - - - Insert Table - 插入表格 - - - - VKeyboardLayoutMappingDialog - - - Manage keybaord layout mappings to used in shortcuts. - 管理用于快捷键的键盘布局映射。 - - - - Double click an item to set mapping key. - 双击一个项目以设置映射按键。 - - - - New Mapping - 新建映射 - - - - Delete Mapping - 删除映射 - - - - Keyboard layout mapping: - 键盘布局映射: - - - - Name: - 名字: - - - - Key - 按键 - - - - New Key - 新的按键 - - - - Mapping Information - 映射信息 - - - - Keyboard Layout Mappings - 键盘布局映射 - - - - - - - - Warning - 警告 - - - - Fail to add mapping <span style="%1">%2</span>. - 新建映射 <span style="%1">%2</span> 失败。 - - - - - - - Please check the configuration file and try again. - 请检查配置文件并重试。 - - - - Are you sure to delete mapping <span style="%1">%2</span>? - 确认删除映射 <span style="%1">%2</span>? - - - - Fail to delete mapping <span style="%1">%2</span>. - 删除映射 <span style="%1">%2</span> 失败。 - - - - Fail to rename mapping <span style="%1">%2</span>. - 重命名映射 <span style="%1">%2</span> 失败。 - - - - Fail to update mapping <span style="%1">%2</span>. - 更新映射 <span style="%1">%2</span> 失败。 - - - - Press key to set mapping - 按下一个按键以设置映射 - - - - VListFolderUE - - - List and search the folders and notes of current folder - 列出和搜索当前文件夹中的文件夹和笔记 - - - - VListUE - - - List and search history - 列出和搜索历史 - - - - Invalid ID %1 - 无效的ID %1 - - - - History - 历史 - - - - VLookTab - - - Icon size in pixel of tool bar (restart VNote to make it work) - 工具栏图标像素大小(重启VNote生效) - - - - Tool bar icon size: - 工具栏图标大小: - - - - VMainWindow - - - View - 查看 - - - - Expand the edit area - 扩展内容编辑区域 - - - - Edit Toolbar - 编辑工具栏 - - - - Heading Sequence - 标题序列 - - - - Enable heading sequence in current note in edit mode - 当前笔记在编辑模式中启用标题序列 - - - - Insert bold text or change selected text to bold - 插入粗体或将所选文本加粗 - - - - Insert italic text or change selected text to italic - 插入斜体或将所选文本改为斜体 - - - - Insert strikethrough text or change selected text to strikethroughed - 插入删除线或在所选文本上添加删除线 - - - - Insert inline-code text or change selected text to inline-coded - 插入行内代码或将所选文本改为行内代码 - - - - Insert fenced code block text or wrap selected text into a fenced code block - 插入代码块或将所选文本嵌入到一个代码块中 - - - - Insert a link - 插入一个链接 - - - - Insert an image from file or URL - 从文件或URL插入图片 - - - - Note - 笔记 - - - - View and edit current note's information - 查看并编辑当前笔记的信息 - - - - Delete current note - 删除当前笔记 - - - - &Edit - 编辑 (&E) - - - - Set as the background color for editor (re-open current tabs to make it work) - 设置为编辑器的背景色(需要重新打开当前标签页) - - - - Quick Access is not set. - 快速访问未设置。 - - - - Please specify the note for Quick Access in the settings dialog or the context menu of a note. - 请在设置对话框或笔记上下文菜单中设置一个笔记用于快速访问。 - - - - Edit current note - 编辑当前笔记 - - - - Discard changes and exit edit mode - 放弃对当前笔记的更改并退出编辑模式 - - - - Save changes and exit edit mode - 保存对当前笔记的更改并退出编辑模式 - - - - Save - 保存 - - - - SearchDock - 搜索窗口 - - - - Export - 导出 - - - - Menu Bar - 菜单栏 - - - - Toggle menu bar - 打开或关闭菜单栏 - - - - Full Screen - 全屏 - - - - ToolBar - 工具栏 - - - - History - 历史 - - - - Explorer - 浏览器 - - - - Full Screen %1 - 全屏 %1 - - - - Toggle full screen - 打开或关闭全屏 - - - - Stay On Top - 保留为顶层窗口 - - - - Toggle stay-on-top - 打开或关闭保留为顶层窗口 - - - - Expand Edit Area - 扩展编辑区域 - - - - Table %1 - 表格 %1 - - - - Insert a table - 插入一个表格 - - - - Flash Page %1 - 灵犀页 %1 - - - - Quick Access - 快速访问 - - - - Open quick access note - 打开快速访问笔记 - - - - Quick Access %1 - 快速访问 %1 - - - - Universal Entry - 通用入口 - - - - Activate Universal Entry - 进入通用入口 - - - - Universal Entry %1 - 通用入口 %1 - - - - Log In (Not Implemented Yet) - 登录 (未实现) - - - - New Root Folder - 新建根文件夹 - - - - New Note - 新建笔记 - - - - New Note %1 - 新建笔记 %1 - - - - Note Info - 笔记信息 - - - - Delete Note - 删除笔记 - - - - Save %1 - 保存 %1 - - - - &Help - 帮助 (&H) - - - - View &Log - 查看日志 (&L) - - - - View VNote's debug log (%1) - 查看VNote的调试日志 (%1) - - - - &Markdown Guide - Markdown指南 (&M) - - - - A quick guide of Markdown syntax - Markdown语法快速指南 - - - - &Documentation - 文档 (&D) - - - - View VNote's documentation - 查看VNote的文档 - - - - Do&nate - 捐赠 (&N) - - - - Donate to VNote or view the donate list - 捐赠给VNote或查看捐赠列表 - - - - Check For &Updates - 检查更新 (&U) - - - - Check for updates of VNote - 检查VNote的可用更新 - - - - &Feedback - 反馈 (&F) - - - - About &Qt - 关于Qt (&Q) - - - - &Markdown - Markdown (&M) - - - - Constrain The Width Of Images - 限制图片宽度 - - - - VNote is a free and open source note-taking application that knows programmers and Markdown better. - VNote是一个更懂程序员和Markdown的自由开源笔记。 - - - - Please visit <a href="https://tamlok.github.io/vnote">VNote</a> for more information. - 请访问<a href="https://tamlok.github.io/vnote">VNote</a>获取更多信息。 - - - - Extensions - 扩展 - - - - &Mermaid - Mermaid (&M) - - - - Enable Mermaid for graph and diagram (re-open current tabs to make it work) - 启用Mermaid绘制图表(需要重新打开当前标签页) - - - - Enable Flowchart.js for flowchart diagram (re-open current tabs to make it work) - 启用Flowchart.js绘制图表(需要重新打开当前标签页) - - - - Enable MathJax for math support in Markdown (re-open current tabs to make it work) - 启用MathJax书写数学公式(需要重新打开当前标签页) - - - - In-Place Preview - 原地预览 - - - - Enable in-place preview (images, diagrams, and formulas) in edit mode (re-open current tabs to make it work) - 编辑模式原地预览(图片、图表和公式)(需要重新打开当前标签页) - - - - Constrain The Width Of In-Place Preview - 限制原地预览宽度 - - - - Constrain the width of in-place preview to the edit window in edit mode - 编辑模式中根据编辑窗口大小限制原地预览的宽度 - - - - Tool Bar - 工具栏 - - - - Toogle the tool bar - 打开或关闭工具栏 - - - - Create notes from external files in current folder (will copy files if they do not locate in current folder) - 在当前文件夹中从外部文件新建笔记(如果这些文件不在当前文件夹中则拷贝文件) - - - - E&xport - 导出 (&X) - - - - Export notes - 导出笔记 - - - - Open Configuration Folder - 打开配置文件夹 - - - - Open configuration folder of VNote - 打开VNote的配置文件夹 - - - - Restart - 重启 - - - - Highlight Tabs - 高亮Tab - - - - Highlight all the tabs - 高亮所有的Tab - - - - Version: %1 - 版本: %1 - - - - Author: Le Tan (tamlok) - 作者: Le Tan (tamlok) - - - - Marked - Marked - - - - Use Marked to convert Markdown to HTML (re-open current tabs to make it work) - 使用Marked对Markdown进行HTML渲染(需要重新打开当前标签页) - - - - Hoedown - Hoedown - - - - Use Hoedown to convert Markdown to HTML (re-open current tabs to make it work) - 使用Hoedown对Markdown进行HTML渲染(需要重新打开当前标签页) - - - - Markdown-it - Markdown-it - - - - Use Markdown-it to convert Markdown to HTML (re-open current tabs to make it work) - 使用Markdown-it对Markdown进行HTML渲染(需要重新打开当前标签页) - - - - Showdown - Showdown - - - - Use Showdown to convert Markdown to HTML (re-open current tabs to make it work) - 使用Showdown对Markdown进行HTML渲染(需要重新打开当前标签页) - - - - AttachmentList - 附件列表 - - - - LocateCurrentFile - 定位当前笔记 - - - - ExpandMode - 扩展模式 - - - - DiscardAndRead - 放弃更改并阅读 - - - - ToolsDock - 工具窗口 - - - - CloseNote - 关闭笔记 - - - - ShortcutsHelp - 快捷键帮助 - - - - FlushLogFile - 写入日志文件 - - - - Constrain the width of images to the window in read mode (re-open current tabs to make it work) - 阅读模式中根据窗口大小限制图片的宽度(需要重新打开当前标签页) - - - - Enable Image Caption - 启用图片标题 - - - - Center the images and display the alt text as caption (re-open current tabs to make it work) - 居中显示图片并将图片的替换文本显示为标题(需要重新打开当前标签页) - - - - &Flowchart.js - Flowchart.js (&F) - - - - &View - 查看 (&V) - - - - &File - 文件 (&F) - - - - &Open - 打开 (&O) - - - - Open external file to edit - 打开外部文件以编辑 - - - - Select External Files To Open - 选择要打开的外部文件 - - - - Code Block Style - 代码块样式 - - - - CodeBlock - 代码块 - - - - Display line number in code block in edit mode (for Markdown only) - 编辑模式下只在代码块显示行号(仅支持Markdown) - - - - Set as the editor style (re-open current tabs to make it work) - 设置为编辑器的样式(需要重新打开当前标签页) - - - - Show VNote - 显示VNote - - - - Quit - 退出VNote - - - - - VNote - VNote - - - - View and change settings for VNote - 查看并更改VNote的配置 - - - - FocusEditArea - 定位编辑区域 - - - - CurrentNoteInfo - 当前笔记信息 - - - - Tags - 标签 - - - - Link %1 - 链接 %1 - - - - Image %1 - 图片 %1 - - - - Note Toolbar - 笔记工具栏 - - - - Attachments (drag files here to add attachments) - 附件(拖动文件到此以添加附件) - - - - Star VNote on &GitHub - 支持VNote GitHub项目 (&G) - - - - Give a star to VNote on GitHub project - 在GitHub上献一个星星给VNote项目 - - - - Open an issue on GitHub - 在GitHub上反馈意见 - - - - Display Line Number In Code Blocks - 代码块显示行号 - - - - Enable line number in code blocks in read mode - 阅读模式下启用代码块行号 - - - - Customize some standard shortcuts - 自定义部分标准快捷键 - - - - - Find/Replace - 查找/替换 - - - - Open Find/Replace dialog to search in current note - 打开查找/替换对话框以在当前笔记中查找 - - - - Advanced Find - 高级查找 - - - - Advanced find within VNote - 在VNote中进行高级查找 - - - - Find Next - 查找下一个 - - - - Find next occurence - 查找下一处出现 - - - - Find Previous - 查找上一个 - - - - Find previous occurence - 查找上一处出现 - - - - Replace - 替换 - - - - Replace current occurence - 替换当前出现 - - - - Replace && Find - 替换并查找 - - - - Replace current occurence and find the next one - 替换当前出现并查找下一个 - - - - Replace All - 全部替换 - - - - Replace all occurences in current note - 替换当前笔记中的所有出现 - - - - Highlight Searched Pattern - 高亮查找模式 - - - - Highlight all occurences of searched pattern - 高亮查找模式的所有出现 - - - - &Expand Tab - 扩展Tab (&E) - - - - Expand entered Tab to spaces - 将输入的Tab扩展为空格 - - - - Expand Tab to 2 spaces - 扩展Tab为2个空格 - - - - Expand Tab to 4 spaces - 扩展Tab为4个空格 - - - - Expand Tab to 8 spaces - 扩展Tab为8个空格 - - - - Auto Indent - 自动缩进 - - - - Indent automatically when inserting a new line - 插入新行时自动缩进 - - - - Auto List - 自动列表 - - - - Continue the list automatically when inserting a new line - 插入新行时自动继续列表 - - - - Highlight Selected Words - 高亮选定字词 - - - - Highlight all occurences of selected words - 高亮选定字词的所有出现 - - - - Highlight all the spaces at the end of a line - 高亮所有行尾空白字符 - - - - Smart Table - 智能表格 - - - - Format table automatically - 自动格式化表格 - - - - Snippets - 片段 - - - - Cart - 小推车 - - - - Search - 搜索 - - - - Toggle the search dock widget - 打开或关闭搜索窗口 - - - - Select Files To Create Notes - 选择文件以创建笔记 - - - - Warning - 警告 - - - - Fail to create notes for all the files. - 无法从所有文件中创建笔记。 - - - - %1 %2 created from external files - 从外部文件夹中创建了%1个%2 - - - - notes - 笔记 - - - - note - 笔记 - - - - &Renderer - 渲染器 (&R) - - - - Markdown-it Options - Markdown-it选项 - - - - HTML - HTML - - - - Line Break - 换行 - - - - Linkify - 自动链接 - - - - Superscript - 上标 - - - - Subscript - 下标 - - - - Metadata Aware - 元数据感知 - - - - Emoji - Emoji - - - - Use system's background color configuration for Markdown rendering - 使用系统的背景色设置对Markdown进行渲染 - - - - Transparent - 透明 - - - - Use a transparent background for Markdown rendering - 使用透明背景来渲染Markdown - - - - - - - - - Add Style - 添加样式 - - - - Add custom style of read mode - 添加阅读模式的自定义样式 - - - - Add custom style of code block in read mode - 添加阅读模式的代码块的自定义样式 - - - - Add custom style of editor - 添加编辑器的自定义样式 - - - - Headings - 标题 - - - - Heading %1 - 标题%1 - - - - Heading %1 %2 - 标题%1 %2 - - - - Clear - 清空标题 - - - - Clear %1 - 清空标题 %1 - - - - Theme - 主题 - - - - - Add Theme - 添加主题 - - - - Add custom theme - 添加自定义主题 - - - - Set as the theme of VNote (restart VNote to make it work) - 设置为VNote的主题(重启VNote生效) - - - - Collect User Statistics - 收集用户统计数据 - - - - VNote would like to send a request to count active users.Do you allow this request? - VNote尝试发送一个请求来计数用户数量。是否允许? - - - - A request to https://tamlok.github.io/user_track/vnote.html will be sent if allowed. - 如果允许,会发送一个到 https://tamlok.github.io/user_track/vnote.html 的请求。 - - - - Notices for Windows Users - Windows用户注意 - - - - OpenGL requried by VNote may not work well on Windows by default.You may update your display card driver or set another openGL option in VNote's Settings dialog.Check <a href="https://github.com/tamlok/vnote/issues/853">GitHub issue</a> for details. - VNote运行所需的openGL组件在默认配置下可能在Windows系统上无法工作。您可能需要更新显卡驱动或者在VNote的设置对话框里面设置openGL选项。详情查看 <a href="https://github.com/tamlok/vnote/issues/853">GitHub issue</a> 。 - - - - Strange behaviors include:<br/>* Interface freezes and does not response;<br/>* Widgets are out of order after maximizing and restoring the main window;<br/>* No cursor in edit mode;<br/>* Menus are not clickable in full screen mode. - 异常的表现包括:<br/>* 界面卡顿冻结,没有响应;<br/>* 最大化并还原主窗口后,部件错乱;<br/>* 编辑模式下无法看到光标;<br/>* 全屏模式下菜单无法点击。 - - - - Restart Needed - 需要重启 - - - - Do you want to restart VNote now? - 是否现在重启VNote? - - - - VNote needs to restart to apply new configurations. - VNote需要重启以应用新的配置。 - - - A request to https://tajs.qq.com/stats will be sent if allowed. - 如果允许,会发送一个到 https://tajs.qq.com/stats 的请求。 - - - - Line Number - 行号 - - - - None - - - - - Do not display line number in edit mode - 编辑模式下不显示行号 - - - - Absolute - 绝对行号 - - - - Display absolute line number in edit mode - 编辑模式下显示绝对行号 - - - - Relative - 相对行号 - - - - Display line number relative to current cursor line in edit mode - 编辑模式下显示相对于当前光标所在行的行号 - - - - Editor &Style - 编辑器样式 (&S) - - - - Close VNote - 关闭VNote - - - - Do you want to minimize VNote to system tray instead of quitting it when closing VNote? - 关闭VNote时是否仅将VNote最小化到系统托盘? - - - - You could change the option in Settings later. - 稍后可以进入设置改变该选项。 - - - - Print Note - 打印笔记 - - - - 2 Spaces - 2个空格 - - - - Discard Changes And Read - 放弃更改并阅读 - - - - Bold %1 - 粗体 %1 - - - - Italic %1 - 斜体 %1 - - - - Strikethrough %1 - 删除线 %1 - - - - Inline Code %1 - 行内代码 %1 - - - - Code Block %1 - 代码块 %1 - - - - Flash Page - 灵犀页 - - - - Open the Flash Page to edit - 打开灵犀页进行编辑 - - - - - Customize Shortcuts - 自定义快捷键 - - - - Auto Scroll Cursor Line - 自动滚动光标所在行 - - - - Disabled - 关闭 - - - - End Of Document - 文档结尾 - - - - Scroll cursor line into the center when it locates at the end of document - 当光标位于文档结尾时,自动滚动光标所在行到编辑区域中部 - - - - Always - 总是 - - - - Always scroll cursor line into the center - 总是滚动光标所在行到编辑区域中部 - - - - Information - 信息 - - - - Edit %1 - 编辑 %1 - - - - Save Changes And Read %1 - 保存更改并阅读 %1 - - - - Edit - 编辑 - - - - Save Changes And Read - 保存更改并阅读 - - - - Save changes to current note - 保存对当前笔记的更改 - - - - &Shortcuts Help - 快捷键帮助 (&S) - - - - View information about shortcut keys - 查看快捷键帮助信息 - - - - &About VNote - 关于VNote (&A) - - - - View information about VNote - 查看VNote的信息 - - - - View information about Qt - 查看Qt的信息 - - - - Math&Jax - MathJax (&J) - - - - Highlight Code Blocks In Edit Mode - 编辑模式高亮代码块 - - - - Enable syntax highlight within code blocks in edit mode - 编辑模式中启用代码块语法高亮 - - - - &New Notes From Files - 从文件新建笔记 (&N) - - - - &Print - 打印 (&P) - - - - Print current note - 打印当前笔记 - - - - &Settings - 设置 (&S) - - - - 4 Spaces - 4个空格 - - - - 8 Spaces - 8个空格 - - - - Highlight Cursor Line - 高亮光标所在行 - - - - Highlight current cursor line - 高亮当前光标所在行 - - - - Highlight Trailing Spaces - 高亮行尾空白字符 - - - - Tab Stop Width - Tab Stop宽度 - - - - Tools - 工具 - - - - Outline - 大纲 - - - - Toggle the tools dock widget - 打开或关闭工具窗口 - - - - About VNote - 关于VNote - - - - Enable HTML tags in source (re-open current tabs to make it work) - 启用源文件中的HTML标签(需要重新打开当前标签页) - - - - Convert '\n' in paragraphs into line break (re-open current tabs to make it work) - 转换'\n'为换行(需要重新打开当前标签页) - - - - Convert URL-like text into links (re-open current tabs to make it work) - 转换URL模式的文本为链接(需要重新打开当前标签页) - - - - Enable superscript like ^vnote^ (re-open current tabs to make it work) - 启用上标如^vnote^(需要重新打开当前标签页) - - - - Enable subscript like ~vnote~ (re-open current tabs to make it work) - 启用下标如~vnote~(需要重新打开当前标签页) - - - - Be aware of metadata in YAML format (re-open current tabs to make it work) - 感知YAML格式的元数据(需要重新打开当前标签页) - - - - Enable emoji and emoticon (re-open current tabs to make it work) - 启用emoji和表情图标(需要重新打开当前标签页) - - - - &WaveDrom - WaveDrom (&W) - - - - Enable WaveDrom for digital timing diagram (re-open current tabs to make it work) - 启用WaveDrom绘制数字时序图表(需要重新打开当前标签页) - - - - &Rendering Background - 渲染背景 (&R) - - - - - System - 默认 - - - - Set as the background color for Markdown rendering (re-open current tabs to make it work) - 使用该背景色对Markdown进行渲染(需要重新打开当前标签页) - - - - Rendering &Style - 渲染样式 (&S) - - - - Notebooks - 笔记本 - - - - Folders - 文件夹 - - - - Create a root folder in current notebook - 在当前笔记本中新建根文件夹 - - - - Create a note in current folder - 在当前文件夹中新建笔记 - - - - &Quit - 退出 (&Q) - - - - Quit VNote - 退出VNote - - - - Set as the CSS style for Markdown rendering (re-open current tabs to make it work) - 设置为Markdown渲染的CSS样式(需要重新打开当前标签页) - - - - Set as the code block CSS style for Markdown rendering (re-open current tabs to make it work) - 设置为Markdown渲染的代码块CSS样式(需要重新打开当前标签页) - - - - &Background Color - 背景颜色 (&B) - - - - Use system's background color configuration for editor - 为编辑器使用系统的背景色设置 - - - - &Sync - 同步 - - - - &Upload - 上传 - - - - &Download - 更新 - - - - upload note - 上传当前笔记本 - - - - download note - 更新当前笔记本 - - - - Are you sure to close opened notes - 确认关闭已打开笔记 - - - - VNote will close all the opened notes before upload. - VNote会在上传前关闭所有已打开笔记 - - - - VMarkdownTab - - - Default mode to open a file - 文件默认打开模式 - - - - Read Mode - 阅读模式 - - - - Edit Mode - 编辑模式 - - - - Code block copy button - 代码块复制按钮 - - - - Display a copy button at the top right corner of each code block to copy the content in read mode - 阅读模式中,在每个代码块右上方显示一个复制按钮用于复制其内容 - - - - Location of MathJax JavaScript and its configuration (restart VNote to make it work in in-place preview) - MathJax JavaScript脚本的位置和配置(重启VNote使其在原地预览中生效) - - - - Need to prepend "file://" to local path - 本地路径需要在前面添加“file://” - - - - Enable PlantUML support in Markdown - 启用PlantUML渲染图表 - - - - Online Service - 在线服务 - - - - Local JAR - 本地JAR - - - - Server address for online PlantUML - PlantUML在线服务器地址 - - - - Location to the PlantUML JAR executable for local PlantUML - PlantUML本地JAR可执行文件位置 - - - - - Test - 测试 - - - - Test PlantUML JAR configuration - 测试PlantUML JAR配置 - - - - - Warning - 警告 - - - - The JAR file specified does not exist. - 指定的JAR文件不存在。 - - - - Please input the right absolute file path to the JAR file. - 请输入正确的JAR文件的绝对文件路径。 - - - - Please specify the absolute file path to the JAR file. - 请输入JAR文件的绝对文件路径。 - - - - It should be something like "/path/to/plantuml.jar". - 应该是类似于“/path/to/plantuml.jar”。 - - - - - Information - 信息 - - - - - Test %1. - 测试 %1。 - - - - - succeeded - 成功 - - - - - failed - 失败 - - - - Graphviz - Graphviz - - - - Enable Graphviz for drawing graph - 启用Graphviz渲染图表 - - - - Empty to detect automatically - 自动检测 - - - - Location to the GraphViz dot executable - Graphviz dot可执行文件位置 - - - - Test Graphviz executable configuration - 测试Graphviz可执行文件配置 - - - - MathJax configuration: - MathJax配置: - - - - PlantUML: - PlantUML: - - - - PlantUML server: - PlantUML服务器: - - - - PlantUML JAR: - PlantUML JAR: - - - - Graphviz executable: - Graphviz可执行文件: - - - - Enable auto sequence for all headings (in the form like 1.2.3.4.) - 自动为所有标题添加序列(类似于1.2.3.4.) - - - - - Disabled - 关闭 - - - - Enabled - 启用 - - - - Enabled for internal notes only - 仅对内部笔记启用 - - - - Base level to start heading sequence - 标题序列起始级别 - - - - 1 - 1 - - - - 2 - 2 - - - - 3 - 3 - - - - 4 - 4 - - - - 5 - 5 - - - - 6 - 6 - - - - Specify the screen column in fenced code block which will be highlighted - 指定编辑模式下代码块中的高亮列 - - - - Color column: - 高亮列: - - - - Open mode: - 打开模式: - - - - Heading sequence: - 标题序列: - - - - VMdEdit - - - Insert From Clipboard - 粘贴选项 - - - - Insert As Image - 作为图像插入 - - - - Insert As Text - 作为文本插入 - - - - Following images seems not to be used in this note anymore. Please confirm the deletion of these images. - 下列图片似乎已经不再在该笔记中被使用。请确认是否删除这些图片。 - - - - Deleted files could be found in the recycle bin of this note.<br>Click "Cancel" to leave them untouched. - 被删除的文件可以在该笔记的回收站中找回。<br>点击“取消”以终止操作。 - - - - Confirm Cleaning Up Unused Images - 确认清理未被使用的图片 - - - - VMdEditOperations - - - Insert Image From Clipboard - 从剪切板中插入图片 - - - - - Fail to create image folder <span style="%1">%2</span>. - 新建图片目录 <span style="%1">%2</span> 失败。 - - - - Fail to save image <span style="%1">%2</span>. - 保存图片 <span style="%1">%2</span> 失败。 - - - - - Warning - 警告 - - - - - Fail to insert image <span style="%1">%2</span>. - 插入图片 <span style="%1">%2</span> 失败。 - - - - Fail to copy image <span style="%1">%2</span>. - 复制图片 <span style="%1">%2</span> 失败。 - - - - Insert Image From File - 从文件插入图片 - - - - Insert Image From Network - 从网络插入图片 - - - - Insert Image - 插入图片 - - - - VMdEditor - - - &Save Changes And Read - 保存更改并阅读 (&S) - - - - Save changes and exit edit mode - 保存对当前笔记的更改并退出编辑模式 - - - - &Discard Changes And Read - 放弃更改并阅读 (&D) - - - - Discard changes and exit edit mode - 放弃对当前笔记的更改并退出编辑模式 - - - - Following images seems not to be used in this note anymore. Please confirm the deletion of these images. - 下列图片似乎已经不再在该笔记中被使用。请确认是否删除这些图片。 - - - - Deleted files could be found in the recycle bin of this note.<br>Click "Cancel" to leave them untouched. - 被删除的文件可以在该笔记的回收站中找回。<br>点击“取消”以终止操作。 - - - - Confirm Cleaning Up Unused Images - 确认清理未被使用的图片 - - - - - - Insert From Clipboard - 粘贴选项 - - - - Insert From URL - 从URL中插入 - - - - Insert From Image Data - 从图片数据中插入 - - - - - - Insert As Image Link - 作为图片链接插入 - - - - - Insert As Image - 作为图片插入 - - - - - Insert As Text - 作为文本插入 - - - - Live Preview For Graphs - 图表实时预览 - - - - Paste As Plain Text - 粘贴为纯文本 - - - - Toggle live preview panel for graphs - 打开或关闭图表实时预览面板 - - - - - - - Warning - 警告 - - - - Fail to move unsaved inserted image %1 to %2. - 移动未保存的插入图片 %1 到 %2 失败。 - - - - Please check it manually to avoid image loss. - 请手动检查以免丢失图片。 - - - - Inserting parsed Markdown text - 正在插入解析的Markdown文本 - - - - Parsed Markdown text inserted - 解析的Markdown文本已插入 - - - - Copy HTML As - 复制HTML为 - - - - Copy selected content as HTML using rules specified by target %1 - 使用目标 %1 指定的规则将所选内容复制为HTML - - - - Paste As Block &Quote - 粘贴为块引用 (&Q) - - - - Paste text from clipboard as block quote - 将剪切版中的文本作为块引用粘贴 - - - - Paste Parsed &Markdown Text - 粘贴解析的Markdown文本 (&M) - - - - Parse HTML to Markdown text and paste - 解析HTML为Markdown文本并粘贴 - - - - Insert Image Link - 插入图片链接 - - - - View Image - 查看图片 - - - - Copy Image URL - 复制图片URL - - - - Copy Image Path - 复制图片路径 - - - - Copy Image - 复制图片 - - - - View Link - 访问链接 - - - - Copy Link URL - 复制链接URL - - - - Copy Link Path - 复制链接路径 - - - - Copy In-Place Preview - 复制原地预览 - - - - Copy Graph - 复制图表 - - - - PNG - PNG格式 - - - - Export graph as PNG to a temporary file and copy - 将图表以PNG格式导出到一个临时文件并复制 - - - - SVG - SVG格式 - - - - Export graph as SVG to a temporary file and copy - 将图表以SVG格式导出到一个临时文件并复制 - - - - Fail to open a temporary file for export. - 无法打开一个临时文件并导出。 - - - - Exporting graph - 正在导出图表 - - - - Fail to export graph. - 导出图表失败。 - - - - Graph exported and copied - 图表已导出并复制 - - - - Fail to read exported image: %1 - 无法读取导出的图片: %1 - - - - Insert As Relative Image Link - 作为相对图片链接插入 - - - - Insert As Link - 作为链接插入 - - - - Insert As Relative Link - 作为相对链接插入 - - - - Attach And Insert Link - 添加附件并插入链接 - - - - Insert File Content - 插入文本内容 - - - - Fail to add attachment %1 for note <span style="%2">%3</span>. - 为笔记 <span style="%2">%3</span> 添加附件 %1 失败。 - - - - 1 file added as attachment - 1个文件添加为附件 - - - - Fetching images to local folder... - 正在获取图片到本地文件夹... - - - - Abort - 终止 - - - - Fetching Images To Local Folder - 正在获取图片到本地文件夹 - - - - Fetching image: %1 - 获取图片: %1 - - - - Link To Attachment - 链接到附件 - - - - &Upload Image To - 上传图片 (&U) - - - - &GitHub - &GitHub - - - - G&itee - G&itee - - - - &Wechat - 微信 (&W) - - - - &Tencent - 腾讯云 (&T) - - - - VMdTab - - - - - - - Information - 注意 - - - - Note <span style="%1">%2</span> has been modified. - 笔记 <span style="%1">%2</span> 已经被更改。 - - - - Do you want to save your changes? - 是否保存更改? - - - - - - - Warning - 警告 - - - - Fail to open note <span style="%1">%2</span>. - 打开笔记 <span style="%1">%2</span> 失败。 - - - - Please check if file %1 exists. - 请检查文件 %1 是否存在。 - - - - Could not modify a read-only note <span style="%1">%2</span>. - 无法修改只读笔记 <span style="%1">%2</span>。 - - - - Please save your changes to other notes manually. - 请手动保存更改到其他笔记。 - - - - - Fail to save note. - 保存笔记失败。 - - - - File <span style="%1">%2</span> being written has been removed. - 将要写入的文件 <span style="%1">%2</span> 已经被移除。 - - - - Fail to write to disk when saving a note. Please try it again. - 保存笔记时,写入文件失败。请稍后再试。 - - - - Snippet applied - 片段已应用 - - - - Snippet %1 is not applicable - 片段 %1 不适用 - - - - Snippets are not applicable - 无法应用片段 - - - - No available snippets defined with shortcuts - 当前没有定义带有快捷键的片段可用 - - - - Backup File Found - 发现备份文件 - - - - Found backup file <span style="%1">%2</span> when opening note <span style="%1">%3</span>. - 打开笔记 <span style="%1">%3</span> 时发现备份文件 <span style="%1">%2</span>。 - - - - VNote may crash while editing this note before.<br/>Please choose to recover from the backup file or delete it.<br/><br/>Note file last modified: <span style="%1">%2</span><br/>Backup file last modified: <span style="%1">%3</span> - VNote此前编辑该笔记时可能意外退出。<br/>请选择从该备份文件恢复或者删除该备份文件。<br/><br/>笔记文件上次修改时间: <span style="%1">%2</span><br/>备份文件上次修改时间: <span style="%1">%3</span> - - - - Recover From Backup File - 从备份文件恢复 - - - - Discard Backup File - 放弃备份文件 - - - - Cancel - 取消 - - - - Quit - 退出 - - - - Not an editor command: %1 - 不是一个编辑器命令:%1 - - - - Page saved to %1 - 页面保存为 %1 - - - - Fail to save page to %1 - 保存页面为 %1 失败 - - - - Single HTML (*.html) - 仅HTML (*.html) - - - - Complete HTML (*.html) - 完整HTML (*.html) - - - - MIME HTML (*.mht) - MIME HTML (*.mht) - - - - Save Page - 保存页面 - - - - Saving page to %1 - 正在保存页面为 %1 - - - - - - - Please save changes to file before uploading images. - 请在上传图片前先保存更改到文件。 - - - - VMetaWordManager - - - the day as number without a leading zero (`1` to `31`) - 没有前导零的日期数字(`1` 到 `31`) - - - - the day as number with a leading zero (`01` to `31`) - 带有前导零的日期数字(`01` 到 `31`) - - - - the abbreviated localized day name (e.g. `Mon` to `Sun`) - 缩写日期名字(如 `一` 到 `日`) - - - - the long localized day name (e.g. `Monday` to `Sunday`) - 完整日期名字(如 `星期一` 到 `星期日`) - - - - the month as number without a leading zero (`1` to `12`) - 没有前导零的月份数字(`1` 到 `12`) - - - - the month as number with a leading zero (`01` to `12`) - 带有前导零的月份数字(`01` 到 `12`) - - - - the abbreviated localized month name (e.g. `Jan` to `Dec`) - 缩写月份名字(如 `一` 到 `十二`) - - - - the year as two digit number (`00` to `99`) - 两位数的年份数字(`00` 到 `99`) - - - - the year as four digit number - 四位数的年份数字 - - - - the long localized month name (e.g. `January` to `December`) - 完整月份名字(如 `一月` 到 `十二月`) - - - - the hour without a leading zero (`0` to `23` or `1` to `12` if AM/PM display) - 没有前导零的小时(`0` 到 `23` 或者 `1` 到 `12`) - - - - the hour with a leading zero (`00` to `23` or `01` to `12` if AM/PM display) - 带有前导零的小时(`00` 到 `23` 或者 `01` 到 `12`) - - - - the hour without a leading zero (`0` to `23` even with AM/PM display) - 没有前导零的小时(`0` 到 `23`) - - - - the hour with a leading zero (`00` to `23` even with AM/PM display) - 带有前导零的小时(`0` 到 `23`) - - - - the minute without a leading zero (`0` to `59`) - 没有前导零的分钟(`0` 到 `59`) - - - - the minute with a leading zero (`00` to `59`) - 带有前导零的分钟(`0` 到 `59`) - - - - the second without a leading zero (`0` to `59`) - 没有前导零的秒(`0` 到 `59`) - - - - the second with a leading zero (`00` to `59`) - 带有前导零的秒(`00` 到 `59`) - - - - the milliseconds without leading zeroes (`0` to `999`) - 没有前导零的毫秒(`0` 到 `999`) - - - - the milliseconds with leading zeroes (`000` to `999`) - 带有前导零的毫秒(`000` 到 `999`) - - - - - use AM/PM display (`AM` or `PM`) - 显示AM或PM - - - - - use am/pm display (`am` or `pm`) - 显示am或pm - - - - the timezone (e.g. `CEST`) - 时区(如 `CEST`) - - - - a random number - 随机数 - - - - dynamic version of `random` - 随机数(动态) - - - - name of current note - 当前笔记名字 - - - - complete base name of current note - 当前笔记的完整基本名字 - - - - relative path of current note's attachment folder - 当前笔记附件文件夹的相对路径 - - - - the week number (`1` to `53`) - 周数数字(`00` 到 `53`) - - - - information about all defined magic words - 列出所有幻词的信息 - - - - VMiscTab - - - Highlight matches of a full-text search in page - 在页面内高亮全文搜索的匹配 - - - - VNewDirDialog - - - Folder &name: - 文件夹名 (&N): - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - VNewFileDialog - - - Note &name: - 笔记名 (&N): - - - - Insert note name as title (for Markdown only) - 将笔记名字作为标题插入(仅支持Markdown) - - - - Choose a template (magic word supported) - 选择一个模板 (支持幻词) - - - - Manage Templates - 管理模板 - - - - Insert note name into the new note as a title - 将笔记名字作为标题插入到新建的笔记中 - - - - Template: - 模板: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - None - - - - - VNewNotebookDialog - - - Notebook &name: - 笔记本名 (&N): - - - - Notebook &root folder: - 笔记本根文件夹 (&R): - - - - Use relative path - 使用相对路径 - - - - Use relative path (to VNote's executable) in configuration file - 在配置文件中使用相对路径(相对于VNote的可执行文件) - - - - &Image folder: - 图片文件夹 (&I): - - - - - Use global configuration (%1) - 使用全局配置 (%1) - - - - Set the name of the folder to hold images of all the notes in this notebook (empty to use global configuration) - 设置一个文件夹以保存该笔记本下所有笔记的图片(为空则使用全局配置) - - - - &Attachment folder: - 附件文件夹 (&A): - - - - Set the name of the folder to hold attachments of all the notes in this notebook (empty to use global configuration, read-only once created) - 设置一个文件夹以保存该笔记本下所有笔记的附件(为空则使用全局配置,创建后不可修改) - - - - <span style="%1">INFO</span>: The folder chosen seems to be a root folder of a notebook created by VNote before. VNote will try to import it by reading the configuration file. - <span style="%1">注意</span>:所选的文件夹可能是此前VNote创建的一个笔记本的根文件夹。VNote会尝试读取配置文件并导入该笔记本。 - - - - <span style="%1">WARNING</span>: Please specify absolute path. - <span style="%1">警告</span>:请使用一个绝对路径。 - - - - <span style="%1">WARNING</span>: The folder chosen is NOT empty! It is highly recommended to use an EMPTY and EXCLUSIVE folder for a new notebook. If continue, VNote will try to create a notebook based on existing folders and files recursively. - <span style="%1">警告</span>:所选的文件夹不是空的!强烈建议为一个新的笔记本指定一个空的、独占的文件夹。如果继续,VNote将会尝试递归地基于已有的文件夹和文件创建一个笔记本。 - - - - <span style="%1">WARNING</span>: The path seems to be illegal. Please choose another one. - <span style="%1">警告</span>:根目录路径可能是非法的。请选择另一个路径。 - - - - <span style="%1">WARNING</span>: The folder chosen has already been a root folder of existing notebook <span style="%2">%3</span> in VNote. - <span style="%1">警告</span>:所选的文件夹已经是当前VNote中一个笔记本 <span style="%2">%3</span> 的根文件夹。 - - - - <span style="%1">WARNING</span>: Please choose a folder in the same drive as <span style="%2">%3</span> when relative path is enabled. - <span style="%1">警告</span>:使用相对路径时,请选择一个和 <span style="%2">%3</span> 在同一驱动器的文件夹。 - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - Select Root Folder Of The Notebook - 选择笔记本根文件夹 - - - - &Browse - 浏览文件 (&B) - - - - VNoteFile - - - Fail to delete images of this note. - 删除笔记的图片失败。 - - - - Fail to delete attachments of this note. - 删除笔记的附件失败。 - - - - Fail to delete the note file. - 删除笔记文件失败。 - - - - Fail to remove the note from the folder configuration. - 从文件夹配置中移除笔记失败。 - - - - Fail to open target folder. - 打开目标文件夹失败。 - - - - - cut - 剪切 - - - - - copy - 复制 - - - - Fail to %1 the note file. - %1笔记文件失败。 - - - - Fail to add the note to target folder's configuration. - 将该笔记添加到目标文件夹的配置失败。 - - - - Source image %1 does not exist. - 源图片 %1 不存在。 - - - - Skip image with the same source and target path %1. - 跳过源和目标路径 %1 相同的图片。 - - - - Fail to %1 image %2 to %3. Please manually %1 it and modify the note. - %1图片 %2 到 %3 失败。请手动%1并修改笔记。 - - - - Fail to %1 attachments folder %2 to %3. Please manually maintain it. - %1附件文件夹 %2 到 %3 失败。请手动维护。 - - - - Fail to update configuration of note %1. - 更新笔记 %1 的配置失败。 - - - - VNoteManagementTab - - - Notes - 笔记 - - - - External Files - 外部文件 - - - - - Custom image folder - 自定义图片文件夹 - - - - Set the global name of the image folder to hold images of notes (restart VNote to make it work) - 全局设置图片文件夹的名字以保存笔记的图片(重启VNote生效) - - - - Custom attachment folder - 自定义附件文件夹 - - - - Set the global name of the attachment folder to hold attachments of notes (restart VNote to make it work) - 全局设置附件文件夹的名字以保存笔记的附件(重启VNote生效) - - - - Name of the attachment folder - 附件文件夹的名字 - - - - Single click to open a note in current tab - 单击在当前标签页打开笔记 - - - - Single click a note in the notes list to open it in current tab, double click to open it in a new tab - 在笔记列表中单击一个笔记在当前标签页打开,双击在新标签页中打开 - - - - Set the path of the global image folder to hold images of external files (restart VNote to make it work). -You could use both absolute or relative path here. If absolute path is used, VNote will not manage -those images, so you need to clean up unused images manually. - 全局设置图片文件夹的路径以保存外部文件的图片(重启VNote生效)。 -这里可以使用绝对路径或者相对路径。如果使用绝对路径,VNote不会管理 -这些图片,需要由用户手动清理不再使用的图片。 - - - - - Name of the image folder - 图片文件夹的名字 - - - - VNotebook - - - Fail to write notebook configuration file. - 写入笔记本的配置失败。 - - - - VNotebookInfoDialog - - - Set the name of the folder to hold images of all the notes in this notebook (empty to use global configuration) - 设置一个文件夹以保存该笔记本下所有笔记的图片(为空则使用全局配置) - - - - The folder to hold attachments of all the notes in this notebook - 保存该笔记本下所有笔记的附件的文件夹 - - - - The folder to hold deleted files from within VNote of all the notes in this notebook - 保存该笔记本的所有笔记在VNote中被删除的文件的文件夹 - - - - Notebook &name: - 笔记本名 (&N): - - - - Notebook &root folder: - 笔记本根文件夹 (&R): - - - - &Image folder: - 图片文件夹 (&I): - - - - Attachment folder: - 附件文件夹: - - - - Recycle bin folder: - 回收站文件夹: - - - - Created time: - 创建时间: - - - - <span style="%1">WARNING</span>: Name (case-insensitive) <span style="%2">%3</span> already exists. Please choose another name. - <span style="%1">警告</span>:已存在该名字(不区分大小写) <span style="%2">%3</span>。请选择另一个名字。 - - - - <span style="%1">WARNING</span>: Name <span style="%2">%3</span> contains illegal characters (after magic word evaluation). - <span style="%1">警告</span>:名字 <span style="%2">%3</span> 包含非法字符(解析幻词之后)。 - - - - - Use global configuration (%1) - 使用全局配置 (%1) - - - - VNotebookSelector - - - &Delete - 删除 (&D) - - - - Delete current notebook - 删除当前笔记本 - - - - View and edit current notebook's information - 查看并编辑当前笔记本的信息 - - - - &Open Notebook Location - 打开笔记本所在位置 (&O) - - - - * When a non-empty folder is chosen, VNote will create a notebook based on the folders and files in it recursively. - * 如果选定一个非空的文件夹,VNote会递归地基于该文件夹下的文件夹和文件来创建一个笔记本。 - - - - Successfully build notebook recursively (%1). - 成功递归构建笔记本 (%1)。 - - - - Fail to build notebook recursively. - 递归构建笔记本失败。 - - - - &Sort - 排序 (&S) - - - - Sort notebooks - 排序笔记本 - - - - &Recycle Bin - 回收站 (&R) - - - - Open the recycle bin of this notebook - 打开该笔记本的回收站 - - - - &Empty Recycle Bin - 清空回收站 (&E) - - - - Empty the recycle bin of this notebook - 清空该笔记本的回收站 - - - - Are you sure to empty recycle bin of notebook <span style="%1">%2</span>? - 确认清空笔记本 <span style="%1">%2</span> 的回收站? - - - - <span style="%1">WARNING</span>: VNote will delete all the files in directory <span style="%2">%3</span>.<br>It may be UNRECOVERABLE! - <span style="%1">警告</span>:VNote会删除目录 <span style="%2">%3</span> 中的所有文件。<br>该操作可能是不可恢复的! - - - - Successfully emptied recycle bin of notebook <span style="%1">%2</span>! - 成功清空笔记本 <span style="%1">%2</span> 的回收站! - - - - Fail to empty recycle bin of notebook <span style="%1">%2</span>! - 清空笔记本 <span style="%1">%2</span> 的回收站失败! - - - - Sort Notebooks - 排序笔记本 - - - - Sort notebooks in the configuration file. - 对笔记本在配置文件中进行排序。 - - - - Name - 名字 - - - - - Information - 注意 - - - - Explore the root folder of this notebook in operating system - 在操作系统中浏览包含该笔记本的根文件夹 - - - - &Info (Rename) - 信息 (重命名)(&I) - - - - Create or import a notebook - 新建或导入一个笔记本 - - - - View and edit notebooks - 查看并编辑笔记本 - - - - * The root folder should be used EXCLUSIVELY by VNote and it is recommended to be EMPTY. - * 根目录应该给VNote单独使用,并且推荐使用空文件夹。 - - - - * A previously created notebook could be imported into VNote by choosing its root folder. - * 选择一个此前创建的笔记本的根目录可以将该笔记本导入VNote。 - - - - - - Warning - 警告 - - - - Fail to create notebook <span style="%1">%2</span> in <span style="%1">%3</span>. - 在 <span style="%1">%3</span> 中新建笔记本 <span style="%1">%2</span> 失败。 - - - - Delete Notebook - 删除笔记本 - - - - Fail to delete the root folder of notebook <span style="%1">%2</span> from disk. You may open the folder and check it manually. - 无法从磁盘中删除笔记本 <span style="%1">%2</span> 的根目录。 请打开该目录并手动检查。 - - - - - Add Notebook - 添加笔记本 - - - - Please type the name of the notebook and choose a folder as the Root Folder of the notebook. - 请输入笔记本的名字并选择一个文件夹作为笔记本的根目录。 - - - - Delete Notebook Folder From Disk - 从磁盘中删除笔记本根目录 - - - - Notebook Information - 笔记本信息 - - - - VOrphanFileInfoDialog - - - File: - 文件: - - - - Use global configuration (%1) - 使用全局配置 (%1) - - - - Set the path of the image folder to store images of this file. -If absolute path is used, VNote will not manage those images.(empty to use global configuration) - 设置该文件的图片文件夹的路径以保存相关图片。 -如果使用绝对路径,VNote不会管理这些图片。(为空则使用全局配置) - - - - &Image folder: - 图片文件夹 (&I): - - - - External File Information - 外部文件信息 - - - - VOutline - - - Decrease Expanded Level - 减小扩展层级 - - - - - Set Outline Expanded Level to %1 - 设置大纲扩展层级为 %1 - - - - Increase Expanded Level - 增加扩展层级 - - - - VOutlineUE - - - List and search the outline of current note - 列出和搜索当前笔记的大纲 - - - - VReadEditTab - - - Read Mode (For Markdown Only) - 阅读模式(仅Markdown笔记有效) - - - - Edit Mode - 编辑模式 - - - - Custom Web zoom factor - 自定义页面缩放倍数 - - - - Set the zoom factor of the Web page when reading - 设置阅读模式下页面的缩放倍数 - - - - Flash current heading - 闪烁当前标题 - - - - Flash current heading on change - 当前标题发生改变时闪烁 - - - Swap file - 交换文件 - - - - Automatically save changes to a swap file for backup - 自动将更改保存到交换文件中以备份 - - - Auto save - 自动保存 - - - Automatically save the note when editing - 编辑时自动保存笔记 - - - - Swap file (Recommended) - 交换文件 (推荐) - - - - Auto save (Buggy) - 自动保存 (不稳定) - - - - Automatically save the note when editing (may DELETE images on save) - 编辑时自动保存笔记 (可能会在保存的时候删除图片) - - - - Choose the key mode in editor - 选择编辑器的按键模式 - - - - Normal - 普通 - - - - Vim - Vim - - - - Smart input method in Vim mode - Vim模式智能输入法 - - - - Disable input method when leaving Insert mode in Vim mode - Vim模式中,退出插入模式时禁用输入法 - - - - Custom editor font - 自定义编辑器字体 - - - - Set the font of editor to override style configuration - 设置编辑器的字体以覆盖样式的配置 - - - - Set the zoom delta of the editor font - 设置编辑器字体的缩放大小 - - - - Key mode: - 按键模式: - - - - Editor zoom delta: - 编辑器缩放大小: - - - - It's recommended to enable "Swap file" or "Auto save", not both - 推荐启用“交换文件”或“自动保存”,但不推荐两者都启用 - - - - VSearchEngineWorker - - - Skip binary file %1. - 跳过二进制文件 %1 。 - - - - VSearchResultTree - - - &Open - 打开 (&O) - - - - Open selected notes - 打开选定笔记 - - - - &Locate To Folder - 定位所在文件夹 (&L) - - - - Locate the folder of current note - 定位到当前笔记所在的文件夹 - - - - Add To Cart - 添加到小推车 - - - - Add selected notes to Cart for further processing - 将所选笔记添加到小推车以进一步处理 - - - - Pin To History - 钉到历史中 - - - - Pin selected notes to History - 将选定笔记钉到历史中 - - - - Expand/Collapse All %1 - 展开/折叠全部 %1 - - - - %1 %2 added to Cart - %1个%2添加到小推车 - - - - - notes - 笔记 - - - - - note - 笔记 - - - - %1 %2 pinned to History - %1个%2被钉到历史中 - - - - VSearchUE - - - List and search all the notebooks - 列出和搜索全部笔记本 - - - - Search the name of folders/notes in all the notebooks - 在全部笔记本中搜索文件夹或笔记的名字 - - - - Search the content of notes in all the notebooks - 在全部笔记本中搜索笔记的内容 - - - - Search the tags of notes in all the notebooks - 在全部笔记本中搜索笔记的标签 - - - - Search the name of folders/notes in current notebook - 在当前笔记本中搜索文件夹或笔记的名字 - - - - Search the content of notes in current notebook - 在当前笔记本中搜索笔记的内容 - - - - Search the tags of notes in current notebook - 在当前笔记本中搜索笔记的标签 - - - - Search the name of folders/notes in current folder - 在当前文件夹中搜索文件夹或笔记的名字 - - - - Search the content of notes in current folder - 在当前文件夹中搜索笔记的内容 - - - - Search the tags of notes in current folder - 在当前文件夹中搜索笔记的标签 - - - - List and search the name of opened notes in buffer - 列出和搜索缓冲区中已打开笔记的名字 - - - - Search the content of opened notes in buffer - 搜索缓冲区中已打开笔记的内容 - - - - Search the outline of opened notes in buffer - 搜索缓冲区中已打开笔记的大纲 - - - - Search the path of folders/notes in all the notebooks - 在全部笔记本中搜索文件夹或笔记的路径 - - - - Search the path of folders/notes in current notebook - 在当前笔记本中搜索文件夹或笔记的路径 - - - - Search the content of notes in Explorer root directory - 在浏览器根目录中搜索笔记的内容 - - - - Invalid ID %1 - 无效的ID %1 - - - - VSearcher - - - Search - 搜索 - - - - Clear Results - 清空结果 - - - - Advanced Settings - 高级设置 - - - - Console - 控制台 - - - - Keywords to search for - 需要搜索的关键词 - - - - Supports space, &&, and || - 支持空格,&& 和 || - - - - Scope to search - 搜索范围 - - - - Object to search - 搜索对象 - - - - Target to search - 搜索目标 - - - - Wildcard pattern to filter the files to be searched - 用于筛选将要被搜索的文件的通配符模式 - - - - Engine to execute the search - 执行搜索的引擎 - - - - &Case sensitive - 区分大小写 (&C) - - - - &Whole word only - 完整字词匹配 (&W) - - - - &Fuzzy search - 模糊搜索 (&F) - - - - Not available for content search - 对内容搜索无效 - - - - Re&gular expression - 正则表达式 (&G) - - - - File pattern: - 文件模式: - - - - Engine: - 引擎: - - - - Cancel - 取消 - - - - Cancelling the search... - 正在取消搜索... - - - - Output logs will be shown here - 输出日志会显示在这里 - - - - Keywords: - 关键词: - - - - Scope: - 范围: - - - - Object: - 对象: - - - - Target: - 目标: - - - - Opened Notes - 已打开笔记 - - - - Current Folder - 当前文件夹 - - - - Current Notebook - 当前笔记本 - - - - All Notebooks - 所有笔记本 - - - - Explorer Directory - 浏览器目录 - - - - Name - 名字 - - - - Content - 内容 - - - - Tag - 标签 - - - - Path - 路径 - - - - Note - 笔记 - - - - Folder - 文件夹 - - - - Notebook - 笔记本 - - - - Note/Folder/Notebook - 笔记/文件夹/笔记本 - - - - Internal - 内置 - - - - Search started. - 搜索开始。 - - - - Search current note %1. - 搜索当前笔记 %1 。 - - - - Search current folder %1. - 搜索当前文件夹 %1 。 - - - - Search current notebook %1. - 搜索当前笔记本 %1 。 - - - - Search Explorer directory %1. - 搜索浏览器目录 %1 。 - - - - Search is on going. - 搜索正在进行。 - - - - Search succeeded. - 搜索成功。 - - - - - Search failed. - 搜索失败。 - - - - - Warning - 警告 - - - - User cancelled the search. Aborted! - 用户取消搜索。终止! - - - - Errors found during search. - 搜索过程中发生错误。 - - - - %1 Items - %1 项 - - - - VSelectDialog - - - Cancel - 取消 - - - - VSettingsDialog - - - General - 常规 - - - - Read/Edit - 阅读与编辑 - - - - Note Management - 笔记管理 - - - - Settings - 设置 - - - - Reset VNote - 重置VNote - - - - Reset all the configurations of VNote - 重置VNote的所有配置 - - - - Reset Layout - 重置布局 - - - - Reset layout of VNote - 重置VNote的布局 - - - - Appearance - 外观 - - - - Markdown - Markdown - - - - Misc - 杂项 - - - - Image Hosting - 图床 - - - - - - - Warning - 警告 - - - - Are you sure to reset VNote? - 确认重置VNote? - - - - All configurations (except notebooks information) will be reset to default values. It is UNRECOVERABLE! - 所有的配置(除了笔记本信息)都会被重置为默认值。该操作是不可恢复的! - - - - - Information - 注意 - - - - - Please restart VNote to make it work. - 请重新启动VNote以便重置生效。 - - - - - Any change to VNote before restart will be lost! - 在重新启动前,所有对VNote的更改都会丢失! - - - - Are you sure to reset the layout of VNote? - 确认重置VNote的布局? - - - - The view and layout mode will be reset. It is UNRECOVERABLE! - 视图和布局会被重置。该操作是不可恢复的! - - - - Fail to load configuration. - 读取配置失败。 - - - - Fail to save configuration. Please try it again. - 保存配置失败。请稍后再试。 - - - - VSimpleSearchInput - - - Type to search - 输入以查找 - - - - %1/%2 - %1/%2 - - - - VSnippetList - - - - - - - Warning - 警告 - - - - Fail to read snippets from <span style="%1">%2</span>. - 从 <span style="%1">%2</span> 读取片段失败。 - - - - New Snippet - 新建片段 - - - - Open Folder - 打开所在文件夹 - - - - &Apply - 应用 (&A) - - - - Insert this snippet in editor - 在编辑器中插入该片段 - - - - View and edit snippet's information - 查看并编辑片段的信息 - - - - &Delete - 删除 (&D) - - - - Delete selected snippets - 删除选定片段 - - - - &Sort - 排序 (&S) - - - - Sort snippets manually - 对片段进行手动排序 - - - - - Magic words are supported in the content of the snippet. - 片段内容支持幻词。 - - - - Create Snippet - 新建片段 - - - - Fail to create snippet <span style="%1">%2</span>. - 新建片段 <span style="%1">%2</span> 失败。 - - - - &Info (Rename) %1 - 信息 (重命名)(&I) %1 - - - - Are you sure to delete these snippets? - 确认删除这些片段? - - - - Click "Cancel" to leave them untouched. - 点击“取消”以终止操作。 - - - - Confirm Deleting Snippets - 确认删除片段 - - - - Fail to delete snippets. - 删除片段失败。 - - - - Sort Snippets - 排序片段 - - - - Sort snippets in the configuration file. - 对片段在配置文件中进行排序。 - - - - Name - 名字 - - - - Fail to sort snippets. - 排序片段失败。 - - - - Snippet Information - 片段信息 - - - - - - - Fail to write snippets configuration file. - 写入片段的配置失败。 - - - - Fail to update information of snippet <span style="%1">%2</span>. - 更新片段 <span style="%1">%2</span> 的信息失败。 - - - - %1 %2 - %1 %2 - - - - Items - - - - - Item - - - - - Fail to add write the snippet file %1. - 写入片段文件 %1 失败。 - - - - Fail to remove snippet file %1. - 删除片段文件 %1 失败。 - - - - VSortDialog - - - &Top - 移到顶部 (&T) - - - - Move selected items to top - 将所选项移动到顶部 - - - - &Up - 上移 (&U) - - - - Move selected items up - 将所选项往上移动一项 - - - - &Down - 下移 (&D) - - - - Move selected items down - 将所选项往下移动一项 - - - - &Bottom - 移到底部 (&B) - - - - Move selected items to bottom - 将所选项移动到底部 - - - - VTabIndicator - - - The type of the file - 文件类型 - - - - ReadOnly - 只读 - - - - This file is read-only - 文件为只读 - - - - Standalone - 独立文件 - - - - This file is not managed by any notebook or folder - 文件未被任何笔记本或文件夹管理 - - - - System - 系统文件 - - - - This file is a system file - 文件为系统文件 - - - - - [W] - [词] - - - - Word Count Information - 字数信息 - - - - Line: %1 - %2(%3%) Col: %4 - 行: %1 - %2(%3%) 列: %4 - - - - [%1]%2 - [%1]%2 - - - - C - - - - - W - - - - - VTagExplorer - - - - Tags - 标签 - - - - - Notes - 笔记 - - - - Split - 分割 - - - - Tags (%1) - 标签 (%1) - - - - Notes (%1) - 笔记 (%1) - - - - Searching for tag "%1" - 正在搜索标签“%1” - - - - Invalid busy state when searching for tag - 搜索标签时遇到非法的忙状态 - - - - Search for tag succeeded - 搜索标签成功 - - - - Search for tag failed - 搜索标签失败 - - - - Search for tag calcelled - 搜索标签被取消 - - - - &Open - 打开 (&O) - - - - Open selected notes - 打开选定笔记 - - - - &Locate To Folder - 定位所在文件夹 (&L) - - - - Locate the folder of current note - 定位到当前笔记所在的文件夹 - - - - Add To Cart - 添加到小推车 - - - - Add selected notes to Cart for further processing - 将所选笔记添加到小推车以进一步处理 - - - - Pin To History - 钉到历史中 - - - - Pin selected notes to History - 将选定笔记钉到历史中 - - - - %1 %2 added to Cart - %1个%2添加到小推车 - - - - - notes - 笔记 - - - - - note - 笔记 - - - - %1 %2 pinned to History - %1个%2被钉到历史中 - - - - Warning - 警告 - - - - Empty tag detected! Do you want to remove it? - 检测到空的标签!是否移除该标签? - - - - The tag <span style="%1">%2</span> seems not to be assigned to any note currently. - 标签 <span style="%1">%2</span> 当前似乎没有被分配给任何笔记。 - - - - VTagLabel - - - Remove - 移除 - - - - VTagPanel - - - View and edit tags of current note - 查看并编辑当前笔记的标签 - - - - Press Enter to add a tag - 输入回车以添加一个标签 - - - - Add a tag - 添加标签 - - - - Tag "%1" added - 标签“%1” 已添加 - - - - Tag "%1" removed - 标签“%1” 已移除 - - - - VTencentImageHosting - - - Abort - 终止 - - - - - - - - - - - Tencent Cloud Image Hosting - 腾讯云图床 - - - - Please configure the Tencent Cloud image hosting first! - 请先配置腾讯云图床! - - - - Uploading images to Tencent Cloud... - 正在上传图片到腾讯云 ... - - - - Uploading Images To Tencent Cloud - 正在上传图片到腾讯云 - - - - - Unsupported type: - 不支持的类型: - - - - No local images to upload: %1 - 没有需要上传的本地图片: %1 - - - - Uploading image: %1 - 正在上传图片: %1 - - - - The picture does not exist in this path: - 图片不存在: - - - - - -Network error: HostNotFoundError - - -网络错误: 无法找到主机 - - - - - -Please check your network - - -请检查网络 - - - - Uploading - 正在上传 - - - - Copied contents with new image links - 已复制替换新图片链接的内容 - - - - VTipsDialog - - - VNote Tips - VNote提示 - - - - VUniversalEntry - - - Universal Entry, reach anything by typing - 通用入口,触手可达 - - - - VUpdater - - - Current Version: v%1 - 当前版本:v%1 - - - - - Checking for updates... - 正在检查更新... - - - - VNote Update - VNote更新 - - - - :( Fail to check for updates. -Please try it later. - :( 检查更新失败。 -请稍后再试。 - - - - Current Version: v%1 -Latest Version: v%2 - 当前版本:v%1 -最新版本:v%2 - - - - <span style="font-weight: bold;">Updates Available!</span><br/>Please visit <a href="%1">GitHub Releases</a> to download the latest version. - <span style="font-weight: bold;">发现更新!</span><br/>请访问<a href="%1">GitHub Releases</a>下载最新版本。 - - - - VNote is already the latest version. - VNote当前已经是最新版本。 - - - - VVim - - - - - - %1 %2 changed - 更改了 %1 %2 - - - - - - - - - - - - - - - - - lines - - - - - - - - - - - - - - - - - - line - - - - - Mark not set - 标记未设置 - - - - - - %1 fewer %2 - 少了 %1 %2 - - - - - - %1 %2 yanked - 复制了 %1 %2 - - - - %1 more %2 - 多了 %1 %2 - - - - - - %1 %2 %3ed 1 time - %1 %2 %3 了1次 - - - - Undo %1 %2 - 撤销 %1 次%2 - - - - - changes - 更改 - - - - - change - 更改 - - - - Redo %1 %2 - 重做 %1 次%2 - - - - Mark has invalid line number - 标记的行号无效 - - - - - Note has been saved - 已保存笔记 - - - - - Quit - 退出编辑 - - - - - Quit with note having been saved - 保存更改并退出编辑 - - - - Not an editor command: %1 - 不是一个编辑器命令:%1 - - - - VVimIndicator - - - Registers - 寄存器 - - - - Register - 寄存器 - - - - Value - - - - - Marks - 标记 - - - - Mark - 标记 - - - - Line - - - - - Column - - - - - Text - 文本 - - - - Normal - 正常 - - - - Insert - 插入 - - - - Visual - 可视 - - - - VisualLine - 可视行 - - - - Replace - 替换 - - - - Unknown - 未知 - - - - VWebView - - - Expand/Restore Preview Area - 扩展/还原预览区域 - - - - &Edit - 编辑 (&E) - - - - Edit current note - 编辑当前笔记 - - - - Copy As - 复制为 - - - - Copy selected content using rules specified by target %1 - 使用目标 %1 指定的规则复制所选内容 - - - - Copy All As - 复制全部为 - - - - Copy all content using rules specified by target %1 - 使用目标 %1 指定的规则复制全部内容 - - - - Live Preview Tunnel - 实时预览隧道 - - - - Disabled - 关闭 - - - - Editor -> Preview - 编辑器 -> 预览 - - - - Preview -> Editor - 预览 -> 编辑器 - - - - Bidirectional - 双向 - - - - VWechatImageHosting - - - - - - - - - - - - - - - - Wechat Image Hosting - 微信图床 - - - - Please configure the Wechat image hosting first! - 请先配置微信图床! - - - - Abort - 终止 - - - - - Unsupported type: - 不支持的类型: - - - - No local images to upload: %1 - 没有需要上传的本地图片: %1 - - - - Your ip address was set to the Clipboard! - IP地址已经复制到剪切板! - - - - -Please add the IP address: - -请添加IP地址: - - - - Please check your Wechat Image Hosting parameters! - - 请检查微信图床参数! - - - - - The size of the picture is more than 1M! Wechat API does not support! - 图片大小超过1M! 微信API不支持! - - - upload failed! Please contact the developer. - 上传错误!请联系开发者。 - - - - Uploading images to Wechat... - 正在上传图片到微信 ... - - - - Uploading Images To Wechat - 正在上传图片到微信 - - - - to the Wechat ip whitelist! - 到微信IP白名单! - - - - - JSON decode error. Please contact the developer. - JSON解析错误。请联系开发者。 - - - - Network error: - 网络错误: - - - - - -Please check your network! - - -请检查网络! - - - - Uploading image: %1 - 正在上传图片: %1 - - - - The picture does not exist in this path: - 图片不存在: - - - - Upload failed! Please contact the developer. - 上传错误!请联系开发者。 - - - - Uploading - 正在上传 - - - - - -Network error: - - -网络错误: - - - - - -Please check the network or image size - - -请检查网络或图片尺寸 - - - - Copied contents with new image links - 已复制替换新图片链接的内容 - - - - Contents with new image links are copied. - 包含新图片链接的内容已经复制。 - - - - Do you want to open the link of Markdown2Wechat tool? - 是否打开Markdown转微信工具链接? - - - - VWordCountPanel - - - - Words - - - - - - Characters (no spaces) - 字 (不含空格) - - - - - Characters (with spaces) - 字 (含空格) - - - - Read - 阅读 - - - - Edit - 编辑 - - - - Word Count - 字数 - - - - VSync - - - Sync - 同步 - - - - Sure - 确认 - - - - Downloading - 更新中... - - - - Uploading - 上传中... - - - - Download Success - 更新成功 - - - - Upload Success - 上传成功 - - - diff --git a/src/translations/widgets_zh_CN.qm b/src/translations/widgets_zh_CN.qm deleted file mode 100644 index b08ab97f..00000000 Binary files a/src/translations/widgets_zh_CN.qm and /dev/null differ diff --git a/src/translations/widgets_zh_CN.ts b/src/translations/widgets_zh_CN.ts deleted file mode 100644 index 9d83b413..00000000 --- a/src/translations/widgets_zh_CN.ts +++ /dev/null @@ -1,1225 +0,0 @@ - - - - - CloseButton - - - Close Tab - - - - - QAbstractSpinBox - - - &Select All - - - - - &Step up - - - - - Step &down - - - - - QApplication - - - Executable '%1' requires Qt %2, found Qt %3. - - - - - Incompatible Qt Library Error - - - - - QColorDialog - - - Hu&e: - - - - - &Sat: - - - - - &Val: - - - - - &Red: - - - - - &Green: - - - - - Bl&ue: - - - - - A&lpha channel: - - - - - &HTML: - - - - - Cursor at %1, %2 -Press ESC to cancel - - - - - Select Color - - - - - &Basic colors - - - - - &Custom colors - - - - - &Add to Custom Colors - - - - - &Pick Screen Color - - - - - QComboBox - - - Open the combo box selection popup - - - - - False - - - - - True - - - - - QDateTimeParser - - - AM - - - - - am - - - - - PM - - - - - pm - - - - - QDialog - - - What's This? - - - - - QDialogButtonBox - - - - OK - - - - - QDirModel - - - Name - - - - - Size - - - - - Kind - Match OS X Finder - - - - - Type - All other platforms - - - - - Date Modified - - - - - QDockWidget - - - Float - Accessible name for button undocking a dock widget (floating state) - - - - - Undocks and re-attaches the dock widget - - - - - Close - Accessible name for button closing a dock widget - - - - - Closes the dock widget - - - - - QErrorMessage - - - Debug Message: - - - - - Warning: - - - - - Critical Error: - - - - - Fatal Error: - - - - - Information: - - - - - &Show this message again - - - - - &OK - - - - - QFileDialog - - - Look in: - - - - - - Back - - - - - Go back - - - - - Alt+Left - - - - - - Forward - - - - - Go forward - - - - - Alt+Right - - - - - - Parent Directory - - - - - Go to the parent directory - - - - - Alt+Up - - - - - - Create New Folder - - - - - Create a New Folder - - - - - - List View - - - - - Change to list view mode - - - - - - Detail View - - - - - Change to detail view mode - - - - - Sidebar - - - - - List of places and bookmarks - - - - - - Files - - - - - Files of type: - - - - - Find Directory - - - - - Open - - - - - Save As - - - - - Directory: - - - - - File &name: - - - - - - &Open - - - - - &Choose - - - - - &Save - - - - - Show - - - - - &Rename - - - - - &Delete - - - - - Show &hidden files - - - - - &New Folder - - - - - All files (*) - - - - - Directories - - - - - - %1 -Directory not found. -Please verify the correct directory name was given. - - - - - %1 already exists. -Do you want to replace it? - - - - - %1 -File not found. -Please verify the correct file name was given. - - - - - New Folder - - - - - - Delete - - - - - '%1' is write protected. -Do you want to delete it anyway? - - - - - Are you sure you want to delete '%1'? - - - - - Could not delete directory. - - - - - Recent Places - - - - - Remove - - - - - My Computer - - - - - Drive - - - - - %1 File - %1 is a file name suffix, for example txt - - - - - File - - - - - File Folder - Match Windows Explorer - - - - - Folder - All other platforms - - - - - Alias - OS X Finder - - - - - Shortcut - All other platforms - - - - - Unknown - - - - - QFileSystemModel - - - - %1 TB - - - - - - %1 GB - - - - - - %1 MB - - - - - - %1 KB - - - - - %1 bytes - - - - - Invalid filename - - - - - <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. - - - - - Name - - - - - Size - - - - - Kind - Match OS X Finder - - - - - Type - All other platforms - - - - - Date Modified - - - - - My Computer - - - - - Computer - - - - - %1 byte(s) - - - - - QFontDialog - - - Select Font - - - - - &Font - - - - - Font st&yle - - - - - &Size - - - - - Effects - - - - - Stri&keout - - - - - &Underline - - - - - Sample - - - - - Wr&iting System - - - - - QInputDialog - - - Enter a value: - - - - - QKeySequenceEdit - - - Press shortcut - - - - - %1, ... - This text is an "unfinished" shortcut, expands like "Ctrl+A, ..." - - - - - QLineEdit - - - &Undo - - - - - &Redo - - - - - Cu&t - - - - - &Copy - - - - - &Paste - - - - - Delete - - - - - Select All - - - - - QMdiArea - - - (Untitled) - - - - - QMdiSubWindow - - - - [%1] - - - - - %1 - [%2] - - - - - Minimize - - - - - Maximize - - - - - Unshade - - - - - Shade - - - - - Restore Down - - - - - Restore - - - - - Close - - - - - Help - - - - - Menu - - - - - &Restore - - - - - &Move - - - - - &Size - - - - - Mi&nimize - - - - - Ma&ximize - - - - - Stay on &Top - - - - - &Close - - - - - QMessageBox - - - Show Details... - - - - - Hide Details... - - - - - <h3>About Qt</h3><p>This program uses Qt version %1.</p> - - - - - <p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across all major desktop operating systems. It is also available for embedded Linux and other embedded and mobile operating systems.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p><p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 3.</p><p>Qt licensed under the GNU LGPL version 3 is appropriate for the development of Qt&nbsp;applications provided you can comply with the terms and conditions of the GNU LGPL version 3.</p><p>Please see <a href="http://%2/">%2</a> for an overview of Qt licensing.</p><p>Copyright (C) %1 The Qt Company Ltd and other contributors.</p><p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p><p>Qt is The Qt Company Ltd product developed as an open source project. See <a href="http://%3/">%3</a> for more information.</p> - - - - - About Qt - - - - - QProgressDialog - - - Cancel - - - - - QScrollBar - - - Scroll here - - - - - Left edge - - - - - Top - - - - - Right edge - - - - - Bottom - - - - - Page left - - - - - Page up - - - - - Page right - - - - - Page down - - - - - Scroll left - - - - - Scroll up - - - - - Scroll right - - - - - Scroll down - - - - - QTabBar - - - Scroll Left - - - - - Scroll Right - - - - - QUndoGroup - - - Undo %1 - - - - - Undo - Default text for undo action - - - - - Redo %1 - - - - - Redo - Default text for redo action - - - - - QUndoModel - - - <empty> - - - - - QUndoStack - - - Undo %1 - - - - - Undo - Default text for undo action - - - - - Redo %1 - - - - - Redo - Default text for redo action - - - - - QUnicodeControlCharacterMenu - - - LRM Left-to-right mark - - - - - RLM Right-to-left mark - - - - - ZWJ Zero width joiner - - - - - ZWNJ Zero width non-joiner - - - - - ZWSP Zero width space - - - - - LRE Start of left-to-right embedding - - - - - RLE Start of right-to-left embedding - - - - - LRO Start of left-to-right override - - - - - RLO Start of right-to-left override - - - - - PDF Pop directional formatting - - - - - LRI Left-to-right isolate - - - - - RLI Right-to-left isolate - - - - - FSI First strong isolate - - - - - PDI Pop directional isolate - - - - - Insert Unicode control character - - - - - QWhatsThisAction - - - What's This? - - - - - QWidget - - - * - - - - - QWidgetTextControl - - - &Undo - - - - - &Redo - - - - - Cu&t - - - - - &Copy - - - - - Copy &Link Location - - - - - &Paste - - - - - Delete - - - - - Select All - - - - - QWizard - - - Go Back - - - - - < &Back - - - - - Continue - - - - - &Next - - - - - &Next > - - - - - Commit - - - - - Done - - - - - &Finish - - - - - Cancel - - - - - Help - - - - - &Help - - - - diff --git a/src/utils/clipboard.js/README.md b/src/utils/clipboard.js/README.md deleted file mode 100644 index 61bfead3..00000000 --- a/src/utils/clipboard.js/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# [clipboard.js](https://github.com/zenorocha/clipboard.js) -v2.0.4 diff --git a/src/utils/clipboard.js/clipboard.min.js b/src/utils/clipboard.js/clipboard.min.js deleted file mode 100644 index 02c549e3..00000000 --- a/src/utils/clipboard.js/clipboard.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * clipboard.js v2.0.4 - * https://zenorocha.github.io/clipboard.js - * - * Licensed MIT © Zeno Rocha - */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n' + xhtml + ''; - }) - .then(function (foreignObject) { - return '' + - foreignObject + ''; - }) - .then(function (svg) { - return 'data:image/svg+xml;charset=utf-8,' + svg; - }); - } - - function newUtil() { - return { - escape: escape, - parseExtension: parseExtension, - mimeType: mimeType, - dataAsUrl: dataAsUrl, - isDataUrl: isDataUrl, - canvasToBlob: canvasToBlob, - resolveUrl: resolveUrl, - getAndEncode: getAndEncode, - uid: uid(), - delay: delay, - asArray: asArray, - escapeXhtml: escapeXhtml, - makeImage: makeImage, - width: width, - height: height - }; - - function mimes() { - /* - * Only WOFF and EOT mime types for fonts are 'real' - * see http://www.iana.org/assignments/media-types/media-types.xhtml - */ - var WOFF = 'application/font-woff'; - var JPEG = 'image/jpeg'; - - return { - 'woff': WOFF, - 'woff2': WOFF, - 'ttf': 'application/font-truetype', - 'eot': 'application/vnd.ms-fontobject', - 'png': 'image/png', - 'jpg': JPEG, - 'jpeg': JPEG, - 'gif': 'image/gif', - 'tiff': 'image/tiff', - 'svg': 'image/svg+xml' - }; - } - - function parseExtension(url) { - var match = /\.([^\.\/]*?)$/g.exec(url); - if (match) return match[1]; - else return ''; - } - - function mimeType(url) { - var extension = parseExtension(url).toLowerCase(); - return mimes()[extension] || ''; - } - - function isDataUrl(url) { - return url.search(/^(data:)/) !== -1; - } - - function toBlob(canvas) { - return new Promise(function (resolve) { - var binaryString = window.atob(canvas.toDataURL().split(',')[1]); - var length = binaryString.length; - var binaryArray = new Uint8Array(length); - - for (var i = 0; i < length; i++) - binaryArray[i] = binaryString.charCodeAt(i); - - resolve(new Blob([binaryArray], { - type: 'image/png' - })); - }); - } - - function canvasToBlob(canvas) { - if (canvas.toBlob) - return new Promise(function (resolve) { - canvas.toBlob(resolve); - }); - - return toBlob(canvas); - } - - function resolveUrl(url, baseUrl) { - var doc = document.implementation.createHTMLDocument(); - var base = doc.createElement('base'); - doc.head.appendChild(base); - var a = doc.createElement('a'); - doc.body.appendChild(a); - base.href = baseUrl; - a.href = url; - return a.href; - } - - function uid() { - var index = 0; - - return function () { - return 'u' + fourRandomChars() + index++; - - function fourRandomChars() { - /* see http://stackoverflow.com/a/6248722/2519373 */ - return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); - } - }; - } - - function makeImage(uri) { - return new Promise(function (resolve, reject) { - var image = new Image(); - image.onload = function () { - resolve(image); - }; - image.onerror = reject; - image.src = uri; - }); - } - - function getAndEncode(url) { - var TIMEOUT = 30000; - if(domtoimage.impl.options.cacheBust) { - // Cache bypass so we dont have CORS issues with cached images - // Source: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache - url += ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime(); - } - - return new Promise(function (resolve) { - var request = new XMLHttpRequest(); - - request.onreadystatechange = done; - request.ontimeout = timeout; - request.responseType = 'blob'; - request.timeout = TIMEOUT; - request.open('GET', url, true); - request.send(); - - var placeholder; - if(domtoimage.impl.options.imagePlaceholder) { - var split = domtoimage.impl.options.imagePlaceholder.split(/,/); - if(split && split[1]) { - placeholder = split[1]; - } - } - - function done() { - if (request.readyState !== 4) return; - - if (request.status !== 200) { - if(placeholder) { - resolve(placeholder); - } else { - fail('cannot fetch resource: ' + url + ', status: ' + request.status); - } - - return; - } - - var encoder = new FileReader(); - encoder.onloadend = function () { - var content = encoder.result.split(/,/)[1]; - resolve(content); - }; - encoder.readAsDataURL(request.response); - } - - function timeout() { - if(placeholder) { - resolve(placeholder); - } else { - fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url); - } - } - - function fail(message) { - console.error(message); - resolve(''); - } - }); - } - - function dataAsUrl(content, type) { - return 'data:' + type + ';base64,' + content; - } - - function escape(string) { - return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); - } - - function delay(ms) { - return function (arg) { - return new Promise(function (resolve) { - setTimeout(function () { - resolve(arg); - }, ms); - }); - }; - } - - function asArray(arrayLike) { - var array = []; - var length = arrayLike.length; - for (var i = 0; i < length; i++) array.push(arrayLike[i]); - return array; - } - - function escapeXhtml(string) { - return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); - } - - function width(node) { - var leftBorder = px(node, 'border-left-width'); - var rightBorder = px(node, 'border-right-width'); - return node.scrollWidth + leftBorder + rightBorder; - } - - function height(node) { - var topBorder = px(node, 'border-top-width'); - var bottomBorder = px(node, 'border-bottom-width'); - return node.scrollHeight + topBorder + bottomBorder; - } - - function px(node, styleProperty) { - var value = window.getComputedStyle(node).getPropertyValue(styleProperty); - return parseFloat(value.replace('px', '')); - } - } - - function newInliner() { - var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; - - return { - inlineAll: inlineAll, - shouldProcess: shouldProcess, - impl: { - readUrls: readUrls, - inline: inline - } - }; - - function shouldProcess(string) { - return string.search(URL_REGEX) !== -1; - } - - function readUrls(string) { - var result = []; - var match; - while ((match = URL_REGEX.exec(string)) !== null) { - result.push(match[1]); - } - return result.filter(function (url) { - return !util.isDataUrl(url); - }); - } - - function inline(string, url, baseUrl, get) { - return Promise.resolve(url) - .then(function (url) { - return baseUrl ? util.resolveUrl(url, baseUrl) : url; - }) - .then(get || util.getAndEncode) - .then(function (data) { - return util.dataAsUrl(data, util.mimeType(url)); - }) - .then(function (dataUrl) { - return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); - }); - - function urlAsRegex(url) { - return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); - } - } - - function inlineAll(string, baseUrl, get) { - if (nothingToInline()) return Promise.resolve(string); - - return Promise.resolve(string) - .then(readUrls) - .then(function (urls) { - var done = Promise.resolve(string); - urls.forEach(function (url) { - done = done.then(function (string) { - return inline(string, url, baseUrl, get); - }); - }); - return done; - }); - - function nothingToInline() { - return !shouldProcess(string); - } - } - } - - function newFontFaces() { - return { - resolveAll: resolveAll, - impl: { - readAll: readAll - } - }; - - function resolveAll() { - return readAll(document) - .then(function (webFonts) { - return Promise.all( - webFonts.map(function (webFont) { - return webFont.resolve(); - }) - ); - }) - .then(function (cssStrings) { - return cssStrings.join('\n'); - }); - } - - function readAll() { - return Promise.resolve(util.asArray(document.styleSheets)) - .then(getCssRules) - .then(selectWebFontRules) - .then(function (rules) { - return rules.map(newWebFont); - }); - - function selectWebFontRules(cssRules) { - return cssRules - .filter(function (rule) { - return rule.type === CSSRule.FONT_FACE_RULE; - }) - .filter(function (rule) { - return inliner.shouldProcess(rule.style.getPropertyValue('src')); - }); - } - - function getCssRules(styleSheets) { - var cssRules = []; - styleSheets.forEach(function (sheet) { - try { - util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); - } catch (e) { - console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); - } - }); - return cssRules; - } - - function newWebFont(webFontRule) { - return { - resolve: function resolve() { - var baseUrl = (webFontRule.parentStyleSheet || {}).href; - return inliner.inlineAll(webFontRule.cssText, baseUrl); - }, - src: function () { - return webFontRule.style.getPropertyValue('src'); - } - }; - } - } - } - - function newImages() { - return { - inlineAll: inlineAll, - impl: { - newImage: newImage - } - }; - - function newImage(element) { - return { - inline: inline - }; - - function inline(get) { - if (util.isDataUrl(element.src)) return Promise.resolve(); - - return Promise.resolve(element.src) - .then(get || util.getAndEncode) - .then(function (data) { - return util.dataAsUrl(data, util.mimeType(element.src)); - }) - .then(function (dataUrl) { - return new Promise(function (resolve, reject) { - element.onload = resolve; - element.onerror = reject; - element.src = dataUrl; - }); - }); - } - } - - function inlineAll(node) { - if (!(node instanceof Element)) return Promise.resolve(node); - - return inlineBackground(node) - .then(function () { - if (node instanceof HTMLImageElement) - return newImage(node).inline(); - else - return Promise.all( - util.asArray(node.childNodes).map(function (child) { - return inlineAll(child); - }) - ); - }); - - function inlineBackground(node) { - // Fix MathJax issue. - if (!node.style) { - return Promise.resolve(node); - } - - var background = node.style.getPropertyValue('background'); - - if (!background) return Promise.resolve(node); - - return inliner.inlineAll(background) - .then(function (inlined) { - node.style.setProperty( - 'background', - inlined, - node.style.getPropertyPriority('background') - ); - }) - .then(function () { - return node; - }); - } - } - } -})(this); diff --git a/src/utils/flowchart.js/README.md b/src/utils/flowchart.js/README.md deleted file mode 100644 index b16d49be..00000000 --- a/src/utils/flowchart.js/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# [flowchart.js](https://github.com/adrai/flowchart.js) -v1.11.3 -Adriano Raiano - -# [Raphael](https://github.com/DmitryBaranovskiy/raphael) -v2.2.7 diff --git a/src/utils/flowchart.js/flowchart.min.js b/src/utils/flowchart.js/flowchart.min.js deleted file mode 100644 index 89260a0a..00000000 --- a/src/utils/flowchart.js/flowchart.min.js +++ /dev/null @@ -1,7 +0,0 @@ -// flowchart.js, v1.11.3 -// Copyright (c)2018 Adriano Raiano (adrai). -// Distributed under MIT license -// http://adrai.github.io/flowchart.js - -!function(t,i){if("object"==typeof exports&&"object"==typeof module)module.exports=i(require("Raphael"));else if("function"==typeof define&&define.amd)define(["Raphael"],i);else{var e=i("object"==typeof exports?require("Raphael"):t.Raphael);for(var r in e)("object"==typeof exports?exports:t)[r]=e[r]}}(this,function(t){return function(t){function i(r){if(e[r])return e[r].exports;var s=e[r]={exports:{},id:r,loaded:!1};return t[r].call(s.exports,s,s.exports,i),s.loaded=!0,s.exports}var e={};return i.m=t,i.c=e,i.p="",i(0)}([function(t,i,e){e(9);var r=e(4);e(15);var s={parse:r};"undefined"!=typeof window&&(window.flowchart=s),t.exports=s},function(t,i){function e(t,i){if(!t||"function"==typeof t)return i;var r={};for(var s in i)r[s]=i[s];for(s in t)t[s]&&("object"==typeof r[s]?r[s]=e(r[s],t[s]):r[s]=t[s]);return r}function r(t,i){if("function"==typeof Object.create)t.super_=i,t.prototype=Object.create(i.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}});else{t.super_=i;var e=function(){};e.prototype=i.prototype,t.prototype=new e,t.prototype.constructor=t}}t.exports={defaults:e,inherits:r}},function(t,i,e){function r(t,i,e){this.chart=t,this.group=this.chart.paper.set(),this.symbol=e,this.connectedTo=[],this.symbolType=i.symbolType,this.flowstate=i.flowstate||"future",this.lineStyle=i.lineStyle||{},this.key=i.key||"",this.next_direction=i.next&&i.direction_next?i.direction_next:void 0,this.text=this.chart.paper.text(0,0,i.text),i.key&&(this.text.node.id=i.key+"t"),this.text.node.setAttribute("class",this.getAttr("class")+"t"),this.text.attr({"text-anchor":"start",x:this.getAttr("text-margin"),fill:this.getAttr("font-color"),"font-size":this.getAttr("font-size")});var r=this.getAttr("font"),s=this.getAttr("font-family"),o=this.getAttr("font-weight");r&&this.text.attr({font:r}),s&&this.text.attr({"font-family":s}),o&&this.text.attr({"font-weight":o}),i.link&&this.text.attr("href",i.link),i.target&&this.text.attr("target",i.target);var h=this.getAttr("maxWidth");if(h){for(var n=i.text.split(" "),a="",l=0,p=n.length;lh?"\n"+y:" "+y}this.text.attr("text",a.substring(1))}if(this.group.push(this.text),e){var x=this.getAttr("text-margin");e.attr({fill:this.getAttr("fill"),stroke:this.getAttr("element-color"),"stroke-width":this.getAttr("line-width"),width:this.text.getBBox().width+2*x,height:this.text.getBBox().height+2*x}),e.node.setAttribute("class",this.getAttr("class")),i.link&&e.attr("href",i.link),i.target&&e.attr("target",i.target),i.key&&(e.node.id=i.key),this.group.push(e),e.insertBefore(this.text),this.text.attr({y:e.getBBox().height/2}),this.initialize()}}var s=e(3),o=s.drawLine,h=s.checkLineIntersection;r.prototype.getAttr=function(t){if(this.chart){var i,e=this.chart.options?this.chart.options[t]:void 0,r=this.chart.options.symbols?this.chart.options.symbols[this.symbolType][t]:void 0;return this.chart.options.flowstate&&this.chart.options.flowstate[this.flowstate]&&(i=this.chart.options.flowstate[this.flowstate][t]),i||r||e}},r.prototype.initialize=function(){this.group.transform("t"+this.getAttr("line-width")+","+this.getAttr("line-width")),this.width=this.group.getBBox().width,this.height=this.group.getBBox().height},r.prototype.getCenter=function(){return{x:this.getX()+this.width/2,y:this.getY()+this.height/2}},r.prototype.getX=function(){return this.group.getBBox().x},r.prototype.getY=function(){return this.group.getBBox().y},r.prototype.shiftX=function(t){this.group.transform("t"+(this.getX()+t)+","+this.getY())},r.prototype.setX=function(t){this.group.transform("t"+t+","+this.getY())},r.prototype.shiftY=function(t){this.group.transform("t"+this.getX()+","+(this.getY()+t))},r.prototype.setY=function(t){this.group.transform("t"+this.getX()+","+t)},r.prototype.getTop=function(){var t=this.getY(),i=this.getX()+this.width/2;return{x:i,y:t}},r.prototype.getBottom=function(){var t=this.getY()+this.height,i=this.getX()+this.width/2;return{x:i,y:t}},r.prototype.getLeft=function(){var t=this.getY()+this.group.getBBox().height/2,i=this.getX();return{x:i,y:t}},r.prototype.getRight=function(){var t=this.getY()+this.group.getBBox().height/2,i=this.getX()+this.group.getBBox().width;return{x:i,y:t}},r.prototype.render=function(){if(this.next){var t=this,i=this.getAttr("line-length");if("right"===this.next_direction){var e=this.getRight();this.next.isPositioned||(this.next.setY(e.y-this.next.height/2),this.next.shiftX(this.group.getBBox().x+this.width+i),function e(){for(var r,s=!1,o=0,h=t.chart.symbols.length;ot.next.getCenter().y&&n<=t.next.width/2){s=!0;break}}if(s){if("end"===t.next.symbolType)return;t.next.setX(r.getX()+r.width+i),e()}}(),this.next.isPositioned=!0,this.next.render())}else if("left"===this.next_direction){var r=this.getLeft();this.next.isPositioned||(this.next.setY(r.y-this.next.height/2),this.next.shiftX(-(this.group.getBBox().x+this.width+i)),function e(){for(var r,s=!1,o=0,h=t.chart.symbols.length;ot.next.getCenter().y&&n<=t.next.width/2){s=!0;break}}if(s){if("end"===t.next.symbolType)return;t.next.setX(r.getX()+r.width+i),e()}}(),this.next.isPositioned=!0,this.next.render())}else{var s=this.getBottom();this.next.isPositioned||(this.next.shiftY(this.getY()+this.height+i),this.next.setX(s.x-this.next.width/2),this.next.isPositioned=!0,this.next.render())}}},r.prototype.renderLines=function(){this.next&&(this.next_direction?this.drawLineTo(this.next,this.getAttr("arrow-text")||"",this.next_direction):this.drawLineTo(this.next,this.getAttr("arrow-text")||""))},r.prototype.drawLineTo=function(t,i,e){this.connectedTo.indexOf(t)<0&&this.connectedTo.push(t);var r,s=this.getCenter().x,n=this.getCenter().y,a=this.getRight(),l=this.getBottom(),p=this.getTop(),y=this.getLeft(),x=t.getCenter().x,g=t.getCenter().y,c=t.getTop(),f=t.getRight(),d=t.getLeft(),m=s===x,u=n===g,b=ng||this===t,v=s>x,w=sk&&(k=c.x);else r=this.leftEnd&&_?o(this.chart,l,[{x:l.x,y:l.y+B/2},{x:l.x+(l.x-c.x)/2,y:l.y+B/2},{x:l.x+(l.x-c.x)/2,y:c.y-B/2},{x:c.x,y:c.y-B/2},{x:c.x,y:c.y}],i):o(this.chart,l,[{x:l.x,y:c.y-B/2},{x:c.x,y:c.y-B/2},{x:c.x,y:c.y}],i),this.bottomStart=!0,t.topEnd=!0,k=l.x+(l.x-c.x)/2;else r=o(this.chart,a,[{x:a.x+B/2,y:a.y},{x:a.x+B/2,y:c.y-B/2},{x:c.x,y:c.y-B/2},{x:c.x,y:c.y}],i),this.rightStart=!0,t.topEnd=!0,k=a.x+B/2;else r=o(this.chart,a,[{x:a.x+B/2,y:a.y},{x:a.x+B/2,y:c.y-B/2},{x:c.x,y:c.y-B/2},{x:c.x,y:c.y}],i),this.rightStart=!0,t.topEnd=!0,k=a.x+B/2;else r=o(this.chart,y,f,i),this.leftStart=!0,t.rightEnd=!0,k=f.x;else r=o(this.chart,a,d,i),this.rightStart=!0,t.leftEnd=!0,k=d.x;else r=o(this.chart,l,c,i),this.bottomStart=!0,t.topEnd=!0,k=l.x;if(this.lineStyle[t.key]&&r&&r.attr(this.lineStyle[t.key]),r){for(var O=0,L=this.chart.lines.length;OG?($=["L",J.x+2*A,q],C.splice(I+1,0,$),$=["C",J.x+2*A,q,J.x,q-4*A,J.x-2*A,q],C.splice(I+2,0,$),r.attr("path",C)):($=["L",J.x-2*A,q],C.splice(I+1,0,$),$=["C",J.x-2*A,q,J.x,q-4*A,J.x+2*A,q],C.splice(I+2,0,$),r.attr("path",C)):q>Q?($=["L",V,J.y+2*A],C.splice(I+1,0,$),$=["C",V,J.y+2*A,V+4*A,J.y,V,J.y-2*A],C.splice(I+2,0,$),r.attr("path",C)):($=["L",V,J.y-2*A],C.splice(I+1,0,$),$=["C",V,J.y-2*A,V+4*A,J.y,V,J.y+2*A],C.splice(I+2,0,$),r.attr("path",C)),I+=2,M+=2}}}this.chart.lines.push(r),(void 0===this.chart.minXFromSymbols||this.chart.minXFromSymbols>y.x)&&(this.chart.minXFromSymbols=y.x)}(!this.chart.maxXFromLine||this.chart.maxXFromLine&&k>this.chart.maxXFromLine)&&(this.chart.maxXFromLine=k)},t.exports=r},function(t,i){function e(t,i,e){var r,s,o="M{0},{1}";for(r=2,s=2*e.length+2;rf.x?i.x-(i.x-f.x)/2:f.x-(f.x-i.x)/2,m=i.y>f.y?i.y-(i.y-f.y)/2:f.y-(f.y-i.y)/2,c?(d-=g.getBBox().width/2,m-=t.options["text-margin"]):(d+=t.options["text-margin"],m-=g.getBBox().height/2)):(d=i.x,m=i.y,c?(d+=t.options["text-margin"]/2,m-=t.options["text-margin"]):(d+=t.options["text-margin"]/2,m+=t.options["text-margin"],i.y>f.y&&(m-=2*t.options["text-margin"]))),g.attr({"text-anchor":"start","font-size":t.options["font-size"],fill:t.options["font-color"],x:d,y:m}),l&&g.attr({font:l}),p&&g.attr({"font-family":p}),y&&g.attr({"font-weight":y})}return a}function s(t,i,e,r,s,o,h,n){var a,l,p,y,x,g={x:null,y:null,onLine1:!1,onLine2:!1};return a=(n-o)*(e-t)-(h-s)*(r-i),0===a?g:(l=i-o,p=t-s,y=(h-s)*l-(n-o)*p,x=(e-t)*l-(r-i)*p,l=y/a,p=x/a,g.x=t+l*(e-t),g.y=i+l*(r-i),l>0&&l<1&&(g.onLine1=!0),p>0&&p<1&&(g.onLine2=!0),g)}t.exports={drawPath:e,drawLine:r,checkLineIntersection:s}},function(t,i,e){function r(t){function i(t){var i=t.indexOf("(")+1,e=t.indexOf(")");return i>=0&&e>=0?t.substring(i,e):"{}"}function e(t){var i=t.indexOf("(")+1,e=t.indexOf(")");return i>=0&&e>=0?t.substring(i,e):""}function r(t){var i=t.indexOf("(")+1,e=t.indexOf(")");return i>=0&&e>=0?g.symbols[t.substring(0,i-1)]:g.symbols[t]}function x(t){var i="next",e=t.indexOf("(")+1,r=t.indexOf(")");return e>=0&&r>=0&&(i=E.substring(e,r),i.indexOf(",")<0&&"yes"!==i&&"no"!==i&&(i="next, "+i)),i}t=t||"",t=t.trim();for(var g={symbols:{},start:null,drawSVG:function(t,i){function e(t){if(g[t.key])return g[t.key];switch(t.symbolType){case"start":g[t.key]=new o(x,t);break;case"end":g[t.key]=new h(x,t);break;case"operation":g[t.key]=new n(x,t);break;case"inputoutput":g[t.key]=new a(x,t);break;case"subroutine":g[t.key]=new l(x,t);break;case"condition":g[t.key]=new p(x,t);break;case"parallel":g[t.key]=new y(x,t);break;default:return new Error("Wrong symbol type!")}return g[t.key]}var r=this;this.diagram&&this.diagram.clean();var x=new s(t,i);this.diagram=x;var g={};!function t(i,s,o){var h=e(i);return r.start===i?x.startWith(h):s&&o&&!s.pathOk&&(s instanceof p?(o.yes===i&&s.yes(h),o.no===i&&s.no(h)):s instanceof y?(o.path1===i&&s.path1(h),o.path2===i&&s.path2(h),o.path3===i&&s.path3(h)):s.then(h)),h.pathOk?h:(h instanceof p?(i.yes&&t(i.yes,h,i),i.no&&t(i.no,h,i)):h instanceof y?(i.path1&&t(i.path1,h,i),i.path2&&t(i.path2,h,i),i.path3&&t(i.path3,h,i)):i.next&&t(i.next,h,i),h)}(this.start),x.render()},clean:function(){this.diagram.clean()}},c=[],f=0,d=1,m=t.length;d")<0&&v.indexOf("=>")<0&&v.indexOf("@>")<0?(c[b-1]+="\n"+v,c.splice(b,1),_--):b++}for(;c.length>0;){var w=c.splice(0,1)[0].trim();if(w.indexOf("=>")>=0){var k=w.split("=>"),B={key:k[0].replace(/\(.*\)/,""),symbolType:k[1],text:null,link:null,target:null,flowstate:null,lineStyle:{},params:{}},A=k[0].match(/\((.*)\)/);if(A&&A.length>1)for(var X=A[1].split(","),O=0;O=0&&(M=B.symbolType.split(": "),B.symbolType=M.shift(),B.text=M.join(": ")),B.text&&B.text.indexOf(":>")>=0?(M=B.text.split(":>"),B.text=M.shift(),B.link=M.join(":>")):B.symbolType.indexOf(":>")>=0&&(M=B.symbolType.split(":>"),B.symbolType=M.shift(),B.link=M.join(":>")),B.symbolType.indexOf("\n")>=0&&(B.symbolType=B.symbolType.split("\n")[0]),B.link){var T=B.link.indexOf("[")+1,S=B.link.indexOf("]");T>=0&&S>=0&&(B.target=B.link.substring(T,S),B.link=B.link.substring(0,T-1))}if(B.text&&B.text.indexOf("|")>=0){var C=B.text.split("|");B.flowstate=C.pop().trim(),B.text=C.join("|")}g.symbols[B.key]=B}else if(w.indexOf("->")>=0)for(var Y=w.split("->"),O=0,P=Y.length;O=0){var I=R.split(",");R=I[0],F=I[1].trim()}if(g.start||(g.start=z),O+1")>=0)for(var W=w.split("@>"),O=0,P=W.length;Or.right_symbol.getCenter().y&&n<=r.right_symbol.width/2){s=!0;break}}if(s){if("end"===r.right_symbol.symbolType)return;r.right_symbol.setX(e.getX()+e.width+t),i()}}(),this.right_symbol.isPositioned=!0,this.right_symbol.render()}}},r.prototype.renderLines=function(){this.yes_symbol&&this.drawLineTo(this.yes_symbol,this.getAttr("yes-text"),this.yes_direction),this.no_symbol&&this.drawLineTo(this.no_symbol,this.getAttr("no-text"),this.no_direction)},t.exports=r},function(t,i,e){function r(t,i){var e=t.paper.rect(0,0,0,0);i=i||{},s.call(this,t,i,e),this.textMargin=this.getAttr("text-margin"),this.path1_direction="bottom",this.path2_direction="right",this.path3_direction="top",this.params=i.params,"path1"===i.direction_next&&!i[i.direction_next]&&i.next&&(i[i.direction_next]=i.next),"path2"===i.direction_next&&!i[i.direction_next]&&i.next&&(i[i.direction_next]=i.next),"path3"===i.direction_next&&!i[i.direction_next]&&i.next&&(i[i.direction_next]=i.next),i.path1&&i.direction_path1&&i.path2&&!i.direction_path2&&i.path3&&!i.direction_path3?"right"===i.direction_path1?(this.path2_direction="bottom",this.path1_direction="right",this.path3_direction="top"):"top"===i.direction_path1?(this.path2_direction="right",this.path1_direction="top",this.path3_direction="bottom"):"left"===i.direction_path1?(this.path2_direction="right",this.path1_direction="left",this.path3_direction="bottom"):(this.path2_direction="right",this.path1_direction="bottom",this.path3_direction="top"):i.path1&&!i.direction_path1&&i.path2&&i.direction_path2&&i.path3&&!i.direction_path3?"right"===i.direction_path2?(this.path1_direction="bottom",this.path2_direction="right",this.path3_direction="top"):"left"===i.direction_path2?(this.path1_direction="bottom",this.path2_direction="left",this.path3_direction="right"):(this.path1_direction="right",this.path2_direction="bottom",this.path3_direction="top"):i.path1&&!i.direction_path1&&i.path2&&!i.direction_path2&&i.path3&&i.direction_path3?"right"===i.direction_path2?(this.path1_direction="bottom",this.path2_direction="top",this.path3_direction="right"):"left"===i.direction_path2?(this.path1_direction="bottom",this.path2_direction="right",this.path3_direction="left"):(this.path1_direction="right",this.path2_direction="bottom",this.path3_direction="top"):(this.path1_direction=i.direction_path1,this.path2_direction=i.direction_path2,this.path3_direction=i.direction_path3),this.path1_direction=this.path1_direction||"bottom",this.path2_direction=this.path2_direction||"right",this.path3_direction=this.path3_direction||"top",this.initialize()}var s=e(2),o=e(1).inherits;o(r,s),r.prototype.render=function(){this.path1_direction&&(this[this.path1_direction+"_symbol"]=this.path1_symbol),this.path2_direction&&(this[this.path2_direction+"_symbol"]=this.path2_symbol),this.path3_direction&&(this[this.path3_direction+"_symbol"]=this.path3_symbol);var t=this.getAttr("line-length");if(this.bottom_symbol){var i=this.getBottom();this.bottom_symbol.isPositioned||(this.bottom_symbol.shiftY(this.getY()+this.height+t),this.bottom_symbol.setX(i.x-this.bottom_symbol.width/2),this.bottom_symbol.isPositioned=!0,this.bottom_symbol.render())}if(this.top_symbol){var e=this.getTop();this.top_symbol.isPositioned||(this.top_symbol.shiftY(this.getY()-this.top_symbol.height-t),this.top_symbol.setX(e.x+this.top_symbol.width),this.top_symbol.isPositioned=!0,this.top_symbol.render())}var r=this;if(this.left_symbol){var s=this.getLeft();this.left_symbol.isPositioned||(this.left_symbol.setY(s.y-this.left_symbol.height/2),this.left_symbol.shiftX(-(this.group.getBBox().x+this.width+t)),function i(){for(var e,s=!1,o=0,h=r.chart.symbols.length;or.left_symbol.getCenter().y&&n<=r.left_symbol.width/2){s=!0;break}}if(s){if("end"===r.left_symbol.symbolType)return;r.left_symbol.setX(e.getX()+e.width+t),i()}}(),this.left_symbol.isPositioned=!0,this.left_symbol.render())}if(this.right_symbol){var o=this.getRight();this.right_symbol.isPositioned||(this.right_symbol.setY(o.y-this.right_symbol.height/2),this.right_symbol.shiftX(this.group.getBBox().x+this.width+t),function i(){for(var e,s=!1,o=0,h=r.chart.symbols.length;or.right_symbol.getCenter().y&&n<=r.right_symbol.width/2){s=!0;break}}if(s){if("end"===r.right_symbol.symbolType)return;r.right_symbol.setX(e.getX()+e.width+t),i()}}(),this.right_symbol.isPositioned=!0,this.right_symbol.render())}},r.prototype.renderLines=function(){this.path1_symbol&&this.drawLineTo(this.path1_symbol,"",this.path1_direction),this.path2_symbol&&this.drawLineTo(this.path2_symbol,"",this.path2_direction),this.path3_symbol&&this.drawLineTo(this.path3_symbol,"",this.path3_direction)},t.exports=r},function(t,i,e){function r(t,i){i=i||{},this.paper=new s(t),this.options=o(i,h),this.symbols=[],this.lines=[],this.start=null}var s=e(16),o=e(1).defaults,h=e(8),n=e(5),a=e(6);r.prototype.handle=function(t){this.symbols.indexOf(t)<=-1&&this.symbols.push(t);var i=this;return t instanceof n?(t.yes=function(e){return t.yes_symbol=e,t.no_symbol&&(t.pathOk=!0),i.handle(e)},t.no=function(e){return t.no_symbol=e,t.yes_symbol&&(t.pathOk=!0),i.handle(e)}):t instanceof a?(t.path1=function(e){return t.path1_symbol=e,t.path2_symbol&&(t.pathOk=!0),i.handle(e)},t.path2=function(e){return t.path2_symbol=e,t.path3_symbol&&(t.pathOk=!0),i.handle(e)},t.path3=function(e){return t.path3_symbol=e,t.path1_symbol&&(t.pathOk=!0),i.handle(e)}):t.then=function(e){return t.next=e,t.pathOk=!0,i.handle(e)},t},r.prototype.startWith=function(t){return this.start=t,this.handle(t)},r.prototype.render=function(){var t,i,e=0,r=0,s=0,o=0,h=0,n=0,a=0,l=0;for(s=0,o=this.symbols.length;se&&(e=t.width),t.height>r&&(r=t.height);for(s=0,o=this.symbols.length;sh&&(h=p),y>n&&(n=y);for(s=0,o=this.lines.length;sh&&(h=x),g>n&&(n=g)}var c=this.options.scale,f=this.options["line-width"];this.minXFromSymbols>>0;if(0===e)return-1;var r=0;if(arguments.length>0&&(r=Number(arguments[1]),r!=r?r=0:0!==r&&r!=1/0&&r!=-(1/0)&&(r=(r>0||-1)*Math.floor(Math.abs(r)))),r>=e)return-1;for(var s=r>=0?r:Math.max(e-Math.abs(r),0);s>>0;if(0===e)return-1;var r=e;arguments.length>1&&(r=Number(arguments[1]),r!=r?r=0:0!==r&&r!=1/0&&r!=-(1/0)&&(r=(r>0||-1)*Math.floor(Math.abs(r))));for(var s=r>=0?Math.min(r,e-1):e-Math.abs(r);s>=0;s--)if(s in i&&i[s]===t)return s;return-1}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")})},function(t,i,e){function r(t,i){var e=t.paper.rect(0,0,0,0,20);i=i||{},i.text=i.text||"End",s.call(this,t,i,e)}var s=e(2),o=e(1).inherits;o(r,s),t.exports=r},function(t,i,e){function r(t,i){i=i||{},s.call(this,t,i),this.textMargin=this.getAttr("text-margin"),this.text.attr({x:3*this.textMargin});var e=this.text.getBBox().width+4*this.textMargin,r=this.text.getBBox().height+2*this.textMargin,o=this.textMargin,h=r/2,a={x:o,y:h},l=[{x:o-this.textMargin,y:r},{x:o-this.textMargin+e,y:r},{x:o-this.textMargin+e+2*this.textMargin,y:0},{x:o-this.textMargin+2*this.textMargin,y:0},{x:o,y:h}],p=n(t,a,l);p.attr({stroke:this.getAttr("element-color"),"stroke-width":this.getAttr("line-width"),fill:this.getAttr("fill")}),i.link&&p.attr("href",i.link),i.target&&p.attr("target",i.target),i.key&&(p.node.id=i.key),p.node.setAttribute("class",this.getAttr("class")),this.text.attr({y:p.getBBox().height/2}),this.group.push(p),p.insertBefore(this.text),this.initialize()}var s=e(2),o=e(1).inherits,h=e(3),n=h.drawPath;o(r,s),r.prototype.getLeft=function(){var t=this.getY()+this.group.getBBox().height/2,i=this.getX()+this.textMargin;return{x:i,y:t}},r.prototype.getRight=function(){var t=this.getY()+this.group.getBBox().height/2,i=this.getX()+this.group.getBBox().width-this.textMargin;return{x:i,y:t}},t.exports=r},function(t,i,e){function r(t,i){var e=t.paper.rect(0,0,0,0);i=i||{},s.call(this,t,i,e)}var s=e(2),o=e(1).inherits;o(r,s),t.exports=r},function(t,i,e){function r(t,i){var e=t.paper.rect(0,0,0,0,20);i=i||{},i.text=i.text||"Start",s.call(this,t,i,e)}var s=e(2),o=e(1).inherits;o(r,s),t.exports=r},function(t,i,e){function r(t,i){var e=t.paper.rect(0,0,0,0);i=i||{},s.call(this,t,i,e),e.attr({width:this.text.getBBox().width+4*this.getAttr("text-margin")}),this.text.attr({x:2*this.getAttr("text-margin")});var r=t.paper.rect(0,0,0,0);r.attr({x:this.getAttr("text-margin"),stroke:this.getAttr("element-color"),"stroke-width":this.getAttr("line-width"),width:this.text.getBBox().width+2*this.getAttr("text-margin"),height:this.text.getBBox().height+2*this.getAttr("text-margin"),fill:this.getAttr("fill")}),i.key&&(r.node.id=i.key+"i");var o=this.getAttr("font"),h=this.getAttr("font-family"),n=this.getAttr("font-weight");o&&r.attr({font:o}),h&&r.attr({"font-family":h}),n&&r.attr({"font-weight":n}),i.link&&r.attr("href",i.link),i.target&&r.attr("target",i.target),this.group.push(r),r.insertBefore(this.text),this.initialize()}var s=e(2),o=e(1).inherits;o(r,s),t.exports=r},function(t,i,e){if("undefined"!=typeof jQuery){var r=e(4);!function(t){t.fn.flowChart=function(i){return this.each(function(){var e=t(this),s=r(e.text());e.html(""),s.drawSVG(this,i)})}}(jQuery)}},function(i,e){i.exports=t}])}); -//# sourceMappingURL=flowchart.min.js.map \ No newline at end of file diff --git a/src/utils/flowchart.js/raphael.min.js b/src/utils/flowchart.js/raphael.min.js deleted file mode 100644 index 2fb91046..00000000 --- a/src/utils/flowchart.js/raphael.min.js +++ /dev/null @@ -1,3 +0,0 @@ -!function t(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.Raphael=r():e.Raphael=r()}(this,function(){return function(t){function e(i){if(r[i])return r[i].exports;var n=r[i]={exports:{},id:i,loaded:!1};return t[i].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var i,n;i=[r(1),r(3),r(4)],n=function(t){return t}.apply(e,i),!(void 0!==n&&(t.exports=n))},function(t,e,r){var i,n;i=[r(2)],n=function(t){function e(r){if(e.is(r,"function"))return w?r():t.on("raphael.DOMload",r);if(e.is(r,Q))return e._engine.create[z](e,r.splice(0,3+e.is(r[0],$))).add(r);var i=Array.prototype.slice.call(arguments,0);if(e.is(i[i.length-1],"function")){var n=i.pop();return w?n.call(e._engine.create[z](e,i)):t.on("raphael.DOMload",function(){n.call(e._engine.create[z](e,i))})}return e._engine.create[z](e,arguments)}function r(t){if("function"==typeof t||Object(t)!==t)return t;var e=new t.constructor;for(var i in t)t[A](i)&&(e[i]=r(t[i]));return e}function i(t,e){for(var r=0,i=t.length;r=1e3&&delete o[l.shift()],l.push(s),o[s]=t[z](e,a),r?r(o[s]):o[s])}return n}function a(){return this.hex}function s(t,e){for(var r=[],i=0,n=t.length;n-2*!e>i;i+=2){var a=[{x:+t[i-2],y:+t[i-1]},{x:+t[i],y:+t[i+1]},{x:+t[i+2],y:+t[i+3]},{x:+t[i+4],y:+t[i+5]}];e?i?n-4==i?a[3]={x:+t[0],y:+t[1]}:n-2==i&&(a[2]={x:+t[0],y:+t[1]},a[3]={x:+t[2],y:+t[3]}):a[0]={x:+t[n-2],y:+t[n-1]}:n-4==i?a[3]=a[2]:i||(a[0]={x:+t[i],y:+t[i+1]}),r.push(["C",(-a[0].x+6*a[1].x+a[2].x)/6,(-a[0].y+6*a[1].y+a[2].y)/6,(a[1].x+6*a[2].x-a[3].x)/6,(a[1].y+6*a[2].y-a[3].y)/6,a[2].x,a[2].y])}return r}function o(t,e,r,i,n){var a=-3*e+9*r-9*i+3*n,s=t*a+6*e-12*r+6*i;return t*s-3*e+3*r}function l(t,e,r,i,n,a,s,l,h){null==h&&(h=1),h=h>1?1:h<0?0:h;for(var u=h/2,c=12,f=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],p=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],d=0,g=0;gd;)c/=2,f+=(pW(n,s)||W(e,i)W(a,o))){var l=(t*i-e*r)*(n-s)-(t-r)*(n*o-a*s),h=(t*i-e*r)*(a-o)-(e-i)*(n*o-a*s),u=(t-r)*(a-o)-(e-i)*(n-s);if(u){var c=l/u,f=h/u,p=+c.toFixed(2),d=+f.toFixed(2);if(!(p<+G(t,r).toFixed(2)||p>+W(t,r).toFixed(2)||p<+G(n,s).toFixed(2)||p>+W(n,s).toFixed(2)||d<+G(e,i).toFixed(2)||d>+W(e,i).toFixed(2)||d<+G(a,o).toFixed(2)||d>+W(a,o).toFixed(2)))return{x:c,y:f}}}}function c(t,e){return p(t,e)}function f(t,e){return p(t,e,1)}function p(t,r,i){var n=e.bezierBBox(t),a=e.bezierBBox(r);if(!e.isBBoxIntersect(n,a))return i?0:[];for(var s=l.apply(0,t),o=l.apply(0,r),h=W(~~(s/5),1),c=W(~~(o/5),1),f=[],p=[],d={},g=i?0:[],v=0;v=0&&S<=1.001&&A>=0&&A<=1.001&&(i?g++:g.push({x:C.x,y:C.y,t1:G(S,1),t2:G(A,1)}))}}return g}function d(t,r,i){t=e._path2curve(t),r=e._path2curve(r);for(var n,a,s,o,l,h,u,c,f,d,g=i?0:[],v=0,x=t.length;vi)return i;for(;ra?r=n:i=n,n=(i-r)/2+r}return n}var h=3*e,u=3*(i-e)-h,c=1-h-u,f=3*r,p=3*(n-r)-f,d=1-f-p;return o(t,1/(200*a))}function m(t,e){var r=[],i={};if(this.ms=e,this.times=1,t){for(var n in t)t[A](n)&&(i[ht(n)]=t[n],r.push(ht(n)));r.sort(Bt)}this.anim=i,this.top=r[r.length-1],this.percents=r}function b(r,i,n,a,s,o){n=ht(n);var l,h,u,c=[],f,p,d,v=r.ms,x={},m={},b={};if(a)for(w=0,B=Ee.length;wa*r.top){n=r.percents[w],p=r.percents[w-1]||0,v=v/r.top*(n-p),f=r.percents[w+1],l=r.anim[n];break}a&&i.attr(r.anim[r.percents[w]])}if(l){if(h)h.initstatus=a,h.start=new Date-h.ms*a;else{for(var C in l)if(l[A](C)&&(pt[A](C)||i.paper.customAttributes[A](C)))switch(x[C]=i.attr(C),null==x[C]&&(x[C]=ft[C]),m[C]=l[C],pt[C]){case $:b[C]=(m[C]-x[C])/v;break;case"colour":x[C]=e.getRGB(x[C]);var S=e.getRGB(m[C]);b[C]={r:(S.r-x[C].r)/v,g:(S.g-x[C].g)/v,b:(S.b-x[C].b)/v};break;case"path":var T=Qt(x[C],m[C]),E=T[1];for(x[C]=T[0],b[C]=[],w=0,B=x[C].length;w',Lt=Nt.firstChild,Lt.style.behavior="url(#default#VML)",!Lt||"object"!=typeof Lt.adj)return e.type=R;Nt=null}e.svg=!(e.vml="VML"==e.type),e._Paper=M,e.fn=N=M.prototype=e.prototype,e._id=0,e.is=function(t,e){return e=O.call(e),"finite"==e?!at[A](+t):"array"==e?t instanceof Array:"null"==e&&null===t||e==typeof t&&null!==t||"object"==e&&t===Object(t)||"array"==e&&Array.isArray&&Array.isArray(t)||tt.call(t).slice(8,-1).toLowerCase()==e},e.angle=function(t,r,i,n,a,s){if(null==a){var o=t-i,l=r-n;return o||l?(180+180*Y.atan2(-l,-o)/U+360)%360:0}return e.angle(t,r,a,s)-e.angle(i,n,a,s)},e.rad=function(t){return t%360*U/180},e.deg=function(t){return Math.round(180*t/U%360*1e3)/1e3},e.snapTo=function(t,r,i){if(i=e.is(i,"finite")?i:10,e.is(t,Q)){for(var n=t.length;n--;)if(H(t[n]-r)<=i)return t[n]}else{t=+t;var a=r%t;if(at-i)return r-a+t}return r};var zt=e.createUUID=function(t,e){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(t,e).toUpperCase()}}(/[xy]/g,function(t){var e=16*Y.random()|0,r="x"==t?e:3&e|8;return r.toString(16)});e.setWindow=function(r){t("raphael.setWindow",e,T.win,r),T.win=r,T.doc=T.win.document,e._engine.initWin&&e._engine.initWin(T.win)};var Pt=function(t){if(e.vml){var r=/^\s+|\s+$/g,i;try{var a=new ActiveXObject("htmlfile");a.write(""),a.close(),i=a.body}catch(s){i=createPopup().document.body}var o=i.createTextRange();Pt=n(function(t){try{i.style.color=I(t).replace(r,R);var e=o.queryCommandValue("ForeColor");return e=(255&e)<<16|65280&e|(16711680&e)>>>16,"#"+("000000"+e.toString(16)).slice(-6)}catch(n){return"none"}})}else{var l=T.doc.createElement("i");l.title="Raphaël Colour Picker",l.style.display="none",T.doc.body.appendChild(l),Pt=n(function(t){return l.style.color=t,T.doc.defaultView.getComputedStyle(l,R).getPropertyValue("color")})}return Pt(t)},Ft=function(){return"hsb("+[this.h,this.s,this.b]+")"},Rt=function(){return"hsl("+[this.h,this.s,this.l]+")"},jt=function(){return this.hex},It=function(t,r,i){if(null==r&&e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t&&(i=t.b,r=t.g,t=t.r),null==r&&e.is(t,Z)){var n=e.getRGB(t);t=n.r,r=n.g,i=n.b}return(t>1||r>1||i>1)&&(t/=255,r/=255,i/=255),[t,r,i]},qt=function(t,r,i,n){t*=255,r*=255,i*=255;var a={r:t,g:r,b:i,hex:e.rgb(t,r,i),toString:jt};return e.is(n,"finite")&&(a.opacity=n),a};e.color=function(t){var r;return e.is(t,"object")&&"h"in t&&"s"in t&&"b"in t?(r=e.hsb2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):e.is(t,"object")&&"h"in t&&"s"in t&&"l"in t?(r=e.hsl2rgb(t),t.r=r.r,t.g=r.g,t.b=r.b,t.hex=r.hex):(e.is(t,"string")&&(t=e.getRGB(t)),e.is(t,"object")&&"r"in t&&"g"in t&&"b"in t?(r=e.rgb2hsl(t),t.h=r.h,t.s=r.s,t.l=r.l,r=e.rgb2hsb(t),t.v=r.b):(t={hex:"none"},t.r=t.g=t.b=t.h=t.s=t.v=t.l=-1)),t.toString=jt,t},e.hsb2rgb=function(t,e,r,i){this.is(t,"object")&&"h"in t&&"s"in t&&"b"in t&&(r=t.b,e=t.s,i=t.o,t=t.h),t*=360;var n,a,s,o,l;return t=t%360/60,l=r*e,o=l*(1-H(t%2-1)),n=a=s=r-l,t=~~t,n+=[l,o,0,0,o,l][t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],qt(n,a,s,i)},e.hsl2rgb=function(t,e,r,i){this.is(t,"object")&&"h"in t&&"s"in t&&"l"in t&&(r=t.l,e=t.s,t=t.h),(t>1||e>1||r>1)&&(t/=360,e/=100,r/=100),t*=360;var n,a,s,o,l;return t=t%360/60,l=2*e*(r<.5?r:1-r),o=l*(1-H(t%2-1)),n=a=s=r-l/2,t=~~t,n+=[l,o,0,0,o,l][t],a+=[o,l,l,o,0,0][t],s+=[0,0,o,l,l,o][t],qt(n,a,s,i)},e.rgb2hsb=function(t,e,r){r=It(t,e,r),t=r[0],e=r[1],r=r[2];var i,n,a,s;return a=W(t,e,r),s=a-G(t,e,r),i=0==s?null:a==t?(e-r)/s:a==e?(r-t)/s+2:(t-e)/s+4,i=(i+360)%6*60/360,n=0==s?0:s/a,{h:i,s:n,b:a,toString:Ft}},e.rgb2hsl=function(t,e,r){r=It(t,e,r),t=r[0],e=r[1],r=r[2];var i,n,a,s,o,l;return s=W(t,e,r),o=G(t,e,r),l=s-o,i=0==l?null:s==t?(e-r)/l:s==e?(r-t)/l+2:(t-e)/l+4,i=(i+360)%6*60/360,a=(s+o)/2,n=0==l?0:a<.5?l/(2*a):l/(2-2*a),{h:i,s:n,l:a,toString:Rt}},e._path2string=function(){return this.join(",").replace(xt,"$1")};var Dt=e._preload=function(t,e){var r=T.doc.createElement("img");r.style.cssText="position:absolute;left:-9999em;top:-9999em",r.onload=function(){e.call(this),this.onload=null,T.doc.body.removeChild(this)},r.onerror=function(){T.doc.body.removeChild(this)},T.doc.body.appendChild(r),r.src=t};e.getRGB=n(function(t){if(!t||(t=I(t)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:a};if("none"==t)return{r:-1,g:-1,b:-1,hex:"none",toString:a};!(vt[A](t.toLowerCase().substring(0,2))||"#"==t.charAt())&&(t=Pt(t));var r,i,n,s,o,l,h,u=t.match(nt);return u?(u[2]&&(s=ut(u[2].substring(5),16),n=ut(u[2].substring(3,5),16),i=ut(u[2].substring(1,3),16)),u[3]&&(s=ut((l=u[3].charAt(3))+l,16),n=ut((l=u[3].charAt(2))+l,16),i=ut((l=u[3].charAt(1))+l,16)),u[4]&&(h=u[4][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),"rgba"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100)),u[5]?(h=u[5][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),("deg"==h[0].slice(-3)||"°"==h[0].slice(-1))&&(i/=360),"hsba"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100),e.hsb2rgb(i,n,s,o)):u[6]?(h=u[6][q](gt),i=ht(h[0]),"%"==h[0].slice(-1)&&(i*=2.55),n=ht(h[1]),"%"==h[1].slice(-1)&&(n*=2.55),s=ht(h[2]),"%"==h[2].slice(-1)&&(s*=2.55),("deg"==h[0].slice(-3)||"°"==h[0].slice(-1))&&(i/=360),"hsla"==u[1].toLowerCase().slice(0,4)&&(o=ht(h[3])),h[3]&&"%"==h[3].slice(-1)&&(o/=100),e.hsl2rgb(i,n,s,o)):(u={r:i,g:n,b:s,toString:a},u.hex="#"+(16777216|s|n<<8|i<<16).toString(16).slice(1),e.is(o,"finite")&&(u.opacity=o),u)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:a}},e),e.hsb=n(function(t,r,i){return e.hsb2rgb(t,r,i).hex}),e.hsl=n(function(t,r,i){return e.hsl2rgb(t,r,i).hex}),e.rgb=n(function(t,e,r){function i(t){return t+.5|0}return"#"+(16777216|i(r)|i(e)<<8|i(t)<<16).toString(16).slice(1)}),e.getColor=function(t){var e=this.getColor.start=this.getColor.start||{h:0,s:1,b:t||.75},r=this.hsb2rgb(e.h,e.s,e.b);return e.h+=.075,e.h>1&&(e.h=0,e.s-=.2,e.s<=0&&(this.getColor.start={h:0,s:1,b:e.b})),r.hex},e.getColor.reset=function(){delete this.start},e.parsePathString=function(t){if(!t)return null;var r=Vt(t);if(r.arr)return Yt(r.arr);var i={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},n=[];return e.is(t,Q)&&e.is(t[0],Q)&&(n=Yt(t)),n.length||I(t).replace(yt,function(t,e,r){var a=[],s=e.toLowerCase();if(r.replace(bt,function(t,e){e&&a.push(+e)}),"m"==s&&a.length>2&&(n.push([e][P](a.splice(0,2))),s="l",e="m"==e?"l":"L"),"r"==s)n.push([e][P](a));else for(;a.length>=i[s]&&(n.push([e][P](a.splice(0,i[s]))),i[s]););}),n.toString=e._path2string,r.arr=Yt(n),n},e.parseTransformString=n(function(t){if(!t)return null;var r={r:3,s:4,t:2,m:6},i=[];return e.is(t,Q)&&e.is(t[0],Q)&&(i=Yt(t)),i.length||I(t).replace(mt,function(t,e,r){var n=[],a=O.call(e);r.replace(bt,function(t,e){e&&n.push(+e)}),i.push([e][P](n))}),i.toString=e._path2string,i});var Vt=function(t){var e=Vt.ps=Vt.ps||{};return e[t]?e[t].sleep=100:e[t]={sleep:100},setTimeout(function(){for(var r in e)e[A](r)&&r!=t&&(e[r].sleep--,!e[r].sleep&&delete e[r])}),e[t]};e.findDotsAtSegment=function(t,e,r,i,n,a,s,o,l){var h=1-l,u=X(h,3),c=X(h,2),f=l*l,p=f*l,d=u*t+3*c*l*r+3*h*l*l*n+p*s,g=u*e+3*c*l*i+3*h*l*l*a+p*o,v=t+2*l*(r-t)+f*(n-2*r+t),x=e+2*l*(i-e)+f*(a-2*i+e),y=r+2*l*(n-r)+f*(s-2*n+r),m=i+2*l*(a-i)+f*(o-2*a+i),b=h*t+l*r,_=h*e+l*i,w=h*n+l*s,k=h*a+l*o,B=90-180*Y.atan2(v-y,x-m)/U;return(v>y||x=t.x&&e<=t.x2&&r>=t.y&&r<=t.y2},e.isBBoxIntersect=function(t,r){var i=e.isPointInsideBBox;return i(r,t.x,t.y)||i(r,t.x2,t.y)||i(r,t.x,t.y2)||i(r,t.x2,t.y2)||i(t,r.x,r.y)||i(t,r.x2,r.y)||i(t,r.x,r.y2)||i(t,r.x2,r.y2)||(t.xr.x||r.xt.x)&&(t.yr.y||r.yt.y)},e.pathIntersection=function(t,e){return d(t,e)},e.pathIntersectionNumber=function(t,e){return d(t,e,1)},e.isPointInsidePath=function(t,r,i){var n=e.pathBBox(t);return e.isPointInsideBBox(n,r,i)&&d(t,[["M",r,i],["H",n.x2+10]],1)%2==1},e._removedFactory=function(e){return function(){t("raphael.log",null,"Raphaël: you are calling to method “"+e+"” of removed object",e)}};var Ot=e.pathBBox=function(t){var e=Vt(t);if(e.bbox)return r(e.bbox);if(!t)return{x:0,y:0,width:0,height:0,x2:0,y2:0};t=Qt(t);for(var i=0,n=0,a=[],s=[],o,l=0,h=t.length;l1&&(b=Y.sqrt(b),r=b*r,i=b*i);var _=r*r,w=i*i,k=(s==o?-1:1)*Y.sqrt(H((_*w-_*m*m-w*y*y)/(_*m*m+w*y*y))),B=k*r*m/i+(t+l)/2,C=k*-i*y/r+(e+h)/2,S=Y.asin(((e-C)/i).toFixed(9)),A=Y.asin(((h-C)/i).toFixed(9));S=tA&&(S-=2*U),!o&&A>S&&(A-=2*U)}var T=A-S;if(H(T)>c){var E=A,M=l,N=h;A=S+c*(o&&A>S?1:-1),l=B+r*Y.cos(A),h=C+i*Y.sin(A),p=Ut(l,h,r,i,a,0,o,M,N,[A,E,B,C])}T=A-S;var L=Y.cos(S),z=Y.sin(S),F=Y.cos(A),R=Y.sin(A),j=Y.tan(T/4),I=4/3*r*j,D=4/3*i*j,V=[t,e],O=[t+I*z,e-D*L],W=[l+I*R,h-D*F],G=[l,h];if(O[0]=2*V[0]-O[0],O[1]=2*V[1]-O[1],u)return[O,W,G][P](p);p=[O,W,G][P](p).join()[q](",");for(var X=[],$=0,Z=p.length;$"1e12"&&(c=.5),H(f)>"1e12"&&(f=.5),c>0&&c<1&&(g=$t(t,e,r,i,n,a,s,o,c),d.push(g.x),p.push(g.y)),f>0&&f<1&&(g=$t(t,e,r,i,n,a,s,o,f),d.push(g.x),p.push(g.y)),l=a-2*i+e-(o-2*a+i),h=2*(i-e)-2*(a-i),u=e-i,c=(-h+Y.sqrt(h*h-4*l*u))/2/l,f=(-h-Y.sqrt(h*h-4*l*u))/2/l,H(c)>"1e12"&&(c=.5),H(f)>"1e12"&&(f=.5),c>0&&c<1&&(g=$t(t,e,r,i,n,a,s,o,c),d.push(g.x),p.push(g.y)),f>0&&f<1&&(g=$t(t,e,r,i,n,a,s,o,f),d.push(g.x),p.push(g.y)),{min:{x:G[z](0,d),y:G[z](0,p)},max:{x:W[z](0,d),y:W[z](0,p)}}}),Qt=e._path2curve=n(function(t,e){var r=!e&&Vt(t);if(!e&&r.curve)return Yt(r.curve);for(var i=Gt(t),n=e&&Gt(e),a={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},s={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},o=(function(t,e,r){var i,n,a={T:1,Q:1};if(!t)return["C",e.x,e.y,e.x,e.y,e.x,e.y];switch(!(t[0]in a)&&(e.qx=e.qy=null),t[0]){case"M":e.X=t[1],e.Y=t[2];break;case"A":t=["C"][P](Ut[z](0,[e.x,e.y][P](t.slice(1))));break;case"S":"C"==r||"S"==r?(i=2*e.x-e.bx,n=2*e.y-e.by):(i=e.x,n=e.y),t=["C",i,n][P](t.slice(1));break;case"T":"Q"==r||"T"==r?(e.qx=2*e.x-e.qx,e.qy=2*e.y-e.qy):(e.qx=e.x,e.qy=e.y),t=["C"][P](Xt(e.x,e.y,e.qx,e.qy,t[1],t[2]));break;case"Q":e.qx=t[1],e.qy=t[2],t=["C"][P](Xt(e.x,e.y,t[1],t[2],t[3],t[4]));break;case"L":t=["C"][P](Ht(e.x,e.y,t[1],t[2]));break;case"H":t=["C"][P](Ht(e.x,e.y,t[1],e.y));break;case"V":t=["C"][P](Ht(e.x,e.y,e.x,t[1]));break;case"Z":t=["C"][P](Ht(e.x,e.y,e.X,e.Y))}return t}),l=function(t,e){if(t[e].length>7){t[e].shift();for(var r=t[e];r.length;)u[e]="A",n&&(c[e]="A"),t.splice(e++,0,["C"][P](r.splice(0,6)));t.splice(e,1),g=W(i.length,n&&n.length||0)}},h=function(t,e,r,a,s){t&&e&&"M"==t[s][0]&&"M"!=e[s][0]&&(e.splice(s,0,["M",a.x,a.y]),r.bx=0,r.by=0,r.x=t[s][1],r.y=t[s][2],g=W(i.length,n&&n.length||0))},u=[],c=[],f="",p="",d=0,g=W(i.length,n&&n.length||0);dn){if(r&&!c.start){if(f=ke(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p),u+=["C"+f.start.x,f.start.y,f.m.x,f.m.y,f.x,f.y],a)return u;c.start=u,u=["M"+f.x,f.y+"C"+f.n.x,f.n.y,f.end.x,f.end.y,l[5],l[6]].join(),p+=h,s=+l[5],o=+l[6];continue}if(!t&&!r)return f=ke(s,o,l[1],l[2],l[3],l[4],l[5],l[6],n-p),{x:f.x,y:f.y,alpha:f.alpha}}p+=h,s=+l[5],o=+l[6]}u+=l.shift()+l}return c.end=u,f=t?p:r?c:e.findDotsAtSegment(s,o,l[0],l[1],l[2],l[3],l[4],l[5],1),f.alpha&&(f={x:f.x,y:f.y,alpha:f.alpha}),f}},Ce=Be(1),Se=Be(),Ae=Be(0,1);e.getTotalLength=Ce,e.getPointAtLength=Se,e.getSubpath=function(t,e,r){if(this.getTotalLength(t)-r<1e-6)return Ae(t,e).end;var i=Ae(t,r,1);return e?Ae(i,e).end:i},ye.getTotalLength=function(){var t=this.getPath();if(t)return this.node.getTotalLength?this.node.getTotalLength():Ce(t)},ye.getPointAtLength=function(t){var e=this.getPath();if(e)return Se(e,t)},ye.getPath=function(){var t,r=e._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return r&&(t=r(this)),t},ye.getSubpath=function(t,r){var i=this.getPath();if(i)return e.getSubpath(i,t,r)};var Te=e.easing_formulas={linear:function(t){return t},"<":function(t){return X(t,1.7)},">":function(t){return X(t,.48)},"<>":function(t){var e=.48-t/1.04,r=Y.sqrt(.1734+e*e),i=r-e,n=X(H(i),1/3)*(i<0?-1:1),a=-r-e,s=X(H(a),1/3)*(a<0?-1:1),o=n+s+.5;return 3*(1-o)*o*o+o*o*o},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){t-=1;var e=1.70158;return t*t*((e+1)*t+e)+1},elastic:function(t){return t==!!t?t:X(2,-10*t)*Y.sin((t-.075)*(2*U)/.3)+1},bounce:function(t){var e=7.5625,r=2.75,i;return t<1/r?i=e*t*t:t<2/r?(t-=1.5/r,i=e*t*t+.75):t<2.5/r?(t-=2.25/r,i=e*t*t+.9375):(t-=2.625/r,i=e*t*t+.984375),i}};Te.easeIn=Te["ease-in"]=Te["<"],Te.easeOut=Te["ease-out"]=Te[">"],Te.easeInOut=Te["ease-in-out"]=Te["<>"],Te["back-in"]=Te.backIn,Te["back-out"]=Te.backOut;var Ee=[],Me=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){setTimeout(t,16)},Ne=function(){for(var r=+new Date,i=0;i1&&!n.next){for(v in u)u[A](v)&&(g[v]=n.totalOrigin[v]);n.el.attr(g),b(n.anim,n.el,n.anim.percents[0],null,n.totalOrigin,n.repeat-1)}n.next&&!n.stop&&b(n.anim,n.el,n.next,null,n.totalOrigin,n.repeat)}}}Ee.length&&Me(Ne)},Le=function(t){return t>255?255:t<0?0:t};ye.animateWith=function(t,r,i,n,a,s){var o=this;if(o.removed)return s&&s.call(o),o;var l=i instanceof m?i:e.animation(i,n,a,s),h,u;b(l,o,l.percents[0],null,o.attr());for(var c=0,f=Ee.length;cl&&(l=u)}l+="%",!t[l].callback&&(t[l].callback=n)}return new m(t,r)},ye.animate=function(t,r,i,n){var a=this;if(a.removed)return n&&n.call(a),a;var s=t instanceof m?t:e.animation(t,r,i,n);return b(s,a,s.percents[0],null,a.attr()),a},ye.setTime=function(t,e){return t&&null!=e&&this.status(t,G(e,t.ms)/t.ms),this},ye.status=function(t,e){var r=[],i=0,n,a;if(null!=e)return b(t,this,-1,G(e,1)),this;for(n=Ee.length;i1)for(var i=0,n=r.length;i.5)-1;l(f-.5,2)+l(p-.5,2)>.25&&(p=a.sqrt(.25-l(f-.5,2))*n+.5)&&.5!=p&&(p=p.toFixed(5)-1e-5*n)}return c}),n=n.split(/\s*\-\s*/),"linear"==h){var b=n.shift();if(b=-i(b),isNaN(b))return null;var _=[0,0,a.cos(t.rad(b)),a.sin(t.rad(b))],w=1/(s(o(_[2]),o(_[3]))||1);_[2]*=w,_[3]*=w,_[2]<0&&(_[0]=-_[2],_[2]=0),_[3]<0&&(_[1]=-_[3],_[3]=0)}var k=t._parseDots(n);if(!k)return null;if(u=u.replace(/[\(\)\s,\xb0#]/g,"_"),e.gradient&&u!=e.gradient.id&&(g.defs.removeChild(e.gradient),delete e.gradient),!e.gradient){y=v(h+"Gradient",{id:u}),e.gradient=y,v(y,"radial"==h?{fx:f,fy:p}:{x1:_[0],y1:_[1],x2:_[2],y2:_[3],gradientTransform:e.matrix.invert()}),g.defs.appendChild(y);for(var B=0,C=k.length;B1?z.opacity/100:z.opacity});case"stroke":z=t.getRGB(g),l.setAttribute(d,z.hex),"stroke"==d&&z[e]("opacity")&&v(l,{"stroke-opacity":z.opacity>1?z.opacity/100:z.opacity}),"stroke"==d&&i._.arrows&&("startString"in i._.arrows&&_(i,i._.arrows.startString),"endString"in i._.arrows&&_(i,i._.arrows.endString,1));break;case"gradient":("circle"==i.type||"ellipse"==i.type||"r"!=r(g).charAt())&&x(i,g);break;case"opacity":u.gradient&&!u[e]("stroke-opacity")&&v(l,{"stroke-opacity":g>1?g/100:g});case"fill-opacity":if(u.gradient){P=t._g.doc.getElementById(l.getAttribute("fill").replace(/^url\(#|\)$/g,c)),P&&(F=P.getElementsByTagName("stop"),v(F[F.length-1],{"stop-opacity":g}));break}default:"font-size"==d&&(g=n(g,10)+"px");var R=d.replace(/(\-.)/g,function(t){return t.substring(1).toUpperCase()});l.style[R]=g,i._.dirty=1,l.setAttribute(d,g)}}S(i,a),l.style.visibility=f},C=1.2,S=function(i,a){if("text"==i.type&&(a[e]("text")||a[e]("font")||a[e]("font-size")||a[e]("x")||a[e]("y"))){var s=i.attrs,o=i.node,l=o.firstChild?n(t._g.doc.defaultView.getComputedStyle(o.firstChild,c).getPropertyValue("font-size"),10):10;if(a[e]("text")){for(s.text=a.text;o.firstChild;)o.removeChild(o.firstChild);for(var h=r(a.text).split("\n"),u=[],f,p=0,d=h.length;p"));var Z=X.getBoundingClientRect();m.W=f.w=(Z.right-Z.left)/U,m.H=f.h=(Z.bottom-Z.top)/U,m.X=f.x,m.Y=f.y+m.H/2,("x"in l||"y"in l)&&(m.path.v=t.format("m{0},{1}l{2},{1}",a(f.x*b),a(f.y*b),a(f.x*b)+1));for(var Q=["x","y","text","font","font-family","font-weight","font-style","font-size"],J=0,K=Q.length;J.25&&(r=n.sqrt(.25-l(e-.5,2))*(2*(r>.5)-1)+.5),f=e+p+r),d}),a=a.split(/\s*\-\s*/),"linear"==c){var g=a.shift();if(g=-i(g),isNaN(g))return null}var v=t._parseDots(a);if(!v)return null;if(e=e.shape||e.node,v.length){e.removeChild(s),s.on=!0,s.method="none",s.color=v[0].color,s.color2=v[v.length-1].color;for(var x=[],y=0,m=v.length;y')}}catch(r){N=function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},t._engine.initWin(t._g.win),t._engine.create=function(){var e=t._getContainer.apply(0,arguments),r=e.container,i=e.height,n,a=e.width,s=e.x,o=e.y;if(!r)throw new Error("VML container not found.");var l=new t._Paper,h=l.canvas=t._g.doc.createElement("div"),u=h.style;return s=s||0,o=o||0,a=a||512,i=i||342,l.width=a,l.height=i,a==+a&&(a+="px"),i==+i&&(i+="px"),l.coordsize=1e3*b+p+1e3*b,l.coordorigin="0 0",l.span=t._g.doc.createElement("span"),l.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",h.appendChild(l.span),u.cssText=t.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",a,i),1==r?(t._g.doc.body.appendChild(h),u.left=s+"px",u.top=o+"px",u.position="absolute"):r.firstChild?r.insertBefore(h,r.firstChild):r.appendChild(h),l.renderfix=function(){},l},t.prototype.clear=function(){t.eve("raphael.clear",this),this.canvas.innerHTML=d,this.span=t._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},t.prototype.remove=function(){t.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var e in this)this[e]="function"==typeof this[e]?t._removedFactory(e):null;return!0};var L=t.st;for(var z in M)M[e](z)&&!L[e](z)&&(L[z]=function(t){return function(){var e=arguments;return this.forEach(function(r){r[t].apply(r,e)})}}(z))}}.apply(e,i),!(void 0!==n&&(t.exports=n))}])}); \ No newline at end of file diff --git a/src/utils/highlightjs/CHANGES.md b/src/utils/highlightjs/CHANGES.md deleted file mode 100644 index 05473a26..00000000 --- a/src/utils/highlightjs/CHANGES.md +++ /dev/null @@ -1,1646 +0,0 @@ -## Version 9.12.0 - -New language: - -- *MikroTik* RouterOS Scripting language by [Ivan Dementev][]. - -New style: - -- *VisualStudio 2015 Dark* by [Nicolas LLOBERA][] - -Improvements: - -- *Crystal* updated with new keywords and syntaxes by [Tsuyusato Kitsune][]. -- *Julia* updated to the modern definitions by [Alex Arslan][]. -- *julia-repl* added by [Morten Piibeleht][]. -- [Stanislav Belov][] wrote a new definition for *1C*, replacing the one that - has not been updated for more than 8 years. The new version supports syntax - for versions 7.7 and 8. -- [Nicolas LLOBERA][] improved C# definition fixing edge cases with function - titles detection and added highlighting of `[Attributes]`. -- [nnnik][] provided a few correctness fixes for *Autohotkey*. -- [Martin Clausen][] made annotation collections in *Clojure* to look - consistently with other kinds. -- [Alejandro Alonso][] updated *Swift* keywords. - -[Tsuyusato Kitsune]: https://github.com/MakeNowJust -[Alex Arslan]: https://github.com/ararslan -[Morten Piibeleht]: https://github.com/mortenpi -[Stanislav Belov]: https://github.com/4ppl -[Ivan Dementev]: https://github.com/DiVAN1x -[Nicolas LLOBERA]: https://github.com/Nicolas01 -[nnnik]: https://github.com/nnnik -[Martin Clausen]: https://github.com/maacl -[Alejandro Alonso]: https://github.com/Azoy - - -## Version 9.11.0 - -New languages: - -- *Shell* by [Tsuyusato Kitsune][] -- *jboss-cli* by [Raphaël Parrëe][] - -Improvements: - -- [Joël Porquet] has [greatly improved the definition of *makefile*][5b3e0e6]. -- *C++* class titles are now highlighted as in other languages with classes. -- [Jordi Petit][] added rarely used `or`, `and` and `not` keywords to *C++*. -- [Pieter Vantorre][] fixed highlighting of negative floating point values. - - -[Tsuyusato Kitsune]: https://github.com/MakeNowJust -[Jordi Petit]: https://github.com/jordi-petit -[Raphaël Parrëe]: https://github.com/rparree -[Pieter Vantorre]: https://github.com/NuclearCookie -[5b3e0e6]: https://github.com/isagalaev/highlight.js/commit/5b3e0e68bfaae282faff6697d6a490567fa9d44b - - -## Version 9.10.0 - -Apologies for missing the previous release cycle. Some thing just can't be -automated… Anyway, we're back! - -New languages: - -- *Hy* by [Sergey Sobko][] -- *Leaf* by [Hale Chan][] -- *N1QL* by [Andres Täht][] and [Rene Saarsoo][] - -Improvements: - -- *Rust* got updated with new keywords by [Kasper Andersen][] and then - significantly modernized even more by [Eduard-Mihai Burtescu][] (yes, @eddyb, - Rust core team member!) -- *Python* updated with f-literals by [Philipp A][]. -- *YAML* updated with unquoted strings support. -- *Gauss* updated with new keywords by [Matt Evans][]. -- *Lua* updated with new keywords by [Joe Blow][]. -- *Kotlin* updated with new keywords by [Philipp Hauer][]. -- *TypeScript* got highlighting of function params and updated keywords by - [Ike Ku][]. -- *Scheme* now correctly handles \`-quoted lists thanks to [Guannan Wei]. -- [Sam Wu][] fixed handling of `<<` in *C++* defines. - -[Philipp A]: https://github.com/flying-sheep -[Philipp Hauer]: https://github.com/phauer -[Sergey Sobko]: https://github.com/profitware -[Hale Chan]: https://github.com/halechan -[Matt Evans]: https://github.com/matthewevans -[Joe Blow]: https://github.com/mossarelli -[Kasper Andersen]: https://github.com/kasma1990 -[Eduard-Mihai Burtescu]: https://github.com/eddyb -[Andres Täht]: https://github.com/andrestaht -[Rene Saarsoo]: https://github.com/nene -[Philipp Hauer]: https://github.com/phauer -[Ike Ku]: https://github.com/dempfi -[Guannan Wei]: https://github.com/Kraks -[Sam Wu]: https://github.com/samsam2310 - - -## Version 9.9.0 - -New languages - -- *LLVM* by [Michael Rodler][] - -Improvements: - -- *TypeScript* updated with annotations and param lists inside constructors, by - [Raphael Parree][]. -- *CoffeeScript* updated with new keywords and fixed to recognize JavaScript - in \`\`\`, thanks to thanks to [Geoffrey Booth][]. -- Compiler directives in *Delphi* are now correctly highlighted as "meta". - -[Raphael Parree]: https://github.com/rparree -[Michael Rodler]: https://github.com/f0rki -[Geoffrey Booth]: https://github.com/GeoffreyBooth - - -## Version 9.8.0 "New York" - -This version is the second one that deserved a name. Because I'm in New York, -and the release isn't missing the deadline only because it's still Tuesday on -West Coast. - -New languages: - -- *Clean* by [Camil Staps][] -- *Flix* by [Magnus Madsen][] - -Improvements: - -- [Kenton Hamaluik][] did a comprehensive update for *Haxe*. -- New commands for *PowerShell* from [Nicolas Le Gall][]. -- [Jan T. Sott][] updated *NSIS*. -- *Java* and *Swift* support unicode characters in identifiers thanks to - [Alexander Lichter][]. - -[Camil Staps]: https://github.com/camilstaps -[Magnus Madsen]: https://github.com/magnus-madsen -[Kenton Hamaluik]: https://github.com/FuzzyWuzzie -[Nicolas Le Gall]: https://github.com/darkitty -[Jan T. Sott]: https://github.com/idleberg -[Alexander Lichter]: https://github.com/manniL - - -## Version 9.7.0 - -A comprehensive bugfix release. This is one of the best things about -highlight.js: even boring things keep getting better (even if slow). - -- VHDL updated with PSL keywords and uses more consistent styling. -- Nested C-style comments no longer break highlighting in many languages. -- JavaScript updated with `=>` functions, highlighted object attributes and - parsing within template string substitution blocks (`${...}`). -- Fixed another corner case with self-closing `` in JSX. -- Added `HEALTHCHECK` directive in Docker. -- Delphi updated with new Free Pascal keywords. -- Fixed digit separator parsing in C++. -- C# updated with new keywords and fixed to allow multiple identifiers within - generics `<...>`. -- Fixed another slow regex in Less. - - -## Version 9.6.0 - -New languages: - -- *ABNF* and *EBNF* by [Alex McKibben][] -- *Awk* by [Matthew Daly][] -- *SubUnit* by [Sergey Bronnikov][] - -New styles: - -- *Atom One* in both Dark and Light variants by [Daniel Gamage][] - -Plus, a few smaller updates for *Lasso*, *Elixir*, *C++* and *SQL*. - -[Alex McKibben]: https://github.com/mckibbenta -[Daniel Gamage]: https://github.com/danielgamage -[Matthew Daly]: https://github.com/matthewbdaly -[Sergey Bronnikov]: https://github.com/ligurio - - -## Version 9.5.0 - -New languages: - -- *Excel* by [Victor Zhou][] -- *Linden Scripting Language* by [Builder's Brewery][] -- *TAP* (Test Anything Protocol) by [Sergey Bronnikov][] -- *Pony* by [Joe Eli McIlvain][] -- *Coq* by [Stephan Boyer][] -- *dsconfig* and *LDIF* by [Jacob Childress][] - -New styles: - -- *Ocean Dark* by [Gavin Siu][] - -Notable changes: - -- [Minh Nguyễn][] added more built-ins to Objective C. -- [Jeremy Hull][] fixed corner cases in C++ preprocessor directives and Diff - comments. -- [Victor Zhou][] added support for digit separators in C++ numbers. - -[Gavin Siu]: https://github.com/gavsiu -[Builder's Brewery]: https://github.com/buildersbrewery -[Victor Zhou]: https://github.com/OiCMudkips -[Sergey Bronnikov]: https://github.com/ligurio -[Joe Eli McIlvain]: https://github.com/jemc -[Stephan Boyer]: https://github.com/boyers -[Jacob Childress]: https://github.com/braveulysses -[Minh Nguyễn]: https://github.com/1ec5 -[Jeremy Hull]: https://github.com/sourrust - - -## Version 9.4.0 - -New languages: - -- *PureBASIC* by [Tristano Ajmone][] -- *BNF* by [Oleg Efimov][] -- *Ada* by [Lars Schulna][] - -New styles: - -- *PureBASIC* by [Tristano Ajmone][] - -Improvements to existing languages and styles: - -- We now highlight function declarations in Go. -- [Taisuke Fujimoto][] contributed very convoluted rules for raw and - interpolated strings in C#. -- [Boone Severson][] updated Verilog to comply with IEEE 1800-2012 - SystemVerilog. -- [Victor Zhou][] improved rules for comments and strings in PowerShell files. -- [Janis Voigtländer][] updated the definition of Elm to version 0.17 of the - languages. Elm is now featured on the front page of . -- Special variable `$this` is highlighted as a keyword in PHP. -- `usize` and `isize` are now highlighted in Rust. -- Fixed labels and directives in x86 assembler. - -[Tristano Ajmone]: https://github.com/tajmone -[Taisuke Fujimoto]: https://github.com/temp-impl -[Oleg Efimov]: https://github.com/Sannis -[Boone Severson]: https://github.com/BooneJS -[Victor Zhou]: https://github.com/OiCMudkips -[Lars Schulna]: https://github.com/captain-hanuta -[Janis Voigtländer]: https://github.com/jvoigtlaender - - -## Version 9.3.0 - -New languages: - -- *Tagger Script* by [Philipp Wolfer][] -- *MoonScript* by [Billy Quith][] - -New styles: - -- *xt256* by [Herbert Shin][] - -Improvements to existing languages and styles: - -- More robust handling of unquoted HTML tag attributes -- Relevance tuning for QML which was unnecessary eager at seizing other - languages' code -- Improve GAMS language parsing -- Fixed a bunch of bugs around selectors in Less -- Kotlin's got a new definition for annotations, updated keywords and other - minor improvements -- Added `move` to Rust keywords -- Markdown now recognizes \`\`\`-fenced code blocks -- Improved detection of function declarations in C++ and C# - -[Philipp Wolfer]: https://github.com/phw -[Billy Quith]: https://github.com/billyquith -[Herbert Shin]: https://github.com/initbar - - -## Version 9.2.0 - -New languages: - -- *QML* by [John Foster][] -- *HTMLBars* by [Michael Johnston][] -- *CSP* by [Taras][] -- *Maxima* by [Robert Dodier][] - -New styles: - -- *Gruvbox* by [Qeole][] -- *Dracula* by [Denis Ciccale][] - -Improvements to existing languages and styles: - -- We now correctly handle JSX with arbitrary node tree depth. -- Argument list for `(lambda)` in Scheme is no longer highlighted as a function - call. -- Stylus syntax doesn't break on valid CSS. -- More correct handling of comments and strings and other improvements for - VimScript. -- More subtle work on the default style. -- We now use anonymous modules for AMD. -- `macro_rules!` is now recognized as a built-in in Rust. - -[John Foster]: https://github.com/jf990 -[Qeole]: https://github.com/Qeole -[Denis Ciccale]: https://github.com/dciccale -[Michael Johnston]: https://github.com/lastobelus -[Taras]: https://github.com/oxdef -[Robert Dodier]: https://github.com/robert-dodier - - -## Version 9.1.0 - -New languages: - -- *Stan* by [Brendan Rocks][] -- *BASIC* by [Raphaël Assénat][] -- *GAUSS* by [Matt Evans][] -- *DTS* by [Martin Braun][] -- *Arduino* by [Stefania Mellai][] - -New Styles: - -- *Arduino Light* by [Stefania Mellai][] - -Improvements to existing languages and styles: - -- Handle return type annotations in Python -- Allow shebang headers in Javascript -- Support strings in Rust meta -- Recognize `struct` as a class-level definition in Rust -- Recognize b-prefixed chars and strings in Rust -- Better numbers handling in Verilog - -[Brendan Rocks]: http://brendanrocks.com -[Raphaël Assénat]: https://github.com/raphnet -[Matt Evans]: https://github.com/matthewevans -[Martin Braun]: https://github.com/mbr0wn -[Stefania Mellai]: https://github.com/smellai - - -## Version 9.0.0 - -The new major version brings a reworked styling system. Highlight.js now defines -a limited set of highlightable classes giving a consistent result across all the -styles and languages. You can read a more detailed explanation and background in -the [tracking issue][#348] that started this long process back in May. - -This change is backwards incompatible for those who uses highlight.js with a -custom stylesheet. The [new style guide][sg] explains how to write styles -in this new world. - -Bundled themes have also suffered a significant amount of improvements and may -look different in places, but all the things now consistent and make more sense. -Among others, the Default style has got a refresh and will probably be tweaked -some more in next releases. Please do give your feedback in our -[issue tracker][issues]. - -New languages in this release: - -- *Caché Object Script* by [Nikita Savchenko][] -- *YAML* by [Stefan Wienert][] -- *MIPS Assembler* by [Nebuleon Fumika][] -- *HSP* by [prince][] - -Improvements to existing languages and styles: - -- ECMAScript 6 modules import now do not require closing semicolon. -- ECMAScript 6 classes constructors now highlighted. -- Template string support for Typescript, as for ECMAScript 6. -- Scala case classes params highlight fixed. -- Built-in names introduced in Julia v0.4 added by [Kenta Sato][]. -- Refreshed Default style. - -Other notable changes: - -- [Web workers support][webworkers] added bu [Jan Kühle][]. -- We now have tests for compressed browser builds as well. -- The building tool chain has been switched to node.js 4.x. and is now - shamelessly uses ES6 features all over the place, courtesy of [Jeremy Hull][]. -- License added to non-compressed browser build. - -[Jan Kühle]: https://github.com/frigus02 -[Stefan Wienert]: https://github.com/zealot128 -[Kenta Sato]: https://github.com/bicycle1885 -[Nikita Savchenko]: https://github.com/ZitRos -[webworkers]: https://github.com/isagalaev/highlight.js#web-workers -[Jeremy Hull]: https://github.com/sourrust -[#348]: https://github.com/isagalaev/highlight.js/issues/348 -[sg]: http://highlightjs.readthedocs.org/en/latest/style-guide.html -[issues]: https://github.com/isagalaev/highlight.js/issues -[Nebuleon Fumika]: https://github.com/Nebuleon -[prince]: https://github.com/prince-0203 - - -## Version 8.9.1 - -Some last-minute changes reverted due to strange bug with minified browser build: - -- Scala case classes params highlight fixed -- ECMAScript 6 modules import now do not require closing semicolon -- ECMAScript 6 classes constructors now highlighted -- Template string support for Typescript, as for ECMAScript 6 -- License added to not minified browser build - - -## Version 8.9.0 - -New languages: - -- *crmsh* by [Kristoffer Gronlund][] -- *SQF* by [Soren Enevoldsen][] - -[Kristoffer Gronlund]: https://github.com/krig -[Soren Enevoldsen]: https://github.com/senevoldsen90 - -Notable fixes and improvements to existing languages: - -- Added `abstract` and `namespace` keywords to TypeScript by [Daniel Rosenwasser][] -- Added `label` support to Dockerfile by [Ladislav Prskavec][] -- Crystal highlighting improved by [Tsuyusato Kitsune][] -- Missing Swift keywords added by [Nate Cook][] -- Improve detection of C block comments -- ~~Scala case classes params highlight fixed~~ -- ~~ECMAScript 6 modules import now do not require closing semicolon~~ -- ~~ECMAScript 6 classes constructors now highlighted~~ -- ~~Template string support for Typescript, as for ECMAScript 6~~ - -Other notable changes: - -- ~~License added to not minified browser build~~ - -[Kristoffer Gronlund]: https://github.com/krig -[Søren Enevoldsen]: https://github.com/senevoldsen90 -[Daniel Rosenwasser]: https://github.com/DanielRosenwasser -[Ladislav Prskavec]: https://github.com/abtris -[Tsuyusato Kitsune]: https://github.com/MakeNowJust -[Nate Cook]: https://github.com/natecook1000 - - -## Version 8.8.0 - -New languages: - -- *Golo* by [Philippe Charrière][] -- *GAMS* by [Stefan Bechert][] -- *IRPF90* by [Anthony Scemama][] -- *Access logs* by [Oleg Efimov][] -- *Crystal* by [Tsuyusato Kitsune][] - -Notable fixes and improvements to existing languages: - -- JavaScript highlighting no longer fails with ES6 default parameters -- Added keywords `async` and `await` to Python -- PHP heredoc support improved -- Allow preprocessor directives within C++ functions - -Other notable changes: - -- Change versions to X.Y.Z SemVer-compatible format -- Added ability to build all targets at once - -[Philippe Charrière]: https://github.com/k33g -[Stefan Bechert]: https://github.com/b-pos465 -[Anthony Scemama]: https://github.com/scemama -[Oleg Efimov]: https://github.com/Sannis -[Tsuyusato Kitsune]: https://github.com/MakeNowJust - - -## Version 8.7 - -New languages: - -- *Zephir* by [Oleg Efimov][] -- *Elm* by [Janis Voigtländer][] -- *XQuery* by [Dirk Kirsten][] -- *Mojolicious* by [Dotan Dimet][] -- *AutoIt* by Manh Tuan from [J2TeaM][] -- *Toml* (ini extension) by [Guillaume Gomez][] - -New styles: - -- *Hopscotch* by [Jan T. Sott][] -- *Grayscale* by [MY Sun][] - -Notable fixes and improvements to existing languages: - -- Fix encoding of images when copied over in certain builds -- Fix incorrect highlighting of the word "bug" in comments -- Treat decorators different from matrix multiplication in Python -- Fix traits inheritance highlighting in Rust -- Fix incorrect document -- Oracle keywords added to SQL language definition by [Vadimtro][] -- Postgres keywords added to SQL language definition by [Benjamin Auder][] -- Fix registers in x86asm being highlighted as a hex number -- Fix highlighting for numbers with a leading decimal point -- Correctly highlight numbers and strings inside of C/C++ macros -- C/C++ functions now support pointer, reference, and move returns - -[Oleg Efimov]: https://github.com/Sannis -[Guillaume Gomez]: https://github.com/GuillaumeGomez -[Janis Voigtländer]: https://github.com/jvoigtlaender -[Jan T. Sott]: https://github.com/idleberg -[Dirk Kirsten]: https://github.com/dirkk -[MY Sun]: https://github.com/simonmysun -[Vadimtro]: https://github.com/Vadimtro -[Benjamin Auder]: https://github.com/ghost -[Dotan Dimet]: https://github.com/dotandimet -[J2TeaM]: https://github.com/J2TeaM - - -## Version 8.6 - -New languages: - -- *C/AL* by [Kenneth Fuglsang][] -- *DNS zone file* by [Tim Schumacher][] -- *Ceylon* by [Lucas Werkmeister][] -- *OpenSCAD* by [Dan Panzarella][] -- *Inform7* by [Bruno Dias][] -- *armasm* by [Dan Panzarella][] -- *TP* by [Jay Strybis][] - -New styles: - -- *Atelier Cave*, *Atelier Estuary*, - *Atelier Plateau* and *Atelier Savanna* by [Bram de Haan][] -- *Github Gist* by [Louis Barranqueiro][] - -Notable fixes and improvements to existing languages: - -- Multi-line raw strings from C++11 are now supported -- Fix class names with dashes in HAML -- The `async` keyword from ES6/7 is now supported -- TypeScript functions handle type and parameter complexity better -- We unified phpdoc/javadoc/yardoc etc modes across all languages -- CSS .class selectors relevance was dropped to prevent wrong language detection -- Images is now included to CDN build -- Release process is now automated - -[Bram de Haan]: https://github.com/atelierbram -[Kenneth Fuglsang]: https://github.com/kfuglsang -[Louis Barranqueiro]: https://github.com/LouisBarranqueiro -[Tim Schumacher]: https://github.com/enko -[Lucas Werkmeister]: https://github.com/lucaswerkmeister -[Dan Panzarella]: https://github.com/pzl -[Bruno Dias]: https://github.com/sequitur -[Jay Strybis]: https://github.com/unreal - - -## Version 8.5 - -New languages: - -- *pf.conf* by [Peter Piwowarski][] -- *Julia* by [Kenta Sato][] -- *Prolog* by [Raivo Laanemets][] -- *Docker* by [Alexis Hénaut][] -- *Fortran* by [Anthony Scemama][] and [Thomas Applencourt][] -- *Kotlin* by [Sergey Mashkov][] - -New styles: - -- *Agate* by [Taufik Nurrohman][] -- *Darcula* by [JetBrains][] -- *Atelier Sulphurpool* by [Bram de Haan][] -- *Android Studio* by [Pedro Oliveira][] - -Notable fixes and improvements to existing languages: - -- ES6 features in JavaScript are better supported now by [Gu Yiling][]. -- Swift now recognizes body-less method definitions. -- Single expression functions `def foo, do: ... ` now work in Elixir. -- More uniform detection of built-in classes in Objective C. -- Fixes for number literals and processor directives in Rust. -- HTML ` - ``` - -- `tabReplace` and `useBR` that were used in different places are also unified - into the global options object and are to be set using `configure(options)`. - This function is documented in our [API docs][]. Also note that these - parameters are gone from `highlightBlock` and `fixMarkup` which are now also - rely on `configure`. - -- We removed public-facing (though undocumented) object `hljs.LANGUAGES` which - was used to register languages with the library in favor of two new methods: - `registerLanguage` and `getLanguage`. Both are documented in our [API docs][]. - -- Result returned from `highlight` and `highlightAuto` no longer contains two - separate attributes contributing to relevance score, `relevance` and - `keyword_count`. They are now unified in `relevance`. - -Another technically compatible change that nonetheless might need attention: - -- The structure of the NPM package was refactored, so if you had installed it - locally, you'll have to update your paths. The usual `require('highlight.js')` - works as before. This is contributed by [Dmitry Smolin][]. - -New features: - -- Languages now can be recognized by multiple names like "js" for JavaScript or - "html" for, well, HTML (which earlier insisted on calling it "xml"). These - aliases can be specified in the class attribute of the code container in your - HTML as well as in various API calls. For now there are only a few very common - aliases but we'll expand it in the future. All of them are listed in the - [class reference][cr]. - -- Language detection can now be restricted to a subset of languages relevant in - a given context — a web page or even a single highlighting call. This is - especially useful for node.js build that includes all the known languages. - Another example is a StackOverflow-style site where users specify languages - as tags rather than in the markdown-formatted code snippets. This is - documented in the [API reference][] (see methods `highlightAuto` and - `configure`). - -- Language definition syntax streamlined with [variants][] and - [beginKeywords][]. - -New languages and styles: - -- *Oxygene* by [Carlo Kok][] -- *Mathematica* by [Daniel Kvasnička][] -- *Autohotkey* by [Seongwon Lee][] -- *Atelier* family of styles in 10 variants by [Bram de Haan][] -- *Paraíso* styles by [Jan T. Sott][] - -Miscellaneous improvements: - -- Highlighting `=>` prompts in Clojure. -- [Jeremy Hull][] fixed a lot of styles for consistency. -- Finally, highlighting PHP and HTML [mixed in peculiar ways][php-html]. -- Objective C and C# now properly highlight titles in method definition. -- Big overhaul of relevance counting for a number of languages. Please do report - bugs about mis-detection of non-trivial code snippets! - -[API reference]: http://highlightjs.readthedocs.org/en/latest/api.html - -[cr]: http://highlightjs.readthedocs.org/en/latest/css-classes-reference.html -[api docs]: http://highlightjs.readthedocs.org/en/latest/api.html -[variants]: https://groups.google.com/d/topic/highlightjs/VoGC9-1p5vk/discussion -[beginKeywords]: https://github.com/isagalaev/highlight.js/commit/6c7fdea002eb3949577a85b3f7930137c7c3038d -[php-html]: https://twitter.com/highlightjs/status/408890903017689088 - -[Carlo Kok]: https://github.com/carlokok -[Bram de Haan]: https://github.com/atelierbram -[Daniel Kvasnička]: https://github.com/dkvasnicka -[Dmitry Smolin]: https://github.com/dimsmol -[Jeremy Hull]: https://github.com/sourrust -[Seongwon Lee]: https://github.com/dlimpid -[Jan T. Sott]: https://github.com/idleberg - - -## Version 7.5 - -A catch-up release dealing with some of the accumulated contributions. This one -is probably will be the last before the 8.0 which will be slightly backwards -incompatible regarding some advanced use-cases. - -One outstanding change in this version is the addition of 6 languages to the -[hosted script][d]: Markdown, ObjectiveC, CoffeeScript, Apache, Nginx and -Makefile. It now weighs about 6K more but we're going to keep it under 30K. - -New languages: - -- OCaml by [Mehdi Dogguy][mehdid] and [Nicolas Braud-Santoni][nbraud] -- [LiveCode Server][lcs] by [Ralf Bitter][revig] -- Scilab by [Sylvestre Ledru][sylvestre] -- basic support for Makefile by [Ivan Sagalaev][isagalaev] - -Improvements: - -- Ruby's got support for characters like `?A`, `?1`, `?\012` etc. and `%r{..}` - regexps. -- Clojure now allows a function call in the beginning of s-expressions - `(($filter "myCount") (arr 1 2 3 4 5))`. -- Haskell's got new keywords and now recognizes more things like pragmas, - preprocessors, modules, containers, FFIs etc. Thanks to [Zena Treep][treep] - for the implementation and to [Jeremy Hull][sourrust] for guiding it. -- Miscellaneous fixes in PHP, Brainfuck, SCSS, Asciidoc, CMake, Python and F#. - -[mehdid]: https://github.com/mehdid -[nbraud]: https://github.com/nbraud -[revig]: https://github.com/revig -[lcs]: http://livecode.com/developers/guides/server/ -[sylvestre]: https://github.com/sylvestre -[isagalaev]: https://github.com/isagalaev -[treep]: https://github.com/treep -[sourrust]: https://github.com/sourrust -[d]: http://highlightjs.org/download/ - - -## New core developers - -The latest long period of almost complete inactivity in the project coincided -with growing interest to it led to a decision that now seems completely obvious: -we need more core developers. - -So without further ado let me welcome to the core team two long-time -contributors: [Jeremy Hull][] and [Oleg -Efimov][]. - -Hope now we'll be able to work through stuff faster! - -P.S. The historical commit is [here][1] for the record. - -[Jeremy Hull]: https://github.com/sourrust -[Oleg Efimov]: https://github.com/sannis -[1]: https://github.com/isagalaev/highlight.js/commit/f3056941bda56d2b72276b97bc0dd5f230f2473f - - -## Version 7.4 - -This long overdue version is a snapshot of the current source tree with all the -changes that happened during the past year. Sorry for taking so long! - -Along with the changes in code highlight.js has finally got its new home at -, moving from its cradle on Software Maniacs which it -outgrew a long time ago. Be sure to report any bugs about the site to -. - -On to what's new… - -New languages: - -- Handlebars templates by [Robin Ward][] -- Oracle Rules Language by [Jason Jacobson][] -- F# by [Joans Follesø][] -- AsciiDoc and Haml by [Dan Allen][] -- Lasso by [Eric Knibbe][] -- SCSS by [Kurt Emch][] -- VB.NET by [Poren Chiang][] -- Mizar by [Kelley van Evert][] - -[Robin Ward]: https://github.com/eviltrout -[Jason Jacobson]: https://github.com/jayce7 -[Joans Follesø]: https://github.com/follesoe -[Dan Allen]: https://github.com/mojavelinux -[Eric Knibbe]: https://github.com/EricFromCanada -[Kurt Emch]: https://github.com/kemch -[Poren Chiang]: https://github.com/rschiang -[Kelley van Evert]: https://github.com/kelleyvanevert - -New style themes: - -- Monokai Sublime by [noformnocontent][] -- Railscasts by [Damien White][] -- Obsidian by [Alexander Marenin][] -- Docco by [Simon Madine][] -- Mono Blue by [Ivan Sagalaev][] (uses a single color hue for everything) -- Foundation by [Dan Allen][] - -[noformnocontent]: http://nn.mit-license.org/ -[Damien White]: https://github.com/visoft -[Alexander Marenin]: https://github.com/ioncreature -[Simon Madine]: https://github.com/thingsinjars -[Ivan Sagalaev]: https://github.com/isagalaev - -Other notable changes: - -- Corrected many corner cases in CSS. -- Dropped Python 2 version of the build tool. -- Implemented building for the AMD format. -- Updated Rust keywords (thanks to [Dmitry Medvinsky][]). -- Literal regexes can now be used in language definitions. -- CoffeeScript highlighting is now significantly more robust and rich due to - input from [Cédric Néhémie][]. - -[Dmitry Medvinsky]: https://github.com/dmedvinsky -[Cédric Néhémie]: https://github.com/abe33 - - -## Version 7.3 - -- Since this version highlight.js no longer works in IE version 8 and older. - It's made it possible to reduce the library size and dramatically improve code - readability and made it easier to maintain. Time to go forward! - -- New languages: AppleScript (by [Nathan Grigg][ng] and [Dr. Drang][dd]) and - Brainfuck (by [Evgeny Stepanischev][bolk]). - -- Improvements to existing languages: - - - interpreter prompt in Python (`>>>` and `...`) - - @-properties and classes in CoffeeScript - - E4X in JavaScript (by [Oleg Efimov][oe]) - - new keywords in Perl (by [Kirk Kimmel][kk]) - - big Ruby syntax update (by [Vasily Polovnyov][vast]) - - small fixes in Bash - -- Also Oleg Efimov did a great job of moving all the docs for language and style - developers and contributors from the old wiki under the source code in the - "docs" directory. Now these docs are nicely presented at - . - -[ng]: https://github.com/nathan11g -[dd]: https://github.com/drdrang -[bolk]: https://github.com/bolknote -[oe]: https://github.com/Sannis -[kk]: https://github.com/kimmel -[vast]: https://github.com/vast - - -## Version 7.2 - -A regular bug-fix release without any significant new features. Enjoy! - - -## Version 7.1 - -A Summer crop: - -- [Marc Fornos][mf] made the definition for Clojure along with the matching - style Rainbow (which, of course, works for other languages too). -- CoffeeScript support continues to improve getting support for regular - expressions. -- Yoshihide Jimbo ported to highlight.js [five Tomorrow styles][tm] from the - [project by Chris Kempson][tm0]. -- Thanks to [Casey Duncun][cd] the library can now be built in the popular - [AMD format][amd]. -- And last but not least, we've got a fair number of correctness and consistency - fixes, including a pretty significant refactoring of Ruby. - -[mf]: https://github.com/mfornos -[tm]: http://jmblog.github.com/color-themes-for-highlightjs/ -[tm0]: https://github.com/ChrisKempson/Tomorrow-Theme -[cd]: https://github.com/caseman -[amd]: http://requirejs.org/docs/whyamd.html - - -## Version 7.0 - -The reason for the new major version update is a global change of keyword syntax -which resulted in the library getting smaller once again. For example, the -hosted build is 2K less than at the previous version while supporting two new -languages. - -Notable changes: - -- The library now works not only in a browser but also with [node.js][]. It is - installable with `npm install highlight.js`. [API][] docs are available on our - wiki. - -- The new unique feature (apparently) among syntax highlighters is highlighting - *HTTP* headers and an arbitrary language in the request body. The most useful - languages here are *XML* and *JSON* both of which highlight.js does support. - Here's [the detailed post][p] about the feature. - -- Two new style themes: a dark "south" *[Pojoaque][]* by Jason Tate and an - emulation of*XCode* IDE by [Angel Olloqui][ao]. - -- Three new languages: *D* by [Aleksandar Ružičić][ar], *R* by [Joe Cheng][jc] - and *GLSL* by [Sergey Tikhomirov][st]. - -- *Nginx* syntax has become a million times smaller and more universal thanks to - remaking it in a more generic manner that doesn't require listing all the - directives in the known universe. - -- Function titles are now highlighted in *PHP*. - -- *Haskell* and *VHDL* were significantly reworked to be more rich and correct - by their respective maintainers [Jeremy Hull][sr] and [Igor Kalnitsky][ik]. - -And last but not least, many bugs have been fixed around correctness and -language detection. - -Overall highlight.js currently supports 51 languages and 20 style themes. - -[node.js]: http://nodejs.org/ -[api]: http://softwaremaniacs.org/wiki/doku.php/highlight.js:api -[p]: http://softwaremaniacs.org/blog/2012/05/10/http-and-json-in-highlight-js/en/ -[pojoaque]: http://web-cms-designs.com/ftopict-10-pojoaque-style-for-highlight-js-code-highlighter.html -[ao]: https://github.com/angelolloqui -[ar]: https://github.com/raleksandar -[jc]: https://github.com/jcheng5 -[st]: https://github.com/tikhomirov -[sr]: https://github.com/sourrust -[ik]: https://github.com/ikalnitsky - - -## Version 6.2 - -A lot of things happened in highlight.js since the last version! We've got nine -new contributors, the discussion group came alive, and the main branch on GitHub -now counts more than 350 followers. Here are most significant results coming -from all this activity: - -- 5 (five!) new languages: Rust, ActionScript, CoffeeScript, MatLab and - experimental support for markdown. Thanks go to [Andrey Vlasovskikh][av], - [Alexander Myadzel][am], [Dmytrii Nagirniak][dn], [Oleg Efimov][oe], [Denis - Bardadym][db] and [John Crepezzi][jc]. - -- 2 new style themes: Monokai by [Luigi Maselli][lm] and stylistic imitation of - another well-known highlighter Google Code Prettify by [Aahan Krish][ak]. - -- A vast number of [correctness fixes and code refactorings][log], mostly made - by [Oleg Efimov][oe] and [Evgeny Stepanischev][es]. - -[av]: https://github.com/vlasovskikh -[am]: https://github.com/myadzel -[dn]: https://github.com/dnagir -[oe]: https://github.com/Sannis -[db]: https://github.com/btd -[jc]: https://github.com/seejohnrun -[lm]: http://grigio.org/ -[ak]: https://github.com/geekpanth3r -[es]: https://github.com/bolknote -[log]: https://github.com/isagalaev/highlight.js/commits/ - - -## Version 6.1 — Solarized - -[Jeremy Hull][jh] has implemented my dream feature — a port of [Solarized][] -style theme famous for being based on the intricate color theory to achieve -correct contrast and color perception. It is now available for highlight.js in -both variants — light and dark. - -This version also adds a new original style Arta. Its author pumbur maintains a -[heavily modified fork of highlight.js][pb] on GitHub. - -[jh]: https://github.com/sourrust -[solarized]: http://ethanschoonover.com/solarized -[pb]: https://github.com/pumbur/highlight.js - - -## Version 6.0 - -New major version of the highlighter has been built on a significantly -refactored syntax. Due to this it's even smaller than the previous one while -supporting more languages! - -New languages are: - -- Haskell by [Jeremy Hull][sourrust] -- Erlang in two varieties — module and REPL — made collectively by [Nikolay - Zakharov][desh], [Dmitry Kovega][arhibot] and [Sergey Ignatov][ignatov] -- Objective C by [Valerii Hiora][vhbit] -- Vala by [Antono Vasiljev][antono] -- Go by [Stephan Kountso][steplg] - -[sourrust]: https://github.com/sourrust -[desh]: http://desh.su/ -[arhibot]: https://github.com/arhibot -[ignatov]: https://github.com/ignatov -[vhbit]: https://github.com/vhbit -[antono]: https://github.com/antono -[steplg]: https://github.com/steplg - -Also this version is marginally faster and fixes a number of small long-standing -bugs. - -Developer overview of the new language syntax is available in a [blog post about -recent beta release][beta]. - -[beta]: http://softwaremaniacs.org/blog/2011/04/25/highlight-js-60-beta/en/ - -P.S. New version is not yet available on a Yandex CDN, so for now you have to -download [your own copy][d]. - -[d]: /soft/highlight/en/download/ - - -## Version 5.14 - -Fixed bugs in HTML/XML detection and relevance introduced in previous -refactoring. - -Also test.html now shows the second best result of language detection by -relevance. - - -## Version 5.13 - -Past weekend began with a couple of simple additions for existing languages but -ended up in a big code refactoring bringing along nice improvements for language -developers. - -### For users - -- Description of C++ has got new keywords from the upcoming [C++ 0x][] standard. -- Description of HTML has got new tags from [HTML 5][]. -- CSS-styles have been unified to use consistent padding and also have lost - pop-outs with names of detected languages. -- [Igor Kalnitsky][ik] has sent two new language descriptions: CMake & VHDL. - -This makes total number of languages supported by highlight.js to reach 35. - -Bug fixes: - -- Custom classes on `
    ` tags are not being overridden anymore
    -- More correct highlighting of code blocks inside non-`
    ` containers:
    -  highlighter now doesn't insist on replacing them with its own container and
    -  just replaces the contents.
    -- Small fixes in browser compatibility and heuristics.
    -
    -[c++ 0x]: http://ru.wikipedia.org/wiki/C%2B%2B0x
    -[html 5]: http://en.wikipedia.org/wiki/HTML5
    -[ik]: http://kalnitsky.org.ua/
    -
    -### For developers
    -
    -The most significant change is the ability to include language submodes right
    -under `contains` instead of defining explicit named submodes in the main array:
    -
    -    contains: [
    -      'string',
    -      'number',
    -      {begin: '\\n', end: hljs.IMMEDIATE_RE}
    -    ]
    -
    -This is useful for auxiliary modes needed only in one place to define parsing.
    -Note that such modes often don't have `className` and hence won't generate a
    -separate `` in the resulting markup. This is similar in effect to
    -`noMarkup: true`. All existing languages have been refactored accordingly.
    -
    -Test file test.html has at last become a real test. Now it not only puts the
    -detected language name under the code snippet but also tests if it matches the
    -expected one. Test summary is displayed right above all language snippets.
    -
    -
    -## CDN
    -
    -Fine people at [Yandex][] agreed to host highlight.js on their big fast servers.
    -[Link up][l]!
    -
    -[yandex]: http://yandex.com/
    -[l]: http://softwaremaniacs.org/soft/highlight/en/download/
    -
    -
    -## Version 5.10 — "Paris".
    -
    -Though I'm on a vacation in Paris, I decided to release a new version with a
    -couple of small fixes:
    -
    -- Tomas Vitvar discovered that TAB replacement doesn't always work when used
    -  with custom markup in code
    -- SQL parsing is even more rigid now and doesn't step over SmallTalk in tests
    -
    -
    -## Version 5.9
    -
    -A long-awaited version is finally released.
    -
    -New languages:
    -
    -- Andrew Fedorov made a definition for Lua
    -- a long-time highlight.js contributor [Peter Leonov][pl] made a definition for
    -  Nginx config
    -- [Vladimir Moskva][vm] made a definition for TeX
    -
    -[pl]: http://kung-fu-tzu.ru/
    -[vm]: http://fulc.ru/
    -
    -Fixes for existing languages:
    -
    -- [Loren Segal][ls] reworked the Ruby definition and added highlighting for
    -  [YARD][] inline documentation
    -- the definition of SQL has become more solid and now it shouldn't be overly
    -  greedy when it comes to language detection
    -
    -[ls]: http://gnuu.org/
    -[yard]: http://yardoc.org/
    -
    -The highlighter has become more usable as a library allowing to do highlighting
    -from initialization code of JS frameworks and in ajax methods (see.
    -readme.eng.txt).
    -
    -Also this version drops support for the [WordPress][wp] plugin. Everyone is
    -welcome to [pick up its maintenance][p] if needed.
    -
    -[wp]: http://wordpress.org/
    -[p]: http://bazaar.launchpad.net/~isagalaev/+junk/highlight/annotate/342/src/wp_highlight.js.php
    -
    -
    -## Version 5.8
    -
    -- Jan Berkel has contributed a definition for Scala. +1 to hotness!
    -- All CSS-styles are rewritten to work only inside `
    ` tags to avoid
    -  conflicts with host site styles.
    -
    -
    -## Version 5.7.
    -
    -Fixed escaping of quotes in VBScript strings.
    -
    -
    -## Version 5.5
    -
    -This version brings a small change: now .ini-files allow digits, underscores and
    -square brackets in key names.
    -
    -
    -## Version 5.4
    -
    -Fixed small but upsetting bug in the packer which caused incorrect highlighting
    -of explicitly specified languages. Thanks to Andrew Fedorov for precise
    -diagnostics!
    -
    -
    -## Version 5.3
    -
    -The version to fulfil old promises.
    -
    -The most significant change is that highlight.js now preserves custom user
    -markup in code along with its own highlighting markup. This means that now it's
    -possible to use, say, links in code. Thanks to [Vladimir Dolzhenko][vd] for the
    -[initial proposal][1] and for making a proof-of-concept patch.
    -
    -Also in this version:
    -
    -- [Vasily Polovnyov][vp] has sent a GitHub-like style and has implemented
    -  support for CSS @-rules and Ruby symbols.
    -- Yura Zaripov has sent two styles: Brown Paper and School Book.
    -- Oleg Volchkov has sent a definition for [Parser 3][p3].
    -
    -[1]: http://softwaremaniacs.org/forum/highlightjs/6612/
    -[p3]: http://www.parser.ru/
    -[vp]: http://vasily.polovnyov.ru/
    -[vd]: http://dolzhenko.blogspot.com/
    -
    -
    -## Version 5.2
    -
    -- at last it's possible to replace indentation TABs with something sensible
    -  (e.g. 2 or 4 spaces)
    -- new keywords and built-ins for 1C by Sergey Baranov
    -- a couple of small fixes to Apache highlighting
    -
    -
    -## Version 5.1
    -
    -This is one of those nice version consisting entirely of new and shiny
    -contributions!
    -
    -- [Vladimir Ermakov][vooon] created highlighting for AVR Assembler
    -- [Ruslan Keba][rukeba] created highlighting for Apache config file. Also his
    -  original visual style for it is now available for all highlight.js languages
    -  under the name "Magula".
    -- [Shuen-Huei Guan][drake] (aka Drake) sent new keywords for RenderMan
    -  languages. Also thanks go to [Konstantin Evdokimenko][ke] for his advice on
    -  the matter.
    -
    -[vooon]: http://vehq.ru/about/
    -[rukeba]: http://rukeba.com/
    -[drake]: http://drakeguan.org/
    -[ke]: http://k-evdokimenko.moikrug.ru/
    -
    -
    -## Version 5.0
    -
    -The main change in the new major version of highlight.js is a mechanism for
    -packing several languages along with the library itself into a single compressed
    -file. Now sites using several languages will load considerably faster because
    -the library won't dynamically include additional files while loading.
    -
    -Also this version fixes a long-standing bug with Javascript highlighting that
    -couldn't distinguish between regular expressions and division operations.
    -
    -And as usually there were a couple of minor correctness fixes.
    -
    -Great thanks to all contributors! Keep using highlight.js.
    -
    -
    -## Version 4.3
    -
    -This version comes with two contributions from [Jason Diamond][jd]:
    -
    -- language definition for C# (yes! it was a long-missed thing!)
    -- Visual Studio-like highlighting style
    -
    -Plus there are a couple of minor bug fixes for parsing HTML and XML attributes.
    -
    -[jd]: http://jason.diamond.name/weblog/
    -
    -
    -## Version 4.2
    -
    -The biggest news is highlighting for Lisp, courtesy of Vasily Polovnyov. It's
    -somewhat experimental meaning that for highlighting "keywords" it doesn't use
    -any pre-defined set of a Lisp dialect. Instead it tries to highlight first word
    -in parentheses wherever it makes sense. I'd like to ask people programming in
    -Lisp to confirm if it's a good idea and send feedback to [the forum][f].
    -
    -Other changes:
    -
    -- Smalltalk was excluded from DEFAULT_LANGUAGES to save traffic
    -- [Vladimir Epifanov][voldmar] has implemented javascript style switcher for
    -  test.html
    -- comments now allowed inside Ruby function definition
    -- [MEL][] language from [Shuen-Huei Guan][drake]
    -- whitespace now allowed between `
    ` and ``
    -- better auto-detection of C++ and PHP
    -- HTML allows embedded VBScript (`<% .. %>`)
    -
    -[f]: http://softwaremaniacs.org/forum/highlightjs/
    -[voldmar]: http://voldmar.ya.ru/
    -[mel]: http://en.wikipedia.org/wiki/Maya_Embedded_Language
    -[drake]: http://drakeguan.org/
    -
    -
    -## Version 4.1
    -
    -Languages:
    -
    -- Bash from Vah
    -- DOS bat-files from Alexander Makarov (Sam)
    -- Diff files from Vasily Polovnyov
    -- Ini files from myself though initial idea was from Sam
    -
    -Styles:
    -
    -- Zenburn from Vladimir Epifanov, this is an imitation of a
    -  [well-known theme for Vim][zenburn].
    -- Ascetic from myself, as a realization of ideals of non-flashy highlighting:
    -  just one color in only three gradations :-)
    -
    -In other news. [One small bug][bug] was fixed, built-in keywords were added for
    -Python and C++ which improved auto-detection for the latter (it was shame that
    -[my wife's blog][alenacpp] had issues with it from time to time). And lastly
    -thanks go to Sam for getting rid of my stylistic comments in code that were
    -getting in the way of [JSMin][].
    -
    -[zenburn]: http://en.wikipedia.org/wiki/Zenburn
    -[alenacpp]: http://alenacpp.blogspot.com/
    -[bug]: http://softwaremaniacs.org/forum/viewtopic.php?id=1823
    -[jsmin]: http://code.google.com/p/jsmin-php/
    -
    -
    -## Version 4.0
    -
    -New major version is a result of vast refactoring and of many contributions.
    -
    -Visible new features:
    -
    -- Highlighting of embedded languages. Currently is implemented highlighting of
    -  Javascript and CSS inside HTML.
    -- Bundled 5 ready-made style themes!
    -
    -Invisible new features:
    -
    -- Highlight.js no longer pollutes global namespace. Only one object and one
    -  function for backward compatibility.
    -- Performance is further increased by about 15%.
    -
    -Changing of a major version number caused by a new format of language definition
    -files. If you use some third-party language files they should be updated.
    -
    -
    -## Version 3.5
    -
    -A very nice version in my opinion fixing a number of small bugs and slightly
    -increased speed in a couple of corner cases. Thanks to everybody who reports
    -bugs in he [forum][f] and by email!
    -
    -There is also a new language — XML. A custom XML formerly was detected as HTML
    -and didn't highlight custom tags. In this version I tried to make custom XML to
    -be detected and highlighted by its own rules. Which by the way include such
    -things as CDATA sections and processing instructions (``).
    -
    -[f]: http://softwaremaniacs.org/forum/viewforum.php?id=6
    -
    -
    -## Version 3.3
    -
    -[Vladimir Gubarkov][xonix] has provided an interesting and useful addition.
    -File export.html contains a little program that shows and allows to copy and
    -paste an HTML code generated by the highlighter for any code snippet. This can
    -be useful in situations when one can't use the script itself on a site.
    -
    -
    -[xonix]: http://xonixx.blogspot.com/
    -
    -
    -## Version 3.2 consists completely of contributions:
    -
    -- Vladimir Gubarkov has described SmallTalk
    -- Yuri Ivanov has described 1C
    -- Peter Leonov has packaged the highlighter as a Firefox extension
    -- Vladimir Ermakov has compiled a mod for phpBB
    -
    -Many thanks to you all!
    -
    -
    -## Version 3.1
    -
    -Three new languages are available: Django templates, SQL and Axapta. The latter
    -two are sent by [Dmitri Roudakov][1]. However I've almost entirely rewrote an
    -SQL definition but I'd never started it be it from the ground up :-)
    -
    -The engine itself has got a long awaited feature of grouping keywords
    -("keyword", "built-in function", "literal"). No more hacks!
    -
    -[1]: http://roudakov.ru/
    -
    -
    -## Version 3.0
    -
    -It is major mainly because now highlight.js has grown large and has become
    -modular. Now when you pass it a list of languages to highlight it will
    -dynamically load into a browser only those languages.
    -
    -Also:
    -
    -- Konstantin Evdokimenko of [RibKit][] project has created a highlighting for
    -  RenderMan Shading Language and RenderMan Interface Bytestream. Yay for more
    -  languages!
    -- Heuristics for C++ and HTML got better.
    -- I've implemented (at last) a correct handling of backslash escapes in C-like
    -  languages.
    -
    -There is also a small backwards incompatible change in the new version. The
    -function initHighlighting that was used to initialize highlighting instead of
    -initHighlightingOnLoad a long time ago no longer works. If you by chance still
    -use it — replace it with the new one.
    -
    -[RibKit]: http://ribkit.sourceforge.net/
    -
    -
    -## Version 2.9
    -
    -Highlight.js is a parser, not just a couple of regular expressions. That said
    -I'm glad to announce that in the new version 2.9 has support for:
    -
    -- in-string substitutions for Ruby -- `#{...}`
    -- strings from from numeric symbol codes (like #XX) for Delphi
    -
    -
    -## Version 2.8
    -
    -A maintenance release with more tuned heuristics. Fully backwards compatible.
    -
    -
    -## Version 2.7
    -
    -- Nikita Ledyaev presents highlighting for VBScript, yay!
    -- A couple of bugs with escaping in strings were fixed thanks to Mickle
    -- Ongoing tuning of heuristics
    -
    -Fixed bugs were rather unpleasant so I encourage everyone to upgrade!
    -
    -
    -## Version 2.4
    -
    -- Peter Leonov provides another improved highlighting for Perl
    -- Javascript gets a new kind of keywords — "literals". These are the words
    -  "true", "false" and "null"
    -
    -Also highlight.js homepage now lists sites that use the library. Feel free to
    -add your site by [dropping me a message][mail] until I find the time to build a
    -submit form.
    -
    -[mail]: mailto:Maniac@SoftwareManiacs.Org
    -
    -
    -## Version 2.3
    -
    -This version fixes IE breakage in previous version. My apologies to all who have
    -already downloaded that one!
    -
    -
    -## Version 2.2
    -
    -- added highlighting for Javascript
    -- at last fixed parsing of Delphi's escaped apostrophes in strings
    -- in Ruby fixed highlighting of keywords 'def' and 'class', same for 'sub' in
    -  Perl
    -
    -
    -## Version 2.0
    -
    -- Ruby support by [Anton Kovalyov][ak]
    -- speed increased by orders of magnitude due to new way of parsing
    -- this same way allows now correct highlighting of keywords in some tricky
    -  places (like keyword "End" at the end of Delphi classes)
    -
    -[ak]: http://anton.kovalyov.net/
    -
    -
    -## Version 1.0
    -
    -Version 1.0 of javascript syntax highlighter is released!
    -
    -It's the first version available with English description. Feel free to post
    -your comments and question to [highlight.js forum][forum]. And don't be afraid
    -if you find there some fancy Cyrillic letters -- it's for Russian users too :-)
    -
    -[forum]: http://softwaremaniacs.org/forum/viewforum.php?id=6
    diff --git a/src/utils/highlightjs/LICENSE b/src/utils/highlightjs/LICENSE
    deleted file mode 100644
    index 422deb73..00000000
    --- a/src/utils/highlightjs/LICENSE
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -Copyright (c) 2006, Ivan Sagalaev
    -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.
    -    * Neither the name of highlight.js nor the names of its contributors 
    -      may be used to endorse or promote products derived from this software 
    -      without specific prior written permission.
    -
    -THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS AND 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.
    diff --git a/src/utils/highlightjs/README.md b/src/utils/highlightjs/README.md
    deleted file mode 100644
    index 9f76e6bd..00000000
    --- a/src/utils/highlightjs/README.md
    +++ /dev/null
    @@ -1,150 +0,0 @@
    -# Highlight.js
    -
    -[![Build Status](https://travis-ci.org/isagalaev/highlight.js.svg?branch=master)](https://travis-ci.org/isagalaev/highlight.js)
    -
    -Highlight.js is a syntax highlighter written in JavaScript. It works in
    -the browser as well as on the server. It works with pretty much any
    -markup, doesn’t depend on any framework and has automatic language
    -detection.
    -
    -## Getting Started
    -
    -The bare minimum for using highlight.js on a web page is linking to the
    -library along with one of the styles and calling
    -[`initHighlightingOnLoad`][1]:
    -
    -```html
    -
    -
    -
    -```
    -
    -This will find and highlight code inside of `
    ` tags; it tries
    -to detect the language automatically. If automatic detection doesn’t
    -work for you, you can specify the language in the `class` attribute:
    -
    -```html
    -
    ...
    -``` - -The list of supported language classes is available in the [class -reference][2]. Classes can also be prefixed with either `language-` or -`lang-`. - -To disable highlighting altogether use the `nohighlight` class: - -```html -
    ...
    -``` - -## Custom Initialization - -When you need a bit more control over the initialization of -highlight.js, you can use the [`highlightBlock`][3] and [`configure`][4] -functions. This allows you to control *what* to highlight and *when*. - -Here’s an equivalent way to calling [`initHighlightingOnLoad`][1] using -jQuery: - -```javascript -$(document).ready(function() { - $('pre code').each(function(i, block) { - hljs.highlightBlock(block); - }); -}); -``` - -You can use any tags instead of `
    ` to mark up your code. If
    -you don't use a container that preserve line breaks you will need to
    -configure highlight.js to use the `
    ` tag: - -```javascript -hljs.configure({useBR: true}); - -$('div.code').each(function(i, block) { - hljs.highlightBlock(block); -}); -``` - -For other options refer to the documentation for [`configure`][4]. - - -## Web Workers - -You can run highlighting inside a web worker to avoid freezing the browser -window while dealing with very big chunks of code. - -In your main script: - -```javascript -addEventListener('load', function() { - var code = document.querySelector('#code'); - var worker = new Worker('worker.js'); - worker.onmessage = function(event) { code.innerHTML = event.data; } - worker.postMessage(code.textContent); -}) -``` - -In worker.js: - -```javascript -onmessage = function(event) { - importScripts('/highlight.pack.js'); - var result = self.hljs.highlightAuto(event.data); - postMessage(result.value); -} -``` - - -## Getting the Library - -You can get highlight.js as a hosted, or custom-build, browser script or -as a server module. Right out of the box the browser script supports -both AMD and CommonJS, so if you wish you can use RequireJS or -Browserify without having to build from source. The server module also -works perfectly fine with Browserify, but there is the option to use a -build specific to browsers rather than something meant for a server. -Head over to the [download page][5] for all the options. - -**Don't link to GitHub directly.** The library is not supposed to work straight -from the source, it requires building. If none of the pre-packaged options -work for you refer to the [building documentation][6]. - -**The CDN-hosted package doesn't have all the languages.** Otherwise it'd be -too big. If you don't see the language you need in the ["Common" section][5], -it can be added manually: - -```html - -``` - -**On Almond.** You need to use the optimizer to give the module a name. For -example: - -``` -r.js -o name=hljs paths.hljs=/path/to/highlight out=highlight.js -``` - - -## License - -Highlight.js is released under the BSD License. See [LICENSE][7] file -for details. - -## Links - -The official site for the library is at . - -Further in-depth documentation for the API and other topics is at -. - -Authors and contributors are listed in the [AUTHORS.en.txt][8] file. - -[1]: http://highlightjs.readthedocs.io/en/latest/api.html#inithighlightingonload -[2]: http://highlightjs.readthedocs.io/en/latest/css-classes-reference.html -[3]: http://highlightjs.readthedocs.io/en/latest/api.html#highlightblock-block -[4]: http://highlightjs.readthedocs.io/en/latest/api.html#configure-options -[5]: https://highlightjs.org/download/ -[6]: http://highlightjs.readthedocs.io/en/latest/building-testing.html -[7]: https://github.com/isagalaev/highlight.js/blob/master/LICENSE -[8]: https://github.com/isagalaev/highlight.js/blob/master/AUTHORS.en.txt diff --git a/src/utils/highlightjs/README.ru.md b/src/utils/highlightjs/README.ru.md deleted file mode 100644 index ac481d07..00000000 --- a/src/utils/highlightjs/README.ru.md +++ /dev/null @@ -1,142 +0,0 @@ -# Highlight.js - -Highlight.js — это инструмент для подсветки синтаксиса, написанный на JavaScript. Он работает -и в браузере, и на сервере. Он работает с практически любой HTML разметкой, не -зависит от каких-либо фреймворков и умеет автоматически определять язык. - - -## Начало работы - -Минимум, что нужно сделать для использования highlight.js на веб-странице — это -подключить библиотеку, CSS-стили и вызывать [`initHighlightingOnLoad`][1]: - -```html - - - -``` - -Библиотека найдёт и раскрасит код внутри тегов `
    `, попытавшись
    -автоматически определить язык. Когда автоопределение не срабатывает, можно явно
    -указать язык в атрибуте class:
    -
    -```html
    -
    ...
    -``` - -Список поддерживаемых классов языков доступен в [справочнике по классам][2]. -Класс также можно предварить префиксами `language-` или `lang-`. - -Чтобы отключить подсветку для какого-то блока, используйте класс `nohighlight`: - -```html -
    ...
    -``` - -## Инициализация вручную - -Чтобы иметь чуть больше контроля за инициализацией подсветки, вы можете -использовать функции [`highlightBlock`][3] и [`configure`][4]. Таким образом -можно управлять тем, *что* и *когда* подсвечивать. - -Вот пример инициализации, эквивалентной вызову [`initHighlightingOnLoad`][1], но -с использованием jQuery: - -```javascript -$(document).ready(function() { - $('pre code').each(function(i, block) { - hljs.highlightBlock(block); - }); -}); -``` - -Вы можете использовать любые теги разметки вместо `
    `. Если
    -используете контейнер, не сохраняющий переводы строк, вам нужно сказать
    -highlight.js использовать для них тег `
    `: - -```javascript -hljs.configure({useBR: true}); - -$('div.code').each(function(i, block) { - hljs.highlightBlock(block); -}); -``` - -Другие опции можно найти в документации функции [`configure`][4]. - - -## Web Workers - -Подсветку можно запустить внутри web worker'а, чтобы окно -браузера не подтормаживало при работе с большими кусками кода. - -В основном скрипте: - -```javascript -addEventListener('load', function() { - var code = document.querySelector('#code'); - var worker = new Worker('worker.js'); - worker.onmessage = function(event) { code.innerHTML = event.data; } - worker.postMessage(code.textContent); -}) -``` - -В worker.js: - -```javascript -onmessage = function(event) { - importScripts('/highlight.pack.js'); - var result = self.hljs.highlightAuto(event.data); - postMessage(result.value); -} -``` - - -## Установка библиотеки - -Highlight.js можно использовать в браузере прямо с CDN хостинга или скачать -индивидуальную сборку, а также установив модуль на сервере. На -[странице загрузки][5] подробно описаны все варианты. - -**Не подключайте GitHub напрямую.** Библиотека не предназначена для -использования в виде исходного кода, а требует отдельной сборки. Если вам не -подходит ни один из готовых вариантов, читайте [документацию по сборке][6]. - -**Файл на CDN содержит не все языки.** Иначе он будет слишком большого размера. -Если нужного вам языка нет в [категории "Common"][5], можно дообавить его -вручную: - -```html - -``` - -**Про Almond.** Нужно задать имя модуля в оптимизаторе, например: - -``` -r.js -o name=hljs paths.hljs=/path/to/highlight out=highlight.js -``` - - -## Лицензия - -Highlight.js распространяется под лицензией BSD. Подробнее читайте файл -[LICENSE][7]. - - -## Ссылки - -Официальный сайт билиотеки расположен по адресу . - -Более подробная документация по API и другим темам расположена на -. - -Авторы и контрибьюторы перечислены в файле [AUTHORS.ru.txt][8] file. - -[1]: http://highlightjs.readthedocs.io/en/latest/api.html#inithighlightingonload -[2]: http://highlightjs.readthedocs.io/en/latest/css-classes-reference.html -[3]: http://highlightjs.readthedocs.io/en/latest/api.html#highlightblock-block -[4]: http://highlightjs.readthedocs.io/en/latest/api.html#configure-options -[5]: https://highlightjs.org/download/ -[6]: http://highlightjs.readthedocs.io/en/latest/building-testing.html -[7]: https://github.com/isagalaev/highlight.js/blob/master/LICENSE -[8]: https://github.com/isagalaev/highlight.js/blob/master/AUTHORS.ru.txt diff --git a/src/utils/highlightjs/highlight.pack.js b/src/utils/highlightjs/highlight.pack.js deleted file mode 100644 index f933a3e9..00000000 --- a/src/utils/highlightjs/highlight.pack.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */ -!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){s+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"
    ":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
    ",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("hy",function(e){var t={"builtin-name":"!= % %= & &= * ** **= *= *map + += , --build-class-- --import-- -= . / // //= /= < << <<= <= = > >= >> >>= @ @= ^ ^= abs accumulate all and any ap-compose ap-dotimes ap-each ap-each-while ap-filter ap-first ap-if ap-last ap-map ap-map-when ap-pipe ap-reduce ap-reject apply as-> ascii assert assoc bin break butlast callable calling-module-name car case cdr chain chr coll? combinations compile compress cond cons cons? continue count curry cut cycle dec def default-method defclass defmacro defmacro-alias defmacro/g! defmain defmethod defmulti defn defn-alias defnc defnr defreader defseq del delattr delete-route dict-comp dir disassemble dispatch-reader-macro distinct divmod do doto drop drop-last drop-while empty? end-sequence eval eval-and-compile eval-when-compile even? every? except exec filter first flatten float? fn fnc fnr for for* format fraction genexpr gensym get getattr global globals group-by hasattr hash hex id identity if if* if-not if-python2 import in inc input instance? integer integer-char? integer? interleave interpose is is-coll is-cons is-empty is-even is-every is-float is-instance is-integer is-integer-char is-iterable is-iterator is-keyword is-neg is-none is-not is-numeric is-odd is-pos is-string is-symbol is-zero isinstance islice issubclass iter iterable? iterate iterator? keyword keyword? lambda last len let lif lif-not list* list-comp locals loop macro-error macroexpand macroexpand-1 macroexpand-all map max merge-with method-decorator min multi-decorator multicombinations name neg? next none? nonlocal not not-in not? nth numeric? oct odd? open or ord partition permutations pos? post-route postwalk pow prewalk print product profile/calls profile/cpu put-route quasiquote quote raise range read read-str recursive-replace reduce remove repeat repeatedly repr require rest round route route-with-methods rwm second seq set-comp setattr setv some sorted string string? sum switch symbol? take take-nth take-while tee try unless unquote unquote-splicing vars walk when while with with* with-decorator with-gensyms xi xor yield yield-from zero? zip zip-longest | |= ~"},i="a-zA-Z_\\-!.?+*=<>&#'",a="["+i+"]["+i+"0-9/;:]*",r="[-+]?\\d+(\\.\\d+)?",o={cN:"meta",b:"^#!",e:"$"},s={b:a,r:0},n={cN:"number",b:r,r:0},l=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b([Tt]rue|[Ff]alse|nil|None)\b/},p={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+a},u=e.C("\\^\\{","\\}"),f={cN:"symbol",b:"[:]{1,2}"+a},h={b:"\\(",e:"\\)"},b={eW:!0,r:0},g={k:t,l:a,cN:"name",b:a,starts:b},y=[h,l,m,u,c,f,p,n,d,s];return h.c=[e.C("comment",""),g,b],b.c=y,p.c=y,{aliases:["hylang"],i:/\S/,c:[o,h,l,m,u,c,f,p,n,d]}});hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],o=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=o,s.c=o,{aliases:["pl","pm"],l:/[\w\.]+/,k:t,c:o}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("htmlbars",function(e){var a="action collection component concat debugger each each-in else get hash if input link-to loc log mut outlet partial query-params render textarea unbound unless with yield view",t={i:/\}\}/,b:/[a-zA-Z0-9_]+=/,rB:!0,r:0,c:[{cN:"attr",b:/[a-zA-Z0-9_]+/}]},i=({i:/\}\}/,b:/\)/,e:/\)/,c:[{b:/[a-zA-Z\.\-]+/,k:{built_in:a},starts:{eW:!0,r:0,c:[e.QSM]}}]},{eW:!0,r:0,k:{keyword:"as",built_in:a},c:[e.QSM,t,e.NM]});return{cI:!0,sL:"xml",c:[e.C("{{!(--)?","(--)?}}"),{cN:"template-tag",b:/\{\{[#\/]/,e:/\}\}/,c:[{cN:"name",b:/[a-zA-Z\.\-]+/,k:{"builtin-name":a},starts:i}]},{cN:"template-variable",b:/\{\{[a-zA-Z][a-zA-Z\-]+/,e:/\}\}/,k:{keyword:"as",built_in:a},c:[e.QSM]}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("erlang",function(e){var r="[a-z'][a-zA-Z0-9_']*",c="("+r+":"+r+"|"+r+")",b={keyword:"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor",literal:"false true"},i=e.C("%","$"),n={cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},a={b:"fun\\s+"+r+"/\\d+"},d={b:c+"\\(",e:"\\)",rB:!0,r:0,c:[{b:c,r:0},{b:"\\(",e:"\\)",eW:!0,rE:!0,r:0}]},o={b:"{",e:"}",r:0},t={b:"\\b_([A-Z][A-Za-z0-9_]*)?",r:0},f={b:"[A-Z][a-zA-Z0-9_]*",r:0},l={b:"#"+e.UIR,r:0,rB:!0,c:[{b:"#"+e.UIR,r:0},{b:"{",e:"}",r:0}]},s={bK:"fun receive if try case",e:"end",k:b};s.c=[i,a,e.inherit(e.ASM,{cN:""}),s,d,e.QSM,n,o,t,f,l];var u=[i,a,s,d,e.QSM,n,o,t,f,l];d.c[1].c=u,o.c=u,l.c[1].c=u;var h={cN:"params",b:"\\(",e:"\\)",c:u};return{aliases:["erl"],k:b,i:"(",rB:!0,i:"\\(|#|//|/\\*|\\\\|:|;",c:[h,e.inherit(e.TM,{b:r})],starts:{e:";|\\.",k:b,c:u}},i,{b:"^-",e:"\\.",r:0,eE:!0,rB:!0,l:"-"+e.IR,k:"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec",c:[h]},n,e.QSM,l,t,f,o,{b:/\.$/}]}});hljs.registerLanguage("haxe",function(e){var t="Int Float String Bool Dynamic Void Array ";return{aliases:["hx"],k:{keyword:"break case cast catch continue default do dynamic else enum extern for function here if import in inline never new override package private get set public return static super switch this throw trace try typedef untyped using var while "+t,built_in:"trace this",literal:"true false null _"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"},{cN:"subst",b:"\\$",e:"\\W}"}]},e.QSM,e.CLCM,e.CBCM,e.CNM,{cN:"meta",b:"@:",e:"$"},{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elseif end error"}},{cN:"type",b:":[ ]*",e:"[^A-Za-z0-9_ \\->]",eB:!0,eE:!0,r:0},{cN:"type",b:":[ ]*",e:"\\W",eB:!0,eE:!0},{cN:"type",b:"new *",e:"\\W",eB:!0,eE:!0},{cN:"class",bK:"enum",e:"\\{",c:[e.TM]},{cN:"class",bK:"abstract",e:"[\\{$]",c:[{cN:"type",b:"\\(",e:"\\)",eB:!0,eE:!0},{cN:"type",b:"from +",e:"\\W",eB:!0,eE:!0},{cN:"type",b:"to +",e:"\\W",eB:!0,eE:!0},e.TM],k:{keyword:"abstract from to"}},{cN:"class",b:"\\b(class|interface) +",e:"[\\{$]",eE:!0,k:"class interface",c:[{cN:"keyword",b:"\\b(extends|implements) +",k:"extends implements",c:[{cN:"type",b:e.IR,r:0}]},e.TM]},{cN:"function",bK:"function",e:"\\(",eE:!0,i:"\\S",c:[e.TM]}],i:/<\//}});hljs.registerLanguage("gcode",function(N){var e="[A-Z_][A-Z0-9_.]*",c="\\%",E="IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT EQ LT GT NE GE LE OR XOR",i={cN:"meta",b:"([O])([0-9]+)"},n=[N.CLCM,N.CBCM,N.C(/\(/,/\)/),N.inherit(N.CNM,{b:"([-+]?([0-9]*\\.?[0-9]+\\.?))|"+N.CNR}),N.inherit(N.ASM,{i:null}),N.inherit(N.QSM,{i:null}),{cN:"name",b:"([G])([0-9]+\\.?[0-9]?)"},{cN:"name",b:"([M])([0-9]+\\.?[0-9]?)"},{cN:"attr",b:"(VC|VS|#)",e:"(\\d+)"},{cN:"attr",b:"(VZOFX|VZOFY|VZOFZ)"},{cN:"built_in",b:"(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\[)",e:"([-+]?([0-9]*\\.?[0-9]+\\.?))(\\])"},{cN:"symbol",v:[{b:"N",e:"\\d+",i:"\\W"}]}];return{aliases:["nc"],cI:!0,l:e,k:E,c:[{cN:"meta",b:c},i].concat(n)}});hljs.registerLanguage("mizar",function(e){return{k:"environ vocabularies notations constructors definitions registrations theorems schemes requirements begin end definition registration cluster existence pred func defpred deffunc theorem proof let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from be being by means equals implies iff redefine define now not or attr is mode suppose per cases set thesis contradiction scheme reserve struct correctness compatibility coherence symmetry assymetry reflexivity irreflexivity connectedness uniqueness commutativity idempotence involutiveness projectivity",c:[e.C("::","$")]}});hljs.registerLanguage("rust",function(e){var t="([ui](8|16|32|64|128|size)|f(32|64))?",r="alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self Self sizeof static struct super trait true type typeof unsafe unsized use virtual while where yield move default",n="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{aliases:["rs"],k:{keyword:r,literal:"true false Some None Ok Err",built_in:n},l:e.IR+"!?",i:""}]}});hljs.registerLanguage("ebnf",function(a){var e=a.C(/\(\*/,/\*\)/),t={cN:"attribute",b:/^[ ]*[a-zA-Z][a-zA-Z-]*([\s-]+[a-zA-Z][a-zA-Z]*)*/},r={cN:"meta",b:/\?.*\?/},b={b:/=/,e:/;/,c:[e,r,a.ASM,a.QSM]};return{i:/\S/,c:[e,t,b]}});hljs.registerLanguage("ldif",function(e){return{c:[{cN:"attribute",b:"^dn",e:": ",eE:!0,starts:{e:"$",r:0},r:10},{cN:"attribute",b:"^\\w",e:": ",eE:!0,starts:{e:"$",r:0}},{cN:"literal",b:"^-",e:"$"},e.HCM]}});hljs.registerLanguage("swift",function(e){var i={keyword:"__COLUMN__ __FILE__ __FUNCTION__ __LINE__ as as! as? associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},t={cN:"type",b:"\\b[A-Z][\\wÀ-ʸ']*",r:0},n=e.C("/\\*","\\*/",{c:["self"]}),r={cN:"subst",b:/\\\(/,e:"\\)",k:i,c:[]},a={cN:"number",b:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",r:0},o=e.inherit(e.QSM,{c:[r,e.BE]});return r.c=[a],{k:i,c:[o,e.CLCM,n,t,a,{cN:"function",bK:"func",e:"{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{b://},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:i,c:["self",a,o,e.CBCM,{b:":"}],i:/["']/}],i:/\[|%/},{cN:"class",bK:"struct protocol class extension enum",k:i,e:"\\{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{cN:"meta",b:"(@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain)"},{bK:"import",e:/$/,c:[e.CLCM,n]}]}});hljs.registerLanguage("smali",function(t){var s=["add","and","cmp","cmpg","cmpl","const","div","double","float","goto","if","int","long","move","mul","neg","new","nop","not","or","rem","return","shl","shr","sput","sub","throw","ushr","xor"],e=["aget","aput","array","check","execute","fill","filled","goto/16","goto/32","iget","instance","invoke","iput","monitor","packed","sget","sparse"],r=["transient","constructor","abstract","final","synthetic","public","private","protected","static","bridge","system"];return{aliases:["smali"],c:[{cN:"string",b:'"',e:'"',r:0},t.C("#","$",{r:0}),{cN:"keyword",v:[{b:"\\s*\\.end\\s[a-zA-Z0-9]*"},{b:"^[ ]*\\.[a-zA-Z]*",r:0},{b:"\\s:[a-zA-Z_0-9]*",r:0},{b:"\\s("+r.join("|")+")"}]},{cN:"built_in",v:[{b:"\\s("+s.join("|")+")\\s"},{b:"\\s("+s.join("|")+")((\\-|/)[a-zA-Z0-9]+)+\\s",r:10},{b:"\\s("+e.join("|")+")((\\-|/)[a-zA-Z0-9]+)*\\s",r:10}]},{cN:"class",b:"L[^(;:\n]*;",r:0},{b:"[vp][0-9]+"}]}});hljs.registerLanguage("cos",function(e){var t={cN:"string",v:[{b:'"',e:'"',c:[{b:'""',r:0}]}]},r={cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)",r:0},s="property parameter class classmethod clientmethod extends as break catch close continue do d|0 else elseif for goto halt hang h|0 if job j|0 kill k|0 lock l|0 merge new open quit q|0 read r|0 return set s|0 tcommit throw trollback try tstart use view while write w|0 xecute x|0 zkill znspace zn ztrap zwrite zw zzdump zzwrite print zbreak zinsert zload zprint zremove zsave zzprint mv mvcall mvcrt mvdim mvprint zquit zsync ascii";return{cI:!0,aliases:["cos","cls"],k:s,c:[r,t,e.CLCM,e.CBCM,{cN:"comment",b:/;/,e:"$",r:0},{cN:"built_in",b:/(?:\$\$?|\.\.)\^?[a-zA-Z]+/},{cN:"built_in",b:/\$\$\$[a-zA-Z]+/},{cN:"built_in",b:/%[a-z]+(?:\.[a-z]+)*/},{cN:"symbol",b:/\^%?[a-zA-Z][\w]*/},{cN:"keyword",b:/##class|##super|#define|#dim/},{b:/&sql\(/,e:/\)/,eB:!0,eE:!0,sL:"sql"},{b:/&(js|jscript|javascript)/,eB:!0,eE:!0,sL:"javascript"},{b:/&html<\s*\s*>/,sL:"xml"}]}});hljs.registerLanguage("nix",function(e){var r={keyword:"rec with let in inherit assert if else then",literal:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},t={cN:"subst",b:/\$\{/,e:/}/,k:r},i={b:/[a-zA-Z0-9-_]+(\s*=)/,rB:!0,r:0,c:[{cN:"attr",b:/\S+/}]},s={cN:"string",c:[t],v:[{b:"''",e:"''"},{b:'"',e:'"'}]},a=[e.NM,e.HCM,e.CBCM,s,i];return t.c=a,{aliases:["nixos"],k:r,c:a}});hljs.registerLanguage("livescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger case default function var with then unless until loop of by when and or is isnt not it that otherwise from to til fallthrough super case default function var void const let enum export import native __hasProp __extends __slice __bind __indexOf",literal:"true false null undefined yes no on off it that void",built_in:"npm require console print module global window document"},s="[A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*",n=e.inherit(e.TM,{b:s}),i={cN:"subst",b:/#\{/,e:/}/,k:t},r={cN:"subst",b:/#[A-Za-z$_]/,e:/(?:\-[0-9A-Za-z$_]|[0-9A-Za-z$_])*/,k:t},c=[e.BNM,{cN:"number",b:"(\\b0[xX][a-fA-F0-9_]+)|(\\b\\d(\\d|_\\d)*(\\.(\\d(\\d|_\\d)*)?)?(_*[eE]([-+]\\d(_\\d|\\d)*)?)?[_a-z]*)",r:0,starts:{e:"(\\s*/)?",r:0}},{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,i,r]},{b:/"/,e:/"/,c:[e.BE,i,r]},{b:/\\/,e:/(\s|$)/,eE:!0}]},{cN:"regexp",v:[{b:"//",e:"//[gim]*",c:[i,e.HCM]},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+s},{b:"``",e:"``",eB:!0,eE:!0,sL:"javascript"}];i.c=c;var a={cN:"params",b:"\\(",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(c)}]};return{aliases:["ls"],k:t,i:/\/\*/,c:c.concat([e.C("\\/\\*","\\*\\/"),e.HCM,{cN:"function",c:[n,a],rB:!0,v:[{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B\\->\\*?",e:"\\->\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?!?(\\(.*\\))?\\s*\\B[-~]{1,2}>\\*?",e:"[-~]{1,2}>\\*?"},{b:"("+s+"\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B!?[-~]{1,2}>\\*?",e:"!?[-~]{1,2}>\\*?"}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[n]},n]},{b:s+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("hsp",function(e){return{cI:!0,l:/[\w\._]+/,k:"goto gosub return break repeat loop continue wait await dim sdim foreach dimtype dup dupptr end stop newmod delmod mref run exgoto on mcall assert logmes newlab resume yield onexit onerror onkey onclick oncmd exist delete mkdir chdir dirlist bload bsave bcopy memfile if else poke wpoke lpoke getstr chdpm memexpand memcpy memset notesel noteadd notedel noteload notesave randomize noteunsel noteget split strrep setease button chgdisp exec dialog mmload mmplay mmstop mci pset pget syscolor mes print title pos circle cls font sysfont objsize picload color palcolor palette redraw width gsel gcopy gzoom gmode bmpsave hsvcolor getkey listbox chkbox combox input mesbox buffer screen bgscr mouse objsel groll line clrobj boxf objprm objmode stick grect grotate gsquare gradf objimage objskip objenable celload celdiv celput newcom querycom delcom cnvstow comres axobj winobj sendmsg comevent comevarg sarrayconv callfunc cnvwtos comevdisp libptr system hspstat hspver stat cnt err strsize looplev sublev iparam wparam lparam refstr refdval int rnd strlen length length2 length3 length4 vartype gettime peek wpeek lpeek varptr varuse noteinfo instr abs limit getease str strmid strf getpath strtrim sin cos tan atan sqrt double absf expf logf limitf powf geteasef mousex mousey mousew hwnd hinstance hdc ginfo objinfo dirinfo sysinfo thismod __hspver__ __hsp30__ __date__ __time__ __line__ __file__ _debug __hspdef__ and or xor not screen_normal screen_palette screen_hide screen_fixedsize screen_tool screen_frame gmode_gdi gmode_mem gmode_rgb0 gmode_alpha gmode_rgb0alpha gmode_add gmode_sub gmode_pixela ginfo_mx ginfo_my ginfo_act ginfo_sel ginfo_wx1 ginfo_wy1 ginfo_wx2 ginfo_wy2 ginfo_vx ginfo_vy ginfo_sizex ginfo_sizey ginfo_winx ginfo_winy ginfo_mesx ginfo_mesy ginfo_r ginfo_g ginfo_b ginfo_paluse ginfo_dispx ginfo_dispy ginfo_cx ginfo_cy ginfo_intid ginfo_newid ginfo_sx ginfo_sy objinfo_mode objinfo_bmscr objinfo_hwnd notemax notesize dir_cur dir_exe dir_win dir_sys dir_cmdline dir_desktop dir_mydoc dir_tv font_normal font_bold font_italic font_underline font_strikeout font_antialias objmode_normal objmode_guifont objmode_usefont gsquare_grad msgothic msmincho do until while wend for next _break _continue switch case default swbreak swend ddim ldim alloc m_pi rad2deg deg2rad ease_linear ease_quad_in ease_quad_out ease_quad_inout ease_cubic_in ease_cubic_out ease_cubic_inout ease_quartic_in ease_quartic_out ease_quartic_inout ease_bounce_in ease_bounce_out ease_bounce_inout ease_shake_in ease_shake_out ease_shake_inout ease_loop",c:[e.CLCM,e.CBCM,e.QSM,e.ASM,{cN:"string",b:'{"',e:'"}',c:[e.BE]},e.C(";","$",{r:0}),{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"addion cfunc cmd cmpopt comfunc const defcfunc deffunc define else endif enum epack func global if ifdef ifndef include modcfunc modfunc modinit modterm module pack packopt regcmd runtime undef usecom uselib"},c:[e.inherit(e.QSM,{cN:"meta-string"}),e.NM,e.CNM,e.CLCM,e.CBCM]},{cN:"symbol",b:"^\\*(\\w+|@)"},e.NM,e.CNM]}});hljs.registerLanguage("lisp",function(b){var e="[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*",c="\\|[^]*?\\|",r="(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|\\-)?\\d+)?",a={cN:"meta",b:"^#!",e:"$"},l={cN:"literal",b:"\\b(t{1}|nil)\\b"},n={cN:"number",v:[{b:r,r:0},{b:"#(b|B)[0-1]+(/[0-1]+)?"},{b:"#(o|O)[0-7]+(/[0-7]+)?"},{b:"#(x|X)[0-9a-fA-F]+(/[0-9a-fA-F]+)?"},{b:"#(c|C)\\("+r+" +"+r,e:"\\)"}]},i=b.inherit(b.QSM,{i:null}),t=b.C(";","$",{r:0}),s={b:"\\*",e:"\\*"},u={cN:"symbol",b:"[:&]"+e},d={b:e,r:0},f={b:c},m={b:"\\(",e:"\\)",c:["self",l,i,n,d]},o={c:[n,i,s,u,m,d],v:[{b:"['`]\\(",e:"\\)"},{b:"\\(quote ",e:"\\)",k:{name:"quote"}},{b:"'"+c}]},v={v:[{b:"'"+e},{b:"#'"+e+"(::"+e+")*"}]},N={b:"\\(\\s*",e:"\\)"},A={eW:!0,r:0};return N.c=[{cN:"name",v:[{b:e},{b:c}]},A],A.c=[o,v,N,l,n,i,t,s,u,f,d],{i:/\S/,c:[n,a,l,i,t,o,v,N,d]}});hljs.registerLanguage("powershell",function(e){var t={b:"`[\\s\\S]",r:0},o={cN:"variable",v:[{b:/\$[\w\d][\w\d_:]*/}]},r={cN:"literal",b:/\$(null|true|false)\b/},n={cN:"string",v:[{b:/"/,e:/"/},{b:/@"/,e:/^"@/}],c:[t,o,{cN:"variable",b:/\$[A-z]/,e:/[^A-z]/}]},a={cN:"string",v:[{b:/'/,e:/'/},{b:/@'/,e:/^'@/}]},i={cN:"doctag",v:[{b:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{b:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]},s=e.inherit(e.C(null,null),{v:[{b:/#/,e:/$/},{b:/<#/,e:/#>/}],c:[i]});return{aliases:["ps"],l:/-?[A-z\.\-]+/,cI:!0,k:{keyword:"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch",built_in:"Add-Computer Add-Content Add-History Add-JobTrigger Add-Member Add-PSSnapin Add-Type Checkpoint-Computer Clear-Content Clear-EventLog Clear-History Clear-Host Clear-Item Clear-ItemProperty Clear-Variable Compare-Object Complete-Transaction Connect-PSSession Connect-WSMan Convert-Path ConvertFrom-Csv ConvertFrom-Json ConvertFrom-SecureString ConvertFrom-StringData ConvertTo-Csv ConvertTo-Html ConvertTo-Json ConvertTo-SecureString ConvertTo-Xml Copy-Item Copy-ItemProperty Debug-Process Disable-ComputerRestore Disable-JobTrigger Disable-PSBreakpoint Disable-PSRemoting Disable-PSSessionConfiguration Disable-WSManCredSSP Disconnect-PSSession Disconnect-WSMan Disable-ScheduledJob Enable-ComputerRestore Enable-JobTrigger Enable-PSBreakpoint Enable-PSRemoting Enable-PSSessionConfiguration Enable-ScheduledJob Enable-WSManCredSSP Enter-PSSession Exit-PSSession Export-Alias Export-Clixml Export-Console Export-Counter Export-Csv Export-FormatData Export-ModuleMember Export-PSSession ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-ComputerRestorePoint Get-Content Get-ControlPanelItem Get-Counter Get-Credential Get-Culture Get-Date Get-Event Get-EventLog Get-EventSubscriber Get-ExecutionPolicy Get-FormatData Get-Host Get-HotFix Get-Help Get-History Get-IseSnippet Get-Item Get-ItemProperty Get-Job Get-JobTrigger Get-Location Get-Member Get-Module Get-PfxCertificate Get-Process Get-PSBreakpoint Get-PSCallStack Get-PSDrive Get-PSProvider Get-PSSession Get-PSSessionConfiguration Get-PSSnapin Get-Random Get-ScheduledJob Get-ScheduledJobOption Get-Service Get-TraceSource Get-Transaction Get-TypeData Get-UICulture Get-Unique Get-Variable Get-Verb Get-WinEvent Get-WmiObject Get-WSManCredSSP Get-WSManInstance Group-Object Import-Alias Import-Clixml Import-Counter Import-Csv Import-IseSnippet Import-LocalizedData Import-PSSession Import-Module Invoke-AsWorkflow Invoke-Command Invoke-Expression Invoke-History Invoke-Item Invoke-RestMethod Invoke-WebRequest Invoke-WmiMethod Invoke-WSManAction Join-Path Limit-EventLog Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Event New-EventLog New-IseSnippet New-Item New-ItemProperty New-JobTrigger New-Object New-Module New-ModuleManifest New-PSDrive New-PSSession New-PSSessionConfigurationFile New-PSSessionOption New-PSTransportOption New-PSWorkflowExecutionOption New-PSWorkflowSession New-ScheduledJobOption New-Service New-TimeSpan New-Variable New-WebServiceProxy New-WinEvent New-WSManInstance New-WSManSessionOption Out-Default Out-File Out-GridView Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Receive-Job Register-EngineEvent Register-ObjectEvent Register-PSSessionConfiguration Register-ScheduledJob Register-WmiEvent Remove-Computer Remove-Event Remove-EventLog Remove-Item Remove-ItemProperty Remove-Job Remove-JobTrigger Remove-Module Remove-PSBreakpoint Remove-PSDrive Remove-PSSession Remove-PSSnapin Remove-TypeData Remove-Variable Remove-WmiObject Remove-WSManInstance Rename-Computer Rename-Item Rename-ItemProperty Reset-ComputerMachinePassword Resolve-Path Restart-Computer Restart-Service Restore-Computer Resume-Job Resume-Service Save-Help Select-Object Select-String Select-Xml Send-MailMessage Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-JobTrigger Set-Location Set-PSBreakpoint Set-PSDebug Set-PSSessionConfiguration Set-ScheduledJob Set-ScheduledJobOption Set-Service Set-StrictMode Set-TraceSource Set-Variable Set-WmiInstance Set-WSManInstance Set-WSManQuickConfig Show-Command Show-ControlPanelItem Show-EventLog Sort-Object Split-Path Start-Job Start-Process Start-Service Start-Sleep Start-Transaction Start-Transcript Stop-Computer Stop-Job Stop-Process Stop-Service Stop-Transcript Suspend-Job Suspend-Service Tee-Object Test-ComputerSecureChannel Test-Connection Test-ModuleManifest Test-Path Test-PSSessionConfigurationFile Trace-Command Unblock-File Undo-Transaction Unregister-Event Unregister-PSSessionConfiguration Unregister-ScheduledJob Update-FormatData Update-Help Update-List Update-TypeData Use-Transaction Wait-Event Wait-Job Wait-Process Where-Object Write-Debug Write-Error Write-EventLog Write-Host Write-Output Write-Progress Write-Verbose Write-Warning Add-MDTPersistentDrive Disable-MDTMonitorService Enable-MDTMonitorService Get-MDTDeploymentShareStatistics Get-MDTMonitorData Get-MDTOperatingSystemCatalog Get-MDTPersistentDrive Import-MDTApplication Import-MDTDriver Import-MDTOperatingSystem Import-MDTPackage Import-MDTTaskSequence New-MDTDatabase Remove-MDTMonitorData Remove-MDTPersistentDrive Restore-MDTPersistentDrive Set-MDTMonitorData Test-MDTDeploymentShare Test-MDTMonitorData Update-MDTDatabaseSchema Update-MDTDeploymentShare Update-MDTLinkedDS Update-MDTMedia Update-MDTMedia Add-VamtProductKey Export-VamtData Find-VamtManagedMachine Get-VamtConfirmationId Get-VamtProduct Get-VamtProductKey Import-VamtData Initialize-VamtData Install-VamtConfirmationId Install-VamtProductActivation Install-VamtProductKey Update-VamtProduct",nomarkup:"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace"},c:[t,e.NM,n,a,r,o,s]}});hljs.registerLanguage("inform7",function(e){var r="\\[",o="\\]";return{aliases:["i7"],cI:!0,k:{keyword:"thing room person man woman animal container supporter backdrop door scenery open closed locked inside gender is are say understand kind of rule"},c:[{cN:"string",b:'"',e:'"',r:0,c:[{cN:"subst",b:r,e:o}]},{cN:"section",b:/^(Volume|Book|Part|Chapter|Section|Table)\b/,e:"$"},{b:/^(Check|Carry out|Report|Instead of|To|Rule|When|Before|After)\b/,e:":",c:[{b:"\\(This",e:"\\)"}]},{cN:"comment",b:r,e:o,c:["self"]}]}});hljs.registerLanguage("subunit",function(s){var r={cN:"string",b:"\\[\n(multipart)?",e:"\\]\n"},t={cN:"string",b:"\\d{4}-\\d{2}-\\d{2}(\\s+)\\d{2}:\\d{2}:\\d{2}.\\d+Z"},e={cN:"string",b:"(\\+|-)\\d+"},c={cN:"keyword",r:10,v:[{b:"^(test|testing|success|successful|failure|error|skip|xfail|uxsuccess)(:?)\\s+(test)?"},{b:"^progress(:?)(\\s+)?(pop|push)?"},{b:"^tags:"},{b:"^time:"}]};return{cI:!0,c:[r,t,e,c]}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[{b:'(u8?|U)?L?"',e:'"',i:"\\n",c:[t.BE]},{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},i={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:/<[^\n>]*>/,e:/$/,i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e]},t.CLCM,t.CBCM,i]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b://,c:["self"]},t.TM]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage("arduino",function(e){var t=e.getLanguage("cpp").exports;return{k:{keyword:"boolean byte word string String array "+t.k.keyword,built_in:"setup loop while catch for if do goto try switch case else default break continue return KeyboardController MouseController SoftwareSerial EthernetServer EthernetClient LiquidCrystal RobotControl GSMVoiceCall EthernetUDP EsploraTFT HttpClient RobotMotor WiFiClient GSMScanner FileSystem Scheduler GSMServer YunClient YunServer IPAddress GSMClient GSMModem Keyboard Ethernet Console GSMBand Esplora Stepper Process WiFiUDP GSM_SMS Mailbox USBHost Firmata PImage Client Server GSMPIN FileIO Bridge Serial EEPROM Stream Mouse Audio Servo File Task GPRS WiFi Wire TFT GSM SPI SD runShellCommandAsynchronously analogWriteResolution retrieveCallingNumber printFirmwareVersion analogReadResolution sendDigitalPortPair noListenOnLocalhost readJoystickButton setFirmwareVersion readJoystickSwitch scrollDisplayRight getVoiceCallStatus scrollDisplayLeft writeMicroseconds delayMicroseconds beginTransmission getSignalStrength runAsynchronously getAsynchronously listenOnLocalhost getCurrentCarrier readAccelerometer messageAvailable sendDigitalPorts lineFollowConfig countryNameWrite runShellCommand readStringUntil rewindDirectory readTemperature setClockDivider readLightSensor endTransmission analogReference detachInterrupt countryNameRead attachInterrupt encryptionType readBytesUntil robotNameWrite readMicrophone robotNameRead cityNameWrite userNameWrite readJoystickY readJoystickX mouseReleased openNextFile scanNetworks noInterrupts digitalWrite beginSpeaker mousePressed isActionDone mouseDragged displayLogos noAutoscroll addParameter remoteNumber getModifiers keyboardRead userNameRead waitContinue processInput parseCommand printVersion readNetworks writeMessage blinkVersion cityNameRead readMessage setDataMode parsePacket isListening setBitOrder beginPacket isDirectory motorsWrite drawCompass digitalRead clearScreen serialEvent rightToLeft setTextSize leftToRight requestFrom keyReleased compassRead analogWrite interrupts WiFiServer disconnect playMelody parseFloat autoscroll getPINUsed setPINUsed setTimeout sendAnalog readSlider analogRead beginWrite createChar motorsStop keyPressed tempoWrite readButton subnetMask debugPrint macAddress writeGreen randomSeed attachGPRS readString sendString remotePort releaseAll mouseMoved background getXChange getYChange answerCall getResult voiceCall endPacket constrain getSocket writeJSON getButton available connected findUntil readBytes exitValue readGreen writeBlue startLoop IPAddress isPressed sendSysex pauseMode gatewayIP setCursor getOemKey tuneWrite noDisplay loadImage switchPIN onRequest onReceive changePIN playFile noBuffer parseInt overflow checkPIN knobRead beginTFT bitClear updateIR bitWrite position writeRGB highByte writeRed setSpeed readBlue noStroke remoteIP transfer shutdown hangCall beginSMS endWrite attached maintain noCursor checkReg checkPUK shiftOut isValid shiftIn pulseIn connect println localIP pinMode getIMEI display noBlink process getBand running beginSD drawBMP lowByte setBand release bitRead prepare pointTo readRed setMode noFill remove listen stroke detach attach noTone exists buffer height bitSet circle config cursor random IRread setDNS endSMS getKey micros millis begin print write ready flush width isPIN blink clear press mkdir rmdir close point yield image BSSID click delay read text move peek beep rect line open seek fill size turn stop home find step tone sqrt RSSI SSID end bit tan cos sin pow map abs max min get run put",literal:"DIGITAL_MESSAGE FIRMATA_STRING ANALOG_MESSAGE REPORT_DIGITAL REPORT_ANALOG INPUT_PULLUP SET_PIN_MODE INTERNAL2V56 SYSTEM_RESET LED_BUILTIN INTERNAL1V1 SYSEX_START INTERNAL EXTERNAL DEFAULT OUTPUT INPUT HIGH LOW"},c:[t.preprocessor,e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM]}});hljs.registerLanguage("scilab",function(e){var s=[e.CNM,{cN:"string",b:"'|\"",e:"'|\"",c:[e.BE,{b:"''"}]}];return{aliases:["sci"],l:/%?\w+/,k:{keyword:"abort break case clear catch continue do elseif else endfunction end for function global if pause return resume select try then while",literal:"%f %F %t %T %pi %eps %inf %nan %e %i %z %s",built_in:"abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp error exec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isempty isinfisnan isvector lasterror length load linspace list listfiles log10 log2 log max min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand real round sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tan type typename warning zeros matrix"},i:'("|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function",e:"$",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)"}]},{b:"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)",e:"",r:0},{b:"\\[",e:"\\]'*[\\.']*",r:0,c:s},e.C("//","$")].concat(s)}});hljs.registerLanguage("lasso",function(e){var r="[a-zA-Z_][\\w.]*",a="<\\?(lasso(script)?|=)",t="\\]|\\?>",n={literal:"true false none minimal full all void and or not bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft",built_in:"array date decimal duration integer map pair string tag xml null boolean bytes keyword list locale queue set stack staticarray local var variable global data self inherited currentcapture givenblock",keyword:"cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else fail_if fail_ifnot fail if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require returnhome skip split_thread sum take thread to trait type where with yield yieldhome"},i=e.C("",{r:0}),s={cN:"meta",b:"\\[noprocess\\]",starts:{e:"\\[/noprocess\\]",rE:!0,c:[i]}},l={cN:"meta",b:"\\[/noprocess|"+a},o={cN:"symbol",b:"'"+r+"'"},c=[e.CLCM,e.CBCM,e.inherit(e.CNM,{b:e.CNR+"|(-?infinity|NaN)\\b"}),e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"`",e:"`"},{v:[{b:"[#$]"+r},{b:"#",e:"\\d+",i:"\\W"}]},{cN:"type",b:"::\\s*",e:r,i:"\\W"},{cN:"params",v:[{b:"-(?!infinity)"+r,r:0},{b:"(\\.\\.\\.)"}]},{b:/(->|\.)\s*/,r:0,c:[o]},{cN:"class",bK:"define",rE:!0,e:"\\(|=>",c:[e.inherit(e.TM,{b:r+"(=(?!>))?|[-+*/%](?!>)"})]}];return{aliases:["ls","lassoscript"],cI:!0,l:r+"|&[lg]t;",k:n,c:[{cN:"meta",b:t,r:0,starts:{e:"\\[|"+a,rE:!0,r:0,c:[i]}},s,l,{cN:"meta",b:"\\[no_square_brackets",starts:{e:"\\[/no_square_brackets\\]",l:r+"|&[lg]t;",k:n,c:[{cN:"meta",b:t,r:0,starts:{e:"\\[noprocess\\]|"+a,rE:!0,c:[i]}},s,l].concat(c)}},{cN:"meta",b:"\\[",r:0},{cN:"meta",b:"^#!",e:"lasso9$",r:10}].concat(c)}});hljs.registerLanguage("coq",function(e){return{k:{keyword:"_ as at cofix else end exists exists2 fix for forall fun if IF in let match mod Prop return Set then Type using where with Abort About Add Admit Admitted All Arguments Assumptions Axiom Back BackTo Backtrack Bind Blacklist Canonical Cd Check Class Classes Close Coercion Coercions CoFixpoint CoInductive Collection Combined Compute Conjecture Conjectures Constant constr Constraint Constructors Context Corollary CreateHintDb Cut Declare Defined Definition Delimit Dependencies DependentDerive Drop eauto End Equality Eval Example Existential Existentials Existing Export exporting Extern Extract Extraction Fact Field Fields File Fixpoint Focus for From Function Functional Generalizable Global Goal Grab Grammar Graph Guarded Heap Hint HintDb Hints Hypotheses Hypothesis ident Identity If Immediate Implicit Import Include Inductive Infix Info Initial Inline Inspect Instance Instances Intro Intros Inversion Inversion_clear Language Left Lemma Let Libraries Library Load LoadPath Local Locate Ltac ML Mode Module Modules Monomorphic Morphism Next NoInline Notation Obligation Obligations Opaque Open Optimize Options Parameter Parameters Parametric Path Paths pattern Polymorphic Preterm Print Printing Program Projections Proof Proposition Pwd Qed Quit Rec Record Recursive Redirect Relation Remark Remove Require Reserved Reset Resolve Restart Rewrite Right Ring Rings Save Scheme Scope Scopes Script Search SearchAbout SearchHead SearchPattern SearchRewrite Section Separate Set Setoid Show Solve Sorted Step Strategies Strategy Structure SubClass Table Tables Tactic Term Test Theorem Time Timeout Transparent Type Typeclasses Types Undelimit Undo Unfocus Unfocused Unfold Universe Universes Unset Unshelve using Variable Variables Variant Verbose Visibility where with",built_in:"abstract absurd admit after apply as assert assumption at auto autorewrite autounfold before bottom btauto by case case_eq cbn cbv change classical_left classical_right clear clearbody cofix compare compute congruence constr_eq constructor contradict contradiction cut cutrewrite cycle decide decompose dependent destruct destruction dintuition discriminate discrR do double dtauto eapply eassumption eauto ecase econstructor edestruct ediscriminate eelim eexact eexists einduction einjection eleft elim elimtype enough equality erewrite eright esimplify_eq esplit evar exact exactly_once exfalso exists f_equal fail field field_simplify field_simplify_eq first firstorder fix fold fourier functional generalize generalizing gfail give_up has_evar hnf idtac in induction injection instantiate intro intro_pattern intros intuition inversion inversion_clear is_evar is_var lapply lazy left lia lra move native_compute nia nsatz omega once pattern pose progress proof psatz quote record red refine reflexivity remember rename repeat replace revert revgoals rewrite rewrite_strat right ring ring_simplify rtauto set setoid_reflexivity setoid_replace setoid_rewrite setoid_symmetry setoid_transitivity shelve shelve_unifiable simpl simple simplify_eq solve specialize split split_Rabs split_Rmult stepl stepr subst sum swap symmetry tactic tauto time timeout top transitivity trivial try tryif unfold unify until using vm_compute with"},c:[e.QSM,e.C("\\(\\*","\\*\\)"),e.CNM,{cN:"type",eB:!0,b:"\\|\\s*",e:"\\w+"},{b:/[-=]>/}]}});hljs.registerLanguage("vbscript",function(e){return{aliases:["vbs"],cI:!0,k:{keyword:"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto",built_in:"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err",literal:"true false null nothing empty"},i:"//",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),e.C(/'/,/$/,{r:0}),e.CNM]}});hljs.registerLanguage("vbscript-html",function(r){return{sL:"xml",c:[{b:"<%",e:"%>",sL:"vbscript"}]}});hljs.registerLanguage("less",function(e){var r="[\\w-]+",t="("+r+"|@{"+r+"})",a=[],c=[],s=function(e){return{cN:"string",b:"~?"+e+".*?"+e}},b=function(e,r,t){return{cN:e,b:r,r:t}},n={b:"\\(",e:"\\)",c:c,r:0};c.push(e.CLCM,e.CBCM,s("'"),s('"'),e.CSSNM,{b:"(url|data-uri)\\(",starts:{cN:"string",e:"[\\)\\n]",eE:!0}},b("number","#[0-9A-Fa-f]+\\b"),n,b("variable","@@?"+r,10),b("variable","@{"+r+"}"),b("built_in","~?`[^`]*?`"),{cN:"attribute",b:r+"\\s*:",e:":",rB:!0,eE:!0},{cN:"meta",b:"!important"});var i=c.concat({b:"{",e:"}",c:a}),o={bK:"when",eW:!0,c:[{bK:"and not"}].concat(c)},u={b:t+"\\s*:",rB:!0,e:"[;}]",r:0,c:[{cN:"attribute",b:t,e:":",eE:!0,starts:{eW:!0,i:"[<=$]",r:0,c:c}}]},l={cN:"keyword",b:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{e:"[;{}]",rE:!0,c:c,r:0}},C={cN:"variable",v:[{b:"@"+r+"\\s*:",r:15},{b:"@"+r}],starts:{e:"[;}]",rE:!0,c:i}},p={v:[{b:"[\\.#:&\\[>]",e:"[;{}]"},{b:t,e:"{"}],rB:!0,rE:!0,i:"[<='$\"]",r:0,c:[e.CLCM,e.CBCM,o,b("keyword","all\\b"),b("variable","@{"+r+"}"),b("selector-tag",t+"%?",0),b("selector-id","#"+t),b("selector-class","\\."+t,0),b("selector-tag","&",0),{cN:"selector-attr",b:"\\[",e:"\\]"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"\\(",e:"\\)",c:i},{b:"!important"}]};return a.push(e.CLCM,e.CBCM,l,C,u,p),{cI:!0,i:"[=>'/<($\"]",c:a}});hljs.registerLanguage("dust",function(e){var t="if eq ne lt lte gt gte select default math sep";return{aliases:["dst"],cI:!0,sL:"xml",c:[{cN:"template-tag",b:/\{[#\/]/,e:/\}/,i:/;/,c:[{cN:"name",b:/[a-zA-Z\.-]+/,starts:{eW:!0,r:0,c:[e.QSM]}}]},{cN:"template-variable",b:/\{/,e:/\}/,i:/;/,k:t}]}});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("dart",function(e){var t={cN:"subst",b:"\\$\\{",e:"}",k:"true false null this is new super"},r={cN:"string",v:[{b:"r'''",e:"'''"},{b:'r"""',e:'"""'},{b:"r'",e:"'",i:"\\n"},{b:'r"',e:'"',i:"\\n"},{b:"'''",e:"'''",c:[e.BE,t]},{b:'"""',e:'"""',c:[e.BE,t]},{b:"'",e:"'",i:"\\n",c:[e.BE,t]},{b:'"',e:'"',i:"\\n",c:[e.BE,t]}]};t.c=[e.CNM,r];var n={keyword:"assert async await break case catch class const continue default do else enum extends false final finally for if in is new null rethrow return super switch sync this throw true try var void while with yield abstract as dynamic export external factory get implements import library operator part set static typedef",built_in:"print Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set Stopwatch String StringBuffer StringSink Symbol Type Uri bool double int num document window querySelector querySelectorAll Element ElementList"};return{k:n,c:[r,e.C("/\\*\\*","\\*/",{sL:"markdown"}),e.C("///","$",{sL:"markdown"}),e.CLCM,e.CBCM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.UTM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"},{b:"=>"}]}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("qml",function(r){var e={keyword:"in of on if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await import",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Behavior bool color coordinate date double enumeration font geocircle georectangle geoshape int list matrix4x4 parent point quaternion real rect size string url variant vector2d vector3d vector4dPromise"},t="[a-zA-Z_][a-zA-Z0-9\\._]*",a={cN:"keyword",b:"\\bproperty\\b",starts:{cN:"string",e:"(:|=|;|,|//|/\\*|$)",rE:!0}},n={cN:"keyword",b:"\\bsignal\\b",starts:{cN:"string",e:"(\\(|:|=|;|,|//|/\\*|$)",rE:!0}},o={cN:"attribute",b:"\\bid\\s*:",starts:{cN:"string",e:t,rE:!1}},i={b:t+"\\s*:",rB:!0,c:[{cN:"attribute",b:t,e:"\\s*:",eE:!0,r:0}],r:0},c={b:t+"\\s*{",e:"{",rB:!0,r:0,c:[r.inherit(r.TM,{b:t})]};return{aliases:["qt"],cI:!1,k:e,c:[{cN:"meta",b:/^\s*['"]use (strict|asm)['"]/},r.ASM,r.QSM,{cN:"string",b:"`",e:"`",c:[r.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},r.CLCM,r.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:r.CNR}],r:0},{b:"("+r.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[r.CLCM,r.CBCM,r.RM,{b:/\s*[);\]]/,r:0,sL:"xml"}],r:0},n,a,{cN:"function",bK:"function",e:/\{/,eE:!0,c:[r.inherit(r.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[r.CLCM,r.CBCM]}],i:/\[|%/},{b:"\\."+r.IR,r:0},o,i,c],i:/#/}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var l="[>?]>",o="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+l+"|"+o+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(w).concat(d)}});hljs.registerLanguage("erb",function(e){return{sL:"xml",c:[e.C("<%#","%>"),{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0}]}});hljs.registerLanguage("xquery",function(e){var t="for let if while then else return where group by xquery encoding versionmodule namespace boundary-space preserve strip default collation base-uri orderingcopy-namespaces order declare import schema namespace function option in allowing emptyat tumbling window sliding window start when only end when previous next stable ascendingdescending empty greatest least some every satisfies switch case typeswitch try catch andor to union intersect instance of treat as castable cast map array delete insert intoreplace value rename copy modify update",a="false true xs:string xs:integer element item xs:date xs:datetime xs:float xs:double xs:decimal QName xs:anyURI xs:long xs:int xs:short xs:byte attribute",s={b:/\$[a-zA-Z0-9\-]+/},n={cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},r={cN:"string",v:[{b:/"/,e:/"/,c:[{b:/""/,r:0}]},{b:/'/,e:/'/,c:[{b:/''/,r:0}]}]},i={cN:"meta",b:"%\\w+"},c={cN:"comment",b:"\\(:",e:":\\)",r:10,c:[{cN:"doctag",b:"@\\w+"}]},o={b:"{",e:"}"},l=[s,r,n,c,i,o];return o.c=l,{aliases:["xpath","xq"],cI:!1,l:/[a-zA-Z\$][a-zA-Z0-9_:\-]*/,i:/(proc)|(abstract)|(extends)|(until)|(#)/,k:{keyword:t,literal:a},c:l}});hljs.registerLanguage("jboss-cli",function(e){var a={b:/[\w-]+ *=/,rB:!0,r:0,c:[{cN:"attr",b:/[\w-]+/}]},r={cN:"params",b:/\(/,e:/\)/,c:[a],r:0},o={cN:"function",b:/:[\w\-.]+/,r:0},t={cN:"string",b:/\B(([\/.])[\w\-.\/=]+)+/},c={cN:"params",b:/--[\w\-=\/]+/};return{aliases:["wildfly-cli"],l:"[a-z-]+",k:{keyword:"alias batch cd clear command connect connection-factory connection-info data-source deploy deployment-info deployment-overlay echo echo-dmr help history if jdbc-driver-info jms-queue|20 jms-topic|20 ls patch pwd quit read-attribute read-operation reload rollout-plan run-batch set shutdown try unalias undeploy unset version xa-data-source",literal:"true false"},c:[e.HCM,e.QSM,c,o,t,r]}});hljs.registerLanguage("applescript",function(e){var t=e.inherit(e.QSM,{i:""}),r={cN:"params",b:"\\(",e:"\\)",c:["self",e.CNM,t]},i=e.C("--","$"),o=e.C("\\(\\*","\\*\\)",{c:["self",i]}),n=[i,o,e.HCM];return{aliases:["osascript"],k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without",literal:"AppleScript false linefeed return pi quote result space tab true",built_in:"alias application boolean class constant date file integer list number real record string text activate beep count delay launch log offset read round run say summarize write character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[t,e.CNM,{cN:"built_in",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"literal",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference)|POSIX file|POSIX path|(date|time) string|quoted form)\\b"},{bK:"on",i:"[${=;\\n]",c:[e.UTM,r]}].concat(n),i:"//|->|=>|\\[\\["}});hljs.registerLanguage("crmsh",function(t){var e="primitive rsc_template",r="group clone ms master location colocation order fencing_topology rsc_ticket acl_target acl_group user role tag xml",s="property rsc_defaults op_defaults",a="params meta operations op rule attributes utilization",i="read write deny defined not_defined in_range date spec in ref reference attribute type xpath version and or lt gt tag lte gte eq ne \\",o="number string",n="Master Started Slave Stopped start promote demote stop monitor true false";return{aliases:["crm","pcmk"],cI:!0,k:{keyword:a+" "+i+" "+o,literal:n},c:[t.HCM,{bK:"node",starts:{e:"\\s*([\\w_-]+:)?",starts:{cN:"title",e:"\\s*[\\$\\w_][\\w_-]*"}}},{bK:e,starts:{cN:"title",e:"\\s*[\\$\\w_][\\w_-]*",starts:{e:"\\s*@?[\\w_][\\w_\\.:-]*"}}},{b:"\\b("+r.split(" ").join("|")+")\\s+",k:r,starts:{cN:"title",e:"[\\$\\w_][\\w_-]*"}},{bK:s,starts:{cN:"title",e:"\\s*([\\w_-]+:)?"}},t.QSM,{cN:"meta",b:"(ocf|systemd|service|lsb):[\\w_:-]+",r:0},{cN:"number",b:"\\b\\d+(\\.\\d+)?(ms|s|h|m)?",r:0},{cN:"literal",b:"[-]?(infinity|inf)",r:0},{cN:"attr",b:/([A-Za-z\$_\#][\w_-]+)=/,r:0},{cN:"tag",b:"",r:0}]}});hljs.registerLanguage("taggerscript",function(e){var c={cN:"comment",b:/\$noop\(/,e:/\)/,c:[{b:/\(/,e:/\)/,c:["self",{b:/\\./}]}],r:10},r={cN:"keyword",b:/\$(?!noop)[a-zA-Z][_a-zA-Z0-9]*/,e:/\(/,eE:!0},a={cN:"variable",b:/%[_a-zA-Z0-9:]*/,e:"%"},b={cN:"symbol",b:/\\./};return{c:[c,r,a,b]}});hljs.registerLanguage("irpf90",function(e){var t={cN:"params",b:"\\(",e:"\\)"},n={literal:".False. .True.",keyword:"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data begin_provider &begin_provider end_provider begin_shell end_shell begin_template end_template subst assert touch soft_touch provide no_dep free irp_if irp_else irp_endif irp_write irp_read",built_in:"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image IRP_ALIGN irp_here"};return{cI:!0,k:n,i:/\/\*/,c:[e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{cN:"string",r:0}),{cN:"function",bK:"subroutine function program",i:"[${=\\n]",c:[e.UTM,t]},e.C("!","$",{r:0}),e.C("begin_doc","end_doc",{r:10}),{cN:"number",b:"(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?",r:0}]}});hljs.registerLanguage("golo",function(e){return{k:{keyword:"println readln print import module function local return let var while for foreach times in case when match with break continue augment augmentation each find filter reduce if then else otherwise try catch finally raise throw orIfNull DynamicObject|10 DynamicVariable struct Observable map set vector list array",literal:"true false null"},c:[e.HCM,e.QSM,e.CNM,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("pony",function(e){var r={keyword:"actor addressof and as be break class compile_error compile_intrinsicconsume continue delegate digestof do else elseif embed end errorfor fun if ifdef in interface is isnt lambda let match new not objector primitive recover repeat return struct then trait try type until use var where while with xor",meta:"iso val tag trn box ref",literal:"this false true"},t={cN:"string",b:'"""',e:'"""',r:10},c={cN:"string",b:'"',e:'"',c:[e.BE]},i={cN:"string",b:"'",e:"'",c:[e.BE],r:0},n={cN:"type",b:"\\b_?[A-Z][\\w]*",r:0},s={b:e.IR+"'",r:0},a={cN:"class",bK:"class actor",e:"$",c:[e.TM,e.CLCM]},o={cN:"function",bK:"new fun",e:"=>",c:[e.TM,{b:/\(/,e:/\)/,c:[n,s,e.CNM,e.CBCM]},{b:/:/,eW:!0,c:[n]},e.CLCM]};return{k:r,c:[a,o,n,t,c,i,s,e.CNM,e.CLCM,e.CBCM]}});hljs.registerLanguage("fsharp",function(e){var t={b:"<",e:">",c:[e.inherit(e.TM,{b:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],k:"abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",i:/\/\*/,c:[{cN:"keyword",b:/\b(yield|return|let|do)!/},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},e.C("\\(\\*","\\*\\)"),{cN:"class",bK:"type",e:"\\(|=|$",eE:!0,c:[e.UTM,t]},{cN:"meta",b:"\\[<",e:">\\]",r:10},{cN:"symbol",b:"\\B('[A-Za-z])\\b",c:[e.BE]},e.CLCM,e.inherit(e.QSM,{i:null}),e.CNM]}});hljs.registerLanguage("scheme",function(e){var t="[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+",r="(\\-|\\+)?\\d+([./]\\d+)?",a=r+"[+\\-]"+r+"i",i={"builtin-name":"case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules ' * + , ,@ - ... / ; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"},n={cN:"meta",b:"^#!",e:"$"},c={cN:"literal",b:"(#t|#f|#\\\\"+t+"|#\\\\.)"},l={cN:"number",v:[{b:r,r:0},{b:a,r:0},{b:"#b[0-1]+(/[0-1]+)?"},{b:"#o[0-7]+(/[0-7]+)?"},{b:"#x[0-9a-f]+(/[0-9a-f]+)?"}]},s=e.QSM,o=[e.C(";","$",{r:0}),e.C("#\\|","\\|#")],u={b:t,r:0},p={cN:"symbol",b:"'"+t},d={eW:!0,r:0},m={v:[{b:/'/},{b:"`"}],c:[{b:"\\(",e:"\\)",c:["self",c,s,l,u,p]}]},g={cN:"name",b:t,l:t,k:i},h={b:/lambda/,eW:!0,rB:!0,c:[g,{b:/\(/,e:/\)/,endsParent:!0,c:[u]}]},b={v:[{b:"\\(",e:"\\)"},{b:"\\[",e:"\\]"}],c:[h,g,d]};return d.c=[c,l,s,u,p,m,b].concat(o),{i:/\S/,c:[n,l,s,p,m,b].concat(o)}});hljs.registerLanguage("twig",function(e){var t={cN:"params",b:"\\(",e:"\\)"},a="attribute block constant cycle date dump include max min parent random range source template_from_string",r={bK:a,k:{name:a},r:0,c:[t]},c={b:/\|[A-Za-z_]+:?/,k:"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode",c:[r]},s="autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim";return s=s+" "+s.split(" ").map(function(e){return"end"+e}).join(" "),{aliases:["craftcms"],cI:!0,sL:"xml",c:[e.C(/\{#/,/#}/),{cN:"template-tag",b:/\{%/,e:/%}/,c:[{cN:"name",b:/\w+/,k:s,starts:{eW:!0,c:[c,r],r:0}}]},{cN:"template-variable",b:/\{\{/,e:/}}/,c:["self",c,r]}]}});hljs.registerLanguage("matlab",function(e){var a=[e.CNM,{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]}],s={r:0,c:[{b:/'['\.]*/}]};return{k:{keyword:"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while",built_in:"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson"},i:'(//|"|#|/\\*|\\s+/\\w+)',c:[{cN:"function",bK:"function",e:"$",c:[e.UTM,{cN:"params",v:[{b:"\\(",e:"\\)"},{b:"\\[",e:"\\]"}]}]},{b:/[a-zA-Z_][a-zA-Z_0-9]*'['\.]*/,rB:!0,r:0,c:[{b:/[a-zA-Z_][a-zA-Z_0-9]*/,r:0},s.c[0]]},{b:"\\[",e:"\\]",c:a,r:0,starts:s},{b:"\\{",e:/}/,c:a,r:0,starts:s},{b:/\)/,r:0,starts:s},e.C("^\\s*\\%\\{\\s*$","^\\s*\\%\\}\\s*$"),e.C("\\%","$")].concat(a)}});hljs.registerLanguage("processing",function(e){return{k:{keyword:"BufferedReader PVector PFont PImage PGraphics HashMap boolean byte char color double float int long String Array FloatDict FloatList IntDict IntList JSONArray JSONObject Object StringDict StringList Table TableRow XML false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",literal:"P2D P3D HALF_PI PI QUARTER_PI TAU TWO_PI",title:"setup draw",built_in:"displayHeight displayWidth mouseY mouseX mousePressed pmouseX pmouseY key keyCode pixels focused frameCount frameRate height width size createGraphics beginDraw createShape loadShape PShape arc ellipse line point quad rect triangle bezier bezierDetail bezierPoint bezierTangent curve curveDetail curvePoint curveTangent curveTightness shape shapeMode beginContour beginShape bezierVertex curveVertex endContour endShape quadraticVertex vertex ellipseMode noSmooth rectMode smooth strokeCap strokeJoin strokeWeight mouseClicked mouseDragged mouseMoved mousePressed mouseReleased mouseWheel keyPressed keyPressedkeyReleased keyTyped print println save saveFrame day hour millis minute month second year background clear colorMode fill noFill noStroke stroke alpha blue brightness color green hue lerpColor red saturation modelX modelY modelZ screenX screenY screenZ ambient emissive shininess specular add createImage beginCamera camera endCamera frustum ortho perspective printCamera printProjection cursor frameRate noCursor exit loop noLoop popStyle pushStyle redraw binary boolean byte char float hex int str unbinary unhex join match matchAll nf nfc nfp nfs split splitTokens trim append arrayCopy concat expand reverse shorten sort splice subset box sphere sphereDetail createInput createReader loadBytes loadJSONArray loadJSONObject loadStrings loadTable loadXML open parseXML saveTable selectFolder selectInput beginRaw beginRecord createOutput createWriter endRaw endRecord PrintWritersaveBytes saveJSONArray saveJSONObject saveStream saveStrings saveXML selectOutput popMatrix printMatrix pushMatrix resetMatrix rotate rotateX rotateY rotateZ scale shearX shearY translate ambientLight directionalLight lightFalloff lights lightSpecular noLights normal pointLight spotLight image imageMode loadImage noTint requestImage tint texture textureMode textureWrap blend copy filter get loadPixels set updatePixels blendMode loadShader PShaderresetShader shader createFont loadFont text textFont textAlign textLeading textMode textSize textWidth textAscent textDescent abs ceil constrain dist exp floor lerp log mag map max min norm pow round sq sqrt acos asin atan atan2 cos degrees radians sin tan noise noiseDetail noiseSeed random randomGaussian randomSeed"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM]}});hljs.registerLanguage("llvm",function(e){var n="([-a-zA-Z$._][\\w\\-$.]*)";return{k:"begin end true false declare define global constant private linker_private internal available_externally linkonce linkonce_odr weak weak_odr appending dllimport dllexport common default hidden protected extern_weak external thread_local zeroinitializer undef null to tail target triple datalayout volatile nuw nsw nnan ninf nsz arcp fast exact inbounds align addrspace section alias module asm sideeffect gc dbg linker_private_weak attributes blockaddress initialexec localdynamic localexec prefix unnamed_addr ccc fastcc coldcc x86_stdcallcc x86_fastcallcc arm_apcscc arm_aapcscc arm_aapcs_vfpcc ptx_device ptx_kernel intel_ocl_bicc msp430_intrcc spir_func spir_kernel x86_64_sysvcc x86_64_win64cc x86_thiscallcc cc c signext zeroext inreg sret nounwind noreturn noalias nocapture byval nest readnone readonly inlinehint noinline alwaysinline optsize ssp sspreq noredzone noimplicitfloat naked builtin cold nobuiltin noduplicate nonlazybind optnone returns_twice sanitize_address sanitize_memory sanitize_thread sspstrong uwtable returned type opaque eq ne slt sgt sle sge ult ugt ule uge oeq one olt ogt ole oge ord uno ueq une x acq_rel acquire alignstack atomic catch cleanup filter inteldialect max min monotonic nand personality release seq_cst singlethread umax umin unordered xchg add fadd sub fsub mul fmul udiv sdiv fdiv urem srem frem shl lshr ashr and or xor icmp fcmp phi call trunc zext sext fptrunc fpext uitofp sitofp fptoui fptosi inttoptr ptrtoint bitcast addrspacecast select va_arg ret br switch invoke unwind unreachable indirectbr landingpad resume malloc alloca free load store getelementptr extractelement insertelement shufflevector getresult extractvalue insertvalue atomicrmw cmpxchg fence argmemonly double",c:[{cN:"keyword",b:"i\\d+"},e.C(";","\\n",{r:0}),e.QSM,{cN:"string",v:[{b:'"',e:'[^\\\\]"'}],r:0},{cN:"title",v:[{b:"@"+n},{b:"@\\d+"},{b:"!"+n},{b:"!\\d+"+n}]},{cN:"symbol",v:[{b:"%"+n},{b:"%\\d+"},{b:"#\\d+"}]},{cN:"number",v:[{b:"0[xX][a-fA-F0-9]+"},{b:"-?\\d+(?:[.]\\d+)?(?:[eE][-+]?\\d+(?:[.]\\d+)?)?"}],r:0}]}});hljs.registerLanguage("capnproto",function(t){return{aliases:["capnp"],k:{keyword:"struct enum interface union group import using const annotation extends in of on as with from fixed",built_in:"Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 Text Data AnyPointer AnyStruct Capability List",literal:"true false"},c:[t.QSM,t.NM,t.HCM,{cN:"meta",b:/@0x[\w\d]{16};/,i:/\n/},{cN:"symbol",b:/@\d+\b/},{cN:"class",bK:"struct enum",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]},{cN:"class",bK:"interface",e:/\{/,i:/\n/,c:[t.inherit(t.TM,{starts:{eW:!0,eE:!0}})]}]}});hljs.registerLanguage("dns",function(d){return{aliases:["bind","zone"],k:{keyword:"IN A AAAA AFSDB APL CAA CDNSKEY CDS CERT CNAME DHCID DLV DNAME DNSKEY DS HIP IPSECKEY KEY KX LOC MX NAPTR NS NSEC NSEC3 NSEC3PARAM PTR RRSIG RP SIG SOA SRV SSHFP TA TKEY TLSA TSIG TXT"},c:[d.C(";","$",{r:0}),{cN:"meta",b:/^\$(TTL|GENERATE|INCLUDE|ORIGIN)\b/},{cN:"number",b:"((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))\\b"},{cN:"number",b:"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\b"},d.inherit(d.NM,{b:/\b\d+[dhwm]?/})]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("vala",function(t){return{k:{keyword:"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override virtual delegate if while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var",built_in:"DBus GLib CCode Gee Object Gtk Posix",literal:"false true null"},c:[{cN:"class",bK:"class interface namespace",e:"{",eE:!0,i:"[^,:\\n\\s\\.]",c:[t.UTM]},t.CLCM,t.CBCM,{cN:"string",b:'"""',e:'"""',r:5},t.ASM,t.QSM,t.CNM,{cN:"meta",b:"^#",e:"$",r:2}]}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*#]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("r",function(e){var r="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{c:[e.HCM,{b:r,l:r,k:{keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{b:"`",e:"`",r:0},{cN:"string",c:[e.BE],v:[{b:'"',e:'"'},{b:"'",e:"'"}]}]}});hljs.registerLanguage("nimrod",function(t){return{aliases:["nim"],k:{keyword:"addr and as asm bind block break case cast const continue converter discard distinct div do elif else end enum except export finally for from generic if import in include interface is isnot iterator let macro method mixin mod nil not notin object of or out proc ptr raise ref return shl shr static template try tuple type using var when while with without xor yield",literal:"shared guarded stdin stdout stderr result true false",built_in:"int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 bool char string cstring pointer expr stmt void auto any range array openarray varargs seq set clong culong cchar cschar cshort cint csize clonglong cfloat cdouble clongdouble cuchar cushort cuint culonglong cstringarray semistatic"},c:[{cN:"meta",b:/{\./,e:/\.}/,r:10},{cN:"string",b:/[a-zA-Z]\w*"/,e:/"/,c:[{b:/""/}]},{cN:"string",b:/([a-zA-Z]\w*)?"""/,e:/"""/},t.QSM,{cN:"type",b:/\b[A-Z]\w+\b/,r:0},{cN:"number",r:0,v:[{b:/\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/},{b:/\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/},{b:/\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/},{b:/\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/}]},t.HCM]}});hljs.registerLanguage("step21",function(e){var i="[A-Z_][A-Z0-9_.]*",r={keyword:"HEADER ENDSEC DATA"},t={cN:"meta",b:"ISO-10303-21;",r:10},n={cN:"meta",b:"END-ISO-10303-21;",r:10};return{aliases:["p21","step","stp"],cI:!0,l:i,k:r,c:[t,n,e.CLCM,e.CBCM,e.C("/\\*\\*!","\\*/"),e.CNM,e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null}),{cN:"string",b:"'",e:"'"},{cN:"symbol",v:[{b:"#",e:"\\d+",i:"\\W"}]}]}});hljs.registerLanguage("axapta",function(e){return{k:"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod",c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM,{cN:"meta",b:"#",e:"$"},{cN:"class",bK:"class interface",e:"{",eE:!0,i:":",c:[{bK:"extends implements"},e.UTM]}]}});hljs.registerLanguage("ruleslanguage",function(T){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM NUMDAYS READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[T.CLCM,T.CBCM,T.ASM,T.QSM,T.CNM,{cN:"literal",v:[{b:"#\\s+[a-zA-Z\\ \\.]*",r:0},{b:"#[a-zA-Z\\ \\.]+"}]}]}});hljs.registerLanguage("roboconf",function(a){var e="[a-zA-Z-_][^\\n{]+\\{",n={cN:"attribute",b:/[a-zA-Z-_]+/,e:/\s*:/,eE:!0,starts:{e:";",r:0,c:[{cN:"variable",b:/\.[a-zA-Z-_]+/},{cN:"keyword",b:/\(optional\)/}]}};return{aliases:["graph","instances"],cI:!0,k:"import",c:[{b:"^facet "+e,e:"}",k:"facet",c:[n,a.HCM]},{b:"^\\s*instance of "+e,e:"}",k:"name count channels instance-data instance-state instance of",i:/\S/,c:["self",n,a.HCM]},{b:"^"+e,e:"}",c:[n,a.HCM]},a.HCM]}});hljs.registerLanguage("gradle",function(e){return{cI:!0,k:{keyword:"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.NM,e.RM]}});hljs.registerLanguage("ceylon",function(e){var a="assembly module package import alias class interface object given value assign void function new of extends satisfies abstracts in out return break continue throw assert dynamic if else switch case for while try catch finally then let this outer super is exists nonempty",t="shared abstract formal default actual variable late native deprecatedfinal sealed annotation suppressWarnings small",s="doc by license see throws tagged",n={cN:"subst",eB:!0,eE:!0,b:/``/,e:/``/,k:a,r:10},r=[{cN:"string",b:'"""',e:'"""',r:10},{cN:"string",b:'"',e:'"',c:[n]},{cN:"string",b:"'",e:"'"},{cN:"number",b:"#[0-9a-fA-F_]+|\\$[01_]+|[0-9_]+(?:\\.[0-9_](?:[eE][+-]?\\d+)?)?[kMGTPmunpf]?",r:0}];return n.c=r,{k:{keyword:a+" "+t,meta:s},i:"\\$[^01]|#[^0-9a-fA-F]",c:[e.CLCM,e.C("/\\*","\\*/",{c:["self"]}),{cN:"meta",b:'@[a-z]\\w*(?:\\:"[^"]*")?'}].concat(r)}});hljs.registerLanguage("puppet",function(e){var s={keyword:"and case default else elsif false if in import enherits node or true undef unless main settings $string ",literal:"alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted",built_in:"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version"},r=e.C("#","$"),a="([A-Za-z_]|::)(\\w|::)*",i=e.inherit(e.TM,{b:a}),o={cN:"variable",b:"\\$"+a},t={cN:"string",c:[e.BE,o],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]};return{aliases:["pp"],c:[r,o,t,{bK:"class",e:"\\{|;",i:/=/,c:[i,r]},{bK:"define",e:/\{/,c:[{cN:"section",b:e.IR,endsParent:!0}]},{b:e.IR+"\\s+\\{",rB:!0,e:/\S/,c:[{cN:"keyword",b:e.IR},{b:/\{/,e:/\}/,k:s,r:0,c:[t,r,{b:"[a-zA-Z_]+\\s*=>",rB:!0,e:"=>",c:[{cN:"attr",b:e.IR}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},o]}],r:0}]}});hljs.registerLanguage("stata",function(e){return{aliases:["do","ado"],cI:!0,k:"if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d|0 datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e|0 ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate g|0 gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h|0 hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l|0 la lab labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m|0 ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize meqparse mer merg merge mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n|0 nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u|0 unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5",c:[{cN:"symbol",b:/`[a-zA-Z0-9_]+'/},{cN:"variable",b:/\$\{?[a-zA-Z0-9_]+\}?/},{cN:"string",v:[{b:'`"[^\r\n]*?"\''},{b:'"[^\r\n"]*"'}]},{cN:"built_in",v:[{b:"\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\(|$)"}]},e.C("^[ ]*\\*.*$",!1),e.CLCM,e.CBCM]}});hljs.registerLanguage("julia",function(e){var r={keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},t="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",a={l:t,k:r,i:/<\//},n={cN:"number",b:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,r:0},o={cN:"string",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i={cN:"subst",b:/\$\(/,e:/\)/,k:r},l={cN:"variable",b:"\\$"+t},c={cN:"string",c:[e.BE,i,l],v:[{b:/\w*"""/,e:/"""\w*/,r:10},{b:/\w*"/,e:/"\w*/}]},s={cN:"string",c:[e.BE,i,l],b:"`",e:"`"},d={cN:"meta",b:"@"+t},u={cN:"comment",v:[{b:"#=",e:"=#",r:10},{b:"#",e:"$"}]};return a.c=[n,o,c,s,d,u,e.HCM,{cN:"keyword",b:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{b:/<:/}],i.c=a.c,a});hljs.registerLanguage("sml",function(e){return{aliases:["ml"],k:{keyword:"abstype and andalso as case datatype do else end eqtype exception fn fun functor handle if in include infix infixr let local nonfix of op open orelse raise rec sharing sig signature struct structure then type val with withtype where while",built_in:"array bool char exn int list option order real ref string substring vector unit word",literal:"true false NONE SOME LESS EQUAL GREATER nil"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:/\[(\|\|)?\]|\(\)/,r:0},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"type",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*"},e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("cs",function(e){var i={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},t={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},r=e.inherit(t,{i:/\n/}),a={cN:"subst",b:"{",e:"}",k:i},c=e.inherit(a,{i:/\n/}),n={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,c]},s={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},a]},o=e.inherit(s,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},c]});a.c=[s,n,t,e.ASM,e.QSM,e.CNM,e.CBCM],c.c=[o,n,r,e.ASM,e.QSM,e.CNM,e.inherit(e.CBCM,{i:/\n/})];var l={v:[s,n,t,e.ASM,e.QSM]},b=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},l,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{cN:"meta",b:"^\\s*\\[",eB:!0,e:"\\]",eE:!0,c:[{cN:"meta-string",b:/"/,e:/"/}]},{bK:"new return throw await else",r:0},{cN:"function",b:"("+b+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[l,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("tcl",function(e){return{aliases:["tk"],k:"after append apply array auto_execok auto_import auto_load auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock close concat continue dde dict encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent filename flush for foreach format gets glob global history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename return safe scan seek set socket source split string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update uplevel upvar variable vwait while",c:[e.C(";[ \\t]*#","$"),e.C("^[ \\t]*#","$"),{bK:"proc",e:"[\\{]",eE:!0,c:[{cN:"title",b:"[ \\t\\n\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"[ \\t\\n\\r]",eW:!0,eE:!0}]},{eE:!0,v:[{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)",e:"[^a-zA-Z0-9_\\}\\$]"},{b:"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*",e:"(\\))?[^a-zA-Z0-9_\\}\\$]"}]},{cN:"string",c:[e.BE],v:[e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},{cN:"number",v:[e.BNM,e.CNM]}]}});hljs.registerLanguage("csp",function(r){return{cI:!1,l:"[a-zA-Z][a-zA-Z0-9_-]*",k:{keyword:"base-uri child-src connect-src default-src font-src form-action frame-ancestors frame-src img-src media-src object-src plugin-types report-uri sandbox script-src style-src"},c:[{cN:"string",b:"'",e:"'"},{cN:"attribute",b:"^Content",e:":",eE:!0}]}});hljs.registerLanguage("rib",function(e){return{k:"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd",i:"",e:",\\s+",rB:!0,eW:!0,c:[{cN:"attr",b:":\\w+"},s.ASM,s.QSM,{b:"\\w+",r:0}]}]},{b:"\\(\\s*",e:"\\s*\\)",eE:!0,c:[{b:"\\w+\\s*=",e:"\\s+",rB:!0,eW:!0,c:[{cN:"attr",b:"\\w+",r:0},s.ASM,s.QSM,{b:"\\w+",r:0}]}]}]},{b:"^\\s*[=~]\\s*"},{b:"#{",starts:{e:"}",sL:"ruby"}}]}});hljs.registerLanguage("dos",function(e){var r=e.C(/^\s*@?rem\b/,/$/,{r:10}),t={cN:"symbol",b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)",r:0};return{aliases:["bat","cmd"],cI:!0,i:/\/\*/,k:{keyword:"if else goto for in do call exit not exist errorlevel defined equ neq lss leq gtr geq",built_in:"prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux shift cd dir echo setlocal endlocal set pause copy append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color comp compact convert date dir diskcomp diskcopy doskey erase fs find findstr format ftype graftabl help keyb label md mkdir mode more move path pause print popd pushd promt rd recover rem rename replace restore rmdir shiftsort start subst time title tree type ver verify vol ping net ipconfig taskkill xcopy ren del"},c:[{cN:"variable",b:/%%[^ ]|%[^ ]+?%|![^ ]+?!/},{cN:"function",b:t.b,e:"goto:eof",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),r]},{cN:"number",b:"\\b\\d+",r:0},r]}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},_={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},i=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:_,l:i,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:i,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("tex",function(c){var e={cN:"tag",b:/\\/,r:0,c:[{cN:"name",v:[{b:/[a-zA-Zа-яА-я]+[*]?/},{b:/[^a-zA-Zа-яА-я0-9]/}],starts:{eW:!0,r:0,c:[{cN:"string",v:[{b:/\[/,e:/\]/},{b:/\{/,e:/\}/}]},{b:/\s*=\s*/,eW:!0,r:0,c:[{cN:"number",b:/-?\d*\.?\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?/}]}]}}]};return{c:[e,{cN:"formula",c:[e],r:0,v:[{b:/\$\$/,e:/\$\$/},{b:/\$/,e:/\$/}]},c.C("%","$",{r:0})]}});hljs.registerLanguage("purebasic",function(e){var r={cN:"string",b:'(~)?"',e:'"',i:"\\n"},t={cN:"symbol",b:"#[a-zA-Z_]\\w*\\$?"};return{aliases:["pb","pbi"],k:"And As Break CallDebugger Case CompilerCase CompilerDefault CompilerElse CompilerEndIf CompilerEndSelect CompilerError CompilerIf CompilerSelect Continue Data DataSection EndDataSection Debug DebugLevel Default Define Dim DisableASM DisableDebugger DisableExplicit Else ElseIf EnableASM EnableDebugger EnableExplicit End EndEnumeration EndIf EndImport EndInterface EndMacro EndProcedure EndSelect EndStructure EndStructureUnion EndWith Enumeration Extends FakeReturn For Next ForEach ForEver Global Gosub Goto If Import ImportC IncludeBinary IncludeFile IncludePath Interface Macro NewList Not Or ProcedureReturn Protected Prototype PrototypeC Read ReDim Repeat Until Restore Return Select Shared Static Step Structure StructureUnion Swap To Wend While With XIncludeFile XOr Procedure ProcedureC ProcedureCDLL ProcedureDLL Declare DeclareC DeclareCDLL DeclareDLL",c:[e.C(";","$",{r:0}),{cN:"function",b:"\\b(Procedure|Declare)(C|CDLL|DLL)?\\b",e:"\\(",eE:!0,rB:!0,c:[{cN:"keyword",b:"(Procedure|Declare)(C|CDLL|DLL)?",eE:!0},{cN:"type",b:"\\.\\w*"},e.UTM]},r,t]}});hljs.registerLanguage("clojure",function(e){var t={"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},c=e.inherit(e.QSM,{i:null}),i=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"symbol",b:"[:]{1,2}"+n},f={b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"name",b:n,starts:h},b=[f,c,m,p,i,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,p.c=[l],{aliases:["clj"],i:/\S/,c:[f,c,m,p,i,u,l,s,d]}});hljs.registerLanguage("clojure-repl",function(e){return{c:[{cN:"meta",b:/^([\w.-]+|\s*#_)=>/,starts:{e:/$/,sL:"clojure"}}]}});hljs.registerLanguage("clean",function(e){return{aliases:["clean","icl","dcl"],k:{keyword:"if let in with where case of class instance otherwise implementation definition system module from import qualified as special code inline foreign export ccall stdcall generic derive infix infixl infixr",literal:"True False"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.CNM,{b:"->|<-[|:]?|::|#!?|>>=|\\{\\||\\|\\}|:==|=:|\\.\\.|<>|`"}]}});hljs.registerLanguage("n1ql",function(e){return{cI:!0,c:[{bK:"build create index delete drop explain infer|10 insert merge prepare select update upsert|10",e:/;/,eW:!0,k:{keyword:"all alter analyze and any array as asc begin between binary boolean break bucket build by call case cast cluster collate collection commit connect continue correlate cover create database dataset datastore declare decrement delete derived desc describe distinct do drop each element else end every except exclude execute exists explain fetch first flatten for force from function grant group gsi having if ignore ilike in include increment index infer inline inner insert intersect into is join key keys keyspace known last left let letting like limit lsm map mapping matched materialized merge minus namespace nest not number object offset on option or order outer over parse partition password path pool prepare primary private privilege procedure public raw realm reduce rename return returning revoke right role rollback satisfies schema select self semi set show some start statistics string system then to transaction trigger truncate under union unique unknown unnest unset update upsert use user using validate value valued values via view when where while with within work xor",literal:"true false null missing|5",built_in:"array_agg array_append array_concat array_contains array_count array_distinct array_ifnull array_length array_max array_min array_position array_prepend array_put array_range array_remove array_repeat array_replace array_reverse array_sort array_sum avg count max min sum greatest least ifmissing ifmissingornull ifnull missingif nullif ifinf ifnan ifnanorinf naninf neginfif posinfif clock_millis clock_str date_add_millis date_add_str date_diff_millis date_diff_str date_part_millis date_part_str date_trunc_millis date_trunc_str duration_to_str millis str_to_millis millis_to_str millis_to_utc millis_to_zone_name now_millis now_str str_to_duration str_to_utc str_to_zone_name decode_json encode_json encoded_size poly_length base64 base64_encode base64_decode meta uuid abs acos asin atan atan2 ceil cos degrees e exp ln log floor pi power radians random round sign sin sqrt tan trunc object_length object_names object_pairs object_inner_pairs object_values object_inner_values object_add object_put object_remove object_unwrap regexp_contains regexp_like regexp_position regexp_replace contains initcap length lower ltrim position repeat replace rtrim split substr title trim upper isarray isatom isboolean isnumber isobject isstring type toarray toatom toboolean tonumber toobject tostring"},c:[{cN:"string",b:"'",e:"'",c:[e.BE],r:0},{cN:"string",b:'"',e:'"',c:[e.BE],r:0},{cN:"symbol",b:"`",e:"`",c:[e.BE],r:2},e.CNM,e.CBCM]},e.CBCM]}});hljs.registerLanguage("lsl",function(E){var T={cN:"subst",b:/\\[tn"\\]/},e={cN:"string",b:'"',e:'"',c:[T]},A={cN:"number",b:E.CNR},R={cN:"literal",v:[{b:"\\b(?:PI|TWO_PI|PI_BY_TWO|DEG_TO_RAD|RAD_TO_DEG|SQRT2)\\b"},{b:"\\b(?:XP_ERROR_(?:EXPERIENCES_DISABLED|EXPERIENCE_(?:DISABLED|SUSPENDED)|INVALID_(?:EXPERIENCE|PARAMETERS)|KEY_NOT_FOUND|MATURITY_EXCEEDED|NONE|NOT_(?:FOUND|PERMITTED(?:_LAND)?)|NO_EXPERIENCE|QUOTA_EXCEEDED|RETRY_UPDATE|STORAGE_EXCEPTION|STORE_DISABLED|THROTTLED|UNKNOWN_ERROR)|JSON_APPEND|STATUS_(?:PHYSICS|ROTATE_[XYZ]|PHANTOM|SANDBOX|BLOCK_GRAB(?:_OBJECT)?|(?:DIE|RETURN)_AT_EDGE|CAST_SHADOWS|OK|MALFORMED_PARAMS|TYPE_MISMATCH|BOUNDS_ERROR|NOT_(?:FOUND|SUPPORTED)|INTERNAL_ERROR|WHITELIST_FAILED)|AGENT(?:_(?:BY_(?:LEGACY_|USER)NAME|FLYING|ATTACHMENTS|SCRIPTED|MOUSELOOK|SITTING|ON_OBJECT|AWAY|WALKING|IN_AIR|TYPING|CROUCHING|BUSY|ALWAYS_RUN|AUTOPILOT|LIST_(?:PARCEL(?:_OWNER)?|REGION)))?|CAMERA_(?:PITCH|DISTANCE|BEHINDNESS_(?:ANGLE|LAG)|(?:FOCUS|POSITION)(?:_(?:THRESHOLD|LOCKED|LAG))?|FOCUS_OFFSET|ACTIVE)|ANIM_ON|LOOP|REVERSE|PING_PONG|SMOOTH|ROTATE|SCALE|ALL_SIDES|LINK_(?:ROOT|SET|ALL_(?:OTHERS|CHILDREN)|THIS)|ACTIVE|PASS(?:IVE|_(?:ALWAYS|IF_NOT_HANDLED|NEVER))|SCRIPTED|CONTROL_(?:FWD|BACK|(?:ROT_)?(?:LEFT|RIGHT)|UP|DOWN|(?:ML_)?LBUTTON)|PERMISSION_(?:RETURN_OBJECTS|DEBIT|OVERRIDE_ANIMATIONS|SILENT_ESTATE_MANAGEMENT|TAKE_CONTROLS|TRIGGER_ANIMATION|ATTACH|CHANGE_LINKS|(?:CONTROL|TRACK)_CAMERA|TELEPORT)|INVENTORY_(?:TEXTURE|SOUND|OBJECT|SCRIPT|LANDMARK|CLOTHING|NOTECARD|BODYPART|ANIMATION|GESTURE|ALL|NONE)|CHANGED_(?:INVENTORY|COLOR|SHAPE|SCALE|TEXTURE|LINK|ALLOWED_DROP|OWNER|REGION(?:_START)?|TELEPORT|MEDIA)|OBJECT_(?:CLICK_ACTION|HOVER_HEIGHT|LAST_OWNER_ID|(?:PHYSICS|SERVER|STREAMING)_COST|UNKNOWN_DETAIL|CHARACTER_TIME|PHANTOM|PHYSICS|TEMP_ON_REZ|NAME|DESC|POS|PRIM_(?:COUNT|EQUIVALENCE)|RETURN_(?:PARCEL(?:_OWNER)?|REGION)|REZZER_KEY|ROO?T|VELOCITY|OMEGA|OWNER|GROUP|CREATOR|ATTACHED_POINT|RENDER_WEIGHT|(?:BODY_SHAPE|PATHFINDING)_TYPE|(?:RUNNING|TOTAL)_SCRIPT_COUNT|TOTAL_INVENTORY_COUNT|SCRIPT_(?:MEMORY|TIME))|TYPE_(?:INTEGER|FLOAT|STRING|KEY|VECTOR|ROTATION|INVALID)|(?:DEBUG|PUBLIC)_CHANNEL|ATTACH_(?:AVATAR_CENTER|CHEST|HEAD|BACK|PELVIS|MOUTH|CHIN|NECK|NOSE|BELLY|[LR](?:SHOULDER|HAND|FOOT|EAR|EYE|[UL](?:ARM|LEG)|HIP)|(?:LEFT|RIGHT)_PEC|HUD_(?:CENTER_[12]|TOP_(?:RIGHT|CENTER|LEFT)|BOTTOM(?:_(?:RIGHT|LEFT))?)|[LR]HAND_RING1|TAIL_(?:BASE|TIP)|[LR]WING|FACE_(?:JAW|[LR]EAR|[LR]EYE|TOUNGE)|GROIN|HIND_[LR]FOOT)|LAND_(?:LEVEL|RAISE|LOWER|SMOOTH|NOISE|REVERT)|DATA_(?:ONLINE|NAME|BORN|SIM_(?:POS|STATUS|RATING)|PAYINFO)|PAYMENT_INFO_(?:ON_FILE|USED)|REMOTE_DATA_(?:CHANNEL|REQUEST|REPLY)|PSYS_(?:PART_(?:BF_(?:ZERO|ONE(?:_MINUS_(?:DEST_COLOR|SOURCE_(ALPHA|COLOR)))?|DEST_COLOR|SOURCE_(ALPHA|COLOR))|BLEND_FUNC_(DEST|SOURCE)|FLAGS|(?:START|END)_(?:COLOR|ALPHA|SCALE|GLOW)|MAX_AGE|(?:RIBBON|WIND|INTERP_(?:COLOR|SCALE)|BOUNCE|FOLLOW_(?:SRC|VELOCITY)|TARGET_(?:POS|LINEAR)|EMISSIVE)_MASK)|SRC_(?:MAX_AGE|PATTERN|ANGLE_(?:BEGIN|END)|BURST_(?:RATE|PART_COUNT|RADIUS|SPEED_(?:MIN|MAX))|ACCEL|TEXTURE|TARGET_KEY|OMEGA|PATTERN_(?:DROP|EXPLODE|ANGLE(?:_CONE(?:_EMPTY)?)?)))|VEHICLE_(?:REFERENCE_FRAME|TYPE_(?:NONE|SLED|CAR|BOAT|AIRPLANE|BALLOON)|(?:LINEAR|ANGULAR)_(?:FRICTION_TIMESCALE|MOTOR_DIRECTION)|LINEAR_MOTOR_OFFSET|HOVER_(?:HEIGHT|EFFICIENCY|TIMESCALE)|BUOYANCY|(?:LINEAR|ANGULAR)_(?:DEFLECTION_(?:EFFICIENCY|TIMESCALE)|MOTOR_(?:DECAY_)?TIMESCALE)|VERTICAL_ATTRACTION_(?:EFFICIENCY|TIMESCALE)|BANKING_(?:EFFICIENCY|MIX|TIMESCALE)|FLAG_(?:NO_DEFLECTION_UP|LIMIT_(?:ROLL_ONLY|MOTOR_UP)|HOVER_(?:(?:WATER|TERRAIN|UP)_ONLY|GLOBAL_HEIGHT)|MOUSELOOK_(?:STEER|BANK)|CAMERA_DECOUPLED))|PRIM_(?:ALPHA_MODE(?:_(?:BLEND|EMISSIVE|MASK|NONE))?|NORMAL|SPECULAR|TYPE(?:_(?:BOX|CYLINDER|PRISM|SPHERE|TORUS|TUBE|RING|SCULPT))?|HOLE_(?:DEFAULT|CIRCLE|SQUARE|TRIANGLE)|MATERIAL(?:_(?:STONE|METAL|GLASS|WOOD|FLESH|PLASTIC|RUBBER))?|SHINY_(?:NONE|LOW|MEDIUM|HIGH)|BUMP_(?:NONE|BRIGHT|DARK|WOOD|BARK|BRICKS|CHECKER|CONCRETE|TILE|STONE|DISKS|GRAVEL|BLOBS|SIDING|LARGETILE|STUCCO|SUCTION|WEAVE)|TEXGEN_(?:DEFAULT|PLANAR)|SCULPT_(?:TYPE_(?:SPHERE|TORUS|PLANE|CYLINDER|MASK)|FLAG_(?:MIRROR|INVERT))|PHYSICS(?:_(?:SHAPE_(?:CONVEX|NONE|PRIM|TYPE)))?|(?:POS|ROT)_LOCAL|SLICE|TEXT|FLEXIBLE|POINT_LIGHT|TEMP_ON_REZ|PHANTOM|POSITION|SIZE|ROTATION|TEXTURE|NAME|OMEGA|DESC|LINK_TARGET|COLOR|BUMP_SHINY|FULLBRIGHT|TEXGEN|GLOW|MEDIA_(?:ALT_IMAGE_ENABLE|CONTROLS|(?:CURRENT|HOME)_URL|AUTO_(?:LOOP|PLAY|SCALE|ZOOM)|FIRST_CLICK_INTERACT|(?:WIDTH|HEIGHT)_PIXELS|WHITELIST(?:_ENABLE)?|PERMS_(?:INTERACT|CONTROL)|PARAM_MAX|CONTROLS_(?:STANDARD|MINI)|PERM_(?:NONE|OWNER|GROUP|ANYONE)|MAX_(?:URL_LENGTH|WHITELIST_(?:SIZE|COUNT)|(?:WIDTH|HEIGHT)_PIXELS)))|MASK_(?:BASE|OWNER|GROUP|EVERYONE|NEXT)|PERM_(?:TRANSFER|MODIFY|COPY|MOVE|ALL)|PARCEL_(?:MEDIA_COMMAND_(?:STOP|PAUSE|PLAY|LOOP|TEXTURE|URL|TIME|AGENT|UNLOAD|AUTO_ALIGN|TYPE|SIZE|DESC|LOOP_SET)|FLAG_(?:ALLOW_(?:FLY|(?:GROUP_)?SCRIPTS|LANDMARK|TERRAFORM|DAMAGE|CREATE_(?:GROUP_)?OBJECTS)|USE_(?:ACCESS_(?:GROUP|LIST)|BAN_LIST|LAND_PASS_LIST)|LOCAL_SOUND_ONLY|RESTRICT_PUSHOBJECT|ALLOW_(?:GROUP|ALL)_OBJECT_ENTRY)|COUNT_(?:TOTAL|OWNER|GROUP|OTHER|SELECTED|TEMP)|DETAILS_(?:NAME|DESC|OWNER|GROUP|AREA|ID|SEE_AVATARS))|LIST_STAT_(?:MAX|MIN|MEAN|MEDIAN|STD_DEV|SUM(?:_SQUARES)?|NUM_COUNT|GEOMETRIC_MEAN|RANGE)|PAY_(?:HIDE|DEFAULT)|REGION_FLAG_(?:ALLOW_DAMAGE|FIXED_SUN|BLOCK_TERRAFORM|SANDBOX|DISABLE_(?:COLLISIONS|PHYSICS)|BLOCK_FLY|ALLOW_DIRECT_TELEPORT|RESTRICT_PUSHOBJECT)|HTTP_(?:METHOD|MIMETYPE|BODY_(?:MAXLENGTH|TRUNCATED)|CUSTOM_HEADER|PRAGMA_NO_CACHE|VERBOSE_THROTTLE|VERIFY_CERT)|STRING_(?:TRIM(?:_(?:HEAD|TAIL))?)|CLICK_ACTION_(?:NONE|TOUCH|SIT|BUY|PAY|OPEN(?:_MEDIA)?|PLAY|ZOOM)|TOUCH_INVALID_FACE|PROFILE_(?:NONE|SCRIPT_MEMORY)|RC_(?:DATA_FLAGS|DETECT_PHANTOM|GET_(?:LINK_NUM|NORMAL|ROOT_KEY)|MAX_HITS|REJECT_(?:TYPES|AGENTS|(?:NON)?PHYSICAL|LAND))|RCERR_(?:CAST_TIME_EXCEEDED|SIM_PERF_LOW|UNKNOWN)|ESTATE_ACCESS_(?:ALLOWED_(?:AGENT|GROUP)_(?:ADD|REMOVE)|BANNED_AGENT_(?:ADD|REMOVE))|DENSITY|FRICTION|RESTITUTION|GRAVITY_MULTIPLIER|KFM_(?:COMMAND|CMD_(?:PLAY|STOP|PAUSE)|MODE|FORWARD|LOOP|PING_PONG|REVERSE|DATA|ROTATION|TRANSLATION)|ERR_(?:GENERIC|PARCEL_PERMISSIONS|MALFORMED_PARAMS|RUNTIME_PERMISSIONS|THROTTLED)|CHARACTER_(?:CMD_(?:(?:SMOOTH_)?STOP|JUMP)|DESIRED_(?:TURN_)?SPEED|RADIUS|STAY_WITHIN_PARCEL|LENGTH|ORIENTATION|ACCOUNT_FOR_SKIPPED_FRAMES|AVOIDANCE_MODE|TYPE(?:_(?:[ABCD]|NONE))?|MAX_(?:DECEL|TURN_RADIUS|(?:ACCEL|SPEED)))|PURSUIT_(?:OFFSET|FUZZ_FACTOR|GOAL_TOLERANCE|INTERCEPT)|REQUIRE_LINE_OF_SIGHT|FORCE_DIRECT_PATH|VERTICAL|HORIZONTAL|AVOID_(?:CHARACTERS|DYNAMIC_OBSTACLES|NONE)|PU_(?:EVADE_(?:HIDDEN|SPOTTED)|FAILURE_(?:DYNAMIC_PATHFINDING_DISABLED|INVALID_(?:GOAL|START)|NO_(?:NAVMESH|VALID_DESTINATION)|OTHER|TARGET_GONE|(?:PARCEL_)?UNREACHABLE)|(?:GOAL|SLOWDOWN_DISTANCE)_REACHED)|TRAVERSAL_TYPE(?:_(?:FAST|NONE|SLOW))?|CONTENT_TYPE_(?:ATOM|FORM|HTML|JSON|LLSD|RSS|TEXT|XHTML|XML)|GCNP_(?:RADIUS|STATIC)|(?:PATROL|WANDER)_PAUSE_AT_WAYPOINTS|OPT_(?:AVATAR|CHARACTER|EXCLUSION_VOLUME|LEGACY_LINKSET|MATERIAL_VOLUME|OTHER|STATIC_OBSTACLE|WALKABLE)|SIM_STAT_PCT_CHARS_STEPPED)\\b"},{b:"\\b(?:FALSE|TRUE)\\b"},{b:"\\b(?:ZERO_ROTATION)\\b"},{b:"\\b(?:EOF|JSON_(?:ARRAY|DELETE|FALSE|INVALID|NULL|NUMBER|OBJECT|STRING|TRUE)|NULL_KEY|TEXTURE_(?:BLANK|DEFAULT|MEDIA|PLYWOOD|TRANSPARENT)|URL_REQUEST_(?:GRANTED|DENIED))\\b"},{b:"\\b(?:ZERO_VECTOR|TOUCH_INVALID_(?:TEXCOORD|VECTOR))\\b"}]},O={cN:"built_in",b:"\\b(?:ll(?:AgentInExperience|(?:Create|DataSize|Delete|KeyCount|Keys|Read|Update)KeyValue|GetExperience(?:Details|ErrorMessage)|ReturnObjectsBy(?:ID|Owner)|Json(?:2List|[GS]etValue|ValueType)|Sin|Cos|Tan|Atan2|Sqrt|Pow|Abs|Fabs|Frand|Floor|Ceil|Round|Vec(?:Mag|Norm|Dist)|Rot(?:Between|2(?:Euler|Fwd|Left|Up))|(?:Euler|Axes)2Rot|Whisper|(?:Region|Owner)?Say|Shout|Listen(?:Control|Remove)?|Sensor(?:Repeat|Remove)?|Detected(?:Name|Key|Owner|Type|Pos|Vel|Grab|Rot|Group|LinkNumber)|Die|Ground|Wind|(?:[GS]et)(?:AnimationOverride|MemoryLimit|PrimMediaParams|ParcelMusicURL|Object(?:Desc|Name)|PhysicsMaterial|Status|Scale|Color|Alpha|Texture|Pos|Rot|Force|Torque)|ResetAnimationOverride|(?:Scale|Offset|Rotate)Texture|(?:Rot)?Target(?:Remove)?|(?:Stop)?MoveToTarget|Apply(?:Rotational)?Impulse|Set(?:KeyframedMotion|ContentType|RegionPos|(?:Angular)?Velocity|Buoyancy|HoverHeight|ForceAndTorque|TimerEvent|ScriptState|Damage|TextureAnim|Sound(?:Queueing|Radius)|Vehicle(?:Type|(?:Float|Vector|Rotation)Param)|(?:Touch|Sit)?Text|Camera(?:Eye|At)Offset|PrimitiveParams|ClickAction|Link(?:Alpha|Color|PrimitiveParams(?:Fast)?|Texture(?:Anim)?|Camera|Media)|RemoteScriptAccessPin|PayPrice|LocalRot)|ScaleByFactor|Get(?:(?:Max|Min)ScaleFactor|ClosestNavPoint|StaticPath|SimStats|Env|PrimitiveParams|Link(?:PrimitiveParams|Number(?:OfSides)?|Key|Name|Media)|HTTPHeader|FreeURLs|Object(?:Details|PermMask|PrimCount)|Parcel(?:MaxPrims|Details|Prim(?:Count|Owners))|Attached(?:List)?|(?:SPMax|Free|Used)Memory|Region(?:Name|TimeDilation|FPS|Corner|AgentCount)|Root(?:Position|Rotation)|UnixTime|(?:Parcel|Region)Flags|(?:Wall|GMT)clock|SimulatorHostname|BoundingBox|GeometricCenter|Creator|NumberOf(?:Prims|NotecardLines|Sides)|Animation(?:List)?|(?:Camera|Local)(?:Pos|Rot)|Vel|Accel|Omega|Time(?:stamp|OfDay)|(?:Object|CenterOf)?Mass|MassMKS|Energy|Owner|(?:Owner)?Key|SunDirection|Texture(?:Offset|Scale|Rot)|Inventory(?:Number|Name|Key|Type|Creator|PermMask)|Permissions(?:Key)?|StartParameter|List(?:Length|EntryType)|Date|Agent(?:Size|Info|Language|List)|LandOwnerAt|NotecardLine|Script(?:Name|State))|(?:Get|Reset|GetAndReset)Time|PlaySound(?:Slave)?|LoopSound(?:Master|Slave)?|(?:Trigger|Stop|Preload)Sound|(?:(?:Get|Delete)Sub|Insert)String|To(?:Upper|Lower)|Give(?:InventoryList|Money)|RezObject|(?:Stop)?LookAt|Sleep|CollisionFilter|(?:Take|Release)Controls|DetachFromAvatar|AttachToAvatar(?:Temp)?|InstantMessage|(?:GetNext)?Email|StopHover|MinEventDelay|RotLookAt|String(?:Length|Trim)|(?:Start|Stop)Animation|TargetOmega|Request(?:Experience)?Permissions|(?:Create|Break)Link|BreakAllLinks|(?:Give|Remove)Inventory|Water|PassTouches|Request(?:Agent|Inventory)Data|TeleportAgent(?:Home|GlobalCoords)?|ModifyLand|CollisionSound|ResetScript|MessageLinked|PushObject|PassCollisions|AxisAngle2Rot|Rot2(?:Axis|Angle)|A(?:cos|sin)|AngleBetween|AllowInventoryDrop|SubStringIndex|List2(?:CSV|Integer|Json|Float|String|Key|Vector|Rot|List(?:Strided)?)|DeleteSubList|List(?:Statistics|Sort|Randomize|(?:Insert|Find|Replace)List)|EdgeOfWorld|AdjustSoundVolume|Key2Name|TriggerSoundLimited|EjectFromLand|(?:CSV|ParseString)2List|OverMyLand|SameGroup|UnSit|Ground(?:Slope|Normal|Contour)|GroundRepel|(?:Set|Remove)VehicleFlags|(?:AvatarOn)?(?:Link)?SitTarget|Script(?:Danger|Profiler)|Dialog|VolumeDetect|ResetOtherScript|RemoteLoadScriptPin|(?:Open|Close)RemoteDataChannel|SendRemoteData|RemoteDataReply|(?:Integer|String)ToBase64|XorBase64|Log(?:10)?|Base64To(?:String|Integer)|ParseStringKeepNulls|RezAtRoot|RequestSimulatorData|ForceMouselook|(?:Load|Release|(?:E|Une)scape)URL|ParcelMedia(?:CommandList|Query)|ModPow|MapDestination|(?:RemoveFrom|AddTo|Reset)Land(?:Pass|Ban)List|(?:Set|Clear)CameraParams|HTTP(?:Request|Response)|TextBox|DetectedTouch(?:UV|Face|Pos|(?:N|Bin)ormal|ST)|(?:MD5|SHA1|DumpList2)String|Request(?:Secure)?URL|Clear(?:Prim|Link)Media|(?:Link)?ParticleSystem|(?:Get|Request)(?:Username|DisplayName)|RegionSayTo|CastRay|GenerateKey|TransferLindenDollars|ManageEstateAccess|(?:Create|Delete)Character|ExecCharacterCmd|Evade|FleeFrom|NavigateTo|PatrolPoints|Pursue|UpdateCharacter|WanderWithin))\\b"};return{i:":",c:[e,{cN:"comment",v:[E.C("//","$"),E.C("/\\*","\\*/")]},A,{cN:"section",v:[{b:"\\b(?:state|default)\\b"},{b:"\\b(?:state_(?:entry|exit)|touch(?:_(?:start|end))?|(?:land_)?collision(?:_(?:start|end))?|timer|listen|(?:no_)?sensor|control|(?:not_)?at_(?:rot_)?target|money|email|experience_permissions(?:_denied)?|run_time_permissions|changed|attach|dataserver|moving_(?:start|end)|link_message|(?:on|object)_rez|remote_data|http_re(?:sponse|quest)|path_update|transaction_result)\\b"}]},O,R,{cN:"type",b:"\\b(?:integer|float|string|key|vector|quaternion|rotation|list)\\b"}]}});hljs.registerLanguage("tp",function(O){var R={cN:"number",b:"[1-9][0-9]*",r:0},E={cN:"symbol",b:":[^\\]]+"},T={cN:"built_in",b:"(AR|P|PAYLOAD|PR|R|SR|RSR|LBL|VR|UALM|MESSAGE|UTOOL|UFRAME|TIMER| TIMER_OVERFLOW|JOINT_MAX_SPEED|RESUME_PROG|DIAG_REC)\\[",e:"\\]",c:["self",R,E]},N={cN:"built_in",b:"(AI|AO|DI|DO|F|RI|RO|UI|UO|GI|GO|SI|SO)\\[",e:"\\]",c:["self",R,O.QSM,E]};return{k:{keyword:"ABORT ACC ADJUST AND AP_LD BREAK CALL CNT COL CONDITION CONFIG DA DB DIV DETECT ELSE END ENDFOR ERR_NUM ERROR_PROG FINE FOR GP GUARD INC IF JMP LINEAR_MAX_SPEED LOCK MOD MONITOR OFFSET Offset OR OVERRIDE PAUSE PREG PTH RT_LD RUN SELECT SKIP Skip TA TB TO TOOL_OFFSET Tool_Offset UF UT UFRAME_NUM UTOOL_NUM UNLOCK WAIT X Y Z W P R STRLEN SUBSTR FINDSTR VOFFSET PROG ATTR MN POS",literal:"ON OFF max_speed LPOS JPOS ENABLE DISABLE START STOP RESET"},c:[T,N,{cN:"keyword",b:"/(PROG|ATTR|MN|POS|END)\\b"},{cN:"keyword",b:"(CALL|RUN|POINT_LOGIC|LBL)\\b"},{cN:"keyword",b:"\\b(ACC|CNT|Skip|Offset|PSPD|RT_LD|AP_LD|Tool_Offset)"},{cN:"number",b:"\\d+(sec|msec|mm/sec|cm/min|inch/min|deg/sec|mm|in|cm)?\\b",r:0},O.C("//","[;$]"),O.C("!","[;$]"),O.C("--eg:","$"),O.QSM,{cN:"string",b:"'",e:"'"},O.CNM,{cN:"variable",b:"\\$[A-Za-z0-9_]+"}]}});hljs.registerLanguage("moonscript",function(e){var t={keyword:"if then not for in while do return else elseif break continue switch and or unless when class extends super local import export from using",literal:"true false nil",built_in:"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},r="[A-Za-z$_][0-9A-Za-z$_]*",s={cN:"subst",b:/#\{/,e:/}/,k:t},a=[e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'/,e:/'/,c:[e.BE]},{b:/"/,e:/"/,c:[e.BE,s]}]},{cN:"built_in",b:"@__"+e.IR},{b:"@"+e.IR},{b:e.IR+"\\\\"+e.IR}];s.c=a;var c=e.inherit(e.TM,{b:r}),n="(\\(.*\\))?\\s*\\B[-=]>",i={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(a)}]};return{aliases:["moon"],k:t,i:/\/\*/,c:a.concat([e.C("--","$"),{cN:"function",b:"^\\s*"+r+"\\s*=\\s*"+n,e:"[-=]>",rB:!0,c:[c,i]},{b:/[\(,:=]\s*/,r:0,c:[{cN:"function",b:n,e:"[-=]>",rB:!0,c:[i]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[c]},c]},{cN:"name",b:r+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("routeros",function(e){var r="foreach do while for if from to step else on-error and or not in",i="global local beep delay put len typeof pick log time set find environment terminal error execute parse resolve toarray tobool toid toip toip6 tonum tostr totime",o="add remove enable disable set get print export edit find run debug error info warning",t="true false yes no nothing nil null",s="traffic-flow traffic-generator firewall scheduler aaa accounting address-list address align area bandwidth-server bfd bgp bridge client clock community config connection console customer default dhcp-client dhcp-server discovery dns e-mail ethernet filter firewall firmware gps graphing group hardware health hotspot identity igmp-proxy incoming instance interface ip ipsec ipv6 irq l2tp-server lcd ldp logging mac-server mac-winbox mangle manual mirror mme mpls nat nd neighbor network note ntp ospf ospf-v3 ovpn-server page peer pim ping policy pool port ppp pppoe-client pptp-server prefix profile proposal proxy queue radius resource rip ripng route routing screen script security-profiles server service service-port settings shares smb sms sniffer snmp snooper socks sstp-server system tool tracking type upgrade upnp user-manager users user vlan secret vrrp watchdog web-access wireless pptp pppoe lan wan layer7-protocol lease simple raw",n={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},p={cN:"string",b:/"/,e:/"/,c:[e.BE,n,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["routeros","mikrotik"],cI:!0,l:/:?[\w-]+/,k:{literal:t,keyword:r+" :"+r.split(" ").join(" :")+" :"+i.split(" ").join(" :")},c:[{v:[{b:/^@/,e:/$/},{b:/\/\*/,e:/\*\//},{b:/%%/,e:/$/},{b:/^'/,e:/$/},{b:/^\s*\/[\w-]+=/,e:/$/},{b:/\/\//,e:/$/},{b:/^\[\\]$/},{b:/<\//,e:/>/},{b:/^facet /,e:/\}/},{b:"^1\\.\\.(\\d+)$",e:/$/}],i:/./},e.C("^#","$"),p,a,n,{b:/[\w-]+\=([^\s\{\}\[\]\(\)]+)/,r:0,rB:!0,c:[{cN:"attribute",b:/[^=]+/},{b:/=/,eW:!0,r:0,c:[p,a,n,{cN:"literal",b:"\\b("+t.split(" ").join("|")+")\\b"},{b:/("[^"]*"|[^\s\{\}\[\]]+)/}]}]},{cN:"number",b:/\*[0-9a-fA-F]+/},{b:"\\b("+o.split(" ").join("|")+")([\\s[(]|])",rB:!0,c:[{cN:"builtin-name",b:/\w+/}]},{cN:"built_in",v:[{b:"(\\.\\./|/|\\s)(("+s.split(" ").join("|")+");?\\s)+",r:10},{b:/\.\./}]}]}});hljs.registerLanguage("protobuf",function(e){return{k:{keyword:"package import option optional required repeated group",built_in:"double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes",literal:"true false"},c:[e.QSM,e.NM,e.CLCM,{cN:"class",bK:"message enum service",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{cN:"function",bK:"rpc",e:/;/,eE:!0,k:"rpc returns"},{b:/^\s*[A-Z_]+/,e:/\s*=/,eE:!0}]}});hljs.registerLanguage("vim",function(e){return{l:/[!#@\w]+/,k:{keyword:"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu go gr grepa gu gv ha helpf helpg helpt hi hid his ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf quita qa rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank",built_in:"synIDtrans atan2 range matcharg did_filetype asin feedkeys xor argv complete_check add getwinposx getqflist getwinposy screencol clearmatches empty extend getcmdpos mzeval garbagecollect setreg ceil sqrt diff_hlID inputsecret get getfperm getpid filewritable shiftwidth max sinh isdirectory synID system inputrestore winline atan visualmode inputlist tabpagewinnr round getregtype mapcheck hasmapto histdel argidx findfile sha256 exists toupper getcmdline taglist string getmatches bufnr strftime winwidth bufexists strtrans tabpagebuflist setcmdpos remote_read printf setloclist getpos getline bufwinnr float2nr len getcmdtype diff_filler luaeval resolve libcallnr foldclosedend reverse filter has_key bufname str2float strlen setline getcharmod setbufvar index searchpos shellescape undofile foldclosed setqflist buflisted strchars str2nr virtcol floor remove undotree remote_expr winheight gettabwinvar reltime cursor tabpagenr finddir localtime acos getloclist search tanh matchend rename gettabvar strdisplaywidth type abs py3eval setwinvar tolower wildmenumode log10 spellsuggest bufloaded synconcealed nextnonblank server2client complete settabwinvar executable input wincol setmatches getftype hlID inputsave searchpair or screenrow line settabvar histadd deepcopy strpart remote_peek and eval getftime submatch screenchar winsaveview matchadd mkdir screenattr getfontname libcall reltimestr getfsize winnr invert pow getbufline byte2line soundfold repeat fnameescape tagfiles sin strwidth spellbadword trunc maparg log lispindent hostname setpos globpath remote_foreground getchar synIDattr fnamemodify cscope_connection stridx winbufnr indent min complete_add nr2char searchpairpos inputdialog values matchlist items hlexists strridx browsedir expand fmod pathshorten line2byte argc count getwinvar glob foldtextresult getreg foreground cosh matchdelete has char2nr simplify histget searchdecl iconv winrestcmd pumvisible writefile foldlevel haslocaldir keys cos matchstr foldtext histnr tan tempname getcwd byteidx getbufvar islocked escape eventhandler remote_send serverlist winrestview synstack pyeval prevnonblank readfile cindent filereadable changenr exp"},i:/;/,c:[e.NM,e.ASM,{cN:"string",b:/"(\\"|\n\\|[^"\n])*"/},e.C('"',"$"),{cN:"variable",b:/[bwtglsav]:[\w\d_]*/},{cN:"function",bK:"function function!",e:"$",r:0,c:[e.TM,{cN:"params",b:"\\(",e:"\\)"}]},{cN:"symbol",b:/<[\w-]+>/}]}});hljs.registerLanguage("zephir",function(e){var i={cN:"string",c:[e.BE],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},n={v:[e.BNM,e.CNM]};return{aliases:["zep"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var let while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally int uint long ulong char uchar double float bool boolean stringlikely unlikely",c:[e.CLCM,e.HCM,e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[e.BE]},{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",e.CBCM,i,n]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},i,n]}});hljs.registerLanguage("php",function(e){var c={b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},i={cN:"meta",b:/<\?(php)?|\?>/},t={cN:"string",c:[e.BE,i],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},a={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[i]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},i,{cN:"keyword",b:/\$this\b/},c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,t,a]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},t,a]}});hljs.registerLanguage("asciidoc",function(e){return{aliases:["adoc"],c:[e.C("^/{4,}\\n","\\n/{4,}$",{r:10}),e.C("^//","$",{r:0}),{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"section",r:10,v:[{b:"^(={1,5}) .+?( \\1)?$"},{b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{cN:"meta",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"meta",b:"^\\[.+?\\]$",r:0},{cN:"quote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"symbol",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"string",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link",b:"\\w",e:"[^\\[]+",r:0},{cN:"string",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}});hljs.registerLanguage("yaml",function(e){var b="true false yes no null",a="^[ \\-]*",r="[a-zA-Z_][\\w\\-]*",t={cN:"attr",v:[{b:a+r+":"},{b:a+'"'+r+'":'},{b:a+"'"+r+"':"}]},c={cN:"template-variable",v:[{b:"{{",e:"}}"},{b:"%{",e:"}"}]},l={cN:"string",r:0,v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/\S+/}],c:[e.BE,c]};return{cI:!0,aliases:["yml","YAML","yaml"],c:[t,{cN:"meta",b:"^---s*$",r:10},{cN:"string",b:"[\\|>] *$",rE:!0,c:l.c,e:t.v[0].b},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0,r:0},{cN:"type",b:"!!"+e.UIR},{cN:"meta",b:"&"+e.UIR+"$"},{cN:"meta",b:"\\*"+e.UIR+"$"},{cN:"bullet",b:"^ *-",r:0},e.HCM,{bK:b,k:{literal:b}},e.CNM,l]}});hljs.registerLanguage("profile",function(e){return{c:[e.CNM,{b:"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}",e:":",eE:!0},{b:"(ncalls|tottime|cumtime)",e:"$",k:"ncalls tottime|10 cumtime|10 filename",r:10},{b:"function calls",e:"$",c:[e.CNM],r:10},e.ASM,e.QSM,{cN:"string",b:"\\(",e:"\\)$",eB:!0,eE:!0,r:0}]}});hljs.registerLanguage("autoit",function(e){var t="ByRef Case Const ContinueCase ContinueLoop Default Dim Do Else ElseIf EndFunc EndIf EndSelect EndSwitch EndWith Enum Exit ExitLoop For Func Global If In Local Next ReDim Return Select Static Step Switch Then To Until Volatile WEnd While With",r="True False And Null Not Or",i="Abs ACos AdlibRegister AdlibUnRegister Asc AscW ASin Assign ATan AutoItSetOption AutoItWinGetTitle AutoItWinSetTitle Beep Binary BinaryLen BinaryMid BinaryToString BitAND BitNOT BitOR BitRotate BitShift BitXOR BlockInput Break Call CDTray Ceiling Chr ChrW ClipGet ClipPut ConsoleRead ConsoleWrite ConsoleWriteError ControlClick ControlCommand ControlDisable ControlEnable ControlFocus ControlGetFocus ControlGetHandle ControlGetPos ControlGetText ControlHide ControlListView ControlMove ControlSend ControlSetText ControlShow ControlTreeView Cos Dec DirCopy DirCreate DirGetSize DirMove DirRemove DllCall DllCallAddress DllCallbackFree DllCallbackGetPtr DllCallbackRegister DllClose DllOpen DllStructCreate DllStructGetData DllStructGetPtr DllStructGetSize DllStructSetData DriveGetDrive DriveGetFileSystem DriveGetLabel DriveGetSerial DriveGetType DriveMapAdd DriveMapDel DriveMapGet DriveSetLabel DriveSpaceFree DriveSpaceTotal DriveStatus EnvGet EnvSet EnvUpdate Eval Execute Exp FileChangeDir FileClose FileCopy FileCreateNTFSLink FileCreateShortcut FileDelete FileExists FileFindFirstFile FileFindNextFile FileFlush FileGetAttrib FileGetEncoding FileGetLongName FileGetPos FileGetShortcut FileGetShortName FileGetSize FileGetTime FileGetVersion FileInstall FileMove FileOpen FileOpenDialog FileRead FileReadLine FileReadToArray FileRecycle FileRecycleEmpty FileSaveDialog FileSelectFolder FileSetAttrib FileSetEnd FileSetPos FileSetTime FileWrite FileWriteLine Floor FtpSetProxy FuncName GUICreate GUICtrlCreateAvi GUICtrlCreateButton GUICtrlCreateCheckbox GUICtrlCreateCombo GUICtrlCreateContextMenu GUICtrlCreateDate GUICtrlCreateDummy GUICtrlCreateEdit GUICtrlCreateGraphic GUICtrlCreateGroup GUICtrlCreateIcon GUICtrlCreateInput GUICtrlCreateLabel GUICtrlCreateList GUICtrlCreateListView GUICtrlCreateListViewItem GUICtrlCreateMenu GUICtrlCreateMenuItem GUICtrlCreateMonthCal GUICtrlCreateObj GUICtrlCreatePic GUICtrlCreateProgress GUICtrlCreateRadio GUICtrlCreateSlider GUICtrlCreateTab GUICtrlCreateTabItem GUICtrlCreateTreeView GUICtrlCreateTreeViewItem GUICtrlCreateUpdown GUICtrlDelete GUICtrlGetHandle GUICtrlGetState GUICtrlRead GUICtrlRecvMsg GUICtrlRegisterListViewSort GUICtrlSendMsg GUICtrlSendToDummy GUICtrlSetBkColor GUICtrlSetColor GUICtrlSetCursor GUICtrlSetData GUICtrlSetDefBkColor GUICtrlSetDefColor GUICtrlSetFont GUICtrlSetGraphic GUICtrlSetImage GUICtrlSetLimit GUICtrlSetOnEvent GUICtrlSetPos GUICtrlSetResizing GUICtrlSetState GUICtrlSetStyle GUICtrlSetTip GUIDelete GUIGetCursorInfo GUIGetMsg GUIGetStyle GUIRegisterMsg GUISetAccelerators GUISetBkColor GUISetCoord GUISetCursor GUISetFont GUISetHelp GUISetIcon GUISetOnEvent GUISetState GUISetStyle GUIStartGroup GUISwitch Hex HotKeySet HttpSetProxy HttpSetUserAgent HWnd InetClose InetGet InetGetInfo InetGetSize InetRead IniDelete IniRead IniReadSection IniReadSectionNames IniRenameSection IniWrite IniWriteSection InputBox Int IsAdmin IsArray IsBinary IsBool IsDeclared IsDllStruct IsFloat IsFunc IsHWnd IsInt IsKeyword IsNumber IsObj IsPtr IsString Log MemGetStats Mod MouseClick MouseClickDrag MouseDown MouseGetCursor MouseGetPos MouseMove MouseUp MouseWheel MsgBox Number ObjCreate ObjCreateInterface ObjEvent ObjGet ObjName OnAutoItExitRegister OnAutoItExitUnRegister Ping PixelChecksum PixelGetColor PixelSearch ProcessClose ProcessExists ProcessGetStats ProcessList ProcessSetPriority ProcessWait ProcessWaitClose ProgressOff ProgressOn ProgressSet Ptr Random RegDelete RegEnumKey RegEnumVal RegRead RegWrite Round Run RunAs RunAsWait RunWait Send SendKeepActive SetError SetExtended ShellExecute ShellExecuteWait Shutdown Sin Sleep SoundPlay SoundSetWaveVolume SplashImageOn SplashOff SplashTextOn Sqrt SRandom StatusbarGetText StderrRead StdinWrite StdioClose StdoutRead String StringAddCR StringCompare StringFormat StringFromASCIIArray StringInStr StringIsAlNum StringIsAlpha StringIsASCII StringIsDigit StringIsFloat StringIsInt StringIsLower StringIsSpace StringIsUpper StringIsXDigit StringLeft StringLen StringLower StringMid StringRegExp StringRegExpReplace StringReplace StringReverse StringRight StringSplit StringStripCR StringStripWS StringToASCIIArray StringToBinary StringTrimLeft StringTrimRight StringUpper Tan TCPAccept TCPCloseSocket TCPConnect TCPListen TCPNameToIP TCPRecv TCPSend TCPShutdown, UDPShutdown TCPStartup, UDPStartup TimerDiff TimerInit ToolTip TrayCreateItem TrayCreateMenu TrayGetMsg TrayItemDelete TrayItemGetHandle TrayItemGetState TrayItemGetText TrayItemSetOnEvent TrayItemSetState TrayItemSetText TraySetClick TraySetIcon TraySetOnEvent TraySetPauseIcon TraySetState TraySetToolTip TrayTip UBound UDPBind UDPCloseSocket UDPOpen UDPRecv UDPSend VarGetType WinActivate WinActive WinClose WinExists WinFlash WinGetCaretPos WinGetClassList WinGetClientSize WinGetHandle WinGetPos WinGetProcess WinGetState WinGetText WinGetTitle WinKill WinList WinMenuSelectItem WinMinimizeAll WinMinimizeAllUndo WinMove WinSetOnTop WinSetState WinSetTitle WinSetTrans WinWait",l={v:[e.C(";","$",{r:0}),e.C("#cs","#ce"),e.C("#comments-start","#comments-end")]},n={b:"\\$[A-z0-9_]+"},o={cN:"string",v:[{b:/"/,e:/"/,c:[{b:/""/,r:0}]},{b:/'/,e:/'/,c:[{b:/''/,r:0}]}]},a={v:[e.BNM,e.CNM]},S={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"comments include include-once NoTrayIcon OnAutoItStartRegister pragma compile RequireAdmin"},c:[{b:/\\\n/,r:0},{bK:"include",k:{"meta-keyword":"include"},e:"$",c:[o,{cN:"meta-string",v:[{b:"<",e:">"},{b:/"/,e:/"/,c:[{b:/""/,r:0}]},{b:/'/,e:/'/,c:[{b:/''/,r:0}]}]}]},o,l]},C={cN:"symbol",b:"@[A-z0-9_]+"},s={cN:"function",bK:"Func",e:"$",i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:[n,o,a]}]};return{cI:!0,i:/\/\*/,k:{keyword:t,built_in:i,literal:r},c:[l,n,o,a,S,C,s]}});hljs.registerLanguage("mipsasm",function(s){return{cI:!0,aliases:["mips"],l:"\\.?"+s.IR,k:{meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .ltorg ",built_in:"$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $20 $21 $22 $23 $24 $25 $26 $27 $28 $29 $30 $31 zero at v0 v1 a0 a1 a2 a3 a4 a5 a6 a7 t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 s0 s1 s2 s3 s4 s5 s6 s7 s8 k0 k1 gp sp fp ra $f0 $f1 $f2 $f2 $f4 $f5 $f6 $f7 $f8 $f9 $f10 $f11 $f12 $f13 $f14 $f15 $f16 $f17 $f18 $f19 $f20 $f21 $f22 $f23 $f24 $f25 $f26 $f27 $f28 $f29 $f30 $f31 Context Random EntryLo0 EntryLo1 Context PageMask Wired EntryHi HWREna BadVAddr Count Compare SR IntCtl SRSCtl SRSMap Cause EPC PRId EBase Config Config1 Config2 Config3 LLAddr Debug DEPC DESAVE CacheErr ECC ErrorEPC TagLo DataLo TagHi DataHi WatchLo WatchHi PerfCtl PerfCnt "},c:[{cN:"keyword",b:"\\b(addi?u?|andi?|b(al)?|beql?|bgez(al)?l?|bgtzl?|blezl?|bltz(al)?l?|bnel?|cl[oz]|divu?|ext|ins|j(al)?|jalr(.hb)?|jr(.hb)?|lbu?|lhu?|ll|lui|lw[lr]?|maddu?|mfhi|mflo|movn|movz|move|msubu?|mthi|mtlo|mul|multu?|nop|nor|ori?|rotrv?|sb|sc|se[bh]|sh|sllv?|slti?u?|srav?|srlv?|subu?|sw[lr]?|xori?|wsbh|abs.[sd]|add.[sd]|alnv.ps|bc1[ft]l?|c.(s?f|un|u?eq|[ou]lt|[ou]le|ngle?|seq|l[et]|ng[et]).[sd]|(ceil|floor|round|trunc).[lw].[sd]|cfc1|cvt.d.[lsw]|cvt.l.[dsw]|cvt.ps.s|cvt.s.[dlw]|cvt.s.p[lu]|cvt.w.[dls]|div.[ds]|ldx?c1|luxc1|lwx?c1|madd.[sd]|mfc1|mov[fntz]?.[ds]|msub.[sd]|mth?c1|mul.[ds]|neg.[ds]|nmadd.[ds]|nmsub.[ds]|p[lu][lu].ps|recip.fmt|r?sqrt.[ds]|sdx?c1|sub.[ds]|suxc1|swx?c1|break|cache|d?eret|[de]i|ehb|mfc0|mtc0|pause|prefx?|rdhwr|rdpgpr|sdbbp|ssnop|synci?|syscall|teqi?|tgei?u?|tlb(p|r|w[ir])|tlti?u?|tnei?|wait|wrpgpr)",e:"\\s"},s.C("[;#]","$"),s.CBCM,s.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"title",b:"\\|",e:"\\|",i:"\\n",r:0},{cN:"number",v:[{b:"0x[0-9a-f]+"},{b:"\\b-?\\d+"}],r:0},{cN:"symbol",v:[{b:"^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{b:"^\\s*[0-9]+:"},{b:"[0-9]+[bf]"}],r:0}],i:"/"}});hljs.registerLanguage("typescript",function(e){var r={keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract as from extends async await",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void Promise"};return{aliases:["ts"],k:r,c:[{cN:"meta",b:/^\s*['"]use strict['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+e.IR+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:e.IR},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:["self",e.CLCM,e.CBCM]}]}]}],r:0},{cN:"function",b:"function",e:/[\{;]/,eE:!0,k:r,c:["self",e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/%/,r:0},{bK:"constructor",e:/\{/,eE:!0,c:["self",{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}]},{b:/module\./,k:{built_in:"module"},r:0},{bK:"module",e:/\{/,eE:!0},{bK:"interface",e:/\{/,eE:!0,k:"interface extends"},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("crystal",function(e){function b(e,b){var r=[{b:e,e:b}];return r[0].c=r,r}var r="(_[uif](8|16|32|64))?",c="[a-zA-Z_]\\w*[!?=]?",i="!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\][=?]?",s={keyword:"abstract alias as as? asm begin break case class def do else elsif end ensure enum extend for fun if include instance_sizeof is_a? lib macro module next nil? of out pointerof private protected rescue responds_to? return require select self sizeof struct super then type typeof union uninitialized unless until when while with yield __DIR__ __END_LINE__ __FILE__ __LINE__",literal:"false nil true"},t={cN:"subst",b:"#{",e:"}",k:s},a={cN:"template-variable",v:[{b:"\\{\\{",e:"\\}\\}"},{b:"\\{%",e:"%\\}"}],k:s},l={cN:"string",c:[e.BE,t],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%w?\\(",e:"\\)",c:b("\\(","\\)")},{b:"%w?\\[",e:"\\]",c:b("\\[","\\]")},{b:"%w?{",e:"}",c:b("{","}")},{b:"%w?<",e:">",c:b("<",">")},{b:"%w?/",e:"/"},{b:"%w?%",e:"%"},{b:"%w?-",e:"-"},{b:"%w?\\|",e:"\\|"},{b:/<<-\w+$/,e:/^\s*\w+$/}],r:0},u={cN:"string",v:[{b:"%q\\(",e:"\\)",c:b("\\(","\\)")},{b:"%q\\[",e:"\\]",c:b("\\[","\\]")},{b:"%q{",e:"}",c:b("{","}")},{b:"%q<",e:">",c:b("<",">")},{b:"%q/",e:"/"},{b:"%q%",e:"%"},{b:"%q-",e:"-"},{b:"%q\\|",e:"\\|"},{b:/<<-'\w+'$/,e:/^\s*\w+$/}],r:0},_={b:"("+i+")\\s*",c:[{cN:"regexp",c:[e.BE,t],v:[{b:"//[a-z]*",r:0},{b:"/",e:"/[a-z]*"},{b:"%r\\(",e:"\\)",c:b("\\(","\\)")},{b:"%r\\[",e:"\\]",c:b("\\[","\\]")},{b:"%r{",e:"}",c:b("{","}")},{b:"%r<",e:">",c:b("<",">")},{b:"%r/",e:"/"},{b:"%r%",e:"%"},{b:"%r-",e:"-"},{b:"%r\\|",e:"\\|"}]}],r:0},o={cN:"regexp",c:[e.BE,t],v:[{b:"%r\\(",e:"\\)",c:b("\\(","\\)")},{b:"%r\\[",e:"\\]",c:b("\\[","\\]")},{b:"%r{",e:"}",c:b("{","}")},{b:"%r<",e:">",c:b("<",">")},{b:"%r/",e:"/"},{b:"%r%",e:"%"},{b:"%r-",e:"-"},{b:"%r\\|",e:"\\|"}],r:0},w={cN:"meta",b:"@\\[",e:"\\]",c:[e.inherit(e.QSM,{cN:"meta-string"})]},f=[a,l,u,_,o,w,e.HCM,{cN:"class",bK:"class module struct",e:"$|;",i:/=/,c:[e.HCM,e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<"}]},{cN:"class",bK:"lib enum union",e:"$|;",i:/=/,c:[e.HCM,e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"})],r:10},{cN:"function",bK:"def",e:/\B\b/,c:[e.inherit(e.TM,{b:n,endsParent:!0})]},{cN:"function",bK:"fun macro",e:/\B\b/,c:[e.inherit(e.TM,{b:n,endsParent:!0})],r:5},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[l,{b:n}],r:0},{cN:"number",v:[{b:"\\b0b([01_]*[01])"+r},{b:"\\b0o([0-7_]*[0-7])"+r},{b:"\\b0x([A-Fa-f0-9_]*[A-Fa-f0-9])"+r},{b:"\\b(([0-9][0-9_]*[0-9]|[0-9])(\\.[0-9_]*[0-9])?([eE][+-]?[0-9_]*[0-9])?)"+r}],r:0}];return t.c=f,a.c=f.slice(1),{aliases:["cr"],l:c,k:s,c:f}});hljs.registerLanguage("rsl",function(e){return{k:{keyword:"float color point normal vector matrix while for if do return else break extern continue",built_in:"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},i:"|<-"}],i:/;/}});hljs.registerLanguage("bnf",function(e){return{c:[{cN:"attribute",b://},{b:/::=/,starts:{e:/$/,c:[{b://},e.CLCM,e.CBCM,e.ASM,e.QSM]}}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("dockerfile",function(e){return{aliases:["docker"],cI:!0,k:"from maintainer expose env arg user onbuild stopsignal",c:[e.HCM,e.ASM,e.QSM,e.NM,{bK:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{e:/[^\\]\n/,sL:"bash"}}],i:"",i:"\\n"}]},a,e.CLCM,e.CBCM]},i={cN:"variable",b:"\\&[a-z\\d_]*\\b"},r={cN:"meta-keyword",b:"/[a-z][a-z\\d-]*/"},d={cN:"symbol",b:"^\\s*[a-zA-Z_][a-zA-Z\\d_]*:"},n={cN:"params",b:"<",e:">",c:[c,i]},s={cN:"class",b:/[a-zA-Z_][a-zA-Z\d_@]*\s{/,e:/[{;=]/,rB:!0,eE:!0},t={cN:"class",b:"/\\s*{",e:"};",r:10,c:[i,r,d,s,n,e.CLCM,e.CBCM,c,a]};return{k:"",c:[t,i,r,d,s,n,e.CLCM,e.CBCM,c,a,b,{b:e.IR+"::",k:""}]}});hljs.registerLanguage("prolog",function(c){var b={b:/[a-z][A-Za-z0-9_]*/,r:0},r={cN:"symbol",v:[{b:/[A-Z][a-zA-Z0-9_]*/},{b:/_[A-Za-z0-9_]*/}],r:0},e={b:/\(/,e:/\)/,r:0},n={b:/\[/,e:/\]/},a={cN:"comment",b:/%/,e:/$/,c:[c.PWM]},t={cN:"string",b:/`/,e:/`/,c:[c.BE]},g={cN:"string",b:/0\'(\\\'|.)/},s={cN:"string",b:/0\'\\s/},o={b:/:-/},N=[b,r,e,o,n,a,c.CBCM,c.QSM,c.ASM,t,g,s,c.CNM];return e.c=N,n.c=N,{c:N.concat([{b:/\.$/}])}});hljs.registerLanguage("1c",function(s){var x="[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+",o="далее ",m="возврат вызватьисключение выполнить для если и из или иначе иначеесли исключение каждого конецесли конецпопытки конеццикла не новый перейти перем по пока попытка прервать продолжить тогда цикл экспорт ",t=o+m,l="загрузитьизфайла ",e="вебклиент вместо внешнеесоединение клиент конецобласти мобильноеприложениеклиент мобильноеприложениесервер наклиенте наклиентенасервере наклиентенасерверебезконтекста насервере насерверебезконтекста область перед после сервер толстыйклиентобычноеприложение толстыйклиентуправляемоеприложение тонкийклиент ",n=l+e,a="разделительстраниц разделительстрок символтабуляции ",d="ansitooem oemtoansi ввестивидсубконто ввестиперечисление ввестипериод ввестиплансчетов выбранныйплансчетов датагод датамесяц датачисло заголовоксистемы значениевстроку значениеизстроки каталогиб каталогпользователя кодсимв конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лог лог10 максимальноеколичествосубконто названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найтиссылки началопериодаби началостандартногоинтервала начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода обработкаожидания основнойжурналрасчетов основнойплансчетов основнойязык очиститьокносообщений периодстр получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта префиксавтонумерации пропись пустоезначение разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо симв создатьобъект статусвозврата стрколичествострок сформироватьпозициюдокумента счетпокоду текущеевремя типзначения типзначениястр установитьтана установитьтапо фиксшаблон шаблон ",i="acos asin atan base64значение base64строка cos exp log log10 pow sin sqrt tan xmlзначение xmlстрока xmlтип xmlтипзнч активноеокно безопасныйрежим безопасныйрежимразделенияданных булево ввестидату ввестизначение ввестистроку ввестичисло возможностьчтенияxml вопрос восстановитьзначение врег выгрузитьжурналрегистрации выполнитьобработкуоповещения выполнитьпроверкуправдоступа вычислить год данныеформывзначение дата день деньгода деньнедели добавитьмесяц заблокироватьданныедляредактирования заблокироватьработупользователя завершитьработусистемы загрузитьвнешнююкомпоненту закрытьсправку записатьjson записатьxml записатьдатуjson записьжурналарегистрации заполнитьзначениясвойств запроситьразрешениепользователя запуститьприложение запуститьсистему зафиксироватьтранзакцию значениевданныеформы значениевстрокувнутр значениевфайл значениезаполнено значениеизстрокивнутр значениеизфайла изxmlтипа импортмоделиxdto имякомпьютера имяпользователя инициализироватьпредопределенныеданные информацияобошибке каталогбиблиотекимобильногоустройства каталогвременныхфайлов каталогдокументов каталогпрограммы кодироватьстроку кодлокализацииинформационнойбазы кодсимвола командасистемы конецгода конецдня конецквартала конецмесяца конецминуты конецнедели конецчаса конфигурациябазыданныхизмененадинамически конфигурацияизменена копироватьданныеформы копироватьфайл краткоепредставлениеошибки лев макс местноевремя месяц мин минута монопольныйрежим найти найтинедопустимыесимволыxml найтиокнопонавигационнойссылке найтипомеченныенаудаление найтипоссылкам найтифайлы началогода началодня началоквартала началомесяца началоминуты началонедели началочаса начатьзапросразрешенияпользователя начатьзапускприложения начатькопированиефайла начатьперемещениефайла начатьподключениевнешнейкомпоненты начатьподключениерасширенияработыскриптографией начатьподключениерасширенияработысфайлами начатьпоискфайлов начатьполучениекаталогавременныхфайлов начатьполучениекаталогадокументов начатьполучениерабочегокаталогаданныхпользователя начатьполучениефайлов начатьпомещениефайла начатьпомещениефайлов начатьсозданиедвоичныхданныхизфайла начатьсозданиекаталога начатьтранзакцию начатьудалениефайлов начатьустановкувнешнейкомпоненты начатьустановкурасширенияработыскриптографией начатьустановкурасширенияработысфайлами неделягода необходимостьзавершениясоединения номерсеансаинформационнойбазы номерсоединенияинформационнойбазы нрег нстр обновитьинтерфейс обновитьнумерациюобъектов обновитьповторноиспользуемыезначения обработкапрерыванияпользователя объединитьфайлы окр описаниеошибки оповестить оповеститьобизменении отключитьобработчикзапросанастроекклиенталицензирования отключитьобработчикожидания отключитьобработчикоповещения открытьзначение открытьиндекссправки открытьсодержаниесправки открытьсправку открытьформу открытьформумодально отменитьтранзакцию очиститьжурналрегистрации очиститьнастройкипользователя очиститьсообщения параметрыдоступа перейтипонавигационнойссылке переместитьфайл подключитьвнешнююкомпоненту подключитьобработчикзапросанастроекклиенталицензирования подключитьобработчикожидания подключитьобработчикоповещения подключитьрасширениеработыскриптографией подключитьрасширениеработысфайлами подробноепредставлениеошибки показатьвводдаты показатьвводзначения показатьвводстроки показатьвводчисла показатьвопрос показатьзначение показатьинформациюобошибке показатьнакарте показатьоповещениепользователя показатьпредупреждение полноеимяпользователя получитьcomобъект получитьxmlтип получитьадреспоместоположению получитьблокировкусеансов получитьвремязавершенияспящегосеанса получитьвремязасыпанияпассивногосеанса получитьвремяожиданияблокировкиданных получитьданныевыбора получитьдополнительныйпараметрклиенталицензирования получитьдопустимыекодылокализации получитьдопустимыечасовыепояса получитьзаголовокклиентскогоприложения получитьзаголовоксистемы получитьзначенияотборажурналарегистрации получитьидентификаторконфигурации получитьизвременногохранилища получитьимявременногофайла получитьимяклиенталицензирования получитьинформациюэкрановклиента получитьиспользованиежурналарегистрации получитьиспользованиесобытияжурналарегистрации получитькраткийзаголовокприложения получитьмакетоформления получитьмаскувсефайлы получитьмаскувсефайлыклиента получитьмаскувсефайлысервера получитьместоположениепоадресу получитьминимальнуюдлинупаролейпользователей получитьнавигационнуюссылку получитьнавигационнуюссылкуинформационнойбазы получитьобновлениеконфигурациибазыданных получитьобновлениепредопределенныхданныхинформационнойбазы получитьобщиймакет получитьобщуюформу получитьокна получитьоперативнуюотметкувремени получитьотключениебезопасногорежима получитьпараметрыфункциональныхопцийинтерфейса получитьполноеимяпредопределенногозначения получитьпредставлениянавигационныхссылок получитьпроверкусложностипаролейпользователей получитьразделительпути получитьразделительпутиклиента получитьразделительпутисервера получитьсеансыинформационнойбазы получитьскоростьклиентскогосоединения получитьсоединенияинформационнойбазы получитьсообщенияпользователю получитьсоответствиеобъектаиформы получитьсоставстандартногоинтерфейсаodata получитьструктурухранениябазыданных получитьтекущийсеансинформационнойбазы получитьфайл получитьфайлы получитьформу получитьфункциональнуюопцию получитьфункциональнуюопциюинтерфейса получитьчасовойпоясинформационнойбазы пользователиос поместитьвовременноехранилище поместитьфайл поместитьфайлы прав праводоступа предопределенноезначение представлениекодалокализации представлениепериода представлениеправа представлениеприложения представлениесобытияжурналарегистрации представлениечасовогопояса предупреждение прекратитьработусистемы привилегированныйрежим продолжитьвызов прочитатьjson прочитатьxml прочитатьдатуjson пустаястрока рабочийкаталогданныхпользователя разблокироватьданныедляредактирования разделитьфайл разорватьсоединениесвнешнимисточникомданных раскодироватьстроку рольдоступна секунда сигнал символ скопироватьжурналрегистрации смещениелетнеговремени смещениестандартноговремени соединитьбуферыдвоичныхданных создатькаталог создатьфабрикуxdto сокрл сокрлп сокрп сообщить состояние сохранитьзначение сохранитьнастройкипользователя сред стрдлина стрзаканчиваетсяна стрзаменить стрнайти стрначинаетсяс строка строкасоединенияинформационнойбазы стрполучитьстроку стрразделить стрсоединить стрсравнить стрчисловхождений стрчислострок стршаблон текущаядата текущаядатасеанса текущаяуниверсальнаядата текущаяуниверсальнаядатавмиллисекундах текущийвариантинтерфейсаклиентскогоприложения текущийвариантосновногошрифтаклиентскогоприложения текущийкодлокализации текущийрежимзапуска текущийязык текущийязыксистемы тип типзнч транзакцияактивна трег удалитьданныеинформационнойбазы удалитьизвременногохранилища удалитьобъекты удалитьфайлы универсальноевремя установитьбезопасныйрежим установитьбезопасныйрежимразделенияданных установитьблокировкусеансов установитьвнешнююкомпоненту установитьвремязавершенияспящегосеанса установитьвремязасыпанияпассивногосеанса установитьвремяожиданияблокировкиданных установитьзаголовокклиентскогоприложения установитьзаголовоксистемы установитьиспользованиежурналарегистрации установитьиспользованиесобытияжурналарегистрации установитькраткийзаголовокприложения установитьминимальнуюдлинупаролейпользователей установитьмонопольныйрежим установитьнастройкиклиенталицензирования установитьобновлениепредопределенныхданныхинформационнойбазы установитьотключениебезопасногорежима установитьпараметрыфункциональныхопцийинтерфейса установитьпривилегированныйрежим установитьпроверкусложностипаролейпользователей установитьрасширениеработыскриптографией установитьрасширениеработысфайлами установитьсоединениесвнешнимисточникомданных установитьсоответствиеобъектаиформы установитьсоставстандартногоинтерфейсаodata установитьчасовойпоясинформационнойбазы установитьчасовойпояссеанса формат цел час часовойпояс часовойпояссеанса число числопрописью этоадресвременногохранилища ",c="wsссылки библиотекакартинок библиотекамакетовоформлениякомпоновкиданных библиотекастилей бизнеспроцессы внешниеисточникиданных внешниеобработки внешниеотчеты встроенныепокупки главныйинтерфейс главныйстиль документы доставляемыеуведомления журналыдокументов задачи информацияобинтернетсоединении использованиерабочейдаты историяработыпользователя константы критерииотбора метаданные обработки отображениерекламы отправкадоставляемыхуведомлений отчеты панельзадачос параметрзапуска параметрысеанса перечисления планывидоврасчета планывидовхарактеристик планыобмена планысчетов полнотекстовыйпоиск пользователиинформационнойбазы последовательности проверкавстроенныхпокупок рабочаядата расширенияконфигурации регистрыбухгалтерии регистрынакопления регистрырасчета регистрысведений регламентныезадания сериализаторxdto справочники средствагеопозиционирования средствакриптографии средствамультимедиа средстваотображениярекламы средствапочты средствателефонии фабрикаxdto файловыепотоки фоновыезадания хранилищанастроек хранилищевариантовотчетов хранилищенастроекданныхформ хранилищеобщихнастроек хранилищепользовательскихнастроекдинамическихсписков хранилищепользовательскихнастроекотчетов хранилищесистемныхнастроек ",r=a+d+i+c,p="webцвета windowsцвета windowsшрифты библиотекакартинок рамкистиля символы цветастиля шрифтыстиля ",b="автоматическоесохранениеданныхформывнастройках автонумерациявформе автораздвижениесерий анимациядиаграммы вариантвыравниванияэлементовизаголовков вариантуправлениявысотойтаблицы вертикальнаяпрокруткаформы вертикальноеположение вертикальноеположениеэлемента видгруппыформы виддекорацииформы виддополненияэлементаформы видизмененияданных видкнопкиформы видпереключателя видподписейкдиаграмме видполяформы видфлажка влияниеразмеранапузырекдиаграммы горизонтальноеположение горизонтальноеположениеэлемента группировкаколонок группировкаподчиненныхэлементовформы группыиэлементы действиеперетаскивания дополнительныйрежимотображения допустимыедействияперетаскивания интервалмеждуэлементамиформы использованиевывода использованиеполосыпрокрутки используемоезначениеточкибиржевойдиаграммы историявыборапривводе источникзначенийоситочекдиаграммы источникзначенияразмерапузырькадиаграммы категориягруппыкоманд максимумсерий начальноеотображениедерева начальноеотображениесписка обновлениетекстаредактирования ориентациядендрограммы ориентациядиаграммы ориентацияметокдиаграммы ориентацияметоксводнойдиаграммы ориентацияэлементаформы отображениевдиаграмме отображениевлегендедиаграммы отображениегруппыкнопок отображениезаголовкашкалыдиаграммы отображениезначенийсводнойдиаграммы отображениезначенияизмерительнойдиаграммы отображениеинтерваладиаграммыганта отображениекнопки отображениекнопкивыбора отображениеобсужденийформы отображениеобычнойгруппы отображениеотрицательныхзначенийпузырьковойдиаграммы отображениепанелипоиска отображениеподсказки отображениепредупрежденияприредактировании отображениеразметкиполосырегулирования отображениестраницформы отображениетаблицы отображениетекстазначениядиаграммыганта отображениеуправленияобычнойгруппы отображениефигурыкнопки палитрацветовдиаграммы поведениеобычнойгруппы поддержкамасштабадендрограммы поддержкамасштабадиаграммыганта поддержкамасштабасводнойдиаграммы поисквтаблицепривводе положениезаголовкаэлементаформы положениекартинкикнопкиформы положениекартинкиэлементаграфическойсхемы положениекоманднойпанелиформы положениекоманднойпанелиэлементаформы положениеопорнойточкиотрисовки положениеподписейкдиаграмме положениеподписейшкалызначенийизмерительнойдиаграммы положениесостоянияпросмотра положениестрокипоиска положениетекстасоединительнойлинии положениеуправленияпоиском положениешкалывремени порядокотображенияточекгоризонтальнойгистограммы порядоксерийвлегендедиаграммы размеркартинки расположениезаголовкашкалыдиаграммы растягиваниеповертикалидиаграммыганта режимавтоотображениясостояния режимвводастроктаблицы режимвыборанезаполненного режимвыделениядаты режимвыделениястрокитаблицы режимвыделениятаблицы режимизмененияразмера режимизменениясвязанногозначения режимиспользованиядиалогапечати режимиспользованияпараметракоманды режиммасштабированияпросмотра режимосновногоокнаклиентскогоприложения режимоткрытияокнаформы режимотображениявыделения режимотображениягеографическойсхемы режимотображениязначенийсерии режимотрисовкисеткиграфическойсхемы режимполупрозрачностидиаграммы режимпробеловдиаграммы режимразмещениянастранице режимредактированияколонки режимсглаживаниядиаграммы режимсглаживанияиндикатора режимсписказадач сквозноевыравнивание сохранениеданныхформывнастройках способзаполнениятекстазаголовкашкалыдиаграммы способопределенияограничивающегозначениядиаграммы стандартнаягруппакоманд стандартноеоформление статусоповещенияпользователя стильстрелки типаппроксимациилиниитрендадиаграммы типдиаграммы типединицышкалывремени типимпортасерийслоягеографическойсхемы типлиниигеографическойсхемы типлиниидиаграммы типмаркерагеографическойсхемы типмаркерадиаграммы типобластиоформления типорганизацииисточникаданныхгеографическойсхемы типотображениясериислоягеографическойсхемы типотображенияточечногообъектагеографическойсхемы типотображенияшкалыэлементалегендыгеографическойсхемы типпоискаобъектовгеографическойсхемы типпроекциигеографическойсхемы типразмещенияизмерений типразмещенияреквизитовизмерений типрамкиэлементауправления типсводнойдиаграммы типсвязидиаграммыганта типсоединениязначенийпосериямдиаграммы типсоединенияточекдиаграммы типсоединительнойлинии типстороныэлементаграфическойсхемы типформыотчета типшкалырадарнойдиаграммы факторлиниитрендадиаграммы фигуракнопки фигурыграфическойсхемы фиксациявтаблице форматдняшкалывремени форматкартинки ширинаподчиненныхэлементовформы ",w="виддвижениябухгалтерии виддвижениянакопления видпериодарегистрарасчета видсчета видточкимаршрутабизнеспроцесса использованиеагрегатарегистранакопления использованиегруппиэлементов использованиережимапроведения использованиесреза периодичностьагрегатарегистранакопления режимавтовремя режимзаписидокумента режимпроведениядокумента ",h="авторегистрацияизменений допустимыйномерсообщения отправкаэлементаданных получениеэлементаданных ",j="использованиерасшифровкитабличногодокумента ориентациястраницы положениеитоговколоноксводнойтаблицы положениеитоговстроксводнойтаблицы положениетекстаотносительнокартинки расположениезаголовкагруппировкитабличногодокумента способчтениязначенийтабличногодокумента типдвустороннейпечати типзаполненияобластитабличногодокумента типкурсоровтабличногодокумента типлиниирисункатабличногодокумента типлинииячейкитабличногодокумента типнаправленияпереходатабличногодокумента типотображениявыделениятабличногодокумента типотображениялинийсводнойтаблицы типразмещениятекстатабличногодокумента типрисункатабличногодокумента типсмещениятабличногодокумента типузоратабличногодокумента типфайлатабличногодокумента точностьпечати чередованиерасположениястраниц ",z="отображениевремениэлементовпланировщика ",f="типфайлаформатированногодокумента ",k="обходрезультатазапроса типзаписизапроса ",u="видзаполнениярасшифровкипостроителяотчета типдобавленияпредставлений типизмеренияпостроителяотчета типразмещенияитогов ",y="доступкфайлу режимдиалогавыборафайла режимоткрытияфайла ",N="типизмеренияпостроителязапроса ",g="видданныханализа методкластеризации типединицыинтервалавременианализаданных типзаполнениятаблицырезультатаанализаданных типиспользованиячисловыхзначенийанализаданных типисточникаданныхпоискаассоциаций типколонкианализаданныхдереворешений типколонкианализаданныхкластеризация типколонкианализаданныхобщаястатистика типколонкианализаданныхпоискассоциаций типколонкианализаданныхпоискпоследовательностей типколонкимоделипрогноза типмерырасстоянияанализаданных типотсеченияправилассоциации типполяанализаданных типстандартизациианализаданных типупорядочиванияправилассоциациианализаданных типупорядочиванияшаблоновпоследовательностейанализаданных типупрощениядереварешений ",E="wsнаправлениепараметра вариантxpathxs вариантзаписидатыjson вариантпростоготипаxs видгруппымоделиxs видфасетаxdto действиепостроителяdom завершенностьпростоготипаxs завершенностьсоставноготипаxs завершенностьсхемыxs запрещенныеподстановкиxs исключениягруппподстановкиxs категорияиспользованияатрибутаxs категорияограниченияидентичностиxs категорияограниченияпространствименxs методнаследованияxs модельсодержимогоxs назначениетипаxml недопустимыеподстановкиxs обработкапробельныхсимволовxs обработкасодержимогоxs ограничениезначенияxs параметрыотбораузловdom переносстрокjson позициявдокументеdom пробельныесимволыxml типатрибутаxml типзначенияjson типканоническогоxml типкомпонентыxs типпроверкиxml типрезультатаdomxpath типузлаdom типузлаxml формаxml формапредставленияxs форматдатыjson экранированиесимволовjson ",M="видсравнениякомпоновкиданных действиеобработкирасшифровкикомпоновкиданных направлениесортировкикомпоновкиданных расположениевложенныхэлементоврезультатакомпоновкиданных расположениеитоговкомпоновкиданных расположениегруппировкикомпоновкиданных расположениеполейгруппировкикомпоновкиданных расположениеполякомпоновкиданных расположениереквизитовкомпоновкиданных расположениересурсовкомпоновкиданных типбухгалтерскогоостаткакомпоновкиданных типвыводатекстакомпоновкиданных типгруппировкикомпоновкиданных типгруппыэлементовотборакомпоновкиданных типдополненияпериодакомпоновкиданных типзаголовкаполейкомпоновкиданных типмакетагруппировкикомпоновкиданных типмакетаобластикомпоновкиданных типостаткакомпоновкиданных типпериодакомпоновкиданных типразмещениятекстакомпоновкиданных типсвязинаборовданныхкомпоновкиданных типэлементарезультатакомпоновкиданных расположениелегендыдиаграммыкомпоновкиданных типпримененияотборакомпоновкиданных режимотображенияэлементанастройкикомпоновкиданных режимотображениянастроеккомпоновкиданных состояниеэлементанастройкикомпоновкиданных способвосстановлениянастроеккомпоновкиданных режимкомпоновкирезультата использованиепараметракомпоновкиданных автопозицияресурсовкомпоновкиданных вариантиспользованиягруппировкикомпоновкиданных расположениересурсоввдиаграммекомпоновкиданных фиксациякомпоновкиданных использованиеусловногооформлениякомпоновкиданных ",_="важностьинтернетпочтовогосообщения обработкатекстаинтернетпочтовогосообщения способкодированияинтернетпочтовоговложения способкодированиянеasciiсимволовинтернетпочтовогосообщения типтекстапочтовогосообщения протоколинтернетпочты статусразборапочтовогосообщения ",v="режимтранзакциизаписижурналарегистрации статустранзакциизаписижурналарегистрации уровеньжурналарегистрации ",A="расположениехранилищасертификатовкриптографии режимвключениясертификатовкриптографии режимпроверкисертификатакриптографии типхранилищасертификатовкриптографии ",C="кодировкаименфайловвzipфайле методсжатияzip методшифрованияzip режимвосстановленияпутейфайловzip режимобработкиподкаталоговzip режимсохраненияпутейzip уровеньсжатияzip ",L="звуковоеоповещение направлениепереходакстроке позициявпотоке порядокбайтов режимблокировкиданных режимуправленияблокировкойданных сервисвстроенныхпокупок состояниефоновогозадания типподписчикадоставляемыхуведомлений уровеньиспользованиязащищенногосоединенияftp ",Z="направлениепорядкасхемызапроса типдополненияпериодамисхемызапроса типконтрольнойточкисхемызапроса типобъединениясхемызапроса типпараметрадоступнойтаблицысхемызапроса типсоединениясхемызапроса ",$="httpметод автоиспользованиеобщегореквизита автопрефиксномеразадачи вариантвстроенногоязыка видиерархии видрегистранакопления видтаблицывнешнегоисточникаданных записьдвиженийприпроведении заполнениепоследовательностей индексирование использованиебазыпланавидоврасчета использованиебыстроговыбора использованиеобщегореквизита использованиеподчинения использованиеполнотекстовогопоиска использованиеразделяемыхданныхобщегореквизита использованиереквизита назначениеиспользованияприложения назначениерасширенияконфигурации направлениепередачи обновлениепредопределенныхданных оперативноепроведение основноепредставлениевидарасчета основноепредставлениевидахарактеристики основноепредставлениезадачи основноепредставлениепланаобмена основноепредставлениесправочника основноепредставлениесчета перемещениеграницыприпроведении периодичностьномерабизнеспроцесса периодичностьномерадокумента периодичностьрегистрарасчета периодичностьрегистрасведений повторноеиспользованиевозвращаемыхзначений полнотекстовыйпоискпривводепостроке принадлежностьобъекта проведение разделениеаутентификацииобщегореквизита разделениеданныхобщегореквизита разделениерасширенийконфигурацииобщегореквизита режимавтонумерацииобъектов режимзаписирегистра режимиспользованиямодальности режимиспользованиясинхронныхвызововрасширенийплатформыивнешнихкомпонент режимповторногоиспользованиясеансов режимполученияданныхвыборапривводепостроке режимсовместимости режимсовместимостиинтерфейса режимуправленияблокировкойданныхпоумолчанию сериикодовпланавидовхарактеристик сериикодовпланасчетов сериикодовсправочника созданиепривводе способвыбора способпоискастрокипривводепостроке способредактирования типданныхтаблицывнешнегоисточникаданных типкодапланавидоврасчета типкодасправочника типмакета типномерабизнеспроцесса типномерадокумента типномеразадачи типформы удалениедвижений ",q="важностьпроблемыприменениярасширенияконфигурации вариантинтерфейсаклиентскогоприложения вариантмасштабаформклиентскогоприложения вариантосновногошрифтаклиентскогоприложения вариантстандартногопериода вариантстандартнойдатыначала видграницы видкартинки видотображенияполнотекстовогопоиска видрамки видсравнения видцвета видчисловогозначения видшрифта допустимаядлина допустимыйзнак использованиеbyteordermark использованиеметаданныхполнотекстовогопоиска источникрасширенийконфигурации клавиша кодвозвратадиалога кодировкаxbase кодировкатекста направлениепоиска направлениесортировки обновлениепредопределенныхданных обновлениеприизмененииданных отображениепанелиразделов проверказаполнения режимдиалогавопрос режимзапускаклиентскогоприложения режимокругления режимоткрытияформприложения режимполнотекстовогопоиска скоростьклиентскогосоединения состояниевнешнегоисточникаданных состояниеобновленияконфигурациибазыданных способвыборасертификатаwindows способкодированиястроки статуссообщения типвнешнейкомпоненты типплатформы типповеденияклавишиenter типэлементаинформацииовыполненииобновленияконфигурациибазыданных уровеньизоляциитранзакций хешфункция частидаты",B=p+b+w+h+j+z+f+k+u+y+N+g+E+M+_+v+A+C+L+Z+$+q,I="comобъект ftpсоединение httpзапрос httpсервисответ httpсоединение wsопределения wsпрокси xbase анализданных аннотацияxs блокировкаданных буфердвоичныхданных включениеxs выражениекомпоновкиданных генераторслучайныхчисел географическаясхема географическиекоординаты графическаясхема группамоделиxs данныерасшифровкикомпоновкиданных двоичныеданные дендрограмма диаграмма диаграммаганта диалогвыборафайла диалогвыборацвета диалогвыборашрифта диалограсписаниярегламентногозадания диалогредактированиястандартногопериода диапазон документdom документhtml документацияxs доставляемоеуведомление записьdom записьfastinfoset записьhtml записьjson записьxml записьzipфайла записьданных записьтекста записьузловdom запрос защищенноесоединениеopenssl значенияполейрасшифровкикомпоновкиданных извлечениетекста импортxs интернетпочта интернетпочтовоесообщение интернетпочтовыйпрофиль интернетпрокси интернетсоединение информациядляприложенияxs использованиеатрибутаxs использованиесобытияжурналарегистрации источникдоступныхнастроеккомпоновкиданных итераторузловdom картинка квалификаторыдаты квалификаторыдвоичныхданных квалификаторыстроки квалификаторычисла компоновщикмакетакомпоновкиданных компоновщикнастроеккомпоновкиданных конструктормакетаоформлениякомпоновкиданных конструкторнастроеккомпоновкиданных конструкторформатнойстроки линия макеткомпоновкиданных макетобластикомпоновкиданных макетоформлениякомпоновкиданных маскаxs менеджеркриптографии наборсхемxml настройкикомпоновкиданных настройкисериализацииjson обработкакартинок обработкарасшифровкикомпоновкиданных обходдереваdom объявлениеатрибутаxs объявлениенотацииxs объявлениеэлементаxs описаниеиспользованиясобытиядоступжурналарегистрации описаниеиспользованиясобытияотказвдоступежурналарегистрации описаниеобработкирасшифровкикомпоновкиданных описаниепередаваемогофайла описаниетипов определениегруппыатрибутовxs определениегруппымоделиxs определениеограниченияидентичностиxs определениепростоготипаxs определениесоставноготипаxs определениетипадокументаdom определенияxpathxs отборкомпоновкиданных пакетотображаемыхдокументов параметрвыбора параметркомпоновкиданных параметрызаписиjson параметрызаписиxml параметрычтенияxml переопределениеxs планировщик полеанализаданных полекомпоновкиданных построительdom построительзапроса построительотчета построительотчетаанализаданных построительсхемxml поток потоквпамяти почта почтовоесообщение преобразованиеxsl преобразованиекканоническомуxml процессорвыводарезультатакомпоновкиданныхвколлекциюзначений процессорвыводарезультатакомпоновкиданныхвтабличныйдокумент процессоркомпоновкиданных разыменовательпространствименdom рамка расписаниерегламентногозадания расширенноеимяxml результатчтенияданных своднаядиаграмма связьпараметравыбора связьпотипу связьпотипукомпоновкиданных сериализаторxdto сертификатклиентаwindows сертификатклиентафайл сертификаткриптографии сертификатыудостоверяющихцентровwindows сертификатыудостоверяющихцентровфайл сжатиеданных системнаяинформация сообщениепользователю сочетаниеклавиш сравнениезначений стандартнаядатаначала стандартныйпериод схемаxml схемакомпоновкиданных табличныйдокумент текстовыйдокумент тестируемоеприложение типданныхxml уникальныйидентификатор фабрикаxdto файл файловыйпоток фасетдлиныxs фасетколичестваразрядовдробнойчастиxs фасетмаксимальноговключающегозначенияxs фасетмаксимальногоисключающегозначенияxs фасетмаксимальнойдлиныxs фасетминимальноговключающегозначенияxs фасетминимальногоисключающегозначенияxs фасетминимальнойдлиныxs фасетобразцаxs фасетобщегоколичестваразрядовxs фасетперечисленияxs фасетпробельныхсимволовxs фильтрузловdom форматированнаястрока форматированныйдокумент фрагментxs хешированиеданных хранилищезначения цвет чтениеfastinfoset чтениеhtml чтениеjson чтениеxml чтениеzipфайла чтениеданных чтениетекста чтениеузловdom шрифт элементрезультатакомпоновкиданных ",P="comsafearray деревозначений массив соответствие списокзначений структура таблицазначений фиксированнаяструктура фиксированноесоответствие фиксированныймассив ",T=I+P,W="null истина ложь неопределено",D=s.inherit(s.NM),F={cN:"string",b:'"|\\|',e:'"|$',c:[{b:'""'}]},G={b:"'",e:"'",eB:!0,eE:!0,c:[{cN:"number",b:"\\d{4}([\\.\\\\/:-]?\\d{2}){0,5}"}]},H=s.inherit(s.CLCM),J={cN:"meta",l:x,b:"#|&",e:"$",k:{"meta-keyword":t+n},c:[H]},K={cN:"symbol",b:"~",e:";|:",eE:!0},O={cN:"function",l:x,v:[{b:"процедура|функция",e:"\\)",k:"процедура функция"},{b:"конецпроцедуры|конецфункции",k:"конецпроцедуры конецфункции"}],c:[{b:"\\(",e:"\\)",endsParent:!0,c:[{cN:"params",l:x,b:x,e:",",eE:!0,eW:!0,k:{keyword:"знач",literal:W},c:[D,F,G]},H]},s.inherit(s.TM,{b:x})]};return{cI:!0,l:x,k:{keyword:t,built_in:r,"class":B,type:T,literal:W},c:[J,O,H,K,D,F,G]}});hljs.registerLanguage("thrift",function(e){var t="bool byte i16 i32 i64 double string binary";return{k:{keyword:"namespace const typedef struct enum service exception void oneway set list map required optional",built_in:t,literal:"true false"},c:[e.QSM,e.NM,e.CLCM,e.CBCM,{cN:"class",bK:"struct enum service exception",e:/\{/,i:/\n/,c:[e.inherit(e.TM,{starts:{eW:!0,eE:!0}})]},{b:"\\b(set|list|map)\\s*<",e:">",k:t,c:["self"]}]}});hljs.registerLanguage("gauss",function(e){var t={keyword:"and bool break call callexe checkinterrupt clear clearg closeall cls comlog compile continue create debug declare delete disable dlibrary dllcall do dos ed edit else elseif enable end endfor endif endp endo errorlog errorlogat expr external fn for format goto gosub graph if keyword let lib library line load loadarray loadexe loadf loadk loadm loadp loads loadx local locate loopnextindex lprint lpwidth lshow matrix msym ndpclex new not open or output outwidth plot plotsym pop prcsn print printdos proc push retp return rndcon rndmod rndmult rndseed run save saveall screen scroll setarray show sparse stop string struct system trace trap threadfor threadendfor threadbegin threadjoin threadstat threadend until use while winprint",built_in:"abs acf aconcat aeye amax amean AmericanBinomCall AmericanBinomCall_Greeks AmericanBinomCall_ImpVol AmericanBinomPut AmericanBinomPut_Greeks AmericanBinomPut_ImpVol AmericanBSCall AmericanBSCall_Greeks AmericanBSCall_ImpVol AmericanBSPut AmericanBSPut_Greeks AmericanBSPut_ImpVol amin amult annotationGetDefaults annotationSetBkd annotationSetFont annotationSetLineColor annotationSetLineStyle annotationSetLineThickness annualTradingDays arccos arcsin areshape arrayalloc arrayindex arrayinit arraytomat asciiload asclabel astd astds asum atan atan2 atranspose axmargin balance band bandchol bandcholsol bandltsol bandrv bandsolpd bar base10 begwind besselj bessely beta box boxcox cdfBeta cdfBetaInv cdfBinomial cdfBinomialInv cdfBvn cdfBvn2 cdfBvn2e cdfCauchy cdfCauchyInv cdfChic cdfChii cdfChinc cdfChincInv cdfExp cdfExpInv cdfFc cdfFnc cdfFncInv cdfGam cdfGenPareto cdfHyperGeo cdfLaplace cdfLaplaceInv cdfLogistic cdfLogisticInv cdfmControlCreate cdfMvn cdfMvn2e cdfMvnce cdfMvne cdfMvt2e cdfMvtce cdfMvte cdfN cdfN2 cdfNc cdfNegBinomial cdfNegBinomialInv cdfNi cdfPoisson cdfPoissonInv cdfRayleigh cdfRayleighInv cdfTc cdfTci cdfTnc cdfTvn cdfWeibull cdfWeibullInv cdir ceil ChangeDir chdir chiBarSquare chol choldn cholsol cholup chrs close code cols colsf combinate combinated complex con cond conj cons ConScore contour conv convertsatostr convertstrtosa corrm corrms corrvc corrx corrxs cos cosh counts countwts crossprd crout croutp csrcol csrlin csvReadM csvReadSA cumprodc cumsumc curve cvtos datacreate datacreatecomplex datalist dataload dataloop dataopen datasave date datestr datestring datestrymd dayinyr dayofweek dbAddDatabase dbClose dbCommit dbCreateQuery dbExecQuery dbGetConnectOptions dbGetDatabaseName dbGetDriverName dbGetDrivers dbGetHostName dbGetLastErrorNum dbGetLastErrorText dbGetNumericalPrecPolicy dbGetPassword dbGetPort dbGetTableHeaders dbGetTables dbGetUserName dbHasFeature dbIsDriverAvailable dbIsOpen dbIsOpenError dbOpen dbQueryBindValue dbQueryClear dbQueryCols dbQueryExecPrepared dbQueryFetchAllM dbQueryFetchAllSA dbQueryFetchOneM dbQueryFetchOneSA dbQueryFinish dbQueryGetBoundValue dbQueryGetBoundValues dbQueryGetField dbQueryGetLastErrorNum dbQueryGetLastErrorText dbQueryGetLastInsertID dbQueryGetLastQuery dbQueryGetPosition dbQueryIsActive dbQueryIsForwardOnly dbQueryIsNull dbQueryIsSelect dbQueryIsValid dbQueryPrepare dbQueryRows dbQuerySeek dbQuerySeekFirst dbQuerySeekLast dbQuerySeekNext dbQuerySeekPrevious dbQuerySetForwardOnly dbRemoveDatabase dbRollback dbSetConnectOptions dbSetDatabaseName dbSetHostName dbSetNumericalPrecPolicy dbSetPort dbSetUserName dbTransaction DeleteFile delif delrows denseToSp denseToSpRE denToZero design det detl dfft dffti diag diagrv digamma doswin DOSWinCloseall DOSWinOpen dotfeq dotfeqmt dotfge dotfgemt dotfgt dotfgtmt dotfle dotflemt dotflt dotfltmt dotfne dotfnemt draw drop dsCreate dstat dstatmt dstatmtControlCreate dtdate dtday dttime dttodtv dttostr dttoutc dtvnormal dtvtodt dtvtoutc dummy dummybr dummydn eig eigh eighv eigv elapsedTradingDays endwind envget eof eqSolve eqSolvemt eqSolvemtControlCreate eqSolvemtOutCreate eqSolveset erf erfc erfccplx erfcplx error etdays ethsec etstr EuropeanBinomCall EuropeanBinomCall_Greeks EuropeanBinomCall_ImpVol EuropeanBinomPut EuropeanBinomPut_Greeks EuropeanBinomPut_ImpVol EuropeanBSCall EuropeanBSCall_Greeks EuropeanBSCall_ImpVol EuropeanBSPut EuropeanBSPut_Greeks EuropeanBSPut_ImpVol exctsmpl exec execbg exp extern eye fcheckerr fclearerr feq feqmt fflush fft ffti fftm fftmi fftn fge fgemt fgets fgetsa fgetsat fgetst fgt fgtmt fileinfo filesa fle flemt floor flt fltmt fmod fne fnemt fonts fopen formatcv formatnv fputs fputst fseek fstrerror ftell ftocv ftos ftostrC gamma gammacplx gammaii gausset gdaAppend gdaCreate gdaDStat gdaDStatMat gdaGetIndex gdaGetName gdaGetNames gdaGetOrders gdaGetType gdaGetTypes gdaGetVarInfo gdaIsCplx gdaLoad gdaPack gdaRead gdaReadByIndex gdaReadSome gdaReadSparse gdaReadStruct gdaReportVarInfo gdaSave gdaUpdate gdaUpdateAndPack gdaVars gdaWrite gdaWrite32 gdaWriteSome getarray getdims getf getGAUSShome getmatrix getmatrix4D getname getnamef getNextTradingDay getNextWeekDay getnr getorders getpath getPreviousTradingDay getPreviousWeekDay getRow getscalar3D getscalar4D getTrRow getwind glm gradcplx gradMT gradMTm gradMTT gradMTTm gradp graphprt graphset hasimag header headermt hess hessMT hessMTg hessMTgw hessMTm hessMTmw hessMTT hessMTTg hessMTTgw hessMTTm hessMTw hessp hist histf histp hsec imag indcv indexcat indices indices2 indicesf indicesfn indnv indsav integrate1d integrateControlCreate intgrat2 intgrat3 inthp1 inthp2 inthp3 inthp4 inthpControlCreate intquad1 intquad2 intquad3 intrleav intrleavsa intrsect intsimp inv invpd invswp iscplx iscplxf isden isinfnanmiss ismiss key keyav keyw lag lag1 lagn lapEighb lapEighi lapEighvb lapEighvi lapgEig lapgEigh lapgEighv lapgEigv lapgSchur lapgSvdcst lapgSvds lapgSvdst lapSvdcusv lapSvds lapSvdusv ldlp ldlsol linSolve listwise ln lncdfbvn lncdfbvn2 lncdfmvn lncdfn lncdfn2 lncdfnc lnfact lngammacplx lnpdfmvn lnpdfmvt lnpdfn lnpdft loadd loadstruct loadwind loess loessmt loessmtControlCreate log loglog logx logy lower lowmat lowmat1 ltrisol lu lusol machEpsilon make makevars makewind margin matalloc matinit mattoarray maxbytes maxc maxindc maxv maxvec mbesselei mbesselei0 mbesselei1 mbesseli mbesseli0 mbesseli1 meanc median mergeby mergevar minc minindc minv miss missex missrv moment momentd movingave movingaveExpwgt movingaveWgt nextindex nextn nextnevn nextwind ntos null null1 numCombinations ols olsmt olsmtControlCreate olsqr olsqr2 olsqrmt ones optn optnevn orth outtyp pacf packedToSp packr parse pause pdfCauchy pdfChi pdfExp pdfGenPareto pdfHyperGeo pdfLaplace pdfLogistic pdfn pdfPoisson pdfRayleigh pdfWeibull pi pinv pinvmt plotAddArrow plotAddBar plotAddBox plotAddHist plotAddHistF plotAddHistP plotAddPolar plotAddScatter plotAddShape plotAddTextbox plotAddTS plotAddXY plotArea plotBar plotBox plotClearLayout plotContour plotCustomLayout plotGetDefaults plotHist plotHistF plotHistP plotLayout plotLogLog plotLogX plotLogY plotOpenWindow plotPolar plotSave plotScatter plotSetAxesPen plotSetBar plotSetBarFill plotSetBarStacked plotSetBkdColor plotSetFill plotSetGrid plotSetLegend plotSetLineColor plotSetLineStyle plotSetLineSymbol plotSetLineThickness plotSetNewWindow plotSetTitle plotSetWhichYAxis plotSetXAxisShow plotSetXLabel plotSetXRange plotSetXTicInterval plotSetXTicLabel plotSetYAxisShow plotSetYLabel plotSetYRange plotSetZAxisShow plotSetZLabel plotSurface plotTS plotXY polar polychar polyeval polygamma polyint polymake polymat polymroot polymult polyroot pqgwin previousindex princomp printfm printfmt prodc psi putarray putf putvals pvCreate pvGetIndex pvGetParNames pvGetParVector pvLength pvList pvPack pvPacki pvPackm pvPackmi pvPacks pvPacksi pvPacksm pvPacksmi pvPutParVector pvTest pvUnpack QNewton QNewtonmt QNewtonmtControlCreate QNewtonmtOutCreate QNewtonSet QProg QProgmt QProgmtInCreate qqr qqre qqrep qr qre qrep qrsol qrtsol qtyr qtyre qtyrep quantile quantiled qyr qyre qyrep qz rank rankindx readr real reclassify reclassifyCuts recode recserar recsercp recserrc rerun rescale reshape rets rev rfft rffti rfftip rfftn rfftnp rfftp rndBernoulli rndBeta rndBinomial rndCauchy rndChiSquare rndCon rndCreateState rndExp rndGamma rndGeo rndGumbel rndHyperGeo rndi rndKMbeta rndKMgam rndKMi rndKMn rndKMnb rndKMp rndKMu rndKMvm rndLaplace rndLCbeta rndLCgam rndLCi rndLCn rndLCnb rndLCp rndLCu rndLCvm rndLogNorm rndMTu rndMVn rndMVt rndn rndnb rndNegBinomial rndp rndPoisson rndRayleigh rndStateSkip rndu rndvm rndWeibull rndWishart rotater round rows rowsf rref sampleData satostrC saved saveStruct savewind scale scale3d scalerr scalinfnanmiss scalmiss schtoc schur searchsourcepath seekr select selif seqa seqm setdif setdifsa setvars setvwrmode setwind shell shiftr sin singleindex sinh sleep solpd sortc sortcc sortd sorthc sorthcc sortind sortindc sortmc sortr sortrc spBiconjGradSol spChol spConjGradSol spCreate spDenseSubmat spDiagRvMat spEigv spEye spLDL spline spLU spNumNZE spOnes spreadSheetReadM spreadSheetReadSA spreadSheetWrite spScale spSubmat spToDense spTrTDense spTScalar spZeros sqpSolve sqpSolveMT sqpSolveMTControlCreate sqpSolveMTlagrangeCreate sqpSolveMToutCreate sqpSolveSet sqrt statements stdc stdsc stocv stof strcombine strindx strlen strput strrindx strsect strsplit strsplitPad strtodt strtof strtofcplx strtriml strtrimr strtrunc strtruncl strtruncpad strtruncr submat subscat substute subvec sumc sumr surface svd svd1 svd2 svdcusv svds svdusv sysstate tab tan tanh tempname threadBegin threadEnd threadEndFor threadFor threadJoin threadStat time timedt timestr timeutc title tkf2eps tkf2ps tocart todaydt toeplitz token topolar trapchk trigamma trimr trunc type typecv typef union unionsa uniqindx uniqindxsa unique uniquesa upmat upmat1 upper utctodt utctodtv utrisol vals varCovMS varCovXS varget vargetl varmall varmares varput varputl vartypef vcm vcms vcx vcxs vec vech vecr vector vget view viewxyz vlist vnamecv volume vput vread vtypecv wait waitc walkindex where window writer xlabel xlsGetSheetCount xlsGetSheetSize xlsGetSheetTypes xlsMakeRange xlsReadM xlsReadSA xlsWrite xlsWriteM xlsWriteSA xpnd xtics xy xyz ylabel ytics zeros zeta zlabel ztics cdfEmpirical dot h5create h5open h5read h5readAttribute h5write h5writeAttribute ldl plotAddErrorBar plotAddSurface plotCDFEmpirical plotSetColormap plotSetContourLabels plotSetLegendFont plotSetTextInterpreter plotSetXTicCount plotSetYTicCount plotSetZLevels powerm strjoin strtrim sylvester",literal:"DB_AFTER_LAST_ROW DB_ALL_TABLES DB_BATCH_OPERATIONS DB_BEFORE_FIRST_ROW DB_BLOB DB_EVENT_NOTIFICATIONS DB_FINISH_QUERY DB_HIGH_PRECISION DB_LAST_INSERT_ID DB_LOW_PRECISION_DOUBLE DB_LOW_PRECISION_INT32 DB_LOW_PRECISION_INT64 DB_LOW_PRECISION_NUMBERS DB_MULTIPLE_RESULT_SETS DB_NAMED_PLACEHOLDERS DB_POSITIONAL_PLACEHOLDERS DB_PREPARED_QUERIES DB_QUERY_SIZE DB_SIMPLE_LOCKING DB_SYSTEM_TABLES DB_TABLES DB_TRANSACTIONS DB_UNICODE DB_VIEWS"},a={cN:"meta",b:"#",e:"$",k:{"meta-keyword":"define definecs|10 undef ifdef ifndef iflight ifdllcall ifmac ifos2win ifunix else endif lineson linesoff srcfile srcline"},c:[{b:/\\\n/,r:0},{bK:"include",e:"$",k:{"meta-keyword":"include"},c:[{cN:"meta-string",b:'"',e:'"',i:"\\n"}]},e.CLCM,e.CBCM]},r=e.UIR+"\\s*\\(?",o=[{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.CNM,e.CLCM,e.CBCM]}];return{aliases:["gss"],cI:!0,k:t,i:"(\\{[%#]|[%#]\\})",c:[e.CNM,e.CLCM,e.CBCM,e.C("@","@"),a,{cN:"string",b:'"',e:'"',c:[e.BE]},{cN:"function",bK:"proc keyword",e:";",eE:!0,k:t,c:[{b:r,rB:!0,c:[e.UTM],r:0},e.CNM,e.CLCM,e.CBCM,a].concat(o)},{cN:"function",bK:"fn",e:";",eE:!0,k:t,c:[{b:r+e.IR+"\\)?\\s*\\=\\s*",rB:!0,c:[e.UTM],r:0},e.CNM,e.CLCM,e.CBCM].concat(o)},{cN:"function",b:"\\bexternal (proc|keyword|fn)\\s+",e:";",eE:!0,k:t,c:[{b:r,rB:!0,c:[e.UTM],r:0},e.CLCM,e.CBCM]},{cN:"function",b:"\\bexternal (matrix|string|array|sparse matrix|struct "+e.IR+")\\s+",e:";",eE:!0,k:t,c:[e.CLCM,e.CBCM]}]}});hljs.registerLanguage("sqf",function(e){var t=e.getLanguage("cpp").exports,a={cN:"variable",b:/\b_+[a-zA-Z_]\w*/},o={cN:"title",b:/[a-zA-Z][a-zA-Z0-9]+_fnc_\w*/},r={cN:"string",v:[{b:'"',e:'"',c:[{b:'""',r:0}]},{b:"'",e:"'",c:[{b:"''",r:0}]}]};return{aliases:["sqf"],cI:!0,k:{keyword:"case catch default do else exit exitWith for forEach from if switch then throw to try waitUntil while with",built_in:"abs accTime acos action actionIDs actionKeys actionKeysImages actionKeysNames actionKeysNamesArray actionName actionParams activateAddons activatedAddons activateKey add3DENConnection add3DENEventHandler add3DENLayer addAction addBackpack addBackpackCargo addBackpackCargoGlobal addBackpackGlobal addCamShake addCuratorAddons addCuratorCameraArea addCuratorEditableObjects addCuratorEditingArea addCuratorPoints addEditorObject addEventHandler addGoggles addGroupIcon addHandgunItem addHeadgear addItem addItemCargo addItemCargoGlobal addItemPool addItemToBackpack addItemToUniform addItemToVest addLiveStats addMagazine addMagazineAmmoCargo addMagazineCargo addMagazineCargoGlobal addMagazineGlobal addMagazinePool addMagazines addMagazineTurret addMenu addMenuItem addMissionEventHandler addMPEventHandler addMusicEventHandler addOwnedMine addPlayerScores addPrimaryWeaponItem addPublicVariableEventHandler addRating addResources addScore addScoreSide addSecondaryWeaponItem addSwitchableUnit addTeamMember addToRemainsCollector addUniform addVehicle addVest addWaypoint addWeapon addWeaponCargo addWeaponCargoGlobal addWeaponGlobal addWeaponItem addWeaponPool addWeaponTurret agent agents AGLToASL aimedAtTarget aimPos airDensityRTD airportSide AISFinishHeal alive all3DENEntities allControls allCurators allCutLayers allDead allDeadMen allDisplays allGroups allMapMarkers allMines allMissionObjects allow3DMode allowCrewInImmobile allowCuratorLogicIgnoreAreas allowDamage allowDammage allowFileOperations allowFleeing allowGetIn allowSprint allPlayers allSites allTurrets allUnits allUnitsUAV allVariables ammo and animate animateDoor animateSource animationNames animationPhase animationSourcePhase animationState append apply armoryPoints arrayIntersect asin ASLToAGL ASLToATL assert assignAsCargo assignAsCargoIndex assignAsCommander assignAsDriver assignAsGunner assignAsTurret assignCurator assignedCargo assignedCommander assignedDriver assignedGunner assignedItems assignedTarget assignedTeam assignedVehicle assignedVehicleRole assignItem assignTeam assignToAirport atan atan2 atg ATLToASL attachedObject attachedObjects attachedTo attachObject attachTo attackEnabled backpack backpackCargo backpackContainer backpackItems backpackMagazines backpackSpaceFor behaviour benchmark binocular blufor boundingBox boundingBoxReal boundingCenter breakOut breakTo briefingName buildingExit buildingPos buttonAction buttonSetAction cadetMode call callExtension camCommand camCommit camCommitPrepared camCommitted camConstuctionSetParams camCreate camDestroy cameraEffect cameraEffectEnableHUD cameraInterest cameraOn cameraView campaignConfigFile camPreload camPreloaded camPrepareBank camPrepareDir camPrepareDive camPrepareFocus camPrepareFov camPrepareFovRange camPreparePos camPrepareRelPos camPrepareTarget camSetBank camSetDir camSetDive camSetFocus camSetFov camSetFovRange camSetPos camSetRelPos camSetTarget camTarget camUseNVG canAdd canAddItemToBackpack canAddItemToUniform canAddItemToVest cancelSimpleTaskDestination canFire canMove canSlingLoad canStand canSuspend canUnloadInCombat canVehicleCargo captive captiveNum cbChecked cbSetChecked ceil channelEnabled cheatsEnabled checkAIFeature checkVisibility civilian className clearAllItemsFromBackpack clearBackpackCargo clearBackpackCargoGlobal clearGroupIcons clearItemCargo clearItemCargoGlobal clearItemPool clearMagazineCargo clearMagazineCargoGlobal clearMagazinePool clearOverlay clearRadio clearWeaponCargo clearWeaponCargoGlobal clearWeaponPool clientOwner closeDialog closeDisplay closeOverlay collapseObjectTree collect3DENHistory combatMode commandArtilleryFire commandChat commander commandFire commandFollow commandFSM commandGetOut commandingMenu commandMove commandRadio commandStop commandSuppressiveFire commandTarget commandWatch comment commitOverlay compile compileFinal completedFSM composeText configClasses configFile configHierarchy configName configNull configProperties configSourceAddonList configSourceMod configSourceModList connectTerminalToUAV controlNull controlsGroupCtrl copyFromClipboard copyToClipboard copyWaypoints cos count countEnemy countFriendly countSide countType countUnknown create3DENComposition create3DENEntity createAgent createCenter createDialog createDiaryLink createDiaryRecord createDiarySubject createDisplay createGearDialog createGroup createGuardedPoint createLocation createMarker createMarkerLocal createMenu createMine createMissionDisplay createMPCampaignDisplay createSimpleObject createSimpleTask createSite createSoundSource createTask createTeam createTrigger createUnit createVehicle createVehicleCrew createVehicleLocal crew ctrlActivate ctrlAddEventHandler ctrlAngle ctrlAutoScrollDelay ctrlAutoScrollRewind ctrlAutoScrollSpeed ctrlChecked ctrlClassName ctrlCommit ctrlCommitted ctrlCreate ctrlDelete ctrlEnable ctrlEnabled ctrlFade ctrlHTMLLoaded ctrlIDC ctrlIDD ctrlMapAnimAdd ctrlMapAnimClear ctrlMapAnimCommit ctrlMapAnimDone ctrlMapCursor ctrlMapMouseOver ctrlMapScale ctrlMapScreenToWorld ctrlMapWorldToScreen ctrlModel ctrlModelDirAndUp ctrlModelScale ctrlParent ctrlParentControlsGroup ctrlPosition ctrlRemoveAllEventHandlers ctrlRemoveEventHandler ctrlScale ctrlSetActiveColor ctrlSetAngle ctrlSetAutoScrollDelay ctrlSetAutoScrollRewind ctrlSetAutoScrollSpeed ctrlSetBackgroundColor ctrlSetChecked ctrlSetEventHandler ctrlSetFade ctrlSetFocus ctrlSetFont ctrlSetFontH1 ctrlSetFontH1B ctrlSetFontH2 ctrlSetFontH2B ctrlSetFontH3 ctrlSetFontH3B ctrlSetFontH4 ctrlSetFontH4B ctrlSetFontH5 ctrlSetFontH5B ctrlSetFontH6 ctrlSetFontH6B ctrlSetFontHeight ctrlSetFontHeightH1 ctrlSetFontHeightH2 ctrlSetFontHeightH3 ctrlSetFontHeightH4 ctrlSetFontHeightH5 ctrlSetFontHeightH6 ctrlSetFontHeightSecondary ctrlSetFontP ctrlSetFontPB ctrlSetFontSecondary ctrlSetForegroundColor ctrlSetModel ctrlSetModelDirAndUp ctrlSetModelScale ctrlSetPosition ctrlSetScale ctrlSetStructuredText ctrlSetText ctrlSetTextColor ctrlSetTooltip ctrlSetTooltipColorBox ctrlSetTooltipColorShade ctrlSetTooltipColorText ctrlShow ctrlShown ctrlText ctrlTextHeight ctrlType ctrlVisible curatorAddons curatorCamera curatorCameraArea curatorCameraAreaCeiling curatorCoef curatorEditableObjects curatorEditingArea curatorEditingAreaType curatorMouseOver curatorPoints curatorRegisteredObjects curatorSelected curatorWaypointCost current3DENOperation currentChannel currentCommand currentMagazine currentMagazineDetail currentMagazineDetailTurret currentMagazineTurret currentMuzzle currentNamespace currentTask currentTasks currentThrowable currentVisionMode currentWaypoint currentWeapon currentWeaponMode currentWeaponTurret currentZeroing cursorObject cursorTarget customChat customRadio cutFadeOut cutObj cutRsc cutText damage date dateToNumber daytime deActivateKey debriefingText debugFSM debugLog deg delete3DENEntities deleteAt deleteCenter deleteCollection deleteEditorObject deleteGroup deleteIdentity deleteLocation deleteMarker deleteMarkerLocal deleteRange deleteResources deleteSite deleteStatus deleteTeam deleteVehicle deleteVehicleCrew deleteWaypoint detach detectedMines diag_activeMissionFSMs diag_activeScripts diag_activeSQFScripts diag_activeSQSScripts diag_captureFrame diag_captureSlowFrame diag_codePerformance diag_drawMode diag_enable diag_enabled diag_fps diag_fpsMin diag_frameNo diag_list diag_log diag_logSlowFrame diag_mergeConfigFile diag_recordTurretLimits diag_tickTime diag_toggle dialog diarySubjectExists didJIP didJIPOwner difficulty difficultyEnabled difficultyEnabledRTD difficultyOption direction directSay disableAI disableCollisionWith disableConversation disableDebriefingStats disableNVGEquipment disableRemoteSensors disableSerialization disableTIEquipment disableUAVConnectability disableUserInput displayAddEventHandler displayCtrl displayNull displayParent displayRemoveAllEventHandlers displayRemoveEventHandler displaySetEventHandler dissolveTeam distance distance2D distanceSqr distributionRegion do3DENAction doArtilleryFire doFire doFollow doFSM doGetOut doMove doorPhase doStop doSuppressiveFire doTarget doWatch drawArrow drawEllipse drawIcon drawIcon3D drawLine drawLine3D drawLink drawLocation drawPolygon drawRectangle driver drop east echo edit3DENMissionAttributes editObject editorSetEventHandler effectiveCommander emptyPositions enableAI enableAIFeature enableAimPrecision enableAttack enableAudioFeature enableCamShake enableCaustics enableChannel enableCollisionWith enableCopilot enableDebriefingStats enableDiagLegend enableEndDialog enableEngineArtillery enableEnvironment enableFatigue enableGunLights enableIRLasers enableMimics enablePersonTurret enableRadio enableReload enableRopeAttach enableSatNormalOnDetail enableSaving enableSentences enableSimulation enableSimulationGlobal enableStamina enableTeamSwitch enableUAVConnectability enableUAVWaypoints enableVehicleCargo endLoadingScreen endMission engineOn enginesIsOnRTD enginesRpmRTD enginesTorqueRTD entities estimatedEndServerTime estimatedTimeLeft evalObjectArgument everyBackpack everyContainer exec execEditorScript execFSM execVM exp expectedDestination exportJIPMessages eyeDirection eyePos face faction fadeMusic fadeRadio fadeSound fadeSpeech failMission fillWeaponsFromPool find findCover findDisplay findEditorObject findEmptyPosition findEmptyPositionReady findNearestEnemy finishMissionInit finite fire fireAtTarget firstBackpack flag flagOwner flagSide flagTexture fleeing floor flyInHeight flyInHeightASL fog fogForecast fogParams forceAddUniform forcedMap forceEnd forceMap forceRespawn forceSpeed forceWalk forceWeaponFire forceWeatherChange forEachMember forEachMemberAgent forEachMemberTeam format formation formationDirection formationLeader formationMembers formationPosition formationTask formatText formLeader freeLook fromEditor fuel fullCrew gearIDCAmmoCount gearSlotAmmoCount gearSlotData get3DENActionState get3DENAttribute get3DENCamera get3DENConnections get3DENEntity get3DENEntityID get3DENGrid get3DENIconsVisible get3DENLayerEntities get3DENLinesVisible get3DENMissionAttribute get3DENMouseOver get3DENSelected getAimingCoef getAllHitPointsDamage getAllOwnedMines getAmmoCargo getAnimAimPrecision getAnimSpeedCoef getArray getArtilleryAmmo getArtilleryComputerSettings getArtilleryETA getAssignedCuratorLogic getAssignedCuratorUnit getBackpackCargo getBleedingRemaining getBurningValue getCameraViewDirection getCargoIndex getCenterOfMass getClientState getClientStateNumber getConnectedUAV getCustomAimingCoef getDammage getDescription getDir getDirVisual getDLCs getEditorCamera getEditorMode getEditorObjectScope getElevationOffset getFatigue getFriend getFSMVariable getFuelCargo getGroupIcon getGroupIconParams getGroupIcons getHideFrom getHit getHitIndex getHitPointDamage getItemCargo getMagazineCargo getMarkerColor getMarkerPos getMarkerSize getMarkerType getMass getMissionConfig getMissionConfigValue getMissionDLCs getMissionLayerEntities getModelInfo getMousePosition getNumber getObjectArgument getObjectChildren getObjectDLC getObjectMaterials getObjectProxy getObjectTextures getObjectType getObjectViewDistance getOxygenRemaining getPersonUsedDLCs getPilotCameraDirection getPilotCameraPosition getPilotCameraRotation getPilotCameraTarget getPlayerChannel getPlayerScores getPlayerUID getPos getPosASL getPosASLVisual getPosASLW getPosATL getPosATLVisual getPosVisual getPosWorld getRelDir getRelPos getRemoteSensorsDisabled getRepairCargo getResolution getShadowDistance getShotParents getSlingLoad getSpeed getStamina getStatValue getSuppression getTerrainHeightASL getText getUnitLoadout getUnitTrait getVariable getVehicleCargo getWeaponCargo getWeaponSway getWPPos glanceAt globalChat globalRadio goggles goto group groupChat groupFromNetId groupIconSelectable groupIconsVisible groupId groupOwner groupRadio groupSelectedUnits groupSelectUnit grpNull gunner gusts halt handgunItems handgunMagazine handgunWeapon handsHit hasInterface hasPilotCamera hasWeapon hcAllGroups hcGroupParams hcLeader hcRemoveAllGroups hcRemoveGroup hcSelected hcSelectGroup hcSetGroup hcShowBar hcShownBar headgear hideBody hideObject hideObjectGlobal hideSelection hint hintC hintCadet hintSilent hmd hostMission htmlLoad HUDMovementLevels humidity image importAllGroups importance in inArea inAreaArray incapacitatedState independent inflame inflamed inGameUISetEventHandler inheritsFrom initAmbientLife inPolygon inputAction inRangeOfArtillery insertEditorObject intersect is3DEN is3DENMultiplayer isAbleToBreathe isAgent isArray isAutoHoverOn isAutonomous isAutotest isBleeding isBurning isClass isCollisionLightOn isCopilotEnabled isDedicated isDLCAvailable isEngineOn isEqualTo isEqualType isEqualTypeAll isEqualTypeAny isEqualTypeArray isEqualTypeParams isFilePatchingEnabled isFlashlightOn isFlatEmpty isForcedWalk isFormationLeader isHidden isInRemainsCollector isInstructorFigureEnabled isIRLaserOn isKeyActive isKindOf isLightOn isLocalized isManualFire isMarkedForCollection isMultiplayer isMultiplayerSolo isNil isNull isNumber isObjectHidden isObjectRTD isOnRoad isPipEnabled isPlayer isRealTime isRemoteExecuted isRemoteExecutedJIP isServer isShowing3DIcons isSprintAllowed isStaminaEnabled isSteamMission isStreamFriendlyUIEnabled isText isTouchingGround isTurnedOut isTutHintsEnabled isUAVConnectable isUAVConnected isUniformAllowed isVehicleCargo isWalking isWeaponDeployed isWeaponRested itemCargo items itemsWithMagazines join joinAs joinAsSilent joinSilent joinString kbAddDatabase kbAddDatabaseTargets kbAddTopic kbHasTopic kbReact kbRemoveTopic kbTell kbWasSaid keyImage keyName knowsAbout land landAt landResult language laserTarget lbAdd lbClear lbColor lbCurSel lbData lbDelete lbIsSelected lbPicture lbSelection lbSetColor lbSetCurSel lbSetData lbSetPicture lbSetPictureColor lbSetPictureColorDisabled lbSetPictureColorSelected lbSetSelectColor lbSetSelectColorRight lbSetSelected lbSetTooltip lbSetValue lbSize lbSort lbSortByValue lbText lbValue leader leaderboardDeInit leaderboardGetRows leaderboardInit leaveVehicle libraryCredits libraryDisclaimers lifeState lightAttachObject lightDetachObject lightIsOn lightnings limitSpeed linearConversion lineBreak lineIntersects lineIntersectsObjs lineIntersectsSurfaces lineIntersectsWith linkItem list listObjects ln lnbAddArray lnbAddColumn lnbAddRow lnbClear lnbColor lnbCurSelRow lnbData lnbDeleteColumn lnbDeleteRow lnbGetColumnsPosition lnbPicture lnbSetColor lnbSetColumnsPos lnbSetCurSelRow lnbSetData lnbSetPicture lnbSetText lnbSetValue lnbSize lnbText lnbValue load loadAbs loadBackpack loadFile loadGame loadIdentity loadMagazine loadOverlay loadStatus loadUniform loadVest local localize locationNull locationPosition lock lockCameraTo lockCargo lockDriver locked lockedCargo lockedDriver lockedTurret lockIdentity lockTurret lockWP log logEntities logNetwork logNetworkTerminate lookAt lookAtPos magazineCargo magazines magazinesAllTurrets magazinesAmmo magazinesAmmoCargo magazinesAmmoFull magazinesDetail magazinesDetailBackpack magazinesDetailUniform magazinesDetailVest magazinesTurret magazineTurretAmmo mapAnimAdd mapAnimClear mapAnimCommit mapAnimDone mapCenterOnCamera mapGridPosition markAsFinishedOnSteam markerAlpha markerBrush markerColor markerDir markerPos markerShape markerSize markerText markerType max members menuAction menuAdd menuChecked menuClear menuCollapse menuData menuDelete menuEnable menuEnabled menuExpand menuHover menuPicture menuSetAction menuSetCheck menuSetData menuSetPicture menuSetValue menuShortcut menuShortcutText menuSize menuSort menuText menuURL menuValue min mineActive mineDetectedBy missionConfigFile missionDifficulty missionName missionNamespace missionStart missionVersion mod modelToWorld modelToWorldVisual modParams moonIntensity moonPhase morale move move3DENCamera moveInAny moveInCargo moveInCommander moveInDriver moveInGunner moveInTurret moveObjectToEnd moveOut moveTime moveTo moveToCompleted moveToFailed musicVolume name nameSound nearEntities nearestBuilding nearestLocation nearestLocations nearestLocationWithDubbing nearestObject nearestObjects nearestTerrainObjects nearObjects nearObjectsReady nearRoads nearSupplies nearTargets needReload netId netObjNull newOverlay nextMenuItemIndex nextWeatherChange nMenuItems not numberToDate objectCurators objectFromNetId objectParent objNull objStatus onBriefingGroup onBriefingNotes onBriefingPlan onBriefingTeamSwitch onCommandModeChanged onDoubleClick onEachFrame onGroupIconClick onGroupIconOverEnter onGroupIconOverLeave onHCGroupSelectionChanged onMapSingleClick onPlayerConnected onPlayerDisconnected onPreloadFinished onPreloadStarted onShowNewObject onTeamSwitch openCuratorInterface openDLCPage openMap openYoutubeVideo opfor or orderGetIn overcast overcastForecast owner param params parseNumber parseText parsingNamespace particlesQuality pi pickWeaponPool pitch pixelGrid pixelGridBase pixelGridNoUIScale pixelH pixelW playableSlotsNumber playableUnits playAction playActionNow player playerRespawnTime playerSide playersNumber playGesture playMission playMove playMoveNow playMusic playScriptedMission playSound playSound3D position positionCameraToWorld posScreenToWorld posWorldToScreen ppEffectAdjust ppEffectCommit ppEffectCommitted ppEffectCreate ppEffectDestroy ppEffectEnable ppEffectEnabled ppEffectForceInNVG precision preloadCamera preloadObject preloadSound preloadTitleObj preloadTitleRsc preprocessFile preprocessFileLineNumbers primaryWeapon primaryWeaponItems primaryWeaponMagazine priority private processDiaryLink productVersion profileName profileNamespace profileNameSteam progressLoadingScreen progressPosition progressSetPosition publicVariable publicVariableClient publicVariableServer pushBack pushBackUnique putWeaponPool queryItemsPool queryMagazinePool queryWeaponPool rad radioChannelAdd radioChannelCreate radioChannelRemove radioChannelSetCallSign radioChannelSetLabel radioVolume rain rainbow random rank rankId rating rectangular registeredTasks registerTask reload reloadEnabled remoteControl remoteExec remoteExecCall remove3DENConnection remove3DENEventHandler remove3DENLayer removeAction removeAll3DENEventHandlers removeAllActions removeAllAssignedItems removeAllContainers removeAllCuratorAddons removeAllCuratorCameraAreas removeAllCuratorEditingAreas removeAllEventHandlers removeAllHandgunItems removeAllItems removeAllItemsWithMagazines removeAllMissionEventHandlers removeAllMPEventHandlers removeAllMusicEventHandlers removeAllOwnedMines removeAllPrimaryWeaponItems removeAllWeapons removeBackpack removeBackpackGlobal removeCuratorAddons removeCuratorCameraArea removeCuratorEditableObjects removeCuratorEditingArea removeDrawIcon removeDrawLinks removeEventHandler removeFromRemainsCollector removeGoggles removeGroupIcon removeHandgunItem removeHeadgear removeItem removeItemFromBackpack removeItemFromUniform removeItemFromVest removeItems removeMagazine removeMagazineGlobal removeMagazines removeMagazinesTurret removeMagazineTurret removeMenuItem removeMissionEventHandler removeMPEventHandler removeMusicEventHandler removeOwnedMine removePrimaryWeaponItem removeSecondaryWeaponItem removeSimpleTask removeSwitchableUnit removeTeamMember removeUniform removeVest removeWeapon removeWeaponGlobal removeWeaponTurret requiredVersion resetCamShake resetSubgroupDirection resistance resize resources respawnVehicle restartEditorCamera reveal revealMine reverse reversedMouseY roadAt roadsConnectedTo roleDescription ropeAttachedObjects ropeAttachedTo ropeAttachEnabled ropeAttachTo ropeCreate ropeCut ropeDestroy ropeDetach ropeEndPosition ropeLength ropes ropeUnwind ropeUnwound rotorsForcesRTD rotorsRpmRTD round runInitScript safeZoneH safeZoneW safeZoneWAbs safeZoneX safeZoneXAbs safeZoneY save3DENInventory saveGame saveIdentity saveJoysticks saveOverlay saveProfileNamespace saveStatus saveVar savingEnabled say say2D say3D scopeName score scoreSide screenshot screenToWorld scriptDone scriptName scriptNull scudState secondaryWeapon secondaryWeaponItems secondaryWeaponMagazine select selectBestPlaces selectDiarySubject selectedEditorObjects selectEditorObject selectionNames selectionPosition selectLeader selectMax selectMin selectNoPlayer selectPlayer selectRandom selectWeapon selectWeaponTurret sendAUMessage sendSimpleCommand sendTask sendTaskResult sendUDPMessage serverCommand serverCommandAvailable serverCommandExecutable serverName serverTime set set3DENAttribute set3DENAttributes set3DENGrid set3DENIconsVisible set3DENLayer set3DENLinesVisible set3DENMissionAttributes set3DENModelsVisible set3DENObjectType set3DENSelected setAccTime setAirportSide setAmmo setAmmoCargo setAnimSpeedCoef setAperture setApertureNew setArmoryPoints setAttributes setAutonomous setBehaviour setBleedingRemaining setCameraInterest setCamShakeDefParams setCamShakeParams setCamUseTi setCaptive setCenterOfMass setCollisionLight setCombatMode setCompassOscillation setCuratorCameraAreaCeiling setCuratorCoef setCuratorEditingAreaType setCuratorWaypointCost setCurrentChannel setCurrentTask setCurrentWaypoint setCustomAimCoef setDamage setDammage setDate setDebriefingText setDefaultCamera setDestination setDetailMapBlendPars setDir setDirection setDrawIcon setDropInterval setEditorMode setEditorObjectScope setEffectCondition setFace setFaceAnimation setFatigue setFlagOwner setFlagSide setFlagTexture setFog setFormation setFormationTask setFormDir setFriend setFromEditor setFSMVariable setFuel setFuelCargo setGroupIcon setGroupIconParams setGroupIconsSelectable setGroupIconsVisible setGroupId setGroupIdGlobal setGroupOwner setGusts setHideBehind setHit setHitIndex setHitPointDamage setHorizonParallaxCoef setHUDMovementLevels setIdentity setImportance setLeader setLightAmbient setLightAttenuation setLightBrightness setLightColor setLightDayLight setLightFlareMaxDistance setLightFlareSize setLightIntensity setLightnings setLightUseFlare setLocalWindParams setMagazineTurretAmmo setMarkerAlpha setMarkerAlphaLocal setMarkerBrush setMarkerBrushLocal setMarkerColor setMarkerColorLocal setMarkerDir setMarkerDirLocal setMarkerPos setMarkerPosLocal setMarkerShape setMarkerShapeLocal setMarkerSize setMarkerSizeLocal setMarkerText setMarkerTextLocal setMarkerType setMarkerTypeLocal setMass setMimic setMousePosition setMusicEffect setMusicEventHandler setName setNameSound setObjectArguments setObjectMaterial setObjectMaterialGlobal setObjectProxy setObjectTexture setObjectTextureGlobal setObjectViewDistance setOvercast setOwner setOxygenRemaining setParticleCircle setParticleClass setParticleFire setParticleParams setParticleRandom setPilotCameraDirection setPilotCameraRotation setPilotCameraTarget setPilotLight setPiPEffect setPitch setPlayable setPlayerRespawnTime setPos setPosASL setPosASL2 setPosASLW setPosATL setPosition setPosWorld setRadioMsg setRain setRainbow setRandomLip setRank setRectangular setRepairCargo setShadowDistance setShotParents setSide setSimpleTaskAlwaysVisible setSimpleTaskCustomData setSimpleTaskDescription setSimpleTaskDestination setSimpleTaskTarget setSimpleTaskType setSimulWeatherLayers setSize setSkill setSlingLoad setSoundEffect setSpeaker setSpeech setSpeedMode setStamina setStaminaScheme setStatValue setSuppression setSystemOfUnits setTargetAge setTaskResult setTaskState setTerrainGrid setText setTimeMultiplier setTitleEffect setTriggerActivation setTriggerArea setTriggerStatements setTriggerText setTriggerTimeout setTriggerType setType setUnconscious setUnitAbility setUnitLoadout setUnitPos setUnitPosWeak setUnitRank setUnitRecoilCoefficient setUnitTrait setUnloadInCombat setUserActionText setVariable setVectorDir setVectorDirAndUp setVectorUp setVehicleAmmo setVehicleAmmoDef setVehicleArmor setVehicleCargo setVehicleId setVehicleLock setVehiclePosition setVehicleTiPars setVehicleVarName setVelocity setVelocityTransformation setViewDistance setVisibleIfTreeCollapsed setWaves setWaypointBehaviour setWaypointCombatMode setWaypointCompletionRadius setWaypointDescription setWaypointForceBehaviour setWaypointFormation setWaypointHousePosition setWaypointLoiterRadius setWaypointLoiterType setWaypointName setWaypointPosition setWaypointScript setWaypointSpeed setWaypointStatements setWaypointTimeout setWaypointType setWaypointVisible setWeaponReloadingTime setWind setWindDir setWindForce setWindStr setWPPos show3DIcons showChat showCinemaBorder showCommandingMenu showCompass showCuratorCompass showGPS showHUD showLegend showMap shownArtilleryComputer shownChat shownCompass shownCuratorCompass showNewEditorObject shownGPS shownHUD shownMap shownPad shownRadio shownScoretable shownUAVFeed shownWarrant shownWatch showPad showRadio showScoretable showSubtitles showUAVFeed showWarrant showWatch showWaypoint showWaypoints side sideAmbientLife sideChat sideEmpty sideEnemy sideFriendly sideLogic sideRadio sideUnknown simpleTasks simulationEnabled simulCloudDensity simulCloudOcclusion simulInClouds simulWeatherSync sin size sizeOf skill skillFinal skipTime sleep sliderPosition sliderRange sliderSetPosition sliderSetRange sliderSetSpeed sliderSpeed slingLoadAssistantShown soldierMagazines someAmmo sort soundVolume spawn speaker speed speedMode splitString sqrt squadParams stance startLoadingScreen step stop stopEngineRTD stopped str sunOrMoon supportInfo suppressFor surfaceIsWater surfaceNormal surfaceType swimInDepth switchableUnits switchAction switchCamera switchGesture switchLight switchMove synchronizedObjects synchronizedTriggers synchronizedWaypoints synchronizeObjectsAdd synchronizeObjectsRemove synchronizeTrigger synchronizeWaypoint systemChat systemOfUnits tan targetKnowledge targetsAggregate targetsQuery taskAlwaysVisible taskChildren taskCompleted taskCustomData taskDescription taskDestination taskHint taskMarkerOffset taskNull taskParent taskResult taskState taskType teamMember teamMemberNull teamName teams teamSwitch teamSwitchEnabled teamType terminate terrainIntersect terrainIntersectASL text textLog textLogFormat tg time timeMultiplier titleCut titleFadeOut titleObj titleRsc titleText toArray toFixed toLower toString toUpper triggerActivated triggerActivation triggerArea triggerAttachedVehicle triggerAttachObject triggerAttachVehicle triggerStatements triggerText triggerTimeout triggerTimeoutCurrent triggerType turretLocal turretOwner turretUnit tvAdd tvClear tvCollapse tvCount tvCurSel tvData tvDelete tvExpand tvPicture tvSetCurSel tvSetData tvSetPicture tvSetPictureColor tvSetPictureColorDisabled tvSetPictureColorSelected tvSetPictureRight tvSetPictureRightColor tvSetPictureRightColorDisabled tvSetPictureRightColorSelected tvSetText tvSetTooltip tvSetValue tvSort tvSortByValue tvText tvTooltip tvValue type typeName typeOf UAVControl uiNamespace uiSleep unassignCurator unassignItem unassignTeam unassignVehicle underwater uniform uniformContainer uniformItems uniformMagazines unitAddons unitAimPosition unitAimPositionVisual unitBackpack unitIsUAV unitPos unitReady unitRecoilCoefficient units unitsBelowHeight unlinkItem unlockAchievement unregisterTask updateDrawIcon updateMenuItem updateObjectTree useAISteeringComponent useAudioTimeForMoves vectorAdd vectorCos vectorCrossProduct vectorDiff vectorDir vectorDirVisual vectorDistance vectorDistanceSqr vectorDotProduct vectorFromTo vectorMagnitude vectorMagnitudeSqr vectorMultiply vectorNormalized vectorUp vectorUpVisual vehicle vehicleCargoEnabled vehicleChat vehicleRadio vehicles vehicleVarName velocity velocityModelSpace verifySignature vest vestContainer vestItems vestMagazines viewDistance visibleCompass visibleGPS visibleMap visiblePosition visiblePositionASL visibleScoretable visibleWatch waves waypointAttachedObject waypointAttachedVehicle waypointAttachObject waypointAttachVehicle waypointBehaviour waypointCombatMode waypointCompletionRadius waypointDescription waypointForceBehaviour waypointFormation waypointHousePosition waypointLoiterRadius waypointLoiterType waypointName waypointPosition waypoints waypointScript waypointsEnabledUAV waypointShow waypointSpeed waypointStatements waypointTimeout waypointTimeoutCurrent waypointType waypointVisible weaponAccessories weaponAccessoriesCargo weaponCargo weaponDirection weaponInertia weaponLowered weapons weaponsItems weaponsItemsCargo weaponState weaponsTurret weightRTD west WFSideText wind",literal:"true false nil"},c:[e.CLCM,e.CBCM,e.NM,a,o,r,t.preprocessor],i:/#/}});hljs.registerLanguage("stan",function(e){return{c:[e.HCM,e.CLCM,e.CBCM,{b:e.UIR,l:e.UIR,k:{name:"for in while repeat until if then else",symbol:"bernoulli bernoulli_logit binomial binomial_logit beta_binomial hypergeometric categorical categorical_logit ordered_logistic neg_binomial neg_binomial_2 neg_binomial_2_log poisson poisson_log multinomial normal exp_mod_normal skew_normal student_t cauchy double_exponential logistic gumbel lognormal chi_square inv_chi_square scaled_inv_chi_square exponential inv_gamma weibull frechet rayleigh wiener pareto pareto_type_2 von_mises uniform multi_normal multi_normal_prec multi_normal_cholesky multi_gp multi_gp_cholesky multi_student_t gaussian_dlm_obs dirichlet lkj_corr lkj_corr_cholesky wishart inv_wishart","selector-tag":"int real vector simplex unit_vector ordered positive_ordered row_vector matrix cholesky_factor_corr cholesky_factor_cov corr_matrix cov_matrix",title:"functions model data parameters quantities transformed generated",literal:"true false"},r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"0[xX][0-9a-fA-F]+[Li]?\\b",r:0},{cN:"number",b:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",r:0},{cN:"number",b:"\\d+\\.(?!\\d)(?:i\\b)?",r:0},{cN:"number",b:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",r:0}]}});hljs.registerLanguage("lua",function(e){var t="\\[=*\\[",a="\\]=*\\]",r={b:t,e:a,c:["self"]},n=[e.C("--(?!"+t+")","$"),e.C("--"+t,a,{c:[r],r:10})];return{l:e.UIR,k:{literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstringmodule next pairs pcall print rawequal rawget rawset require select setfenvsetmetatable tonumber tostring type unpack xpcall arg selfcoroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},c:n.concat([{cN:"function",bK:"function",e:"\\)",c:[e.inherit(e.TM,{b:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{cN:"params",b:"\\(",eW:!0,c:n}].concat(n)},e.CNM,e.ASM,e.QSM,{cN:"string",b:t,e:a,c:[r],r:5}])}});hljs.registerLanguage("mel",function(e){return{k:"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform",i:" ",r:10},e.C("%","$"),{cN:"number",b:"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)",r:0},e.ASM,e.QSM,{b:"\\?(::)?([A-Z]\\w*(::)?)+"},{b:"->"},{b:"ok"},{b:"!"},{b:"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)",r:0},{b:"[A-Z][a-zA-Z0-9_']*",r:0}]}});hljs.registerLanguage("dsconfig",function(e){var i={cN:"string",b:/"/,e:/"/},r={cN:"string",b:/'/,e:/'/},s={cN:"string",b:"[\\w-?]+:\\w+",e:"\\W",r:0},t={cN:"string",b:"\\w+-?\\w+",e:"\\W",r:0};return{k:"dsconfig",c:[{cN:"keyword",b:"^dsconfig",e:"\\s",eE:!0,r:10},{cN:"built_in",b:"(list|create|get|set|delete)-(\\w+)",e:"\\s",eE:!0,i:"!@#$%^&*()",r:10},{cN:"built_in",b:"--(\\w+)",e:"\\s",eE:!0},i,r,s,t,e.HCM]}});hljs.registerLanguage("pf",function(t){var o={cN:"variable",b:/\$[\w\d#@][\w\d_]*/},e={cN:"variable",b:/<(?!\/)/,e:/>/};return{aliases:["pf.conf"],l:/[a-z0-9_<>-]+/,k:{built_in:"block match pass load anchor|5 antispoof|10 set table",keyword:"in out log quick on rdomain inet inet6 proto from port os to routeallow-opts divert-packet divert-reply divert-to flags group icmp-typeicmp6-type label once probability recieved-on rtable prio queuetos tag tagged user keep fragment for os dropaf-to|10 binat-to|10 nat-to|10 rdr-to|10 bitmask least-stats random round-robinsource-hash static-portdup-to reply-to route-toparent bandwidth default min max qlimitblock-policy debug fingerprints hostid limit loginterface optimizationreassemble ruleset-optimization basic none profile skip state-defaultsstate-policy timeoutconst counters persistno modulate synproxy state|5 floating if-bound no-sync pflow|10 sloppysource-track global rule max-src-nodes max-src-states max-src-connmax-src-conn-rate overload flushscrub|5 max-mss min-ttl no-df|10 random-id",literal:"all any no-route self urpf-failed egress|5 unknown"},c:[t.HCM,t.NM,t.QSM,o,e]}});hljs.registerLanguage("x86asm",function(s){return{cI:!0,l:"[.%]?"+s.IR,k:{keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",built_in:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr",meta:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},c:[s.C(";","$",{r:0}),{cN:"number",v:[{b:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",r:0},{b:"\\$[0-9][0-9A-Fa-f]*",r:0},{b:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{b:"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},s.QSM,{cN:"string",v:[{b:"'",e:"[^\\\\]'"},{b:"`",e:"[^\\\\]`"}],r:0},{cN:"symbol",v:[{b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{b:"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],r:0},{cN:"subst",b:"%[0-9]+",r:0},{cN:"subst",b:"%!S+",r:0},{cN:"meta",b:/^\s*\.[\w_-]+/}]}});hljs.registerLanguage("handlebars",function(e){var a={"builtin-name":"each in with if else unless bindattr action collection debugger log outlet template unbound view yield"};return{aliases:["hbs","html.hbs","html.handlebars"],cI:!0,sL:"xml",c:[e.C("{{!(--)?","(--)?}}"),{cN:"template-tag",b:/\{\{[#\/]/,e:/\}\}/,c:[{cN:"name",b:/[a-zA-Z\.-]+/,k:a,starts:{eW:!0,r:0,c:[e.QSM]}}]},{cN:"template-variable",b:/\{\{/,e:/\}\}/,k:a}]}});hljs.registerLanguage("scss",function(e){var t="[a-zA-Z-][a-zA-Z0-9_-]*",i={cN:"variable",b:"(\\$"+t+")\\b"},r={cN:"number",b:"#[0-9A-Fa-f]+"};({cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{eW:!0,eE:!0,c:[r,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"meta",b:"!important"}]}});return{cI:!0,i:"[=/|']",c:[e.CLCM,e.CBCM,{cN:"selector-id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"selector-class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"selector-attr",b:"\\[",e:"\\]",i:"$"},{cN:"selector-tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},i,{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{b:":",e:";",c:[i,r,e.CSSNM,e.QSM,e.ASM,{cN:"meta",b:"!important"}]},{b:"@",e:"[{;]",k:"mixin include extend for if else each while charset import debug media page content font-face namespace warn",c:[i,e.QSM,e.ASM,r,e.CSSNM,{b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}});hljs.registerLanguage("delphi",function(e){var r="exports register file shl array record property for mod while set ally label uses raise not stored class safecall var interface or private static exit index inherited to else stdcall override shr asm far resourcestring finalization packed virtual out and protected library do xorwrite goto near function end div overload object unit begin string on inline repeat until destructor write message program with read initialization except default nil if case cdecl in downto threadvar of try pascal const external constructor type public then implementation finally published procedure absolute reintroduce operator as is abstract alias assembler bitpacked break continue cppdecl cvar enumerator experimental platform deprecated unimplemented dynamic export far16 forward generic helper implements interrupt iochecks local name nodefault noreturn nostackframe oldfpccall otherwise saveregisters softfloat specialize strict unaligned varargs ",t=[e.CLCM,e.C(/\{/,/\}/,{r:0}),e.C(/\(\*/,/\*\)/,{r:10})],a={cN:"meta",v:[{b:/\{\$/,e:/\}/},{b:/\(\*\$/,e:/\*\)/}]},c={cN:"string",b:/'/,e:/'/,c:[{b:/''/}]},i={cN:"string",b:/(#\d+)+/},o={b:e.IR+"\\s*=\\s*class\\s*\\(",rB:!0,c:[e.TM]},n={cN:"function",bK:"function constructor destructor procedure",e:/[:;]/,k:"function constructor|10 destructor|10 procedure|10",c:[e.TM,{cN:"params",b:/\(/,e:/\)/,k:r,c:[c,i,a].concat(t)},a].concat(t)};return{aliases:["dpr","dfm","pas","pascal","freepascal","lazarus","lpr","lfm"],cI:!0,k:r,i:/"|\$[G-Zg-z]|\/\*|<\/|\|/,c:[c,i,e.NM,o,n,a].concat(t)}});hljs.registerLanguage("vhdl",function(e){var r="\\d(_|\\d)*",t="[eE][-+]?"+r,n=r+"(\\."+r+")?("+t+")?",o="\\w+",i=r+"#"+o+"(\\."+o+")?#("+t+")?",a="\\b("+i+"|"+n+")";return{cI:!0,k:{keyword:"abs access after alias all and architecture array assert assume assume_guarantee attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable vmode vprop vunit wait when while with xnor xor",built_in:"boolean bit character integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_logic std_logic_vector unsigned signed boolean_vector integer_vector std_ulogic std_ulogic_vector unresolved_unsigned u_unsigned unresolved_signed u_signedreal_vector time_vector",literal:"false true note warning error failure line text side width"},i:"{",c:[e.CBCM,e.C("--","$"),e.QSM,{cN:"number",b:a,r:0},{cN:"string",b:"'(U|X|0|1|Z|W|L|H|-)'",c:[e.BE]},{cN:"symbol",b:"'[A-Za-z](_?[A-Za-z0-9])*",c:[e.BE]}]}});hljs.registerLanguage("accesslog",function(T){return{c:[{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+\\b",r:0},{cN:"string",b:'"(GET|POST|HEAD|PUT|DELETE|CONNECT|OPTIONS|PATCH|TRACE)',e:'"',k:"GET POST HEAD PUT DELETE CONNECT OPTIONS PATCH TRACE",i:"\\n",r:10},{cN:"string",b:/\[/,e:/\]/,i:"\\n"},{cN:"string",b:'"',e:'"',i:"\\n"}]}});hljs.registerLanguage("ini",function(e){var b={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_-]+/},{b:/=/,eW:!0,r:0,c:[{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},b,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}});hljs.registerLanguage("vbnet",function(e){return{aliases:["vb"],cI:!0,k:{keyword:"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor",built_in:"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort",literal:"true false nothing"},i:"//|{|}|endif|gosub|variant|wend",c:[e.inherit(e.QSM,{c:[{b:'""'}]}),e.C("'","$",{rB:!0,c:[{cN:"doctag",b:"'''|",c:[e.PWM]},{cN:"doctag",b:"",c:[e.PWM]}]}),e.CNM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elseif end region externalsource"}}]}});hljs.registerLanguage("gherkin",function(e){return{aliases:["feature"],k:"Feature Background Ability Business Need Scenario Scenarios Scenario Outline Scenario Template Examples Given And Then But When",c:[{cN:"symbol",b:"\\*",r:0},{cN:"meta",b:"@[^@\\s]+"},{b:"\\|",e:"\\|\\w*$",c:[{cN:"string",b:"[^|]+"}]},{cN:"variable",b:"<",e:">"},e.HCM,{cN:"string",b:'"""',e:'"""'},e.QSM]}});hljs.registerLanguage("maxima",function(e){var t="if then else elseif for thru do while unless step in and or not",a="true false unknown inf minf ind und %e %i %pi %phi %gamma",r=" abasep abs absint absolute_real_time acos acosh acot acoth acsc acsch activate addcol add_edge add_edges addmatrices addrow add_vertex add_vertices adjacency_matrix adjoin adjoint af agd airy airy_ai airy_bi airy_dai airy_dbi algsys alg_type alias allroots alphacharp alphanumericp amortization %and annuity_fv annuity_pv antid antidiff AntiDifference append appendfile apply apply1 apply2 applyb1 apropos args arit_amortization arithmetic arithsum array arrayapply arrayinfo arraymake arraysetapply ascii asec asech asin asinh askinteger asksign assoc assoc_legendre_p assoc_legendre_q assume assume_external_byte_order asympa at atan atan2 atanh atensimp atom atvalue augcoefmatrix augmented_lagrangian_method av average_degree backtrace bars barsplot barsplot_description base64 base64_decode bashindices batch batchload bc2 bdvac belln benefit_cost bern bernpoly bernstein_approx bernstein_expand bernstein_poly bessel bessel_i bessel_j bessel_k bessel_simplify bessel_y beta beta_incomplete beta_incomplete_generalized beta_incomplete_regularized bezout bfallroots bffac bf_find_root bf_fmin_cobyla bfhzeta bfloat bfloatp bfpsi bfpsi0 bfzeta biconnected_components bimetric binomial bipartition block blockmatrixp bode_gain bode_phase bothcoef box boxplot boxplot_description break bug_report build_info|10 buildq build_sample burn cabs canform canten cardinality carg cartan cartesian_product catch cauchy_matrix cbffac cdf_bernoulli cdf_beta cdf_binomial cdf_cauchy cdf_chi2 cdf_continuous_uniform cdf_discrete_uniform cdf_exp cdf_f cdf_gamma cdf_general_finite_discrete cdf_geometric cdf_gumbel cdf_hypergeometric cdf_laplace cdf_logistic cdf_lognormal cdf_negative_binomial cdf_noncentral_chi2 cdf_noncentral_student_t cdf_normal cdf_pareto cdf_poisson cdf_rank_sum cdf_rayleigh cdf_signed_rank cdf_student_t cdf_weibull cdisplay ceiling central_moment cequal cequalignore cf cfdisrep cfexpand cgeodesic cgreaterp cgreaterpignore changename changevar chaosgame charat charfun charfun2 charlist charp charpoly chdir chebyshev_t chebyshev_u checkdiv check_overlaps chinese cholesky christof chromatic_index chromatic_number cint circulant_graph clear_edge_weight clear_rules clear_vertex_label clebsch_gordan clebsch_graph clessp clesspignore close closefile cmetric coeff coefmatrix cograd col collapse collectterms columnop columnspace columnswap columnvector combination combine comp2pui compare compfile compile compile_file complement_graph complete_bipartite_graph complete_graph complex_number_p components compose_functions concan concat conjugate conmetderiv connected_components connect_vertices cons constant constantp constituent constvalue cont2part content continuous_freq contortion contour_plot contract contract_edge contragrad contrib_ode convert coord copy copy_file copy_graph copylist copymatrix cor cos cosh cot coth cov cov1 covdiff covect covers crc24sum create_graph create_list csc csch csetup cspline ctaylor ct_coordsys ctransform ctranspose cube_graph cuboctahedron_graph cunlisp cv cycle_digraph cycle_graph cylindrical days360 dblint deactivate declare declare_constvalue declare_dimensions declare_fundamental_dimensions declare_fundamental_units declare_qty declare_translated declare_unit_conversion declare_units declare_weights decsym defcon define define_alt_display define_variable defint defmatch defrule defstruct deftaylor degree_sequence del delete deleten delta demo demoivre denom depends derivdegree derivlist describe desolve determinant dfloat dgauss_a dgauss_b dgeev dgemm dgeqrf dgesv dgesvd diag diagmatrix diag_matrix diagmatrixp diameter diff digitcharp dimacs_export dimacs_import dimension dimensionless dimensions dimensions_as_list direct directory discrete_freq disjoin disjointp disolate disp dispcon dispform dispfun dispJordan display disprule dispterms distrib divide divisors divsum dkummer_m dkummer_u dlange dodecahedron_graph dotproduct dotsimp dpart draw draw2d draw3d drawdf draw_file draw_graph dscalar echelon edge_coloring edge_connectivity edges eigens_by_jacobi eigenvalues eigenvectors eighth einstein eivals eivects elapsed_real_time elapsed_run_time ele2comp ele2polynome ele2pui elem elementp elevation_grid elim elim_allbut eliminate eliminate_using ellipse elliptic_e elliptic_ec elliptic_eu elliptic_f elliptic_kc elliptic_pi ematrix empty_graph emptyp endcons entermatrix entertensor entier equal equalp equiv_classes erf erfc erf_generalized erfi errcatch error errormsg errors euler ev eval_string evenp every evolution evolution2d evundiff example exp expand expandwrt expandwrt_factored expint expintegral_chi expintegral_ci expintegral_e expintegral_e1 expintegral_ei expintegral_e_simplify expintegral_li expintegral_shi expintegral_si explicit explose exponentialize express expt exsec extdiff extract_linear_equations extremal_subset ezgcd %f f90 facsum factcomb factor factorfacsum factorial factorout factorsum facts fast_central_elements fast_linsolve fasttimes featurep fernfale fft fib fibtophi fifth filename_merge file_search file_type fillarray findde find_root find_root_abs find_root_error find_root_rel first fix flatten flength float floatnump floor flower_snark flush flush1deriv flushd flushnd flush_output fmin_cobyla forget fortran fourcos fourexpand fourier fourier_elim fourint fourintcos fourintsin foursimp foursin fourth fposition frame_bracket freeof freshline fresnel_c fresnel_s from_adjacency_matrix frucht_graph full_listify fullmap fullmapl fullratsimp fullratsubst fullsetify funcsolve fundamental_dimensions fundamental_units fundef funmake funp fv g0 g1 gamma gamma_greek gamma_incomplete gamma_incomplete_generalized gamma_incomplete_regularized gauss gauss_a gauss_b gaussprob gcd gcdex gcdivide gcfac gcfactor gd generalized_lambert_w genfact gen_laguerre genmatrix gensym geo_amortization geo_annuity_fv geo_annuity_pv geomap geometric geometric_mean geosum get getcurrentdirectory get_edge_weight getenv get_lu_factors get_output_stream_string get_pixel get_plot_option get_tex_environment get_tex_environment_default get_vertex_label gfactor gfactorsum ggf girth global_variances gn gnuplot_close gnuplot_replot gnuplot_reset gnuplot_restart gnuplot_start go Gosper GosperSum gr2d gr3d gradef gramschmidt graph6_decode graph6_encode graph6_export graph6_import graph_center graph_charpoly graph_eigenvalues graph_flow graph_order graph_periphery graph_product graph_size graph_union great_rhombicosidodecahedron_graph great_rhombicuboctahedron_graph grid_graph grind grobner_basis grotzch_graph hamilton_cycle hamilton_path hankel hankel_1 hankel_2 harmonic harmonic_mean hav heawood_graph hermite hessian hgfred hilbertmap hilbert_matrix hipow histogram histogram_description hodge horner hypergeometric i0 i1 %ibes ic1 ic2 ic_convert ichr1 ichr2 icosahedron_graph icosidodecahedron_graph icurvature ident identfor identity idiff idim idummy ieqn %if ifactors iframes ifs igcdex igeodesic_coords ilt image imagpart imetric implicit implicit_derivative implicit_plot indexed_tensor indices induced_subgraph inferencep inference_result infix info_display init_atensor init_ctensor in_neighbors innerproduct inpart inprod inrt integerp integer_partitions integrate intersect intersection intervalp intopois intosum invariant1 invariant2 inverse_fft inverse_jacobi_cd inverse_jacobi_cn inverse_jacobi_cs inverse_jacobi_dc inverse_jacobi_dn inverse_jacobi_ds inverse_jacobi_nc inverse_jacobi_nd inverse_jacobi_ns inverse_jacobi_sc inverse_jacobi_sd inverse_jacobi_sn invert invert_by_adjoint invert_by_lu inv_mod irr is is_biconnected is_bipartite is_connected is_digraph is_edge_in_graph is_graph is_graph_or_digraph ishow is_isomorphic isolate isomorphism is_planar isqrt isreal_p is_sconnected is_tree is_vertex_in_graph items_inference %j j0 j1 jacobi jacobian jacobi_cd jacobi_cn jacobi_cs jacobi_dc jacobi_dn jacobi_ds jacobi_nc jacobi_nd jacobi_ns jacobi_p jacobi_sc jacobi_sd jacobi_sn JF jn join jordan julia julia_set julia_sin %k kdels kdelta kill killcontext kostka kron_delta kronecker_product kummer_m kummer_u kurtosis kurtosis_bernoulli kurtosis_beta kurtosis_binomial kurtosis_chi2 kurtosis_continuous_uniform kurtosis_discrete_uniform kurtosis_exp kurtosis_f kurtosis_gamma kurtosis_general_finite_discrete kurtosis_geometric kurtosis_gumbel kurtosis_hypergeometric kurtosis_laplace kurtosis_logistic kurtosis_lognormal kurtosis_negative_binomial kurtosis_noncentral_chi2 kurtosis_noncentral_student_t kurtosis_normal kurtosis_pareto kurtosis_poisson kurtosis_rayleigh kurtosis_student_t kurtosis_weibull label labels lagrange laguerre lambda lambert_w laplace laplacian_matrix last lbfgs lc2kdt lcharp lc_l lcm lc_u ldefint ldisp ldisplay legendre_p legendre_q leinstein length let letrules letsimp levi_civita lfreeof lgtreillis lhs li liediff limit Lindstedt linear linearinterpol linear_program linear_regression line_graph linsolve listarray list_correlations listify list_matrix_entries list_nc_monomials listoftens listofvars listp lmax lmin load loadfile local locate_matrix_entry log logcontract log_gamma lopow lorentz_gauge lowercasep lpart lratsubst lreduce lriemann lsquares_estimates lsquares_estimates_approximate lsquares_estimates_exact lsquares_mse lsquares_residual_mse lsquares_residuals lsum ltreillis lu_backsub lucas lu_factor %m macroexpand macroexpand1 make_array makebox makefact makegamma make_graph make_level_picture makelist makeOrders make_poly_continent make_poly_country make_polygon make_random_state make_rgb_picture makeset make_string_input_stream make_string_output_stream make_transform mandelbrot mandelbrot_set map mapatom maplist matchdeclare matchfix mat_cond mat_fullunblocker mat_function mathml_display mat_norm matrix matrixmap matrixp matrix_size mattrace mat_trace mat_unblocker max max_clique max_degree max_flow maximize_lp max_independent_set max_matching maybe md5sum mean mean_bernoulli mean_beta mean_binomial mean_chi2 mean_continuous_uniform mean_deviation mean_discrete_uniform mean_exp mean_f mean_gamma mean_general_finite_discrete mean_geometric mean_gumbel mean_hypergeometric mean_laplace mean_logistic mean_lognormal mean_negative_binomial mean_noncentral_chi2 mean_noncentral_student_t mean_normal mean_pareto mean_poisson mean_rayleigh mean_student_t mean_weibull median median_deviation member mesh metricexpandall mgf1_sha1 min min_degree min_edge_cut minfactorial minimalPoly minimize_lp minimum_spanning_tree minor minpack_lsquares minpack_solve min_vertex_cover min_vertex_cut mkdir mnewton mod mode_declare mode_identity ModeMatrix moebius mon2schur mono monomial_dimensions multibernstein_poly multi_display_for_texinfo multi_elem multinomial multinomial_coeff multi_orbit multiplot_mode multi_pui multsym multthru mycielski_graph nary natural_unit nc_degree ncexpt ncharpoly negative_picture neighbors new newcontext newdet new_graph newline newton new_variable next_prime nicedummies niceindices ninth nofix nonarray noncentral_moment nonmetricity nonnegintegerp nonscalarp nonzeroandfreeof notequal nounify nptetrad npv nroots nterms ntermst nthroot nullity nullspace num numbered_boundaries numberp number_to_octets num_distinct_partitions numerval numfactor num_partitions nusum nzeta nzetai nzetar octets_to_number octets_to_oid odd_girth oddp ode2 ode_check odelin oid_to_octets op opena opena_binary openr openr_binary openw openw_binary operatorp opsubst optimize %or orbit orbits ordergreat ordergreatp orderless orderlessp orthogonal_complement orthopoly_recur orthopoly_weight outermap out_neighbors outofpois pade parabolic_cylinder_d parametric parametric_surface parg parGosper parse_string parse_timedate part part2cont partfrac partition partition_set partpol path_digraph path_graph pathname_directory pathname_name pathname_type pdf_bernoulli pdf_beta pdf_binomial pdf_cauchy pdf_chi2 pdf_continuous_uniform pdf_discrete_uniform pdf_exp pdf_f pdf_gamma pdf_general_finite_discrete pdf_geometric pdf_gumbel pdf_hypergeometric pdf_laplace pdf_logistic pdf_lognormal pdf_negative_binomial pdf_noncentral_chi2 pdf_noncentral_student_t pdf_normal pdf_pareto pdf_poisson pdf_rank_sum pdf_rayleigh pdf_signed_rank pdf_student_t pdf_weibull pearson_skewness permanent permut permutation permutations petersen_graph petrov pickapart picture_equalp picturep piechart piechart_description planar_embedding playback plog plot2d plot3d plotdf ploteq plsquares pochhammer points poisdiff poisexpt poisint poismap poisplus poissimp poissubst poistimes poistrim polar polarform polartorect polar_to_xy poly_add poly_buchberger poly_buchberger_criterion poly_colon_ideal poly_content polydecomp poly_depends_p poly_elimination_ideal poly_exact_divide poly_expand poly_expt poly_gcd polygon poly_grobner poly_grobner_equal poly_grobner_member poly_grobner_subsetp poly_ideal_intersection poly_ideal_polysaturation poly_ideal_polysaturation1 poly_ideal_saturation poly_ideal_saturation1 poly_lcm poly_minimization polymod poly_multiply polynome2ele polynomialp poly_normal_form poly_normalize poly_normalize_list poly_polysaturation_extension poly_primitive_part poly_pseudo_divide poly_reduced_grobner poly_reduction poly_saturation_extension poly_s_polynomial poly_subtract polytocompanion pop postfix potential power_mod powerseries powerset prefix prev_prime primep primes principal_components print printf printfile print_graph printpois printprops prodrac product properties propvars psi psubst ptriangularize pui pui2comp pui2ele pui2polynome pui_direct puireduc push put pv qput qrange qty quad_control quad_qag quad_qagi quad_qagp quad_qags quad_qawc quad_qawf quad_qawo quad_qaws quadrilateral quantile quantile_bernoulli quantile_beta quantile_binomial quantile_cauchy quantile_chi2 quantile_continuous_uniform quantile_discrete_uniform quantile_exp quantile_f quantile_gamma quantile_general_finite_discrete quantile_geometric quantile_gumbel quantile_hypergeometric quantile_laplace quantile_logistic quantile_lognormal quantile_negative_binomial quantile_noncentral_chi2 quantile_noncentral_student_t quantile_normal quantile_pareto quantile_poisson quantile_rayleigh quantile_student_t quantile_weibull quartile_skewness quit qunit quotient racah_v racah_w radcan radius random random_bernoulli random_beta random_binomial random_bipartite_graph random_cauchy random_chi2 random_continuous_uniform random_digraph random_discrete_uniform random_exp random_f random_gamma random_general_finite_discrete random_geometric random_graph random_graph1 random_gumbel random_hypergeometric random_laplace random_logistic random_lognormal random_negative_binomial random_network random_noncentral_chi2 random_noncentral_student_t random_normal random_pareto random_permutation random_poisson random_rayleigh random_regular_graph random_student_t random_tournament random_tree random_weibull range rank rat ratcoef ratdenom ratdiff ratdisrep ratexpand ratinterpol rational rationalize ratnumer ratnump ratp ratsimp ratsubst ratvars ratweight read read_array read_binary_array read_binary_list read_binary_matrix readbyte readchar read_hashed_array readline read_list read_matrix read_nested_list readonly read_xpm real_imagpart_to_conjugate realpart realroots rearray rectangle rectform rectform_log_if_constant recttopolar rediff reduce_consts reduce_order region region_boundaries region_boundaries_plus rem remainder remarray rembox remcomps remcon remcoord remfun remfunction remlet remove remove_constvalue remove_dimensions remove_edge remove_fundamental_dimensions remove_fundamental_units remove_plot_option remove_vertex rempart remrule remsym remvalue rename rename_file reset reset_displays residue resolvante resolvante_alternee1 resolvante_bipartite resolvante_diedrale resolvante_klein resolvante_klein3 resolvante_produit_sym resolvante_unitaire resolvante_vierer rest resultant return reveal reverse revert revert2 rgb2level rhs ricci riemann rinvariant risch rk rmdir rncombine romberg room rootscontract round row rowop rowswap rreduce run_testsuite %s save saving scalarp scaled_bessel_i scaled_bessel_i0 scaled_bessel_i1 scalefactors scanmap scatterplot scatterplot_description scene schur2comp sconcat scopy scsimp scurvature sdowncase sec sech second sequal sequalignore set_alt_display setdifference set_draw_defaults set_edge_weight setelmx setequalp setify setp set_partitions set_plot_option set_prompt set_random_state set_tex_environment set_tex_environment_default setunits setup_autoload set_up_dot_simplifications set_vertex_label seventh sexplode sf sha1sum sha256sum shortest_path shortest_weighted_path show showcomps showratvars sierpinskiale sierpinskimap sign signum similaritytransform simp_inequality simplify_sum simplode simpmetderiv simtran sin sinh sinsert sinvertcase sixth skewness skewness_bernoulli skewness_beta skewness_binomial skewness_chi2 skewness_continuous_uniform skewness_discrete_uniform skewness_exp skewness_f skewness_gamma skewness_general_finite_discrete skewness_geometric skewness_gumbel skewness_hypergeometric skewness_laplace skewness_logistic skewness_lognormal skewness_negative_binomial skewness_noncentral_chi2 skewness_noncentral_student_t skewness_normal skewness_pareto skewness_poisson skewness_rayleigh skewness_student_t skewness_weibull slength smake small_rhombicosidodecahedron_graph small_rhombicuboctahedron_graph smax smin smismatch snowmap snub_cube_graph snub_dodecahedron_graph solve solve_rec solve_rec_rat some somrac sort sparse6_decode sparse6_encode sparse6_export sparse6_import specint spherical spherical_bessel_j spherical_bessel_y spherical_hankel1 spherical_hankel2 spherical_harmonic spherical_to_xyz splice split sposition sprint sqfr sqrt sqrtdenest sremove sremovefirst sreverse ssearch ssort sstatus ssubst ssubstfirst staircase standardize standardize_inverse_trig starplot starplot_description status std std1 std_bernoulli std_beta std_binomial std_chi2 std_continuous_uniform std_discrete_uniform std_exp std_f std_gamma std_general_finite_discrete std_geometric std_gumbel std_hypergeometric std_laplace std_logistic std_lognormal std_negative_binomial std_noncentral_chi2 std_noncentral_student_t std_normal std_pareto std_poisson std_rayleigh std_student_t std_weibull stemplot stirling stirling1 stirling2 strim striml strimr string stringout stringp strong_components struve_h struve_l sublis sublist sublist_indices submatrix subsample subset subsetp subst substinpart subst_parallel substpart substring subvar subvarp sum sumcontract summand_to_rec supcase supcontext symbolp symmdifference symmetricp system take_channel take_inference tan tanh taylor taylorinfo taylorp taylor_simplifier taytorat tcl_output tcontract tellrat tellsimp tellsimpafter tentex tenth test_mean test_means_difference test_normality test_proportion test_proportions_difference test_rank_sum test_sign test_signed_rank test_variance test_variance_ratio tex tex1 tex_display texput %th third throw time timedate timer timer_info tldefint tlimit todd_coxeter toeplitz tokens to_lisp topological_sort to_poly to_poly_solve totaldisrep totalfourier totient tpartpol trace tracematrix trace_options transform_sample translate translate_file transpose treefale tree_reduce treillis treinat triangle triangularize trigexpand trigrat trigreduce trigsimp trunc truncate truncated_cube_graph truncated_dodecahedron_graph truncated_icosahedron_graph truncated_tetrahedron_graph tr_warnings_get tube tutte_graph ueivects uforget ultraspherical underlying_graph undiff union unique uniteigenvectors unitp units unit_step unitvector unorder unsum untellrat untimer untrace uppercasep uricci uriemann uvect vandermonde_matrix var var1 var_bernoulli var_beta var_binomial var_chi2 var_continuous_uniform var_discrete_uniform var_exp var_f var_gamma var_general_finite_discrete var_geometric var_gumbel var_hypergeometric var_laplace var_logistic var_lognormal var_negative_binomial var_noncentral_chi2 var_noncentral_student_t var_normal var_pareto var_poisson var_rayleigh var_student_t var_weibull vector vectorpotential vectorsimp verbify vers vertex_coloring vertex_connectivity vertex_degree vertex_distance vertex_eccentricity vertex_in_degree vertex_out_degree vertices vertices_to_cycle vertices_to_path %w weyl wheel_graph wiener_index wigner_3j wigner_6j wigner_9j with_stdout write_binary_data writebyte write_data writefile wronskian xreduce xthru %y Zeilberger zeroequiv zerofor zeromatrix zeromatrixp zeta zgeev zheev zlange zn_add_table zn_carmichael_lambda zn_characteristic_factors zn_determinant zn_factor_generators zn_invert_by_lu zn_log zn_mult_table absboxchar activecontexts adapt_depth additive adim aform algebraic algepsilon algexact aliases allbut all_dotsimp_denoms allocation allsym alphabetic animation antisymmetric arrays askexp assume_pos assume_pos_pred assumescalar asymbol atomgrad atrig1 axes axis_3d axis_bottom axis_left axis_right axis_top azimuth background background_color backsubst berlefact bernstein_explicit besselexpand beta_args_sum_to_integer beta_expand bftorat bftrunc bindtest border boundaries_array box boxchar breakup %c capping cauchysum cbrange cbtics center cflength cframe_flag cnonmet_flag color color_bar color_bar_tics colorbox columns commutative complex cone context contexts contour contour_levels cosnpiflag ctaypov ctaypt ctayswitch ctayvar ct_coords ctorsion_flag ctrgsimp cube current_let_rule_package cylinder data_file_name debugmode decreasing default_let_rule_package delay dependencies derivabbrev derivsubst detout diagmetric diff dim dimensions dispflag display2d|10 display_format_internal distribute_over doallmxops domain domxexpt domxmxops domxnctimes dontfactor doscmxops doscmxplus dot0nscsimp dot0simp dot1simp dotassoc dotconstrules dotdistrib dotexptsimp dotident dotscrules draw_graph_program draw_realpart edge_color edge_coloring edge_partition edge_type edge_width %edispflag elevation %emode endphi endtheta engineering_format_floats enhanced3d %enumer epsilon_lp erfflag erf_representation errormsg error_size error_syms error_type %e_to_numlog eval even evenfun evflag evfun ev_point expandwrt_denom expintexpand expintrep expon expop exptdispflag exptisolate exptsubst facexpand facsum_combine factlim factorflag factorial_expand factors_only fb feature features file_name file_output_append file_search_demo file_search_lisp file_search_maxima|10 file_search_tests file_search_usage file_type_lisp file_type_maxima|10 fill_color fill_density filled_func fixed_vertices flipflag float2bf font font_size fortindent fortspaces fpprec fpprintprec functions gamma_expand gammalim gdet genindex gensumnum GGFCFMAX GGFINFINITY globalsolve gnuplot_command gnuplot_curve_styles gnuplot_curve_titles gnuplot_default_term_command gnuplot_dumb_term_command gnuplot_file_args gnuplot_file_name gnuplot_out_file gnuplot_pdf_term_command gnuplot_pm3d gnuplot_png_term_command gnuplot_postamble gnuplot_preamble gnuplot_ps_term_command gnuplot_svg_term_command gnuplot_term gnuplot_view_args Gosper_in_Zeilberger gradefs grid grid2d grind halfangles head_angle head_both head_length head_type height hypergeometric_representation %iargs ibase icc1 icc2 icounter idummyx ieqnprint ifb ifc1 ifc2 ifg ifgi ifr iframe_bracket_form ifri igeowedge_flag ikt1 ikt2 imaginary inchar increasing infeval infinity inflag infolists inm inmc1 inmc2 intanalysis integer integervalued integrate_use_rootsof integration_constant integration_constant_counter interpolate_color intfaclim ip_grid ip_grid_in irrational isolate_wrt_times iterations itr julia_parameter %k1 %k2 keepfloat key key_pos kinvariant kt label label_alignment label_orientation labels lassociative lbfgs_ncorrections lbfgs_nfeval_max leftjust legend letrat let_rule_packages lfg lg lhospitallim limsubst linear linear_solver linechar linel|10 linenum line_type linewidth line_width linsolve_params linsolvewarn lispdisp listarith listconstvars listdummyvars lmxchar load_pathname loadprint logabs logarc logcb logconcoeffp logexpand lognegint logsimp logx logx_secondary logy logy_secondary logz lriem m1pbranch macroexpansion macros mainvar manual_demo maperror mapprint matrix_element_add matrix_element_mult matrix_element_transpose maxapplydepth maxapplyheight maxima_tempdir|10 maxima_userdir|10 maxnegex MAX_ORD maxposex maxpsifracdenom maxpsifracnum maxpsinegint maxpsiposint maxtayorder mesh_lines_color method mod_big_prime mode_check_errorp mode_checkp mode_check_warnp mod_test mod_threshold modular_linear_solver modulus multiplicative multiplicities myoptions nary negdistrib negsumdispflag newline newtonepsilon newtonmaxiter nextlayerfactor niceindicespref nm nmc noeval nolabels nonegative_lp noninteger nonscalar noun noundisp nouns np npi nticks ntrig numer numer_pbranch obase odd oddfun opacity opproperties opsubst optimprefix optionset orientation origin orthopoly_returns_intervals outative outchar packagefile palette partswitch pdf_file pfeformat phiresolution %piargs piece pivot_count_sx pivot_max_sx plot_format plot_options plot_realpart png_file pochhammer_max_index points pointsize point_size points_joined point_type poislim poisson poly_coefficient_ring poly_elimination_order polyfactor poly_grobner_algorithm poly_grobner_debug poly_monomial_order poly_primary_elimination_order poly_return_term_list poly_secondary_elimination_order poly_top_reduction_only posfun position powerdisp pred prederror primep_number_of_tests product_use_gamma program programmode promote_float_to_bigfloat prompt proportional_axes props psexpand ps_file radexpand radius radsubstflag rassociative ratalgdenom ratchristof ratdenomdivide rateinstein ratepsilon ratfac rational ratmx ratprint ratriemann ratsimpexpons ratvarswitch ratweights ratweyl ratwtlvl real realonly redraw refcheck resolution restart resultant ric riem rmxchar %rnum_list rombergabs rombergit rombergmin rombergtol rootsconmode rootsepsilon run_viewer same_xy same_xyz savedef savefactors scalar scalarmatrixp scale scale_lp setcheck setcheckbreak setval show_edge_color show_edges show_edge_type show_edge_width show_id show_label showtime show_vertex_color show_vertex_size show_vertex_type show_vertices show_weight simp simplified_output simplify_products simpproduct simpsum sinnpiflag solvedecomposes solveexplicit solvefactors solvenullwarn solveradcan solvetrigwarn space sparse sphere spring_embedding_depth sqrtdispflag stardisp startphi starttheta stats_numer stringdisp structures style sublis_apply_lambda subnumsimp sumexpand sumsplitfact surface surface_hide svg_file symmetric tab taylordepth taylor_logexpand taylor_order_coefficients taylor_truncate_polynomials tensorkill terminal testsuite_files thetaresolution timer_devalue title tlimswitch tr track transcompile transform transform_xy translate_fast_arrays transparent transrun tr_array_as_ref tr_bound_function_applyp tr_file_tty_messagesp tr_float_can_branch_complex tr_function_call_default trigexpandplus trigexpandtimes triginverses trigsign trivial_solutions tr_numer tr_optimize_max_loop tr_semicompile tr_state_vars tr_warn_bad_function_calls tr_warn_fexpr tr_warn_meval tr_warn_mode tr_warn_undeclared tr_warn_undefined_variable tstep ttyoff tube_extremes ufg ug %unitexpand unit_vectors uric uriem use_fast_arrays user_preamble usersetunits values vect_cross verbose vertex_color vertex_coloring vertex_partition vertex_size vertex_type view warnings weyl width windowname windowtitle wired_surface wireframe xaxis xaxis_color xaxis_secondary xaxis_type xaxis_width xlabel xlabel_secondary xlength xrange xrange_secondary xtics xtics_axis xtics_rotate xtics_rotate_secondary xtics_secondary xtics_secondary_axis xu_grid x_voxel xy_file xyplane xy_scale yaxis yaxis_color yaxis_secondary yaxis_type yaxis_width ylabel ylabel_secondary ylength yrange yrange_secondary ytics ytics_axis ytics_rotate ytics_rotate_secondary ytics_secondary ytics_secondary_axis yv_grid y_voxel yx_ratio zaxis zaxis_color zaxis_type zaxis_width zeroa zerob zerobern zeta%pi zlabel zlabel_rotate zlength zmin zn_primroot_limit zn_primroot_pretest",i="_ __ %|0 %%|0";return{l:"[A-Za-z_%][0-9A-Za-z_%]*",k:{keyword:t,literal:a,built_in:r,symbol:i},c:[{cN:"comment",b:"/\\*",e:"\\*/",c:["self"]},e.QSM,{cN:"number",r:0,v:[{b:"\\b(\\d+|\\d+\\.|\\.\\d+|\\d+\\.\\d+)[Ee][-+]?\\d+\\b"},{b:"\\b(\\d+|\\d+\\.|\\.\\d+|\\d+\\.\\d+)[Bb][-+]?\\d+\\b",r:10},{b:"\\b(\\.\\d+|\\d+\\.\\d+)\\b"},{b:"\\b(\\d+|0[0-9A-Za-z]+)\\.?\\b"}]}],i:/@/}});hljs.registerLanguage("parser3",function(r){var e=r.C("{","}",{c:["self"]});return{sL:"xml",r:0,c:[r.C("^#","$"),r.C("\\^rem{","}",{r:10,c:[e]}),{cN:"meta",b:"^@(?:BASE|USE|CLASS|OPTIONS)$",r:10},{cN:"title",b:"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{cN:"variable",b:"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{cN:"keyword",b:"\\^[\\w\\-\\.\\:]+"},{cN:"number",b:"\\^#[0-9a-fA-F]+"},r.CNM]}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"|->)',c:[t,a,e.CLCM,n,o,e.NM,i,{cN:"class",b:"=\\bclass\\b",e:"end;",k:r,c:[n,o,t,a,e.CLCM,i]}]}});hljs.registerLanguage("ada",function(e){var r="\\d(_|\\d)*",t="[eE][-+]?"+r,s=r+"(\\."+r+")?("+t+")?",n="\\w+",a=r+"#"+n+"(\\."+n+")?#("+t+")?",i="\\b("+a+"|"+s+")",c="[A-Za-z](_?[A-Za-z0-9.])*",o="[]{}%#'\"",b=e.C("--","$"),d={b:"\\s+:\\s+",e:"\\s*(:=|;|\\)|=>|$)",i:o,c:[{bK:"loop for declare others",endsParent:!0},{cN:"keyword",bK:"not null constant access function procedure in out aliased exception"},{cN:"type",b:c,endsParent:!0,r:0}]};return{cI:!0,k:{keyword:"abort else new return abs elsif not reverse abstract end accept entry select access exception of separate aliased exit or some all others subtype and for out synchronized array function overriding at tagged generic package task begin goto pragma terminate body private then if procedure type case in protected constant interface is raise use declare range delay limited record when delta loop rem while digits renames with do mod requeue xor",literal:"True False"},c:[b,{cN:"string",b:/"/,e:/"/,c:[{b:/""/,r:0}]},{cN:"string",b:/'.'/},{cN:"number",b:i,r:0},{cN:"symbol",b:"'"+c},{cN:"title",b:"(\\bwith\\s+)?(\\bprivate\\s+)?\\bpackage\\s+(\\bbody\\s+)?",e:"(is|$)",k:"package body",eB:!0,eE:!0,i:o},{b:"(\\b(with|overriding)\\s+)?\\b(function|procedure)\\s+",e:"(\\bis|\\bwith|\\brenames|\\)\\s*;)",k:"overriding function procedure with is renames return",rB:!0,c:[b,{cN:"title",b:"(\\bwith\\s+)?\\b(function|procedure)\\s+",e:"(\\(|\\s+|$)",eB:!0,eE:!0,i:o},d,{cN:"type",b:"\\breturn\\s+",e:"(\\s+|;|$)",k:"return",eB:!0,eE:!0,endsParent:!0,i:o}]},{cN:"type",b:"\\b(sub)?type\\s+",e:"\\s+",k:"type",eB:!0,i:o},d]}});hljs.registerLanguage("flix",function(e){var t={cN:"string",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i={cN:"string",v:[{b:'"',e:'"'}]},n={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/},c={cN:"function",bK:"def",e:/[:={\[(\n;]/,eE:!0,c:[n]};return{k:{literal:"true false",keyword:"case class def else enum if impl import in lat rel index let match namespace switch type yield with"},c:[e.CLCM,e.CBCM,t,i,c,e.CNM]}});hljs.registerLanguage("cmake",function(e){return{aliases:["cmake.in"],cI:!0,k:{keyword:"add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_minimum_required cmake_policy configure_file create_test_sourcelist define_property else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile execute_process export find_file find_library find_package find_path find_program fltk_wrap_ui foreach function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property if include include_directories include_external_msproject include_regular_expression install link_directories load_cache load_command macro mark_as_advanced message option output_required_files project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_link_libraries try_compile try_run unset variable_watch while build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or equal less greater strless strgreater strequal matches"},c:[{cN:"variable",b:"\\${",e:"}"},e.HCM,e.QSM,e.NM]}});hljs.registerLanguage("python",function(e){var r={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},b={cN:"meta",b:/^(>>>|\.\.\.) /},c={cN:"subst",b:/\{/,e:/\}/,k:r,i:/#/},a={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[b],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[b],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[b,c]},{b:/(fr|rf|f)"""/,e:/"""/,c:[b,c]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[c]},{b:/(fr|rf|f)"/,e:/"/,c:[c]},e.ASM,e.QSM]},s={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},i={cN:"params",b:/\(/,e:/\)/,c:["self",b,s,a]};return c.c=[a,s,b],{aliases:["py","gyp"],k:r,i:/(<\/|->|\?)|=>/,c:[b,s,a,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,i,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},i=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+n},{sL:"javascript",eB:!0,eE:!0,v:[{b:"```",e:"```"},{b:"`",e:"`"}]}];r.c=i;var s=e.inherit(e.TM,{b:n}),t="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(i)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:i.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+t,e:"[-=]>",rB:!0,c:[s,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:t,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[s]},s]},{b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("basic",function(E){return{cI:!0,i:"^.",l:"[a-zA-Z][a-zA-Z0-9_$%!#]*",k:{keyword:"ABS ASC AND ATN AUTO|0 BEEP BLOAD|10 BSAVE|10 CALL CALLS CDBL CHAIN CHDIR CHR$|10 CINT CIRCLE CLEAR CLOSE CLS COLOR COM COMMON CONT COS CSNG CSRLIN CVD CVI CVS DATA DATE$ DEFDBL DEFINT DEFSNG DEFSTR DEF|0 SEG USR DELETE DIM DRAW EDIT END ENVIRON ENVIRON$ EOF EQV ERASE ERDEV ERDEV$ ERL ERR ERROR EXP FIELD FILES FIX FOR|0 FRE GET GOSUB|10 GOTO HEX$ IF|0 THEN ELSE|0 INKEY$ INP INPUT INPUT# INPUT$ INSTR IMP INT IOCTL IOCTL$ KEY ON OFF LIST KILL LEFT$ LEN LET LINE LLIST LOAD LOC LOCATE LOF LOG LPRINT USING LSET MERGE MID$ MKDIR MKD$ MKI$ MKS$ MOD NAME NEW NEXT NOISE NOT OCT$ ON OR PEN PLAY STRIG OPEN OPTION BASE OUT PAINT PALETTE PCOPY PEEK PMAP POINT POKE POS PRINT PRINT] PSET PRESET PUT RANDOMIZE READ REM RENUM RESET|0 RESTORE RESUME RETURN|0 RIGHT$ RMDIR RND RSET RUN SAVE SCREEN SGN SHELL SIN SOUND SPACE$ SPC SQR STEP STICK STOP STR$ STRING$ SWAP SYSTEM TAB TAN TIME$ TIMER TROFF TRON TO USR VAL VARPTR VARPTR$ VIEW WAIT WHILE WEND WIDTH WINDOW WRITE XOR"},c:[E.QSM,E.C("REM","$",{r:10}),E.C("'","$",{r:0}),{cN:"symbol",b:"^[0-9]+ ",r:10},{cN:"number",b:"\\b([0-9]+[0-9edED.]*[#!]?)",r:0},{cN:"number",b:"(&[hH][0-9a-fA-F]{1,4})"},{cN:"number",b:"(&[oO][0-7]{1,6})"}]}});hljs.registerLanguage("ocaml",function(e){return{aliases:["ml"],k:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)",r:0},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"type",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*",r:0},e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("tap",function(b){return{cI:!0,c:[b.HCM,{cN:"meta",v:[{b:"^TAP version (\\d+)$"},{b:"^1\\.\\.(\\d+)$"}]},{b:"(s+)?---$",e:"\\.\\.\\.$",sL:"yaml",r:0},{cN:"number",b:" (\\d+) "},{cN:"symbol",v:[{b:"^ok"},{b:"^not ok"}]}]}});hljs.registerLanguage("haskell",function(e){var i={v:[e.C("--","$"),e.C("{-","-}",{c:["self"]})]},a={cN:"meta",b:"{-#",e:"#-}"},l={cN:"meta",b:"^#",e:"$"},c={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n={b:"\\(",e:"\\)",i:'"',c:[a,l,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TM,{b:"[_a-z][\\w']*"}),i]},s={b:"{",e:"}",c:n.c};return{aliases:["hs"],k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{bK:"module",e:"where",k:"module where",c:[n,i],i:"\\W\\.|;"},{b:"\\bimport\\b",e:"$",k:"import qualified as hiding",c:[n,i],i:"\\W\\.|;"},{cN:"class",b:"^(\\s*)?(class|instance)\\b",e:"where",k:"class family instance where",c:[c,n,i]},{cN:"class",b:"\\b(data|(new)?type)\\b",e:"$",k:"data family type newtype deriving",c:[a,c,n,s,i]},{bK:"default",e:"$",c:[c,n,i]},{bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{b:"\\bforeign\\b",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[c,e.QSM,i]},{cN:"meta",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},a,l,e.QSM,e.CNM,c,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),i,{b:"->|<-"}]}});hljs.registerLanguage("mojolicious",function(e){return{sL:"xml",c:[{cN:"meta",b:"^__(END|DATA)__$"},{b:"^\\s*%{1,2}={0,2}",e:"$",sL:"perl"},{b:"<%{1,2}={0,2}",e:"={0,1}%>",sL:"perl",eB:!0,eE:!0}]}});hljs.registerLanguage("livecodeserver",function(e){var r={b:"\\b[gtps][A-Z]+[A-Za-z0-9_\\-]*\\b|\\$_[A-Z]+",r:0},t=[e.CBCM,e.HCM,e.C("--","$"),e.C("[^:]//","$")],a=e.inherit(e.TM,{v:[{b:"\\b_*rig[A-Z]+[A-Za-z0-9_\\-]*"},{b:"\\b_[a-z0-9\\-]+"}]}),o=e.inherit(e.TM,{b:"\\b([A-Za-z0-9_\\-]+)\\b"});return{cI:!1,k:{keyword:"$_COOKIE $_FILES $_GET $_GET_BINARY $_GET_RAW $_POST $_POST_BINARY $_POST_RAW $_SESSION $_SERVER codepoint codepoints segment segments codeunit codeunits sentence sentences trueWord trueWords paragraph after byte bytes english the until http forever descending using line real8 with seventh for stdout finally element word words fourth before black ninth sixth characters chars stderr uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat end repeat URL in try into switch to words https token binfile each tenth as ticks tick system real4 by dateItems without char character ascending eighth whole dateTime numeric short first ftp integer abbreviated abbr abbrev private case while if div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within contains ends with begins the keys of keys",literal:"SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five quote empty one true return cr linefeed right backslash null seven tab three two RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK",built_in:"put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg avgDev base64Decode base64Encode baseConvert binaryDecode binaryEncode byteOffset byteToNum cachedURL cachedURLs charToNum cipherNames codepointOffset codepointProperty codepointToNum codeunitOffset commandNames compound compress constantNames cos date dateFormat decompress directories diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames geometricMean global globals hasMemory harmonicMean hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge millisec millisecs millisecond milliseconds min monthNames nativeCharToNum normalizeText num number numToByte numToChar numToCodepoint numToNativeChar offset open openfiles openProcesses openProcessIDs openSockets paragraphOffset paramCount param params peerAddress pendingMessages platform popStdDev populationStandardDeviation populationVariance popVariance processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLCreateTreeFromFileWithNamespaces revXMLCreateTreeWithNamespaces revXMLDataFromXPathQuery revXMLEvaluateXPath revXMLFirstChild revXMLMatchingNode revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_Execute revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sampVariance sec secs seconds sentenceOffset sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound stdDev sum sysError systemVersion tan tempName textDecode textEncode tick ticks time to tokenOffset toLower toUpper transpose truewordOffset trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus uuid value variableNames variance version waitDepth weekdayNames wordOffset xsltApplyStylesheet xsltApplyStylesheetFromFile xsltLoadStylesheet xsltLoadStylesheetFromFile add breakpoint cancel clear local variable file word line folder directory URL close socket process combine constant convert create new alias folder directory decrypt delete variable word line folder directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime libURLSetStatusCallback load multiply socket prepare process post seek rel relative read from process rename replace require resetAll resolve revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split start stop subtract union unload wait write"},c:[r,{cN:"keyword",b:"\\bend\\sif\\b"},{cN:"function",bK:"function",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"function",b:"\\bend\\s+",e:"$",k:"end",c:[o,a],r:0},{bK:"command on",e:"$",c:[r,o,e.ASM,e.QSM,e.BNM,e.CNM,a]},{cN:"meta",v:[{b:"<\\?(rev|lc|livecode)",r:10},{b:"<\\?"},{b:"\\?>"}]},e.ASM,e.QSM,e.BNM,e.CNM,a].concat(t),i:";$|^\\[|^=|&|{"}});hljs.registerLanguage("leaf",function(e){return{c:[{cN:"function",b:"#+[A-Za-z_0-9]*\\(",e:" {",rB:!0,eE:!0,c:[{cN:"keyword",b:"#+"},{cN:"title",b:"[A-Za-z_][A-Za-z_0-9]*"},{cN:"params",b:"\\(",e:"\\)",endsParent:!0,c:[{cN:"string",b:'"',e:'"'},{cN:"variable",b:"[A-Za-z_][A-Za-z_0-9]*"}]}]}]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("smalltalk",function(e){var s="[a-z][a-zA-Z0-9_]*",a={cN:"string",b:"\\$.{1}"},r={cN:"symbol",b:"#"+e.UIR};return{aliases:["st"],k:"self super nil true false thisContext",c:[e.C('"','"'),e.ASM,{cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},{b:s+":",r:0},e.CNM,r,a,{b:"\\|[ ]*"+s+"([ ]+"+s+")*[ ]*\\|",rB:!0,e:/\|/,i:/\S/,c:[{b:"(\\|[ ]*)?"+s}]},{b:"\\#\\(",e:"\\)",c:[e.ASM,a,e.CNM,r]}]}});hljs.registerLanguage("brainfuck",function(r){var n={cN:"literal",b:"[\\+\\-]",r:0};return{aliases:["bf"],c:[r.C("[^\\[\\]\\.,\\+\\-<> \r\n]","[\\[\\]\\.,\\+\\-<> \r\n]",{rE:!0,r:0}),{cN:"title",b:"[\\[\\]]",r:0},{cN:"string",b:"[\\.,]",r:0},{b:/\+\+|\-\-/,rB:!0,c:[n]},n]}});hljs.registerLanguage("q",function(e){var s={keyword:"do while select delete by update from",literal:"0b 1b",built_in:"neg not null string reciprocal floor ceiling signum mod xbar xlog and or each scan over prior mmu lsq inv md5 ltime gtime count first var dev med cov cor all any rand sums prds mins maxs fills deltas ratios avgs differ prev next rank reverse iasc idesc asc desc msum mcount mavg mdev xrank mmin mmax xprev rotate distinct group where flip type key til get value attr cut set upsert raze union inter except cross sv vs sublist enlist read0 read1 hopen hclose hdel hsym hcount peach system ltrim rtrim trim lower upper ssr view tables views cols xcols keys xkey xcol xasc xdesc fkeys meta lj aj aj0 ij pj asof uj ww wj wj1 fby xgroup ungroup ej save load rsave rload show csv parse eval min max avg wavg wsum sin cos tan sum",type:"`float `double int `timestamp `timespan `datetime `time `boolean `symbol `char `byte `short `long `real `month `date `minute `second `guid"};return{aliases:["k","kdb"],k:s,l:/(`?)[A-Za-z0-9_]+\b/,c:[e.CLCM,e.QSM,e.CNM]}});hljs.registerLanguage("julia-repl",function(a){return{c:[{cN:"meta",b:/^julia>/,r:10,starts:{e:/^(?![ ]{6})/,sL:"julia"},aliases:["jldoctest"]}]}});hljs.registerLanguage("mercury",function(e){var i={keyword:"module use_module import_module include_module end_module initialise mutable initialize finalize finalise interface implementation pred mode func type inst solver any_pred any_func is semidet det nondet multi erroneous failure cc_nondet cc_multi typeclass instance where pragma promise external trace atomic or_else require_complete_switch require_det require_semidet require_multi require_nondet require_cc_multi require_cc_nondet require_erroneous require_failure",meta:"inline no_inline type_spec source_file fact_table obsolete memo loop_check minimal_model terminates does_not_terminate check_termination promise_equivalent_clauses foreign_proc foreign_decl foreign_code foreign_type foreign_import_module foreign_export_enum foreign_export foreign_enum may_call_mercury will_not_call_mercury thread_safe not_thread_safe maybe_thread_safe promise_pure promise_semipure tabled_for_io local untrailed trailed attach_to_io_state can_pass_as_mercury_type stable will_not_throw_exception may_modify_trail will_not_modify_trail may_duplicate may_not_duplicate affects_liveness does_not_affect_liveness doesnt_affect_liveness no_sharing unknown_sharing sharing",built_in:"some all not if then else true fail false try catch catch_any semidet_true semidet_false semidet_fail impure_true impure semipure"},r=e.C("%","$"),t={cN:"number",b:"0'.\\|0[box][0-9a-fA-F]*"},_=e.inherit(e.ASM,{r:0}),n=e.inherit(e.QSM,{r:0}),a={cN:"subst",b:"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]",r:0};n.c.push(a);var o={cN:"built_in",v:[{b:"<=>"},{b:"<=",r:0},{b:"=>",r:0},{b:"/\\\\"},{b:"\\\\/"}]},l={cN:"built_in",v:[{b:":-\\|-->"},{b:"=",r:0}]};return{aliases:["m","moo"],k:i,c:[o,l,r,e.CBCM,t,e.NM,_,n,{b:/:-/}]}});hljs.registerLanguage("verilog",function(e){var n={keyword:"accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind bins binsof bit break buf|0 bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin function generate|5 genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import incdir include initial inout input inside instance int integer interconnect interface intersect join join_any join_none large let liblist library local localparam logic longint macromodule matches medium modport module nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 or output package packed parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor",literal:"null",built_in:"$finish $stop $exit $fatal $error $warning $info $realtime $time $printtimescale $bitstoreal $bitstoshortreal $itor $signed $cast $bits $stime $timeformat $realtobits $shortrealtobits $rtoi $unsigned $asserton $assertkill $assertpasson $assertfailon $assertnonvacuouson $assertoff $assertcontrol $assertpassoff $assertfailoff $assertvacuousoff $isunbounded $sampled $fell $changed $past_gclk $fell_gclk $changed_gclk $rising_gclk $steady_gclk $coverage_control $coverage_get $coverage_save $set_coverage_db_name $rose $stable $past $rose_gclk $stable_gclk $future_gclk $falling_gclk $changing_gclk $display $coverage_get_max $coverage_merge $get_coverage $load_coverage_db $typename $unpacked_dimensions $left $low $increment $clog2 $ln $log10 $exp $sqrt $pow $floor $ceil $sin $cos $tan $countbits $onehot $isunknown $fatal $warning $dimensions $right $high $size $asin $acos $atan $atan2 $hypot $sinh $cosh $tanh $asinh $acosh $atanh $countones $onehot0 $error $info $random $dist_chi_square $dist_erlang $dist_exponential $dist_normal $dist_poisson $dist_t $dist_uniform $q_initialize $q_remove $q_exam $async$and$array $async$nand$array $async$or$array $async$nor$array $sync$and$array $sync$nand$array $sync$or$array $sync$nor$array $q_add $q_full $psprintf $async$and$plane $async$nand$plane $async$or$plane $async$nor$plane $sync$and$plane $sync$nand$plane $sync$or$plane $sync$nor$plane $system $display $displayb $displayh $displayo $strobe $strobeb $strobeh $strobeo $write $readmemb $readmemh $writememh $value$plusargs $dumpvars $dumpon $dumplimit $dumpports $dumpportson $dumpportslimit $writeb $writeh $writeo $monitor $monitorb $monitorh $monitoro $writememb $dumpfile $dumpoff $dumpall $dumpflush $dumpportsoff $dumpportsall $dumpportsflush $fclose $fdisplay $fdisplayb $fdisplayh $fdisplayo $fstrobe $fstrobeb $fstrobeh $fstrobeo $swrite $swriteb $swriteh $swriteo $fscanf $fread $fseek $fflush $feof $fopen $fwrite $fwriteb $fwriteh $fwriteo $fmonitor $fmonitorb $fmonitorh $fmonitoro $sformat $sformatf $fgetc $ungetc $fgets $sscanf $rewind $ftell $ferror"};return{aliases:["v","sv","svh"],cI:!1,k:n,l:/[\w\$]+/,c:[e.CBCM,e.CLCM,e.QSM,{cN:"number",c:[e.BE],v:[{b:"\\b((\\d+'(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{b:"\\B(('(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{b:"\\b([0-9_])+",r:0}]},{cN:"variable",v:[{b:"#\\((?!parameter).+\\)"},{b:"\\.\\w+",r:0}]},{cN:"meta",b:"`",e:"$",k:{"meta-keyword":"define __FILE__ __LINE__ begin_keywords celldefine default_nettype define else elsif end_keywords endcelldefine endif ifdef ifndef include line nounconnected_drive pragma resetall timescale unconnected_drive undef undefineall"},r:0}]}});hljs.registerLanguage("xl",function(e){var t="ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts",o={keyword:"if then else do while until for loop import with is as where when by data constant integer real text name boolean symbol infix prefix postfix block tree",literal:"true false nil",built_in:"in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x mouse_?y mouse_buttons "+t},a={cN:"string",b:'"',e:'"',i:"\\n"},r={cN:"string",b:"'",e:"'",i:"\\n"},i={cN:"string",b:"<<",e:">>"},l={cN:"number",b:"[0-9]+#[0-9A-Z_]+(\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?"},n={bK:"import",e:"$",k:o,c:[a]},s={cN:"function",b:/[a-z][^\n]*->/,rB:!0,e:/->/,c:[e.inherit(e.TM,{starts:{eW:!0,k:o}})]};return{aliases:["tao"],l:/[a-zA-Z][a-zA-Z0-9_?]*/,k:o,c:[e.CLCM,e.CBCM,a,r,i,s,n,l,e.NM]}});hljs.registerLanguage("groovy",function(e){return{k:{literal:"true false null",keyword:"byte short char int long boolean float double void def as in assert trait super this abstract static volatile transient public private protected synchronized final class interface enum if else for while switch case break default continue throw throws try catch finally implements extends new import package return instanceof"},c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,{cN:"string",b:'"""',e:'"""'},{cN:"string",b:"'''",e:"'''"},{cN:"string",b:"\\$/",e:"/\\$",r:10},e.ASM,{cN:"regexp",b:/~?\/[^\/\n]+\//,c:[e.BE]},e.QSM,{cN:"meta",b:"^#!/usr/bin/env",e:"$",i:"\n"},e.BNM,{cN:"class",bK:"class interface trait enum",e:"{",i:":",c:[{bK:"extends implements"},e.UTM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"},{cN:"string",b:/[^\?]{0}[A-Za-z0-9_$]+ *:/},{b:/\?/,e:/\:/},{cN:"symbol",b:"^\\s*[A-Za-z0-9_$]+:",r:0}],i:/#|<\//}});hljs.registerLanguage("abnf",function(e){var r={ruleDeclaration:"^[a-zA-Z][a-zA-Z0-9-]*",unexpectedChars:"[!@#$^&',?+~`|:]"},a=["ALPHA","BIT","CHAR","CR","CRLF","CTL","DIGIT","DQUOTE","HEXDIG","HTAB","LF","LWSP","OCTET","SP","VCHAR","WSP"],b=e.C(";","$"),c={cN:"symbol",b:/%b[0-1]+(-[0-1]+|(\.[0-1]+)+){0,1}/},l={cN:"symbol",b:/%d[0-9]+(-[0-9]+|(\.[0-9]+)+){0,1}/},n={cN:"symbol",b:/%x[0-9A-F]+(-[0-9A-F]+|(\.[0-9A-F]+)+){0,1}/},t={cN:"symbol",b:/%[si]/},s={b:r.ruleDeclaration+"\\s*=",rB:!0,e:/=/,r:0,c:[{cN:"attribute",b:r.ruleDeclaration}]};return{i:r.unexpectedChars,k:a.join(" "),c:[s,b,c,l,n,t,e.QSM,e.NM]}});hljs.registerLanguage("gams",function(e){var a={keyword:"abort acronym acronyms alias all and assign binary card diag display else eq file files for free ge gt if integer le loop lt maximizing minimizing model models ne negative no not option options or ord positive prod put putpage puttl repeat sameas semicont semiint smax smin solve sos1 sos2 sum system table then until using while xor yes",literal:"eps inf na","built-in":"abs arccos arcsin arctan arctan2 Beta betaReg binomial ceil centropy cos cosh cvPower div div0 eDist entropy errorf execSeed exp fact floor frac gamma gammaReg log logBeta logGamma log10 log2 mapVal max min mod ncpCM ncpF ncpVUpow ncpVUsin normal pi poly power randBinomial randLinear randTriangle round rPower sigmoid sign signPower sin sinh slexp sllog10 slrec sqexp sqlog10 sqr sqrec sqrt tan tanh trunc uniform uniformInt vcPower bool_and bool_eqv bool_imp bool_not bool_or bool_xor ifThen rel_eq rel_ge rel_gt rel_le rel_lt rel_ne gday gdow ghour gleap gmillisec gminute gmonth gsecond gyear jdate jnow jstart jtime errorLevel execError gamsRelease gamsVersion handleCollect handleDelete handleStatus handleSubmit heapFree heapLimit heapSize jobHandle jobKill jobStatus jobTerminate licenseLevel licenseStatus maxExecError sleep timeClose timeComp timeElapsed timeExec timeStart"},o={cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0},r={cN:"symbol",v:[{b:/\=[lgenxc]=/},{b:/\$/}]},t={cN:"comment",v:[{b:"'",e:"'"},{b:'"',e:'"'}],i:"\\n",c:[e.BE]},i={b:"/",e:"/",k:a,c:[t,e.CLCM,e.CBCM,e.QSM,e.ASM,e.CNM]},l={b:/[a-z][a-z0-9_]*(\([a-z0-9_, ]*\))?[ \t]+/,eB:!0,e:"$",eW:!0,c:[t,i,{cN:"comment",b:/([ ]*[a-z0-9&#*=?@>\\<:\-,()$\[\]_.{}!+%^]+)+/,r:0}]};return{aliases:["gms"],cI:!0,k:a,c:[e.C(/^\$ontext/,/^\$offtext/),{cN:"meta",b:"^\\$[a-z0-9]+",e:"$",rB:!0,c:[{cN:"meta-keyword",b:"^\\$[a-z0-9]+"}]},e.C("^\\*","$"),e.CLCM,e.CBCM,e.QSM,e.ASM,{bK:"set sets parameter parameters variable variables scalar scalars equation equations",e:";",c:[e.C("^\\*","$"),e.CLCM,e.CBCM,e.QSM,e.ASM,i,l]},{bK:"table",e:";",rB:!0,c:[{bK:"table",e:"$",c:[l]},e.C("^\\*","$"),e.CLCM,e.CBCM,e.QSM,e.ASM,e.CNM]},{cN:"function",b:/^[a-z][a-z0-9_,\-+' ()$]+\.{2}/,rB:!0,c:[{cN:"title",b:/^[a-z0-9_]+/},o,r]},e.CNM,r]}});hljs.registerLanguage("makefile",function(e){var i={cN:"variable",v:[{b:"\\$\\("+e.UIR+"\\)",c:[e.BE]},{b:/\$[@%)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("monkey",function(e){var n={cN:"number",r:0,v:[{b:"[$][a-fA-F0-9]+"},e.NM]};return{cI:!0,k:{keyword:"public private property continue exit extern new try catch eachin not abstract final select case default const local global field end if then else elseif endif while wend repeat until forever for to step next return module inline throw import",built_in:"DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI",literal:"true false null and or shl shr mod"},i:/\/\*/,c:[e.C("#rem","#end"),e.C("'","$",{r:0}),{cN:"function",bK:"function method",e:"[(=:]|$",i:/\n/,c:[e.UTM]},{cN:"class",bK:"class interface",e:"$",c:[{bK:"extends implements"},e.UTM]},{cN:"built_in",b:"\\b(self|super)\\b"},{cN:"meta",b:"\\s*#",e:"$",k:{"meta-keyword":"if else elseif endif end then"}},{cN:"meta",b:"^\\s*strict\\b"},{bK:"alias",e:"=",c:[e.UTM]},e.QSM,n]}});hljs.registerLanguage("openscad",function(e){var r={cN:"keyword",b:"\\$(f[asn]|t|vp[rtd]|children)"},n={cN:"literal",b:"false|true|PI|undef"},o={cN:"number",b:"\\b\\d+(\\.\\d+)?(e-?\\d+)?",r:0},i=e.inherit(e.QSM,{i:null}),t={cN:"meta",k:{"meta-keyword":"include use"},b:"include|use <",e:">"},s={cN:"params",b:"\\(",e:"\\)",c:["self",o,i,r,n]},c={b:"[*!#%]",r:0},a={cN:"function",bK:"module function",e:"\\=|\\{",c:[s,e.UTM]};return{aliases:["scad"],k:{keyword:"function module include use for intersection_for if else \\%",literal:"false true PI undef",built_in:"circle square polygon text sphere cube cylinder polyhedron translate rotate scale resize mirror multmatrix color offset hull minkowski union difference intersection abs sign sin cos tan acos asin atan atan2 floor round ceil ln log pow sqrt exp rands min max concat lookup str chr search version version_num norm cross parent_module echo import import_dxf dxf_linear_extrude linear_extrude rotate_extrude surface projection render children dxf_cross dxf_dim let assign"},c:[e.CLCM,e.CBCM,o,t,i,r,c,a]}});hljs.registerLanguage("scala",function(e){var t={cN:"meta",b:"@[A-Za-z]+"},a={cN:"subst",v:[{b:"\\$[A-Za-z0-9_]+"},{b:"\\${",e:"}"}]},r={cN:"string",v:[{b:'"',e:'"',i:"\\n",c:[e.BE]},{b:'"""',e:'"""',r:10},{b:'[a-z]+"',e:'"',i:"\\n",c:[e.BE,a]},{cN:"string",b:'[a-z]+"""',e:'"""',c:[a],r:10}]},c={cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"},i={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},s={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0},n={cN:"class",bK:"class object trait type",e:/[:={\[\n;]/,eE:!0,c:[{bK:"extends with",r:10},{b:/\[/,e:/\]/,eB:!0,eE:!0,r:0,c:[i]},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,r:0,c:[i]},s]},l={cN:"function",bK:"def",e:/[:={\[(\n;]/,eE:!0,c:[s]};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[e.CLCM,e.CBCM,r,c,i,l,n,e.CNM,t]}});hljs.registerLanguage("elixir",function(e){var r="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",b="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",c={cN:"subst",b:"#\\{",e:"}",l:r,k:b},a={cN:"string",c:[e.BE,c],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},i={cN:"function",bK:"def defp defmacro",e:/\B\b/,c:[e.inherit(e.TM,{b:r,endsParent:!0})]},l=e.inherit(i,{cN:"class",bK:"defimpl defmodule defprotocol defrecord",e:/\bdo\b|$|;/}),s=[a,e.HCM,l,i,{cN:"symbol",b:":(?!\\s)",c:[a,{b:n}],r:0},{cN:"symbol",b:r+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"->"},{b:"("+e.RSR+")\\s*",c:[e.HCM,{cN:"regexp",i:"\\n",c:[e.BE,c],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];return c.c=s,{l:r,k:b,c:s}});hljs.registerLanguage("stylus",function(e){var t={cN:"variable",b:"\\$"+e.IR},o={cN:"number",b:"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})"},i=["charset","css","debug","extend","font-face","for","import","include","media","mixin","page","warn","while"],r=["after","before","first-letter","first-line","active","first-child","focus","hover","lang","link","visited"],n=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],a="[\\.\\s\\n\\[\\:,]",l=["align-content","align-items","align-self","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","auto","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","clip-path","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-variant-ligatures","font-weight","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inherit","initial","justify-content","left","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","mask","max-height","max-width","min-height","min-width","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","perspective","perspective-origin","pointer-events","position","quotes","resize","right","tab-size","table-layout","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","white-space","widows","width","word-break","word-spacing","word-wrap","z-index"],d=["\\?","(\\bReturn\\b)","(\\bEnd\\b)","(\\bend\\b)","(\\bdef\\b)",";","#\\s","\\*\\s","===\\s","\\|","%"];return{aliases:["styl"],cI:!1,k:"if else for in",i:"("+d.join("|")+")",c:[e.QSM,e.ASM,e.CLCM,e.CBCM,o,{b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"selector-class",b:"\\.[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"+a,rB:!0,c:[{cN:"selector-id",b:"\\#[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"\\b("+n.join("|")+")"+a,rB:!0,c:[{cN:"selector-tag",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"}]},{b:"&?:?:\\b("+r.join("|")+")"+a},{b:"@("+i.join("|")+")\\b"},t,e.CSSNM,e.NM,{cN:"function",b:"^[a-zA-Z][a-zA-Z0-9_-]*\\(.*\\)",i:"[\\n]",rB:!0,c:[{cN:"title",b:"\\b[a-zA-Z][a-zA-Z0-9_-]*"},{cN:"params",b:/\(/,e:/\)/,c:[o,t,e.ASM,e.CSSNM,e.NM,e.QSM]}]},{cN:"attribute",b:"\\b("+l.reverse().join("|")+")\\b",starts:{e:/;|$/,c:[o,t,e.ASM,e.QSM,e.CSSNM,e.NM,e.CBCM],i:/\./,r:0}}]}});hljs.registerLanguage("d",function(e){var t={keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},r="(0|[1-9][\\d_]*)",a="(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)",i="0[bB][01_]+",n="([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)",_="0[xX]"+n,c="([eE][+-]?"+a+")",d="("+a+"(\\.\\d*|"+c+")|\\d+\\."+a+a+"|\\."+r+c+"?)",o="(0[xX]("+n+"\\."+n+"|\\.?"+n+")[pP][+-]?"+a+")",s="("+r+"|"+i+"|"+_+")",l="("+o+"|"+d+")",u="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",b={cN:"number",b:"\\b"+s+"(L|u|U|Lu|LU|uL|UL)?",r:0},f={cN:"number",b:"\\b("+l+"([fF]|L|i|[fF]i|Li)?|"+s+"(i|[fF]i|Li))",r:0},g={cN:"string",b:"'("+u+"|.)",e:"'",i:"."},h={b:u,r:0},p={cN:"string",b:'"',c:[h],e:'"[cwd]?'},m={cN:"string",b:'[rq]"',e:'"[cwd]?',r:5},w={cN:"string",b:"`",e:"`[cwd]?"},N={cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10},A={cN:"string",b:'q"\\{',e:'\\}"'},F={cN:"meta",b:"^#!",e:"$",r:5},y={cN:"meta",b:"#(line)",e:"$",r:5},L={cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"},v=e.C("\\/\\+","\\+\\/",{c:["self"],r:10});return{l:e.UIR,k:t,c:[e.CLCM,e.CBCM,v,N,p,m,w,A,f,b,g,F,y,L]}});hljs.registerLanguage("kotlin",function(e){var t={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit initinterface annotation data sealed internal infix operator out by constructor super trait volatile transient native default",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},r={cN:"keyword",b:/\b(break|continue|return|this)\b/,starts:{c:[{cN:"symbol",b:/@\w+/}]}},i={cN:"symbol",b:e.UIR+"@"},n={cN:"subst",b:"\\${",e:"}",c:[e.ASM,e.CNM]},a={cN:"variable",b:"\\$"+e.UIR},c={cN:"string",v:[{b:'"""',e:'"""',c:[a,n]},{b:"'",e:"'",i:/\n/,c:[e.BE]},{b:'"',e:'"',i:/\n/,c:[e.BE,a,n]}]},s={cN:"meta",b:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UIR+")?"},o={cN:"meta",b:"@"+e.UIR,c:[{b:/\(/,e:/\)/,c:[e.inherit(c,{cN:"meta-string"})]}]};return{k:t,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,r,i,s,o,{cN:"function",bK:"fun",e:"[(]|$",rB:!0,eE:!0,k:t,i:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,r:5,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"type",b://,k:"reified",r:0},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:t,r:0,c:[{b:/:/,e:/[=,\/]/,eW:!0,c:[{cN:"type",b:e.UIR},e.CLCM,e.CBCM],r:0},e.CLCM,e.CBCM,s,o,c,e.CNM]},e.CBCM]},{cN:"class",bK:"class interface trait",e:/[:\{(]|$/,eE:!0,i:"extends implements",c:[{bK:"public protected internal private constructor"},e.UTM,{cN:"type",b://,eB:!0,eE:!0,r:0},{cN:"type",b:/[,:]\s*/,e:/[<\(,]|$/,eB:!0,rE:!0},s,o]},c,{cN:"meta",b:"^#!/usr/bin/env",e:"$",i:"\n"},e.CNM]}}); \ No newline at end of file diff --git a/src/utils/highlightjs/highlightjs-line-numbers.min.js b/src/utils/highlightjs/highlightjs-line-numbers.min.js deleted file mode 100644 index 2699f8a3..00000000 --- a/src/utils/highlightjs/highlightjs-line-numbers.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){"use strict";function t(){var e=document.createElement("style");e.type="text/css",e.innerHTML=".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}".format(s,d,u),document.getElementsByTagName("head")[0].appendChild(e)}function n(){"complete"===document.readyState?r():e.addEventListener("DOMContentLoaded",r)}function r(){try{var e=document.querySelectorAll("code.hljs");for(var t in e)e.hasOwnProperty(t)&&o(e[t])}catch(n){console.error("LineNumbers error: ",n)}}function o(e){if("object"==typeof e){var t=l(e.innerHTML);if(t.length>1){for(var n="",r=0;r
    {6}
    '.format(c,a,d,u,i,r+1,t[r].length>0?t[r]:" ");e.innerHTML='{1}
    '.format(s,n)}}}function l(e){return 0===e.length?[]:e.split(/\r\n|\r|\n/g)}var s="hljs-ln",a="hljs-ln-line",i="hljs-ln-code",c="hljs-ln-numbers",d="hljs-ln-n",u="data-line-number";String.prototype.format=String.prototype.f=function(){var e=arguments;return this.replace(/\{(\d+)\}/g,function(t,n){return e[n]?e[n]:t})},"undefined"==typeof e.hljs?console.error("highlight.js not detected!"):(e.hljs.initLineNumbersOnLoad=n,e.hljs.lineNumbersBlock=o,t())}(window); \ No newline at end of file diff --git a/src/utils/markdown-it/README.md b/src/utils/markdown-it/README.md deleted file mode 100644 index 4ce9b7e5..00000000 --- a/src/utils/markdown-it/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# [markdown-it](https://github.com/markdown-it/markdown-it) -v8.3.1 -Alex Kocharin -Vitaly Puzrin - -# [markdown-it-headinganchor](https://github.com/adam-p/markdown-it-headinganchor) -v1.3.0 -Adam Pritchard -Modified by Le Tan - -# [markdown-it-task-lists](https://github.com/revin/markdown-it-task-lists) -v1.4.0 -Revin Guillen - -# [markdown-it-footnote](https://github.com/markdown-it/markdown-it-footnote) -v3.0.1 -Vitaly Puzrin - -# [markdown-it-sub](https://github.com/markdown-it/markdown-it-sub) -v1.0.0 -Vitaly Puzrin - -# [markdown-it-sup](https://github.com/markdown-it/markdown-it-sup) -v1.0.0 -Vitaly Puzrin - -# [markddown-it-front-matter](https://github.com/craigdmckenna/markdown-it-front-matter) -v0.1.2 -Craig McKenna - -# [markdown-it-imsize](https://github.com/tatsy/markdown-it-imsize) -v2.0.1 -Tatsuya Yatagawa - -# [markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji) -v1.4.0 -Vitaly Puzrin - -# [markdown-it-texmath](https://github.com/goessner/markdown-it-texmath) -v0.0.0 -Stefan Goessner -Modified by Le Tan - -# [markdown-it-container](https://github.com/markdown-it/markdown-it-container) -v2.0.0 -Vitaly Puzrin \ No newline at end of file diff --git a/src/utils/markdown-it/markdown-it-container.min.js b/src/utils/markdown-it/markdown-it-container.min.js deleted file mode 100644 index cbbe1a25..00000000 --- a/src/utils/markdown-it/markdown-it-container.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! markdown-it-container 2.0.0 https://github.com//markdown-it/markdown-it-container @license MIT */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.markdownitContainer=e()}}(function(){return function e(r,n,t){function o(f,a){if(!n[f]){if(!r[f]){var u="function"==typeof require&&require;if(!a&&u)return u(f,!0);if(i)return i(f,!0);var c=new Error("Cannot find module '"+f+"'");throw c.code="MODULE_NOT_FOUND",c}var s=n[f]={exports:{}};r[f][0].call(s.exports,function(e){var n=r[f][1][e];return o(n?n:e)},s,s.exports,e,r,n,t)}return n[f].exports}for(var i="function"==typeof require&&require,f=0;f=i&&a[(i-y)%c]===e.src[i];i++);if(d=Math.floor((i-y)/c),f>d)return!1;if(i-=(i-y)%c,p=e.src.slice(y,i),k=e.src.slice(i,_),!s(k))return!1;if(o)return!0;for(l=n;(l++,!(l>=t))&&(y=e.bMarks[l]+e.tShift[l],_=e.eMarks[l],!(_>y&&e.sCount[l]=4)){for(i=y+1;_>=i&&a[(i-y)%c]===e.src[i];i++);if(!(Math.floor((i-y)/c)i))){v=!0;break}}return b=e.parentType,m=e.lineMax,e.parentType="container",e.lineMax=l,h=e.push("container_"+r+"_open","div",1),h.markup=p,h.block=!0,h.info=k,h.map=[n,l],e.md.block.tokenize(e,n+1,l),h=e.push("container_"+r+"_close","div",-1),h.markup=e.src.slice(y,i),h.block=!0,e.parentType=b,e.lineMax=m,e.line=l+(v?1:0),!0}n=n||{};var f=3,a=n.marker||":",u=a.charCodeAt(0),c=a.length,s=n.validate||t,l=n.render||o;e.block.ruler.before("fence","container_"+r,i,{alt:["paragraph","reference","blockquote","list"]}),e.renderer.rules["container_"+r+"_open"]=l,e.renderer.rules["container_"+r+"_close"]=l}},{}]},{},[1])(1)}); diff --git a/src/utils/markdown-it/markdown-it-emoji.min.js b/src/utils/markdown-it/markdown-it-emoji.min.js deleted file mode 100644 index feee94b6..00000000 --- a/src/utils/markdown-it/markdown-it-emoji.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! markdown-it-emoji 1.4.0 https://github.com//markdown-it/markdown-it-emoji @license MIT */ -!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.markdownitEmoji=a()}}(function(){return function a(e,n,o){function i(_,t){if(!n[_]){if(!e[_]){var s="function"==typeof require&&require;if(!t&&s)return s(_,!0);if(r)return r(_,!0);var l=new Error("Cannot find module '"+_+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[_]={exports:{}};e[_][0].call(c.exports,function(a){var n=e[_][1][a];return i(n?n:a)},c,c.exports,a,e,n,o)}return n[_].exports}for(var r="function"==typeof require&&require,_=0;_:(",">:-("],blush:[':")',':-")'],broken_heart:["=0&&(e[o]=n[o]),e},{})),e=Object.keys(a.shortcuts).reduce(function(e,o){return n[o]?Array.isArray(a.shortcuts[o])?(a.shortcuts[o].forEach(function(a){e[a]=o}),e):(e[a.shortcuts[o]]=o,e):e},{});var i=Object.keys(n).map(function(a){return":"+a+":"}).concat(Object.keys(e)).sort().reverse().map(function(a){return o(a)}).join("|"),r=RegExp(i),_=RegExp(i,"g");return{defs:n,shortcuts:e,scanRE:r,replaceRE:_}}},{}],4:[function(a,e,n){"use strict";e.exports=function(a,e){return a[e].content}},{}],5:[function(a,e,n){"use strict";e.exports=function(a,e,n,o,i){function r(a,o,r){var _,t=0,l=[];return a.replace(i,function(o,i,c){var m;if(n.hasOwnProperty(o)){if(m=n[o],i>0&&!s.test(c[i-1]))return;if(i+o.lengtht&&(_=new r("text","",0),_.content=a.slice(t,i),l.push(_)),_=new r("emoji","",0),_.markup=m,_.content=e[m],l.push(_),t=i+o.length}),t=0;e--)s=t[e],"link_open"!==s.type&&"link_close"!==s.type||"auto"===s.info&&(c-=s.nesting),"text"===s.type&&0===c&&o.test(s.content)&&(l[n].children=t=_(t,e,r(s.content,s.level,a.Token)))}}},{}],6:[function(a,e,n){"use strict";var o=a("./lib/data/full.json"),i=a("./lib/data/shortcuts"),r=a("./lib/render"),_=a("./lib/replace"),t=a("./lib/normalize_opts");e.exports=function(a,e){var n={defs:o,shortcuts:i,enabled:[]},s=t(a.utils.assign({},n,e||{}));a.renderer.rules.emoji=r,a.core.ruler.push("emoji",_(a,s.defs,s.shortcuts,s.scanRE,s.replaceRE))}},{"./lib/data/full.json":1,"./lib/data/shortcuts":2,"./lib/normalize_opts":3,"./lib/render":4,"./lib/replace":5}]},{},[6])(6)}); diff --git a/src/utils/markdown-it/markdown-it-footnote.min.js b/src/utils/markdown-it/markdown-it-footnote.min.js deleted file mode 100644 index d0271179..00000000 --- a/src/utils/markdown-it/markdown-it-footnote.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! markdown-it-footnote 3.0.1 https://github.com//markdown-it/markdown-it-footnote @license MIT */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o;o="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,o.markdownitFootnote=e()}}(function(){return function e(o,t,n){function r(f,l){if(!t[f]){if(!o[f]){var u="function"==typeof require&&require;if(!l&&u)return u(f,!0);if(s)return s(f,!0);var i=new Error("Cannot find module '"+f+"'");throw i.code="MODULE_NOT_FOUND",i}var a=t[f]={exports:{}};o[f][0].call(a.exports,function(e){var t=o[f][1][e];return r(t?t:e)},a,a.exports,e,o,t,n)}return t[f].exports}for(var s="function"==typeof require&&require,f=0;f0&&(t+=":"+e[o].meta.subId),"["+t+"]"}function s(e,o,t,n,r){var s=r.rules.footnote_anchor_name(e,o,t,n,r),f=r.rules.footnote_caption(e,o,t,n,r),l=s;return e[o].meta.subId>0&&(l+=":"+e[o].meta.subId),''+f+""}function f(e,o,t){return(t.xhtmlOut?'
    \n':'
    \n')+'
    \n
      \n'}function l(){return"
    \n
    \n"}function u(e,o,t,n,r){var s=r.rules.footnote_anchor_name(e,o,t,n,r);return e[o].meta.subId>0&&(s+=":"+e[o].meta.subId),'
  • '}function i(){return"
  • \n"}function a(e,o,t,n,r){var s=r.rules.footnote_anchor_name(e,o,t,n,r);return e[o].meta.subId>0&&(s+=":"+e[o].meta.subId),' \u21a9\ufe0e'}o.exports=function(e){function o(e,o,t,n){var r,s,f,l,u,i,a,c,p,d,k,b=e.bMarks[o]+e.tShift[o],v=e.eMarks[o];if(b+4>v)return!1;if(91!==e.src.charCodeAt(b))return!1;if(94!==e.src.charCodeAt(b+1))return!1;for(u=b+2;u=v||58!==e.src.charCodeAt(++u))return!1;if(n)return!0;for(u++,e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.refs||(e.env.footnotes.refs={}),i=e.src.slice(b+2,u-2),e.env.footnotes.refs[":"+i]=-1,a=new e.Token("footnote_reference_open","",1),a.meta={label:i},a.level=e.level++,e.tokens.push(a),r=e.bMarks[o],s=e.tShift[o],f=e.sCount[o],l=e.parentType,k=u,c=p=e.sCount[o]+u-(e.bMarks[o]+e.tShift[o]);u=l)&&(94===e.src.charCodeAt(u)&&(91===e.src.charCodeAt(u+1)&&(t=u+2,n=d(e,u+1),!(n<0)&&(o||(e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.list||(e.env.footnotes.list=[]),r=e.env.footnotes.list.length,e.md.inline.parse(e.src.slice(t,n),e.md,e.env,f=[]),s=e.push("footnote_ref","",0),s.meta={id:r},e.env.footnotes.list[r]={tokens:f}),e.pos=n+1,e.posMax=l,!0))))}function c(e,o){var t,n,r,s,f,l=e.posMax,u=e.pos;if(u+3>l)return!1;if(!e.env.footnotes||!e.env.footnotes.refs)return!1;if(91!==e.src.charCodeAt(u))return!1;if(94!==e.src.charCodeAt(u+1))return!1;for(n=u+2;n=l)&&(n++,t=e.src.slice(u+2,n-1),"undefined"!=typeof e.env.footnotes.refs[":"+t]&&(o||(e.env.footnotes.list||(e.env.footnotes.list=[]),e.env.footnotes.refs[":"+t]<0?(r=e.env.footnotes.list.length,e.env.footnotes.list[r]={label:t,count:0},e.env.footnotes.refs[":"+t]=r):r=e.env.footnotes.refs[":"+t],s=e.env.footnotes.list[r].count,e.env.footnotes.list[r].count++,f=e.push("footnote_ref","",0),f.meta={id:r,subId:s,label:t}),e.pos=n,e.posMax=l,!0)))}function p(e){var o,t,n,r,s,f,l,u,i,a,c=!1,p={};if(e.env.footnotes&&(e.tokens=e.tokens.filter(function(e){return"footnote_reference_open"===e.type?(c=!0,i=[],a=e.meta.label,!1):"footnote_reference_close"===e.type?(c=!1,p[":"+a]=i,!1):(c&&i.push(e),!c)}),e.env.footnotes.list)){for(f=e.env.footnotes.list,l=new e.Token("footnote_block_open","",1),e.tokens.push(l),o=0,t=f.length;o0?f[o].count:1,n=0;n= endLine) { - // unclosed block should be autoclosed by end of document. - // also block seems to be autoclosed by end of parent - break; - } - - start = state.bMarks[nextLine] + state.tShift[nextLine]; - max = state.eMarks[nextLine]; - - if (start < max && state.sCount[nextLine] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - // - ``` - // test - break; - } - - if (marker_char !== state.src.charCodeAt(start)) { continue; } - - if (state.sCount[nextLine] - state.blkIndent >= 4) { - // closing fence should be indented less than 4 spaces - continue; - } - - for (pos = start + 1; pos <= max; pos++) { - if (marker_str[(pos - start) % marker_len] !== state.src[pos]) { - break; - } - } - - // closing code fence must be at least as long as the opening one - if (Math.floor((pos - start) / marker_len) < marker_count) { continue; } - - // make sure tail has spaces only - pos -= (pos - start) % marker_len; - pos = state.skipSpaces(pos); - - if (pos < max) { continue; } - - // found! - auto_closed = true; - break; - } - - old_parent = state.parentType; - old_line_max = state.lineMax; - state.parentType = 'container'; - - // this will prevent lazy continuations from ever going past our end marker - state.lineMax = nextLine; - - token = state.push('front_matter', null, 0); - token.hidden = true; - token.markup = state.src.slice(startLine, pos) - token.block = true; - token.map = [ startLine, pos ]; - - state.parentType = old_parent; - state.lineMax = old_line_max; - state.line = nextLine + (auto_closed ? 1 : 0); - - cb(state.src.slice(start_content, start - 1)) - - return true; - } - - md.block.ruler.before('table', 'front_matter', frontMatter, { - alt: [ 'paragraph', 'reference', 'blockquote', 'list' ] - }); -}; - -},{}]},{},[1])(1) -}); diff --git a/src/utils/markdown-it/markdown-it-headinganchor.js b/src/utils/markdown-it/markdown-it-headinganchor.js deleted file mode 100644 index 93c872d6..00000000 --- a/src/utils/markdown-it/markdown-it-headinganchor.js +++ /dev/null @@ -1,80 +0,0 @@ -/*! markdown-it-headinganchor 1.2.1 https://github.com//adam-p/markdown-it-headinganchor @license MIT */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.markdownitHeadingAnchor = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o'; - } else { - anchorToken.content = ''; - } - - headingInlineToken.children.push(anchorToken); - } - - // Advance past the inline and heading_close tokens. - i += 2; - } - }; -} - -module.exports = function headinganchor_plugin(md, opts) { - var defaults = { - anchorClass: 'markdown-it-headinganchor', - addHeadingID: true, - addHeadingAnchor: true, - // Added by Le Tan (github.com/tamlok) - anchorIcon: '#', - slugify: slugify, - headingHook: function(openToken, inlineToken, anchor) {} - }; - var options = md.utils.assign(defaults, opts); - md.core.ruler.push('heading_anchors', makeRule(md, options)); -}; - -},{}]},{},[1])(1) -}); diff --git a/src/utils/markdown-it/markdown-it-imsize.min.js b/src/utils/markdown-it/markdown-it-imsize.min.js deleted file mode 100644 index 7ec10e81..00000000 --- a/src/utils/markdown-it/markdown-it-imsize.min.js +++ /dev/null @@ -1,2 +0,0 @@ -(function webpackUniversalModuleDefinition(root,factory){if(typeof exports==="object"&&typeof module==="object")module.exports=factory();else if(typeof define==="function"&&define.amd)define(factory);else if(typeof exports==="object")exports["markdown-it-imsize.js"]=factory();else root["markdown-it-imsize.js"]=factory()})(this,function(){return function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:false};modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);module.loaded=true;return module.exports}__webpack_require__.m=modules;__webpack_require__.c=installedModules;__webpack_require__.p="";return __webpack_require__(0)}([function(module,exports,__webpack_require__){"use strict";var sizeOf=__webpack_require__(2);var parseImageSize=__webpack_require__(1);function image_with_size(md,options){return function(state,silent){var attrs,code,label,labelEnd,labelStart,pos,ref,res,title,width="",height="",token,tokens,start,href="",oldPos=state.pos,max=state.posMax;if(state.src.charCodeAt(state.pos)!==33){return false}if(state.src.charCodeAt(state.pos+1)!==91){return false}labelStart=state.pos+2;labelEnd=md.helpers.parseLinkLabel(state,state.pos+1,false);if(labelEnd<0){return false}pos=labelEnd+1;if(pos=max){return false}start=pos;res=md.helpers.parseLinkDestination(state.src,pos,state.posMax);if(res.ok){href=state.md.normalizeLink(res.str);if(state.md.validateLink(href)){pos=res.pos}else{href=""}}start=pos;for(;pos=0){code=state.src.charCodeAt(pos-1);if(code===32){res=parseImageSize(state.src,pos,state.posMax);if(res.ok){width=res.width;height=res.height;pos=res.pos;for(;pos=max||state.src.charCodeAt(pos)!==41){state.pos=oldPos;return false}pos++}else{if(typeof state.env.references==="undefined"){return false}for(;pos=0){label=state.src.slice(start,pos++)}else{pos=labelEnd+1}}else{pos=labelEnd+1}if(!label){label=state.src.slice(labelStart,labelEnd)}ref=state.env.references[md.utils.normalizeReference(label)];if(!ref){state.pos=oldPos;return false}href=ref.href;title=ref.title}if(!silent){state.pos=labelStart;state.posMax=labelEnd;var newState=new state.md.inline.State(state.src.slice(labelStart,labelEnd),state.md,state.env,tokens=[]);newState.md.inline.tokenize(newState);if(options){if(options.autofill&&width===""&&height===""){try{var dimensions=sizeOf(href);width=dimensions.width;height=dimensions.height}catch(e){}}}token=state.push("image","img",0);token.attrs=attrs=[["src",href],["alt",""]];token.children=tokens;if(title){attrs.push(["title",title])}if(width!==""){attrs.push(["width",width])}if(height!==""){attrs.push(["height",height])}}state.pos=pos;state.posMax=max;return true}}module.exports=function imsize_plugin(md,options){md.inline.ruler.before("emphasis","image",image_with_size(md,options))}},function(module,exports,__webpack_require__){"use strict";function parseNextNumber(str,pos,max){var code,start=pos,result={ok:false,pos:pos,value:""};code=str.charCodeAt(pos);while(pos=48&&code<=57)||code===37){code=str.charCodeAt(++pos)}result.ok=true;result.pos=pos;result.value=str.slice(start,pos);return result}module.exports=function parseImageSize(str,pos,max){var code,result={ok:false,pos:0,width:"",height:""};if(pos>=max){return result}code=str.charCodeAt(pos);if(code!==61){return result}pos++;code=str.charCodeAt(pos);if(code!==120&&(code<48||code>57)){return result}var resultW=parseNextNumber(str,pos,max);pos=resultW.pos;code=str.charCodeAt(pos);if(code!==120){return result}pos++;var resultH=parseNextNumber(str,pos,max);pos=resultH.pos;result.width=resultW.value;result.height=resultH.value;result.pos=pos;result.ok=true;return result}},function(module,exports,__webpack_require__){(function(Buffer){"use strict";var fs=__webpack_require__(16);var path=__webpack_require__(6);var detector=__webpack_require__(3);var handlers={};var types=__webpack_require__(5);types.forEach(function(type){handlers[type]=__webpack_require__(4)("./"+type)});var MaxBufferSize=128*1024;function lookup(buffer,filepath){var type=detector(buffer,filepath);if(type in handlers){var size=handlers[type].calculate(buffer,filepath);if(size!==false){size.type=type;return size}}throw new TypeError("Unsupported file type")}function asyncFileToBuffer(filepath,callback){fs.open(filepath,"r",function(err0,descriptor){if(err0){return callback(err0)}var size=fs.fstatSync(descriptor).size;var bufferSize=Math.min(size,MaxBufferSize);var buffer=new Buffer(bufferSize);fs.read(descriptor,buffer,0,bufferSize,0,function(err1){if(err1){return callback(err1)}fs.close(descriptor,function(err2){callback(err2,buffer)})})})}function syncFileToBuffer(filepath){var descriptor=fs.openSync(filepath,"r");var size=fs.fstatSync(descriptor).size;var bufferSize=Math.min(size,MaxBufferSize);var buffer=new Buffer(bufferSize);fs.readSync(descriptor,buffer,0,bufferSize,0);fs.closeSync(descriptor);return buffer}module.exports=function(input,callback){if(typeof input!=="string"){throw new TypeError("Input must be file name")}var filepath=path.resolve(input);if(typeof callback==="function"){asyncFileToBuffer(filepath,function(err,buffer){if(err){return callback(err)}var dimensions;try{dimensions=lookup(buffer,filepath)}catch(e){err=e}callback(err,dimensions)})}else{var buffer=syncFileToBuffer(filepath);return lookup(buffer,filepath)}}}).call(exports,__webpack_require__(7).Buffer)},function(module,exports,__webpack_require__){"use strict";var typeMap={};var types=__webpack_require__(5);types.forEach(function(type){typeMap[type]=__webpack_require__(4)("./"+type).detect});module.exports=function(buffer,filepath){var type,result;for(type in typeMap){if(type in typeMap){result=typeMap[type](buffer,filepath);if(result){return type}}}throw new TypeError("Unsupported type")}},function(module,exports,__webpack_require__){var map={"./bmp":8,"./bmp.js":8,"./gif":9,"./gif.js":9,"./jpg":10,"./jpg.js":10,"./png":11,"./png.js":11,"./psd":12,"./psd.js":12,"./svg":13,"./svg.js":13,"./tiff":14,"./tiff.js":14,"./webp":15,"./webp.js":15};function webpackContext(req){return __webpack_require__(webpackContextResolve(req))}function webpackContextResolve(req){return map[req]||function(){throw new Error("Cannot find module '"+req+"'.")}()}webpackContext.keys=function webpackContextKeys(){return Object.keys(map)};webpackContext.resolve=webpackContextResolve;module.exports=webpackContext;webpackContext.id=4},function(module,exports,__webpack_require__){"use strict";module.exports=["bmp","gif","jpg","png","tiff"]},function(module,exports,__webpack_require__){(function(process){function normalizeArray(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up--;up){parts.unshift("..")}}return parts}var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;var splitPath=function(filename){return splitPathRe.exec(filename).slice(1)};exports.resolve=function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:process.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){continue}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=normalizeArray(filter(resolvedPath.split("/"),function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."};exports.normalize=function(path){var isAbsolute=exports.isAbsolute(path),trailingSlash=substr(path,-1)==="/";path=normalizeArray(filter(path.split("/"),function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path};exports.isAbsolute=function(path){return path.charAt(0)==="/"};exports.join=function(){var paths=Array.prototype.slice.call(arguments,0);return exports.normalize(filter(paths,function(p,index){if(typeof p!=="string"){throw new TypeError("Arguments to path.join must be strings")}return p}).join("/"))};exports.relative=function(from,to){from=exports.resolve(from).substr(1);to=exports.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;ikMaxLength){throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+kMaxLength.toString(16)+" bytes")}if(length<0)length=0;else length>>>=0;if(Buffer.TYPED_ARRAY_SUPPORT){self=Buffer._augment(new Uint8Array(length))}else{self.length=length;self._isBuffer=true}var i;if(Buffer.TYPED_ARRAY_SUPPORT&&typeof subject.byteLength==="number"){self._set(subject)}else if(isArrayish(subject)){if(Buffer.isBuffer(subject)){for(i=0;i0&&length<=Buffer.poolSize)self.parent=rootParent;return self}function SlowBuffer(subject,encoding){if(!(this instanceof SlowBuffer))return new SlowBuffer(subject,encoding);var buf=new Buffer(subject,encoding);delete buf.parent;return buf}Buffer.isBuffer=function isBuffer(b){return!!(b!=null&&b._isBuffer)};Buffer.compare=function compare(a,b){if(!Buffer.isBuffer(a)||!Buffer.isBuffer(b)){throw new TypeError("Arguments must be Buffers")}if(a===b)return 0;var x=a.length;var y=b.length;for(var i=0,len=Math.min(x,y);i>>1;break;case"utf8":case"utf-8":ret=utf8ToBytes(str).length;break;case"base64":ret=base64ToBytes(str).length;break;default:ret=str.length}return ret};Buffer.prototype.length=undefined;Buffer.prototype.parent=undefined;Buffer.prototype.toString=function toString(encoding,start,end){var loweredCase=false;start=start>>>0;end=end===undefined||end===Infinity?this.length:end>>>0;if(!encoding)encoding="utf8";if(start<0)start=0;if(end>this.length)end=this.length;if(end<=start)return"";while(true){switch(encoding){case"hex":return hexSlice(this,start,end);case"utf8":case"utf-8":return utf8Slice(this,start,end);case"ascii":return asciiSlice(this,start,end);case"binary":return binarySlice(this,start,end);case"base64":return base64Slice(this,start,end);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,start,end);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(encoding+"").toLowerCase();loweredCase=true}}};Buffer.prototype.equals=function equals(b){if(!Buffer.isBuffer(b))throw new TypeError("Argument must be a Buffer");if(this===b)return true;return Buffer.compare(this,b)===0};Buffer.prototype.inspect=function inspect(){var str="";var max=exports.INSPECT_MAX_BYTES;if(this.length>0){str=this.toString("hex",0,max).match(/.{2}/g).join(" ");if(this.length>max)str+=" ... "}return""};Buffer.prototype.compare=function compare(b){if(!Buffer.isBuffer(b))throw new TypeError("Argument must be a Buffer");if(this===b)return 0;return Buffer.compare(this,b)};Buffer.prototype.indexOf=function indexOf(val,byteOffset){if(byteOffset>2147483647)byteOffset=2147483647;else if(byteOffset<-2147483648)byteOffset=-2147483648;byteOffset>>=0;if(this.length===0)return-1;if(byteOffset>=this.length)return-1;if(byteOffset<0)byteOffset=Math.max(this.length+byteOffset,0);if(typeof val==="string"){if(val.length===0)return-1;return String.prototype.indexOf.call(this,val,byteOffset)}if(Buffer.isBuffer(val)){return arrayIndexOf(this,val,byteOffset)}if(typeof val==="number"){if(Buffer.TYPED_ARRAY_SUPPORT&&Uint8Array.prototype.indexOf==="function"){return Uint8Array.prototype.indexOf.call(this,val,byteOffset)}return arrayIndexOf(this,[val],byteOffset)}function arrayIndexOf(arr,val,byteOffset){var foundIndex=-1;for(var i=0;byteOffset+iremaining){length=remaining}}var strLen=string.length;if(strLen%2!==0)throw new Error("Invalid hex string");if(length>strLen/2){length=strLen/2}for(var i=0;ithis.length){throw new RangeError("attempt to write outside buffer bounds")}var remaining=this.length-offset;if(!length){length=remaining}else{length=Number(length);if(length>remaining){length=remaining}}encoding=String(encoding||"utf8").toLowerCase();var ret;switch(encoding){case"hex":ret=hexWrite(this,string,offset,length);break;case"utf8":case"utf-8":ret=utf8Write(this,string,offset,length);break;case"ascii":ret=asciiWrite(this,string,offset,length);break;case"binary":ret=binaryWrite(this,string,offset,length);break;case"base64":ret=base64Write(this,string,offset,length);break;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":ret=utf16leWrite(this,string,offset,length);break;default:throw new TypeError("Unknown encoding: "+encoding)}return ret};Buffer.prototype.toJSON=function toJSON(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function base64Slice(buf,start,end){if(start===0&&end===buf.length){return base64.fromByteArray(buf)}else{return base64.fromByteArray(buf.slice(start,end))}}function utf8Slice(buf,start,end){var res="";var tmp="";end=Math.min(buf.length,end);for(var i=start;ilen)end=len;var out="";for(var i=start;ilen){start=len}if(end<0){end+=len;if(end<0)end=0}else if(end>len){end=len}if(endlength)throw new RangeError("Trying to access beyond buffer length")}Buffer.prototype.readUIntLE=function readUIntLE(offset,byteLength,noAssert){offset=offset>>>0;byteLength=byteLength>>>0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i>>0;byteLength=byteLength>>>0;if(!noAssert){checkOffset(offset,byteLength,this.length)}var val=this[offset+--byteLength];var mul=1;while(byteLength>0&&(mul*=256)){val+=this[offset+--byteLength]*mul}return val};Buffer.prototype.readUInt8=function readUInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);return this[offset]};Buffer.prototype.readUInt16LE=function readUInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]|this[offset+1]<<8};Buffer.prototype.readUInt16BE=function readUInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]<<8|this[offset+1]};Buffer.prototype.readUInt32LE=function readUInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return(this[offset]|this[offset+1]<<8|this[offset+2]<<16)+this[offset+3]*16777216};Buffer.prototype.readUInt32BE=function readUInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]*16777216+(this[offset+1]<<16|this[offset+2]<<8|this[offset+3])};Buffer.prototype.readIntLE=function readIntLE(offset,byteLength,noAssert){offset=offset>>>0;byteLength=byteLength>>>0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readIntBE=function readIntBE(offset,byteLength,noAssert){offset=offset>>>0;byteLength=byteLength>>>0;if(!noAssert)checkOffset(offset,byteLength,this.length);var i=byteLength;var mul=1;var val=this[offset+--i];while(i>0&&(mul*=256)){val+=this[offset+--i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readInt8=function readInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);if(!(this[offset]&128))return this[offset];return(255-this[offset]+1)*-1};Buffer.prototype.readInt16LE=function readInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset]|this[offset+1]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt16BE=function readInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset+1]|this[offset]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt32LE=function readInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]|this[offset+1]<<8|this[offset+2]<<16|this[offset+3]<<24};Buffer.prototype.readInt32BE=function readInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]<<24|this[offset+1]<<16|this[offset+2]<<8|this[offset+3]};Buffer.prototype.readFloatLE=function readFloatLE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,true,23,4)};Buffer.prototype.readFloatBE=function readFloatBE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,false,23,4)};Buffer.prototype.readDoubleLE=function readDoubleLE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,true,52,8)};Buffer.prototype.readDoubleBE=function readDoubleBE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,false,52,8)};function checkInt(buf,value,offset,ext,max,min){if(!Buffer.isBuffer(buf))throw new TypeError("buffer must be a Buffer instance");if(value>max||valuebuf.length)throw new RangeError("index out of range")}Buffer.prototype.writeUIntLE=function writeUIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset>>>0;byteLength=byteLength>>>0;if(!noAssert)checkInt(this,value,offset,byteLength,Math.pow(2,8*byteLength),0);var mul=1;var i=0;this[offset]=value&255;while(++i>>0&255}return offset+byteLength};Buffer.prototype.writeUIntBE=function writeUIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset>>>0;byteLength=byteLength>>>0;if(!noAssert)checkInt(this,value,offset,byteLength,Math.pow(2,8*byteLength),0);var i=byteLength-1;var mul=1;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){this[offset+i]=value/mul>>>0&255}return offset+byteLength};Buffer.prototype.writeUInt8=function writeUInt8(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,1,255,0);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);this[offset]=value;return offset+1};function objectWriteUInt16(buf,value,offset,littleEndian){if(value<0)value=65535+value+1;for(var i=0,j=Math.min(buf.length-offset,2);i>>(littleEndian?i:1-i)*8}}Buffer.prototype.writeUInt16LE=function writeUInt16LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeUInt16BE=function writeUInt16BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value}else{objectWriteUInt16(this,value,offset,false)}return offset+2};function objectWriteUInt32(buf,value,offset,littleEndian){if(value<0)value=4294967295+value+1;for(var i=0,j=Math.min(buf.length-offset,4);i>>(littleEndian?i:3-i)*8&255}}Buffer.prototype.writeUInt32LE=function writeUInt32LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset+3]=value>>>24;this[offset+2]=value>>>16;this[offset+1]=value>>>8;this[offset]=value}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeUInt32BE=function writeUInt32BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value}else{objectWriteUInt32(this,value,offset,false)}return offset+4};Buffer.prototype.writeIntLE=function writeIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset>>>0;if(!noAssert){checkInt(this,value,offset,byteLength,Math.pow(2,8*byteLength-1)-1,-Math.pow(2,8*byteLength-1))}var i=0;var mul=1;var sub=value<0?1:0;this[offset]=value&255;while(++i>0)-sub&255}return offset+byteLength};Buffer.prototype.writeIntBE=function writeIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset>>>0;if(!noAssert){checkInt(this,value,offset,byteLength,Math.pow(2,8*byteLength-1)-1,-Math.pow(2,8*byteLength-1))}var i=byteLength-1;var mul=1;var sub=value<0?1:0;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeInt8=function writeInt8(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,1,127,-128);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);if(value<0)value=255+value+1;this[offset]=value;return offset+1};Buffer.prototype.writeInt16LE=function writeInt16LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeInt16BE=function writeInt16BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value}else{objectWriteUInt16(this,value,offset,false)}return offset+2};Buffer.prototype.writeInt32LE=function writeInt32LE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value;this[offset+1]=value>>>8;this[offset+2]=value>>>16;this[offset+3]=value>>>24}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeInt32BE=function writeInt32BE(value,offset,noAssert){value=+value;offset=offset>>>0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(value<0)value=4294967295+value+1;if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value}else{objectWriteUInt32(this,value,offset,false)}return offset+4};function checkIEEE754(buf,value,offset,ext,max,min){if(value>max||valuebuf.length)throw new RangeError("index out of range");if(offset<0)throw new RangeError("index out of range")}function writeFloat(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,4,3.4028234663852886e38,-3.4028234663852886e38)}ieee754.write(buf,value,offset,littleEndian,23,4);return offset+4}Buffer.prototype.writeFloatLE=function writeFloatLE(value,offset,noAssert){return writeFloat(this,value,offset,true,noAssert)};Buffer.prototype.writeFloatBE=function writeFloatBE(value,offset,noAssert){return writeFloat(this,value,offset,false,noAssert)};function writeDouble(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,8,1.7976931348623157e308,-1.7976931348623157e308)}ieee754.write(buf,value,offset,littleEndian,52,8);return offset+8}Buffer.prototype.writeDoubleLE=function writeDoubleLE(value,offset,noAssert){return writeDouble(this,value,offset,true,noAssert)};Buffer.prototype.writeDoubleBE=function writeDoubleBE(value,offset,noAssert){return writeDouble(this,value,offset,false,noAssert)};Buffer.prototype.copy=function copy(target,target_start,start,end){if(!start)start=0;if(!end&&end!==0)end=this.length;if(target_start>=target.length)target_start=target.length;if(!target_start)target_start=0;if(end>0&&end=this.length)throw new RangeError("sourceStart out of bounds");if(end<0)throw new RangeError("sourceEnd out of bounds");if(end>this.length)end=this.length;if(target.length-target_start=this.length)throw new RangeError("start out of bounds"); -if(end<0||end>this.length)throw new RangeError("end out of bounds");var i;if(typeof value==="number"){for(i=start;i55295&&codePoint<57344){if(leadSurrogate){if(codePoint<56320){if((units-=3)>-1)bytes.push(239,191,189);leadSurrogate=codePoint;continue}else{codePoint=leadSurrogate-55296<<10|codePoint-56320|65536;leadSurrogate=null}}else{if(codePoint>56319){if((units-=3)>-1)bytes.push(239,191,189);continue}else if(i+1===length){if((units-=3)>-1)bytes.push(239,191,189);continue}else{leadSurrogate=codePoint;continue}}}else if(leadSurrogate){if((units-=3)>-1)bytes.push(239,191,189);leadSurrogate=null}if(codePoint<128){if((units-=1)<0)break;bytes.push(codePoint)}else if(codePoint<2048){if((units-=2)<0)break;bytes.push(codePoint>>6|192,codePoint&63|128)}else if(codePoint<65536){if((units-=3)<0)break;bytes.push(codePoint>>12|224,codePoint>>6&63|128,codePoint&63|128)}else if(codePoint<2097152){if((units-=4)<0)break;bytes.push(codePoint>>18|240,codePoint>>12&63|128,codePoint>>6&63|128,codePoint&63|128)}else{throw new Error("Invalid code point")}}return bytes}function asciiToBytes(str){var byteArray=[];for(var i=0;i>8;lo=c%256;byteArray.push(lo);byteArray.push(hi)}return byteArray}function base64ToBytes(str){return base64.toByteArray(base64clean(str))}function blitBuffer(src,dst,offset,length){for(var i=0;i=dst.length||i>=src.length)break;dst[i+offset]=src[i]}return i}function decodeUtf8Char(str){try{return decodeURIComponent(str)}catch(err){return String.fromCharCode(65533)}}}).call(exports,__webpack_require__(7).Buffer)},function(module,exports,__webpack_require__){"use strict";function isBMP(buffer){return"BM"===buffer.toString("ascii",0,2)}function calculate(buffer){return{width:buffer.readUInt32LE(18),height:buffer.readUInt32LE(22)}}module.exports={detect:isBMP,calculate:calculate}},function(module,exports,__webpack_require__){"use strict";var gifRegexp=/^GIF8[7,9]a/;function isGIF(buffer){var signature=buffer.toString("ascii",0,6);return gifRegexp.test(signature)}function calculate(buffer){return{width:buffer.readUInt16LE(6),height:buffer.readUInt16LE(8)}}module.exports={detect:isGIF,calculate:calculate}},function(module,exports,__webpack_require__){"use strict";var validJFIFMarkers={ffdb:"0001010101",ffe0:"4a46494600",ffe1:"4578696600",ffe2:"4943435f50",ffe3:"",ffe8:"5350494646",ffec:"4475636b79",ffed:"50686f746f",ffee:"41646f6265"};var red=["",""];function isJPG(buffer){var SOIMarker=buffer.toString("hex",0,2);var JFIFMarker=buffer.toString("hex",2,4);if("ffd8"!==SOIMarker){return false}var got=buffer.toString("hex",6,11);var expected=JFIFMarker&&validJFIFMarkers[JFIFMarker];if(expected===""){console.warn(red[0]+"this looks like a unrecognised jpeg\n"+"please report the issue here\n"+red[1]," https://github.com/netroy/image-size/issues/new\n");return false}return got===expected||JFIFMarker==="ffdb"}function extractSize(buffer,i){return{height:buffer.readUInt16BE(i),width:buffer.readUInt16BE(i+2)}}function validateBuffer(buffer,i){if(i>buffer.length){throw new TypeError("Corrupt JPG, exceeded buffer limits")}if(buffer[i]!==255){throw new TypeError("Invalid JPG, marker table corrupted")}}function calculate(buffer){buffer=buffer.slice(4);var i,next;while(buffer.length){i=buffer.readUInt16BE(0);validateBuffer(buffer,i);next=buffer[i+1];if(next===192||next===194){return extractSize(buffer,i+5)}buffer=buffer.slice(i+2)}throw new TypeError("Invalid JPG, no size found")}module.exports={detect:isJPG,calculate:calculate}},function(module,exports,__webpack_require__){"use strict";var pngSignature="PNG\r\n\n";function isPNG(buffer){if(pngSignature===buffer.toString("ascii",1,8)){if("IHDR"!==buffer.toString("ascii",12,16)){throw new TypeError("invalid png")}return true}}function calculate(buffer){return{width:buffer.readUInt32BE(16),height:buffer.readUInt32BE(20)}}module.exports={detect:isPNG,calculate:calculate}},function(module,exports,__webpack_require__){"use strict";function isPSD(buffer){return"8BPS"===buffer.toString("ascii",0,4)}function calculate(buffer){return{width:buffer.readUInt32BE(18),height:buffer.readUInt32BE(14)}}module.exports={detect:isPSD,calculate:calculate}},function(module,exports,__webpack_require__){"use strict";var svgReg=/]+[^>]*>/;function isSVG(buffer){return svgReg.test(buffer)}var extractorRegExps={root:/]+>/,width:/(^|\s)width\s*=\s*"(.+?)"/i,height:/(^|\s)height\s*=\s*"(.+?)"/i,viewbox:/(^|\s)viewbox\s*=\s*"(.+?)"/i};function getRatio(viewbox){var ratio=1;if(viewbox&&viewbox[2]){var dim=viewbox[2].split(/\s/g);if(dim.length===4){dim=dim.map(function(i){return parseInt(i,10)});ratio=(dim[2]-dim[0])/(dim[3]-dim[1])}}return ratio}function parse(buffer){var body=buffer.toString().replace(/[\r\n\s]+/g," ");var section=body.match(extractorRegExps.root);var root=section&§ion[0];if(root){var width=root.match(extractorRegExps.width);var height=root.match(extractorRegExps.height);var viewbox=root.match(extractorRegExps.viewbox);var ratio=getRatio(viewbox);return{width:parseInt(width&&width[2],10)||0,height:parseInt(height&&height[2],10)||0,ratio:ratio}}}function calculate(buffer){var parsed=parse(buffer);var width=parsed.width;var height=parsed.height;var ratio=parsed.ratio;if(width&&height){return{width:width,height:height}}else{if(width){return{width:width,height:Math.floor(width/ratio)}}else if(height){return{width:Math.floor(height*ratio),height:height}}else{throw new TypeError("invalid svg")}}}module.exports={detect:isSVG,calculate:calculate}},function(module,exports,__webpack_require__){(function(Buffer){"use strict";var fs=__webpack_require__(16);var readUInt=__webpack_require__(17);function isTIFF(buffer){var hex4=buffer.toString("hex",0,4);return"49492a00"===hex4||"4d4d002a"===hex4}function readIFD(buffer,filepath,isBigEndian){var ifdOffset=readUInt(buffer,32,4,isBigEndian);var bufferSize=1024;var fileSize=fs.statSync(filepath).size;if(ifdOffset+bufferSize>fileSize){bufferSize=fileSize-ifdOffset-10}var endBuffer=new Buffer(bufferSize);var descriptor=fs.openSync(filepath,"r");fs.readSync(descriptor,endBuffer,0,bufferSize,ifdOffset);var ifdBuffer=endBuffer.slice(2);return ifdBuffer}function readValue(buffer,isBigEndian){var low=readUInt(buffer,16,8,isBigEndian);var high=readUInt(buffer,16,10,isBigEndian);return(high<<16)+low}function nextTag(buffer){if(buffer.length>24){return buffer.slice(12)}}function extractTags(buffer,isBigEndian){var tags={};var code,type,length;while(buffer&&buffer.length){code=readUInt(buffer,16,0,isBigEndian);type=readUInt(buffer,16,2,isBigEndian);length=readUInt(buffer,32,4,isBigEndian);if(code===0){break}else{if(length===1&&type===3){tags[code]=readValue(buffer,isBigEndian)}buffer=nextTag(buffer)}}return tags}function determineEndianness(buffer){var signature=buffer.toString("ascii",0,2);if("II"===signature){return"LE"}else if("MM"===signature){return"BE"}}function calculate(buffer,filepath){if(!filepath){throw new TypeError("Tiff doesn't support buffer")}var isBigEndian=determineEndianness(buffer)==="BE";var ifdBuffer=readIFD(buffer,filepath,isBigEndian);var tags=extractTags(ifdBuffer,isBigEndian);var width=tags[256];var height=tags[257];if(!width||!height){throw new TypeError("Invalid Tiff, missing tags")}return{width:width,height:height}}module.exports={detect:isTIFF,calculate:calculate}}).call(exports,__webpack_require__(7).Buffer)},function(module,exports,__webpack_require__){"use strict";function isWebP(buffer){var riffHeader="RIFF"===buffer.toString("ascii",0,4);var webpHeader="WEBP"===buffer.toString("ascii",8,12);var vp8Header="VP8"===buffer.toString("ascii",12,15);return riffHeader&&webpHeader&&vp8Header}function calculate(buffer){var chunkHeader=buffer.toString("ascii",12,16);buffer=buffer.slice(20,30);if(chunkHeader==="VP8 "&&buffer[0]!==47){return calculateLossy(buffer)}var signature=buffer.toString("hex",3,6);if(chunkHeader==="VP8L"&&signature!=="9d012a"){return calculateLossless(buffer)}return false}function calculateLossless(buffer){return{width:1+((buffer[2]&63)<<8|buffer[1]),height:1+((buffer[4]&15)<<10|buffer[3]<<2|(buffer[2]&192)>>6)}}function calculateLossy(buffer){return{width:buffer.readInt16LE(6)&16383,height:buffer.readInt16LE(8)&16383}}module.exports={detect:isWebP,calculate:calculate}},function(module,exports,__webpack_require__){},function(module,exports,__webpack_require__){"use strict";module.exports=function(buffer,bits,offset,isBigEndian){offset=offset||0;var endian=!!isBigEndian?"BE":"LE";var method=buffer["readUInt"+bits+endian];return method.call(buffer,offset)}},function(module,exports,__webpack_require__){var process=module.exports={};var queue=[];var draining=false;function drainQueue(){if(draining){return}draining=true;var currentQueue;var len=queue.length;while(len){currentQueue=queue;queue=[];var i=-1;while(++i>1,nBits=-7,i=isLE?nBytes-1:0,d=isLE?-1:1,s=buffer[offset+i];i+=d;e=s&(1<<-nBits)-1;s>>=-nBits;nBits+=eLen;for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8);m=e&(1<<-nBits)-1;e>>=-nBits;nBits+=mLen;for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8);if(e===0){e=1-eBias}else if(e===eMax){return m?NaN:(s?-1:1)*Infinity}else{m=m+Math.pow(2,mLen);e=e-eBias}return(s?-1:1)*m*Math.pow(2,e-mLen)};exports.write=function(buffer,value,offset,isLE,mLen,nBytes){var e,m,c,eLen=nBytes*8-mLen-1,eMax=(1<>1,rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0,i=isLE?0:nBytes-1,d=isLE?1:-1,s=value<0||value===0&&1/value<0?1:0;value=Math.abs(value);if(isNaN(value)||value===Infinity){m=isNaN(value)?1:0;e=eMax}else{e=Math.floor(Math.log(value)/Math.LN2);if(value*(c=Math.pow(2,-e))<1){e--;c*=2}if(e+eBias>=1){value+=rt/c}else{value+=rt*Math.pow(2,1-eBias)}if(value*c>=2){e++;c/=2}if(e+eBias>=eMax){m=0;e=eMax}else if(e+eBias>=1){m=(value*c-1)*Math.pow(2,mLen);e=e+eBias}else{m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);e=0}}for(;mLen>=8;buffer[offset+i]=m&255,i+=d,m/=256,mLen-=8);e=e<0;buffer[offset+i]=e&255,i+=d,e/=256,eLen-=8);buffer[offset+i-d]|=s*128}},function(module,exports,__webpack_require__){var isArray=Array.isArray;var str=Object.prototype.toString;module.exports=isArray||function(val){return!!val&&"[object Array]"==str.call(val)}},function(module,exports,__webpack_require__){var lookup="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";(function(exports){"use strict";var Arr=typeof Uint8Array!=="undefined"?Uint8Array:Array;var PLUS="+".charCodeAt(0);var SLASH="/".charCodeAt(0);var NUMBER="0".charCodeAt(0);var LOWER="a".charCodeAt(0);var UPPER="A".charCodeAt(0);var PLUS_URL_SAFE="-".charCodeAt(0);var SLASH_URL_SAFE="_".charCodeAt(0);function decode(elt){var code=elt.charCodeAt(0);if(code===PLUS||code===PLUS_URL_SAFE)return 62;if(code===SLASH||code===SLASH_URL_SAFE)return 63;if(code0){throw new Error("Invalid string. Length must be a multiple of 4")}var len=b64.length;placeHolders="="===b64.charAt(len-2)?2:"="===b64.charAt(len-1)?1:0;arr=new Arr(b64.length*3/4-placeHolders);l=placeHolders>0?b64.length-4:b64.length;var L=0;function push(v){arr[L++]=v}for(i=0,j=0;i>16);push((tmp&65280)>>8);push(tmp&255)}if(placeHolders===2){tmp=decode(b64.charAt(i))<<2|decode(b64.charAt(i+1))>>4;push(tmp&255)}else if(placeHolders===1){tmp=decode(b64.charAt(i))<<10|decode(b64.charAt(i+1))<<4|decode(b64.charAt(i+2))>>2;push(tmp>>8&255);push(tmp&255)}return arr}function uint8ToBase64(uint8){var i,extraBytes=uint8.length%3,output="",temp,length;function encode(num){return lookup.charAt(num)}function tripletToBase64(num){return encode(num>>18&63)+encode(num>>12&63)+encode(num>>6&63)+encode(num&63)}for(i=0,length=uint8.length-extraBytes;i>2);output+=encode(temp<<4&63);output+="==";break;case 2:temp=(uint8[uint8.length-2]<<8)+uint8[uint8.length-1];output+=encode(temp>>10);output+=encode(temp>>4&63);output+=encode(temp<<2&63);output+="=";break}return output}exports.toByteArray=b64ToByteArray;exports.fromByteArray=uint8ToBase64})(false?this.base64js={}:exports)}])}); \ No newline at end of file diff --git a/src/utils/markdown-it/markdown-it-sub.min.js b/src/utils/markdown-it/markdown-it-sub.min.js deleted file mode 100644 index a3a4542f..00000000 --- a/src/utils/markdown-it/markdown-it-sub.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! markdown-it-sub 1.0.0 https://github.com//markdown-it/markdown-it-sub @license MIT */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.markdownitSub=e()}}(function(){return function e(r,o,n){function t(i,u){if(!o[i]){if(!r[i]){var f="function"==typeof require&&require;if(!u&&f)return f(i,!0);if(s)return s(i,!0);var p=new Error("Cannot find module '"+i+"'");throw p.code="MODULE_NOT_FOUND",p}var a=o[i]={exports:{}};r[i][0].call(a.exports,function(e){var o=r[i][1][e];return t(o?o:e)},a,a.exports,e,r,o,n)}return o[i].exports}for(var s="function"==typeof require&&require,i=0;i=i)return!1;for(e.pos=u+1;e.pos?@[\]^_`{|}~-])/g;r.exports=function(e){e.inline.ruler.after("emphasis","sub",o)}},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/utils/markdown-it/markdown-it-sup.min.js b/src/utils/markdown-it/markdown-it-sup.min.js deleted file mode 100644 index 67da65cd..00000000 --- a/src/utils/markdown-it/markdown-it-sup.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! markdown-it-sup 1.0.0 https://github.com//markdown-it/markdown-it-sup @license MIT */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.markdownitSup=e()}}(function(){return function e(r,o,n){function t(i,p){if(!o[i]){if(!r[i]){var u="function"==typeof require&&require;if(!p&&u)return u(i,!0);if(s)return s(i,!0);var f=new Error("Cannot find module '"+i+"'");throw f.code="MODULE_NOT_FOUND",f}var a=o[i]={exports:{}};r[i][0].call(a.exports,function(e){var o=r[i][1][e];return t(o?o:e)},a,a.exports,e,r,o,n)}return o[i].exports}for(var s="function"==typeof require&&require,i=0;i=i)return!1;for(e.pos=p+1;e.pos?@[\]^_`{|}~-])/g;r.exports=function(e){e.inline.ruler.after("emphasis","sup",o)}},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/src/utils/markdown-it/markdown-it-task-lists.min.js b/src/utils/markdown-it/markdown-it-task-lists.min.js deleted file mode 100644 index 6a3f81a7..00000000 --- a/src/utils/markdown-it/markdown-it-task-lists.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! markdown-it-task-lists 1.4.0 https://github.com/revin/markdown-it-task-lists#readme by @license {ISC} */ -!function(n){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define([],n);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.markdownitTaskLists=n()}}(function(){return function n(e,t,i){function r(c,f){if(!t[c]){if(!e[c]){var u="function"==typeof require&&require;if(!f&&u)return u(c,!0);if(o)return o(c,!0);var l=new Error("Cannot find module '"+c+"'");throw l.code="MODULE_NOT_FOUND",l}var s=t[c]={exports:{}};e[c][0].call(s.exports,function(n){var t=e[c][1][n];return r(t?t:n)},s,s.exports,n,e,t,i)}return t[c].exports}for(var o="function"==typeof require&&require,c=0;ci?n.attrPush(r):n.attrs[i]=r}function r(n,e){for(var t=n[e].level-1,i=e-1;i>=0;i--)if(n[i].level===t)return i;return-1}function o(n,e){return s(n[e])&&a(n[e-1])&&d(n[e-2])&&p(n[e])}function c(n,e){n.children.unshift(f(n,e)),n.children[1].content=n.children[1].content.slice(3),n.content=n.content.slice(3),x&&(n.children.unshift(u(e)),n.children.push(l(e)))}function f(n,e){var t=new e("html_inline","",0),i=h?' disabled="" ':"";return 0===n.content.indexOf("[ ]")?t.content='($2)', - tag: '\\[' - }, - { name: 'math_block', - rex: /\\\[(.+?)\\\]\s*$/gmy, - tmpl: '$1', - tag: '\\[' - } - ] - }, - gitlab: { - inline: [ - { name: 'math_inline', - rex: /\$`(.+?)`\$/gy, - tmpl: '$1', - tag: '$`' - } - ], - block: [ - { name: 'math_block_eqno', - rex: /`{3}math\s+?([^`]+?)\s+?`{3}\s*?\(([^)$\r\n]+?)\)\s*$/gmy, - tmpl: '$1($2)', - tag: '```math' - }, - { name: 'math_block', - rex: /`{3}math\s+?([^`]+?)\s+?`{3}\s*$/gmy, - tmpl: '$1', - tag: '```math' - } - ] - }, - dollars: { - inline: [ - { name: 'math_inline', - rex: /\$(\S[^$\r\n]*?[^\s\\]{1}?)\$/gy, - tmpl: '$1', - tag: '$', - pre: texmath.$_pre, - post: texmath.$_post - }, - { name: 'math_single', - rex: /\$([^$\s\\]{1}?)\$/gy, - tmpl: '$1', - tag: '$', - pre: texmath.$_pre, - post: texmath.$_post - } - ], - block: [ - { name: 'math_block_eqno', - rex: /\${2}((?:[^$]|\$(?!\$))*?)\${2}\s*?\(([^)$\r\n]+?)\)\s*$/gmy, - tmpl: '$1($2)', - tag: '$$' - }, - { name: 'math_block', - rex: /\${2}((?:[^$]|\$(?!\$))*?)\${2}\s*$/gmy, - tmpl: '$1', - tag: '$$' - } - ] - }, - raw: { - inline: [], - block: [ - { - name: 'math_block', - rex: /(\\begin\s*\{([^{}\s\r\n]+)\}(?:[^\\]|\\(?!end\s*\{\2\}))*\\end\s*\{\2\})\s*$/gmy, - tmpl: '$1', - tag: '\\begin' - } - ] - } -}; - -if (typeof module === "object" && module.exports) - module.exports = texmath; diff --git a/src/utils/markdown-it/markdown-it.min.js b/src/utils/markdown-it/markdown-it.min.js deleted file mode 100644 index f9ea3235..00000000 --- a/src/utils/markdown-it/markdown-it.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! markdown-it 8.3.1 https://github.com//markdown-it/markdown-it @license MIT */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.markdownit=e()}}(function(){var e;return function e(r,t,n){function s(i,a){if(!t[i]){if(!r[i]){var c="function"==typeof require&&require;if(!a&&c)return c(i,!0);if(o)return o(i,!0);var l=new Error("Cannot find module '"+i+"'");throw l.code="MODULE_NOT_FOUND",l}var u=t[i]={exports:{}};r[i][0].call(u.exports,function(e){var t=r[i][1][e];return s(t?t:e)},u,u.exports,e,r,t,n)}return t[i].exports}for(var o="function"==typeof require&&require,i=0;i`\\x00-\\x20]+|'[^']*'|\"[^\"]*\"))?)*\\s*\\/?>",s="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",o=new RegExp("^(?:"+n+"|"+s+"|||<[?].*?[?]>|]*>|)"),i=new RegExp("^(?:"+n+"|"+s+")");r.exports.HTML_TAG_RE=o,r.exports.HTML_OPEN_CLOSE_TAG_RE=i},{}],4:[function(e,r,t){"use strict";function n(e){return Object.prototype.toString.call(e)}function s(e){return"[object String]"===n(e)}function o(e,r){return y.call(e,r)}function i(e){return Array.prototype.slice.call(arguments,1).forEach(function(r){if(r){if("object"!=typeof r)throw new TypeError(r+"must be object");Object.keys(r).forEach(function(t){e[t]=r[t]})}}),e}function a(e,r,t){return[].concat(e.slice(0,r),t,e.slice(r+1))}function c(e){return!(e>=55296&&e<=57343)&&(!(e>=64976&&e<=65007)&&(65535!=(65535&e)&&65534!=(65535&e)&&(!(e>=0&&e<=8)&&(11!==e&&(!(e>=14&&e<=31)&&(!(e>=127&&e<=159)&&!(e>1114111)))))))}function l(e){if(e>65535){e-=65536;var r=55296+(e>>10),t=56320+(1023&e);return String.fromCharCode(r,t)}return String.fromCharCode(e)}function u(e,r){var t=0;return o(w,r)?w[r]:35===r.charCodeAt(0)&&A.test(r)&&(t="x"===r[1].toLowerCase()?parseInt(r.slice(2),16):parseInt(r.slice(1),10),c(t))?l(t):e}function p(e){return e.indexOf("\\")<0?e:e.replace(x,"$1")}function h(e){return e.indexOf("\\")<0&&e.indexOf("&")<0?e:e.replace(C,function(e,r,t){return r?r:u(e,t)})}function f(e){return q[e]}function d(e){return D.test(e)?e.replace(/[&<>"]/g,f):e}function m(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}function _(e){switch(e){case 9:case 32:return!0}return!1}function g(e){if(e>=8192&&e<=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1}function b(e){return E.test(e)}function k(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}}function v(e){return e.trim().replace(/\s+/g," ").toUpperCase()}var y=Object.prototype.hasOwnProperty,x=/\\([!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])/g,C=new RegExp(x.source+"|"+/&([a-z#][a-z0-9]{1,31});/gi.source,"gi"),A=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i,w=e("./entities"),D=/[&<>"]/,q={"&":"&","<":"<",">":">",'"':"""},E=e("uc.micro/categories/P/regex");t.lib={},t.lib.mdurl=e("mdurl"),t.lib.ucmicro=e("uc.micro"),t.assign=i,t.isString=s,t.has=o,t.unescapeMd=p,t.unescapeAll=h,t.isValidEntityCode=c,t.fromCodePoint=l,t.escapeHtml=d,t.arrayReplaceAt=a,t.isSpace=_,t.isWhiteSpace=g,t.isMdAsciiPunct=k,t.isPunctChar=b,t.escapeRE=m,t.normalizeReference=v},{"./entities":1,mdurl:58,"uc.micro":65,"uc.micro/categories/P/regex":63}],5:[function(e,r,t){"use strict";t.parseLinkLabel=e("./parse_link_label"),t.parseLinkDestination=e("./parse_link_destination"),t.parseLinkTitle=e("./parse_link_title")},{"./parse_link_destination":6,"./parse_link_label":7,"./parse_link_title":8}],6:[function(e,r,t){"use strict";var n=e("../common/utils").isSpace,s=e("../common/utils").unescapeAll;r.exports=function(e,r,t){var o,i,a=r,c={ok:!1,pos:0,lines:0,str:""};if(60===e.charCodeAt(r)){for(r++;r1)break;if(41===o&&--i<0)break;r++}return a===r?c:(c.str=s(e.slice(a,r)),c.lines=0,c.pos=r,c.ok=!0,c)}},{"../common/utils":4}],7:[function(e,r,t){"use strict";r.exports=function(e,r,t){var n,s,o,i,a=-1,c=e.posMax,l=e.pos;for(e.pos=r+1,n=1;e.pos=t)return c;if(34!==(o=e.charCodeAt(r))&&39!==o&&40!==o)return c;for(r++,40===o&&(o=41);r=0))try{r.hostname=m.toASCII(r.hostname)}catch(e){}return d.encode(d.format(r))}function o(e){var r=d.parse(e,!0);if(r.hostname&&(!r.protocol||k.indexOf(r.protocol)>=0))try{r.hostname=m.toUnicode(r.hostname)}catch(e){}return d.decode(d.format(r))}function i(e,r){if(!(this instanceof i))return new i(e,r);r||a.isString(e)||(r=e||{},e="default"),this.inline=new h,this.block=new p,this.core=new u,this.renderer=new l,this.linkify=new f,this.validateLink=n,this.normalizeLink=s,this.normalizeLinkText=o,this.utils=a,this.helpers=a.assign({},c),this.options={},this.configure(e),r&&this.set(r)}var a=e("./common/utils"),c=e("./helpers"),l=e("./renderer"),u=e("./parser_core"),p=e("./parser_block"),h=e("./parser_inline"),f=e("linkify-it"),d=e("mdurl"),m=e("punycode"),_={default:e("./presets/default"),zero:e("./presets/zero"),commonmark:e("./presets/commonmark")},g=/^(vbscript|javascript|file|data):/,b=/^data:image\/(gif|png|jpeg|webp);/,k=["http:","https:","mailto:"];i.prototype.set=function(e){return a.assign(this.options,e),this},i.prototype.configure=function(e){var r,t=this;if(a.isString(e)&&(r=e,!(e=_[r])))throw new Error('Wrong `markdown-it` preset "'+r+'", check name');if(!e)throw new Error("Wrong `markdown-it` preset, can't be empty");return e.options&&t.set(e.options),e.components&&Object.keys(e.components).forEach(function(r){e.components[r].rules&&t[r].ruler.enableOnly(e.components[r].rules),e.components[r].rules2&&t[r].ruler2.enableOnly(e.components[r].rules2)}),this},i.prototype.enable=function(e,r){var t=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach(function(r){t=t.concat(this[r].ruler.enable(e,!0))},this),t=t.concat(this.inline.ruler2.enable(e,!0));var n=e.filter(function(e){return t.indexOf(e)<0});if(n.length&&!r)throw new Error("MarkdownIt. Failed to enable unknown rule(s): "+n);return this},i.prototype.disable=function(e,r){var t=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach(function(r){t=t.concat(this[r].ruler.disable(e,!0))},this),t=t.concat(this.inline.ruler2.disable(e,!0));var n=e.filter(function(e){return t.indexOf(e)<0});if(n.length&&!r)throw new Error("MarkdownIt. Failed to disable unknown rule(s): "+n);return this},i.prototype.use=function(e){var r=[this].concat(Array.prototype.slice.call(arguments,1));return e.apply(e,r),this},i.prototype.parse=function(e,r){if("string"!=typeof e)throw new Error("Input data should be a String");var t=new this.core.State(e,this,r);return this.core.process(t),t.tokens},i.prototype.render=function(e,r){return r=r||{},this.renderer.render(this.parse(e,r),this.options,r)},i.prototype.parseInline=function(e,r){var t=new this.core.State(e,this,r);return t.inlineMode=!0,this.core.process(t),t.tokens},i.prototype.renderInline=function(e,r){return r=r||{},this.renderer.render(this.parseInline(e,r),this.options,r)},r.exports=i},{"./common/utils":4,"./helpers":5,"./parser_block":10,"./parser_core":11,"./parser_inline":12,"./presets/commonmark":13,"./presets/default":14,"./presets/zero":15,"./renderer":16,"linkify-it":53,mdurl:58,punycode:60}],10:[function(e,r,t){"use strict";function n(){this.ruler=new s;for(var e=0;e=t))&&!(e.sCount[i]=c){e.line=t;break}for(n=0;n=o)break}else e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()},n.prototype.parse=function(e,r,t,n){var s,o,i,a=new this.State(e,r,t,n);for(this.tokenize(a),o=this.ruler2.getRules(""),i=o.length,s=0;s"+i(e[r].content)+"
    "},a.code_block=function(e,r,t,n,s){var o=e[r];return""+i(e[r].content)+"
    \n"},a.fence=function(e,r,t,n,s){var a,c,l,u,p=e[r],h=p.info?o(p.info).trim():"",f="";return h&&(f=h.split(/\s+/g)[0]),a=t.highlight?t.highlight(p.content,f)||i(p.content):i(p.content),0===a.indexOf(""+a+"
    \n"):"
    "+a+"
    \n"},a.image=function(e,r,t,n,s){var o=e[r];return o.attrs[o.attrIndex("alt")][1]=s.renderInlineAsText(o.children,t,n),s.renderToken(e,r,t)},a.hardbreak=function(e,r,t){return t.xhtmlOut?"
    \n":"
    \n"},a.softbreak=function(e,r,t){return t.breaks?t.xhtmlOut?"
    \n":"
    \n":"\n"},a.text=function(e,r){return i(e[r].content)},a.html_block=function(e,r){return e[r].content},a.html_inline=function(e,r){return e[r].content},n.prototype.renderAttrs=function(e){var r,t,n;if(!e.attrs)return"";for(n="",r=0,t=e.attrs.length;r\n":">")},n.prototype.renderInline=function(e,r,t){for(var n,s="",o=this.rules,i=0,a=e.length;i=4)return!1;if(62!==e.src.charCodeAt(D++))return!1;if(s)return!0;for(c=d=e.sCount[r]+D-(e.bMarks[r]+e.tShift[r]),32===e.src.charCodeAt(D)?(D++,c++,d++,o=!1,y=!0):9===e.src.charCodeAt(D)?(y=!0,(e.bsCount[r]+d)%4==3?(D++,c++,d++,o=!1):o=!0):y=!1,m=[e.bMarks[r]],e.bMarks[r]=D;D=q,k=[e.sCount[r]],e.sCount[r]=d-c,v=[e.tShift[r]],e.tShift[r]=D-e.bMarks[r],C=e.md.block.ruler.getRules("blockquote"),b=e.parentType,e.parentType="blockquote",f=r+1;f=q));f++)if(62!==e.src.charCodeAt(D++)||l){if(p)break;for(x=!1,a=0,u=C.length;a=q,_.push(e.bsCount[f]),e.bsCount[f]=e.sCount[f]+1+(y?1:0),k.push(e.sCount[f]),e.sCount[f]=d-c,v.push(e.tShift[f]),e.tShift[f]=D-e.bMarks[f]}for(g=e.blkIndent,e.blkIndent=0,A=e.push("blockquote_open","blockquote",1),A.markup=">",A.map=h=[r,0],e.md.block.tokenize(e,r,f),A=e.push("blockquote_close","blockquote",-1),A.markup=">",e.lineMax=w,e.parentType=b,h[1]=e.line,a=0;a=4))break;n++,s=n}return e.line=s,o=e.push("code_block","code",0),o.content=e.getLines(r,s,4+e.blkIndent,!0),o.map=[r,e.line],!0}},{}],20:[function(e,r,t){"use strict";r.exports=function(e,r,t,n){var s,o,i,a,c,l,u,p=!1,h=e.bMarks[r]+e.tShift[r],f=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(h+3>f)return!1;if(126!==(s=e.src.charCodeAt(h))&&96!==s)return!1;if(c=h,h=e.skipChars(h,s),(o=h-c)<3)return!1;if(u=e.src.slice(c,h),i=e.src.slice(h,f),i.indexOf(String.fromCharCode(s))>=0)return!1;if(n)return!0;for(a=r;!(++a>=t)&&(h=c=e.bMarks[a]+e.tShift[a],f=e.eMarks[a],!(h=4||(h=e.skipChars(h,s))-c=4)return!1;if(35!==(o=e.src.charCodeAt(l))||l>=u)return!1;for(i=1,o=e.src.charCodeAt(++l);35===o&&l6||ll&&n(e.src.charCodeAt(a-1))&&(u=a),e.line=r+1,c=e.push("heading_open","h"+String(i),1),c.markup="########".slice(0,i),c.map=[r,e.line],c=e.push("inline","",0),c.content=e.src.slice(l,u).trim(),c.map=[r,e.line],c.children=[],c=e.push("heading_close","h"+String(i),-1),c.markup="########".slice(0,i),!0))}},{"../common/utils":4}],22:[function(e,r,t){"use strict";var n=e("../common/utils").isSpace;r.exports=function(e,r,t,s){var o,i,a,c,l=e.bMarks[r]+e.tShift[r],u=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(42!==(o=e.src.charCodeAt(l++))&&45!==o&&95!==o)return!1;for(i=1;l|$))/i,/<\/(script|pre|style)>/i,!0],[/^/,!0],[/^<\?/,/\?>/,!0],[/^/,!0],[/^/,!0],[new RegExp("^|$))","i"),/^$/,!0],[new RegExp(s.source+"\\s*$"),/^$/,!1]];r.exports=function(e,r,t,n){var s,i,a,c,l=e.bMarks[r]+e.tShift[r],u=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(!e.md.options.html)return!1;if(60!==e.src.charCodeAt(l))return!1;for(c=e.src.slice(l,u),s=0;s=4)return!1;for(h=e.parentType,e.parentType="paragraph";f3)){if(e.sCount[f]>=e.blkIndent&&(c=e.bMarks[f]+e.tShift[f],l=e.eMarks[f],c=l))){u=61===p?1:2;break}if(!(e.sCount[f]<0)){for(s=!1,o=0,i=d.length;o=o)return-1;if((t=e.src.charCodeAt(s++))<48||t>57)return-1;for(;;){if(s>=o)return-1;t=e.src.charCodeAt(s++);{if(!(t>=48&&t<=57)){if(41===t||46===t)break;return-1}if(s-n>=10)return-1}}return s=4)return!1;if(a&&"paragraph"===e.parentType&&e.tShift[r]>=e.blkIndent&&(M=!0),(F=s(e,r))>=0){if(d=!0,z=e.bMarks[r]+e.tShift[r],v=Number(e.src.substr(z,F-z-1)),M&&1!==v)return!1}else{if(!((F=n(e,r))>=0))return!1;d=!1}if(M&&e.skipSpaces(F)>=e.eMarks[r])return!1;if(k=e.src.charCodeAt(F-1),a)return!0;for(b=e.tokens.length,d?(R=e.push("ordered_list_open","ol",1),1!==v&&(R.attrs=[["start",v]])):R=e.push("bullet_list_open","ul",1),R.map=g=[r,0],R.markup=String.fromCharCode(k),x=r,L=!1,I=e.md.block.ruler.getRules("list"),D=e.parentType,e.parentType="list";x=y?1:C-f,h>4&&(h=1),p=f+h,R=e.push("list_item_open","li",1),R.markup=String.fromCharCode(k),R.map=m=[r,0],A=e.blkIndent,E=e.tight,q=e.tShift[r],w=e.sCount[r],e.blkIndent=p,e.tight=!0,e.tShift[r]=l-e.bMarks[r],e.sCount[r]=C,l>=y&&e.isEmpty(r+1)?e.line=Math.min(e.line+2,t):e.md.block.tokenize(e,r,t,!0),e.tight&&!L||(B=!1),L=e.line-r>1&&e.isEmpty(e.line-1),e.blkIndent=A,e.tShift[r]=q,e.sCount[r]=w,e.tight=E,R=e.push("list_item_close","li",-1),R.markup=String.fromCharCode(k),x=r=e.line,m[1]=x,l=e.bMarks[r],x>=t)break;if(e.sCount[x]3||e.sCount[c]<0)){for(n=!1,s=0,o=l.length;s=4)return!1;if(91!==e.src.charCodeAt(C))return!1;for(;++C3||e.sCount[w]<0)){for(k=!1,p=0,h=v.length;p0&&this.level++,this.tokens.push(n),n},n.prototype.isEmpty=function(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]},n.prototype.skipEmptyLines=function(e){for(var r=this.lineMax;er;)if(!o(this.src.charCodeAt(--e)))return e+1;return e},n.prototype.skipChars=function(e,r){for(var t=this.src.length;et;)if(r!==this.src.charCodeAt(--e))return e+1;return e},n.prototype.getLines=function(e,r,t,n){var s,i,a,c,l,u,p,h=e;if(e>=r)return"";for(u=new Array(r-e),s=0;ht?new Array(i-t+1).join(" ")+this.src.slice(c,l):this.src.slice(c,l)}return u.join("")},n.prototype.Token=s,r.exports=n},{"../common/utils":4,"../token":51}],29:[function(e,r,t){"use strict";function n(e,r){var t=e.bMarks[r]+e.blkIndent,n=e.eMarks[r];return e.src.substr(t,n-t)}function s(e){var r,t=[],n=0,s=e.length,o=0,i=0,a=!1,c=0;for(r=e.charCodeAt(n);nt)return!1;if(p=r+1,e.sCount[p]=4)return!1;if((l=e.bMarks[p]+e.tShift[p])>=e.eMarks[p])return!1;if(124!==(a=e.src.charCodeAt(l++))&&45!==a&&58!==a)return!1;for(;l=4)return!1;if(h=s(c.replace(/^\||\|$/g,"")),(f=h.length)>m.length)return!1;if(i)return!0;for(d=e.push("table_open","table",1),d.map=g=[r,0],d=e.push("thead_open","thead",1),d.map=[r,r+1],d=e.push("tr_open","tr",1),d.map=[r,r+1],u=0;u=4);p++){for(h=s(c.replace(/^\||\|$/g,"")),d=e.push("tr_open","tr",1),u=0;u\s]/i.test(e)}function s(e){return/^<\/a\s*>/i.test(e)}var o=e("../common/utils").arrayReplaceAt;r.exports=function(e){var r,t,i,a,c,l,u,p,h,f,d,m,_,g,b,k,v,y=e.tokens;if(e.md.options.linkify)for(t=0,i=y.length;t=0;r--)if(l=a[r],"link_close"!==l.type){if("html_inline"===l.type&&(n(l.content)&&_>0&&_--,s(l.content)&&_++),!(_>0)&&"text"===l.type&&e.md.linkify.test(l.content)){for(h=l.content,v=e.md.linkify.match(h),u=[],m=l.level,d=0,p=0;pd&&(c=new e.Token("text","",0),c.content=h.slice(d,f),c.level=m,u.push(c)),c=new e.Token("link_open","a",1),c.attrs=[["href",b]],c.level=m++,c.markup="linkify",c.info="auto",u.push(c),c=new e.Token("text","",0),c.content=k,c.level=m,u.push(c),c=new e.Token("link_close","a",-1),c.level=--m,c.markup="linkify",c.info="auto",u.push(c),d=v[p].lastIndex);d=0;r--)t=e[r],"text"!==t.type||s||(t.content=t.content.replace(/\((c|tm|r|p)\)/gi,n)),"link_open"===t.type&&"auto"===t.info&&s--,"link_close"===t.type&&"auto"===t.info&&s++}function o(e){var r,t,n=0;for(r=e.length-1;r>=0;r--)t=e[r],"text"!==t.type||n||i.test(t.content)&&(t.content=t.content.replace(/\+-/g,"\xb1").replace(/\.{2,}/g,"\u2026").replace(/([?!])\u2026/g,"$1..").replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",").replace(/(^|[^-])---([^-]|$)/gm,"$1\u2014$2").replace(/(^|\s)--(\s|$)/gm,"$1\u2013$2").replace(/(^|[^-\s])--([^-\s]|$)/gm,"$1\u2013$2")),"link_open"===t.type&&"auto"===t.info&&n--,"link_close"===t.type&&"auto"===t.info&&n++}var i=/\+-|\.\.|\?\?\?\?|!!!!|,,|--/,a=/\((c|tm|r|p)\)/i,c={c:"\xa9",r:"\xae",p:"\xa7",tm:"\u2122"};r.exports=function(e){var r;if(e.md.options.typographer)for(r=e.tokens.length-1;r>=0;r--)"inline"===e.tokens[r].type&&(a.test(e.tokens[r].content)&&s(e.tokens[r].children),i.test(e.tokens[r].content)&&o(e.tokens[r].children))}},{}],35:[function(e,r,t){"use strict";function n(e,r,t){return e.substr(0,r)+t+e.substr(r+1)}function s(e,r){var t,s,c,u,p,h,f,d,m,_,g,b,k,v,y,x,C,A,w,D,q;for(w=[],t=0;t=0&&!(w[C].level<=f);C--);if(w.length=C+1,"text"===s.type){c=s.content,p=0,h=c.length;e:for(;p=0)m=c.charCodeAt(u.index-1);else for(C=t-1;C>=0;C--)if("text"===e[C].type){m=e[C].content.charCodeAt(e[C].content.length-1);break}if(_=32,p=48&&m<=57&&(x=y=!1),y&&x&&(y=!1,x=b),y||x){if(x)for(C=w.length-1;C>=0&&(d=w[C],!(w[C].level=0;r--)"inline"===e.tokens[r].type&&c.test(e.tokens[r].content)&&s(e.tokens[r].children,e)}},{"../common/utils":4}],36:[function(e,r,t){"use strict";function n(e,r,t){this.src=e,this.env=t,this.tokens=[],this.inlineMode=!1,this.md=r}var s=e("../token");n.prototype.Token=s,r.exports=n},{"../token":51}],37:[function(e,r,t){"use strict";var n=/^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/,s=/^<([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)>/;r.exports=function(e,r){var t,o,i,a,c,l,u=e.pos;return 60===e.src.charCodeAt(u)&&(t=e.src.slice(u),!(t.indexOf(">")<0)&&(s.test(t)?(o=t.match(s),a=o[0].slice(1,-1),c=e.md.normalizeLink(a),!!e.md.validateLink(c)&&(r||(l=e.push("link_open","a",1),l.attrs=[["href",c]],l.markup="autolink",l.info="auto",l=e.push("text","",0),l.content=e.md.normalizeLinkText(a),l=e.push("link_close","a",-1),l.markup="autolink",l.info="auto"),e.pos+=o[0].length,!0)):!!n.test(t)&&(i=t.match(n),a=i[0].slice(1,-1),c=e.md.normalizeLink("mailto:"+a),!!e.md.validateLink(c)&&(r||(l=e.push("link_open","a",1),l.attrs=[["href",c]],l.markup="autolink",l.info="auto",l=e.push("text","",0),l.content=e.md.normalizeLinkText(a),l=e.push("link_close","a",-1),l.markup="autolink",l.info="auto"),e.pos+=i[0].length,!0))))}},{}],38:[function(e,r,t){"use strict";r.exports=function(e,r){var t,n,s,o,i,a,c=e.pos;if(96!==e.src.charCodeAt(c))return!1;for(t=c,c++,n=e.posMax;c=0;){if(s=o[t],s.open&&s.marker===n.marker&&s.end<0&&s.level===n.level){var a=(s.close||n.open)&&void 0!==s.length&&void 0!==n.length&&(s.length+n.length)%3==0;if(!a){n.jump=r-t,n.open=!1,s.end=r,s.jump=0;break}}t-=s.jump+1}}},{}],40:[function(e,r,t){"use strict";r.exports.tokenize=function(e,r){var t,n,s,o=e.pos,i=e.src.charCodeAt(o);if(r)return!1;if(95!==i&&42!==i)return!1;for(n=e.scanDelims(e.pos,42===i),t=0;t?@[]^_`{|}~-".split("").forEach(function(e){s[e.charCodeAt(0)]=1}),r.exports=function(e,r){var t,o=e.pos,i=e.posMax;if(92!==e.src.charCodeAt(o))return!1;if(++o=97&&r<=122}var s=e("../common/html_re").HTML_TAG_RE;r.exports=function(e,r){var t,o,i,a,c=e.pos;return!!e.md.options.html&&(i=e.posMax,!(60!==e.src.charCodeAt(c)||c+2>=i)&&(!(33!==(t=e.src.charCodeAt(c+1))&&63!==t&&47!==t&&!n(t))&&(!!(o=e.src.slice(c).match(s))&&(r||(a=e.push("html_inline","",0),a.content=e.src.slice(c,c+o[0].length)),e.pos+=o[0].length,!0))))}},{"../common/html_re":3}],44:[function(e,r,t){"use strict";var n=e("../common/utils").normalizeReference,s=e("../common/utils").isSpace;r.exports=function(e,r){var t,o,i,a,c,l,u,p,h,f,d,m,_,g="",b=e.pos,k=e.posMax;if(33!==e.src.charCodeAt(e.pos))return!1;if(91!==e.src.charCodeAt(e.pos+1))return!1;if(l=e.pos+2,(c=e.md.helpers.parseLinkLabel(e,e.pos+1,!1))<0)return!1;if((u=c+1)=k)return!1;for(_=u,h=e.md.helpers.parseLinkDestination(e.src,u,e.posMax),h.ok&&(g=e.md.normalizeLink(h.str),e.md.validateLink(g)?u=h.pos:g=""),_=u;u=k||41!==e.src.charCodeAt(u))return e.pos=b,!1;u++}else{if(void 0===e.env.references)return!1;if(u=0?a=e.src.slice(_,u++):u=c+1):u=c+1,a||(a=e.src.slice(l,c)),!(p=e.env.references[n(a)]))return e.pos=b,!1;g=p.href,f=p.title}return r||(i=e.src.slice(l,c),e.md.inline.parse(i,e.md,e.env,m=[]),d=e.push("image","img",0),d.attrs=t=[["src",g],["alt",""]],d.children=m,d.content=i,f&&t.push(["title",f])),e.pos=u,e.posMax=k,!0}},{"../common/utils":4}],45:[function(e,r,t){"use strict";var n=e("../common/utils").normalizeReference,s=e("../common/utils").isSpace;r.exports=function(e,r){var t,o,i,a,c,l,u,p,h,f,d="",m=e.pos,_=e.posMax,g=e.pos,b=!0;if(91!==e.src.charCodeAt(e.pos))return!1;if(c=e.pos+1,(a=e.md.helpers.parseLinkLabel(e,e.pos,!0))<0)return!1;if((l=a+1)<_&&40===e.src.charCodeAt(l)){for(b=!1,l++;l<_&&(o=e.src.charCodeAt(l),s(o)||10===o);l++);if(l>=_)return!1;for(g=l,u=e.md.helpers.parseLinkDestination(e.src,l,e.posMax),u.ok&&(d=e.md.normalizeLink(u.str),e.md.validateLink(d)?l=u.pos:d=""),g=l;l<_&&(o=e.src.charCodeAt(l),s(o)||10===o);l++);if(u=e.md.helpers.parseLinkTitle(e.src,l,e.posMax),l<_&&g!==l&&u.ok)for(h=u.str,l=u.pos;l<_&&(o=e.src.charCodeAt(l),s(o)||10===o);l++);else h="";(l>=_||41!==e.src.charCodeAt(l))&&(b=!0),l++}if(b){if(void 0===e.env.references)return!1;if(l<_&&91===e.src.charCodeAt(l)?(g=l+1,l=e.md.helpers.parseLinkLabel(e,l),l>=0?i=e.src.slice(g,l++):l=a+1):l=a+1,i||(i=e.src.slice(c,a)),!(p=e.env.references[n(i)]))return e.pos=m,!1;d=p.href,h=p.title}return r||(e.pos=c,e.posMax=a,f=e.push("link_open","a",1),f.attrs=t=[["href",d]],h&&t.push(["title",h]),e.md.inline.tokenize(e),f=e.push("link_close","a",-1)),e.pos=l,e.posMax=_,!0}},{"../common/utils":4}],46:[function(e,r,t){"use strict";var n=e("../common/utils").isSpace;r.exports=function(e,r){var t,s,o=e.pos;if(10!==e.src.charCodeAt(o))return!1;for(t=e.pending.length-1,s=e.posMax,r||(t>=0&&32===e.pending.charCodeAt(t)?t>=1&&32===e.pending.charCodeAt(t-1)?(e.pending=e.pending.replace(/ +$/,""),e.push("hardbreak","br",0)):(e.pending=e.pending.slice(0,-1),e.push("softbreak","br",0)):e.push("softbreak","br",0)),o++;o0&&this.level++,this.pendingLevel=this.level,this.tokens.push(n),n},n.prototype.scanDelims=function(e,r){var t,n,s,c,l,u,p,h,f,d=e,m=!0,_=!0,g=this.posMax,b=this.src.charCodeAt(e);for(t=e>0?this.src.charCodeAt(e-1):32;d=0&&(t=this.attrs[r][1]),t},n.prototype.attrJoin=function(e,r){var t=this.attrIndex(e);t<0?this.attrPush([e,r]):this.attrs[t][1]=this.attrs[t][1]+" "+r},r.exports=n},{}],52:[function(e,r,t){r.exports={Aacute:"\xc1",aacute:"\xe1",Abreve:"\u0102",abreve:"\u0103",ac:"\u223e",acd:"\u223f",acE:"\u223e\u0333",Acirc:"\xc2",acirc:"\xe2",acute:"\xb4",Acy:"\u0410",acy:"\u0430",AElig:"\xc6",aelig:"\xe6",af:"\u2061",Afr:"\ud835\udd04",afr:"\ud835\udd1e",Agrave:"\xc0",agrave:"\xe0",alefsym:"\u2135",aleph:"\u2135",Alpha:"\u0391",alpha:"\u03b1",Amacr:"\u0100",amacr:"\u0101",amalg:"\u2a3f",amp:"&",AMP:"&",andand:"\u2a55",And:"\u2a53",and:"\u2227",andd:"\u2a5c",andslope:"\u2a58",andv:"\u2a5a",ang:"\u2220",ange:"\u29a4",angle:"\u2220",angmsdaa:"\u29a8",angmsdab:"\u29a9",angmsdac:"\u29aa",angmsdad:"\u29ab",angmsdae:"\u29ac",angmsdaf:"\u29ad",angmsdag:"\u29ae",angmsdah:"\u29af",angmsd:"\u2221",angrt:"\u221f",angrtvb:"\u22be",angrtvbd:"\u299d",angsph:"\u2222",angst:"\xc5",angzarr:"\u237c",Aogon:"\u0104",aogon:"\u0105",Aopf:"\ud835\udd38",aopf:"\ud835\udd52",apacir:"\u2a6f",ap:"\u2248",apE:"\u2a70",ape:"\u224a",apid:"\u224b",apos:"'",ApplyFunction:"\u2061",approx:"\u2248",approxeq:"\u224a",Aring:"\xc5",aring:"\xe5",Ascr:"\ud835\udc9c",ascr:"\ud835\udcb6",Assign:"\u2254",ast:"*",asymp:"\u2248",asympeq:"\u224d",Atilde:"\xc3",atilde:"\xe3",Auml:"\xc4",auml:"\xe4",awconint:"\u2233",awint:"\u2a11",backcong:"\u224c",backepsilon:"\u03f6",backprime:"\u2035",backsim:"\u223d",backsimeq:"\u22cd",Backslash:"\u2216",Barv:"\u2ae7",barvee:"\u22bd",barwed:"\u2305",Barwed:"\u2306",barwedge:"\u2305",bbrk:"\u23b5",bbrktbrk:"\u23b6",bcong:"\u224c",Bcy:"\u0411",bcy:"\u0431",bdquo:"\u201e",becaus:"\u2235",because:"\u2235",Because:"\u2235",bemptyv:"\u29b0",bepsi:"\u03f6",bernou:"\u212c",Bernoullis:"\u212c",Beta:"\u0392",beta:"\u03b2",beth:"\u2136",between:"\u226c",Bfr:"\ud835\udd05",bfr:"\ud835\udd1f",bigcap:"\u22c2",bigcirc:"\u25ef",bigcup:"\u22c3",bigodot:"\u2a00",bigoplus:"\u2a01",bigotimes:"\u2a02",bigsqcup:"\u2a06",bigstar:"\u2605",bigtriangledown:"\u25bd",bigtriangleup:"\u25b3",biguplus:"\u2a04",bigvee:"\u22c1",bigwedge:"\u22c0",bkarow:"\u290d",blacklozenge:"\u29eb",blacksquare:"\u25aa",blacktriangle:"\u25b4",blacktriangledown:"\u25be",blacktriangleleft:"\u25c2",blacktriangleright:"\u25b8",blank:"\u2423",blk12:"\u2592",blk14:"\u2591",blk34:"\u2593",block:"\u2588",bne:"=\u20e5",bnequiv:"\u2261\u20e5",bNot:"\u2aed",bnot:"\u2310",Bopf:"\ud835\udd39",bopf:"\ud835\udd53",bot:"\u22a5",bottom:"\u22a5",bowtie:"\u22c8",boxbox:"\u29c9",boxdl:"\u2510",boxdL:"\u2555",boxDl:"\u2556",boxDL:"\u2557",boxdr:"\u250c",boxdR:"\u2552",boxDr:"\u2553",boxDR:"\u2554",boxh:"\u2500",boxH:"\u2550",boxhd:"\u252c",boxHd:"\u2564",boxhD:"\u2565",boxHD:"\u2566",boxhu:"\u2534",boxHu:"\u2567",boxhU:"\u2568",boxHU:"\u2569",boxminus:"\u229f",boxplus:"\u229e",boxtimes:"\u22a0",boxul:"\u2518",boxuL:"\u255b",boxUl:"\u255c",boxUL:"\u255d",boxur:"\u2514",boxuR:"\u2558",boxUr:"\u2559",boxUR:"\u255a",boxv:"\u2502",boxV:"\u2551",boxvh:"\u253c",boxvH:"\u256a",boxVh:"\u256b",boxVH:"\u256c",boxvl:"\u2524",boxvL:"\u2561",boxVl:"\u2562",boxVL:"\u2563",boxvr:"\u251c",boxvR:"\u255e",boxVr:"\u255f",boxVR:"\u2560",bprime:"\u2035",breve:"\u02d8",Breve:"\u02d8",brvbar:"\xa6",bscr:"\ud835\udcb7",Bscr:"\u212c",bsemi:"\u204f",bsim:"\u223d",bsime:"\u22cd",bsolb:"\u29c5",bsol:"\\",bsolhsub:"\u27c8",bull:"\u2022",bullet:"\u2022",bump:"\u224e",bumpE:"\u2aae",bumpe:"\u224f",Bumpeq:"\u224e",bumpeq:"\u224f",Cacute:"\u0106",cacute:"\u0107",capand:"\u2a44",capbrcup:"\u2a49",capcap:"\u2a4b",cap:"\u2229",Cap:"\u22d2",capcup:"\u2a47",capdot:"\u2a40",CapitalDifferentialD:"\u2145",caps:"\u2229\ufe00",caret:"\u2041",caron:"\u02c7",Cayleys:"\u212d",ccaps:"\u2a4d",Ccaron:"\u010c",ccaron:"\u010d",Ccedil:"\xc7",ccedil:"\xe7",Ccirc:"\u0108",ccirc:"\u0109",Cconint:"\u2230",ccups:"\u2a4c",ccupssm:"\u2a50",Cdot:"\u010a",cdot:"\u010b",cedil:"\xb8",Cedilla:"\xb8",cemptyv:"\u29b2",cent:"\xa2",centerdot:"\xb7",CenterDot:"\xb7",cfr:"\ud835\udd20",Cfr:"\u212d",CHcy:"\u0427",chcy:"\u0447",check:"\u2713",checkmark:"\u2713",Chi:"\u03a7",chi:"\u03c7",circ:"\u02c6",circeq:"\u2257",circlearrowleft:"\u21ba",circlearrowright:"\u21bb",circledast:"\u229b",circledcirc:"\u229a",circleddash:"\u229d",CircleDot:"\u2299",circledR:"\xae",circledS:"\u24c8",CircleMinus:"\u2296",CirclePlus:"\u2295",CircleTimes:"\u2297",cir:"\u25cb",cirE:"\u29c3",cire:"\u2257",cirfnint:"\u2a10",cirmid:"\u2aef",cirscir:"\u29c2",ClockwiseContourIntegral:"\u2232",CloseCurlyDoubleQuote:"\u201d",CloseCurlyQuote:"\u2019",clubs:"\u2663",clubsuit:"\u2663",colon:":",Colon:"\u2237",Colone:"\u2a74",colone:"\u2254",coloneq:"\u2254",comma:",",commat:"@",comp:"\u2201",compfn:"\u2218",complement:"\u2201",complexes:"\u2102",cong:"\u2245",congdot:"\u2a6d",Congruent:"\u2261",conint:"\u222e",Conint:"\u222f",ContourIntegral:"\u222e",copf:"\ud835\udd54",Copf:"\u2102",coprod:"\u2210",Coproduct:"\u2210",copy:"\xa9",COPY:"\xa9",copysr:"\u2117",CounterClockwiseContourIntegral:"\u2233",crarr:"\u21b5",cross:"\u2717",Cross:"\u2a2f",Cscr:"\ud835\udc9e",cscr:"\ud835\udcb8",csub:"\u2acf",csube:"\u2ad1",csup:"\u2ad0",csupe:"\u2ad2",ctdot:"\u22ef",cudarrl:"\u2938",cudarrr:"\u2935",cuepr:"\u22de",cuesc:"\u22df",cularr:"\u21b6",cularrp:"\u293d",cupbrcap:"\u2a48",cupcap:"\u2a46",CupCap:"\u224d",cup:"\u222a",Cup:"\u22d3",cupcup:"\u2a4a",cupdot:"\u228d",cupor:"\u2a45",cups:"\u222a\ufe00",curarr:"\u21b7",curarrm:"\u293c",curlyeqprec:"\u22de",curlyeqsucc:"\u22df",curlyvee:"\u22ce",curlywedge:"\u22cf",curren:"\xa4",curvearrowleft:"\u21b6",curvearrowright:"\u21b7",cuvee:"\u22ce",cuwed:"\u22cf",cwconint:"\u2232",cwint:"\u2231",cylcty:"\u232d",dagger:"\u2020",Dagger:"\u2021",daleth:"\u2138",darr:"\u2193",Darr:"\u21a1",dArr:"\u21d3",dash:"\u2010",Dashv:"\u2ae4",dashv:"\u22a3",dbkarow:"\u290f",dblac:"\u02dd",Dcaron:"\u010e",dcaron:"\u010f",Dcy:"\u0414",dcy:"\u0434",ddagger:"\u2021",ddarr:"\u21ca",DD:"\u2145",dd:"\u2146",DDotrahd:"\u2911",ddotseq:"\u2a77",deg:"\xb0",Del:"\u2207",Delta:"\u0394",delta:"\u03b4",demptyv:"\u29b1",dfisht:"\u297f",Dfr:"\ud835\udd07",dfr:"\ud835\udd21",dHar:"\u2965",dharl:"\u21c3",dharr:"\u21c2",DiacriticalAcute:"\xb4",DiacriticalDot:"\u02d9",DiacriticalDoubleAcute:"\u02dd",DiacriticalGrave:"`",DiacriticalTilde:"\u02dc",diam:"\u22c4",diamond:"\u22c4",Diamond:"\u22c4",diamondsuit:"\u2666",diams:"\u2666",die:"\xa8",DifferentialD:"\u2146",digamma:"\u03dd",disin:"\u22f2",div:"\xf7",divide:"\xf7",divideontimes:"\u22c7",divonx:"\u22c7",DJcy:"\u0402",djcy:"\u0452",dlcorn:"\u231e",dlcrop:"\u230d",dollar:"$",Dopf:"\ud835\udd3b",dopf:"\ud835\udd55",Dot:"\xa8",dot:"\u02d9",DotDot:"\u20dc",doteq:"\u2250",doteqdot:"\u2251",DotEqual:"\u2250",dotminus:"\u2238",dotplus:"\u2214",dotsquare:"\u22a1",doublebarwedge:"\u2306",DoubleContourIntegral:"\u222f",DoubleDot:"\xa8",DoubleDownArrow:"\u21d3",DoubleLeftArrow:"\u21d0",DoubleLeftRightArrow:"\u21d4",DoubleLeftTee:"\u2ae4",DoubleLongLeftArrow:"\u27f8",DoubleLongLeftRightArrow:"\u27fa",DoubleLongRightArrow:"\u27f9",DoubleRightArrow:"\u21d2",DoubleRightTee:"\u22a8",DoubleUpArrow:"\u21d1",DoubleUpDownArrow:"\u21d5",DoubleVerticalBar:"\u2225",DownArrowBar:"\u2913",downarrow:"\u2193",DownArrow:"\u2193",Downarrow:"\u21d3",DownArrowUpArrow:"\u21f5",DownBreve:"\u0311",downdownarrows:"\u21ca",downharpoonleft:"\u21c3",downharpoonright:"\u21c2",DownLeftRightVector:"\u2950",DownLeftTeeVector:"\u295e",DownLeftVectorBar:"\u2956",DownLeftVector:"\u21bd",DownRightTeeVector:"\u295f",DownRightVectorBar:"\u2957",DownRightVector:"\u21c1",DownTeeArrow:"\u21a7",DownTee:"\u22a4",drbkarow:"\u2910",drcorn:"\u231f",drcrop:"\u230c",Dscr:"\ud835\udc9f",dscr:"\ud835\udcb9",DScy:"\u0405",dscy:"\u0455",dsol:"\u29f6",Dstrok:"\u0110",dstrok:"\u0111",dtdot:"\u22f1",dtri:"\u25bf",dtrif:"\u25be",duarr:"\u21f5",duhar:"\u296f",dwangle:"\u29a6",DZcy:"\u040f",dzcy:"\u045f",dzigrarr:"\u27ff",Eacute:"\xc9",eacute:"\xe9",easter:"\u2a6e",Ecaron:"\u011a",ecaron:"\u011b",Ecirc:"\xca",ecirc:"\xea",ecir:"\u2256",ecolon:"\u2255",Ecy:"\u042d",ecy:"\u044d",eDDot:"\u2a77",Edot:"\u0116",edot:"\u0117",eDot:"\u2251",ee:"\u2147",efDot:"\u2252",Efr:"\ud835\udd08",efr:"\ud835\udd22",eg:"\u2a9a",Egrave:"\xc8",egrave:"\xe8",egs:"\u2a96",egsdot:"\u2a98",el:"\u2a99",Element:"\u2208",elinters:"\u23e7",ell:"\u2113",els:"\u2a95",elsdot:"\u2a97",Emacr:"\u0112",emacr:"\u0113",empty:"\u2205",emptyset:"\u2205",EmptySmallSquare:"\u25fb",emptyv:"\u2205",EmptyVerySmallSquare:"\u25ab",emsp13:"\u2004",emsp14:"\u2005",emsp:"\u2003",ENG:"\u014a",eng:"\u014b",ensp:"\u2002",Eogon:"\u0118",eogon:"\u0119",Eopf:"\ud835\udd3c",eopf:"\ud835\udd56",epar:"\u22d5",eparsl:"\u29e3",eplus:"\u2a71",epsi:"\u03b5",Epsilon:"\u0395",epsilon:"\u03b5",epsiv:"\u03f5",eqcirc:"\u2256",eqcolon:"\u2255",eqsim:"\u2242",eqslantgtr:"\u2a96",eqslantless:"\u2a95",Equal:"\u2a75",equals:"=",EqualTilde:"\u2242",equest:"\u225f",Equilibrium:"\u21cc",equiv:"\u2261",equivDD:"\u2a78",eqvparsl:"\u29e5",erarr:"\u2971",erDot:"\u2253",escr:"\u212f",Escr:"\u2130",esdot:"\u2250",Esim:"\u2a73",esim:"\u2242",Eta:"\u0397",eta:"\u03b7",ETH:"\xd0",eth:"\xf0",Euml:"\xcb",euml:"\xeb",euro:"\u20ac",excl:"!",exist:"\u2203",Exists:"\u2203",expectation:"\u2130",exponentiale:"\u2147",ExponentialE:"\u2147",fallingdotseq:"\u2252",Fcy:"\u0424",fcy:"\u0444",female:"\u2640",ffilig:"\ufb03",fflig:"\ufb00",ffllig:"\ufb04",Ffr:"\ud835\udd09",ffr:"\ud835\udd23",filig:"\ufb01",FilledSmallSquare:"\u25fc",FilledVerySmallSquare:"\u25aa",fjlig:"fj",flat:"\u266d",fllig:"\ufb02",fltns:"\u25b1",fnof:"\u0192",Fopf:"\ud835\udd3d",fopf:"\ud835\udd57",forall:"\u2200",ForAll:"\u2200",fork:"\u22d4",forkv:"\u2ad9",Fouriertrf:"\u2131",fpartint:"\u2a0d",frac12:"\xbd",frac13:"\u2153",frac14:"\xbc",frac15:"\u2155",frac16:"\u2159",frac18:"\u215b",frac23:"\u2154",frac25:"\u2156",frac34:"\xbe",frac35:"\u2157",frac38:"\u215c",frac45:"\u2158",frac56:"\u215a",frac58:"\u215d",frac78:"\u215e",frasl:"\u2044",frown:"\u2322",fscr:"\ud835\udcbb",Fscr:"\u2131",gacute:"\u01f5",Gamma:"\u0393",gamma:"\u03b3",Gammad:"\u03dc",gammad:"\u03dd",gap:"\u2a86",Gbreve:"\u011e",gbreve:"\u011f",Gcedil:"\u0122",Gcirc:"\u011c",gcirc:"\u011d",Gcy:"\u0413",gcy:"\u0433",Gdot:"\u0120",gdot:"\u0121",ge:"\u2265",gE:"\u2267",gEl:"\u2a8c",gel:"\u22db",geq:"\u2265",geqq:"\u2267",geqslant:"\u2a7e",gescc:"\u2aa9",ges:"\u2a7e",gesdot:"\u2a80",gesdoto:"\u2a82",gesdotol:"\u2a84",gesl:"\u22db\ufe00",gesles:"\u2a94",Gfr:"\ud835\udd0a",gfr:"\ud835\udd24",gg:"\u226b",Gg:"\u22d9",ggg:"\u22d9",gimel:"\u2137",GJcy:"\u0403",gjcy:"\u0453",gla:"\u2aa5",gl:"\u2277",glE:"\u2a92",glj:"\u2aa4",gnap:"\u2a8a",gnapprox:"\u2a8a",gne:"\u2a88",gnE:"\u2269",gneq:"\u2a88",gneqq:"\u2269",gnsim:"\u22e7",Gopf:"\ud835\udd3e",gopf:"\ud835\udd58",grave:"`",GreaterEqual:"\u2265",GreaterEqualLess:"\u22db",GreaterFullEqual:"\u2267",GreaterGreater:"\u2aa2",GreaterLess:"\u2277",GreaterSlantEqual:"\u2a7e",GreaterTilde:"\u2273",Gscr:"\ud835\udca2",gscr:"\u210a",gsim:"\u2273",gsime:"\u2a8e",gsiml:"\u2a90",gtcc:"\u2aa7",gtcir:"\u2a7a",gt:">",GT:">",Gt:"\u226b",gtdot:"\u22d7",gtlPar:"\u2995",gtquest:"\u2a7c",gtrapprox:"\u2a86",gtrarr:"\u2978",gtrdot:"\u22d7",gtreqless:"\u22db",gtreqqless:"\u2a8c",gtrless:"\u2277",gtrsim:"\u2273",gvertneqq:"\u2269\ufe00",gvnE:"\u2269\ufe00",Hacek:"\u02c7",hairsp:"\u200a",half:"\xbd",hamilt:"\u210b",HARDcy:"\u042a",hardcy:"\u044a",harrcir:"\u2948",harr:"\u2194",hArr:"\u21d4",harrw:"\u21ad",Hat:"^",hbar:"\u210f",Hcirc:"\u0124",hcirc:"\u0125",hearts:"\u2665",heartsuit:"\u2665",hellip:"\u2026",hercon:"\u22b9",hfr:"\ud835\udd25",Hfr:"\u210c",HilbertSpace:"\u210b",hksearow:"\u2925",hkswarow:"\u2926",hoarr:"\u21ff",homtht:"\u223b",hookleftarrow:"\u21a9",hookrightarrow:"\u21aa",hopf:"\ud835\udd59",Hopf:"\u210d",horbar:"\u2015",HorizontalLine:"\u2500",hscr:"\ud835\udcbd",Hscr:"\u210b",hslash:"\u210f",Hstrok:"\u0126",hstrok:"\u0127",HumpDownHump:"\u224e",HumpEqual:"\u224f",hybull:"\u2043",hyphen:"\u2010",Iacute:"\xcd",iacute:"\xed",ic:"\u2063",Icirc:"\xce",icirc:"\xee",Icy:"\u0418",icy:"\u0438",Idot:"\u0130",IEcy:"\u0415",iecy:"\u0435",iexcl:"\xa1",iff:"\u21d4",ifr:"\ud835\udd26",Ifr:"\u2111",Igrave:"\xcc",igrave:"\xec",ii:"\u2148",iiiint:"\u2a0c",iiint:"\u222d",iinfin:"\u29dc",iiota:"\u2129",IJlig:"\u0132",ijlig:"\u0133",Imacr:"\u012a",imacr:"\u012b",image:"\u2111",ImaginaryI:"\u2148",imagline:"\u2110",imagpart:"\u2111",imath:"\u0131",Im:"\u2111",imof:"\u22b7",imped:"\u01b5",Implies:"\u21d2",incare:"\u2105",in:"\u2208",infin:"\u221e",infintie:"\u29dd",inodot:"\u0131",intcal:"\u22ba",int:"\u222b",Int:"\u222c",integers:"\u2124",Integral:"\u222b",intercal:"\u22ba",Intersection:"\u22c2",intlarhk:"\u2a17",intprod:"\u2a3c",InvisibleComma:"\u2063",InvisibleTimes:"\u2062",IOcy:"\u0401",iocy:"\u0451",Iogon:"\u012e",iogon:"\u012f",Iopf:"\ud835\udd40",iopf:"\ud835\udd5a",Iota:"\u0399",iota:"\u03b9",iprod:"\u2a3c",iquest:"\xbf",iscr:"\ud835\udcbe",Iscr:"\u2110",isin:"\u2208",isindot:"\u22f5",isinE:"\u22f9",isins:"\u22f4",isinsv:"\u22f3",isinv:"\u2208",it:"\u2062",Itilde:"\u0128",itilde:"\u0129",Iukcy:"\u0406",iukcy:"\u0456",Iuml:"\xcf",iuml:"\xef",Jcirc:"\u0134",jcirc:"\u0135",Jcy:"\u0419",jcy:"\u0439",Jfr:"\ud835\udd0d",jfr:"\ud835\udd27",jmath:"\u0237",Jopf:"\ud835\udd41", -jopf:"\ud835\udd5b",Jscr:"\ud835\udca5",jscr:"\ud835\udcbf",Jsercy:"\u0408",jsercy:"\u0458",Jukcy:"\u0404",jukcy:"\u0454",Kappa:"\u039a",kappa:"\u03ba",kappav:"\u03f0",Kcedil:"\u0136",kcedil:"\u0137",Kcy:"\u041a",kcy:"\u043a",Kfr:"\ud835\udd0e",kfr:"\ud835\udd28",kgreen:"\u0138",KHcy:"\u0425",khcy:"\u0445",KJcy:"\u040c",kjcy:"\u045c",Kopf:"\ud835\udd42",kopf:"\ud835\udd5c",Kscr:"\ud835\udca6",kscr:"\ud835\udcc0",lAarr:"\u21da",Lacute:"\u0139",lacute:"\u013a",laemptyv:"\u29b4",lagran:"\u2112",Lambda:"\u039b",lambda:"\u03bb",lang:"\u27e8",Lang:"\u27ea",langd:"\u2991",langle:"\u27e8",lap:"\u2a85",Laplacetrf:"\u2112",laquo:"\xab",larrb:"\u21e4",larrbfs:"\u291f",larr:"\u2190",Larr:"\u219e",lArr:"\u21d0",larrfs:"\u291d",larrhk:"\u21a9",larrlp:"\u21ab",larrpl:"\u2939",larrsim:"\u2973",larrtl:"\u21a2",latail:"\u2919",lAtail:"\u291b",lat:"\u2aab",late:"\u2aad",lates:"\u2aad\ufe00",lbarr:"\u290c",lBarr:"\u290e",lbbrk:"\u2772",lbrace:"{",lbrack:"[",lbrke:"\u298b",lbrksld:"\u298f",lbrkslu:"\u298d",Lcaron:"\u013d",lcaron:"\u013e",Lcedil:"\u013b",lcedil:"\u013c",lceil:"\u2308",lcub:"{",Lcy:"\u041b",lcy:"\u043b",ldca:"\u2936",ldquo:"\u201c",ldquor:"\u201e",ldrdhar:"\u2967",ldrushar:"\u294b",ldsh:"\u21b2",le:"\u2264",lE:"\u2266",LeftAngleBracket:"\u27e8",LeftArrowBar:"\u21e4",leftarrow:"\u2190",LeftArrow:"\u2190",Leftarrow:"\u21d0",LeftArrowRightArrow:"\u21c6",leftarrowtail:"\u21a2",LeftCeiling:"\u2308",LeftDoubleBracket:"\u27e6",LeftDownTeeVector:"\u2961",LeftDownVectorBar:"\u2959",LeftDownVector:"\u21c3",LeftFloor:"\u230a",leftharpoondown:"\u21bd",leftharpoonup:"\u21bc",leftleftarrows:"\u21c7",leftrightarrow:"\u2194",LeftRightArrow:"\u2194",Leftrightarrow:"\u21d4",leftrightarrows:"\u21c6",leftrightharpoons:"\u21cb",leftrightsquigarrow:"\u21ad",LeftRightVector:"\u294e",LeftTeeArrow:"\u21a4",LeftTee:"\u22a3",LeftTeeVector:"\u295a",leftthreetimes:"\u22cb",LeftTriangleBar:"\u29cf",LeftTriangle:"\u22b2",LeftTriangleEqual:"\u22b4",LeftUpDownVector:"\u2951",LeftUpTeeVector:"\u2960",LeftUpVectorBar:"\u2958",LeftUpVector:"\u21bf",LeftVectorBar:"\u2952",LeftVector:"\u21bc",lEg:"\u2a8b",leg:"\u22da",leq:"\u2264",leqq:"\u2266",leqslant:"\u2a7d",lescc:"\u2aa8",les:"\u2a7d",lesdot:"\u2a7f",lesdoto:"\u2a81",lesdotor:"\u2a83",lesg:"\u22da\ufe00",lesges:"\u2a93",lessapprox:"\u2a85",lessdot:"\u22d6",lesseqgtr:"\u22da",lesseqqgtr:"\u2a8b",LessEqualGreater:"\u22da",LessFullEqual:"\u2266",LessGreater:"\u2276",lessgtr:"\u2276",LessLess:"\u2aa1",lesssim:"\u2272",LessSlantEqual:"\u2a7d",LessTilde:"\u2272",lfisht:"\u297c",lfloor:"\u230a",Lfr:"\ud835\udd0f",lfr:"\ud835\udd29",lg:"\u2276",lgE:"\u2a91",lHar:"\u2962",lhard:"\u21bd",lharu:"\u21bc",lharul:"\u296a",lhblk:"\u2584",LJcy:"\u0409",ljcy:"\u0459",llarr:"\u21c7",ll:"\u226a",Ll:"\u22d8",llcorner:"\u231e",Lleftarrow:"\u21da",llhard:"\u296b",lltri:"\u25fa",Lmidot:"\u013f",lmidot:"\u0140",lmoustache:"\u23b0",lmoust:"\u23b0",lnap:"\u2a89",lnapprox:"\u2a89",lne:"\u2a87",lnE:"\u2268",lneq:"\u2a87",lneqq:"\u2268",lnsim:"\u22e6",loang:"\u27ec",loarr:"\u21fd",lobrk:"\u27e6",longleftarrow:"\u27f5",LongLeftArrow:"\u27f5",Longleftarrow:"\u27f8",longleftrightarrow:"\u27f7",LongLeftRightArrow:"\u27f7",Longleftrightarrow:"\u27fa",longmapsto:"\u27fc",longrightarrow:"\u27f6",LongRightArrow:"\u27f6",Longrightarrow:"\u27f9",looparrowleft:"\u21ab",looparrowright:"\u21ac",lopar:"\u2985",Lopf:"\ud835\udd43",lopf:"\ud835\udd5d",loplus:"\u2a2d",lotimes:"\u2a34",lowast:"\u2217",lowbar:"_",LowerLeftArrow:"\u2199",LowerRightArrow:"\u2198",loz:"\u25ca",lozenge:"\u25ca",lozf:"\u29eb",lpar:"(",lparlt:"\u2993",lrarr:"\u21c6",lrcorner:"\u231f",lrhar:"\u21cb",lrhard:"\u296d",lrm:"\u200e",lrtri:"\u22bf",lsaquo:"\u2039",lscr:"\ud835\udcc1",Lscr:"\u2112",lsh:"\u21b0",Lsh:"\u21b0",lsim:"\u2272",lsime:"\u2a8d",lsimg:"\u2a8f",lsqb:"[",lsquo:"\u2018",lsquor:"\u201a",Lstrok:"\u0141",lstrok:"\u0142",ltcc:"\u2aa6",ltcir:"\u2a79",lt:"<",LT:"<",Lt:"\u226a",ltdot:"\u22d6",lthree:"\u22cb",ltimes:"\u22c9",ltlarr:"\u2976",ltquest:"\u2a7b",ltri:"\u25c3",ltrie:"\u22b4",ltrif:"\u25c2",ltrPar:"\u2996",lurdshar:"\u294a",luruhar:"\u2966",lvertneqq:"\u2268\ufe00",lvnE:"\u2268\ufe00",macr:"\xaf",male:"\u2642",malt:"\u2720",maltese:"\u2720",Map:"\u2905",map:"\u21a6",mapsto:"\u21a6",mapstodown:"\u21a7",mapstoleft:"\u21a4",mapstoup:"\u21a5",marker:"\u25ae",mcomma:"\u2a29",Mcy:"\u041c",mcy:"\u043c",mdash:"\u2014",mDDot:"\u223a",measuredangle:"\u2221",MediumSpace:"\u205f",Mellintrf:"\u2133",Mfr:"\ud835\udd10",mfr:"\ud835\udd2a",mho:"\u2127",micro:"\xb5",midast:"*",midcir:"\u2af0",mid:"\u2223",middot:"\xb7",minusb:"\u229f",minus:"\u2212",minusd:"\u2238",minusdu:"\u2a2a",MinusPlus:"\u2213",mlcp:"\u2adb",mldr:"\u2026",mnplus:"\u2213",models:"\u22a7",Mopf:"\ud835\udd44",mopf:"\ud835\udd5e",mp:"\u2213",mscr:"\ud835\udcc2",Mscr:"\u2133",mstpos:"\u223e",Mu:"\u039c",mu:"\u03bc",multimap:"\u22b8",mumap:"\u22b8",nabla:"\u2207",Nacute:"\u0143",nacute:"\u0144",nang:"\u2220\u20d2",nap:"\u2249",napE:"\u2a70\u0338",napid:"\u224b\u0338",napos:"\u0149",napprox:"\u2249",natural:"\u266e",naturals:"\u2115",natur:"\u266e",nbsp:"\xa0",nbump:"\u224e\u0338",nbumpe:"\u224f\u0338",ncap:"\u2a43",Ncaron:"\u0147",ncaron:"\u0148",Ncedil:"\u0145",ncedil:"\u0146",ncong:"\u2247",ncongdot:"\u2a6d\u0338",ncup:"\u2a42",Ncy:"\u041d",ncy:"\u043d",ndash:"\u2013",nearhk:"\u2924",nearr:"\u2197",neArr:"\u21d7",nearrow:"\u2197",ne:"\u2260",nedot:"\u2250\u0338",NegativeMediumSpace:"\u200b",NegativeThickSpace:"\u200b",NegativeThinSpace:"\u200b",NegativeVeryThinSpace:"\u200b",nequiv:"\u2262",nesear:"\u2928",nesim:"\u2242\u0338",NestedGreaterGreater:"\u226b",NestedLessLess:"\u226a",NewLine:"\n",nexist:"\u2204",nexists:"\u2204",Nfr:"\ud835\udd11",nfr:"\ud835\udd2b",ngE:"\u2267\u0338",nge:"\u2271",ngeq:"\u2271",ngeqq:"\u2267\u0338",ngeqslant:"\u2a7e\u0338",nges:"\u2a7e\u0338",nGg:"\u22d9\u0338",ngsim:"\u2275",nGt:"\u226b\u20d2",ngt:"\u226f",ngtr:"\u226f",nGtv:"\u226b\u0338",nharr:"\u21ae",nhArr:"\u21ce",nhpar:"\u2af2",ni:"\u220b",nis:"\u22fc",nisd:"\u22fa",niv:"\u220b",NJcy:"\u040a",njcy:"\u045a",nlarr:"\u219a",nlArr:"\u21cd",nldr:"\u2025",nlE:"\u2266\u0338",nle:"\u2270",nleftarrow:"\u219a",nLeftarrow:"\u21cd",nleftrightarrow:"\u21ae",nLeftrightarrow:"\u21ce",nleq:"\u2270",nleqq:"\u2266\u0338",nleqslant:"\u2a7d\u0338",nles:"\u2a7d\u0338",nless:"\u226e",nLl:"\u22d8\u0338",nlsim:"\u2274",nLt:"\u226a\u20d2",nlt:"\u226e",nltri:"\u22ea",nltrie:"\u22ec",nLtv:"\u226a\u0338",nmid:"\u2224",NoBreak:"\u2060",NonBreakingSpace:"\xa0",nopf:"\ud835\udd5f",Nopf:"\u2115",Not:"\u2aec",not:"\xac",NotCongruent:"\u2262",NotCupCap:"\u226d",NotDoubleVerticalBar:"\u2226",NotElement:"\u2209",NotEqual:"\u2260",NotEqualTilde:"\u2242\u0338",NotExists:"\u2204",NotGreater:"\u226f",NotGreaterEqual:"\u2271",NotGreaterFullEqual:"\u2267\u0338",NotGreaterGreater:"\u226b\u0338",NotGreaterLess:"\u2279",NotGreaterSlantEqual:"\u2a7e\u0338",NotGreaterTilde:"\u2275",NotHumpDownHump:"\u224e\u0338",NotHumpEqual:"\u224f\u0338",notin:"\u2209",notindot:"\u22f5\u0338",notinE:"\u22f9\u0338",notinva:"\u2209",notinvb:"\u22f7",notinvc:"\u22f6",NotLeftTriangleBar:"\u29cf\u0338",NotLeftTriangle:"\u22ea",NotLeftTriangleEqual:"\u22ec",NotLess:"\u226e",NotLessEqual:"\u2270",NotLessGreater:"\u2278",NotLessLess:"\u226a\u0338",NotLessSlantEqual:"\u2a7d\u0338",NotLessTilde:"\u2274",NotNestedGreaterGreater:"\u2aa2\u0338",NotNestedLessLess:"\u2aa1\u0338",notni:"\u220c",notniva:"\u220c",notnivb:"\u22fe",notnivc:"\u22fd",NotPrecedes:"\u2280",NotPrecedesEqual:"\u2aaf\u0338",NotPrecedesSlantEqual:"\u22e0",NotReverseElement:"\u220c",NotRightTriangleBar:"\u29d0\u0338",NotRightTriangle:"\u22eb",NotRightTriangleEqual:"\u22ed",NotSquareSubset:"\u228f\u0338",NotSquareSubsetEqual:"\u22e2",NotSquareSuperset:"\u2290\u0338",NotSquareSupersetEqual:"\u22e3",NotSubset:"\u2282\u20d2",NotSubsetEqual:"\u2288",NotSucceeds:"\u2281",NotSucceedsEqual:"\u2ab0\u0338",NotSucceedsSlantEqual:"\u22e1",NotSucceedsTilde:"\u227f\u0338",NotSuperset:"\u2283\u20d2",NotSupersetEqual:"\u2289",NotTilde:"\u2241",NotTildeEqual:"\u2244",NotTildeFullEqual:"\u2247",NotTildeTilde:"\u2249",NotVerticalBar:"\u2224",nparallel:"\u2226",npar:"\u2226",nparsl:"\u2afd\u20e5",npart:"\u2202\u0338",npolint:"\u2a14",npr:"\u2280",nprcue:"\u22e0",nprec:"\u2280",npreceq:"\u2aaf\u0338",npre:"\u2aaf\u0338",nrarrc:"\u2933\u0338",nrarr:"\u219b",nrArr:"\u21cf",nrarrw:"\u219d\u0338",nrightarrow:"\u219b",nRightarrow:"\u21cf",nrtri:"\u22eb",nrtrie:"\u22ed",nsc:"\u2281",nsccue:"\u22e1",nsce:"\u2ab0\u0338",Nscr:"\ud835\udca9",nscr:"\ud835\udcc3",nshortmid:"\u2224",nshortparallel:"\u2226",nsim:"\u2241",nsime:"\u2244",nsimeq:"\u2244",nsmid:"\u2224",nspar:"\u2226",nsqsube:"\u22e2",nsqsupe:"\u22e3",nsub:"\u2284",nsubE:"\u2ac5\u0338",nsube:"\u2288",nsubset:"\u2282\u20d2",nsubseteq:"\u2288",nsubseteqq:"\u2ac5\u0338",nsucc:"\u2281",nsucceq:"\u2ab0\u0338",nsup:"\u2285",nsupE:"\u2ac6\u0338",nsupe:"\u2289",nsupset:"\u2283\u20d2",nsupseteq:"\u2289",nsupseteqq:"\u2ac6\u0338",ntgl:"\u2279",Ntilde:"\xd1",ntilde:"\xf1",ntlg:"\u2278",ntriangleleft:"\u22ea",ntrianglelefteq:"\u22ec",ntriangleright:"\u22eb",ntrianglerighteq:"\u22ed",Nu:"\u039d",nu:"\u03bd",num:"#",numero:"\u2116",numsp:"\u2007",nvap:"\u224d\u20d2",nvdash:"\u22ac",nvDash:"\u22ad",nVdash:"\u22ae",nVDash:"\u22af",nvge:"\u2265\u20d2",nvgt:">\u20d2",nvHarr:"\u2904",nvinfin:"\u29de",nvlArr:"\u2902",nvle:"\u2264\u20d2",nvlt:"<\u20d2",nvltrie:"\u22b4\u20d2",nvrArr:"\u2903",nvrtrie:"\u22b5\u20d2",nvsim:"\u223c\u20d2",nwarhk:"\u2923",nwarr:"\u2196",nwArr:"\u21d6",nwarrow:"\u2196",nwnear:"\u2927",Oacute:"\xd3",oacute:"\xf3",oast:"\u229b",Ocirc:"\xd4",ocirc:"\xf4",ocir:"\u229a",Ocy:"\u041e",ocy:"\u043e",odash:"\u229d",Odblac:"\u0150",odblac:"\u0151",odiv:"\u2a38",odot:"\u2299",odsold:"\u29bc",OElig:"\u0152",oelig:"\u0153",ofcir:"\u29bf",Ofr:"\ud835\udd12",ofr:"\ud835\udd2c",ogon:"\u02db",Ograve:"\xd2",ograve:"\xf2",ogt:"\u29c1",ohbar:"\u29b5",ohm:"\u03a9",oint:"\u222e",olarr:"\u21ba",olcir:"\u29be",olcross:"\u29bb",oline:"\u203e",olt:"\u29c0",Omacr:"\u014c",omacr:"\u014d",Omega:"\u03a9",omega:"\u03c9",Omicron:"\u039f",omicron:"\u03bf",omid:"\u29b6",ominus:"\u2296",Oopf:"\ud835\udd46",oopf:"\ud835\udd60",opar:"\u29b7",OpenCurlyDoubleQuote:"\u201c",OpenCurlyQuote:"\u2018",operp:"\u29b9",oplus:"\u2295",orarr:"\u21bb",Or:"\u2a54",or:"\u2228",ord:"\u2a5d",order:"\u2134",orderof:"\u2134",ordf:"\xaa",ordm:"\xba",origof:"\u22b6",oror:"\u2a56",orslope:"\u2a57",orv:"\u2a5b",oS:"\u24c8",Oscr:"\ud835\udcaa",oscr:"\u2134",Oslash:"\xd8",oslash:"\xf8",osol:"\u2298",Otilde:"\xd5",otilde:"\xf5",otimesas:"\u2a36",Otimes:"\u2a37",otimes:"\u2297",Ouml:"\xd6",ouml:"\xf6",ovbar:"\u233d",OverBar:"\u203e",OverBrace:"\u23de",OverBracket:"\u23b4",OverParenthesis:"\u23dc",para:"\xb6",parallel:"\u2225",par:"\u2225",parsim:"\u2af3",parsl:"\u2afd",part:"\u2202",PartialD:"\u2202",Pcy:"\u041f",pcy:"\u043f",percnt:"%",period:".",permil:"\u2030",perp:"\u22a5",pertenk:"\u2031",Pfr:"\ud835\udd13",pfr:"\ud835\udd2d",Phi:"\u03a6",phi:"\u03c6",phiv:"\u03d5",phmmat:"\u2133",phone:"\u260e",Pi:"\u03a0",pi:"\u03c0",pitchfork:"\u22d4",piv:"\u03d6",planck:"\u210f",planckh:"\u210e",plankv:"\u210f",plusacir:"\u2a23",plusb:"\u229e",pluscir:"\u2a22",plus:"+",plusdo:"\u2214",plusdu:"\u2a25",pluse:"\u2a72",PlusMinus:"\xb1",plusmn:"\xb1",plussim:"\u2a26",plustwo:"\u2a27",pm:"\xb1",Poincareplane:"\u210c",pointint:"\u2a15",popf:"\ud835\udd61",Popf:"\u2119",pound:"\xa3",prap:"\u2ab7",Pr:"\u2abb",pr:"\u227a",prcue:"\u227c",precapprox:"\u2ab7",prec:"\u227a",preccurlyeq:"\u227c",Precedes:"\u227a",PrecedesEqual:"\u2aaf",PrecedesSlantEqual:"\u227c",PrecedesTilde:"\u227e",preceq:"\u2aaf",precnapprox:"\u2ab9",precneqq:"\u2ab5",precnsim:"\u22e8",pre:"\u2aaf",prE:"\u2ab3",precsim:"\u227e",prime:"\u2032",Prime:"\u2033",primes:"\u2119",prnap:"\u2ab9",prnE:"\u2ab5",prnsim:"\u22e8",prod:"\u220f",Product:"\u220f",profalar:"\u232e",profline:"\u2312",profsurf:"\u2313",prop:"\u221d",Proportional:"\u221d",Proportion:"\u2237",propto:"\u221d",prsim:"\u227e",prurel:"\u22b0",Pscr:"\ud835\udcab",pscr:"\ud835\udcc5",Psi:"\u03a8",psi:"\u03c8",puncsp:"\u2008",Qfr:"\ud835\udd14",qfr:"\ud835\udd2e",qint:"\u2a0c",qopf:"\ud835\udd62",Qopf:"\u211a",qprime:"\u2057",Qscr:"\ud835\udcac",qscr:"\ud835\udcc6",quaternions:"\u210d",quatint:"\u2a16",quest:"?",questeq:"\u225f",quot:'"',QUOT:'"',rAarr:"\u21db",race:"\u223d\u0331",Racute:"\u0154",racute:"\u0155",radic:"\u221a",raemptyv:"\u29b3",rang:"\u27e9",Rang:"\u27eb",rangd:"\u2992",range:"\u29a5",rangle:"\u27e9",raquo:"\xbb",rarrap:"\u2975",rarrb:"\u21e5",rarrbfs:"\u2920",rarrc:"\u2933",rarr:"\u2192",Rarr:"\u21a0",rArr:"\u21d2",rarrfs:"\u291e",rarrhk:"\u21aa",rarrlp:"\u21ac",rarrpl:"\u2945",rarrsim:"\u2974",Rarrtl:"\u2916",rarrtl:"\u21a3",rarrw:"\u219d",ratail:"\u291a",rAtail:"\u291c",ratio:"\u2236",rationals:"\u211a",rbarr:"\u290d",rBarr:"\u290f",RBarr:"\u2910",rbbrk:"\u2773",rbrace:"}",rbrack:"]",rbrke:"\u298c",rbrksld:"\u298e",rbrkslu:"\u2990",Rcaron:"\u0158",rcaron:"\u0159",Rcedil:"\u0156",rcedil:"\u0157",rceil:"\u2309",rcub:"}",Rcy:"\u0420",rcy:"\u0440",rdca:"\u2937",rdldhar:"\u2969",rdquo:"\u201d",rdquor:"\u201d",rdsh:"\u21b3",real:"\u211c",realine:"\u211b",realpart:"\u211c",reals:"\u211d",Re:"\u211c",rect:"\u25ad",reg:"\xae",REG:"\xae",ReverseElement:"\u220b",ReverseEquilibrium:"\u21cb",ReverseUpEquilibrium:"\u296f",rfisht:"\u297d",rfloor:"\u230b",rfr:"\ud835\udd2f",Rfr:"\u211c",rHar:"\u2964",rhard:"\u21c1",rharu:"\u21c0",rharul:"\u296c",Rho:"\u03a1",rho:"\u03c1",rhov:"\u03f1",RightAngleBracket:"\u27e9",RightArrowBar:"\u21e5",rightarrow:"\u2192",RightArrow:"\u2192",Rightarrow:"\u21d2",RightArrowLeftArrow:"\u21c4",rightarrowtail:"\u21a3",RightCeiling:"\u2309",RightDoubleBracket:"\u27e7",RightDownTeeVector:"\u295d",RightDownVectorBar:"\u2955",RightDownVector:"\u21c2",RightFloor:"\u230b",rightharpoondown:"\u21c1",rightharpoonup:"\u21c0",rightleftarrows:"\u21c4",rightleftharpoons:"\u21cc",rightrightarrows:"\u21c9",rightsquigarrow:"\u219d",RightTeeArrow:"\u21a6",RightTee:"\u22a2",RightTeeVector:"\u295b",rightthreetimes:"\u22cc",RightTriangleBar:"\u29d0",RightTriangle:"\u22b3",RightTriangleEqual:"\u22b5",RightUpDownVector:"\u294f",RightUpTeeVector:"\u295c",RightUpVectorBar:"\u2954",RightUpVector:"\u21be",RightVectorBar:"\u2953",RightVector:"\u21c0",ring:"\u02da",risingdotseq:"\u2253",rlarr:"\u21c4",rlhar:"\u21cc",rlm:"\u200f",rmoustache:"\u23b1",rmoust:"\u23b1",rnmid:"\u2aee",roang:"\u27ed",roarr:"\u21fe",robrk:"\u27e7",ropar:"\u2986",ropf:"\ud835\udd63",Ropf:"\u211d",roplus:"\u2a2e",rotimes:"\u2a35",RoundImplies:"\u2970",rpar:")",rpargt:"\u2994",rppolint:"\u2a12",rrarr:"\u21c9",Rrightarrow:"\u21db",rsaquo:"\u203a",rscr:"\ud835\udcc7",Rscr:"\u211b",rsh:"\u21b1",Rsh:"\u21b1",rsqb:"]",rsquo:"\u2019",rsquor:"\u2019",rthree:"\u22cc",rtimes:"\u22ca",rtri:"\u25b9",rtrie:"\u22b5",rtrif:"\u25b8",rtriltri:"\u29ce",RuleDelayed:"\u29f4",ruluhar:"\u2968",rx:"\u211e",Sacute:"\u015a",sacute:"\u015b",sbquo:"\u201a",scap:"\u2ab8",Scaron:"\u0160",scaron:"\u0161",Sc:"\u2abc",sc:"\u227b",sccue:"\u227d",sce:"\u2ab0",scE:"\u2ab4",Scedil:"\u015e",scedil:"\u015f",Scirc:"\u015c",scirc:"\u015d",scnap:"\u2aba",scnE:"\u2ab6",scnsim:"\u22e9",scpolint:"\u2a13",scsim:"\u227f",Scy:"\u0421",scy:"\u0441",sdotb:"\u22a1",sdot:"\u22c5",sdote:"\u2a66",searhk:"\u2925",searr:"\u2198",seArr:"\u21d8",searrow:"\u2198",sect:"\xa7",semi:";",seswar:"\u2929",setminus:"\u2216",setmn:"\u2216",sext:"\u2736",Sfr:"\ud835\udd16",sfr:"\ud835\udd30",sfrown:"\u2322",sharp:"\u266f",SHCHcy:"\u0429",shchcy:"\u0449",SHcy:"\u0428",shcy:"\u0448",ShortDownArrow:"\u2193",ShortLeftArrow:"\u2190",shortmid:"\u2223",shortparallel:"\u2225",ShortRightArrow:"\u2192",ShortUpArrow:"\u2191",shy:"\xad",Sigma:"\u03a3",sigma:"\u03c3",sigmaf:"\u03c2",sigmav:"\u03c2",sim:"\u223c",simdot:"\u2a6a",sime:"\u2243",simeq:"\u2243",simg:"\u2a9e",simgE:"\u2aa0",siml:"\u2a9d",simlE:"\u2a9f",simne:"\u2246",simplus:"\u2a24",simrarr:"\u2972",slarr:"\u2190",SmallCircle:"\u2218",smallsetminus:"\u2216",smashp:"\u2a33",smeparsl:"\u29e4",smid:"\u2223",smile:"\u2323",smt:"\u2aaa",smte:"\u2aac",smtes:"\u2aac\ufe00",SOFTcy:"\u042c",softcy:"\u044c",solbar:"\u233f",solb:"\u29c4",sol:"/",Sopf:"\ud835\udd4a",sopf:"\ud835\udd64",spades:"\u2660",spadesuit:"\u2660",spar:"\u2225",sqcap:"\u2293",sqcaps:"\u2293\ufe00",sqcup:"\u2294",sqcups:"\u2294\ufe00",Sqrt:"\u221a",sqsub:"\u228f",sqsube:"\u2291",sqsubset:"\u228f",sqsubseteq:"\u2291",sqsup:"\u2290",sqsupe:"\u2292",sqsupset:"\u2290",sqsupseteq:"\u2292",square:"\u25a1",Square:"\u25a1",SquareIntersection:"\u2293",SquareSubset:"\u228f",SquareSubsetEqual:"\u2291",SquareSuperset:"\u2290",SquareSupersetEqual:"\u2292",SquareUnion:"\u2294",squarf:"\u25aa",squ:"\u25a1",squf:"\u25aa",srarr:"\u2192",Sscr:"\ud835\udcae",sscr:"\ud835\udcc8",ssetmn:"\u2216",ssmile:"\u2323",sstarf:"\u22c6",Star:"\u22c6",star:"\u2606",starf:"\u2605",straightepsilon:"\u03f5",straightphi:"\u03d5",strns:"\xaf",sub:"\u2282",Sub:"\u22d0",subdot:"\u2abd",subE:"\u2ac5",sube:"\u2286",subedot:"\u2ac3",submult:"\u2ac1",subnE:"\u2acb",subne:"\u228a",subplus:"\u2abf",subrarr:"\u2979",subset:"\u2282",Subset:"\u22d0",subseteq:"\u2286",subseteqq:"\u2ac5",SubsetEqual:"\u2286",subsetneq:"\u228a",subsetneqq:"\u2acb",subsim:"\u2ac7",subsub:"\u2ad5",subsup:"\u2ad3",succapprox:"\u2ab8",succ:"\u227b",succcurlyeq:"\u227d",Succeeds:"\u227b",SucceedsEqual:"\u2ab0",SucceedsSlantEqual:"\u227d",SucceedsTilde:"\u227f",succeq:"\u2ab0",succnapprox:"\u2aba",succneqq:"\u2ab6",succnsim:"\u22e9",succsim:"\u227f",SuchThat:"\u220b",sum:"\u2211",Sum:"\u2211",sung:"\u266a",sup1:"\xb9",sup2:"\xb2",sup3:"\xb3",sup:"\u2283",Sup:"\u22d1",supdot:"\u2abe",supdsub:"\u2ad8",supE:"\u2ac6",supe:"\u2287",supedot:"\u2ac4",Superset:"\u2283",SupersetEqual:"\u2287",suphsol:"\u27c9",suphsub:"\u2ad7",suplarr:"\u297b",supmult:"\u2ac2",supnE:"\u2acc",supne:"\u228b",supplus:"\u2ac0",supset:"\u2283",Supset:"\u22d1",supseteq:"\u2287",supseteqq:"\u2ac6",supsetneq:"\u228b",supsetneqq:"\u2acc",supsim:"\u2ac8",supsub:"\u2ad4",supsup:"\u2ad6",swarhk:"\u2926",swarr:"\u2199",swArr:"\u21d9",swarrow:"\u2199",swnwar:"\u292a",szlig:"\xdf",Tab:"\t",target:"\u2316",Tau:"\u03a4",tau:"\u03c4",tbrk:"\u23b4",Tcaron:"\u0164",tcaron:"\u0165",Tcedil:"\u0162",tcedil:"\u0163",Tcy:"\u0422",tcy:"\u0442",tdot:"\u20db",telrec:"\u2315",Tfr:"\ud835\udd17",tfr:"\ud835\udd31",there4:"\u2234",therefore:"\u2234",Therefore:"\u2234",Theta:"\u0398",theta:"\u03b8",thetasym:"\u03d1",thetav:"\u03d1",thickapprox:"\u2248",thicksim:"\u223c",ThickSpace:"\u205f\u200a",ThinSpace:"\u2009",thinsp:"\u2009",thkap:"\u2248",thksim:"\u223c",THORN:"\xde",thorn:"\xfe",tilde:"\u02dc",Tilde:"\u223c",TildeEqual:"\u2243",TildeFullEqual:"\u2245",TildeTilde:"\u2248",timesbar:"\u2a31",timesb:"\u22a0",times:"\xd7",timesd:"\u2a30",tint:"\u222d",toea:"\u2928",topbot:"\u2336",topcir:"\u2af1",top:"\u22a4",Topf:"\ud835\udd4b",topf:"\ud835\udd65",topfork:"\u2ada",tosa:"\u2929",tprime:"\u2034",trade:"\u2122",TRADE:"\u2122",triangle:"\u25b5",triangledown:"\u25bf",triangleleft:"\u25c3",trianglelefteq:"\u22b4",triangleq:"\u225c",triangleright:"\u25b9",trianglerighteq:"\u22b5",tridot:"\u25ec",trie:"\u225c",triminus:"\u2a3a",TripleDot:"\u20db",triplus:"\u2a39",trisb:"\u29cd",tritime:"\u2a3b",trpezium:"\u23e2",Tscr:"\ud835\udcaf",tscr:"\ud835\udcc9",TScy:"\u0426",tscy:"\u0446",TSHcy:"\u040b",tshcy:"\u045b",Tstrok:"\u0166",tstrok:"\u0167",twixt:"\u226c",twoheadleftarrow:"\u219e",twoheadrightarrow:"\u21a0",Uacute:"\xda",uacute:"\xfa",uarr:"\u2191",Uarr:"\u219f",uArr:"\u21d1",Uarrocir:"\u2949",Ubrcy:"\u040e",ubrcy:"\u045e",Ubreve:"\u016c",ubreve:"\u016d",Ucirc:"\xdb",ucirc:"\xfb",Ucy:"\u0423",ucy:"\u0443",udarr:"\u21c5",Udblac:"\u0170",udblac:"\u0171",udhar:"\u296e",ufisht:"\u297e",Ufr:"\ud835\udd18",ufr:"\ud835\udd32",Ugrave:"\xd9",ugrave:"\xf9",uHar:"\u2963",uharl:"\u21bf",uharr:"\u21be",uhblk:"\u2580",ulcorn:"\u231c",ulcorner:"\u231c",ulcrop:"\u230f",ultri:"\u25f8",Umacr:"\u016a",umacr:"\u016b",uml:"\xa8",UnderBar:"_",UnderBrace:"\u23df",UnderBracket:"\u23b5",UnderParenthesis:"\u23dd",Union:"\u22c3",UnionPlus:"\u228e",Uogon:"\u0172",uogon:"\u0173",Uopf:"\ud835\udd4c",uopf:"\ud835\udd66",UpArrowBar:"\u2912",uparrow:"\u2191",UpArrow:"\u2191",Uparrow:"\u21d1",UpArrowDownArrow:"\u21c5",updownarrow:"\u2195",UpDownArrow:"\u2195",Updownarrow:"\u21d5",UpEquilibrium:"\u296e",upharpoonleft:"\u21bf",upharpoonright:"\u21be",uplus:"\u228e",UpperLeftArrow:"\u2196",UpperRightArrow:"\u2197",upsi:"\u03c5",Upsi:"\u03d2",upsih:"\u03d2",Upsilon:"\u03a5",upsilon:"\u03c5",UpTeeArrow:"\u21a5",UpTee:"\u22a5",upuparrows:"\u21c8",urcorn:"\u231d",urcorner:"\u231d",urcrop:"\u230e",Uring:"\u016e",uring:"\u016f",urtri:"\u25f9",Uscr:"\ud835\udcb0",uscr:"\ud835\udcca",utdot:"\u22f0",Utilde:"\u0168",utilde:"\u0169",utri:"\u25b5",utrif:"\u25b4",uuarr:"\u21c8",Uuml:"\xdc",uuml:"\xfc",uwangle:"\u29a7",vangrt:"\u299c",varepsilon:"\u03f5",varkappa:"\u03f0",varnothing:"\u2205",varphi:"\u03d5",varpi:"\u03d6",varpropto:"\u221d",varr:"\u2195",vArr:"\u21d5",varrho:"\u03f1",varsigma:"\u03c2",varsubsetneq:"\u228a\ufe00",varsubsetneqq:"\u2acb\ufe00",varsupsetneq:"\u228b\ufe00",varsupsetneqq:"\u2acc\ufe00",vartheta:"\u03d1",vartriangleleft:"\u22b2",vartriangleright:"\u22b3",vBar:"\u2ae8",Vbar:"\u2aeb",vBarv:"\u2ae9",Vcy:"\u0412",vcy:"\u0432",vdash:"\u22a2",vDash:"\u22a8",Vdash:"\u22a9",VDash:"\u22ab",Vdashl:"\u2ae6",veebar:"\u22bb",vee:"\u2228",Vee:"\u22c1",veeeq:"\u225a",vellip:"\u22ee",verbar:"|",Verbar:"\u2016",vert:"|",Vert:"\u2016",VerticalBar:"\u2223",VerticalLine:"|",VerticalSeparator:"\u2758",VerticalTilde:"\u2240",VeryThinSpace:"\u200a",Vfr:"\ud835\udd19",vfr:"\ud835\udd33",vltri:"\u22b2",vnsub:"\u2282\u20d2",vnsup:"\u2283\u20d2",Vopf:"\ud835\udd4d",vopf:"\ud835\udd67",vprop:"\u221d",vrtri:"\u22b3",Vscr:"\ud835\udcb1",vscr:"\ud835\udccb",vsubnE:"\u2acb\ufe00",vsubne:"\u228a\ufe00",vsupnE:"\u2acc\ufe00",vsupne:"\u228b\ufe00",Vvdash:"\u22aa",vzigzag:"\u299a",Wcirc:"\u0174",wcirc:"\u0175",wedbar:"\u2a5f",wedge:"\u2227",Wedge:"\u22c0",wedgeq:"\u2259",weierp:"\u2118",Wfr:"\ud835\udd1a",wfr:"\ud835\udd34",Wopf:"\ud835\udd4e",wopf:"\ud835\udd68",wp:"\u2118",wr:"\u2240",wreath:"\u2240",Wscr:"\ud835\udcb2",wscr:"\ud835\udccc",xcap:"\u22c2",xcirc:"\u25ef",xcup:"\u22c3",xdtri:"\u25bd",Xfr:"\ud835\udd1b",xfr:"\ud835\udd35",xharr:"\u27f7",xhArr:"\u27fa",Xi:"\u039e",xi:"\u03be",xlarr:"\u27f5",xlArr:"\u27f8",xmap:"\u27fc",xnis:"\u22fb",xodot:"\u2a00",Xopf:"\ud835\udd4f",xopf:"\ud835\udd69",xoplus:"\u2a01",xotime:"\u2a02",xrarr:"\u27f6",xrArr:"\u27f9",Xscr:"\ud835\udcb3",xscr:"\ud835\udccd",xsqcup:"\u2a06",xuplus:"\u2a04",xutri:"\u25b3",xvee:"\u22c1",xwedge:"\u22c0",Yacute:"\xdd",yacute:"\xfd",YAcy:"\u042f",yacy:"\u044f",Ycirc:"\u0176",ycirc:"\u0177",Ycy:"\u042b",ycy:"\u044b",yen:"\xa5",Yfr:"\ud835\udd1c",yfr:"\ud835\udd36",YIcy:"\u0407",yicy:"\u0457",Yopf:"\ud835\udd50",yopf:"\ud835\udd6a",Yscr:"\ud835\udcb4",yscr:"\ud835\udcce",YUcy:"\u042e",yucy:"\u044e",yuml:"\xff",Yuml:"\u0178",Zacute:"\u0179",zacute:"\u017a",Zcaron:"\u017d",zcaron:"\u017e",Zcy:"\u0417",zcy:"\u0437",Zdot:"\u017b",zdot:"\u017c",zeetrf:"\u2128",ZeroWidthSpace:"\u200b",Zeta:"\u0396",zeta:"\u03b6",zfr:"\ud835\udd37",Zfr:"\u2128",ZHcy:"\u0416",zhcy:"\u0436",zigrarr:"\u21dd",zopf:"\ud835\udd6b",Zopf:"\u2124",Zscr:"\ud835\udcb5",zscr:"\ud835\udccf",zwj:"\u200d",zwnj:"\u200c"}},{}],53:[function(e,r,t){"use strict";function n(e){return Array.prototype.slice.call(arguments,1).forEach(function(r){r&&Object.keys(r).forEach(function(t){e[t]=r[t]})}),e}function s(e){return Object.prototype.toString.call(e)}function o(e){return"[object String]"===s(e)}function i(e){return"[object Object]"===s(e)}function a(e){return"[object RegExp]"===s(e)}function c(e){return"[object Function]"===s(e)}function l(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}function u(e){return Object.keys(e||{}).reduce(function(e,r){return e||b.hasOwnProperty(r)},!1)}function p(e){e.__index__=-1,e.__text_cache__=""}function h(e){return function(r,t){var n=r.slice(t);return e.test(n)?n.match(e)[0].length:0}}function f(){return function(e,r){r.normalize(e)}}function d(r){function t(e){return e.replace("%TLDS%",s.src_tlds)}function n(e,r){throw new Error('(LinkifyIt) Invalid schema "'+e+'": '+r)}var s=r.re=e("./lib/re")(r.__opts__),u=r.__tlds__.slice();r.onCompile(),r.__tlds_replaced__||u.push("a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]"),u.push(s.src_xn),s.src_tlds=u.join("|"),s.email_fuzzy=RegExp(t(s.tpl_email_fuzzy),"i"),s.link_fuzzy=RegExp(t(s.tpl_link_fuzzy),"i"),s.link_no_ip_fuzzy=RegExp(t(s.tpl_link_no_ip_fuzzy),"i"),s.host_fuzzy_test=RegExp(t(s.tpl_host_fuzzy_test),"i");var d=[];r.__compiled__={},Object.keys(r.__schemas__).forEach(function(e){var t=r.__schemas__[e];if(null!==t){var s={validate:null,link:null};return r.__compiled__[e]=s,i(t)?(a(t.validate)?s.validate=h(t.validate):c(t.validate)?s.validate=t.validate:n(e,t),void(c(t.normalize)?s.normalize=t.normalize:t.normalize?n(e,t):s.normalize=f())):o(t)?void d.push(e):void n(e,t)}}),d.forEach(function(e){r.__compiled__[r.__schemas__[e]]&&(r.__compiled__[e].validate=r.__compiled__[r.__schemas__[e]].validate,r.__compiled__[e].normalize=r.__compiled__[r.__schemas__[e]].normalize)}),r.__compiled__[""]={validate:null,normalize:f()};var m=Object.keys(r.__compiled__).filter(function(e){return e.length>0&&r.__compiled__[e]}).map(l).join("|");r.re.schema_test=RegExp("(^|(?!_)(?:[><\uff5c]|"+s.src_ZPCc+"))("+m+")","i"),r.re.schema_search=RegExp("(^|(?!_)(?:[><\uff5c]|"+s.src_ZPCc+"))("+m+")","ig"),r.re.pretest=RegExp("("+r.re.schema_test.source+")|("+r.re.host_fuzzy_test.source+")|@","i"),p(r)}function m(e,r){var t=e.__index__,n=e.__last_index__,s=e.__text_cache__.slice(t,n);this.schema=e.__schema__.toLowerCase(),this.index=t+r,this.lastIndex=n+r,this.raw=s,this.text=s,this.url=s}function _(e,r){var t=new m(e,r);return e.__compiled__[t.schema].normalize(t,e),t}function g(e,r){if(!(this instanceof g))return new g(e,r);r||u(e)&&(r=e,e={}),this.__opts__=n({},b,r),this.__index__=-1,this.__last_index__=-1,this.__schema__="",this.__text_cache__="",this.__schemas__=n({},k,e),this.__compiled__={},this.__tlds__=v,this.__tlds_replaced__=!1,this.re={},d(this)}var b={fuzzyLink:!0,fuzzyEmail:!0,fuzzyIP:!1},k={"http:":{validate:function(e,r,t){var n=e.slice(r);return t.re.http||(t.re.http=new RegExp("^\\/\\/"+t.re.src_auth+t.re.src_host_port_strict+t.re.src_path,"i")),t.re.http.test(n)?n.match(t.re.http)[0].length:0}},"https:":"http:","ftp:":"http:","//":{validate:function(e,r,t){var n=e.slice(r);return t.re.no_http||(t.re.no_http=new RegExp("^"+t.re.src_auth+"(?:localhost|(?:(?:"+t.re.src_domain+")\\.)+"+t.re.src_domain_root+")"+t.re.src_port+t.re.src_host_terminator+t.re.src_path,"i")),t.re.no_http.test(n)?r>=3&&":"===e[r-3]?0:r>=3&&"/"===e[r-3]?0:n.match(t.re.no_http)[0].length:0}},"mailto:":{validate:function(e,r,t){var n=e.slice(r);return t.re.mailto||(t.re.mailto=new RegExp("^"+t.re.src_email_name+"@"+t.re.src_host_strict,"i")),t.re.mailto.test(n)?n.match(t.re.mailto)[0].length:0}}},v="biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|\u0440\u0444".split("|");g.prototype.add=function(e,r){return this.__schemas__[e]=r,d(this),this},g.prototype.set=function(e){return this.__opts__=n(this.__opts__,e),this},g.prototype.test=function(e){if(this.__text_cache__=e,this.__index__=-1,!e.length)return!1;var r,t,n,s,o,i,a,c;if(this.re.schema_test.test(e))for(a=this.re.schema_search,a.lastIndex=0;null!==(r=a.exec(e));)if(s=this.testSchemaAt(e,r[2],a.lastIndex)){this.__schema__=r[2],this.__index__=r.index+r[1].length,this.__last_index__=r.index+r[0].length+s;break}return this.__opts__.fuzzyLink&&this.__compiled__["http:"]&&(c=e.search(this.re.host_fuzzy_test))>=0&&(this.__index__<0||c=0&&null!==(n=e.match(this.re.email_fuzzy))&&(o=n.index+n[1].length,i=n.index+n[0].length,(this.__index__<0||othis.__last_index__)&&(this.__schema__="mailto:",this.__index__=o,this.__last_index__=i)),this.__index__>=0},g.prototype.pretest=function(e){return this.re.pretest.test(e)},g.prototype.testSchemaAt=function(e,r,t){return this.__compiled__[r.toLowerCase()]?this.__compiled__[r.toLowerCase()].validate(e,t,this):0},g.prototype.match=function(e){var r=0,t=[];this.__index__>=0&&this.__text_cache__===e&&(t.push(_(this,r)),r=this.__last_index__);for(var n=r?e.slice(r):e;this.test(n);)t.push(_(this,r)),n=n.slice(this.__last_index__),r+=this.__last_index__;return t.length?t:null},g.prototype.tlds=function(e,r){return e=Array.isArray(e)?e:[e],r?(this.__tlds__=this.__tlds__.concat(e).sort().filter(function(e,r,t){return e!==t[r-1]}).reverse(),d(this),this):(this.__tlds__=e.slice(),this.__tlds_replaced__=!0,d(this),this)},g.prototype.normalize=function(e){e.schema||(e.url="http://"+e.url),"mailto:"!==e.schema||/^mailto:/i.test(e.url)||(e.url="mailto:"+e.url)},g.prototype.onCompile=function(){},r.exports=g},{"./lib/re":54}],54:[function(e,r,t){"use strict";r.exports=function(r){var t={};t.src_Any=e("uc.micro/properties/Any/regex").source,t.src_Cc=e("uc.micro/categories/Cc/regex").source,t.src_Z=e("uc.micro/categories/Z/regex").source,t.src_P=e("uc.micro/categories/P/regex").source,t.src_ZPCc=[t.src_Z,t.src_P,t.src_Cc].join("|"),t.src_ZCc=[t.src_Z,t.src_Cc].join("|");return t.src_pseudo_letter="(?:(?![><\uff5c]|"+t.src_ZPCc+")"+t.src_Any+")",t.src_ip4="(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",t.src_auth="(?:(?:(?!"+t.src_ZCc+"|[@/\\[\\]()]).)+@)?",t.src_port="(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?",t.src_host_terminator="(?=$|[><\uff5c]|"+t.src_ZPCc+")(?!-|_|:\\d|\\.-|\\.(?!$|"+t.src_ZPCc+"))",t.src_path="(?:[/?#](?:(?!"+t.src_ZCc+"|[><\uff5c]|[()[\\]{}.,\"'?!\\-]).|\\[(?:(?!"+t.src_ZCc+"|\\]).)*\\]|\\((?:(?!"+t.src_ZCc+"|[)]).)*\\)|\\{(?:(?!"+t.src_ZCc+'|[}]).)*\\}|\\"(?:(?!'+t.src_ZCc+'|["]).)+\\"|\\\'(?:(?!'+t.src_ZCc+"|[']).)+\\'|\\'(?="+t.src_pseudo_letter+"|[-]).|\\.{2,3}[a-zA-Z0-9%/]|\\.(?!"+t.src_ZCc+"|[.]).|"+(r&&r["---"]?"\\-(?!--(?:[^-]|$))(?:-*)|":"\\-+|")+"\\,(?!"+t.src_ZCc+").|\\!(?!"+t.src_ZCc+"|[!]).|\\?(?!"+t.src_ZCc+"|[?]).)+|\\/)?",t.src_email_name='[\\-;:&=\\+\\$,\\"\\.a-zA-Z0-9_]+',t.src_xn="xn--[a-z0-9\\-]{1,59}",t.src_domain_root="(?:"+t.src_xn+"|"+t.src_pseudo_letter+"{1,63})",t.src_domain="(?:"+t.src_xn+"|(?:"+t.src_pseudo_letter+")|(?:"+t.src_pseudo_letter+"(?:-(?!-)|"+t.src_pseudo_letter+"){0,61}"+t.src_pseudo_letter+"))",t.src_host="(?:(?:(?:(?:"+t.src_domain+")\\.)*"+t.src_domain+"))",t.tpl_host_fuzzy="(?:"+t.src_ip4+"|(?:(?:(?:"+t.src_domain+")\\.)+(?:%TLDS%)))",t.tpl_host_no_ip_fuzzy="(?:(?:(?:"+t.src_domain+")\\.)+(?:%TLDS%))",t.src_host_strict=t.src_host+t.src_host_terminator,t.tpl_host_fuzzy_strict=t.tpl_host_fuzzy+t.src_host_terminator,t.src_host_port_strict=t.src_host+t.src_port+t.src_host_terminator,t.tpl_host_port_fuzzy_strict=t.tpl_host_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_port_no_ip_fuzzy_strict=t.tpl_host_no_ip_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_fuzzy_test="localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:"+t.src_ZPCc+"|>|$))",t.tpl_email_fuzzy="(^|[><\uff5c]|\\(|"+t.src_ZCc+")("+t.src_email_name+"@"+t.tpl_host_fuzzy_strict+")",t.tpl_link_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|"+t.src_ZPCc+"))((?![$+<=>^`|\uff5c])"+t.tpl_host_port_fuzzy_strict+t.src_path+")",t.tpl_link_no_ip_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|"+t.src_ZPCc+"))((?![$+<=>^`|\uff5c])"+t.tpl_host_port_no_ip_fuzzy_strict+t.src_path+")",t}},{ -"uc.micro/categories/Cc/regex":61,"uc.micro/categories/P/regex":63,"uc.micro/categories/Z/regex":64,"uc.micro/properties/Any/regex":66}],55:[function(e,r,t){"use strict";function n(e){var r,t,n=o[e];if(n)return n;for(n=o[e]=[],r=0;r<128;r++)t=String.fromCharCode(r),n.push(t);for(r=0;r=55296&&c<=57343?"\ufffd\ufffd\ufffd":String.fromCharCode(c),r+=6):240==(248&s)&&r+91114111?l+="\ufffd\ufffd\ufffd\ufffd":(c-=65536,l+=String.fromCharCode(55296+(c>>10),56320+(1023&c))),r+=9):l+="\ufffd";return l})}var o={};s.defaultChars=";/?:@&=+$,#",s.componentChars="",r.exports=s},{}],56:[function(e,r,t){"use strict";function n(e){var r,t,n=o[e];if(n)return n;for(n=o[e]=[],r=0;r<128;r++)t=String.fromCharCode(r),/^[0-9a-z]$/i.test(t)?n.push(t):n.push("%"+("0"+r.toString(16).toUpperCase()).slice(-2));for(r=0;r=55296&&a<=57343){if(a>=55296&&a<=56319&&o+1=56320&&c<=57343){u+=encodeURIComponent(e[o]+e[o+1]),o++;continue}u+="%EF%BF%BD"}else u+=encodeURIComponent(e[o]);return u}var o={};s.defaultChars=";/?:@&=+$,-_.!~*'()#",s.componentChars="-_.!~*'()",r.exports=s},{}],57:[function(e,r,t){"use strict";r.exports=function(e){var r="";return r+=e.protocol||"",r+=e.slashes?"//":"",r+=e.auth?e.auth+"@":"",r+=e.hostname&&e.hostname.indexOf(":")!==-1?"["+e.hostname+"]":e.hostname||"",r+=e.port?":"+e.port:"",r+=e.pathname||"",r+=e.search||"",r+=e.hash||""}},{}],58:[function(e,r,t){"use strict";r.exports.encode=e("./encode"),r.exports.decode=e("./decode"),r.exports.format=e("./format"),r.exports.parse=e("./parse")},{"./decode":55,"./encode":56,"./format":57,"./parse":59}],59:[function(e,r,t){"use strict";function n(){this.protocol=null,this.slashes=null,this.auth=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.pathname=null}function s(e,r){if(e&&e instanceof n)return e;var t=new n;return t.parse(e,r),t}var o=/^([a-z0-9.+-]+:)/i,i=/:[0-9]*$/,a=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,c=["<",">",'"',"`"," ","\r","\n","\t"],l=["{","}","|","\\","^","`"].concat(c),u=["'"].concat(l),p=["%","/","?",";","#"].concat(u),h=["/","?","#"],f={javascript:!0,"javascript:":!0},d={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0};n.prototype.parse=function(e,r){var t,n,s,i,c,l=e;if(l=l.trim(),!r&&1===e.split("#").length){var u=a.exec(l);if(u)return this.pathname=u[1],u[2]&&(this.search=u[2]),this}var m=o.exec(l);if(m&&(m=m[0],s=m.toLowerCase(),this.protocol=m,l=l.substr(m.length)),(r||m||l.match(/^\/\/[^@\/]+@[^@\/]+/))&&(!(c="//"===l.substr(0,2))||m&&f[m]||(l=l.substr(2),this.slashes=!0)),!f[m]&&(c||m&&!d[m])){var _=-1;for(t=0;t127?"x":x[A];if(!C.match(/^[+a-z0-9A-Z_-]{0,63}$/)){var D=y.slice(0,t),q=y.slice(t+1),E=x.match(/^([+a-z0-9A-Z_-]{0,63})(.*)$/);E&&(D.push(E[1]),q.unshift(E[2])),q.length&&(l=q.join(".")+l),this.hostname=D.join(".");break}}}}this.hostname.length>255&&(this.hostname=""),v&&(this.hostname=this.hostname.substr(1,this.hostname.length-2))}var S=l.indexOf("#");S!==-1&&(this.hash=l.substr(S),l=l.slice(0,S));var F=l.indexOf("?");return F!==-1&&(this.search=l.substr(F),l=l.slice(0,F)),l&&(this.pathname=l),d[s]&&this.hostname&&!this.pathname&&(this.pathname=""),this},n.prototype.parseHost=function(e){var r=i.exec(e);r&&(r=r[0],":"!==r&&(this.port=r.substr(1)),e=e.substr(0,e.length-r.length)),e&&(this.hostname=e)},r.exports=s},{}],60:[function(r,t,n){(function(r){!function(s){function o(e){throw new RangeError(w[e])}function i(e,r){for(var t=e.length,n=[];t--;)n[t]=r(e[t]);return n}function a(e,r){var t=e.split("@"),n="";return t.length>1&&(n=t[0]+"@",e=t[1]),e=e.replace(/[\x2E\u3002\uFF0E\uFF61]/g,"."),n+i(e.split("."),r).join(".")}function c(e){for(var r,t,n=[],s=0,o=e.length;s=55296&&r<=56319&&s65535&&(e-=65536,r+=q(e>>>10&1023|55296),e=56320|1023&e),r+=q(e)}).join("")}function u(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:36}function p(e,r){return e+22+75*(e<26)-((0!=r)<<5)}function h(e,r,t){var n=0;for(e=t?D(e/700):e>>1,e+=D(e/r);e>455;n+=36)e=D(e/35);return D(n+36*e/(e+38))}function f(e){var r,t,n,s,i,a,c,p,f,d,m=[],_=e.length,g=0,b=128,k=72;for(t=e.lastIndexOf("-"),t<0&&(t=0),n=0;n=128&&o("not-basic"),m.push(e.charCodeAt(n));for(s=t>0?t+1:0;s<_;){for(i=g,a=1,c=36;s>=_&&o("invalid-input"),p=u(e.charCodeAt(s++)),(p>=36||p>D((x-g)/a))&&o("overflow"),g+=p*a,f=c<=k?1:c>=k+26?26:c-k,!(pD(x/d)&&o("overflow"),a*=d;r=m.length+1,k=h(g-i,r,0==i),D(g/r)>x-b&&o("overflow"),b+=D(g/r),g%=r,m.splice(g++,0,b)}return l(m)}function d(e){var r,t,n,s,i,a,l,u,f,d,m,_,g,b,k,v=[];for(e=c(e),_=e.length,r=128,t=0,i=72,a=0;a<_;++a)(m=e[a])<128&&v.push(q(m));for(n=s=v.length,s&&v.push("-");n<_;){for(l=x,a=0;a<_;++a)(m=e[a])>=r&&mD((x-t)/g)&&o("overflow"),t+=(l-r)*g,r=l,a=0;a<_;++a)if(m=e[a],mx&&o("overflow"),m==r){for(u=t,f=36;d=f<=i?1:f>=i+26?26:f-i,!(u= 0x80 (not a basic code point)","invalid-input":"Invalid input"},D=Math.floor,q=String.fromCharCode;if(v={version:"1.4.1",ucs2:{decode:c,encode:l},decode:f,encode:d,toASCII:_,toUnicode:m},"function"==typeof e&&"object"==typeof e.amd&&e.amd)e("punycode",function(){return v});else if(g&&b)if(t.exports==g)b.exports=v;else for(y in v)v.hasOwnProperty(y)&&(g[y]=v[y]);else s.punycode=v}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],61:[function(e,r,t){r.exports=/[\0-\x1F\x7F-\x9F]/},{}],62:[function(e,r,t){r.exports=/[\xAD\u0600-\u0605\u061C\u06DD\u070F\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804\uDCBD|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/},{}],63:[function(e,r,t){r.exports=/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E44\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDF3C-\uDF3E]|\uD807[\uDC41-\uDC45\uDC70\uDC71]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]/},{}],64:[function(e,r,t){r.exports=/[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/},{}],65:[function(e,r,t){"use strict";t.Any=e("./properties/Any/regex"),t.Cc=e("./categories/Cc/regex"),t.Cf=e("./categories/Cf/regex"),t.P=e("./categories/P/regex"),t.Z=e("./categories/Z/regex")},{"./categories/Cc/regex":61,"./categories/Cf/regex":62,"./categories/P/regex":63,"./categories/Z/regex":64,"./properties/Any/regex":66}],66:[function(e,r,t){r.exports=/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/},{}],67:[function(e,r,t){"use strict";r.exports=e("./lib/")},{"./lib/":9}]},{},[67])(67)}); diff --git a/src/utils/marked b/src/utils/marked deleted file mode 160000 index f1ddca7f..00000000 --- a/src/utils/marked +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f1ddca7febad16eb7861af0a7135989df0eb8e80 diff --git a/src/utils/mermaid/mermaid.min.js b/src/utils/mermaid/mermaid.min.js deleted file mode 100644 index 0a72f337..00000000 --- a/src/utils/mermaid/mermaid.min.js +++ /dev/null @@ -1,49 +0,0 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.mermaid=e():t.mermaid=e()}(window,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=509)}([function(t,e,n){"use strict";n.r(e);var r=function(t,e){return te?1:t>=e?0:NaN},i=function(t){var e;return 1===t.length&&(e=t,t=function(t,n){return r(e(t),n)}),{left:function(e,n,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r>>1;t(e[o],n)<0?r=o+1:i=o}return r},right:function(e,n,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r>>1;t(e[o],n)>0?i=o:r=o+1}return r}}};var o=i(r),a=o.right,s=o.left,u=a,c=function(t,e){null==e&&(e=f);for(var n=0,r=t.length-1,i=t[0],o=new Array(r<0?0:r);nt?1:e>=t?0:NaN},d=function(t){return null===t?NaN:+t},p=function(t,e){var n,r,i=t.length,o=0,a=-1,s=0,u=0;if(null==e)for(;++a1)return u/(o-1)},g=function(t,e){var n=p(t,e);return n?Math.sqrt(n):n},y=function(t,e){var n,r,i,o=t.length,a=-1;if(null==e){for(;++a=n)for(r=i=n;++an&&(r=n),i=n)for(r=i=n;++an&&(r=n),i0)return[t];if((r=e0)for(t=Math.ceil(t/a),e=Math.floor(e/a),o=new Array(i=Math.ceil(e-t+1));++s=0?(o>=k?10:o>=E?5:o>=A?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(o>=k?10:o>=E?5:o>=A?2:1)}function M(t,e,n){var r=Math.abs(e-t)/Math.max(0,n),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),o=r/i;return o>=k?i*=10:o>=E?i*=5:o>=A&&(i*=2),el;)h.pop(),--d;var p,g=new Array(d+1);for(i=0;i<=d;++i)(p=g[i]=[]).x0=i>0?h[i-1]:f,p.x1=i=1)return+n(t[r-1],r-1,t);var r,i=(r-1)*e,o=Math.floor(i),a=+n(t[o],o,t);return a+(+n(t[o+1],o+1,t)-a)*(i-o)}},R=function(t,e,n){return t=v.call(t,d).sort(r),Math.ceil((n-e)/(2*(O(t,.75)-O(t,.25))*Math.pow(t.length,-1/3)))},I=function(t,e,n){return Math.ceil((n-e)/(3.5*g(t)*Math.pow(t.length,-1/3)))},N=function(t,e){var n,r,i=t.length,o=-1;if(null==e){for(;++o=n)for(r=n;++or&&(r=n)}else for(;++o=n)for(r=n;++or&&(r=n);return r},B=function(t,e){var n,r=t.length,i=r,o=-1,a=0;if(null==e)for(;++o=0;)for(e=(r=t[i]).length;--e>=0;)n[--a]=r[e];return n},F=function(t,e){var n,r,i=t.length,o=-1;if(null==e){for(;++o=n)for(r=n;++on&&(r=n)}else for(;++o=n)for(r=n;++on&&(r=n);return r},q=function(t,e){for(var n=e.length,r=new Array(n);n--;)r[n]=t[e[n]];return r},j=function(t,e){if(n=t.length){var n,i,o=0,a=0,s=t[a];for(null==e&&(e=r);++o=0&&(n=t.slice(r+1),t=t.slice(0,r)),t&&!e.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:n}}))}function dt(t,e){for(var n,r=0,i=t.length;r0)for(var n,r,i=new Array(n),o=0;o=0&&"xmlns"!==(e=t.slice(0,n))&&(t=t.slice(n+1)),bt.hasOwnProperty(e)?{space:bt[e],local:t}:t};function vt(t){return function(){var e=this.ownerDocument,n=this.namespaceURI;return n===yt&&e.documentElement.namespaceURI===yt?e.createElement(t):e.createElementNS(n,t)}}function _t(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}var wt=function(t){var e=mt(t);return(e.local?_t:vt)(e)};function xt(){}var kt=function(t){return null==t?xt:function(){return this.querySelector(t)}};function Et(){return[]}var At=function(t){return null==t?Et:function(){return this.querySelectorAll(t)}},St=function(t){return function(){return this.matches(t)}},Tt=function(t){return new Array(t.length)};function Mt(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}Mt.prototype={constructor:Mt,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var Dt="$";function Ct(t,e,n,r,i,o){for(var a,s=0,u=e.length,c=o.length;se?1:t>=e?0:NaN}function It(t){return function(){this.removeAttribute(t)}}function Nt(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Bt(t,e){return function(){this.setAttribute(t,e)}}function Lt(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function Pt(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttribute(t):this.setAttribute(t,n)}}function Ft(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,n)}}var qt=function(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView};function jt(t){return function(){this.style.removeProperty(t)}}function Ut(t,e,n){return function(){this.style.setProperty(t,e,n)}}function zt(t,e,n){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,n)}}function Yt(t,e){return t.style.getPropertyValue(e)||qt(t).getComputedStyle(t,null).getPropertyValue(e)}function Vt(t){return function(){delete this[t]}}function Ht(t,e){return function(){this[t]=e}}function $t(t,e){return function(){var n=e.apply(this,arguments);null==n?delete this[t]:this[t]=n}}function Gt(t){return t.trim().split(/^|\s+/)}function Wt(t){return t.classList||new Kt(t)}function Kt(t){this._node=t,this._names=Gt(t.getAttribute("class")||"")}function Xt(t,e){for(var n=Wt(t),r=-1,i=e.length;++r=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};function ee(){this.textContent=""}function ne(t){return function(){this.textContent=t}}function re(t){return function(){var e=t.apply(this,arguments);this.textContent=null==e?"":e}}function ie(){this.innerHTML=""}function oe(t){return function(){this.innerHTML=t}}function ae(t){return function(){var e=t.apply(this,arguments);this.innerHTML=null==e?"":e}}function se(){this.nextSibling&&this.parentNode.appendChild(this)}function ue(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function ce(){return null}function fe(){var t=this.parentNode;t&&t.removeChild(this)}function le(){return this.parentNode.insertBefore(this.cloneNode(!1),this.nextSibling)}function he(){return this.parentNode.insertBefore(this.cloneNode(!0),this.nextSibling)}var de={},pe=null;"undefined"!=typeof document&&("onmouseenter"in document.documentElement||(de={mouseenter:"mouseover",mouseleave:"mouseout"}));function ge(t,e,n){return t=ye(t,e,n),function(e){var n=e.relatedTarget;n&&(n===this||8&n.compareDocumentPosition(this))||t.call(this,e)}}function ye(t,e,n){return function(r){var i=pe;pe=r;try{t.call(this,this.__data__,e,n)}finally{pe=i}}}function be(t){return t.trim().split(/^|\s+/).map((function(t){var e="",n=t.indexOf(".");return n>=0&&(e=t.slice(n+1),t=t.slice(0,n)),{type:t,name:e}}))}function me(t){return function(){var e=this.__on;if(e){for(var n,r=0,i=-1,o=e.length;r=w&&(w=_+1);!(v=b[w])&&++w=0;)(r=i[o])&&(a&&4^r.compareDocumentPosition(a)&&a.parentNode.insertBefore(r,a),a=r);return this},sort:function(t){function e(e,n){return e&&n?t(e.__data__,n.__data__):!e-!n}t||(t=Rt);for(var n=this._groups,r=n.length,i=new Array(r),o=0;o1?this.each((null==e?jt:"function"==typeof e?zt:Ut)(t,e,null==n?"":n)):Yt(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?Vt:"function"==typeof e?$t:Ht)(t,e)):this.node()[t]},classed:function(t,e){var n=Gt(t+"");if(arguments.length<2){for(var r=Wt(this.node()),i=-1,o=n.length;++il}u.mouse("drag")}function g(){Me(pe.view).on("mousemove.drag mouseup.drag",null),ze(pe.view,n),je(),u.mouse("end")}function y(){if(i.apply(this,arguments)){var t,e,n=pe.changedTouches,r=o.apply(this,arguments),a=n.length;for(t=0;t>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?new mn(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?new mn(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=rn.exec(t))?new mn(e[1],e[2],e[3],1):(e=on.exec(t))?new mn(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=an.exec(t))?gn(e[1],e[2],e[3],e[4]):(e=sn.exec(t))?gn(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=un.exec(t))?xn(e[1],e[2]/100,e[3]/100,1):(e=cn.exec(t))?xn(e[1],e[2]/100,e[3]/100,e[4]):fn.hasOwnProperty(t)?pn(fn[t]):"transparent"===t?new mn(NaN,NaN,NaN,0):null}function pn(t){return new mn(t>>16&255,t>>8&255,255&t,1)}function gn(t,e,n,r){return r<=0&&(t=e=n=NaN),new mn(t,e,n,r)}function yn(t){return t instanceof Je||(t=dn(t)),t?new mn((t=t.rgb()).r,t.g,t.b,t.opacity):new mn}function bn(t,e,n,r){return 1===arguments.length?yn(t):new mn(t,e,n,null==r?1:r)}function mn(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}function vn(){return"#"+wn(this.r)+wn(this.g)+wn(this.b)}function _n(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}function wn(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function xn(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new An(t,e,n,r)}function kn(t){if(t instanceof An)return new An(t.h,t.s,t.l,t.opacity);if(t instanceof Je||(t=dn(t)),!t)return new An;if(t instanceof An)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),o=Math.max(e,n,r),a=NaN,s=o-i,u=(o+i)/2;return s?(a=e===o?(n-r)/s+6*(n0&&u<1?0:a,new An(a,s,u,t.opacity)}function En(t,e,n,r){return 1===arguments.length?kn(t):new An(t,e,n,null==r?1:r)}function An(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function Sn(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}function Tn(t,e,n,r,i){var o=t*t,a=o*t;return((1-3*t+3*o-a)*e+(4-6*o+3*a)*n+(1+3*t+3*o-3*a)*r+a*i)/6}Xe(Je,dn,{copy:function(t){return Object.assign(new this.constructor,this,t)},displayable:function(){return this.rgb().displayable()},hex:ln,formatHex:ln,formatHsl:function(){return kn(this).formatHsl()},formatRgb:hn,toString:hn}),Xe(mn,bn,Ze(Je,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new mn(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new mn(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:vn,formatHex:vn,formatRgb:_n,toString:_n})),Xe(An,En,Ze(Je,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new An(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new An(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new mn(Sn(t>=240?t-240:t+120,i,r),Sn(t,i,r),Sn(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"hsl(":"hsla(")+(this.h||0)+", "+100*(this.s||0)+"%, "+100*(this.l||0)+"%"+(1===t?")":", "+t+")")}}));var Mn=function(t){var e=t.length-1;return function(n){var r=n<=0?n=0:n>=1?(n=1,e-1):Math.floor(n*e),i=t[r],o=t[r+1],a=r>0?t[r-1]:2*i-o,s=r180||n<-180?n-360*Math.round(n/360):n):Cn(isNaN(t)?e:t)}function In(t){return 1==(t=+t)?Nn:function(e,n){return n-e?function(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}(e,n,t):Cn(isNaN(e)?n:e)}}function Nn(t,e){var n=e-t;return n?On(t,n):Cn(isNaN(t)?e:t)}var Bn=function t(e){var n=In(e);function r(t,e){var r=n((t=bn(t)).r,(e=bn(e)).r),i=n(t.g,e.g),o=n(t.b,e.b),a=Nn(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=i(e),t.b=o(e),t.opacity=a(e),t+""}}return r.gamma=t,r}(1);function Ln(t){return function(e){var n,r,i=e.length,o=new Array(i),a=new Array(i),s=new Array(i);for(n=0;no&&(i=e.slice(o,i),s[a]?s[a]+=i:s[++a]=i),(n=n[0])===(r=r[0])?s[a]?s[a]+=r:s[++a]=r:(s[++a]=null,u.push({i:a,x:Un(n,r)})),o=Vn.lastIndex;return o180?e+=360:e-t>180&&(t+=360),o.push({i:n.push(i(n)+"rotate(",null,r)-2,x:Un(t,e)})):e&&n.push(i(n)+"rotate("+e+r)}(o.rotate,a.rotate,s,u),function(t,e,n,o){t!==e?o.push({i:n.push(i(n)+"skewX(",null,r)-2,x:Un(t,e)}):e&&n.push(i(n)+"skewX("+e+r)}(o.skewX,a.skewX,s,u),function(t,e,n,r,o,a){if(t!==n||e!==r){var s=o.push(i(o)+"scale(",null,",",null,")");a.push({i:s-4,x:Un(t,n)},{i:s-2,x:Un(e,r)})}else 1===n&&1===r||o.push(i(o)+"scale("+n+","+r+")")}(o.scaleX,o.scaleY,a.scaleX,a.scaleY,s,u),o=a=null,function(t){for(var e,n=-1,r=u.length;++n_r?Math.pow(t,1/3):t/vr+br}function Sr(t){return t>mr?t*t*t:vr*(t-br)}function Tr(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function Mr(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Dr(t){if(t instanceof Rr)return new Rr(t.h,t.c,t.l,t.opacity);if(t instanceof Er||(t=wr(t)),0===t.a&&0===t.b)return new Rr(NaN,0=0&&e._call.call(null,t),e=e._next;--Qr}function di(){ii=(ri=ai.now())+oi,Qr=ti=0;try{hi()}finally{Qr=0,function(){var t,e,n=Xr,r=1/0;for(;n;)n._call?(r>n._time&&(r=n._time),t=n,n=n._next):(e=n._next,n._next=null,n=t?t._next=e:Xr=e);Zr=t,gi(r)}(),ii=0}}function pi(){var t=ai.now(),e=t-ri;e>ni&&(oi-=e,ri=t)}function gi(t){Qr||(ti&&(ti=clearTimeout(ti)),t-ii>24?(t<1/0&&(ti=setTimeout(di,t-ai.now()-oi)),ei&&(ei=clearInterval(ei))):(ei||(ri=ai.now(),ei=setInterval(pi,ni)),Qr=1,si(di)))}fi.prototype=li.prototype={constructor:fi,restart:function(t,e,n){if("function"!=typeof t)throw new TypeError("callback is not a function");n=(null==n?ui():+n)+(null==e?0:+e),this._next||Zr===this||(Zr?Zr._next=this:Xr=this,Zr=this),this._call=t,this._time=n,gi()},stop:function(){this._call&&(this._call=null,this._time=1/0,gi())}};var yi=function(t,e,n){var r=new fi;return e=null==e?0:+e,r.restart((function(n){r.stop(),t(n+e)}),e,n),r},bi=function(t,e,n){var r=new fi,i=e;return null==e?(r.restart(t,e,n),r):(e=+e,n=null==n?ui():+n,r.restart((function o(a){a+=i,r.restart(o,i+=e,n),t(a)}),e,n),r)},mi=gt("start","end","cancel","interrupt"),vi=[],_i=0,wi=1,xi=2,ki=3,Ei=4,Ai=5,Si=6,Ti=function(t,e,n,r,i,o){var a=t.__transition;if(a){if(n in a)return}else t.__transition={};!function(t,e,n){var r,i=t.__transition;function o(u){var c,f,l,h;if(n.state!==wi)return s();for(c in i)if((h=i[c]).name===n.name){if(h.state===ki)return yi(o);h.state===Ei?(h.state=Si,h.timer.stop(),h.on.call("interrupt",t,t.__data__,h.index,h.group),delete i[c]):+c_i)throw new Error("too late; already scheduled");return n}function Di(t,e){var n=Ci(t,e);if(n.state>ki)throw new Error("too late; already running");return n}function Ci(t,e){var n=t.__transition;if(!n||!(n=n[e]))throw new Error("transition not found");return n}var Oi=function(t,e){var n,r,i,o=t.__transition,a=!0;if(o){for(i in e=null==e?null:e+"",o)(n=o[i]).name===e?(r=n.state>xi&&n.state=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?Mi:Di;return function(){var a=o(this,t),s=a.on;s!==r&&(i=(r=s).copy()).on(e,n),a.on=i}}var Xi=Te.prototype.constructor;function Zi(t){return function(){this.style.removeProperty(t)}}function Ji(t,e,n){var r,i;function o(){var o=e.apply(this,arguments);return o!==i&&(r=(i=o)&&function(t,e,n){return function(r){this.style.setProperty(t,e(r),n)}}(t,o,n)),r}return o._value=e,o}var Qi=0;function to(t,e,n,r){this._groups=t,this._parents=e,this._name=n,this._id=r}function eo(t){return Te().transition(t)}function no(){return++Qi}var ro=Te.prototype;function io(t){return+t}function oo(t){return t*t}function ao(t){return t*(2-t)}function so(t){return((t*=2)<=1?t*t:--t*(2-t)+1)/2}function uo(t){return t*t*t}function co(t){return--t*t*t+1}function fo(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}to.prototype=eo.prototype={constructor:to,select:function(t){var e=this._name,n=this._id;"function"!=typeof t&&(t=kt(t));for(var r=this._groups,i=r.length,o=new Array(i),a=0;awi&&n.name===e)return new to([[t]],Wo,e,+r);return null},Xo=function(t){return function(){return t}},Zo=function(t,e,n){this.target=t,this.type=e,this.selection=n};function Jo(){pe.stopImmediatePropagation()}var Qo=function(){pe.preventDefault(),pe.stopImmediatePropagation()},ta={name:"drag"},ea={name:"space"},na={name:"handle"},ra={name:"center"};function ia(t){return[+t[0],+t[1]]}function oa(t){return[ia(t[0]),ia(t[1])]}var aa={name:"x",handles:["w","e"].map(pa),input:function(t,e){return null==t?null:[[+t[0],e[0][1]],[+t[1],e[1][1]]]},output:function(t){return t&&[t[0][0],t[1][0]]}},sa={name:"y",handles:["n","s"].map(pa),input:function(t,e){return null==t?null:[[e[0][0],+t[0]],[e[1][0],+t[1]]]},output:function(t){return t&&[t[0][1],t[1][1]]}},ua={name:"xy",handles:["n","w","e","s","nw","ne","sw","se"].map(pa),input:function(t){return null==t?null:oa(t)},output:function(t){return t}},ca={overlay:"crosshair",selection:"move",n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},fa={e:"w",w:"e",nw:"ne",ne:"nw",se:"sw",sw:"se"},la={n:"s",s:"n",nw:"sw",ne:"se",se:"ne",sw:"nw"},ha={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},da={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1};function pa(t){return{type:t}}function ga(){return!pe.ctrlKey&&!pe.button}function ya(){var t=this.ownerSVGElement||this;return t.hasAttribute("viewBox")?[[(t=t.viewBox.baseVal).x,t.y],[t.x+t.width,t.y+t.height]]:[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]}function ba(){return navigator.maxTouchPoints||"ontouchstart"in this}function ma(t){for(;!t.__brush;)if(!(t=t.parentNode))return;return t.__brush}function va(t){var e=t.__brush;return e?e.dim.output(e.selection):null}function _a(){return ka(aa)}function wa(){return ka(sa)}var xa=function(){return ka(ua)};function ka(t){var e,n=ya,r=ga,i=ba,o=!0,a=gt(u,"start","brush","end"),s=6;function u(e){var n=e.property("__brush",g).selectAll(".overlay").data([pa("overlay")]);n.enter().append("rect").attr("class","overlay").attr("pointer-events","all").attr("cursor",ca.overlay).merge(n).each((function(){var t=ma(this).extent;Me(this).attr("x",t[0][0]).attr("y",t[0][1]).attr("width",t[1][0]-t[0][0]).attr("height",t[1][1]-t[0][1])})),e.selectAll(".selection").data([pa("selection")]).enter().append("rect").attr("class","selection").attr("cursor",ca.selection).attr("fill","#777").attr("fill-opacity",.3).attr("stroke","#fff").attr("shape-rendering","crispEdges");var r=e.selectAll(".handle").data(t.handles,(function(t){return t.type}));r.exit().remove(),r.enter().append("rect").attr("class",(function(t){return"handle handle--"+t.type})).attr("cursor",(function(t){return ca[t.type]})),e.each(c).attr("fill","none").attr("pointer-events","all").on("mousedown.brush",h).filter(i).on("touchstart.brush",h).on("touchmove.brush",d).on("touchend.brush touchcancel.brush",p).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function c(){var t=Me(this),e=ma(this).selection;e?(t.selectAll(".selection").style("display",null).attr("x",e[0][0]).attr("y",e[0][1]).attr("width",e[1][0]-e[0][0]).attr("height",e[1][1]-e[0][1]),t.selectAll(".handle").style("display",null).attr("x",(function(t){return"e"===t.type[t.type.length-1]?e[1][0]-s/2:e[0][0]-s/2})).attr("y",(function(t){return"s"===t.type[0]?e[1][1]-s/2:e[0][1]-s/2})).attr("width",(function(t){return"n"===t.type||"s"===t.type?e[1][0]-e[0][0]+s:s})).attr("height",(function(t){return"e"===t.type||"w"===t.type?e[1][1]-e[0][1]+s:s}))):t.selectAll(".selection,.handle").style("display","none").attr("x",null).attr("y",null).attr("width",null).attr("height",null)}function f(t,e,n){return!n&&t.__brush.emitter||new l(t,e)}function l(t,e){this.that=t,this.args=e,this.state=t.__brush,this.active=0}function h(){if((!e||pe.touches)&&r.apply(this,arguments)){var n,i,a,s,u,l,h,d,p,g,y,b,m=this,v=pe.target.__data__.type,_="selection"===(o&&pe.metaKey?v="overlay":v)?ta:o&&pe.altKey?ra:na,w=t===sa?null:ha[v],x=t===aa?null:da[v],k=ma(m),E=k.extent,A=k.selection,S=E[0][0],T=E[0][1],M=E[1][0],D=E[1][1],C=0,O=0,R=w&&x&&o&&pe.shiftKey,I=pe.touches?(b=pe.changedTouches[0].identifier,function(t){return Pe(t,pe.touches,b)}):Be,N=I(m),B=N,L=f(m,arguments,!0).beforestart();"overlay"===v?(A&&(p=!0),k.selection=A=[[n=t===sa?S:N[0],a=t===aa?T:N[1]],[u=t===sa?M:n,h=t===aa?D:a]]):(n=A[0][0],a=A[0][1],u=A[1][0],h=A[1][1]),i=n,s=a,l=u,d=h;var P=Me(m).attr("pointer-events","none"),F=P.selectAll(".overlay").attr("cursor",ca[v]);if(pe.touches)L.moved=j,L.ended=z;else{var q=Me(pe.view).on("mousemove.brush",j,!0).on("mouseup.brush",z,!0);o&&q.on("keydown.brush",(function(){switch(pe.keyCode){case 16:R=w&&x;break;case 18:_===na&&(w&&(u=l-C*w,n=i+C*w),x&&(h=d-O*x,a=s+O*x),_=ra,U());break;case 32:_!==na&&_!==ra||(w<0?u=l-C:w>0&&(n=i-C),x<0?h=d-O:x>0&&(a=s-O),_=ea,F.attr("cursor",ca.selection),U());break;default:return}Qo()}),!0).on("keyup.brush",(function(){switch(pe.keyCode){case 16:R&&(g=y=R=!1,U());break;case 18:_===ra&&(w<0?u=l:w>0&&(n=i),x<0?h=d:x>0&&(a=s),_=na,U());break;case 32:_===ea&&(pe.altKey?(w&&(u=l-C*w,n=i+C*w),x&&(h=d-O*x,a=s+O*x),_=ra):(w<0?u=l:w>0&&(n=i),x<0?h=d:x>0&&(a=s),_=na),F.attr("cursor",ca[v]),U());break;default:return}Qo()}),!0),Ue(pe.view)}Jo(),Oi(m),c.call(m),L.start()}function j(){var t=I(m);!R||g||y||(Math.abs(t[0]-B[0])>Math.abs(t[1]-B[1])?y=!0:g=!0),B=t,p=!0,Qo(),U()}function U(){var t;switch(C=B[0]-N[0],O=B[1]-N[1],_){case ea:case ta:w&&(C=Math.max(S-n,Math.min(M-u,C)),i=n+C,l=u+C),x&&(O=Math.max(T-a,Math.min(D-h,O)),s=a+O,d=h+O);break;case na:w<0?(C=Math.max(S-n,Math.min(M-n,C)),i=n+C,l=u):w>0&&(C=Math.max(S-u,Math.min(M-u,C)),i=n,l=u+C),x<0?(O=Math.max(T-a,Math.min(D-a,O)),s=a+O,d=h):x>0&&(O=Math.max(T-h,Math.min(D-h,O)),s=a,d=h+O);break;case ra:w&&(i=Math.max(S,Math.min(M,n-C*w)),l=Math.max(S,Math.min(M,u+C*w))),x&&(s=Math.max(T,Math.min(D,a-O*x)),d=Math.max(T,Math.min(D,h+O*x)))}l1e-6)if(Math.abs(f*s-u*c)>1e-6&&i){var h=n-o,d=r-a,p=s*s+u*u,g=h*h+d*d,y=Math.sqrt(p),b=Math.sqrt(l),m=i*Math.tan((Na-Math.acos((p+l-g)/(2*y*b)))/2),v=m/b,_=m/y;Math.abs(v-1)>1e-6&&(this._+="L"+(t+v*c)+","+(e+v*f)),this._+="A"+i+","+i+",0,0,"+ +(f*h>c*d)+","+(this._x1=t+_*s)+","+(this._y1=e+_*u)}else this._+="L"+(this._x1=t)+","+(this._y1=e);else;},arc:function(t,e,n,r,i,o){t=+t,e=+e,o=!!o;var a=(n=+n)*Math.cos(r),s=n*Math.sin(r),u=t+a,c=e+s,f=1^o,l=o?r-i:i-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+u+","+c:(Math.abs(this._x1-u)>1e-6||Math.abs(this._y1-c)>1e-6)&&(this._+="L"+u+","+c),n&&(l<0&&(l=l%Ba+Ba),l>La?this._+="A"+n+","+n+",0,1,"+f+","+(t-a)+","+(e-s)+"A"+n+","+n+",0,1,"+f+","+(this._x1=u)+","+(this._y1=c):l>1e-6&&(this._+="A"+n+","+n+",0,"+ +(l>=Na)+","+f+","+(this._x1=t+n*Math.cos(i))+","+(this._y1=e+n*Math.sin(i))))},rect:function(t,e,n,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};var qa=Fa;function ja(t){return t.source}function Ua(t){return t.target}function za(t){return t.radius}function Ya(t){return t.startAngle}function Va(t){return t.endAngle}var Ha=function(){var t=ja,e=Ua,n=za,r=Ya,i=Va,o=null;function a(){var a,s=Ra.call(arguments),u=t.apply(this,s),c=e.apply(this,s),f=+n.apply(this,(s[0]=u,s)),l=r.apply(this,s)-Ta,h=i.apply(this,s)-Ta,d=f*Ea(l),p=f*Aa(l),g=+n.apply(this,(s[0]=c,s)),y=r.apply(this,s)-Ta,b=i.apply(this,s)-Ta;if(o||(o=a=qa()),o.moveTo(d,p),o.arc(0,0,f,l,h),l===y&&h===b||(o.quadraticCurveTo(0,0,g*Ea(y),g*Aa(y)),o.arc(0,0,g,y,b)),o.quadraticCurveTo(0,0,d,p),o.closePath(),a)return o=null,a+""||null}return a.radius=function(t){return arguments.length?(n="function"==typeof t?t:Ia(+t),a):n},a.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:Ia(+t),a):r},a.endAngle=function(t){return arguments.length?(i="function"==typeof t?t:Ia(+t),a):i},a.source=function(e){return arguments.length?(t=e,a):t},a.target=function(t){return arguments.length?(e=t,a):e},a.context=function(t){return arguments.length?(o=null==t?null:t,a):o},a};function $a(){}function Ga(t,e){var n=new $a;if(t instanceof $a)t.each((function(t,e){n.set(e,t)}));else if(Array.isArray(t)){var r,i=-1,o=t.length;if(null==e)for(;++i=r.length)return null!=t&&n.sort(t),null!=e?e(n):n;for(var u,c,f,l=-1,h=n.length,d=r[i++],p=Wa(),g=a();++lr.length)return n;var a,s=i[o-1];return null!=e&&o>=r.length?a=n.entries():(a=[],n.each((function(e,n){a.push({key:n,values:t(e,o)})}))),null!=s?a.sort((function(t,e){return s(t.key,e.key)})):a}(o(t,0,Ja,Qa),0)},key:function(t){return r.push(t),n},sortKeys:function(t){return i[r.length-1]=t,n},sortValues:function(e){return t=e,n},rollup:function(t){return e=t,n}}};function Xa(){return{}}function Za(t,e,n){t[e]=n}function Ja(){return Wa()}function Qa(t,e,n){t.set(e,n)}function ts(){}var es=Wa.prototype;function ns(t,e){var n=new ts;if(t instanceof ts)t.each((function(t){n.add(t)}));else if(t){var r=-1,i=t.length;if(null==e)for(;++rr!=d>r&&n<(h-c)*(r-f)/(d-f)+c&&(i=-i)}return i}function ds(t,e,n){var r,i,o,a;return function(t,e,n){return(e[0]-t[0])*(n[1]-t[1])==(n[0]-t[0])*(e[1]-t[1])}(t,e,n)&&(i=t[r=+(t[0]===e[0])],o=n[r],a=e[r],i<=o&&o<=a||a<=o&&o<=i)}var ps=function(){},gs=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]],ys=function(){var t=1,e=1,n=D,r=s;function i(t){var e=n(t);if(Array.isArray(e))e=e.slice().sort(us);else{var r=y(t),i=r[0],a=r[1];e=M(i,a,e),e=x(Math.floor(i/e)*e,Math.floor(a/e)*e,e)}return e.map((function(e){return o(t,e)}))}function o(n,i){var o=[],s=[];return function(n,r,i){var o,s,u,c,f,l,h=new Array,d=new Array;o=s=-1,c=n[0]>=r,gs[c<<1].forEach(p);for(;++o=r,gs[u|c<<1].forEach(p);gs[c<<0].forEach(p);for(;++s=r,f=n[s*t]>=r,gs[c<<1|f<<2].forEach(p);++o=r,l=f,f=n[s*t+o+1]>=r,gs[u|c<<1|f<<2|l<<3].forEach(p);gs[c|f<<3].forEach(p)}o=-1,f=n[s*t]>=r,gs[f<<2].forEach(p);for(;++o=r,gs[f<<2|l<<3].forEach(p);function p(t){var e,n,r=[t[0][0]+o,t[0][1]+s],u=[t[1][0]+o,t[1][1]+s],c=a(r),f=a(u);(e=d[c])?(n=h[f])?(delete d[e.end],delete h[n.start],e===n?(e.ring.push(u),i(e.ring)):h[e.start]=d[n.end]={start:e.start,end:n.end,ring:e.ring.concat(n.ring)}):(delete d[e.end],e.ring.push(u),d[e.end=f]=e):(e=h[f])?(n=d[c])?(delete h[e.start],delete d[n.end],e===n?(e.ring.push(u),i(e.ring)):h[n.start]=d[e.end]={start:n.start,end:e.end,ring:n.ring.concat(e.ring)}):(delete h[e.start],e.ring.unshift(r),h[e.start=c]=e):h[c]=d[f]={start:c,end:f,ring:[r,u]}}gs[f<<3].forEach(p)}(n,i,(function(t){r(t,n,i),cs(t)>0?o.push([t]):s.push(t)})),s.forEach((function(t){for(var e,n=0,r=o.length;n0&&a0&&s0&&o>0))throw new Error("invalid size");return t=r,e=o,i},i.thresholds=function(t){return arguments.length?(n="function"==typeof t?t:Array.isArray(t)?fs(ss.call(t)):fs(t),i):n},i.smooth=function(t){return arguments.length?(r=t?s:ps,i):r===s},i};function bs(t,e,n){for(var r=t.width,i=t.height,o=1+(n<<1),a=0;a=n&&(s>=o&&(u-=t.data[s-o+a*r]),e.data[s-n+a*r]=u/Math.min(s+1,r-1+o-s,o))}function ms(t,e,n){for(var r=t.width,i=t.height,o=1+(n<<1),a=0;a=n&&(s>=o&&(u-=t.data[a+(s-o)*r]),e.data[a+(s-n)*r]=u/Math.min(s+1,i-1+o-s,o))}function vs(t){return t[0]}function _s(t){return t[1]}function ws(){return 1}var xs=function(){var t=vs,e=_s,n=ws,r=960,i=500,o=20,a=2,s=3*o,u=r+2*s>>a,c=i+2*s>>a,f=fs(20);function l(r){var i=new Float32Array(u*c),l=new Float32Array(u*c);r.forEach((function(r,o,f){var l=+t(r,o,f)+s>>a,h=+e(r,o,f)+s>>a,d=+n(r,o,f);l>=0&&l=0&&h>a),ms({width:u,height:c,data:l},{width:u,height:c,data:i},o>>a),bs({width:u,height:c,data:i},{width:u,height:c,data:l},o>>a),ms({width:u,height:c,data:l},{width:u,height:c,data:i},o>>a),bs({width:u,height:c,data:i},{width:u,height:c,data:l},o>>a),ms({width:u,height:c,data:l},{width:u,height:c,data:i},o>>a);var d=f(i);if(!Array.isArray(d)){var p=N(i);d=M(0,p,d),(d=x(0,Math.floor(p/d)*d,d)).shift()}return ys().thresholds(d).size([u,c])(i).map(h)}function h(t){return t.value*=Math.pow(2,-2*a),t.coordinates.forEach(d),t}function d(t){t.forEach(p)}function p(t){t.forEach(g)}function g(t){t[0]=t[0]*Math.pow(2,a)-s,t[1]=t[1]*Math.pow(2,a)-s}function y(){return u=r+2*(s=3*o)>>a,c=i+2*s>>a,l}return l.x=function(e){return arguments.length?(t="function"==typeof e?e:fs(+e),l):t},l.y=function(t){return arguments.length?(e="function"==typeof t?t:fs(+t),l):e},l.weight=function(t){return arguments.length?(n="function"==typeof t?t:fs(+t),l):n},l.size=function(t){if(!arguments.length)return[r,i];var e=Math.ceil(t[0]),n=Math.ceil(t[1]);if(!(e>=0||e>=0))throw new Error("invalid size");return r=e,i=n,y()},l.cellSize=function(t){if(!arguments.length)return 1<=1))throw new Error("invalid cell size");return a=Math.floor(Math.log(t)/Math.LN2),y()},l.thresholds=function(t){return arguments.length?(f="function"==typeof t?t:Array.isArray(t)?fs(ss.call(t)):fs(t),l):f},l.bandwidth=function(t){if(!arguments.length)return Math.sqrt(o*(o+1));if(!((t=+t)>=0))throw new Error("invalid bandwidth");return o=Math.round((Math.sqrt(4*t*t+1)-1)/2),y()},l},ks={},Es={},As=34,Ss=10,Ts=13;function Ms(t){return new Function("d","return {"+t.map((function(t,e){return JSON.stringify(t)+": d["+e+"]"})).join(",")+"}")}function Ds(t){var e=Object.create(null),n=[];return t.forEach((function(t){for(var r in t)r in e||n.push(e[r]=r)})),n}function Cs(t,e){var n=t+"",r=n.length;return r9999?"+"+Cs(e,6):Cs(e,4))+"-"+Cs(t.getUTCMonth()+1,2)+"-"+Cs(t.getUTCDate(),2)+(o?"T"+Cs(n,2)+":"+Cs(r,2)+":"+Cs(i,2)+"."+Cs(o,3)+"Z":i?"T"+Cs(n,2)+":"+Cs(r,2)+":"+Cs(i,2)+"Z":r||n?"T"+Cs(n,2)+":"+Cs(r,2)+"Z":"")}var Rs=function(t){var e=new RegExp('["'+t+"\n\r]"),n=t.charCodeAt(0);function r(t,e){var r,i=[],o=t.length,a=0,s=0,u=o<=0,c=!1;function f(){if(u)return Es;if(c)return c=!1,ks;var e,r,i=a;if(t.charCodeAt(i)===As){for(;a++=o?u=!0:(r=t.charCodeAt(a++))===Ss?c=!0:r===Ts&&(c=!0,t.charCodeAt(a)===Ss&&++a),t.slice(i+1,e-1).replace(/""/g,'"')}for(;a=(o=(g+b)/2))?g=o:b=o,(f=n>=(a=(y+m)/2))?y=a:m=a,i=d,!(d=d[l=f<<1|c]))return i[l]=p,t;if(s=+t._x.call(null,d.data),u=+t._y.call(null,d.data),e===s&&n===u)return p.next=d,i?i[l]=p:t._root=p,t;do{i=i?i[l]=new Array(4):t._root=new Array(4),(c=e>=(o=(g+b)/2))?g=o:b=o,(f=n>=(a=(y+m)/2))?y=a:m=a}while((l=f<<1|c)==(h=(u>=a)<<1|s>=o));return i[h]=d,i[l]=p,t}var du=function(t,e,n,r,i){this.node=t,this.x0=e,this.y0=n,this.x1=r,this.y1=i};function pu(t){return t[0]}function gu(t){return t[1]}function yu(t,e,n){var r=new bu(null==e?pu:e,null==n?gu:n,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function bu(t,e,n,r,i,o){this._x=t,this._y=e,this._x0=n,this._y0=r,this._x1=i,this._y1=o,this._root=void 0}function mu(t){for(var e={data:t.data},n=e;t=t.next;)n=n.next={data:t.data};return e}var vu=yu.prototype=bu.prototype;function _u(t){return t.x+t.vx}function wu(t){return t.y+t.vy}vu.copy=function(){var t,e,n=new bu(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return n;if(!r.length)return n._root=mu(r),n;for(t=[{source:r,target:n._root=new Array(4)}];r=t.pop();)for(var i=0;i<4;++i)(e=r.source[i])&&(e.length?t.push({source:e,target:r.target[i]=new Array(4)}):r.target[i]=mu(e));return n},vu.add=function(t){var e=+this._x.call(null,t),n=+this._y.call(null,t);return hu(this.cover(e,n),e,n,t)},vu.addAll=function(t){var e,n,r,i,o=t.length,a=new Array(o),s=new Array(o),u=1/0,c=1/0,f=-1/0,l=-1/0;for(n=0;nf&&(f=r),il&&(l=i));if(u>f||c>l)return this;for(this.cover(u,c).cover(f,l),n=0;nt||t>=i||r>e||e>=o;)switch(s=(eh||(o=u.y0)>d||(a=u.x1)=b)<<1|t>=y)&&(u=p[p.length-1],p[p.length-1]=p[p.length-1-c],p[p.length-1-c]=u)}else{var m=t-+this._x.call(null,g.data),v=e-+this._y.call(null,g.data),_=m*m+v*v;if(_=(s=(p+y)/2))?p=s:y=s,(f=a>=(u=(g+b)/2))?g=u:b=u,e=d,!(d=d[l=f<<1|c]))return this;if(!d.length)break;(e[l+1&3]||e[l+2&3]||e[l+3&3])&&(n=e,h=l)}for(;d.data!==t;)if(r=d,!(d=d.next))return this;return(i=d.next)&&delete d.next,r?(i?r.next=i:delete r.next,this):e?(i?e[l]=i:delete e[l],(d=e[0]||e[1]||e[2]||e[3])&&d===(e[3]||e[2]||e[1]||e[0])&&!d.length&&(n?n[h]=d:this._root=d),this):(this._root=i,this)},vu.removeAll=function(t){for(var e=0,n=t.length;eu+d||ic+d||os.index){var p=u-a.x-a.vx,g=c-a.y-a.vy,y=p*p+g*g;yt.r&&(t.r=t[e].r)}function s(){if(e){var r,i,o=e.length;for(n=new Array(o),r=0;r1?(null==n?s.remove(t):s.set(t,d(n)),e):s.get(t)},find:function(e,n,r){var i,o,a,s,u,c=0,f=t.length;for(null==r?r=1/0:r*=r,c=0;c1?(c.on(t,n),e):c.on(t)}}},Ou=function(){var t,e,n,r,i=fu(-30),o=1,a=1/0,s=.81;function u(r){var i,o=t.length,a=yu(t,Su,Tu).visitAfter(f);for(n=r,i=0;i=a)){(t.data!==e||t.next)&&(0===f&&(d+=(f=lu())*f),0===l&&(d+=(l=lu())*l),d1?r[0]+r.slice(2):r,+t.slice(n+1)]},Lu=function(t){return(t=Bu(Math.abs(t)))?t[1]:NaN},Pu=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Fu(t){if(!(e=Pu.exec(t)))throw new Error("invalid format: "+t);var e;return new qu({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function qu(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}Fu.prototype=qu.prototype,qu.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};var ju,Uu,zu,Yu,Vu=function(t){t:for(var e,n=t.length,r=1,i=-1;r0){if(!+t[r])break t;i=0}}return i>0?t.slice(0,i)+t.slice(e+1):t},Hu=function(t,e){var n=Bu(t,e);if(!n)return t+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")},$u={"%":function(t,e){return(100*t).toFixed(e)},b:function(t){return Math.round(t).toString(2)},c:function(t){return t+""},d:function(t){return Math.round(t).toString(10)},e:function(t,e){return t.toExponential(e)},f:function(t,e){return t.toFixed(e)},g:function(t,e){return t.toPrecision(e)},o:function(t){return Math.round(t).toString(8)},p:function(t,e){return Hu(100*t,e)},r:Hu,s:function(t,e){var n=Bu(t,e);if(!n)return t+"";var r=n[0],i=n[1],o=i-(ju=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,a=r.length;return o===a?r:o>a?r+new Array(o-a+1).join("0"):o>0?r.slice(0,o)+"."+r.slice(o):"0."+new Array(1-o).join("0")+Bu(t,Math.max(0,e+o-1))[0]},X:function(t){return Math.round(t).toString(16).toUpperCase()},x:function(t){return Math.round(t).toString(16)}},Gu=function(t){return t},Wu=Array.prototype.map,Ku=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"],Xu=function(t){var e,n,r=void 0===t.grouping||void 0===t.thousands?Gu:(e=Wu.call(t.grouping,Number),n=t.thousands+"",function(t,r){for(var i=t.length,o=[],a=0,s=e[0],u=0;i>0&&s>0&&(u+s+1>r&&(s=Math.max(1,r-u)),o.push(t.substring(i-=s,i+s)),!((u+=s+1)>r));)s=e[a=(a+1)%e.length];return o.reverse().join(n)}),i=void 0===t.currency?"":t.currency[0]+"",o=void 0===t.currency?"":t.currency[1]+"",a=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?Gu:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(Wu.call(t.numerals,String)),u=void 0===t.percent?"%":t.percent+"",c=void 0===t.minus?"-":t.minus+"",f=void 0===t.nan?"NaN":t.nan+"";function l(t){var e=(t=Fu(t)).fill,n=t.align,l=t.sign,h=t.symbol,d=t.zero,p=t.width,g=t.comma,y=t.precision,b=t.trim,m=t.type;"n"===m?(g=!0,m="g"):$u[m]||(void 0===y&&(y=12),b=!0,m="g"),(d||"0"===e&&"="===n)&&(d=!0,e="0",n="=");var v="$"===h?i:"#"===h&&/[boxX]/.test(m)?"0"+m.toLowerCase():"",_="$"===h?o:/[%p]/.test(m)?u:"",w=$u[m],x=/[defgprs%]/.test(m);function k(t){var i,o,u,h=v,k=_;if("c"===m)k=w(t)+k,t="";else{var E=(t=+t)<0;if(t=isNaN(t)?f:w(Math.abs(t),y),b&&(t=Vu(t)),E&&0==+t&&(E=!1),h=(E?"("===l?l:c:"-"===l||"("===l?"":l)+h,k=("s"===m?Ku[8+ju/3]:"")+k+(E&&"("===l?")":""),x)for(i=-1,o=t.length;++i(u=t.charCodeAt(i))||u>57){k=(46===u?a+t.slice(i+1):t.slice(i))+k,t=t.slice(0,i);break}}g&&!d&&(t=r(t,1/0));var A=h.length+t.length+k.length,S=A>1)+h+t+k+S.slice(A);break;default:t=S+h+t+k}return s(t)}return y=void 0===y?6:/[gprs]/.test(m)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y)),k.toString=function(){return t+""},k}return{format:l,formatPrefix:function(t,e){var n=l(((t=Fu(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(Lu(e)/3))),i=Math.pow(10,-r),o=Ku[8+r/3];return function(t){return n(i*t)+o}}}};function Zu(t){return Uu=Xu(t),zu=Uu.format,Yu=Uu.formatPrefix,Uu}Zu({decimal:".",thousands:",",grouping:[3],currency:["$",""],minus:"-"});var Ju=function(t){return Math.max(0,-Lu(Math.abs(t)))},Qu=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(Lu(e)/3)))-Lu(Math.abs(t)))},tc=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,Lu(e)-Lu(t))+1},ec=function(){return new nc};function nc(){this.reset()}nc.prototype={constructor:nc,reset:function(){this.s=this.t=0},add:function(t){ic(rc,t,this.t),ic(this,rc.s,this.s),this.s?this.t+=rc.t:this.s=rc.t},valueOf:function(){return this.s}};var rc=new nc;function ic(t,e,n){var r=t.s=e+n,i=r-e,o=r-i;t.t=e-o+(n-i)}var oc=1e-6,ac=1e-12,sc=Math.PI,uc=sc/2,cc=sc/4,fc=2*sc,lc=180/sc,hc=sc/180,dc=Math.abs,pc=Math.atan,gc=Math.atan2,yc=Math.cos,bc=Math.ceil,mc=Math.exp,vc=(Math.floor,Math.log),_c=Math.pow,wc=Math.sin,xc=Math.sign||function(t){return t>0?1:t<0?-1:0},kc=Math.sqrt,Ec=Math.tan;function Ac(t){return t>1?0:t<-1?sc:Math.acos(t)}function Sc(t){return t>1?uc:t<-1?-uc:Math.asin(t)}function Tc(t){return(t=wc(t/2))*t}function Mc(){}function Dc(t,e){t&&Oc.hasOwnProperty(t.type)&&Oc[t.type](t,e)}var Cc={Feature:function(t,e){Dc(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,o=yc(e=(e*=hc)/2+cc),a=wc(e),s=Fc*a,u=Pc*o+s*yc(i),c=s*r*wc(i);jc.add(gc(c,u)),Lc=t,Pc=o,Fc=a}var Gc=function(t){return Uc.reset(),qc(t,zc),2*Uc};function Wc(t){return[gc(t[1],t[0]),Sc(t[2])]}function Kc(t){var e=t[0],n=t[1],r=yc(n);return[r*yc(e),r*wc(e),wc(n)]}function Xc(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function Zc(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function Jc(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function Qc(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function tf(t){var e=kc(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}var ef,nf,rf,of,af,sf,uf,cf,ff,lf,hf=ec(),df={point:pf,lineStart:yf,lineEnd:bf,polygonStart:function(){df.point=mf,df.lineStart=vf,df.lineEnd=_f,hf.reset(),zc.polygonStart()},polygonEnd:function(){zc.polygonEnd(),df.point=pf,df.lineStart=yf,df.lineEnd=bf,jc<0?(ef=-(rf=180),nf=-(of=90)):hf>oc?of=90:hf<-oc&&(nf=-90),lf[0]=ef,lf[1]=rf},sphere:function(){ef=-(rf=180),nf=-(of=90)}};function pf(t,e){ff.push(lf=[ef=t,rf=t]),eof&&(of=e)}function gf(t,e){var n=Kc([t*hc,e*hc]);if(cf){var r=Zc(cf,n),i=Zc([r[1],-r[0],0],r);tf(i),i=Wc(i);var o,a=t-af,s=a>0?1:-1,u=i[0]*lc*s,c=dc(a)>180;c^(s*afof&&(of=o):c^(s*af<(u=(u+360)%360-180)&&uof&&(of=e)),c?twf(ef,rf)&&(rf=t):wf(t,rf)>wf(ef,rf)&&(ef=t):rf>=ef?(trf&&(rf=t)):t>af?wf(ef,t)>wf(ef,rf)&&(rf=t):wf(t,rf)>wf(ef,rf)&&(ef=t)}else ff.push(lf=[ef=t,rf=t]);eof&&(of=e),cf=n,af=t}function yf(){df.point=gf}function bf(){lf[0]=ef,lf[1]=rf,df.point=pf,cf=null}function mf(t,e){if(cf){var n=t-af;hf.add(dc(n)>180?n+(n>0?360:-360):n)}else sf=t,uf=e;zc.point(t,e),gf(t,e)}function vf(){zc.lineStart()}function _f(){mf(sf,uf),zc.lineEnd(),dc(hf)>oc&&(ef=-(rf=180)),lf[0]=ef,lf[1]=rf,cf=null}function wf(t,e){return(e-=t)<0?e+360:e}function xf(t,e){return t[0]-e[0]}function kf(t,e){return t[0]<=t[1]?t[0]<=e&&e<=t[1]:ewf(r[0],r[1])&&(r[1]=i[1]),wf(i[0],r[1])>wf(r[0],r[1])&&(r[0]=i[0])):o.push(r=i);for(a=-1/0,e=0,r=o[n=o.length-1];e<=n;r=i,++e)i=o[e],(s=wf(r[1],i[0]))>a&&(a=s,ef=i[0],rf=r[1])}return ff=lf=null,ef===1/0||nf===1/0?[[NaN,NaN],[NaN,NaN]]:[[ef,nf],[rf,of]]},Uf={sphere:Mc,point:zf,lineStart:Vf,lineEnd:Gf,polygonStart:function(){Uf.lineStart=Wf,Uf.lineEnd=Kf},polygonEnd:function(){Uf.lineStart=Vf,Uf.lineEnd=Gf}};function zf(t,e){t*=hc;var n=yc(e*=hc);Yf(n*yc(t),n*wc(t),wc(e))}function Yf(t,e,n){Sf+=(t-Sf)/++Ef,Tf+=(e-Tf)/Ef,Mf+=(n-Mf)/Ef}function Vf(){Uf.point=Hf}function Hf(t,e){t*=hc;var n=yc(e*=hc);Pf=n*yc(t),Ff=n*wc(t),qf=wc(e),Uf.point=$f,Yf(Pf,Ff,qf)}function $f(t,e){t*=hc;var n=yc(e*=hc),r=n*yc(t),i=n*wc(t),o=wc(e),a=gc(kc((a=Ff*o-qf*i)*a+(a=qf*r-Pf*o)*a+(a=Pf*i-Ff*r)*a),Pf*r+Ff*i+qf*o);Af+=a,Df+=a*(Pf+(Pf=r)),Cf+=a*(Ff+(Ff=i)),Of+=a*(qf+(qf=o)),Yf(Pf,Ff,qf)}function Gf(){Uf.point=zf}function Wf(){Uf.point=Xf}function Kf(){Zf(Bf,Lf),Uf.point=zf}function Xf(t,e){Bf=t,Lf=e,t*=hc,e*=hc,Uf.point=Zf;var n=yc(e);Pf=n*yc(t),Ff=n*wc(t),qf=wc(e),Yf(Pf,Ff,qf)}function Zf(t,e){t*=hc;var n=yc(e*=hc),r=n*yc(t),i=n*wc(t),o=wc(e),a=Ff*o-qf*i,s=qf*r-Pf*o,u=Pf*i-Ff*r,c=kc(a*a+s*s+u*u),f=Sc(c),l=c&&-f/c;Rf+=l*a,If+=l*s,Nf+=l*u,Af+=f,Df+=f*(Pf+(Pf=r)),Cf+=f*(Ff+(Ff=i)),Of+=f*(qf+(qf=o)),Yf(Pf,Ff,qf)}var Jf=function(t){Ef=Af=Sf=Tf=Mf=Df=Cf=Of=Rf=If=Nf=0,qc(t,Uf);var e=Rf,n=If,r=Nf,i=e*e+n*n+r*r;return isc?t+Math.round(-t/fc)*fc:t,e]}function nl(t,e,n){return(t%=fc)?e||n?tl(il(t),ol(e,n)):il(t):e||n?ol(e,n):el}function rl(t){return function(e,n){return[(e+=t)>sc?e-fc:e<-sc?e+fc:e,n]}}function il(t){var e=rl(t);return e.invert=rl(-t),e}function ol(t,e){var n=yc(t),r=wc(t),i=yc(e),o=wc(e);function a(t,e){var a=yc(e),s=yc(t)*a,u=wc(t)*a,c=wc(e),f=c*n+s*r;return[gc(u*i-f*o,s*n-c*r),Sc(f*i+u*o)]}return a.invert=function(t,e){var a=yc(e),s=yc(t)*a,u=wc(t)*a,c=wc(e),f=c*i-u*o;return[gc(u*i+c*o,s*n+f*r),Sc(f*n-s*r)]},a}el.invert=el;var al=function(t){function e(e){return(e=t(e[0]*hc,e[1]*hc))[0]*=lc,e[1]*=lc,e}return t=nl(t[0]*hc,t[1]*hc,t.length>2?t[2]*hc:0),e.invert=function(e){return(e=t.invert(e[0]*hc,e[1]*hc))[0]*=lc,e[1]*=lc,e},e};function sl(t,e,n,r,i,o){if(n){var a=yc(e),s=wc(e),u=r*n;null==i?(i=e+r*fc,o=e-u/2):(i=ul(a,i),o=ul(a,o),(r>0?io)&&(i+=r*fc));for(var c,f=i;r>0?f>o:f1&&e.push(e.pop().concat(e.shift()))},result:function(){var n=e;return e=[],t=null,n}}},ll=function(t,e){return dc(t[0]-e[0])=0;--o)i.point((f=c[o])[0],f[1]);else r(h.x,h.p.x,-1,i);h=h.p}c=(h=h.o).z,d=!d}while(!h.v);i.lineEnd()}}};function pl(t){if(e=t.length){for(var e,n,r=0,i=t[0];++r=0?1:-1,A=E*k,S=A>sc,T=g*w;if(gl.add(gc(T*E*wc(A),y*x+T*yc(A))),a+=S?k+E*fc:k,S^d>=n^v>=n){var M=Zc(Kc(h),Kc(m));tf(M);var D=Zc(o,M);tf(D);var C=(S^k>=0?-1:1)*Sc(D[2]);(r>C||r===C&&(M[0]||M[1]))&&(s+=S^k>=0?1:-1)}}return(a<-oc||a0){for(l||(i.polygonStart(),l=!0),i.lineStart(),t=0;t1&&2&u&&h.push(h.pop().concat(h.shift())),a.push(h.filter(vl))}return h}};function vl(t){return t.length>1}function _l(t,e){return((t=t.x)[0]<0?t[1]-uc-oc:uc-t[1])-((e=e.x)[0]<0?e[1]-uc-oc:uc-e[1])}var wl=ml((function(){return!0}),(function(t){var e,n=NaN,r=NaN,i=NaN;return{lineStart:function(){t.lineStart(),e=1},point:function(o,a){var s=o>0?sc:-sc,u=dc(o-n);dc(u-sc)0?uc:-uc),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(s,r),t.point(o,r),e=0):i!==s&&u>=sc&&(dc(n-i)oc?pc((wc(e)*(o=yc(r))*wc(n)-wc(r)*(i=yc(e))*wc(t))/(i*o*a)):(e+r)/2}(n,r,o,a),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(s,r),e=0),t.point(n=o,r=a),i=s},lineEnd:function(){t.lineEnd(),n=r=NaN},clean:function(){return 2-e}}}),(function(t,e,n,r){var i;if(null==t)i=n*uc,r.point(-sc,i),r.point(0,i),r.point(sc,i),r.point(sc,0),r.point(sc,-i),r.point(0,-i),r.point(-sc,-i),r.point(-sc,0),r.point(-sc,i);else if(dc(t[0]-e[0])>oc){var o=t[0]0,i=dc(e)>oc;function o(t,n){return yc(t)*yc(n)>e}function a(t,n,r){var i=[1,0,0],o=Zc(Kc(t),Kc(n)),a=Xc(o,o),s=o[0],u=a-s*s;if(!u)return!r&&t;var c=e*a/u,f=-e*s/u,l=Zc(i,o),h=Qc(i,c);Jc(h,Qc(o,f));var d=l,p=Xc(h,d),g=Xc(d,d),y=p*p-g*(Xc(h,h)-1);if(!(y<0)){var b=kc(y),m=Qc(d,(-p-b)/g);if(Jc(m,h),m=Wc(m),!r)return m;var v,_=t[0],w=n[0],x=t[1],k=n[1];w<_&&(v=_,_=w,w=v);var E=w-_,A=dc(E-sc)0^m[1]<(dc(m[0]-_)sc^(_<=m[0]&&m[0]<=w)){var S=Qc(d,(-p+b)/g);return Jc(S,h),[m,Wc(S)]}}}function s(e,n){var i=r?t:sc-t,o=0;return e<-i?o|=1:e>i&&(o|=2),n<-i?o|=4:n>i&&(o|=8),o}return ml(o,(function(t){var e,n,u,c,f;return{lineStart:function(){c=u=!1,f=1},point:function(l,h){var d,p=[l,h],g=o(l,h),y=r?g?0:s(l,h):g?s(l+(l<0?sc:-sc),h):0;if(!e&&(c=u=g)&&t.lineStart(),g!==u&&(!(d=a(e,p))||ll(e,d)||ll(p,d))&&(p[0]+=oc,p[1]+=oc,g=o(p[0],p[1])),g!==u)f=0,g?(t.lineStart(),d=a(p,e),t.point(d[0],d[1])):(d=a(e,p),t.point(d[0],d[1]),t.lineEnd()),e=d;else if(i&&e&&r^g){var b;y&n||!(b=a(p,e,!0))||(f=0,r?(t.lineStart(),t.point(b[0][0],b[0][1]),t.point(b[1][0],b[1][1]),t.lineEnd()):(t.point(b[1][0],b[1][1]),t.lineEnd(),t.lineStart(),t.point(b[0][0],b[0][1])))}!g||e&&ll(e,p)||t.point(p[0],p[1]),e=p,u=g,n=y},lineEnd:function(){u&&t.lineEnd(),e=null},clean:function(){return f|(c&&u)<<1}}}),(function(e,r,i,o){sl(o,t,n,i,e,r)}),r?[0,-t]:[-sc,t-sc])},kl=function(t,e,n,r,i,o){var a,s=t[0],u=t[1],c=0,f=1,l=e[0]-s,h=e[1]-u;if(a=n-s,l||!(a>0)){if(a/=l,l<0){if(a0){if(a>f)return;a>c&&(c=a)}if(a=i-s,l||!(a<0)){if(a/=l,l<0){if(a>f)return;a>c&&(c=a)}else if(l>0){if(a0)){if(a/=h,h<0){if(a0){if(a>f)return;a>c&&(c=a)}if(a=o-u,h||!(a<0)){if(a/=h,h<0){if(a>f)return;a>c&&(c=a)}else if(h>0){if(a0&&(t[0]=s+c*l,t[1]=u+c*h),f<1&&(e[0]=s+f*l,e[1]=u+f*h),!0}}}}},El=1e9,Al=-El;function Sl(t,e,n,r){function i(i,o){return t<=i&&i<=n&&e<=o&&o<=r}function o(i,o,s,c){var f=0,l=0;if(null==i||(f=a(i,s))!==(l=a(o,s))||u(i,o)<0^s>0)do{c.point(0===f||3===f?t:n,f>1?r:e)}while((f=(f+s+4)%4)!==l);else c.point(o[0],o[1])}function a(r,i){return dc(r[0]-t)0?0:3:dc(r[0]-n)0?2:1:dc(r[1]-e)0?1:0:i>0?3:2}function s(t,e){return u(t.x,e.x)}function u(t,e){var n=a(t,1),r=a(e,1);return n!==r?n-r:0===n?e[1]-t[1]:1===n?t[0]-e[0]:2===n?t[1]-e[1]:e[0]-t[0]}return function(a){var u,c,f,l,h,d,p,g,y,b,m,v=a,_=fl(),w={point:x,lineStart:function(){w.point=k,c&&c.push(f=[]);b=!0,y=!1,p=g=NaN},lineEnd:function(){u&&(k(l,h),d&&y&&_.rejoin(),u.push(_.result()));w.point=x,y&&v.lineEnd()},polygonStart:function(){v=_,u=[],c=[],m=!0},polygonEnd:function(){var e=function(){for(var e=0,n=0,i=c.length;nr&&(h-o)*(r-a)>(d-a)*(t-o)&&++e:d<=r&&(h-o)*(r-a)<(d-a)*(t-o)&&--e;return e}(),n=m&&e,i=(u=P(u)).length;(n||i)&&(a.polygonStart(),n&&(a.lineStart(),o(null,null,1,a),a.lineEnd()),i&&dl(u,s,e,o,a),a.polygonEnd());v=a,u=c=f=null}};function x(t,e){i(t,e)&&v.point(t,e)}function k(o,a){var s=i(o,a);if(c&&f.push([o,a]),b)l=o,h=a,d=s,b=!1,s&&(v.lineStart(),v.point(o,a));else if(s&&y)v.point(o,a);else{var u=[p=Math.max(Al,Math.min(El,p)),g=Math.max(Al,Math.min(El,g))],_=[o=Math.max(Al,Math.min(El,o)),a=Math.max(Al,Math.min(El,a))];kl(u,_,t,e,n,r)?(y||(v.lineStart(),v.point(u[0],u[1])),v.point(_[0],_[1]),s||v.lineEnd(),m=!1):s&&(v.lineStart(),v.point(o,a),m=!1)}p=o,g=a,y=s}return w}}var Tl,Ml,Dl,Cl=function(){var t,e,n,r=0,i=0,o=960,a=500;return n={stream:function(n){return t&&e===n?t:t=Sl(r,i,o,a)(e=n)},extent:function(s){return arguments.length?(r=+s[0][0],i=+s[0][1],o=+s[1][0],a=+s[1][1],t=e=null,n):[[r,i],[o,a]]}}},Ol=ec(),Rl={sphere:Mc,point:Mc,lineStart:function(){Rl.point=Nl,Rl.lineEnd=Il},lineEnd:Mc,polygonStart:Mc,polygonEnd:Mc};function Il(){Rl.point=Rl.lineEnd=Mc}function Nl(t,e){Tl=t*=hc,Ml=wc(e*=hc),Dl=yc(e),Rl.point=Bl}function Bl(t,e){t*=hc;var n=wc(e*=hc),r=yc(e),i=dc(t-Tl),o=yc(i),a=r*wc(i),s=Dl*n-Ml*r*o,u=Ml*n+Dl*r*o;Ol.add(gc(kc(a*a+s*s),u)),Tl=t,Ml=n,Dl=r}var Ll=function(t){return Ol.reset(),qc(t,Rl),+Ol},Pl=[null,null],Fl={type:"LineString",coordinates:Pl},ql=function(t,e){return Pl[0]=t,Pl[1]=e,Ll(Fl)},jl={Feature:function(t,e){return zl(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r0&&(i=ql(t[o],t[o-1]))>0&&n<=i&&r<=i&&(n+r-i)*(1-Math.pow((n-r)/i,2))oc})).map(u)).concat(x(bc(o/d)*d,i,d).filter((function(t){return dc(t%g)>oc})).map(c))}return b.lines=function(){return m().map((function(t){return{type:"LineString",coordinates:t}}))},b.outline=function(){return{type:"Polygon",coordinates:[f(r).concat(l(a).slice(1),f(n).reverse().slice(1),l(s).reverse().slice(1))]}},b.extent=function(t){return arguments.length?b.extentMajor(t).extentMinor(t):b.extentMinor()},b.extentMajor=function(t){return arguments.length?(r=+t[0][0],n=+t[1][0],s=+t[0][1],a=+t[1][1],r>n&&(t=r,r=n,n=t),s>a&&(t=s,s=a,a=t),b.precision(y)):[[r,s],[n,a]]},b.extentMinor=function(n){return arguments.length?(e=+n[0][0],t=+n[1][0],o=+n[0][1],i=+n[1][1],e>t&&(n=e,e=t,t=n),o>i&&(n=o,o=i,i=n),b.precision(y)):[[e,o],[t,i]]},b.step=function(t){return arguments.length?b.stepMajor(t).stepMinor(t):b.stepMinor()},b.stepMajor=function(t){return arguments.length?(p=+t[0],g=+t[1],b):[p,g]},b.stepMinor=function(t){return arguments.length?(h=+t[0],d=+t[1],b):[h,d]},b.precision=function(h){return arguments.length?(y=+h,u=Kl(o,i,90),c=Xl(e,t,y),f=Kl(s,a,90),l=Xl(r,n,y),b):y},b.extentMajor([[-180,-90+oc],[180,90-oc]]).extentMinor([[-180,-80-oc],[180,80+oc]])}function Jl(){return Zl()()}var Ql,th,eh,nh,rh=function(t,e){var n=t[0]*hc,r=t[1]*hc,i=e[0]*hc,o=e[1]*hc,a=yc(r),s=wc(r),u=yc(o),c=wc(o),f=a*yc(n),l=a*wc(n),h=u*yc(i),d=u*wc(i),p=2*Sc(kc(Tc(o-r)+a*u*Tc(i-n))),g=wc(p),y=p?function(t){var e=wc(t*=p)/g,n=wc(p-t)/g,r=n*f+e*h,i=n*l+e*d,o=n*s+e*c;return[gc(i,r)*lc,gc(o,kc(r*r+i*i))*lc]}:function(){return[n*lc,r*lc]};return y.distance=p,y},ih=function(t){return t},oh=ec(),ah=ec(),sh={point:Mc,lineStart:Mc,lineEnd:Mc,polygonStart:function(){sh.lineStart=uh,sh.lineEnd=lh},polygonEnd:function(){sh.lineStart=sh.lineEnd=sh.point=Mc,oh.add(dc(ah)),ah.reset()},result:function(){var t=oh/2;return oh.reset(),t}};function uh(){sh.point=ch}function ch(t,e){sh.point=fh,Ql=eh=t,th=nh=e}function fh(t,e){ah.add(nh*t-eh*e),eh=t,nh=e}function lh(){fh(Ql,th)}var hh=sh,dh=1/0,ph=dh,gh=-dh,yh=gh;var bh,mh,vh,_h,wh={point:function(t,e){tgh&&(gh=t);eyh&&(yh=e)},lineStart:Mc,lineEnd:Mc,polygonStart:Mc,polygonEnd:Mc,result:function(){var t=[[dh,ph],[gh,yh]];return gh=yh=-(ph=dh=1/0),t}},xh=0,kh=0,Eh=0,Ah=0,Sh=0,Th=0,Mh=0,Dh=0,Ch=0,Oh={point:Rh,lineStart:Ih,lineEnd:Lh,polygonStart:function(){Oh.lineStart=Ph,Oh.lineEnd=Fh},polygonEnd:function(){Oh.point=Rh,Oh.lineStart=Ih,Oh.lineEnd=Lh},result:function(){var t=Ch?[Mh/Ch,Dh/Ch]:Th?[Ah/Th,Sh/Th]:Eh?[xh/Eh,kh/Eh]:[NaN,NaN];return xh=kh=Eh=Ah=Sh=Th=Mh=Dh=Ch=0,t}};function Rh(t,e){xh+=t,kh+=e,++Eh}function Ih(){Oh.point=Nh}function Nh(t,e){Oh.point=Bh,Rh(vh=t,_h=e)}function Bh(t,e){var n=t-vh,r=e-_h,i=kc(n*n+r*r);Ah+=i*(vh+t)/2,Sh+=i*(_h+e)/2,Th+=i,Rh(vh=t,_h=e)}function Lh(){Oh.point=Rh}function Ph(){Oh.point=qh}function Fh(){jh(bh,mh)}function qh(t,e){Oh.point=jh,Rh(bh=vh=t,mh=_h=e)}function jh(t,e){var n=t-vh,r=e-_h,i=kc(n*n+r*r);Ah+=i*(vh+t)/2,Sh+=i*(_h+e)/2,Th+=i,Mh+=(i=_h*t-vh*e)*(vh+t),Dh+=i*(_h+e),Ch+=3*i,Rh(vh=t,_h=e)}var Uh=Oh;function zh(t){this._context=t}zh.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(t,e){switch(this._point){case 0:this._context.moveTo(t,e),this._point=1;break;case 1:this._context.lineTo(t,e);break;default:this._context.moveTo(t+this._radius,e),this._context.arc(t,e,this._radius,0,fc)}},result:Mc};var Yh,Vh,Hh,$h,Gh,Wh=ec(),Kh={point:Mc,lineStart:function(){Kh.point=Xh},lineEnd:function(){Yh&&Zh(Vh,Hh),Kh.point=Mc},polygonStart:function(){Yh=!0},polygonEnd:function(){Yh=null},result:function(){var t=+Wh;return Wh.reset(),t}};function Xh(t,e){Kh.point=Zh,Vh=$h=t,Hh=Gh=e}function Zh(t,e){$h-=t,Gh-=e,Wh.add(kc($h*$h+Gh*Gh)),$h=t,Gh=e}var Jh=Kh;function Qh(){this._string=[]}function td(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}Qh.prototype={_radius:4.5,_circle:td(4.5),pointRadius:function(t){return(t=+t)!==this._radius&&(this._radius=t,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push("Z"),this._point=NaN},point:function(t,e){switch(this._point){case 0:this._string.push("M",t,",",e),this._point=1;break;case 1:this._string.push("L",t,",",e);break;default:null==this._circle&&(this._circle=td(this._radius)),this._string.push("M",t,",",e,this._circle)}},result:function(){if(this._string.length){var t=this._string.join("");return this._string=[],t}return null}};var ed=function(t,e){var n,r,i=4.5;function o(t){return t&&("function"==typeof i&&r.pointRadius(+i.apply(this,arguments)),qc(t,n(r))),r.result()}return o.area=function(t){return qc(t,n(hh)),hh.result()},o.measure=function(t){return qc(t,n(Jh)),Jh.result()},o.bounds=function(t){return qc(t,n(wh)),wh.result()},o.centroid=function(t){return qc(t,n(Uh)),Uh.result()},o.projection=function(e){return arguments.length?(n=null==e?(t=null,ih):(t=e).stream,o):t},o.context=function(t){return arguments.length?(r=null==t?(e=null,new Qh):new zh(e=t),"function"!=typeof i&&r.pointRadius(i),o):e},o.pointRadius=function(t){return arguments.length?(i="function"==typeof t?t:(r.pointRadius(+t),+t),o):i},o.projection(t).context(e)},nd=function(t){return{stream:rd(t)}};function rd(t){return function(e){var n=new id;for(var r in t)n[r]=t[r];return n.stream=e,n}}function id(){}function od(t,e,n){var r=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),null!=r&&t.clipExtent(null),qc(n,t.stream(wh)),e(wh.result()),null!=r&&t.clipExtent(r),t}function ad(t,e,n){return od(t,(function(n){var r=e[1][0]-e[0][0],i=e[1][1]-e[0][1],o=Math.min(r/(n[1][0]-n[0][0]),i/(n[1][1]-n[0][1])),a=+e[0][0]+(r-o*(n[1][0]+n[0][0]))/2,s=+e[0][1]+(i-o*(n[1][1]+n[0][1]))/2;t.scale(150*o).translate([a,s])}),n)}function sd(t,e,n){return ad(t,[[0,0],e],n)}function ud(t,e,n){return od(t,(function(n){var r=+e,i=r/(n[1][0]-n[0][0]),o=(r-i*(n[1][0]+n[0][0]))/2,a=-i*n[0][1];t.scale(150*i).translate([o,a])}),n)}function cd(t,e,n){return od(t,(function(n){var r=+e,i=r/(n[1][1]-n[0][1]),o=-i*n[0][0],a=(r-i*(n[1][1]+n[0][1]))/2;t.scale(150*i).translate([o,a])}),n)}id.prototype={constructor:id,point:function(t,e){this.stream.point(t,e)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var fd=16,ld=yc(30*hc),hd=function(t,e){return+e?function(t,e){function n(r,i,o,a,s,u,c,f,l,h,d,p,g,y){var b=c-r,m=f-i,v=b*b+m*m;if(v>4*e&&g--){var _=a+h,w=s+d,x=u+p,k=kc(_*_+w*w+x*x),E=Sc(x/=k),A=dc(dc(x)-1)e||dc((b*D+m*C)/v-.5)>.3||a*h+s*d+u*p2?t[2]%360*hc:0,T()):[y*lc,b*lc,m*lc]},A.angle=function(t){return arguments.length?(v=t%360*hc,T()):v*lc},A.precision=function(t){return arguments.length?(a=hd(s,E=t*t),M()):kc(E)},A.fitExtent=function(t,e){return ad(A,t,e)},A.fitSize=function(t,e){return sd(A,t,e)},A.fitWidth=function(t,e){return ud(A,t,e)},A.fitHeight=function(t,e){return cd(A,t,e)},function(){return e=t.apply(this,arguments),A.invert=e.invert&&S,T()}}function md(t){var e=0,n=sc/3,r=bd(t),i=r(e,n);return i.parallels=function(t){return arguments.length?r(e=t[0]*hc,n=t[1]*hc):[e*lc,n*lc]},i}function vd(t,e){var n=wc(t),r=(n+wc(e))/2;if(dc(r)=.12&&i<.234&&r>=-.425&&r<-.214?s:i>=.166&&i<.234&&r>=-.214&&r<-.115?u:a).invert(t)},f.stream=function(n){return t&&e===n?t:(r=[a.stream(e=n),s.stream(n),u.stream(n)],i=r.length,t={point:function(t,e){for(var n=-1;++n0?e<-uc+oc&&(e=-uc+oc):e>uc-oc&&(e=uc-oc);var n=i/_c(Rd(e),r);return[n*wc(r*t),i-n*yc(r*t)]}return o.invert=function(t,e){var n=i-e,o=xc(r)*kc(t*t+n*n);return[gc(t,dc(n))/r*xc(n),2*pc(_c(i/o,1/r))-uc]},o}var Nd=function(){return md(Id).scale(109.5).parallels([30,30])};function Bd(t,e){return[t,e]}Bd.invert=Bd;var Ld=function(){return yd(Bd).scale(152.63)};function Pd(t,e){var n=yc(t),r=t===e?wc(t):(n-yc(e))/(e-t),i=n/r+t;if(dc(r)oc&&--i>0);return[t/(.8707+(o=r*r)*(o*(o*o*o*(.003971-.001529*o)-.013791)-.131979)),r]};var Zd=function(){return yd(Xd).scale(175.295)};function Jd(t,e){return[yc(e)*wc(t),wc(e)]}Jd.invert=Ed(Sc);var Qd=function(){return yd(Jd).scale(249.5).clipAngle(90+oc)};function tp(t,e){var n=yc(e),r=1+yc(t)*n;return[n*wc(t)/r,wc(e)/r]}tp.invert=Ed((function(t){return 2*pc(t)}));var ep=function(){return yd(tp).scale(250).clipAngle(142)};function np(t,e){return[vc(Ec((uc+e)/2)),-t]}np.invert=function(t,e){return[-e,2*pc(mc(t))-uc]};var rp=function(){var t=Od(np),e=t.center,n=t.rotate;return t.center=function(t){return arguments.length?e([-t[1],t[0]]):[(t=e())[1],-t[0]]},t.rotate=function(t){return arguments.length?n([t[0],t[1],t.length>2?t[2]+90:90]):[(t=n())[0],t[1],t[2]-90]},n([0,0,90]).scale(159.155)};function ip(t,e){return t.parent===e.parent?1:2}function op(t,e){return t+e.x}function ap(t,e){return Math.max(t,e.y)}var sp=function(){var t=ip,e=1,n=1,r=!1;function i(i){var o,a=0;i.eachAfter((function(e){var n=e.children;n?(e.x=function(t){return t.reduce(op,0)/t.length}(n),e.y=function(t){return 1+t.reduce(ap,0)}(n)):(e.x=o?a+=t(e,o):0,e.y=0,o=e)}));var s=function(t){for(var e;e=t.children;)t=e[0];return t}(i),u=function(t){for(var e;e=t.children;)t=e[e.length-1];return t}(i),c=s.x-t(s,u)/2,f=u.x+t(u,s)/2;return i.eachAfter(r?function(t){t.x=(t.x-i.x)*e,t.y=(i.y-t.y)*n}:function(t){t.x=(t.x-c)/(f-c)*e,t.y=(1-(i.y?t.y/i.y:1))*n})}return i.separation=function(e){return arguments.length?(t=e,i):t},i.size=function(t){return arguments.length?(r=!1,e=+t[0],n=+t[1],i):r?null:[e,n]},i.nodeSize=function(t){return arguments.length?(r=!0,e=+t[0],n=+t[1],i):r?[e,n]:null},i};function up(t){var e=0,n=t.children,r=n&&n.length;if(r)for(;--r>=0;)e+=n[r].value;else e=1;t.value=e}function cp(t,e){var n,r,i,o,a,s=new dp(t),u=+t.value&&(s.value=t.value),c=[s];for(null==e&&(e=fp);n=c.pop();)if(u&&(n.value=+n.data.value),(i=e(n.data))&&(a=i.length))for(n.children=new Array(a),o=a-1;o>=0;--o)c.push(r=n.children[o]=new dp(i[o])),r.parent=n,r.depth=n.depth+1;return s.eachBefore(hp)}function fp(t){return t.children}function lp(t){t.data=t.data.data}function hp(t){var e=0;do{t.height=e}while((t=t.parent)&&t.height<++e)}function dp(t){this.data=t,this.depth=this.height=0,this.parent=null}dp.prototype=cp.prototype={constructor:dp,count:function(){return this.eachAfter(up)},each:function(t){var e,n,r,i,o=this,a=[o];do{for(e=a.reverse(),a=[];o=e.pop();)if(t(o),n=o.children)for(r=0,i=n.length;r=0;--n)i.push(e[n]);return this},sum:function(t){return this.eachAfter((function(e){for(var n=+t(e.data)||0,r=e.children,i=r&&r.length;--i>=0;)n+=r[i].value;e.value=n}))},sort:function(t){return this.eachBefore((function(e){e.children&&e.children.sort(t)}))},path:function(t){for(var e=this,n=function(t,e){if(t===e)return t;var n=t.ancestors(),r=e.ancestors(),i=null;t=n.pop(),e=r.pop();for(;t===e;)i=t,t=n.pop(),e=r.pop();return i}(e,t),r=[e];e!==n;)e=e.parent,r.push(e);for(var i=r.length;t!==n;)r.splice(i,0,t),t=t.parent;return r},ancestors:function(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e},descendants:function(){var t=[];return this.each((function(e){t.push(e)})),t},leaves:function(){var t=[];return this.eachBefore((function(e){e.children||t.push(e)})),t},links:function(){var t=this,e=[];return t.each((function(n){n!==t&&e.push({source:n.parent,target:n})})),e},copy:function(){return cp(this).eachBefore(lp)}};var pp=Array.prototype.slice;var gp=function(t){for(var e,n,r=0,i=(t=function(t){for(var e,n,r=t.length;r;)n=Math.random()*r--|0,e=t[r],t[r]=t[n],t[n]=e;return t}(pp.call(t))).length,o=[];r0&&n*n>r*r+i*i}function vp(t,e){for(var n=0;n(a*=a)?(r=(c+a-i)/(2*c),o=Math.sqrt(Math.max(0,a/c-r*r)),n.x=t.x-r*s-o*u,n.y=t.y-r*u+o*s):(r=(c+i-a)/(2*c),o=Math.sqrt(Math.max(0,i/c-r*r)),n.x=e.x+r*s-o*u,n.y=e.y+r*u+o*s)):(n.x=e.x+n.r,n.y=e.y)}function Ep(t,e){var n=t.r+e.r-1e-6,r=e.x-t.x,i=e.y-t.y;return n>0&&n*n>r*r+i*i}function Ap(t){var e=t._,n=t.next._,r=e.r+n.r,i=(e.x*n.r+n.x*e.r)/r,o=(e.y*n.r+n.y*e.r)/r;return i*i+o*o}function Sp(t){this._=t,this.next=null,this.previous=null}function Tp(t){if(!(i=t.length))return 0;var e,n,r,i,o,a,s,u,c,f,l;if((e=t[0]).x=0,e.y=0,!(i>1))return e.r;if(n=t[1],e.x=-n.r,n.x=e.r,n.y=0,!(i>2))return e.r+n.r;kp(n,e,r=t[2]),e=new Sp(e),n=new Sp(n),r=new Sp(r),e.next=r.previous=n,n.next=e.previous=r,r.next=n.previous=e;t:for(s=3;s0)throw new Error("cycle");return o}return n.id=function(e){return arguments.length?(t=Cp(e),n):t},n.parentId=function(t){return arguments.length?(e=Cp(t),n):e},n};function Gp(t,e){return t.parent===e.parent?1:2}function Wp(t){var e=t.children;return e?e[0]:t.t}function Kp(t){var e=t.children;return e?e[e.length-1]:t.t}function Xp(t,e,n){var r=n/(e.i-t.i);e.c-=r,e.s+=n,t.c+=r,e.z+=n,e.m+=n}function Zp(t,e,n){return t.a.parent===e.parent?t.a:n}function Jp(t,e){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=e}Jp.prototype=Object.create(dp.prototype);var Qp=function(){var t=Gp,e=1,n=1,r=null;function i(i){var u=function(t){for(var e,n,r,i,o,a=new Jp(t,0),s=[a];e=s.pop();)if(r=e._.children)for(e.children=new Array(o=r.length),i=o-1;i>=0;--i)s.push(n=e.children[i]=new Jp(r[i],i)),n.parent=e;return(a.parent=new Jp(null,0)).children=[a],a}(i);if(u.eachAfter(o),u.parent.m=-u.z,u.eachBefore(a),r)i.eachBefore(s);else{var c=i,f=i,l=i;i.eachBefore((function(t){t.xf.x&&(f=t),t.depth>l.depth&&(l=t)}));var h=c===f?1:t(c,f)/2,d=h-c.x,p=e/(f.x+h+d),g=n/(l.depth||1);i.eachBefore((function(t){t.x=(t.x+d)*p,t.y=t.depth*g}))}return i}function o(e){var n=e.children,r=e.parent.children,i=e.i?r[e.i-1]:null;if(n){!function(t){for(var e,n=0,r=0,i=t.children,o=i.length;--o>=0;)(e=i[o]).z+=n,e.m+=n,n+=e.s+(r+=e.c)}(e);var o=(n[0].z+n[n.length-1].z)/2;i?(e.z=i.z+t(e._,i._),e.m=e.z-o):e.z=o}else i&&(e.z=i.z+t(e._,i._));e.parent.A=function(e,n,r){if(n){for(var i,o=e,a=e,s=n,u=o.parent.children[0],c=o.m,f=a.m,l=s.m,h=u.m;s=Kp(s),o=Wp(o),s&&o;)u=Wp(u),(a=Kp(a)).a=e,(i=s.z+l-o.z-c+t(s._,o._))>0&&(Xp(Zp(s,e,r),e,i),c+=i,f+=i),l+=s.m,c+=o.m,h+=u.m,f+=a.m;s&&!Kp(a)&&(a.t=s,a.m+=l-f),o&&!Wp(u)&&(u.t=o,u.m+=c-h,r=e)}return r}(e,i,e.parent.A||r[0])}function a(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function s(t){t.x*=e,t.y=t.depth*n}return i.separation=function(e){return arguments.length?(t=e,i):t},i.size=function(t){return arguments.length?(r=!1,e=+t[0],n=+t[1],i):r?null:[e,n]},i.nodeSize=function(t){return arguments.length?(r=!0,e=+t[0],n=+t[1],i):r?[e,n]:null},i},tg=function(t,e,n,r,i){for(var o,a=t.children,s=-1,u=a.length,c=t.value&&(i-n)/t.value;++sh&&(h=s),y=f*f*g,(d=Math.max(h/y,y/l))>p){f-=s;break}p=d}b.push(a={value:f,dice:u1?e:1)},n}(eg),ig=function(){var t=rg,e=!1,n=1,r=1,i=[0],o=Op,a=Op,s=Op,u=Op,c=Op;function f(t){return t.x0=t.y0=0,t.x1=n,t.y1=r,t.eachBefore(l),i=[0],e&&t.eachBefore(Fp),t}function l(e){var n=i[e.depth],r=e.x0+n,f=e.y0+n,l=e.x1-n,h=e.y1-n;l=n-1){var f=s[e];return f.x0=i,f.y0=o,f.x1=a,void(f.y1=u)}var l=c[e],h=r/2+l,d=e+1,p=n-1;for(;d>>1;c[g]u-o){var m=(i*b+a*y)/r;t(e,d,y,i,o,m,u),t(d,n,b,m,o,a,u)}else{var v=(o*b+u*y)/r;t(e,d,y,i,o,a,v),t(d,n,b,i,v,a,u)}}(0,u,t.value,e,n,r,i)},ag=function(t,e,n,r,i){(1&t.depth?tg:qp)(t,e,n,r,i)},sg=function t(e){function n(t,n,r,i,o){if((a=t._squarify)&&a.ratio===e)for(var a,s,u,c,f,l=-1,h=a.length,d=t.value;++l1?e:1)},n}(eg),ug=function(t){for(var e,n=-1,r=t.length,i=t[r-1],o=0;++n1&&fg(t[n[r-2]],t[n[r-1]],t[i])<=0;)--r;n[r++]=i}return n.slice(0,r)}var dg=function(t){if((n=t.length)<3)return null;var e,n,r=new Array(n),i=new Array(n);for(e=0;e=0;--e)c.push(t[r[o[e]][2]]);for(e=+s;es!=c>s&&a<(u-n)*(s-r)/(c-r)+n&&(f=!f),u=n,c=r;return f},gg=function(t){for(var e,n,r=-1,i=t.length,o=t[i-1],a=o[0],s=o[1],u=0;++r1);return t+n*o*Math.sqrt(-2*Math.log(i)/i)}}return n.source=t,n}(yg),vg=function t(e){function n(){var t=mg.source(e).apply(this,arguments);return function(){return Math.exp(t())}}return n.source=t,n}(yg),_g=function t(e){function n(t){return function(){for(var n=0,r=0;rr&&(e=n,n=r,r=e),function(t){return Math.max(n,Math.min(r,t))}}function Fg(t,e,n){var r=t[0],i=t[1],o=e[0],a=e[1];return i2?qg:Fg,i=o=null,l}function l(e){return isNaN(e=+e)?n:(i||(i=r(a.map(t),s,u)))(t(c(e)))}return l.invert=function(n){return c(e((o||(o=r(s,a.map(t),Un)))(n)))},l.domain=function(t){return arguments.length?(a=Sg.call(t,Ig),c===Bg||(c=Pg(a)),f()):a.slice()},l.range=function(t){return arguments.length?(s=Tg.call(t),f()):s.slice()},l.rangeRound=function(t){return s=Tg.call(t),u=Qn,f()},l.clamp=function(t){return arguments.length?(c=t?Pg(a):Bg,l):c!==Bg},l.interpolate=function(t){return arguments.length?(u=t,f()):u},l.unknown=function(t){return arguments.length?(n=t,l):n},function(n,r){return t=n,e=r,f()}}function zg(t,e){return Ug()(t,e)}var Yg=function(t,e,n,r){var i,o=M(t,e,n);switch((r=Fu(null==r?",f":r)).type){case"s":var a=Math.max(Math.abs(t),Math.abs(e));return null!=r.precision||isNaN(i=Qu(o,a))||(r.precision=i),Yu(r,a);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(i=tc(o,Math.max(Math.abs(t),Math.abs(e))))||(r.precision=i-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(i=Ju(o))||(r.precision=i-2*("%"===r.type))}return zu(r)};function Vg(t){var e=t.domain;return t.ticks=function(t){var n=e();return S(n[0],n[n.length-1],null==t?10:t)},t.tickFormat=function(t,n){var r=e();return Yg(r[0],r[r.length-1],null==t?10:t,n)},t.nice=function(n){null==n&&(n=10);var r,i=e(),o=0,a=i.length-1,s=i[o],u=i[a];return u0?r=T(s=Math.floor(s/r)*r,u=Math.ceil(u/r)*r,n):r<0&&(r=T(s=Math.ceil(s*r)/r,u=Math.floor(u*r)/r,n)),r>0?(i[o]=Math.floor(s/r)*r,i[a]=Math.ceil(u/r)*r,e(i)):r<0&&(i[o]=Math.ceil(s*r)/r,i[a]=Math.floor(u*r)/r,e(i)),t},t}function Hg(){var t=zg(Bg,Bg);return t.copy=function(){return jg(t,Hg())},kg.apply(t,arguments),Vg(t)}function $g(t){var e;function n(t){return isNaN(t=+t)?e:t}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=Sg.call(e,Ig),n):t.slice()},n.unknown=function(t){return arguments.length?(e=t,n):e},n.copy=function(){return $g(t).unknown(e)},t=arguments.length?Sg.call(t,Ig):[0,1],Vg(n)}var Gg=function(t,e){var n,r=0,i=(t=t.slice()).length-1,o=t[r],a=t[i];return a0){for(;hu)break;g.push(l)}}else for(;h=1;--f)if(!((l=c*f)u)break;g.push(l)}}else g=S(h,d,Math.min(d-h,p)).map(n);return r?g.reverse():g},r.tickFormat=function(t,i){if(null==i&&(i=10===o?".0e":","),"function"!=typeof i&&(i=zu(i)),t===1/0)return i;null==t&&(t=10);var a=Math.max(1,o*t/r.ticks().length);return function(t){var r=t/n(Math.round(e(t)));return r*o0?i[r-1]:e[0],r=r?[i[r-1],n]:[i[a-1],i[a]]},a.unknown=function(e){return arguments.length?(t=e,a):a},a.thresholds=function(){return i.slice()},a.copy=function(){return dy().domain([e,n]).range(o).unknown(t)},kg.apply(Vg(a),arguments)}function py(){var t,e=[.5],n=[0,1],r=1;function i(i){return i<=i?n[u(e,i,0,r)]:t}return i.domain=function(t){return arguments.length?(e=Tg.call(t),r=Math.min(e.length,n.length-1),i):e.slice()},i.range=function(t){return arguments.length?(n=Tg.call(t),r=Math.min(e.length,n.length-1),i):n.slice()},i.invertExtent=function(t){var r=n.indexOf(t);return[e[r-1],e[r]]},i.unknown=function(e){return arguments.length?(t=e,i):t},i.copy=function(){return py().domain(e).range(n).unknown(t)},kg.apply(i,arguments)}var gy=new Date,yy=new Date;function by(t,e,n,r){function i(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return i.floor=function(e){return t(e=new Date(+e)),e},i.ceil=function(n){return t(n=new Date(n-1)),e(n,1),t(n),n},i.round=function(t){var e=i(t),n=i.ceil(t);return t-e0))return s;do{s.push(a=new Date(+n)),e(n,o),t(n)}while(a=e)for(;t(e),!n(e);)e.setTime(e-1)}),(function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););}))},n&&(i.count=function(e,r){return gy.setTime(+e),yy.setTime(+r),t(gy),t(yy),Math.floor(n(gy,yy))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}var my=by((function(t){t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,e){t.setFullYear(t.getFullYear()+e)}),(function(t,e){return e.getFullYear()-t.getFullYear()}),(function(t){return t.getFullYear()}));my.every=function(t){return isFinite(t=Math.floor(t))&&t>0?by((function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,n){e.setFullYear(e.getFullYear()+n*t)})):null};var vy=my,_y=my.range,wy=by((function(t){t.setDate(1),t.setHours(0,0,0,0)}),(function(t,e){t.setMonth(t.getMonth()+e)}),(function(t,e){return e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())}),(function(t){return t.getMonth()})),xy=wy,ky=wy.range,Ey=6e4,Ay=6048e5;function Sy(t){return by((function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+7*e)}),(function(t,e){return(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*Ey)/Ay}))}var Ty=Sy(0),My=Sy(1),Dy=Sy(2),Cy=Sy(3),Oy=Sy(4),Ry=Sy(5),Iy=Sy(6),Ny=Ty.range,By=My.range,Ly=Dy.range,Py=Cy.range,Fy=Oy.range,qy=Ry.range,jy=Iy.range,Uy=by((function(t){t.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+e)}),(function(t,e){return(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*Ey)/864e5}),(function(t){return t.getDate()-1})),zy=Uy,Yy=Uy.range,Vy=by((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds()-t.getMinutes()*Ey)}),(function(t,e){t.setTime(+t+36e5*e)}),(function(t,e){return(e-t)/36e5}),(function(t){return t.getHours()})),Hy=Vy,$y=Vy.range,Gy=by((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds())}),(function(t,e){t.setTime(+t+e*Ey)}),(function(t,e){return(e-t)/Ey}),(function(t){return t.getMinutes()})),Wy=Gy,Ky=Gy.range,Xy=by((function(t){t.setTime(t-t.getMilliseconds())}),(function(t,e){t.setTime(+t+1e3*e)}),(function(t,e){return(e-t)/1e3}),(function(t){return t.getUTCSeconds()})),Zy=Xy,Jy=Xy.range,Qy=by((function(){}),(function(t,e){t.setTime(+t+e)}),(function(t,e){return e-t}));Qy.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?by((function(e){e.setTime(Math.floor(e/t)*t)}),(function(e,n){e.setTime(+e+n*t)}),(function(e,n){return(n-e)/t})):Qy:null};var tb=Qy,eb=Qy.range;function nb(t){return by((function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+7*e)}),(function(t,e){return(e-t)/Ay}))}var rb=nb(0),ib=nb(1),ob=nb(2),ab=nb(3),sb=nb(4),ub=nb(5),cb=nb(6),fb=rb.range,lb=ib.range,hb=ob.range,db=ab.range,pb=sb.range,gb=ub.range,yb=cb.range,bb=by((function(t){t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+e)}),(function(t,e){return(e-t)/864e5}),(function(t){return t.getUTCDate()-1})),mb=bb,vb=bb.range,_b=by((function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)}),(function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}),(function(t){return t.getUTCFullYear()}));_b.every=function(t){return isFinite(t=Math.floor(t))&&t>0?by((function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null};var wb=_b,xb=_b.range;function kb(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function Eb(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Ab(t){return{y:t,m:0,d:1,H:0,M:0,S:0,L:0}}function Sb(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,o=t.days,a=t.shortDays,s=t.months,u=t.shortMonths,c=Fb(i),f=qb(i),l=Fb(o),h=qb(o),d=Fb(a),p=qb(a),g=Fb(s),y=qb(s),b=Fb(u),m=qb(u),v={a:function(t){return a[t.getDay()]},A:function(t){return o[t.getDay()]},b:function(t){return u[t.getMonth()]},B:function(t){return s[t.getMonth()]},c:null,d:om,e:om,f:fm,H:am,I:sm,j:um,L:cm,m:lm,M:hm,p:function(t){return i[+(t.getHours()>=12)]},Q:jm,s:Um,S:dm,u:pm,U:gm,V:ym,w:bm,W:mm,x:null,X:null,y:vm,Y:_m,Z:wm,"%":qm},_={a:function(t){return a[t.getUTCDay()]},A:function(t){return o[t.getUTCDay()]},b:function(t){return u[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:xm,e:xm,f:Tm,H:km,I:Em,j:Am,L:Sm,m:Mm,M:Dm,p:function(t){return i[+(t.getUTCHours()>=12)]},Q:jm,s:Um,S:Cm,u:Om,U:Rm,V:Im,w:Nm,W:Bm,x:null,X:null,y:Lm,Y:Pm,Z:Fm,"%":qm},w={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=p[r[0].toLowerCase()],n+r[0].length):-1},A:function(t,e,n){var r=l.exec(e.slice(n));return r?(t.w=h[r[0].toLowerCase()],n+r[0].length):-1},b:function(t,e,n){var r=b.exec(e.slice(n));return r?(t.m=m[r[0].toLowerCase()],n+r[0].length):-1},B:function(t,e,n){var r=g.exec(e.slice(n));return r?(t.m=y[r[0].toLowerCase()],n+r[0].length):-1},c:function(t,n,r){return E(t,e,n,r)},d:Kb,e:Kb,f:em,H:Zb,I:Zb,j:Xb,L:tm,m:Wb,M:Jb,p:function(t,e,n){var r=c.exec(e.slice(n));return r?(t.p=f[r[0].toLowerCase()],n+r[0].length):-1},Q:rm,s:im,S:Qb,u:Ub,U:zb,V:Yb,w:jb,W:Vb,x:function(t,e,r){return E(t,n,e,r)},X:function(t,e,n){return E(t,r,e,n)},y:$b,Y:Hb,Z:Gb,"%":nm};function x(t,e){return function(n){var r,i,o,a=[],s=-1,u=0,c=t.length;for(n instanceof Date||(n=new Date(+n));++s53)return null;"w"in o||(o.w=1),"Z"in o?(i=(r=Eb(Ab(o.y))).getUTCDay(),r=i>4||0===i?ib.ceil(r):ib(r),r=mb.offset(r,7*(o.V-1)),o.y=r.getUTCFullYear(),o.m=r.getUTCMonth(),o.d=r.getUTCDate()+(o.w+6)%7):(i=(r=e(Ab(o.y))).getDay(),r=i>4||0===i?My.ceil(r):My(r),r=zy.offset(r,7*(o.V-1)),o.y=r.getFullYear(),o.m=r.getMonth(),o.d=r.getDate()+(o.w+6)%7)}else("W"in o||"U"in o)&&("w"in o||(o.w="u"in o?o.u%7:"W"in o?1:0),i="Z"in o?Eb(Ab(o.y)).getUTCDay():e(Ab(o.y)).getDay(),o.m=0,o.d="W"in o?(o.w+6)%7+7*o.W-(i+5)%7:o.w+7*o.U-(i+6)%7);return"Z"in o?(o.H+=o.Z/100|0,o.M+=o.Z%100,Eb(o)):e(o)}}function E(t,e,n,r){for(var i,o,a=0,s=e.length,u=n.length;a=u)return-1;if(37===(i=e.charCodeAt(a++))){if(i=e.charAt(a++),!(o=w[i in Rb?e.charAt(a++):i])||(r=o(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return(v.x=x(n,v),v.X=x(r,v),v.c=x(e,v),_.x=x(n,_),_.X=x(r,_),_.c=x(e,_),{format:function(t){var e=x(t+="",v);return e.toString=function(){return t},e},parse:function(t){var e=k(t+="",kb);return e.toString=function(){return t},e},utcFormat:function(t){var e=x(t+="",_);return e.toString=function(){return t},e},utcParse:function(t){var e=k(t,Eb);return e.toString=function(){return t},e}})}var Tb,Mb,Db,Cb,Ob,Rb={"-":"",_:" ",0:"0"},Ib=/^\s*\d+/,Nb=/^%/,Bb=/[\\^$*+?|[\]().{}]/g;function Lb(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",o=i.length;return r+(o68?1900:2e3),n+r[0].length):-1}function Gb(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function Wb(t,e,n){var r=Ib.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Kb(t,e,n){var r=Ib.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Xb(t,e,n){var r=Ib.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function Zb(t,e,n){var r=Ib.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function Jb(t,e,n){var r=Ib.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function Qb(t,e,n){var r=Ib.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function tm(t,e,n){var r=Ib.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function em(t,e,n){var r=Ib.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function nm(t,e,n){var r=Nb.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function rm(t,e,n){var r=Ib.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function im(t,e,n){var r=Ib.exec(e.slice(n));return r?(t.Q=1e3*+r[0],n+r[0].length):-1}function om(t,e){return Lb(t.getDate(),e,2)}function am(t,e){return Lb(t.getHours(),e,2)}function sm(t,e){return Lb(t.getHours()%12||12,e,2)}function um(t,e){return Lb(1+zy.count(vy(t),t),e,3)}function cm(t,e){return Lb(t.getMilliseconds(),e,3)}function fm(t,e){return cm(t,e)+"000"}function lm(t,e){return Lb(t.getMonth()+1,e,2)}function hm(t,e){return Lb(t.getMinutes(),e,2)}function dm(t,e){return Lb(t.getSeconds(),e,2)}function pm(t){var e=t.getDay();return 0===e?7:e}function gm(t,e){return Lb(Ty.count(vy(t),t),e,2)}function ym(t,e){var n=t.getDay();return t=n>=4||0===n?Oy(t):Oy.ceil(t),Lb(Oy.count(vy(t),t)+(4===vy(t).getDay()),e,2)}function bm(t){return t.getDay()}function mm(t,e){return Lb(My.count(vy(t),t),e,2)}function vm(t,e){return Lb(t.getFullYear()%100,e,2)}function _m(t,e){return Lb(t.getFullYear()%1e4,e,4)}function wm(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Lb(e/60|0,"0",2)+Lb(e%60,"0",2)}function xm(t,e){return Lb(t.getUTCDate(),e,2)}function km(t,e){return Lb(t.getUTCHours(),e,2)}function Em(t,e){return Lb(t.getUTCHours()%12||12,e,2)}function Am(t,e){return Lb(1+mb.count(wb(t),t),e,3)}function Sm(t,e){return Lb(t.getUTCMilliseconds(),e,3)}function Tm(t,e){return Sm(t,e)+"000"}function Mm(t,e){return Lb(t.getUTCMonth()+1,e,2)}function Dm(t,e){return Lb(t.getUTCMinutes(),e,2)}function Cm(t,e){return Lb(t.getUTCSeconds(),e,2)}function Om(t){var e=t.getUTCDay();return 0===e?7:e}function Rm(t,e){return Lb(rb.count(wb(t),t),e,2)}function Im(t,e){var n=t.getUTCDay();return t=n>=4||0===n?sb(t):sb.ceil(t),Lb(sb.count(wb(t),t)+(4===wb(t).getUTCDay()),e,2)}function Nm(t){return t.getUTCDay()}function Bm(t,e){return Lb(ib.count(wb(t),t),e,2)}function Lm(t,e){return Lb(t.getUTCFullYear()%100,e,2)}function Pm(t,e){return Lb(t.getUTCFullYear()%1e4,e,4)}function Fm(){return"+0000"}function qm(){return"%"}function jm(t){return+t}function Um(t){return Math.floor(+t/1e3)}function zm(t){return Tb=Sb(t),Mb=Tb.format,Db=Tb.parse,Cb=Tb.utcFormat,Ob=Tb.utcParse,Tb}zm({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});var Ym=Date.prototype.toISOString?function(t){return t.toISOString()}:Cb("%Y-%m-%dT%H:%M:%S.%LZ");var Vm=+new Date("2000-01-01T00:00:00.000Z")?function(t){var e=new Date(t);return isNaN(e)?null:e}:Ob("%Y-%m-%dT%H:%M:%S.%LZ"),Hm=1e3,$m=60*Hm,Gm=60*$m,Wm=24*Gm,Km=7*Wm,Xm=30*Wm,Zm=365*Wm;function Jm(t){return new Date(t)}function Qm(t){return t instanceof Date?+t:+new Date(+t)}function tv(t,e,n,r,o,a,s,u,c){var f=zg(Bg,Bg),l=f.invert,h=f.domain,d=c(".%L"),p=c(":%S"),g=c("%I:%M"),y=c("%I %p"),b=c("%a %d"),m=c("%b %d"),v=c("%B"),_=c("%Y"),w=[[s,1,Hm],[s,5,5*Hm],[s,15,15*Hm],[s,30,30*Hm],[a,1,$m],[a,5,5*$m],[a,15,15*$m],[a,30,30*$m],[o,1,Gm],[o,3,3*Gm],[o,6,6*Gm],[o,12,12*Gm],[r,1,Wm],[r,2,2*Wm],[n,1,Km],[e,1,Xm],[e,3,3*Xm],[t,1,Zm]];function x(i){return(s(i)1)&&(t-=Math.floor(t));var e=Math.abs(t-.5);return z_.h=360*t-100,z_.s=1.5-1.5*e,z_.l=.8-.9*e,z_+""},V_=bn(),H_=Math.PI/3,$_=2*Math.PI/3,G_=function(t){var e;return t=(.5-t)*Math.PI,V_.r=255*(e=Math.sin(t))*e,V_.g=255*(e=Math.sin(t+H_))*e,V_.b=255*(e=Math.sin(t+$_))*e,V_+""},W_=function(t){return t=Math.max(0,Math.min(1,t)),"rgb("+Math.max(0,Math.min(255,Math.round(34.61+t*(1172.33-t*(10793.56-t*(33300.12-t*(38394.49-14825.05*t)))))))+", "+Math.max(0,Math.min(255,Math.round(23.31+t*(557.33+t*(1225.33-t*(3574.96-t*(1073.77+707.56*t)))))))+", "+Math.max(0,Math.min(255,Math.round(27.2+t*(3211.1-t*(15327.97-t*(27814-t*(22569.18-6838.66*t)))))))+")"};function K_(t){var e=t.length;return function(n){return t[Math.max(0,Math.min(e-1,Math.floor(n*e)))]}}var X_=K_(Sv("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")),Z_=K_(Sv("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),J_=K_(Sv("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Q_=K_(Sv("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),tw=function(t){return function(){return t}},ew=Math.abs,nw=Math.atan2,rw=Math.cos,iw=Math.max,ow=Math.min,aw=Math.sin,sw=Math.sqrt,uw=1e-12,cw=Math.PI,fw=cw/2,lw=2*cw;function hw(t){return t>=1?fw:t<=-1?-fw:Math.asin(t)}function dw(t){return t.innerRadius}function pw(t){return t.outerRadius}function gw(t){return t.startAngle}function yw(t){return t.endAngle}function bw(t){return t&&t.padAngle}function mw(t,e,n,r,i,o,a){var s=t-n,u=e-r,c=(a?o:-o)/sw(s*s+u*u),f=c*u,l=-c*s,h=t+f,d=e+l,p=n+f,g=r+l,y=(h+p)/2,b=(d+g)/2,m=p-h,v=g-d,_=m*m+v*v,w=i-o,x=h*g-p*d,k=(v<0?-1:1)*sw(iw(0,w*w*_-x*x)),E=(x*v-m*k)/_,A=(-x*m-v*k)/_,S=(x*v+m*k)/_,T=(-x*m+v*k)/_,M=E-y,D=A-b,C=S-y,O=T-b;return M*M+D*D>C*C+O*O&&(E=S,A=T),{cx:E,cy:A,x01:-f,y01:-l,x11:E*(i/w-1),y11:A*(i/w-1)}}var vw=function(){var t=dw,e=pw,n=tw(0),r=null,i=gw,o=yw,a=bw,s=null;function u(){var u,c,f,l=+t.apply(this,arguments),h=+e.apply(this,arguments),d=i.apply(this,arguments)-fw,p=o.apply(this,arguments)-fw,g=ew(p-d),y=p>d;if(s||(s=u=qa()),huw)if(g>lw-uw)s.moveTo(h*rw(d),h*aw(d)),s.arc(0,0,h,d,p,!y),l>uw&&(s.moveTo(l*rw(p),l*aw(p)),s.arc(0,0,l,p,d,y));else{var b,m,v=d,_=p,w=d,x=p,k=g,E=g,A=a.apply(this,arguments)/2,S=A>uw&&(r?+r.apply(this,arguments):sw(l*l+h*h)),T=ow(ew(h-l)/2,+n.apply(this,arguments)),M=T,D=T;if(S>uw){var C=hw(S/l*aw(A)),O=hw(S/h*aw(A));(k-=2*C)>uw?(w+=C*=y?1:-1,x-=C):(k=0,w=x=(d+p)/2),(E-=2*O)>uw?(v+=O*=y?1:-1,_-=O):(E=0,v=_=(d+p)/2)}var R=h*rw(v),I=h*aw(v),N=l*rw(x),B=l*aw(x);if(T>uw){var L,P=h*rw(_),F=h*aw(_),q=l*rw(w),j=l*aw(w);if(g1?0:f<-1?cw:Math.acos(f))/2),$=sw(L[0]*L[0]+L[1]*L[1]);M=ow(T,(l-$)/(H-1)),D=ow(T,(h-$)/(H+1))}}E>uw?D>uw?(b=mw(q,j,R,I,h,D,y),m=mw(P,F,N,B,h,D,y),s.moveTo(b.cx+b.x01,b.cy+b.y01),Duw&&k>uw?M>uw?(b=mw(N,B,P,F,l,-M,y),m=mw(R,I,q,j,l,-M,y),s.lineTo(b.cx+b.x01,b.cy+b.y01),M=f;--l)s.point(y[l],b[l]);s.lineEnd(),s.areaEnd()}g&&(y[c]=+t(h,c,u),b[c]=+n(h,c,u),s.point(e?+e(h,c,u):y[c],r?+r(h,c,u):b[c]))}if(d)return s=null,d+""||null}function c(){return Ew().defined(i).curve(a).context(o)}return u.x=function(n){return arguments.length?(t="function"==typeof n?n:tw(+n),e=null,u):t},u.x0=function(e){return arguments.length?(t="function"==typeof e?e:tw(+e),u):t},u.x1=function(t){return arguments.length?(e=null==t?null:"function"==typeof t?t:tw(+t),u):e},u.y=function(t){return arguments.length?(n="function"==typeof t?t:tw(+t),r=null,u):n},u.y0=function(t){return arguments.length?(n="function"==typeof t?t:tw(+t),u):n},u.y1=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:tw(+t),u):r},u.lineX0=u.lineY0=function(){return c().x(t).y(n)},u.lineY1=function(){return c().x(t).y(r)},u.lineX1=function(){return c().x(e).y(n)},u.defined=function(t){return arguments.length?(i="function"==typeof t?t:tw(!!t),u):i},u.curve=function(t){return arguments.length?(a=t,null!=o&&(s=a(o)),u):a},u.context=function(t){return arguments.length?(null==t?o=s=null:s=a(o=t),u):o},u},Sw=function(t,e){return et?1:e>=t?0:NaN},Tw=function(t){return t},Mw=function(){var t=Tw,e=Sw,n=null,r=tw(0),i=tw(lw),o=tw(0);function a(a){var s,u,c,f,l,h=a.length,d=0,p=new Array(h),g=new Array(h),y=+r.apply(this,arguments),b=Math.min(lw,Math.max(-lw,i.apply(this,arguments)-y)),m=Math.min(Math.abs(b)/h,o.apply(this,arguments)),v=m*(b<0?-1:1);for(s=0;s0&&(d+=l);for(null!=e?p.sort((function(t,n){return e(g[t],g[n])})):null!=n&&p.sort((function(t,e){return n(a[t],a[e])})),s=0,c=d?(b-h*v)/d:0;s0?l*c:0)+v,g[u]={data:a[u],index:s,value:l,startAngle:y,endAngle:f,padAngle:m};return g}return a.value=function(e){return arguments.length?(t="function"==typeof e?e:tw(+e),a):t},a.sortValues=function(t){return arguments.length?(e=t,n=null,a):e},a.sort=function(t){return arguments.length?(n=t,e=null,a):n},a.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:tw(+t),a):r},a.endAngle=function(t){return arguments.length?(i="function"==typeof t?t:tw(+t),a):i},a.padAngle=function(t){return arguments.length?(o="function"==typeof t?t:tw(+t),a):o},a},Dw=Ow(ww);function Cw(t){this._curve=t}function Ow(t){function e(e){return new Cw(t(e))}return e._curve=t,e}function Rw(t){var e=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(t){return arguments.length?e(Ow(t)):e()._curve},t}Cw.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,e){this._curve.point(e*Math.sin(t),e*-Math.cos(t))}};var Iw=function(){return Rw(Ew().curve(Dw))},Nw=function(){var t=Aw().curve(Dw),e=t.curve,n=t.lineX0,r=t.lineX1,i=t.lineY0,o=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return Rw(n())},delete t.lineX0,t.lineEndAngle=function(){return Rw(r())},delete t.lineX1,t.lineInnerRadius=function(){return Rw(i())},delete t.lineY0,t.lineOuterRadius=function(){return Rw(o())},delete t.lineY1,t.curve=function(t){return arguments.length?e(Ow(t)):e()._curve},t},Bw=function(t,e){return[(e=+e)*Math.cos(t-=Math.PI/2),e*Math.sin(t)]},Lw=Array.prototype.slice;function Pw(t){return t.source}function Fw(t){return t.target}function qw(t){var e=Pw,n=Fw,r=xw,i=kw,o=null;function a(){var a,s=Lw.call(arguments),u=e.apply(this,s),c=n.apply(this,s);if(o||(o=a=qa()),t(o,+r.apply(this,(s[0]=u,s)),+i.apply(this,s),+r.apply(this,(s[0]=c,s)),+i.apply(this,s)),a)return o=null,a+""||null}return a.source=function(t){return arguments.length?(e=t,a):e},a.target=function(t){return arguments.length?(n=t,a):n},a.x=function(t){return arguments.length?(r="function"==typeof t?t:tw(+t),a):r},a.y=function(t){return arguments.length?(i="function"==typeof t?t:tw(+t),a):i},a.context=function(t){return arguments.length?(o=null==t?null:t,a):o},a}function jw(t,e,n,r,i){t.moveTo(e,n),t.bezierCurveTo(e=(e+r)/2,n,e,i,r,i)}function Uw(t,e,n,r,i){t.moveTo(e,n),t.bezierCurveTo(e,n=(n+i)/2,r,n,r,i)}function zw(t,e,n,r,i){var o=Bw(e,n),a=Bw(e,n=(n+i)/2),s=Bw(r,n),u=Bw(r,i);t.moveTo(o[0],o[1]),t.bezierCurveTo(a[0],a[1],s[0],s[1],u[0],u[1])}function Yw(){return qw(jw)}function Vw(){return qw(Uw)}function Hw(){var t=qw(zw);return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t}var $w={draw:function(t,e){var n=Math.sqrt(e/cw);t.moveTo(n,0),t.arc(0,0,n,0,lw)}},Gw={draw:function(t,e){var n=Math.sqrt(e/5)/2;t.moveTo(-3*n,-n),t.lineTo(-n,-n),t.lineTo(-n,-3*n),t.lineTo(n,-3*n),t.lineTo(n,-n),t.lineTo(3*n,-n),t.lineTo(3*n,n),t.lineTo(n,n),t.lineTo(n,3*n),t.lineTo(-n,3*n),t.lineTo(-n,n),t.lineTo(-3*n,n),t.closePath()}},Ww=Math.sqrt(1/3),Kw=2*Ww,Xw={draw:function(t,e){var n=Math.sqrt(e/Kw),r=n*Ww;t.moveTo(0,-n),t.lineTo(r,0),t.lineTo(0,n),t.lineTo(-r,0),t.closePath()}},Zw=Math.sin(cw/10)/Math.sin(7*cw/10),Jw=Math.sin(lw/10)*Zw,Qw=-Math.cos(lw/10)*Zw,tx={draw:function(t,e){var n=Math.sqrt(.8908130915292852*e),r=Jw*n,i=Qw*n;t.moveTo(0,-n),t.lineTo(r,i);for(var o=1;o<5;++o){var a=lw*o/5,s=Math.cos(a),u=Math.sin(a);t.lineTo(u*n,-s*n),t.lineTo(s*r-u*i,u*r+s*i)}t.closePath()}},ex={draw:function(t,e){var n=Math.sqrt(e),r=-n/2;t.rect(r,r,n,n)}},nx=Math.sqrt(3),rx={draw:function(t,e){var n=-Math.sqrt(e/(3*nx));t.moveTo(0,2*n),t.lineTo(-nx*n,-n),t.lineTo(nx*n,-n),t.closePath()}},ix=Math.sqrt(3)/2,ox=1/Math.sqrt(12),ax=3*(ox/2+1),sx={draw:function(t,e){var n=Math.sqrt(e/ax),r=n/2,i=n*ox,o=r,a=n*ox+n,s=-o,u=a;t.moveTo(r,i),t.lineTo(o,a),t.lineTo(s,u),t.lineTo(-.5*r-ix*i,ix*r+-.5*i),t.lineTo(-.5*o-ix*a,ix*o+-.5*a),t.lineTo(-.5*s-ix*u,ix*s+-.5*u),t.lineTo(-.5*r+ix*i,-.5*i-ix*r),t.lineTo(-.5*o+ix*a,-.5*a-ix*o),t.lineTo(-.5*s+ix*u,-.5*u-ix*s),t.closePath()}},ux=[$w,Gw,Xw,ex,tx,rx,sx],cx=function(){var t=tw($w),e=tw(64),n=null;function r(){var r;if(n||(n=r=qa()),t.apply(this,arguments).draw(n,+e.apply(this,arguments)),r)return n=null,r+""||null}return r.type=function(e){return arguments.length?(t="function"==typeof e?e:tw(e),r):t},r.size=function(t){return arguments.length?(e="function"==typeof t?t:tw(+t),r):e},r.context=function(t){return arguments.length?(n=null==t?null:t,r):n},r},fx=function(){};function lx(t,e,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+n)/6)}function hx(t){this._context=t}hx.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:lx(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:lx(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};var dx=function(t){return new hx(t)};function px(t){this._context=t}px.prototype={areaStart:fx,areaEnd:fx,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:lx(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};var gx=function(t){return new px(t)};function yx(t){this._context=t}yx.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:lx(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};var bx=function(t){return new yx(t)};function mx(t,e){this._basis=new hx(t),this._beta=e}mx.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,n=t.length-1;if(n>0)for(var r,i=t[0],o=e[0],a=t[n]-i,s=e[n]-o,u=-1;++u<=n;)r=u/n,this._basis.point(this._beta*t[u]+(1-this._beta)*(i+r*a),this._beta*e[u]+(1-this._beta)*(o+r*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};var vx=function t(e){function n(t){return 1===e?new hx(t):new mx(t,e)}return n.beta=function(e){return t(+e)},n}(.85);function _x(t,e,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function wx(t,e){this._context=t,this._k=(1-e)/6}wx.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:_x(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:_x(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var xx=function t(e){function n(t){return new wx(t,e)}return n.tension=function(e){return t(+e)},n}(0);function kx(t,e){this._context=t,this._k=(1-e)/6}kx.prototype={areaStart:fx,areaEnd:fx,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:_x(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Ex=function t(e){function n(t){return new kx(t,e)}return n.tension=function(e){return t(+e)},n}(0);function Ax(t,e){this._context=t,this._k=(1-e)/6}Ax.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:_x(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Sx=function t(e){function n(t){return new Ax(t,e)}return n.tension=function(e){return t(+e)},n}(0);function Tx(t,e,n){var r=t._x1,i=t._y1,o=t._x2,a=t._y2;if(t._l01_a>uw){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,u=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/u,i=(i*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/u}if(t._l23_a>uw){var c=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*c+t._x1*t._l23_2a-e*t._l12_2a)/f,a=(a*c+t._y1*t._l23_2a-n*t._l12_2a)/f}t._context.bezierCurveTo(r,i,o,a,t._x2,t._y2)}function Mx(t,e){this._context=t,this._alpha=e}Mx.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Tx(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Dx=function t(e){function n(t){return e?new Mx(t,e):new wx(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function Cx(t,e){this._context=t,this._alpha=e}Cx.prototype={areaStart:fx,areaEnd:fx,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Tx(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Ox=function t(e){function n(t){return e?new Cx(t,e):new kx(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function Rx(t,e){this._context=t,this._alpha=e}Rx.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Tx(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Ix=function t(e){function n(t){return e?new Rx(t,e):new Ax(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function Nx(t){this._context=t}Nx.prototype={areaStart:fx,areaEnd:fx,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}};var Bx=function(t){return new Nx(t)};function Lx(t){return t<0?-1:1}function Px(t,e,n){var r=t._x1-t._x0,i=e-t._x1,o=(t._y1-t._y0)/(r||i<0&&-0),a=(n-t._y1)/(i||r<0&&-0),s=(o*i+a*r)/(r+i);return(Lx(o)+Lx(a))*Math.min(Math.abs(o),Math.abs(a),.5*Math.abs(s))||0}function Fx(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function qx(t,e,n){var r=t._x0,i=t._y0,o=t._x1,a=t._y1,s=(o-r)/3;t._context.bezierCurveTo(r+s,i+s*e,o-s,a-s*n,o,a)}function jx(t){this._context=t}function Ux(t){this._context=new zx(t)}function zx(t){this._context=t}function Yx(t){return new jx(t)}function Vx(t){return new Ux(t)}function Hx(t){this._context=t}function $x(t){var e,n,r=t.length-1,i=new Array(r),o=new Array(r),a=new Array(r);for(i[0]=0,o[0]=2,a[0]=t[0]+2*t[1],e=1;e=0;--e)i[e]=(a[e]-i[e+1])/o[e];for(o[r-1]=(t[r]+i[r-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}}this._x=t,this._y=e}};var Kx=function(t){return new Wx(t,.5)};function Xx(t){return new Wx(t,0)}function Zx(t){return new Wx(t,1)}var Jx=function(t,e){if((i=t.length)>1)for(var n,r,i,o=1,a=t[e[0]],s=a.length;o=0;)n[e]=e;return n};function tk(t,e){return t[e]}var ek=function(){var t=tw([]),e=Qx,n=Jx,r=tk;function i(i){var o,a,s=t.apply(this,arguments),u=i.length,c=s.length,f=new Array(c);for(o=0;o0){for(var n,r,i,o=0,a=t[0].length;o0)for(var n,r,i,o,a,s,u=0,c=t[e[0]].length;u=0?(r[0]=o,r[1]=o+=i):i<0?(r[1]=a,r[0]=a+=i):r[0]=o},ik=function(t,e){if((n=t.length)>0){for(var n,r=0,i=t[e[0]],o=i.length;r0&&(r=(n=t[e[0]]).length)>0){for(var n,r,i,o=0,a=1;ao&&(o=e,r=n);return r}var uk=function(t){var e=t.map(ck);return Qx(t).sort((function(t,n){return e[t]-e[n]}))};function ck(t){for(var e,n=0,r=-1,i=t.length;++r0)){if(o/=h,h<0){if(o0){if(o>l)return;o>f&&(f=o)}if(o=r-u,h||!(o<0)){if(o/=h,h<0){if(o>l)return;o>f&&(f=o)}else if(h>0){if(o0)){if(o/=d,d<0){if(o0){if(o>l)return;o>f&&(f=o)}if(o=i-c,d||!(o<0)){if(o/=d,d<0){if(o>l)return;o>f&&(f=o)}else if(d>0){if(o0||l<1)||(f>0&&(t[0]=[u+f*h,c+f*d]),l<1&&(t[1]=[u+l*h,c+l*d]),!0)}}}}}function Sk(t,e,n,r,i){var o=t[1];if(o)return!0;var a,s,u=t[0],c=t.left,f=t.right,l=c[0],h=c[1],d=f[0],p=f[1],g=(l+d)/2,y=(h+p)/2;if(p===h){if(g=r)return;if(l>d){if(u){if(u[1]>=i)return}else u=[g,n];o=[g,i]}else{if(u){if(u[1]1)if(l>d){if(u){if(u[1]>=i)return}else u=[(n-s)/a,n];o=[(i-s)/a,i]}else{if(u){if(u[1]=r)return}else u=[e,a*e+s];o=[r,a*r+s]}else{if(u){if(u[0]=-Wk)){var d=u*u+c*c,p=f*f+l*l,g=(l*d-c*p)/h,y=(u*p-f*d)/h,b=Ok.pop()||new Rk;b.arc=t,b.site=i,b.x=g+a,b.y=(b.cy=y+s)+Math.sqrt(g*g+y*y),t.circle=b;for(var m=null,v=Hk._;v;)if(b.yGk)s=s.L;else{if(!((i=o-zk(s,a))>Gk)){r>-Gk?(e=s.P,n=s):i>-Gk?(e=s,n=s.N):e=n=s;break}if(!s.R){e=s;break}s=s.R}!function(t){Vk[t.index]={site:t,halfedges:[]}}(t);var u=Pk(t);if(Yk.insert(e,u),e||n){if(e===n)return Nk(e),n=Pk(e.site),Yk.insert(u,n),u.edge=n.edge=xk(e.site,u.site),Ik(e),void Ik(n);if(n){Nk(e),Nk(n);var c=e.site,f=c[0],l=c[1],h=t[0]-f,d=t[1]-l,p=n.site,g=p[0]-f,y=p[1]-l,b=2*(h*y-d*g),m=h*h+d*d,v=g*g+y*y,_=[(y*m-d*v)/b+f,(h*v-g*m)/b+l];Ek(n.edge,c,p,_),u.edge=xk(c,t,null,_),n.edge=xk(t,p,null,_),Ik(e),Ik(n)}else u.edge=xk(e.site,u.site)}}function Uk(t,e){var n=t.site,r=n[0],i=n[1],o=i-e;if(!o)return r;var a=t.P;if(!a)return-1/0;var s=(n=a.site)[0],u=n[1],c=u-e;if(!c)return s;var f=s-r,l=1/o-1/c,h=f/c;return l?(-h+Math.sqrt(h*h-2*l*(f*f/(-2*c)-u+c/2+i-o/2)))/l+r:(r+s)/2}function zk(t,e){var n=t.N;if(n)return Uk(n,e);var r=t.site;return r[1]===e?r[0]:1/0}var Yk,Vk,Hk,$k,Gk=1e-6,Wk=1e-12;function Kk(t,e){return e[1]-t[1]||e[0]-t[0]}function Xk(t,e){var n,r,i,o=t.sort(Kk).pop();for($k=[],Vk=new Array(t.length),Yk=new wk,Hk=new wk;;)if(i=Ck,o&&(!i||o[1]Gk||Math.abs(i[0][1]-i[1][1])>Gk)||delete $k[o]}(a,s,u,c),function(t,e,n,r){var i,o,a,s,u,c,f,l,h,d,p,g,y=Vk.length,b=!0;for(i=0;iGk||Math.abs(g-h)>Gk)&&(u.splice(s,0,$k.push(kk(a,d,Math.abs(p-t)Gk?[t,Math.abs(l-t)Gk?[Math.abs(h-r)Gk?[n,Math.abs(l-n)Gk?[Math.abs(h-e)=s)return null;var u=t-i.site[0],c=e-i.site[1],f=u*u+c*c;do{i=o.cells[r=a],a=null,i.halfedges.forEach((function(n){var r=o.edges[n],s=r.left;if(s!==i.site&&s||(s=r.right)){var u=t-s[0],c=e-s[1],l=u*u+c*c;lr?(r+i)/2:Math.min(0,r)||Math.max(0,i),a>o?(o+a)/2:Math.min(0,o)||Math.max(0,a))}var lE=function(){var t,e,n=oE,r=aE,i=fE,o=uE,a=cE,s=[0,1/0],u=[[-1/0,-1/0],[1/0,1/0]],c=250,f=ur,l=gt("start","zoom","end"),h=500,d=150,p=0;function g(t){t.property("__zoom",sE).on("wheel.zoom",x).on("mousedown.zoom",k).on("dblclick.zoom",E).filter(a).on("touchstart.zoom",A).on("touchmove.zoom",S).on("touchend.zoom touchcancel.zoom",T).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function y(t,e){return(e=Math.max(s[0],Math.min(s[1],e)))===t.k?t:new tE(e,t.x,t.y)}function b(t,e,n){var r=e[0]-n[0]*t.k,i=e[1]-n[1]*t.k;return r===t.x&&i===t.y?t:new tE(t.k,r,i)}function m(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function v(t,e,n){t.on("start.zoom",(function(){_(this,arguments).start()})).on("interrupt.zoom end.zoom",(function(){_(this,arguments).end()})).tween("zoom",(function(){var t=this,i=arguments,o=_(t,i),a=r.apply(t,i),s=null==n?m(a):"function"==typeof n?n.apply(t,i):n,u=Math.max(a[1][0]-a[0][0],a[1][1]-a[0][1]),c=t.__zoom,l="function"==typeof e?e.apply(t,i):e,h=f(c.invert(s).concat(u/c.k),l.invert(s).concat(u/l.k));return function(t){if(1===t)t=l;else{var e=h(t),n=u/e[2];t=new tE(n,s[0]-e[0]*n,s[1]-e[1]*n)}o.zoom(null,t)}}))}function _(t,e,n){return!n&&t.__zooming||new w(t,e)}function w(t,e){this.that=t,this.args=e,this.active=0,this.extent=r.apply(t,e),this.taps=0}function x(){if(n.apply(this,arguments)){var t=_(this,arguments),e=this.__zoom,r=Math.max(s[0],Math.min(s[1],e.k*Math.pow(2,o.apply(this,arguments)))),a=Be(this);if(t.wheel)t.mouse[0][0]===a[0]&&t.mouse[0][1]===a[1]||(t.mouse[1]=e.invert(t.mouse[0]=a)),clearTimeout(t.wheel);else{if(e.k===r)return;t.mouse=[a,e.invert(a)],Oi(this),t.start()}iE(),t.wheel=setTimeout((function(){t.wheel=null,t.end()}),d),t.zoom("mouse",i(b(y(e,r),t.mouse[0],t.mouse[1]),t.extent,u))}}function k(){if(!e&&n.apply(this,arguments)){var t=_(this,arguments,!0),r=Me(pe.view).on("mousemove.zoom",(function(){if(iE(),!t.moved){var e=pe.clientX-a,n=pe.clientY-s;t.moved=e*e+n*n>p}t.zoom("mouse",i(b(t.that.__zoom,t.mouse[0]=Be(t.that),t.mouse[1]),t.extent,u))}),!0).on("mouseup.zoom",(function(){r.on("mousemove.zoom mouseup.zoom",null),ze(pe.view,t.moved),iE(),t.end()}),!0),o=Be(this),a=pe.clientX,s=pe.clientY;Ue(pe.view),rE(),t.mouse=[o,this.__zoom.invert(o)],Oi(this),t.start()}}function E(){if(n.apply(this,arguments)){var t=this.__zoom,e=Be(this),o=t.invert(e),a=t.k*(pe.shiftKey?.5:2),s=i(b(y(t,a),e,o),r.apply(this,arguments),u);iE(),c>0?Me(this).transition().duration(c).call(v,s,e):Me(this).call(g.transform,s)}}function A(){if(n.apply(this,arguments)){var e,r,i,o,a=pe.touches,s=a.length,u=_(this,arguments,pe.changedTouches.length===s);for(rE(),r=0;rl&&M.push("'"+this.terminals_[A]+"'");C=p.showPosition?"Parse error on line "+(u+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(u+1)+": Unexpected "+(_==h?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:b,expected:M})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),o.push(p.yylloc),n.push(k[1]),_=null,w?(_=w,w=null):(c=p.yyleng,s=p.yytext,u=p.yylineno,b=p.yylloc,f>0&&f--);break;case 2:if(S=this.productions_[k[1]][1],D.$=i[i.length-S],D._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},m&&(D._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(E=this.performAction.apply(D,[s,c,u,g.yy,k[1],i,o].concat(d))))return E;S&&(n=n.slice(0,-1*S*2),i=i.slice(0,-1*S),o=o.slice(0,-1*S)),n.push(this.productions_[k[1]][0]),i.push(D.$),o.push(D._$),T=a[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0}},A={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var o in i)this[o]=i[o];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),o=0;oe[0].length)){if(e=n,r=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return 5;case 1:case 2:case 3:case 4:break;case 5:return this.begin("ID"),10;case 6:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),41;case 7:return this.popState(),this.popState(),this.begin("LINE"),12;case 8:return this.popState(),this.popState(),5;case 9:return this.begin("LINE"),20;case 10:return this.begin("LINE"),22;case 11:return this.begin("LINE"),23;case 12:return this.begin("LINE"),24;case 13:return this.begin("LINE"),29;case 14:return this.begin("LINE"),26;case 15:return this.begin("LINE"),28;case 16:return this.popState(),13;case 17:return 21;case 18:return 36;case 19:return 37;case 20:return 32;case 21:return 30;case 22:return this.begin("ID"),15;case 23:return this.begin("ID"),16;case 24:return 18;case 25:return 6;case 26:return 35;case 27:return 5;case 28:return e.yytext=e.yytext.trim(),41;case 29:return 44;case 30:return 45;case 31:return 42;case 32:return 43;case 33:return 46;case 34:return 47;case 35:return 48;case 36:return 39;case 37:return 40;case 38:return 5;case 39:return"INVALID"}},rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:participant\b)/i,/^(?:[^\->:\n,;]+?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:and\b)/i,/^(?:[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\b)/i,/^(?:sequenceDiagram\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?::[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[2,3,16],inclusive:!1},ALIAS:{rules:[2,3,7,8],inclusive:!1},ID:{rules:[2,3,6],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,9,10,11,12,13,14,15,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],inclusive:!0}}};function S(){this.yy={}}return E.lexer=A,S.prototype=E,E.Parser=S,new S}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(28).readFileSync(n(29).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(7),n(9)(t))},function(t,e){"function"==typeof Object.create?t.exports=function(t,e){e&&(t.super_=e,t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}))}:t.exports=function(t,e){if(e){t.super_=e;var n=function(){};n.prototype=e.prototype,t.prototype=new n,t.prototype.constructor=t}}},function(t,e,n){var r=n(8),i=r.Buffer;function o(t,e){for(var n in t)e[n]=t[n]}function a(t,e,n){return i(t,e,n)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?t.exports=r:(o(r,e),e.Buffer=a),a.prototype=Object.create(i.prototype),o(i,a),a.from=function(t,e,n){if("number"==typeof t)throw new TypeError("Argument must not be a number");return i(t,e,n)},a.alloc=function(t,e,n){if("number"!=typeof t)throw new TypeError("Argument must be a number");var r=i(t);return void 0!==e?"string"==typeof n?r.fill(e,n):r.fill(e):r.fill(0),r},a.allocUnsafe=function(t){if("number"!=typeof t)throw new TypeError("Argument must be a number");return i(t)},a.allocUnsafeSlow=function(t){if("number"!=typeof t)throw new TypeError("Argument must be a number");return r.SlowBuffer(t)}},function(t,e,n){var r;try{r={cloneDeep:n(348),constant:n(99),defaults:n(176),each:n(100),filter:n(150),find:n(349),flatten:n(178),forEach:n(148),forIn:n(354),has:n(106),isUndefined:n(161),last:n(355),map:n(162),mapValues:n(356),max:n(357),merge:n(359),min:n(364),minBy:n(365),now:n(366),pick:n(183),range:n(184),reduce:n(164),sortBy:n(373),uniqueId:n(185),values:n(169),zipObject:n(378)}}catch(t){}r||(r=window._),t.exports=r},function(t,e,n){(function(t){!function(t,e){"use strict";function r(t,e){if(!t)throw new Error(e||"Assertion failed")}function i(t,e){t.super_=e;var n=function(){};n.prototype=e.prototype,t.prototype=new n,t.prototype.constructor=t}function o(t,e,n){if(o.isBN(t))return t;this.negative=0,this.words=null,this.length=0,this.red=null,null!==t&&("le"!==e&&"be"!==e||(n=e,e=10),this._init(t||0,e||10,n||"be"))}var a;"object"==typeof t?t.exports=o:e.BN=o,o.BN=o,o.wordSize=26;try{a=n(457).Buffer}catch(t){}function s(t,e,n){for(var r=0,i=Math.min(t.length,n),o=e;o=49&&a<=54?a-49+10:a>=17&&a<=22?a-17+10:15&a}return r}function u(t,e,n,r){for(var i=0,o=Math.min(t.length,n),a=e;a=49?s-49+10:s>=17?s-17+10:s}return i}o.isBN=function(t){return t instanceof o||null!==t&&"object"==typeof t&&t.constructor.wordSize===o.wordSize&&Array.isArray(t.words)},o.max=function(t,e){return t.cmp(e)>0?t:e},o.min=function(t,e){return t.cmp(e)<0?t:e},o.prototype._init=function(t,e,n){if("number"==typeof t)return this._initNumber(t,e,n);if("object"==typeof t)return this._initArray(t,e,n);"hex"===e&&(e=16),r(e===(0|e)&&e>=2&&e<=36);var i=0;"-"===(t=t.toString().replace(/\s+/g,""))[0]&&i++,16===e?this._parseHex(t,i):this._parseBase(t,e,i),"-"===t[0]&&(this.negative=1),this.strip(),"le"===n&&this._initArray(this.toArray(),e,n)},o.prototype._initNumber=function(t,e,n){t<0&&(this.negative=1,t=-t),t<67108864?(this.words=[67108863&t],this.length=1):t<4503599627370496?(this.words=[67108863&t,t/67108864&67108863],this.length=2):(r(t<9007199254740992),this.words=[67108863&t,t/67108864&67108863,1],this.length=3),"le"===n&&this._initArray(this.toArray(),e,n)},o.prototype._initArray=function(t,e,n){if(r("number"==typeof t.length),t.length<=0)return this.words=[0],this.length=1,this;this.length=Math.ceil(t.length/3),this.words=new Array(this.length);for(var i=0;i=0;i-=3)a=t[i]|t[i-1]<<8|t[i-2]<<16,this.words[o]|=a<>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);else if("le"===n)for(i=0,o=0;i>>26-s&67108863,(s+=24)>=26&&(s-=26,o++);return this.strip()},o.prototype._parseHex=function(t,e){this.length=Math.ceil((t.length-e)/6),this.words=new Array(this.length);for(var n=0;n=e;n-=6)i=s(t,n,n+6),this.words[r]|=i<>>26-o&4194303,(o+=24)>=26&&(o-=26,r++);n+6!==e&&(i=s(t,e,n+6),this.words[r]|=i<>>26-o&4194303),this.strip()},o.prototype._parseBase=function(t,e,n){this.words=[0],this.length=1;for(var r=0,i=1;i<=67108863;i*=e)r++;r--,i=i/e|0;for(var o=t.length-n,a=o%r,s=Math.min(o,o-a)+n,c=0,f=n;f1&&0===this.words[this.length-1];)this.length--;return this._normSign()},o.prototype._normSign=function(){return 1===this.length&&0===this.words[0]&&(this.negative=0),this},o.prototype.inspect=function(){return(this.red?""};var c=["","0","00","000","0000","00000","000000","0000000","00000000","000000000","0000000000","00000000000","000000000000","0000000000000","00000000000000","000000000000000","0000000000000000","00000000000000000","000000000000000000","0000000000000000000","00000000000000000000","000000000000000000000","0000000000000000000000","00000000000000000000000","000000000000000000000000","0000000000000000000000000"],f=[0,0,25,16,12,11,10,9,8,8,7,7,7,7,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5],l=[0,0,33554432,43046721,16777216,48828125,60466176,40353607,16777216,43046721,1e7,19487171,35831808,62748517,7529536,11390625,16777216,24137569,34012224,47045881,64e6,4084101,5153632,6436343,7962624,9765625,11881376,14348907,17210368,20511149,243e5,28629151,33554432,39135393,45435424,52521875,60466176];function h(t,e,n){n.negative=e.negative^t.negative;var r=t.length+e.length|0;n.length=r,r=r-1|0;var i=0|t.words[0],o=0|e.words[0],a=i*o,s=67108863&a,u=a/67108864|0;n.words[0]=s;for(var c=1;c>>26,l=67108863&u,h=Math.min(c,e.length-1),d=Math.max(0,c-t.length+1);d<=h;d++){var p=c-d|0;f+=(a=(i=0|t.words[p])*(o=0|e.words[d])+l)/67108864|0,l=67108863&a}n.words[c]=0|l,u=0|f}return 0!==u?n.words[c]=0|u:n.length--,n.strip()}o.prototype.toString=function(t,e){var n;if(e=0|e||1,16===(t=t||10)||"hex"===t){n="";for(var i=0,o=0,a=0;a>>24-i&16777215)||a!==this.length-1?c[6-u.length]+u+n:u+n,(i+=2)>=26&&(i-=26,a--)}for(0!==o&&(n=o.toString(16)+n);n.length%e!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}if(t===(0|t)&&t>=2&&t<=36){var h=f[t],d=l[t];n="";var p=this.clone();for(p.negative=0;!p.isZero();){var g=p.modn(d).toString(t);n=(p=p.idivn(d)).isZero()?g+n:c[h-g.length]+g+n}for(this.isZero()&&(n="0"+n);n.length%e!=0;)n="0"+n;return 0!==this.negative&&(n="-"+n),n}r(!1,"Base should be between 2 and 36")},o.prototype.toNumber=function(){var t=this.words[0];return 2===this.length?t+=67108864*this.words[1]:3===this.length&&1===this.words[2]?t+=4503599627370496+67108864*this.words[1]:this.length>2&&r(!1,"Number can only safely store up to 53 bits"),0!==this.negative?-t:t},o.prototype.toJSON=function(){return this.toString(16)},o.prototype.toBuffer=function(t,e){return r(void 0!==a),this.toArrayLike(a,t,e)},o.prototype.toArray=function(t,e){return this.toArrayLike(Array,t,e)},o.prototype.toArrayLike=function(t,e,n){var i=this.byteLength(),o=n||Math.max(1,i);r(i<=o,"byte array longer than desired length"),r(o>0,"Requested array length <= 0"),this.strip();var a,s,u="le"===e,c=new t(o),f=this.clone();if(u){for(s=0;!f.isZero();s++)a=f.andln(255),f.iushrn(8),c[s]=a;for(;s=4096&&(n+=13,e>>>=13),e>=64&&(n+=7,e>>>=7),e>=8&&(n+=4,e>>>=4),e>=2&&(n+=2,e>>>=2),n+e},o.prototype._zeroBits=function(t){if(0===t)return 26;var e=t,n=0;return 0==(8191&e)&&(n+=13,e>>>=13),0==(127&e)&&(n+=7,e>>>=7),0==(15&e)&&(n+=4,e>>>=4),0==(3&e)&&(n+=2,e>>>=2),0==(1&e)&&n++,n},o.prototype.bitLength=function(){var t=this.words[this.length-1],e=this._countBits(t);return 26*(this.length-1)+e},o.prototype.zeroBits=function(){if(this.isZero())return 0;for(var t=0,e=0;et.length?this.clone().ior(t):t.clone().ior(this)},o.prototype.uor=function(t){return this.length>t.length?this.clone().iuor(t):t.clone().iuor(this)},o.prototype.iuand=function(t){var e;e=this.length>t.length?t:this;for(var n=0;nt.length?this.clone().iand(t):t.clone().iand(this)},o.prototype.uand=function(t){return this.length>t.length?this.clone().iuand(t):t.clone().iuand(this)},o.prototype.iuxor=function(t){var e,n;this.length>t.length?(e=this,n=t):(e=t,n=this);for(var r=0;rt.length?this.clone().ixor(t):t.clone().ixor(this)},o.prototype.uxor=function(t){return this.length>t.length?this.clone().iuxor(t):t.clone().iuxor(this)},o.prototype.inotn=function(t){r("number"==typeof t&&t>=0);var e=0|Math.ceil(t/26),n=t%26;this._expand(e),n>0&&e--;for(var i=0;i0&&(this.words[i]=~this.words[i]&67108863>>26-n),this.strip()},o.prototype.notn=function(t){return this.clone().inotn(t)},o.prototype.setn=function(t,e){r("number"==typeof t&&t>=0);var n=t/26|0,i=t%26;return this._expand(n+1),this.words[n]=e?this.words[n]|1<t.length?(n=this,r=t):(n=t,r=this);for(var i=0,o=0;o>>26;for(;0!==i&&o>>26;if(this.length=n.length,0!==i)this.words[this.length]=i,this.length++;else if(n!==this)for(;ot.length?this.clone().iadd(t):t.clone().iadd(this)},o.prototype.isub=function(t){if(0!==t.negative){t.negative=0;var e=this.iadd(t);return t.negative=1,e._normSign()}if(0!==this.negative)return this.negative=0,this.iadd(t),this.negative=1,this._normSign();var n,r,i=this.cmp(t);if(0===i)return this.negative=0,this.length=1,this.words[0]=0,this;i>0?(n=this,r=t):(n=t,r=this);for(var o=0,a=0;a>26,this.words[a]=67108863&e;for(;0!==o&&a>26,this.words[a]=67108863&e;if(0===o&&a>>13,d=0|a[1],p=8191&d,g=d>>>13,y=0|a[2],b=8191&y,m=y>>>13,v=0|a[3],_=8191&v,w=v>>>13,x=0|a[4],k=8191&x,E=x>>>13,A=0|a[5],S=8191&A,T=A>>>13,M=0|a[6],D=8191&M,C=M>>>13,O=0|a[7],R=8191&O,I=O>>>13,N=0|a[8],B=8191&N,L=N>>>13,P=0|a[9],F=8191&P,q=P>>>13,j=0|s[0],U=8191&j,z=j>>>13,Y=0|s[1],V=8191&Y,H=Y>>>13,$=0|s[2],G=8191&$,W=$>>>13,K=0|s[3],X=8191&K,Z=K>>>13,J=0|s[4],Q=8191&J,tt=J>>>13,et=0|s[5],nt=8191&et,rt=et>>>13,it=0|s[6],ot=8191&it,at=it>>>13,st=0|s[7],ut=8191&st,ct=st>>>13,ft=0|s[8],lt=8191&ft,ht=ft>>>13,dt=0|s[9],pt=8191&dt,gt=dt>>>13;n.negative=t.negative^e.negative,n.length=19;var yt=(c+(r=Math.imul(l,U))|0)+((8191&(i=(i=Math.imul(l,z))+Math.imul(h,U)|0))<<13)|0;c=((o=Math.imul(h,z))+(i>>>13)|0)+(yt>>>26)|0,yt&=67108863,r=Math.imul(p,U),i=(i=Math.imul(p,z))+Math.imul(g,U)|0,o=Math.imul(g,z);var bt=(c+(r=r+Math.imul(l,V)|0)|0)+((8191&(i=(i=i+Math.imul(l,H)|0)+Math.imul(h,V)|0))<<13)|0;c=((o=o+Math.imul(h,H)|0)+(i>>>13)|0)+(bt>>>26)|0,bt&=67108863,r=Math.imul(b,U),i=(i=Math.imul(b,z))+Math.imul(m,U)|0,o=Math.imul(m,z),r=r+Math.imul(p,V)|0,i=(i=i+Math.imul(p,H)|0)+Math.imul(g,V)|0,o=o+Math.imul(g,H)|0;var mt=(c+(r=r+Math.imul(l,G)|0)|0)+((8191&(i=(i=i+Math.imul(l,W)|0)+Math.imul(h,G)|0))<<13)|0;c=((o=o+Math.imul(h,W)|0)+(i>>>13)|0)+(mt>>>26)|0,mt&=67108863,r=Math.imul(_,U),i=(i=Math.imul(_,z))+Math.imul(w,U)|0,o=Math.imul(w,z),r=r+Math.imul(b,V)|0,i=(i=i+Math.imul(b,H)|0)+Math.imul(m,V)|0,o=o+Math.imul(m,H)|0,r=r+Math.imul(p,G)|0,i=(i=i+Math.imul(p,W)|0)+Math.imul(g,G)|0,o=o+Math.imul(g,W)|0;var vt=(c+(r=r+Math.imul(l,X)|0)|0)+((8191&(i=(i=i+Math.imul(l,Z)|0)+Math.imul(h,X)|0))<<13)|0;c=((o=o+Math.imul(h,Z)|0)+(i>>>13)|0)+(vt>>>26)|0,vt&=67108863,r=Math.imul(k,U),i=(i=Math.imul(k,z))+Math.imul(E,U)|0,o=Math.imul(E,z),r=r+Math.imul(_,V)|0,i=(i=i+Math.imul(_,H)|0)+Math.imul(w,V)|0,o=o+Math.imul(w,H)|0,r=r+Math.imul(b,G)|0,i=(i=i+Math.imul(b,W)|0)+Math.imul(m,G)|0,o=o+Math.imul(m,W)|0,r=r+Math.imul(p,X)|0,i=(i=i+Math.imul(p,Z)|0)+Math.imul(g,X)|0,o=o+Math.imul(g,Z)|0;var _t=(c+(r=r+Math.imul(l,Q)|0)|0)+((8191&(i=(i=i+Math.imul(l,tt)|0)+Math.imul(h,Q)|0))<<13)|0;c=((o=o+Math.imul(h,tt)|0)+(i>>>13)|0)+(_t>>>26)|0,_t&=67108863,r=Math.imul(S,U),i=(i=Math.imul(S,z))+Math.imul(T,U)|0,o=Math.imul(T,z),r=r+Math.imul(k,V)|0,i=(i=i+Math.imul(k,H)|0)+Math.imul(E,V)|0,o=o+Math.imul(E,H)|0,r=r+Math.imul(_,G)|0,i=(i=i+Math.imul(_,W)|0)+Math.imul(w,G)|0,o=o+Math.imul(w,W)|0,r=r+Math.imul(b,X)|0,i=(i=i+Math.imul(b,Z)|0)+Math.imul(m,X)|0,o=o+Math.imul(m,Z)|0,r=r+Math.imul(p,Q)|0,i=(i=i+Math.imul(p,tt)|0)+Math.imul(g,Q)|0,o=o+Math.imul(g,tt)|0;var wt=(c+(r=r+Math.imul(l,nt)|0)|0)+((8191&(i=(i=i+Math.imul(l,rt)|0)+Math.imul(h,nt)|0))<<13)|0;c=((o=o+Math.imul(h,rt)|0)+(i>>>13)|0)+(wt>>>26)|0,wt&=67108863,r=Math.imul(D,U),i=(i=Math.imul(D,z))+Math.imul(C,U)|0,o=Math.imul(C,z),r=r+Math.imul(S,V)|0,i=(i=i+Math.imul(S,H)|0)+Math.imul(T,V)|0,o=o+Math.imul(T,H)|0,r=r+Math.imul(k,G)|0,i=(i=i+Math.imul(k,W)|0)+Math.imul(E,G)|0,o=o+Math.imul(E,W)|0,r=r+Math.imul(_,X)|0,i=(i=i+Math.imul(_,Z)|0)+Math.imul(w,X)|0,o=o+Math.imul(w,Z)|0,r=r+Math.imul(b,Q)|0,i=(i=i+Math.imul(b,tt)|0)+Math.imul(m,Q)|0,o=o+Math.imul(m,tt)|0,r=r+Math.imul(p,nt)|0,i=(i=i+Math.imul(p,rt)|0)+Math.imul(g,nt)|0,o=o+Math.imul(g,rt)|0;var xt=(c+(r=r+Math.imul(l,ot)|0)|0)+((8191&(i=(i=i+Math.imul(l,at)|0)+Math.imul(h,ot)|0))<<13)|0;c=((o=o+Math.imul(h,at)|0)+(i>>>13)|0)+(xt>>>26)|0,xt&=67108863,r=Math.imul(R,U),i=(i=Math.imul(R,z))+Math.imul(I,U)|0,o=Math.imul(I,z),r=r+Math.imul(D,V)|0,i=(i=i+Math.imul(D,H)|0)+Math.imul(C,V)|0,o=o+Math.imul(C,H)|0,r=r+Math.imul(S,G)|0,i=(i=i+Math.imul(S,W)|0)+Math.imul(T,G)|0,o=o+Math.imul(T,W)|0,r=r+Math.imul(k,X)|0,i=(i=i+Math.imul(k,Z)|0)+Math.imul(E,X)|0,o=o+Math.imul(E,Z)|0,r=r+Math.imul(_,Q)|0,i=(i=i+Math.imul(_,tt)|0)+Math.imul(w,Q)|0,o=o+Math.imul(w,tt)|0,r=r+Math.imul(b,nt)|0,i=(i=i+Math.imul(b,rt)|0)+Math.imul(m,nt)|0,o=o+Math.imul(m,rt)|0,r=r+Math.imul(p,ot)|0,i=(i=i+Math.imul(p,at)|0)+Math.imul(g,ot)|0,o=o+Math.imul(g,at)|0;var kt=(c+(r=r+Math.imul(l,ut)|0)|0)+((8191&(i=(i=i+Math.imul(l,ct)|0)+Math.imul(h,ut)|0))<<13)|0;c=((o=o+Math.imul(h,ct)|0)+(i>>>13)|0)+(kt>>>26)|0,kt&=67108863,r=Math.imul(B,U),i=(i=Math.imul(B,z))+Math.imul(L,U)|0,o=Math.imul(L,z),r=r+Math.imul(R,V)|0,i=(i=i+Math.imul(R,H)|0)+Math.imul(I,V)|0,o=o+Math.imul(I,H)|0,r=r+Math.imul(D,G)|0,i=(i=i+Math.imul(D,W)|0)+Math.imul(C,G)|0,o=o+Math.imul(C,W)|0,r=r+Math.imul(S,X)|0,i=(i=i+Math.imul(S,Z)|0)+Math.imul(T,X)|0,o=o+Math.imul(T,Z)|0,r=r+Math.imul(k,Q)|0,i=(i=i+Math.imul(k,tt)|0)+Math.imul(E,Q)|0,o=o+Math.imul(E,tt)|0,r=r+Math.imul(_,nt)|0,i=(i=i+Math.imul(_,rt)|0)+Math.imul(w,nt)|0,o=o+Math.imul(w,rt)|0,r=r+Math.imul(b,ot)|0,i=(i=i+Math.imul(b,at)|0)+Math.imul(m,ot)|0,o=o+Math.imul(m,at)|0,r=r+Math.imul(p,ut)|0,i=(i=i+Math.imul(p,ct)|0)+Math.imul(g,ut)|0,o=o+Math.imul(g,ct)|0;var Et=(c+(r=r+Math.imul(l,lt)|0)|0)+((8191&(i=(i=i+Math.imul(l,ht)|0)+Math.imul(h,lt)|0))<<13)|0;c=((o=o+Math.imul(h,ht)|0)+(i>>>13)|0)+(Et>>>26)|0,Et&=67108863,r=Math.imul(F,U),i=(i=Math.imul(F,z))+Math.imul(q,U)|0,o=Math.imul(q,z),r=r+Math.imul(B,V)|0,i=(i=i+Math.imul(B,H)|0)+Math.imul(L,V)|0,o=o+Math.imul(L,H)|0,r=r+Math.imul(R,G)|0,i=(i=i+Math.imul(R,W)|0)+Math.imul(I,G)|0,o=o+Math.imul(I,W)|0,r=r+Math.imul(D,X)|0,i=(i=i+Math.imul(D,Z)|0)+Math.imul(C,X)|0,o=o+Math.imul(C,Z)|0,r=r+Math.imul(S,Q)|0,i=(i=i+Math.imul(S,tt)|0)+Math.imul(T,Q)|0,o=o+Math.imul(T,tt)|0,r=r+Math.imul(k,nt)|0,i=(i=i+Math.imul(k,rt)|0)+Math.imul(E,nt)|0,o=o+Math.imul(E,rt)|0,r=r+Math.imul(_,ot)|0,i=(i=i+Math.imul(_,at)|0)+Math.imul(w,ot)|0,o=o+Math.imul(w,at)|0,r=r+Math.imul(b,ut)|0,i=(i=i+Math.imul(b,ct)|0)+Math.imul(m,ut)|0,o=o+Math.imul(m,ct)|0,r=r+Math.imul(p,lt)|0,i=(i=i+Math.imul(p,ht)|0)+Math.imul(g,lt)|0,o=o+Math.imul(g,ht)|0;var At=(c+(r=r+Math.imul(l,pt)|0)|0)+((8191&(i=(i=i+Math.imul(l,gt)|0)+Math.imul(h,pt)|0))<<13)|0;c=((o=o+Math.imul(h,gt)|0)+(i>>>13)|0)+(At>>>26)|0,At&=67108863,r=Math.imul(F,V),i=(i=Math.imul(F,H))+Math.imul(q,V)|0,o=Math.imul(q,H),r=r+Math.imul(B,G)|0,i=(i=i+Math.imul(B,W)|0)+Math.imul(L,G)|0,o=o+Math.imul(L,W)|0,r=r+Math.imul(R,X)|0,i=(i=i+Math.imul(R,Z)|0)+Math.imul(I,X)|0,o=o+Math.imul(I,Z)|0,r=r+Math.imul(D,Q)|0,i=(i=i+Math.imul(D,tt)|0)+Math.imul(C,Q)|0,o=o+Math.imul(C,tt)|0,r=r+Math.imul(S,nt)|0,i=(i=i+Math.imul(S,rt)|0)+Math.imul(T,nt)|0,o=o+Math.imul(T,rt)|0,r=r+Math.imul(k,ot)|0,i=(i=i+Math.imul(k,at)|0)+Math.imul(E,ot)|0,o=o+Math.imul(E,at)|0,r=r+Math.imul(_,ut)|0,i=(i=i+Math.imul(_,ct)|0)+Math.imul(w,ut)|0,o=o+Math.imul(w,ct)|0,r=r+Math.imul(b,lt)|0,i=(i=i+Math.imul(b,ht)|0)+Math.imul(m,lt)|0,o=o+Math.imul(m,ht)|0;var St=(c+(r=r+Math.imul(p,pt)|0)|0)+((8191&(i=(i=i+Math.imul(p,gt)|0)+Math.imul(g,pt)|0))<<13)|0;c=((o=o+Math.imul(g,gt)|0)+(i>>>13)|0)+(St>>>26)|0,St&=67108863,r=Math.imul(F,G),i=(i=Math.imul(F,W))+Math.imul(q,G)|0,o=Math.imul(q,W),r=r+Math.imul(B,X)|0,i=(i=i+Math.imul(B,Z)|0)+Math.imul(L,X)|0,o=o+Math.imul(L,Z)|0,r=r+Math.imul(R,Q)|0,i=(i=i+Math.imul(R,tt)|0)+Math.imul(I,Q)|0,o=o+Math.imul(I,tt)|0,r=r+Math.imul(D,nt)|0,i=(i=i+Math.imul(D,rt)|0)+Math.imul(C,nt)|0,o=o+Math.imul(C,rt)|0,r=r+Math.imul(S,ot)|0,i=(i=i+Math.imul(S,at)|0)+Math.imul(T,ot)|0,o=o+Math.imul(T,at)|0,r=r+Math.imul(k,ut)|0,i=(i=i+Math.imul(k,ct)|0)+Math.imul(E,ut)|0,o=o+Math.imul(E,ct)|0,r=r+Math.imul(_,lt)|0,i=(i=i+Math.imul(_,ht)|0)+Math.imul(w,lt)|0,o=o+Math.imul(w,ht)|0;var Tt=(c+(r=r+Math.imul(b,pt)|0)|0)+((8191&(i=(i=i+Math.imul(b,gt)|0)+Math.imul(m,pt)|0))<<13)|0;c=((o=o+Math.imul(m,gt)|0)+(i>>>13)|0)+(Tt>>>26)|0,Tt&=67108863,r=Math.imul(F,X),i=(i=Math.imul(F,Z))+Math.imul(q,X)|0,o=Math.imul(q,Z),r=r+Math.imul(B,Q)|0,i=(i=i+Math.imul(B,tt)|0)+Math.imul(L,Q)|0,o=o+Math.imul(L,tt)|0,r=r+Math.imul(R,nt)|0,i=(i=i+Math.imul(R,rt)|0)+Math.imul(I,nt)|0,o=o+Math.imul(I,rt)|0,r=r+Math.imul(D,ot)|0,i=(i=i+Math.imul(D,at)|0)+Math.imul(C,ot)|0,o=o+Math.imul(C,at)|0,r=r+Math.imul(S,ut)|0,i=(i=i+Math.imul(S,ct)|0)+Math.imul(T,ut)|0,o=o+Math.imul(T,ct)|0,r=r+Math.imul(k,lt)|0,i=(i=i+Math.imul(k,ht)|0)+Math.imul(E,lt)|0,o=o+Math.imul(E,ht)|0;var Mt=(c+(r=r+Math.imul(_,pt)|0)|0)+((8191&(i=(i=i+Math.imul(_,gt)|0)+Math.imul(w,pt)|0))<<13)|0;c=((o=o+Math.imul(w,gt)|0)+(i>>>13)|0)+(Mt>>>26)|0,Mt&=67108863,r=Math.imul(F,Q),i=(i=Math.imul(F,tt))+Math.imul(q,Q)|0,o=Math.imul(q,tt),r=r+Math.imul(B,nt)|0,i=(i=i+Math.imul(B,rt)|0)+Math.imul(L,nt)|0,o=o+Math.imul(L,rt)|0,r=r+Math.imul(R,ot)|0,i=(i=i+Math.imul(R,at)|0)+Math.imul(I,ot)|0,o=o+Math.imul(I,at)|0,r=r+Math.imul(D,ut)|0,i=(i=i+Math.imul(D,ct)|0)+Math.imul(C,ut)|0,o=o+Math.imul(C,ct)|0,r=r+Math.imul(S,lt)|0,i=(i=i+Math.imul(S,ht)|0)+Math.imul(T,lt)|0,o=o+Math.imul(T,ht)|0;var Dt=(c+(r=r+Math.imul(k,pt)|0)|0)+((8191&(i=(i=i+Math.imul(k,gt)|0)+Math.imul(E,pt)|0))<<13)|0;c=((o=o+Math.imul(E,gt)|0)+(i>>>13)|0)+(Dt>>>26)|0,Dt&=67108863,r=Math.imul(F,nt),i=(i=Math.imul(F,rt))+Math.imul(q,nt)|0,o=Math.imul(q,rt),r=r+Math.imul(B,ot)|0,i=(i=i+Math.imul(B,at)|0)+Math.imul(L,ot)|0,o=o+Math.imul(L,at)|0,r=r+Math.imul(R,ut)|0,i=(i=i+Math.imul(R,ct)|0)+Math.imul(I,ut)|0,o=o+Math.imul(I,ct)|0,r=r+Math.imul(D,lt)|0,i=(i=i+Math.imul(D,ht)|0)+Math.imul(C,lt)|0,o=o+Math.imul(C,ht)|0;var Ct=(c+(r=r+Math.imul(S,pt)|0)|0)+((8191&(i=(i=i+Math.imul(S,gt)|0)+Math.imul(T,pt)|0))<<13)|0;c=((o=o+Math.imul(T,gt)|0)+(i>>>13)|0)+(Ct>>>26)|0,Ct&=67108863,r=Math.imul(F,ot),i=(i=Math.imul(F,at))+Math.imul(q,ot)|0,o=Math.imul(q,at),r=r+Math.imul(B,ut)|0,i=(i=i+Math.imul(B,ct)|0)+Math.imul(L,ut)|0,o=o+Math.imul(L,ct)|0,r=r+Math.imul(R,lt)|0,i=(i=i+Math.imul(R,ht)|0)+Math.imul(I,lt)|0,o=o+Math.imul(I,ht)|0;var Ot=(c+(r=r+Math.imul(D,pt)|0)|0)+((8191&(i=(i=i+Math.imul(D,gt)|0)+Math.imul(C,pt)|0))<<13)|0;c=((o=o+Math.imul(C,gt)|0)+(i>>>13)|0)+(Ot>>>26)|0,Ot&=67108863,r=Math.imul(F,ut),i=(i=Math.imul(F,ct))+Math.imul(q,ut)|0,o=Math.imul(q,ct),r=r+Math.imul(B,lt)|0,i=(i=i+Math.imul(B,ht)|0)+Math.imul(L,lt)|0,o=o+Math.imul(L,ht)|0;var Rt=(c+(r=r+Math.imul(R,pt)|0)|0)+((8191&(i=(i=i+Math.imul(R,gt)|0)+Math.imul(I,pt)|0))<<13)|0;c=((o=o+Math.imul(I,gt)|0)+(i>>>13)|0)+(Rt>>>26)|0,Rt&=67108863,r=Math.imul(F,lt),i=(i=Math.imul(F,ht))+Math.imul(q,lt)|0,o=Math.imul(q,ht);var It=(c+(r=r+Math.imul(B,pt)|0)|0)+((8191&(i=(i=i+Math.imul(B,gt)|0)+Math.imul(L,pt)|0))<<13)|0;c=((o=o+Math.imul(L,gt)|0)+(i>>>13)|0)+(It>>>26)|0,It&=67108863;var Nt=(c+(r=Math.imul(F,pt))|0)+((8191&(i=(i=Math.imul(F,gt))+Math.imul(q,pt)|0))<<13)|0;return c=((o=Math.imul(q,gt))+(i>>>13)|0)+(Nt>>>26)|0,Nt&=67108863,u[0]=yt,u[1]=bt,u[2]=mt,u[3]=vt,u[4]=_t,u[5]=wt,u[6]=xt,u[7]=kt,u[8]=Et,u[9]=At,u[10]=St,u[11]=Tt,u[12]=Mt,u[13]=Dt,u[14]=Ct,u[15]=Ot,u[16]=Rt,u[17]=It,u[18]=Nt,0!==c&&(u[19]=c,n.length++),n};function p(t,e,n){return(new g).mulp(t,e,n)}function g(t,e){this.x=t,this.y=e}Math.imul||(d=h),o.prototype.mulTo=function(t,e){var n=this.length+t.length;return 10===this.length&&10===t.length?d(this,t,e):n<63?h(this,t,e):n<1024?function(t,e,n){n.negative=e.negative^t.negative,n.length=t.length+e.length;for(var r=0,i=0,o=0;o>>26)|0)>>>26,a&=67108863}n.words[o]=s,r=a,a=i}return 0!==r?n.words[o]=r:n.length--,n.strip()}(this,t,e):p(this,t,e)},g.prototype.makeRBT=function(t){for(var e=new Array(t),n=o.prototype._countBits(t)-1,r=0;r>=1;return r},g.prototype.permute=function(t,e,n,r,i,o){for(var a=0;a>>=1)i++;return 1<>>=13,n[2*a+1]=8191&o,o>>>=13;for(a=2*e;a>=26,e+=i/67108864|0,e+=o>>>26,this.words[n]=67108863&o}return 0!==e&&(this.words[n]=e,this.length++),this},o.prototype.muln=function(t){return this.clone().imuln(t)},o.prototype.sqr=function(){return this.mul(this)},o.prototype.isqr=function(){return this.imul(this.clone())},o.prototype.pow=function(t){var e=function(t){for(var e=new Array(t.bitLength()),n=0;n>>i}return e}(t);if(0===e.length)return new o(1);for(var n=this,r=0;r=0);var e,n=t%26,i=(t-n)/26,o=67108863>>>26-n<<26-n;if(0!==n){var a=0;for(e=0;e>>26-n}a&&(this.words[e]=a,this.length++)}if(0!==i){for(e=this.length-1;e>=0;e--)this.words[e+i]=this.words[e];for(e=0;e=0),i=e?(e-e%26)/26:0;var o=t%26,a=Math.min((t-o)/26,this.length),s=67108863^67108863>>>o<a)for(this.length-=a,c=0;c=0&&(0!==f||c>=i);c--){var l=0|this.words[c];this.words[c]=f<<26-o|l>>>o,f=l&s}return u&&0!==f&&(u.words[u.length++]=f),0===this.length&&(this.words[0]=0,this.length=1),this.strip()},o.prototype.ishrn=function(t,e,n){return r(0===this.negative),this.iushrn(t,e,n)},o.prototype.shln=function(t){return this.clone().ishln(t)},o.prototype.ushln=function(t){return this.clone().iushln(t)},o.prototype.shrn=function(t){return this.clone().ishrn(t)},o.prototype.ushrn=function(t){return this.clone().iushrn(t)},o.prototype.testn=function(t){r("number"==typeof t&&t>=0);var e=t%26,n=(t-e)/26,i=1<=0);var e=t%26,n=(t-e)/26;if(r(0===this.negative,"imaskn works only with positive numbers"),this.length<=n)return this;if(0!==e&&n++,this.length=Math.min(n,this.length),0!==e){var i=67108863^67108863>>>e<=67108864;e++)this.words[e]-=67108864,e===this.length-1?this.words[e+1]=1:this.words[e+1]++;return this.length=Math.max(this.length,e+1),this},o.prototype.isubn=function(t){if(r("number"==typeof t),r(t<67108864),t<0)return this.iaddn(-t);if(0!==this.negative)return this.negative=0,this.iaddn(t),this.negative=1,this;if(this.words[0]-=t,1===this.length&&this.words[0]<0)this.words[0]=-this.words[0],this.negative=1;else for(var e=0;e>26)-(u/67108864|0),this.words[i+n]=67108863&o}for(;i>26,this.words[i+n]=67108863&o;if(0===s)return this.strip();for(r(-1===s),s=0,i=0;i>26,this.words[i]=67108863&o;return this.negative=1,this.strip()},o.prototype._wordDiv=function(t,e){var n=(this.length,t.length),r=this.clone(),i=t,a=0|i.words[i.length-1];0!==(n=26-this._countBits(a))&&(i=i.ushln(n),r.iushln(n),a=0|i.words[i.length-1]);var s,u=r.length-i.length;if("mod"!==e){(s=new o(null)).length=u+1,s.words=new Array(s.length);for(var c=0;c=0;l--){var h=67108864*(0|r.words[i.length+l])+(0|r.words[i.length+l-1]);for(h=Math.min(h/a|0,67108863),r._ishlnsubmul(i,h,l);0!==r.negative;)h--,r.negative=0,r._ishlnsubmul(i,1,l),r.isZero()||(r.negative^=1);s&&(s.words[l]=h)}return s&&s.strip(),r.strip(),"div"!==e&&0!==n&&r.iushrn(n),{div:s||null,mod:r}},o.prototype.divmod=function(t,e,n){return r(!t.isZero()),this.isZero()?{div:new o(0),mod:new o(0)}:0!==this.negative&&0===t.negative?(s=this.neg().divmod(t,e),"mod"!==e&&(i=s.div.neg()),"div"!==e&&(a=s.mod.neg(),n&&0!==a.negative&&a.iadd(t)),{div:i,mod:a}):0===this.negative&&0!==t.negative?(s=this.divmod(t.neg(),e),"mod"!==e&&(i=s.div.neg()),{div:i,mod:s.mod}):0!=(this.negative&t.negative)?(s=this.neg().divmod(t.neg(),e),"div"!==e&&(a=s.mod.neg(),n&&0!==a.negative&&a.isub(t)),{div:s.div,mod:a}):t.length>this.length||this.cmp(t)<0?{div:new o(0),mod:this}:1===t.length?"div"===e?{div:this.divn(t.words[0]),mod:null}:"mod"===e?{div:null,mod:new o(this.modn(t.words[0]))}:{div:this.divn(t.words[0]),mod:new o(this.modn(t.words[0]))}:this._wordDiv(t,e);var i,a,s},o.prototype.div=function(t){return this.divmod(t,"div",!1).div},o.prototype.mod=function(t){return this.divmod(t,"mod",!1).mod},o.prototype.umod=function(t){return this.divmod(t,"mod",!0).mod},o.prototype.divRound=function(t){var e=this.divmod(t);if(e.mod.isZero())return e.div;var n=0!==e.div.negative?e.mod.isub(t):e.mod,r=t.ushrn(1),i=t.andln(1),o=n.cmp(r);return o<0||1===i&&0===o?e.div:0!==e.div.negative?e.div.isubn(1):e.div.iaddn(1)},o.prototype.modn=function(t){r(t<=67108863);for(var e=(1<<26)%t,n=0,i=this.length-1;i>=0;i--)n=(e*n+(0|this.words[i]))%t;return n},o.prototype.idivn=function(t){r(t<=67108863);for(var e=0,n=this.length-1;n>=0;n--){var i=(0|this.words[n])+67108864*e;this.words[n]=i/t|0,e=i%t}return this.strip()},o.prototype.divn=function(t){return this.clone().idivn(t)},o.prototype.egcd=function(t){r(0===t.negative),r(!t.isZero());var e=this,n=t.clone();e=0!==e.negative?e.umod(t):e.clone();for(var i=new o(1),a=new o(0),s=new o(0),u=new o(1),c=0;e.isEven()&&n.isEven();)e.iushrn(1),n.iushrn(1),++c;for(var f=n.clone(),l=e.clone();!e.isZero();){for(var h=0,d=1;0==(e.words[0]&d)&&h<26;++h,d<<=1);if(h>0)for(e.iushrn(h);h-- >0;)(i.isOdd()||a.isOdd())&&(i.iadd(f),a.isub(l)),i.iushrn(1),a.iushrn(1);for(var p=0,g=1;0==(n.words[0]&g)&&p<26;++p,g<<=1);if(p>0)for(n.iushrn(p);p-- >0;)(s.isOdd()||u.isOdd())&&(s.iadd(f),u.isub(l)),s.iushrn(1),u.iushrn(1);e.cmp(n)>=0?(e.isub(n),i.isub(s),a.isub(u)):(n.isub(e),s.isub(i),u.isub(a))}return{a:s,b:u,gcd:n.iushln(c)}},o.prototype._invmp=function(t){r(0===t.negative),r(!t.isZero());var e=this,n=t.clone();e=0!==e.negative?e.umod(t):e.clone();for(var i,a=new o(1),s=new o(0),u=n.clone();e.cmpn(1)>0&&n.cmpn(1)>0;){for(var c=0,f=1;0==(e.words[0]&f)&&c<26;++c,f<<=1);if(c>0)for(e.iushrn(c);c-- >0;)a.isOdd()&&a.iadd(u),a.iushrn(1);for(var l=0,h=1;0==(n.words[0]&h)&&l<26;++l,h<<=1);if(l>0)for(n.iushrn(l);l-- >0;)s.isOdd()&&s.iadd(u),s.iushrn(1);e.cmp(n)>=0?(e.isub(n),a.isub(s)):(n.isub(e),s.isub(a))}return(i=0===e.cmpn(1)?a:s).cmpn(0)<0&&i.iadd(t),i},o.prototype.gcd=function(t){if(this.isZero())return t.abs();if(t.isZero())return this.abs();var e=this.clone(),n=t.clone();e.negative=0,n.negative=0;for(var r=0;e.isEven()&&n.isEven();r++)e.iushrn(1),n.iushrn(1);for(;;){for(;e.isEven();)e.iushrn(1);for(;n.isEven();)n.iushrn(1);var i=e.cmp(n);if(i<0){var o=e;e=n,n=o}else if(0===i||0===n.cmpn(1))break;e.isub(n)}return n.iushln(r)},o.prototype.invm=function(t){return this.egcd(t).a.umod(t)},o.prototype.isEven=function(){return 0==(1&this.words[0])},o.prototype.isOdd=function(){return 1==(1&this.words[0])},o.prototype.andln=function(t){return this.words[0]&t},o.prototype.bincn=function(t){r("number"==typeof t);var e=t%26,n=(t-e)/26,i=1<>>26,s&=67108863,this.words[a]=s}return 0!==o&&(this.words[a]=o,this.length++),this},o.prototype.isZero=function(){return 1===this.length&&0===this.words[0]},o.prototype.cmpn=function(t){var e,n=t<0;if(0!==this.negative&&!n)return-1;if(0===this.negative&&n)return 1;if(this.strip(),this.length>1)e=1;else{n&&(t=-t),r(t<=67108863,"Number is too big");var i=0|this.words[0];e=i===t?0:it.length)return 1;if(this.length=0;n--){var r=0|this.words[n],i=0|t.words[n];if(r!==i){ri&&(e=1);break}}return e},o.prototype.gtn=function(t){return 1===this.cmpn(t)},o.prototype.gt=function(t){return 1===this.cmp(t)},o.prototype.gten=function(t){return this.cmpn(t)>=0},o.prototype.gte=function(t){return this.cmp(t)>=0},o.prototype.ltn=function(t){return-1===this.cmpn(t)},o.prototype.lt=function(t){return-1===this.cmp(t)},o.prototype.lten=function(t){return this.cmpn(t)<=0},o.prototype.lte=function(t){return this.cmp(t)<=0},o.prototype.eqn=function(t){return 0===this.cmpn(t)},o.prototype.eq=function(t){return 0===this.cmp(t)},o.red=function(t){return new x(t)},o.prototype.toRed=function(t){return r(!this.red,"Already a number in reduction context"),r(0===this.negative,"red works only with positives"),t.convertTo(this)._forceRed(t)},o.prototype.fromRed=function(){return r(this.red,"fromRed works only with numbers in reduction context"),this.red.convertFrom(this)},o.prototype._forceRed=function(t){return this.red=t,this},o.prototype.forceRed=function(t){return r(!this.red,"Already a number in reduction context"),this._forceRed(t)},o.prototype.redAdd=function(t){return r(this.red,"redAdd works only with red numbers"),this.red.add(this,t)},o.prototype.redIAdd=function(t){return r(this.red,"redIAdd works only with red numbers"),this.red.iadd(this,t)},o.prototype.redSub=function(t){return r(this.red,"redSub works only with red numbers"),this.red.sub(this,t)},o.prototype.redISub=function(t){return r(this.red,"redISub works only with red numbers"),this.red.isub(this,t)},o.prototype.redShl=function(t){return r(this.red,"redShl works only with red numbers"),this.red.shl(this,t)},o.prototype.redMul=function(t){return r(this.red,"redMul works only with red numbers"),this.red._verify2(this,t),this.red.mul(this,t)},o.prototype.redIMul=function(t){return r(this.red,"redMul works only with red numbers"),this.red._verify2(this,t),this.red.imul(this,t)},o.prototype.redSqr=function(){return r(this.red,"redSqr works only with red numbers"),this.red._verify1(this),this.red.sqr(this)},o.prototype.redISqr=function(){return r(this.red,"redISqr works only with red numbers"),this.red._verify1(this),this.red.isqr(this)},o.prototype.redSqrt=function(){return r(this.red,"redSqrt works only with red numbers"),this.red._verify1(this),this.red.sqrt(this)},o.prototype.redInvm=function(){return r(this.red,"redInvm works only with red numbers"),this.red._verify1(this),this.red.invm(this)},o.prototype.redNeg=function(){return r(this.red,"redNeg works only with red numbers"),this.red._verify1(this),this.red.neg(this)},o.prototype.redPow=function(t){return r(this.red&&!t.red,"redPow(normalNum)"),this.red._verify1(this),this.red.pow(this,t)};var y={k256:null,p224:null,p192:null,p25519:null};function b(t,e){this.name=t,this.p=new o(e,16),this.n=this.p.bitLength(),this.k=new o(1).iushln(this.n).isub(this.p),this.tmp=this._tmp()}function m(){b.call(this,"k256","ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f")}function v(){b.call(this,"p224","ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001")}function _(){b.call(this,"p192","ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff")}function w(){b.call(this,"25519","7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed")}function x(t){if("string"==typeof t){var e=o._prime(t);this.m=e.p,this.prime=e}else r(t.gtn(1),"modulus must be greater than 1"),this.m=t,this.prime=null}function k(t){x.call(this,t),this.shift=this.m.bitLength(),this.shift%26!=0&&(this.shift+=26-this.shift%26),this.r=new o(1).iushln(this.shift),this.r2=this.imod(this.r.sqr()),this.rinv=this.r._invmp(this.m),this.minv=this.rinv.mul(this.r).isubn(1).div(this.m),this.minv=this.minv.umod(this.r),this.minv=this.r.sub(this.minv)}b.prototype._tmp=function(){var t=new o(null);return t.words=new Array(Math.ceil(this.n/13)),t},b.prototype.ireduce=function(t){var e,n=t;do{this.split(n,this.tmp),e=(n=(n=this.imulK(n)).iadd(this.tmp)).bitLength()}while(e>this.n);var r=e0?n.isub(this.p):n.strip(),n},b.prototype.split=function(t,e){t.iushrn(this.n,0,e)},b.prototype.imulK=function(t){return t.imul(this.k)},i(m,b),m.prototype.split=function(t,e){for(var n=Math.min(t.length,9),r=0;r>>22,i=o}i>>>=22,t.words[r-10]=i,0===i&&t.length>10?t.length-=10:t.length-=9},m.prototype.imulK=function(t){t.words[t.length]=0,t.words[t.length+1]=0,t.length+=2;for(var e=0,n=0;n>>=26,t.words[n]=i,e=r}return 0!==e&&(t.words[t.length++]=e),t},o._prime=function(t){if(y[t])return y[t];var e;if("k256"===t)e=new m;else if("p224"===t)e=new v;else if("p192"===t)e=new _;else{if("p25519"!==t)throw new Error("Unknown prime "+t);e=new w}return y[t]=e,e},x.prototype._verify1=function(t){r(0===t.negative,"red works only with positives"),r(t.red,"red works only with red numbers")},x.prototype._verify2=function(t,e){r(0==(t.negative|e.negative),"red works only with positives"),r(t.red&&t.red===e.red,"red works only with red numbers")},x.prototype.imod=function(t){return this.prime?this.prime.ireduce(t)._forceRed(this):t.umod(this.m)._forceRed(this)},x.prototype.neg=function(t){return t.isZero()?t.clone():this.m.sub(t)._forceRed(this)},x.prototype.add=function(t,e){this._verify2(t,e);var n=t.add(e);return n.cmp(this.m)>=0&&n.isub(this.m),n._forceRed(this)},x.prototype.iadd=function(t,e){this._verify2(t,e);var n=t.iadd(e);return n.cmp(this.m)>=0&&n.isub(this.m),n},x.prototype.sub=function(t,e){this._verify2(t,e);var n=t.sub(e);return n.cmpn(0)<0&&n.iadd(this.m),n._forceRed(this)},x.prototype.isub=function(t,e){this._verify2(t,e);var n=t.isub(e);return n.cmpn(0)<0&&n.iadd(this.m),n},x.prototype.shl=function(t,e){return this._verify1(t),this.imod(t.ushln(e))},x.prototype.imul=function(t,e){return this._verify2(t,e),this.imod(t.imul(e))},x.prototype.mul=function(t,e){return this._verify2(t,e),this.imod(t.mul(e))},x.prototype.isqr=function(t){return this.imul(t,t.clone())},x.prototype.sqr=function(t){return this.mul(t,t)},x.prototype.sqrt=function(t){if(t.isZero())return t.clone();var e=this.m.andln(3);if(r(e%2==1),3===e){var n=this.m.add(new o(1)).iushrn(2);return this.pow(t,n)}for(var i=this.m.subn(1),a=0;!i.isZero()&&0===i.andln(1);)a++,i.iushrn(1);r(!i.isZero());var s=new o(1).toRed(this),u=s.redNeg(),c=this.m.subn(1).iushrn(1),f=this.m.bitLength();for(f=new o(2*f*f).toRed(this);0!==this.pow(f,c).cmp(u);)f.redIAdd(u);for(var l=this.pow(f,i),h=this.pow(t,i.addn(1).iushrn(1)),d=this.pow(t,i),p=a;0!==d.cmp(s);){for(var g=d,y=0;0!==g.cmp(s);y++)g=g.redSqr();r(y=0;r--){for(var c=e.words[r],f=u-1;f>=0;f--){var l=c>>f&1;i!==n[0]&&(i=this.sqr(i)),0!==l||0!==a?(a<<=1,a|=l,(4===++s||0===r&&0===f)&&(i=this.mul(i,n[a]),s=0,a=0)):s=0}u=26}return i},x.prototype.convertTo=function(t){var e=t.umod(this.m);return e===t?e.clone():e},x.prototype.convertFrom=function(t){var e=t.clone();return e.red=null,e},o.mont=function(t){return new k(t)},i(k,x),k.prototype.convertTo=function(t){return this.imod(t.ushln(this.shift))},k.prototype.convertFrom=function(t){var e=this.imod(t.mul(this.rinv));return e.red=null,e},k.prototype.imul=function(t,e){if(t.isZero()||e.isZero())return t.words[0]=0,t.length=1,t;var n=t.imul(e),r=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=n.isub(r).iushrn(this.shift),o=i;return i.cmp(this.m)>=0?o=i.isub(this.m):i.cmpn(0)<0&&(o=i.iadd(this.m)),o._forceRed(this)},k.prototype.mul=function(t,e){if(t.isZero()||e.isZero())return new o(0)._forceRed(this);var n=t.mul(e),r=n.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m),i=n.isub(r).iushrn(this.shift),a=i;return i.cmp(this.m)>=0?a=i.isub(this.m):i.cmpn(0)<0&&(a=i.iadd(this.m)),a._forceRed(this)},k.prototype.invm=function(t){return this.imod(t._invmp(this.m).mul(this.r2))._forceRed(this)}}(t,this)}).call(this,n(9)(t))},function(t,e){var n=Array.isArray;t.exports=n},function(t,e){var n,r,i=t.exports={};function o(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function s(t){if(n===setTimeout)return setTimeout(t,0);if((n===o||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:o}catch(t){n=o}try{r="function"==typeof clearTimeout?clearTimeout:a}catch(t){r=a}}();var u,c=[],f=!1,l=-1;function h(){f&&u&&(f=!1,u.length?c=u.concat(c):l=-1,c.length&&d())}function d(){if(!f){var t=s(h);f=!0;for(var e=c.length;e;){for(u=c,c=[];++l1)for(var n=1;n - * @license MIT - */ -var r=n(419),i=n(420),o=n(191);function a(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(t,e){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|t}function p(t,e){if(u.isBuffer(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var n=t.length;if(0===n)return 0;for(var r=!1;;)switch(e){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return U(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return z(t).length;default:if(r)return U(t).length;e=(""+e).toLowerCase(),r=!0}}function g(t,e,n){var r=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return C(this,e,n);case"utf8":case"utf-8":return S(this,e,n);case"ascii":return M(this,e,n);case"latin1":case"binary":return D(this,e,n);case"base64":return A(this,e,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,e,n);default:if(r)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),r=!0}}function y(t,e,n){var r=t[e];t[e]=t[n],t[n]=r}function b(t,e,n,r,i){if(0===t.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:t.length-1),n<0&&(n=t.length+n),n>=t.length){if(i)return-1;n=t.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof e&&(e=u.from(e,r)),u.isBuffer(e))return 0===e.length?-1:m(t,e,n,r,i);if("number"==typeof e)return e&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,e,n):Uint8Array.prototype.lastIndexOf.call(t,e,n):m(t,[e],n,r,i);throw new TypeError("val must be string, number or Buffer")}function m(t,e,n,r,i){var o,a=1,s=t.length,u=e.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(t.length<2||e.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(t,e){return 1===a?t[e]:t.readUInt16BE(e*a)}if(i){var f=-1;for(o=n;os&&(n=s-u),o=n;o>=0;o--){for(var l=!0,h=0;hi&&(r=i):r=i;var o=e.length;if(o%2!=0)throw new TypeError("Invalid hex string");r>o/2&&(r=o/2);for(var a=0;a>8,i=n%256,o.push(i),o.push(r);return o}(e,t.length-n),t,n,r)}function A(t,e,n){return 0===e&&n===t.length?r.fromByteArray(t):r.fromByteArray(t.slice(e,n))}function S(t,e,n){n=Math.min(t.length,n);for(var r=[],i=e;i239?4:c>223?3:c>191?2:1;if(i+l<=n)switch(l){case 1:c<128&&(f=c);break;case 2:128==(192&(o=t[i+1]))&&(u=(31&c)<<6|63&o)>127&&(f=u);break;case 3:o=t[i+1],a=t[i+2],128==(192&o)&&128==(192&a)&&(u=(15&c)<<12|(63&o)<<6|63&a)>2047&&(u<55296||u>57343)&&(f=u);break;case 4:o=t[i+1],a=t[i+2],s=t[i+3],128==(192&o)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&o)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(f=u)}null===f?(f=65533,l=1):f>65535&&(f-=65536,r.push(f>>>10&1023|55296),f=56320|1023&f),r.push(f),i+=l}return function(t){var e=t.length;if(e<=T)return String.fromCharCode.apply(String,t);var n="",r=0;for(;r0&&(t=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(t+=" ... ")),""},u.prototype.compare=function(t,e,n,r,i){if(!u.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===e&&(e=0),void 0===n&&(n=t?t.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),e<0||n>t.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&e>=n)return 0;if(r>=i)return-1;if(e>=n)return 1;if(this===t)return 0;for(var o=(i>>>=0)-(r>>>=0),a=(n>>>=0)-(e>>>=0),s=Math.min(o,a),c=this.slice(r,i),f=t.slice(e,n),l=0;li)&&(n=i),t.length>0&&(n<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var o=!1;;)switch(r){case"hex":return v(this,t,e,n);case"utf8":case"utf-8":return _(this,t,e,n);case"ascii":return w(this,t,e,n);case"latin1":case"binary":return x(this,t,e,n);case"base64":return k(this,t,e,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return E(this,t,e,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var T=4096;function M(t,e,n){var r="";n=Math.min(t.length,n);for(var i=e;ir)&&(n=r);for(var i="",o=e;on)throw new RangeError("Trying to access beyond buffer length")}function I(t,e,n,r,i,o){if(!u.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>i||et.length)throw new RangeError("Index out of range")}function N(t,e,n,r){e<0&&(e=65535+e+1);for(var i=0,o=Math.min(t.length-n,2);i>>8*(r?i:1-i)}function B(t,e,n,r){e<0&&(e=4294967295+e+1);for(var i=0,o=Math.min(t.length-n,4);i>>8*(r?i:3-i)&255}function L(t,e,n,r,i,o){if(n+r>t.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function P(t,e,n,r,o){return o||L(t,0,n,4),i.write(t,e,n,r,23,4),n+4}function F(t,e,n,r,o){return o||L(t,0,n,8),i.write(t,e,n,r,52,8),n+8}u.prototype.slice=function(t,e){var n,r=this.length;if((t=~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),(e=void 0===e?r:~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),e0&&(i*=256);)r+=this[t+--e]*i;return r},u.prototype.readUInt8=function(t,e){return e||R(t,1,this.length),this[t]},u.prototype.readUInt16LE=function(t,e){return e||R(t,2,this.length),this[t]|this[t+1]<<8},u.prototype.readUInt16BE=function(t,e){return e||R(t,2,this.length),this[t]<<8|this[t+1]},u.prototype.readUInt32LE=function(t,e){return e||R(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},u.prototype.readUInt32BE=function(t,e){return e||R(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},u.prototype.readIntLE=function(t,e,n){t|=0,e|=0,n||R(t,e,this.length);for(var r=this[t],i=1,o=0;++o=(i*=128)&&(r-=Math.pow(2,8*e)),r},u.prototype.readIntBE=function(t,e,n){t|=0,e|=0,n||R(t,e,this.length);for(var r=e,i=1,o=this[t+--r];r>0&&(i*=256);)o+=this[t+--r]*i;return o>=(i*=128)&&(o-=Math.pow(2,8*e)),o},u.prototype.readInt8=function(t,e){return e||R(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},u.prototype.readInt16LE=function(t,e){e||R(t,2,this.length);var n=this[t]|this[t+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(t,e){e||R(t,2,this.length);var n=this[t+1]|this[t]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(t,e){return e||R(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},u.prototype.readInt32BE=function(t,e){return e||R(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},u.prototype.readFloatLE=function(t,e){return e||R(t,4,this.length),i.read(this,t,!0,23,4)},u.prototype.readFloatBE=function(t,e){return e||R(t,4,this.length),i.read(this,t,!1,23,4)},u.prototype.readDoubleLE=function(t,e){return e||R(t,8,this.length),i.read(this,t,!0,52,8)},u.prototype.readDoubleBE=function(t,e){return e||R(t,8,this.length),i.read(this,t,!1,52,8)},u.prototype.writeUIntLE=function(t,e,n,r){(t=+t,e|=0,n|=0,r)||I(this,t,e,n,Math.pow(2,8*n)-1,0);var i=1,o=0;for(this[e]=255&t;++o=0&&(o*=256);)this[e+i]=t/o&255;return e+n},u.prototype.writeUInt8=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,1,255,0),u.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[e]=255&t,e+1},u.prototype.writeUInt16LE=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):N(this,t,e,!0),e+2},u.prototype.writeUInt16BE=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):N(this,t,e,!1),e+2},u.prototype.writeUInt32LE=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t):B(this,t,e,!0),e+4},u.prototype.writeUInt32BE=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):B(this,t,e,!1),e+4},u.prototype.writeIntLE=function(t,e,n,r){if(t=+t,e|=0,!r){var i=Math.pow(2,8*n-1);I(this,t,e,n,i-1,-i)}var o=0,a=1,s=0;for(this[e]=255&t;++o>0)-s&255;return e+n},u.prototype.writeIntBE=function(t,e,n,r){if(t=+t,e|=0,!r){var i=Math.pow(2,8*n-1);I(this,t,e,n,i-1,-i)}var o=n-1,a=1,s=0;for(this[e+o]=255&t;--o>=0&&(a*=256);)t<0&&0===s&&0!==this[e+o+1]&&(s=1),this[e+o]=(t/a>>0)-s&255;return e+n},u.prototype.writeInt8=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,1,127,-128),u.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[e]=255&t,e+1},u.prototype.writeInt16LE=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):N(this,t,e,!0),e+2},u.prototype.writeInt16BE=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):N(this,t,e,!1),e+2},u.prototype.writeInt32LE=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24):B(this,t,e,!0),e+4},u.prototype.writeInt32BE=function(t,e,n){return t=+t,e|=0,n||I(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),u.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):B(this,t,e,!1),e+4},u.prototype.writeFloatLE=function(t,e,n){return P(this,t,e,!0,n)},u.prototype.writeFloatBE=function(t,e,n){return P(this,t,e,!1,n)},u.prototype.writeDoubleLE=function(t,e,n){return F(this,t,e,!0,n)},u.prototype.writeDoubleBE=function(t,e,n){return F(this,t,e,!1,n)},u.prototype.copy=function(t,e,n,r){if(n||(n=0),r||0===r||(r=this.length),e>=t.length&&(e=t.length),e||(e=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),t.length-e=0;--i)t[i+e]=this[i+n];else if(o<1e3||!u.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,n=void 0===n?this.length:n>>>0,t||(t=0),"number"==typeof t)for(o=e;o55295&&n<57344){if(!i){if(n>56319){(e-=3)>-1&&o.push(239,191,189);continue}if(a+1===r){(e-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(n<56320){(e-=3)>-1&&o.push(239,191,189),i=n;continue}n=65536+(i-55296<<10|n-56320)}else i&&(e-=3)>-1&&o.push(239,191,189);if(i=null,n<128){if((e-=1)<0)break;o.push(n)}else if(n<2048){if((e-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(n<65536){if((e-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function z(t){return r.toByteArray(function(t){if((t=function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}(t).replace(q,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function Y(t,e,n,r){for(var i=0;i=e.length||i>=t.length);++i)e[i+n]=t[i];return i}}).call(this,n(11))},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}},function(t,e,n){"use strict";var r=n(4),i=n(19).Graph;function o(t,e,n,i){var o;do{o=r.uniqueId(i)}while(t.hasNode(o));return n.dummy=e,t.setNode(o,n),o}function a(t){return r.max(r.map(t.nodes(),(function(e){var n=t.node(e).rank;if(!r.isUndefined(n))return n})))}t.exports={addDummyNode:o,simplify:function(t){var e=(new i).setGraph(t.graph());return r.forEach(t.nodes(),(function(n){e.setNode(n,t.node(n))})),r.forEach(t.edges(),(function(n){var r=e.edge(n.v,n.w)||{weight:0,minlen:1},i=t.edge(n);e.setEdge(n.v,n.w,{weight:r.weight+i.weight,minlen:Math.max(r.minlen,i.minlen)})})),e},asNonCompoundGraph:function(t){var e=new i({multigraph:t.isMultigraph()}).setGraph(t.graph());return r.forEach(t.nodes(),(function(n){t.children(n).length||e.setNode(n,t.node(n))})),r.forEach(t.edges(),(function(n){e.setEdge(n,t.edge(n))})),e},successorWeights:function(t){var e=r.map(t.nodes(),(function(e){var n={};return r.forEach(t.outEdges(e),(function(e){n[e.w]=(n[e.w]||0)+t.edge(e).weight})),n}));return r.zipObject(t.nodes(),e)},predecessorWeights:function(t){var e=r.map(t.nodes(),(function(e){var n={};return r.forEach(t.inEdges(e),(function(e){n[e.v]=(n[e.v]||0)+t.edge(e).weight})),n}));return r.zipObject(t.nodes(),e)},intersectRect:function(t,e){var n,r,i=t.x,o=t.y,a=e.x-i,s=e.y-o,u=t.width/2,c=t.height/2;if(!a&&!s)throw new Error("Not possible to find intersection inside of the rectangle");Math.abs(s)*u>Math.abs(a)*c?(s<0&&(c=-c),n=c*a/s,r=c):(a<0&&(u=-u),n=u,r=u*s/a);return{x:i+n,y:o+r}},buildLayerMatrix:function(t){var e=r.map(r.range(a(t)+1),(function(){return[]}));return r.forEach(t.nodes(),(function(n){var i=t.node(n),o=i.rank;r.isUndefined(o)||(e[o][i.order]=n)})),e},normalizeRanks:function(t){var e=r.min(r.map(t.nodes(),(function(e){return t.node(e).rank})));r.forEach(t.nodes(),(function(n){var i=t.node(n);r.has(i,"rank")&&(i.rank-=e)}))},removeEmptyRanks:function(t){var e=r.min(r.map(t.nodes(),(function(e){return t.node(e).rank}))),n=[];r.forEach(t.nodes(),(function(r){var i=t.node(r).rank-e;n[i]||(n[i]=[]),n[i].push(r)}));var i=0,o=t.graph().nodeRankFactor;r.forEach(n,(function(e,n){r.isUndefined(e)&&n%o!=0?--i:i&&r.forEach(e,(function(e){t.node(e).rank+=i}))}))},addBorderNode:function(t,e,n,r){var i={width:0,height:0};arguments.length>=4&&(i.rank=n,i.order=r);return o(t,"border",i,e)},maxRank:a,partition:function(t,e){var n={lhs:[],rhs:[]};return r.forEach(t,(function(t){e(t)?n.lhs.push(t):n.rhs.push(t)})),n},time:function(t,e){var n=r.now();try{return e()}finally{console.log(t+" time: "+(r.now()-n)+"ms")}},notime:function(t,e){return e()}}},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){var r;try{r={clone:n(235),constant:n(99),each:n(100),filter:n(150),has:n(106),isArray:n(6),isEmpty:n(311),isFunction:n(37),isUndefined:n(161),keys:n(27),map:n(162),reduce:n(164),size:n(314),transform:n(320),union:n(321),values:n(169)}}catch(t){}r||(r=window._),t.exports=r},function(t,e){t.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},function(t,e,n){var r=n(43);t.exports={isSubgraph:function(t,e){return!!t.children(e).length},edgeToId:function(t){return o(t.v)+":"+o(t.w)+":"+o(t.name)},applyStyle:function(t,e){e&&t.attr("style",e)},applyClass:function(t,e,n){e&&t.attr("class",e).attr("class",n+" "+t.attr("class"))},applyTransition:function(t,e){var n=e.graph();if(r.isPlainObject(n)){var i=n.transition;if(r.isFunction(i))return i(t)}return t}};var i=/:/g;function o(t){return t?String(t).replace(i,"\\:"):""}},function(t,e){function n(t,e){if(!t)throw new Error(e||"Assertion failed")}t.exports=n,n.equal=function(t,e,n){if(t!=e)throw new Error(n||"Assertion failed: "+t+" != "+e)}},function(t,e,n){"use strict";var r=e,i=n(5),o=n(15),a=n(213);r.assert=o,r.toArray=a.toArray,r.zero2=a.zero2,r.toHex=a.toHex,r.encode=a.encode,r.getNAF=function(t,e){for(var n=[],r=1<=0;){var o;if(i.isOdd()){var a=i.andln(r-1);o=a>(r>>1)-1?(r>>1)-a:a,i.isubn(o)}else o=0;n.push(o);for(var s=0!==i.cmpn(0)&&0===i.andln(r-1)?e+1:1,u=1;u0||e.cmpn(-i)>0;){var o,a,s,u=t.andln(3)+r&3,c=e.andln(3)+i&3;if(3===u&&(u=-1),3===c&&(c=-1),0==(1&u))o=0;else o=3!==(s=t.andln(7)+r&7)&&5!==s||2!==c?u:-u;if(n[0].push(o),0==(1&c))a=0;else a=3!==(s=e.andln(7)+i&7)&&5!==s||2!==u?c:-c;n[1].push(a),2*r===o+1&&(r=1-r),2*i===a+1&&(i=1-i),t.iushrn(1),e.iushrn(1)}return n},r.cachedProperty=function(t,e,n){var r="_"+e;t.prototype[e]=function(){return void 0!==this[r]?this[r]:this[r]=n.call(this)}},r.parseBytes=function(t){return"string"==typeof t?r.toArray(t,"hex"):t},r.intFromLE=function(t){return new i(t,"hex","le")}},function(t,e,n){ -/** - * @license - * Copyright (c) 2012-2013 Chris Pettitt - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -t.exports={graphlib:n(346),dagre:n(175),intersect:n(403),render:n(405),util:n(14),version:n(417)}},function(t,e,n){var r=n(131),i="object"==typeof self&&self&&self.Object===Object&&self,o=r||i||Function("return this")();t.exports=o},function(t,e,n){var r;try{r=n(22)}catch(t){}r||(r=window.graphlib),t.exports=r},function(t,e){t.exports=function(t){return null!=t&&"object"==typeof t}},function(t,e,n){"use strict";var r=n(15),i=n(2);function o(t,e){return 55296==(64512&t.charCodeAt(e))&&(!(e<0||e+1>=t.length)&&56320==(64512&t.charCodeAt(e+1)))}function a(t){return(t>>>24|t>>>8&65280|t<<8&16711680|(255&t)<<24)>>>0}function s(t){return 1===t.length?"0"+t:t}function u(t){return 7===t.length?"0"+t:6===t.length?"00"+t:5===t.length?"000"+t:4===t.length?"0000"+t:3===t.length?"00000"+t:2===t.length?"000000"+t:1===t.length?"0000000"+t:t}e.inherits=i,e.toArray=function(t,e){if(Array.isArray(t))return t.slice();if(!t)return[];var n=[];if("string"==typeof t)if(e){if("hex"===e)for((t=t.replace(/[^a-z0-9]+/gi,"")).length%2!=0&&(t="0"+t),i=0;i>6|192,n[r++]=63&a|128):o(t,i)?(a=65536+((1023&a)<<10)+(1023&t.charCodeAt(++i)),n[r++]=a>>18|240,n[r++]=a>>12&63|128,n[r++]=a>>6&63|128,n[r++]=63&a|128):(n[r++]=a>>12|224,n[r++]=a>>6&63|128,n[r++]=63&a|128)}else for(i=0;i>>0}return a},e.split32=function(t,e){for(var n=new Array(4*t.length),r=0,i=0;r>>24,n[i+1]=o>>>16&255,n[i+2]=o>>>8&255,n[i+3]=255&o):(n[i+3]=o>>>24,n[i+2]=o>>>16&255,n[i+1]=o>>>8&255,n[i]=255&o)}return n},e.rotr32=function(t,e){return t>>>e|t<<32-e},e.rotl32=function(t,e){return t<>>32-e},e.sum32=function(t,e){return t+e>>>0},e.sum32_3=function(t,e,n){return t+e+n>>>0},e.sum32_4=function(t,e,n,r){return t+e+n+r>>>0},e.sum32_5=function(t,e,n,r,i){return t+e+n+r+i>>>0},e.sum64=function(t,e,n,r){var i=t[e],o=r+t[e+1]>>>0,a=(o>>0,t[e+1]=o},e.sum64_hi=function(t,e,n,r){return(e+r>>>0>>0},e.sum64_lo=function(t,e,n,r){return e+r>>>0},e.sum64_4_hi=function(t,e,n,r,i,o,a,s){var u=0,c=e;return u+=(c=c+r>>>0)>>0)>>0)>>0},e.sum64_4_lo=function(t,e,n,r,i,o,a,s){return e+r+o+s>>>0},e.sum64_5_hi=function(t,e,n,r,i,o,a,s,u,c){var f=0,l=e;return f+=(l=l+r>>>0)>>0)>>0)>>0)>>0},e.sum64_5_lo=function(t,e,n,r,i,o,a,s,u,c){return e+r+o+s+c>>>0},e.rotr64_hi=function(t,e,n){return(e<<32-n|t>>>n)>>>0},e.rotr64_lo=function(t,e,n){return(t<<32-n|e>>>n)>>>0},e.shr64_hi=function(t,e,n){return t>>>n},e.shr64_lo=function(t,e,n){return(t<<32-n|e>>>n)>>>0}},function(t,e,n){var r=n(234);t.exports={Graph:r.Graph,json:n(336),alg:n(337),version:r.version}},function(t,e,n){(function(t){t.exports=function(){"use strict";var e,r;function i(){return e.apply(null,arguments)}function o(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function a(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function s(t){return void 0===t}function u(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function c(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function f(t,e){var n,r=[];for(n=0;n>>0,r=0;rAt(t)?(o=t+1,a=s-At(t)):(o=t,a=s),{year:o,dayOfYear:a}}function Vt(t,e,n){var r,i,o=zt(t.year(),e,n),a=Math.floor((t.dayOfYear()-o-1)/7)+1;return a<1?r=a+Ht(i=t.year()-1,e,n):a>Ht(t.year(),e,n)?(r=a-Ht(t.year(),e,n),i=t.year()+1):(i=t.year(),r=a),{week:r,year:i}}function Ht(t,e,n){var r=zt(t,e,n),i=zt(t+1,e,n);return(At(t)-r+i)/7}V("w",["ww",2],"wo","week"),V("W",["WW",2],"Wo","isoWeek"),N("week","w"),N("isoWeek","W"),F("week",5),F("isoWeek",5),ft("w",J),ft("ww",J,W),ft("W",J),ft("WW",J,W),gt(["w","ww","W","WW"],(function(t,e,n,r){e[r.substr(0,1)]=k(t)})),V("d",0,"do","day"),V("dd",0,0,(function(t){return this.localeData().weekdaysMin(this,t)})),V("ddd",0,0,(function(t){return this.localeData().weekdaysShort(this,t)})),V("dddd",0,0,(function(t){return this.localeData().weekdays(this,t)})),V("e",0,0,"weekday"),V("E",0,0,"isoWeekday"),N("day","d"),N("weekday","e"),N("isoWeekday","E"),F("day",11),F("weekday",11),F("isoWeekday",11),ft("d",J),ft("e",J),ft("E",J),ft("dd",(function(t,e){return e.weekdaysMinRegex(t)})),ft("ddd",(function(t,e){return e.weekdaysShortRegex(t)})),ft("dddd",(function(t,e){return e.weekdaysRegex(t)})),gt(["dd","ddd","dddd"],(function(t,e,n,r){var i=n._locale.weekdaysParse(t,r,n._strict);null!=i?e.d=i:p(n).invalidWeekday=t})),gt(["d","e","E"],(function(t,e,n,r){e[r]=k(t)}));var $t="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Gt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Wt="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Kt=ut,Xt=ut,Zt=ut;function Jt(){function t(t,e){return e.length-t.length}var e,n,r,i,o,a=[],s=[],u=[],c=[];for(e=0;e<7;e++)n=d([2e3,1]).day(e),r=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),o=this.weekdays(n,""),a.push(r),s.push(i),u.push(o),c.push(r),c.push(i),c.push(o);for(a.sort(t),s.sort(t),u.sort(t),c.sort(t),e=0;e<7;e++)s[e]=ht(s[e]),u[e]=ht(u[e]),c[e]=ht(c[e]);this._weekdaysRegex=new RegExp("^("+c.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function Qt(){return this.hours()%12||12}function te(t,e){V(t,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)}))}function ee(t,e){return e._meridiemParse}V("H",["HH",2],0,"hour"),V("h",["hh",2],0,Qt),V("k",["kk",2],0,(function(){return this.hours()||24})),V("hmm",0,0,(function(){return""+Qt.apply(this)+q(this.minutes(),2)})),V("hmmss",0,0,(function(){return""+Qt.apply(this)+q(this.minutes(),2)+q(this.seconds(),2)})),V("Hmm",0,0,(function(){return""+this.hours()+q(this.minutes(),2)})),V("Hmmss",0,0,(function(){return""+this.hours()+q(this.minutes(),2)+q(this.seconds(),2)})),te("a",!0),te("A",!1),N("hour","h"),F("hour",13),ft("a",ee),ft("A",ee),ft("H",J),ft("h",J),ft("k",J),ft("HH",J,W),ft("hh",J,W),ft("kk",J,W),ft("hmm",Q),ft("hmmss",tt),ft("Hmm",Q),ft("Hmmss",tt),pt(["H","HH"],vt),pt(["k","kk"],(function(t,e,n){var r=k(t);e[vt]=24===r?0:r})),pt(["a","A"],(function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t})),pt(["h","hh"],(function(t,e,n){e[vt]=k(t),p(n).bigHour=!0})),pt("hmm",(function(t,e,n){var r=t.length-2;e[vt]=k(t.substr(0,r)),e[_t]=k(t.substr(r)),p(n).bigHour=!0})),pt("hmmss",(function(t,e,n){var r=t.length-4,i=t.length-2;e[vt]=k(t.substr(0,r)),e[_t]=k(t.substr(r,2)),e[wt]=k(t.substr(i)),p(n).bigHour=!0})),pt("Hmm",(function(t,e,n){var r=t.length-2;e[vt]=k(t.substr(0,r)),e[_t]=k(t.substr(r))})),pt("Hmmss",(function(t,e,n){var r=t.length-4,i=t.length-2;e[vt]=k(t.substr(0,r)),e[_t]=k(t.substr(r,2)),e[wt]=k(t.substr(i))}));var ne,re=Dt("Hours",!0),ie={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Nt,monthsShort:Bt,week:{dow:0,doy:6},weekdays:$t,weekdaysMin:Wt,weekdaysShort:Gt,meridiemParse:/[ap]\.?m?\.?/i},oe={},ae={};function se(t){return t?t.toLowerCase().replace("_","-"):t}function ue(e){var r=null;if(!oe[e]&&void 0!==t&&t&&t.exports)try{r=ne._abbr,n(233)("./"+e),ce(r)}catch(e){}return oe[e]}function ce(t,e){var n;return t&&((n=s(e)?le(t):fe(t,e))?ne=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),ne._abbr}function fe(t,e){if(null!==e){var n,r=ie;if(e.abbr=t,null!=oe[t])D("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),r=oe[t]._config;else if(null!=e.parentLocale)if(null!=oe[e.parentLocale])r=oe[e.parentLocale]._config;else{if(null==(n=ue(e.parentLocale)))return ae[e.parentLocale]||(ae[e.parentLocale]=[]),ae[e.parentLocale].push({name:t,config:e}),null;r=n._config}return oe[t]=new R(O(r,e)),ae[t]&&ae[t].forEach((function(t){fe(t.name,t.config)})),ce(t),oe[t]}return delete oe[t],null}function le(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return ne;if(!o(t)){if(e=ue(t))return e;t=[t]}return function(t){for(var e,n,r,i,o=0;o=e&&E(i,n,!0)>=e-1)break;e--}o++}return ne}(t)}function he(t){var e,n=t._a;return n&&-2===p(t).overflow&&(e=n[bt]<0||11Rt(n[yt],n[bt])?mt:n[vt]<0||24Ht(n,o,a)?p(t)._overflowWeeks=!0:null!=u?p(t)._overflowWeekday=!0:(s=Yt(n,r,i,o,a),t._a[yt]=s.year,t._dayOfYear=s.dayOfYear)}(t),null!=t._dayOfYear&&(a=de(t._a[yt],r[yt]),(t._dayOfYear>At(a)||0===t._dayOfYear)&&(p(t)._overflowDayOfYear=!0),n=Ut(a,0,t._dayOfYear),t._a[bt]=n.getUTCMonth(),t._a[mt]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=s[e]=r[e];for(;e<7;e++)t._a[e]=s[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[vt]&&0===t._a[_t]&&0===t._a[wt]&&0===t._a[xt]&&(t._nextDay=!0,t._a[vt]=0),t._d=(t._useUTC?Ut:function(t,e,n,r,i,o,a){var s=new Date(t,e,n,r,i,o,a);return t<100&&0<=t&&isFinite(s.getFullYear())&&s.setFullYear(t),s}).apply(null,s),o=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[vt]=24),t._w&&void 0!==t._w.d&&t._w.d!==o&&(p(t).weekdayMismatch=!0)}}var ge=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ye=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,be=/Z|[+-]\d\d(?::?\d\d)?/,me=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],ve=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],_e=/^\/?Date\((\-?\d+)/i;function we(t){var e,n,r,i,o,a,s=t._i,u=ge.exec(s)||ye.exec(s);if(u){for(p(t).iso=!0,e=0,n=me.length;en.valueOf():n.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},fn.isLocal=function(){return!!this.isValid()&&!this._isUTC},fn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},fn.isUtc=Ue,fn.isUTC=Ue,fn.zoneAbbr=function(){return this._isUTC?"UTC":""},fn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},fn.dates=S("dates accessor is deprecated. Use date instead.",rn),fn.months=S("months accessor is deprecated. Use month instead",Pt),fn.years=S("years accessor is deprecated. Use year instead",Mt),fn.zone=S("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()})),fn.isDSTShifted=S("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!s(this._isDSTShifted))return this._isDSTShifted;var t={};if(m(t,this),(t=Se(t))._a){var e=t._isUTC?d(t._a):Me(t._a);this._isDSTShifted=this.isValid()&&0l&&M.push("'"+this.terminals_[A]+"'");C=p.showPosition?"Parse error on line "+(u+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(u+1)+": Unexpected "+(_==h?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:b,expected:M})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),o.push(p.yylloc),n.push(k[1]),_=null,w?(_=w,w=null):(c=p.yyleng,s=p.yytext,u=p.yylineno,b=p.yylloc,f>0&&f--);break;case 2:if(S=this.productions_[k[1]][1],D.$=i[i.length-S],D._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},m&&(D._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(E=this.performAction.apply(D,[s,c,u,g.yy,k[1],i,o].concat(d))))return E;S&&(n=n.slice(0,-1*S*2),i=i.slice(0,-1*S),o=o.slice(0,-1*S)),n.push(this.productions_[k[1]][0]),i.push(D.$),o.push(D._$),T=a[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0}},l={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var o in i)this[o]=i[o];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),o=0;oe[0].length)){if(e=n,r=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return 10;case 1:case 2:case 3:break;case 4:this.begin("href");break;case 5:this.popState();break;case 6:return 23;case 7:this.begin("callbackname");break;case 8:this.popState();break;case 9:this.popState(),this.begin("callbackargs");break;case 10:return 21;case 11:this.popState();break;case 12:return 22;case 13:this.begin("click");break;case 14:this.popState();break;case 15:return 20;case 16:return 4;case 17:return 11;case 18:return 12;case 19:return 13;case 20:return 14;case 21:return"date";case 22:return 15;case 23:return 16;case 24:return 18;case 25:return 19;case 26:return":";case 27:return 6;case 28:return"INVALID"}},rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{callbackargs:{rules:[11,12],inclusive:!1},callbackname:{rules:[8,9,10],inclusive:!1},href:{rules:[5,6],inclusive:!1},click:{rules:[14,15],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,7,13,16,17,18,19,20,21,22,23,24,25,26,27,28],inclusive:!0}}};function h(){this.yy={}}return f.lexer=l,h.prototype=f,f.Parser=h,new h}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(28).readFileSync(n(29).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(7),n(9)(t))},function(t,e,n){var r=n(134),i=n(95),o=n(24);t.exports=function(t){return o(t)?r(t):i(t)}},function(t,e){},function(t,e,n){(function(t){function n(t,e){for(var n=0,r=t.length-1;r>=0;r--){var i=t[r];"."===i?t.splice(r,1):".."===i?(t.splice(r,1),n++):n&&(t.splice(r,1),n--)}if(e)for(;n--;n)t.unshift("..");return t}function r(t,e){if(t.filter)return t.filter(e);for(var n=[],r=0;r=-1&&!i;o--){var a=o>=0?arguments[o]:t.cwd();if("string"!=typeof a)throw new TypeError("Arguments to path.resolve must be strings");a&&(e=a+"/"+e,i="/"===a.charAt(0))}return(i?"/":"")+(e=n(r(e.split("/"),(function(t){return!!t})),!i).join("/"))||"."},e.normalize=function(t){var o=e.isAbsolute(t),a="/"===i(t,-1);return(t=n(r(t.split("/"),(function(t){return!!t})),!o).join("/"))||o||(t="."),t&&a&&(t+="/"),(o?"/":"")+t},e.isAbsolute=function(t){return"/"===t.charAt(0)},e.join=function(){var t=Array.prototype.slice.call(arguments,0);return e.normalize(r(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},e.relative=function(t,n){function r(t){for(var e=0;e=0&&""===t[n];n--);return e>n?[]:t.slice(e,n-e+1)}t=e.resolve(t).substr(1),n=e.resolve(n).substr(1);for(var i=r(t.split("/")),o=r(n.split("/")),a=Math.min(i.length,o.length),s=a,u=0;u=1;--o)if(47===(e=t.charCodeAt(o))){if(!i){r=o;break}}else i=!1;return-1===r?n?"/":".":n&&1===r?"/":t.slice(0,r)},e.basename=function(t,e){var n=function(t){"string"!=typeof t&&(t+="");var e,n=0,r=-1,i=!0;for(e=t.length-1;e>=0;--e)if(47===t.charCodeAt(e)){if(!i){n=e+1;break}}else-1===r&&(i=!1,r=e+1);return-1===r?"":t.slice(n,r)}(t);return e&&n.substr(-1*e.length)===e&&(n=n.substr(0,n.length-e.length)),n},e.extname=function(t){"string"!=typeof t&&(t+="");for(var e=-1,n=0,r=-1,i=!0,o=0,a=t.length-1;a>=0;--a){var s=t.charCodeAt(a);if(47!==s)-1===r&&(i=!1,r=a+1),46===s?-1===e?e=a:1!==o&&(o=1):-1!==e&&(o=-1);else if(!i){n=a+1;break}}return-1===e||-1===r||0===o||1===o&&e===r-1&&e===n+1?"":t.slice(e,r)};var i="b"==="ab".substr(-1)?function(t,e,n){return t.substr(e,n)}:function(t,e,n){return e<0&&(e=t.length+e),t.substr(e,n)}}).call(this,n(7))},function(t,e,n){var r;if(!r)try{r=n(0)}catch(t){}r||(r=window.d3),t.exports=r},function(t,e,n){var r=n(3).Buffer,i=n(112).Transform,o=n(117).StringDecoder;function a(t){i.call(this),this.hashMode="string"==typeof t,this.hashMode?this[t]=this._finalOrDigest:this.final=this._finalOrDigest,this._final&&(this.__final=this._final,this._final=null),this._decoder=null,this._encoding=null}n(2)(a,i),a.prototype.update=function(t,e,n){"string"==typeof t&&(t=r.from(t,e));var i=this._update(t);return this.hashMode?this:(n&&(i=this._toString(i,n)),i)},a.prototype.setAutoPadding=function(){},a.prototype.getAuthTag=function(){throw new Error("trying to get auth tag in unsupported state")},a.prototype.setAuthTag=function(){throw new Error("trying to set auth tag in unsupported state")},a.prototype.setAAD=function(){throw new Error("trying to set aad in unsupported state")},a.prototype._transform=function(t,e,n){var r;try{this.hashMode?this._update(t):this.push(this._update(t))}catch(t){r=t}finally{n(r)}},a.prototype._flush=function(t){var e;try{this.push(this.__final())}catch(t){e=t}t(e)},a.prototype._finalOrDigest=function(t){var e=this.__final()||r.alloc(0);return t&&(e=this._toString(e,t,!0)),e},a.prototype._toString=function(t,e,n){if(this._decoder||(this._decoder=new o(e),this._encoding=e),this._encoding!==e)throw new Error("can't switch encodings");var r=this._decoder.write(t);return n&&(r+=this._decoder.end()),r},t.exports=a},function(t,e,n){var r=n(246),i=n(251);t.exports=function(t,e){var n=i(t,e);return r(n)?n:void 0}},function(t,e,n){var r=n(38),i=n(247),o=n(248),a="[object Null]",s="[object Undefined]",u=r?r.toStringTag:void 0;t.exports=function(t){return null==t?void 0===t?s:a:u&&u in Object(t)?i(t):o(t)}},function(t,e){t.exports=function(t){return t}},function(t,e,n){"use strict";var r=n(78),i=Object.keys||function(t){var e=[];for(var n in t)e.push(n);return e};t.exports=l;var o=n(54);o.inherits=n(2);var a=n(193),s=n(116);o.inherits(l,a);for(var u=i(s.prototype),c=0;co)throw new RangeError("requested too many random bytes");var n=a.allocUnsafe(t);if(t>0)if(t>i)for(var u=0;u=this._finalSize&&(this._update(this._block),this._block.fill(0));var n=8*this._len;if(n<=4294967295)this._block.writeUInt32BE(n,this._blockSize-4);else{var r=(4294967295&n)>>>0,i=(n-r)/4294967296;this._block.writeUInt32BE(i,this._blockSize-8),this._block.writeUInt32BE(r,this._blockSize-4)}this._update(this._block);var o=this._hash();return t?o.toString(t):o},i.prototype._update=function(){throw new Error("_update must be implemented by subclass")},t.exports=i},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,12],n=[1,15],r=[1,13],i=[1,14],o=[1,17],a=[1,18],s=[1,19],u=[6,8],c=[1,28],f=[1,29],l=[1,30],h=[1,31],d=[1,32],p=[1,33],g=[6,8,13,18,26,29,30,31,32,33,34],y=[6,8,13,18,22,26,29,30,31,32,33,34,48,49,50],b=[26,48,49,50],m=[26,33,34,48,49,50],v=[26,29,30,31,32,48,49,50],_=[6,8,13],w=[1,50],x={trace:function(){},yy:{},symbols_:{error:2,mermaidDoc:3,graphConfig:4,CLASS_DIAGRAM:5,NEWLINE:6,statements:7,EOF:8,statement:9,className:10,alphaNumToken:11,relationStatement:12,LABEL:13,classStatement:14,methodStatement:15,annotationStatement:16,CLASS:17,STRUCT_START:18,members:19,STRUCT_STOP:20,ANNOTATION_START:21,ANNOTATION_END:22,MEMBER:23,SEPARATOR:24,relation:25,STR:26,relationType:27,lineType:28,AGGREGATION:29,EXTENSION:30,COMPOSITION:31,DEPENDENCY:32,LINE:33,DOTTED_LINE:34,commentToken:35,textToken:36,graphCodeTokens:37,textNoTagsToken:38,TAGSTART:39,TAGEND:40,"==":41,"--":42,PCT:43,DEFAULT:44,SPACE:45,MINUS:46,keywords:47,UNICODE_TEXT:48,NUM:49,ALPHA:50,$accept:0,$end:1},terminals_:{2:"error",5:"CLASS_DIAGRAM",6:"NEWLINE",8:"EOF",13:"LABEL",17:"CLASS",18:"STRUCT_START",20:"STRUCT_STOP",21:"ANNOTATION_START",22:"ANNOTATION_END",23:"MEMBER",24:"SEPARATOR",26:"STR",29:"AGGREGATION",30:"EXTENSION",31:"COMPOSITION",32:"DEPENDENCY",33:"LINE",34:"DOTTED_LINE",37:"graphCodeTokens",39:"TAGSTART",40:"TAGEND",41:"==",42:"--",43:"PCT",44:"DEFAULT",45:"SPACE",46:"MINUS",47:"keywords",48:"UNICODE_TEXT",49:"NUM",50:"ALPHA"},productions_:[0,[3,1],[4,4],[7,1],[7,2],[7,3],[10,2],[10,1],[9,1],[9,2],[9,1],[9,1],[9,1],[14,2],[14,5],[16,4],[19,1],[19,2],[15,1],[15,2],[15,1],[15,1],[12,3],[12,4],[12,4],[12,5],[25,3],[25,2],[25,2],[25,1],[27,1],[27,1],[27,1],[27,1],[28,1],[28,1],[35,1],[35,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,1],[38,1],[38,1],[38,1],[38,1],[11,1],[11,1],[11,1]],performAction:function(t,e,n,r,i,o,a){var s=o.length-1;switch(i){case 6:this.$=o[s-1]+o[s];break;case 7:this.$=o[s];break;case 8:r.addRelation(o[s]);break;case 9:o[s-1].title=r.cleanupLabel(o[s]),r.addRelation(o[s-1]);break;case 13:r.addClass(o[s]);break;case 14:r.addClass(o[s-3]),r.addMembers(o[s-3],o[s-1]);break;case 15:r.addAnnotation(o[s],o[s-2]);break;case 16:this.$=[o[s]];break;case 17:o[s].push(o[s-1]),this.$=o[s];break;case 18:break;case 19:r.addMember(o[s-1],r.cleanupLabel(o[s]));break;case 20:case 21:break;case 22:this.$={id1:o[s-2],id2:o[s],relation:o[s-1],relationTitle1:"none",relationTitle2:"none"};break;case 23:this.$={id1:o[s-3],id2:o[s],relation:o[s-1],relationTitle1:o[s-2],relationTitle2:"none"};break;case 24:this.$={id1:o[s-3],id2:o[s],relation:o[s-2],relationTitle1:"none",relationTitle2:o[s-1]};break;case 25:this.$={id1:o[s-4],id2:o[s],relation:o[s-2],relationTitle1:o[s-3],relationTitle2:o[s-1]};break;case 26:this.$={type1:o[s-2],type2:o[s],lineType:o[s-1]};break;case 27:this.$={type1:"none",type2:o[s],lineType:o[s-1]};break;case 28:this.$={type1:o[s-1],type2:"none",lineType:o[s]};break;case 29:this.$={type1:"none",type2:"none",lineType:o[s]};break;case 30:this.$=r.relationType.AGGREGATION;break;case 31:this.$=r.relationType.EXTENSION;break;case 32:this.$=r.relationType.COMPOSITION;break;case 33:this.$=r.relationType.DEPENDENCY;break;case 34:this.$=r.lineType.LINE;break;case 35:this.$=r.lineType.DOTTED_LINE}},table:[{3:1,4:2,5:[1,3]},{1:[3]},{1:[2,1]},{6:[1,4]},{7:5,9:6,10:11,11:16,12:7,14:8,15:9,16:10,17:e,21:n,23:r,24:i,48:o,49:a,50:s},{8:[1,20]},{6:[1,21],8:[2,3]},t(u,[2,8],{13:[1,22]}),t(u,[2,10]),t(u,[2,11]),t(u,[2,12]),t(u,[2,18],{25:23,27:26,28:27,13:[1,25],26:[1,24],29:c,30:f,31:l,32:h,33:d,34:p}),{10:34,11:16,48:o,49:a,50:s},t(u,[2,20]),t(u,[2,21]),{11:35,48:o,49:a,50:s},t(g,[2,7],{11:16,10:36,48:o,49:a,50:s}),t(y,[2,49]),t(y,[2,50]),t(y,[2,51]),{1:[2,2]},{7:37,8:[2,4],9:6,10:11,11:16,12:7,14:8,15:9,16:10,17:e,21:n,23:r,24:i,48:o,49:a,50:s},t(u,[2,9]),{10:38,11:16,26:[1,39],48:o,49:a,50:s},{25:40,27:26,28:27,29:c,30:f,31:l,32:h,33:d,34:p},t(u,[2,19]),{28:41,33:d,34:p},t(b,[2,29],{27:42,29:c,30:f,31:l,32:h}),t(m,[2,30]),t(m,[2,31]),t(m,[2,32]),t(m,[2,33]),t(v,[2,34]),t(v,[2,35]),t(u,[2,13],{18:[1,43]}),{22:[1,44]},t(g,[2,6]),{8:[2,5]},t(_,[2,22]),{10:45,11:16,48:o,49:a,50:s},{10:46,11:16,26:[1,47],48:o,49:a,50:s},t(b,[2,28],{27:48,29:c,30:f,31:l,32:h}),t(b,[2,27]),{19:49,23:w},{10:51,11:16,48:o,49:a,50:s},t(_,[2,24]),t(_,[2,23]),{10:52,11:16,48:o,49:a,50:s},t(b,[2,26]),{20:[1,53]},{19:54,20:[2,16],23:w},t(u,[2,15]),t(_,[2,25]),t(u,[2,14]),{20:[2,17]}],defaultActions:{2:[2,1],20:[2,2],37:[2,5],54:[2,17]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],o=[],a=this.table,s="",u=0,c=0,f=0,l=2,h=1,d=o.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var b=p.yylloc;o.push(b);var m=p.options&&p.options.ranges;function v(){var t;return"number"!=typeof(t=r.pop()||p.lex()||h)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,w,x,k,E,A,S,T,M,D={};;){if(x=n[n.length-1],this.defaultActions[x]?k=this.defaultActions[x]:(null==_&&(_=v()),k=a[x]&&a[x][_]),void 0===k||!k.length||!k[0]){var C="";for(A in M=[],a[x])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=p.showPosition?"Parse error on line "+(u+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(u+1)+": Unexpected "+(_==h?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:b,expected:M})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),o.push(p.yylloc),n.push(k[1]),_=null,w?(_=w,w=null):(c=p.yyleng,s=p.yytext,u=p.yylineno,b=p.yylloc,f>0&&f--);break;case 2:if(S=this.productions_[k[1]][1],D.$=i[i.length-S],D._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},m&&(D._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(E=this.performAction.apply(D,[s,c,u,g.yy,k[1],i,o].concat(d))))return E;S&&(n=n.slice(0,-1*S*2),i=i.slice(0,-1*S),o=o.slice(0,-1*S)),n.push(this.productions_[k[1]][0]),i.push(D.$),o.push(D._$),T=a[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0}},k={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var o in i)this[o]=i[o];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),o=0;oe[0].length)){if(e=n,r=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,r){switch(n){case 0:break;case 1:return 6;case 2:break;case 3:return 5;case 4:return this.begin("struct"),18;case 5:return this.popState(),20;case 6:break;case 7:return"MEMBER";case 8:return 17;case 9:return 21;case 10:return 22;case 11:this.begin("string");break;case 12:this.popState();break;case 13:return"STR";case 14:case 15:return 30;case 16:case 17:return 32;case 18:return 31;case 19:return 29;case 20:return 33;case 21:return 34;case 22:return 13;case 23:return 46;case 24:return"DOT";case 25:return"PLUS";case 26:return 43;case 27:case 28:return"EQUALS";case 29:return 50;case 30:return"PUNCTUATION";case 31:return 49;case 32:return 48;case 33:return 45;case 34:return 8}},rules:[/^(?:%%[^\n]*)/,/^(?:\n+)/,/^(?:\s+)/,/^(?:classDiagram\b)/,/^(?:[\{])/,/^(?:\})/,/^(?:[\n])/,/^(?:[^\{\}\n]*)/,/^(?:class\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:--)/,/^(?:\.\.)/,/^(?::[^\n;]+)/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:[!"#$%&'*+,-.`?\\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],conditions:{string:{rules:[12,13],inclusive:!1},struct:{rules:[5,6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,8,9,10,11,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],inclusive:!0}}};function E(){this.yy={}}return x.lexer=k,E.prototype=x,x.Parser=E,new E}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(28).readFileSync(n(29).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(7),n(9)(t))},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,2],n=[1,3],r=[1,4],i=[2,4],o=[1,9],a=[1,11],s=[1,13],u=[1,14],c=[1,15],f=[1,16],l=[1,21],h=[1,17],d=[1,18],p=[1,19],g=[1,20],y=[1,22],b=[1,4,5,13,14,16,18,19,21,22,23,24,25,28],m=[1,4,5,11,12,13,14,16,18,19,21,22,23,24,25,28],v=[4,5,13,14,16,18,19,21,22,23,24,25,28],_={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,idStatement:10,DESCR:11,"--\x3e":12,HIDE_EMPTY:13,scale:14,WIDTH:15,COMPOSIT_STATE:16,STRUCT_START:17,STRUCT_STOP:18,STATE_DESCR:19,AS:20,ID:21,FORK:22,JOIN:23,CONCURRENT:24,note:25,notePosition:26,NOTE_TEXT:27,EDGE_STATE:28,left_of:29,right_of:30,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",11:"DESCR",12:"--\x3e",13:"HIDE_EMPTY",14:"scale",15:"WIDTH",16:"COMPOSIT_STATE",17:"STRUCT_START",18:"STRUCT_STOP",19:"STATE_DESCR",20:"AS",21:"ID",22:"FORK",23:"JOIN",24:"CONCURRENT",25:"note",27:"NOTE_TEXT",28:"EDGE_STATE",29:"left_of",30:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,4],[9,4],[10,1],[10,1],[26,1],[26,1]],performAction:function(t,e,n,r,i,o,a){var s=o.length-1;switch(i){case 3:return r.setRootDoc(o[s]),o[s];case 4:this.$=[];break;case 5:"nl"!=o[s]&&(o[s-1].push(o[s]),this.$=o[s-1]);break;case 6:case 7:this.$=o[s];break;case 8:this.$="nl";break;case 9:this.$={stmt:"state",id:o[s],type:"default",description:""};break;case 10:this.$={stmt:"state",id:o[s-1],type:"default",description:o[s].trim()};break;case 11:this.$={stmt:"relation",state1:{stmt:"state",id:o[s-2],type:"default",description:""},state2:{stmt:"state",id:o[s],type:"default",description:""}};break;case 12:this.$={stmt:"relation",state1:{stmt:"state",id:o[s-3],type:"default",description:""},state2:{stmt:"state",id:o[s-1],type:"default",description:""},description:o[s].substr(1).trim()};break;case 16:this.$={stmt:"state",id:o[s-3],type:"default",description:"",doc:o[s-1]};break;case 17:var u=o[s],c=o[s-2].trim();if(o[s].match(":")){var f=o[s].split(":");u=f[0],c=[c,f[1]]}this.$={stmt:"state",id:u,type:"default",description:c};break;case 18:this.$={stmt:"state",id:o[s-3],type:"default",description:o[s-5],doc:o[s-1]};break;case 19:this.$={stmt:"state",id:o[s],type:"fork"};break;case 20:this.$={stmt:"state",id:o[s],type:"join"};break;case 21:this.$={stmt:"state",id:r.getDividerId(),type:"divider"};break;case 22:this.$={stmt:"state",id:o[s-1].trim(),note:{position:o[s-2].trim(),text:o[s].trim()}};break;case 24:case 25:this.$=o[s]}},table:[{3:1,4:e,5:n,6:r},{1:[3]},{3:5,4:e,5:n,6:r},{3:6,4:e,5:n,6:r},t([1,4,5,13,14,16,19,21,22,23,24,25,28],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:o,5:a,8:8,9:10,10:12,13:s,14:u,16:c,19:f,21:l,22:h,23:d,24:p,25:g,28:y},t(b,[2,5]),{9:23,10:12,13:s,14:u,16:c,19:f,21:l,22:h,23:d,24:p,25:g,28:y},t(b,[2,7]),t(b,[2,8]),t(b,[2,9],{11:[1,24],12:[1,25]}),t(b,[2,13]),{15:[1,26]},t(b,[2,15],{17:[1,27]}),{20:[1,28]},t(b,[2,19]),t(b,[2,20]),t(b,[2,21]),{26:29,27:[1,30],29:[1,31],30:[1,32]},t(m,[2,24]),t(m,[2,25]),t(b,[2,6]),t(b,[2,10]),{10:33,21:l,28:y},t(b,[2,14]),t(v,i,{7:34}),{21:[1,35]},{21:[1,36]},{20:[1,37]},{21:[2,26]},{21:[2,27]},t(b,[2,11],{11:[1,38]}),{4:o,5:a,8:8,9:10,10:12,13:s,14:u,16:c,18:[1,39],19:f,21:l,22:h,23:d,24:p,25:g,28:y},t(b,[2,17],{17:[1,40]}),{27:[1,41]},{21:[1,42]},t(b,[2,12]),t(b,[2,16]),t(v,i,{7:43}),t(b,[2,22]),t(b,[2,23]),{4:o,5:a,8:8,9:10,10:12,13:s,14:u,16:c,18:[1,44],19:f,21:l,22:h,23:d,24:p,25:g,28:y},t(b,[2,18])],defaultActions:{5:[2,1],6:[2,2],31:[2,26],32:[2,27]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],o=[],a=this.table,s="",u=0,c=0,f=0,l=2,h=1,d=o.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var b=p.yylloc;o.push(b);var m=p.options&&p.options.ranges;function v(){var t;return"number"!=typeof(t=r.pop()||p.lex()||h)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,w,x,k,E,A,S,T,M,D={};;){if(x=n[n.length-1],this.defaultActions[x]?k=this.defaultActions[x]:(null==_&&(_=v()),k=a[x]&&a[x][_]),void 0===k||!k.length||!k[0]){var C="";for(A in M=[],a[x])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=p.showPosition?"Parse error on line "+(u+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(u+1)+": Unexpected "+(_==h?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:b,expected:M})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),o.push(p.yylloc),n.push(k[1]),_=null,w?(_=w,w=null):(c=p.yyleng,s=p.yytext,u=p.yylineno,b=p.yylloc,f>0&&f--);break;case 2:if(S=this.productions_[k[1]][1],D.$=i[i.length-S],D._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},m&&(D._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(E=this.performAction.apply(D,[s,c,u,g.yy,k[1],i,o].concat(d))))return E;S&&(n=n.slice(0,-1*S*2),i=i.slice(0,-1*S),o=o.slice(0,-1*S)),n.push(this.productions_[k[1]][0]),i.push(D.$),o.push(D._$),T=a[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0}},w={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var o in i)this[o]=i[o];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),o=0;oe[0].length)){if(e=n,r=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return 5;case 1:case 2:case 3:case 4:break;case 5:return this.pushState("SCALE"),14;case 6:return 15;case 7:this.popState();break;case 8:this.pushState("STATE");break;case 9:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),22;case 10:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),23;case 11:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),22;case 12:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),23;case 13:this.begin("STATE_STRING");break;case 14:return this.popState(),this.pushState("STATE_ID"),"AS";case 15:return this.popState(),"ID";case 16:this.popState();break;case 17:return"STATE_DESCR";case 18:return 16;case 19:this.popState();break;case 20:return this.popState(),this.pushState("struct"),17;case 21:return this.popState(),18;case 22:break;case 23:return this.begin("NOTE"),25;case 24:return this.popState(),this.pushState("NOTE_ID"),29;case 25:return this.popState(),this.pushState("NOTE_ID"),30;case 26:this.popState(),this.pushState("FLOATING_NOTE");break;case 27:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 28:break;case 29:return"NOTE_TEXT";case 30:return this.popState(),"ID";case 31:return this.popState(),this.pushState("NOTE_TEXT"),21;case 32:return this.popState(),e.yytext=e.yytext.substr(2).trim(),27;case 33:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),27;case 34:return 6;case 35:return 13;case 36:return 28;case 37:return 21;case 38:return e.yytext=e.yytext.trim(),11;case 39:return 12;case 40:return 24;case 41:return 5;case 42:return"INVALID"}},rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:["])/i,/^(?:as\s*)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:\s*[^:;]+end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[2,3],inclusive:!1},struct:{rules:[2,3,8,21,22,23,36,37,38,39,40],inclusive:!1},FLOATING_NOTE_ID:{rules:[30],inclusive:!1},FLOATING_NOTE:{rules:[27,28,29],inclusive:!1},NOTE_TEXT:{rules:[32,33],inclusive:!1},NOTE_ID:{rules:[31],inclusive:!1},NOTE:{rules:[24,25,26],inclusive:!1},SCALE:{rules:[6,7],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[15],inclusive:!1},STATE_STRING:{rules:[16,17],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[2,3,9,10,11,12,13,14,18,19,20],inclusive:!1},ID:{rules:[2,3],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,8,20,23,34,35,36,37,38,39,41,42],inclusive:!0}}};function x(){this.yy={}}return _.lexer=w,x.prototype=_,_.Parser=x,new x}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(28).readFileSync(n(29).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(7),n(9)(t))},function(t,e,n){(function(t,n){(function(){var r,i=200,o="Unsupported core-js use. Try https://npms.io/search?q=ponyfill.",a="Expected a function",s="__lodash_hash_undefined__",u=500,c="__lodash_placeholder__",f=1,l=2,h=4,d=1,p=2,g=1,y=2,b=4,m=8,v=16,_=32,w=64,x=128,k=256,E=512,A=30,S="...",T=800,M=16,D=1,C=2,O=1/0,R=9007199254740991,I=17976931348623157e292,N=NaN,B=4294967295,L=B-1,P=B>>>1,F=[["ary",x],["bind",g],["bindKey",y],["curry",m],["curryRight",v],["flip",E],["partial",_],["partialRight",w],["rearg",k]],q="[object Arguments]",j="[object Array]",U="[object AsyncFunction]",z="[object Boolean]",Y="[object Date]",V="[object DOMException]",H="[object Error]",$="[object Function]",G="[object GeneratorFunction]",W="[object Map]",K="[object Number]",X="[object Null]",Z="[object Object]",J="[object Proxy]",Q="[object RegExp]",tt="[object Set]",et="[object String]",nt="[object Symbol]",rt="[object Undefined]",it="[object WeakMap]",ot="[object WeakSet]",at="[object ArrayBuffer]",st="[object DataView]",ut="[object Float32Array]",ct="[object Float64Array]",ft="[object Int8Array]",lt="[object Int16Array]",ht="[object Int32Array]",dt="[object Uint8Array]",pt="[object Uint8ClampedArray]",gt="[object Uint16Array]",yt="[object Uint32Array]",bt=/\b__p \+= '';/g,mt=/\b(__p \+=) '' \+/g,vt=/(__e\(.*?\)|\b__t\)) \+\n'';/g,_t=/&(?:amp|lt|gt|quot|#39);/g,wt=/[&<>"']/g,xt=RegExp(_t.source),kt=RegExp(wt.source),Et=/<%-([\s\S]+?)%>/g,At=/<%([\s\S]+?)%>/g,St=/<%=([\s\S]+?)%>/g,Tt=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Mt=/^\w*$/,Dt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Ct=/[\\^$.*+?()[\]{}|]/g,Ot=RegExp(Ct.source),Rt=/^\s+|\s+$/g,It=/^\s+/,Nt=/\s+$/,Bt=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Lt=/\{\n\/\* \[wrapped with (.+)\] \*/,Pt=/,? & /,Ft=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,qt=/\\(\\)?/g,jt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,Ut=/\w*$/,zt=/^[-+]0x[0-9a-f]+$/i,Yt=/^0b[01]+$/i,Vt=/^\[object .+?Constructor\]$/,Ht=/^0o[0-7]+$/i,$t=/^(?:0|[1-9]\d*)$/,Gt=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Wt=/($^)/,Kt=/['\n\r\u2028\u2029\\]/g,Xt="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",Zt="\\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",Jt="[\\ud800-\\udfff]",Qt="["+Zt+"]",te="["+Xt+"]",ee="\\d+",ne="[\\u2700-\\u27bf]",re="[a-z\\xdf-\\xf6\\xf8-\\xff]",ie="[^\\ud800-\\udfff"+Zt+ee+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",oe="\\ud83c[\\udffb-\\udfff]",ae="[^\\ud800-\\udfff]",se="(?:\\ud83c[\\udde6-\\uddff]){2}",ue="[\\ud800-\\udbff][\\udc00-\\udfff]",ce="[A-Z\\xc0-\\xd6\\xd8-\\xde]",fe="(?:"+re+"|"+ie+")",le="(?:"+ce+"|"+ie+")",he="(?:"+te+"|"+oe+")"+"?",de="[\\ufe0e\\ufe0f]?"+he+("(?:\\u200d(?:"+[ae,se,ue].join("|")+")[\\ufe0e\\ufe0f]?"+he+")*"),pe="(?:"+[ne,se,ue].join("|")+")"+de,ge="(?:"+[ae+te+"?",te,se,ue,Jt].join("|")+")",ye=RegExp("['’]","g"),be=RegExp(te,"g"),me=RegExp(oe+"(?="+oe+")|"+ge+de,"g"),ve=RegExp([ce+"?"+re+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[Qt,ce,"$"].join("|")+")",le+"+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[Qt,ce+fe,"$"].join("|")+")",ce+"?"+fe+"+(?:['’](?:d|ll|m|re|s|t|ve))?",ce+"+(?:['’](?: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_])",ee,pe].join("|"),"g"),_e=RegExp("[\\u200d\\ud800-\\udfff"+Xt+"\\ufe0e\\ufe0f]"),we=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,xe=["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"],ke=-1,Ee={};Ee[ut]=Ee[ct]=Ee[ft]=Ee[lt]=Ee[ht]=Ee[dt]=Ee[pt]=Ee[gt]=Ee[yt]=!0,Ee[q]=Ee[j]=Ee[at]=Ee[z]=Ee[st]=Ee[Y]=Ee[H]=Ee[$]=Ee[W]=Ee[K]=Ee[Z]=Ee[Q]=Ee[tt]=Ee[et]=Ee[it]=!1;var Ae={};Ae[q]=Ae[j]=Ae[at]=Ae[st]=Ae[z]=Ae[Y]=Ae[ut]=Ae[ct]=Ae[ft]=Ae[lt]=Ae[ht]=Ae[W]=Ae[K]=Ae[Z]=Ae[Q]=Ae[tt]=Ae[et]=Ae[nt]=Ae[dt]=Ae[pt]=Ae[gt]=Ae[yt]=!0,Ae[H]=Ae[$]=Ae[it]=!1;var Se={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Te=parseFloat,Me=parseInt,De="object"==typeof t&&t&&t.Object===Object&&t,Ce="object"==typeof self&&self&&self.Object===Object&&self,Oe=De||Ce||Function("return this")(),Re=e&&!e.nodeType&&e,Ie=Re&&"object"==typeof n&&n&&!n.nodeType&&n,Ne=Ie&&Ie.exports===Re,Be=Ne&&De.process,Le=function(){try{var t=Ie&&Ie.require&&Ie.require("util").types;return t||Be&&Be.binding&&Be.binding("util")}catch(t){}}(),Pe=Le&&Le.isArrayBuffer,Fe=Le&&Le.isDate,qe=Le&&Le.isMap,je=Le&&Le.isRegExp,Ue=Le&&Le.isSet,ze=Le&&Le.isTypedArray;function Ye(t,e,n){switch(n.length){case 0:return t.call(e);case 1:return t.call(e,n[0]);case 2:return t.call(e,n[0],n[1]);case 3:return t.call(e,n[0],n[1],n[2])}return t.apply(e,n)}function Ve(t,e,n,r){for(var i=-1,o=null==t?0:t.length;++i-1}function Xe(t,e,n){for(var r=-1,i=null==t?0:t.length;++r-1;);return n}function vn(t,e){for(var n=t.length;n--&&an(e,t[n],0)>-1;);return n}var _n=ln({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"}),wn=ln({"&":"&","<":"<",">":">",'"':""","'":"'"});function xn(t){return"\\"+Se[t]}function kn(t){return _e.test(t)}function En(t){var e=-1,n=Array(t.size);return t.forEach((function(t,r){n[++e]=[r,t]})),n}function An(t,e){return function(n){return t(e(n))}}function Sn(t,e){for(var n=-1,r=t.length,i=0,o=[];++n",""":'"',"'":"'"});var Rn=function t(e){var n,Xt=(e=null==e?Oe:Rn.defaults(Oe.Object(),e,Rn.pick(Oe,xe))).Array,Zt=e.Date,Jt=e.Error,Qt=e.Function,te=e.Math,ee=e.Object,ne=e.RegExp,re=e.String,ie=e.TypeError,oe=Xt.prototype,ae=Qt.prototype,se=ee.prototype,ue=e["__core-js_shared__"],ce=ae.toString,fe=se.hasOwnProperty,le=0,he=(n=/[^.]+$/.exec(ue&&ue.keys&&ue.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"",de=se.toString,pe=ce.call(ee),ge=Oe._,me=ne("^"+ce.call(fe).replace(Ct,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),_e=Ne?e.Buffer:r,Se=e.Symbol,De=e.Uint8Array,Ce=_e?_e.allocUnsafe:r,Re=An(ee.getPrototypeOf,ee),Ie=ee.create,Be=se.propertyIsEnumerable,Le=oe.splice,nn=Se?Se.isConcatSpreadable:r,ln=Se?Se.iterator:r,In=Se?Se.toStringTag:r,Nn=function(){try{var t=qo(ee,"defineProperty");return t({},"",{}),t}catch(t){}}(),Bn=e.clearTimeout!==Oe.clearTimeout&&e.clearTimeout,Ln=Zt&&Zt.now!==Oe.Date.now&&Zt.now,Pn=e.setTimeout!==Oe.setTimeout&&e.setTimeout,Fn=te.ceil,qn=te.floor,jn=ee.getOwnPropertySymbols,Un=_e?_e.isBuffer:r,zn=e.isFinite,Yn=oe.join,Vn=An(ee.keys,ee),Hn=te.max,$n=te.min,Gn=Zt.now,Wn=e.parseInt,Kn=te.random,Xn=oe.reverse,Zn=qo(e,"DataView"),Jn=qo(e,"Map"),Qn=qo(e,"Promise"),tr=qo(e,"Set"),er=qo(e,"WeakMap"),nr=qo(ee,"create"),rr=er&&new er,ir={},or=la(Zn),ar=la(Jn),sr=la(Qn),ur=la(tr),cr=la(er),fr=Se?Se.prototype:r,lr=fr?fr.valueOf:r,hr=fr?fr.toString:r;function dr(t){if(Ms(t)&&!bs(t)&&!(t instanceof br)){if(t instanceof yr)return t;if(fe.call(t,"__wrapped__"))return ha(t)}return new yr(t)}var pr=function(){function t(){}return function(e){if(!Ts(e))return{};if(Ie)return Ie(e);t.prototype=e;var n=new t;return t.prototype=r,n}}();function gr(){}function yr(t,e){this.__wrapped__=t,this.__actions__=[],this.__chain__=!!e,this.__index__=0,this.__values__=r}function br(t){this.__wrapped__=t,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=B,this.__views__=[]}function mr(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e=e?t:e)),t}function Br(t,e,n,i,o,a){var s,u=e&f,c=e&l,d=e&h;if(n&&(s=o?n(t,i,o,a):n(t)),s!==r)return s;if(!Ts(t))return t;var p=bs(t);if(p){if(s=function(t){var e=t.length,n=new t.constructor(e);e&&"string"==typeof t[0]&&fe.call(t,"index")&&(n.index=t.index,n.input=t.input);return n}(t),!u)return no(t,s)}else{var g=zo(t),y=g==$||g==G;if(ws(t))return Xi(t,u);if(g==Z||g==q||y&&!o){if(s=c||y?{}:Vo(t),!u)return c?function(t,e){return ro(t,Uo(t),e)}(t,function(t,e){return t&&ro(e,ou(e),t)}(s,t)):function(t,e){return ro(t,jo(t),e)}(t,Or(s,t))}else{if(!Ae[g])return o?t:{};s=function(t,e,n){var r=t.constructor;switch(e){case at:return Zi(t);case z:case Y:return new r(+t);case st:return function(t,e){var n=e?Zi(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.byteLength)}(t,n);case ut:case ct:case ft:case lt:case ht:case dt:case pt:case gt:case yt:return Ji(t,n);case W:return new r;case K:case et:return new r(t);case Q:return function(t){var e=new t.constructor(t.source,Ut.exec(t));return e.lastIndex=t.lastIndex,e}(t);case tt:return new r;case nt:return i=t,lr?ee(lr.call(i)):{}}var i}(t,g,u)}}a||(a=new xr);var b=a.get(t);if(b)return b;a.set(t,s),Is(t)?t.forEach((function(r){s.add(Br(r,e,n,r,t,a))})):Ds(t)&&t.forEach((function(r,i){s.set(i,Br(r,e,n,i,t,a))}));var m=p?r:(d?c?Ro:Oo:c?ou:iu)(t);return He(m||t,(function(r,i){m&&(r=t[i=r]),Mr(s,i,Br(r,e,n,i,t,a))})),s}function Lr(t,e,n){var i=n.length;if(null==t)return!i;for(t=ee(t);i--;){var o=n[i],a=e[o],s=t[o];if(s===r&&!(o in t)||!a(s))return!1}return!0}function Pr(t,e,n){if("function"!=typeof t)throw new ie(a);return ia((function(){t.apply(r,n)}),e)}function Fr(t,e,n,r){var o=-1,a=Ke,s=!0,u=t.length,c=[],f=e.length;if(!u)return c;n&&(e=Ze(e,gn(n))),r?(a=Xe,s=!1):e.length>=i&&(a=bn,s=!1,e=new wr(e));t:for(;++o-1},vr.prototype.set=function(t,e){var n=this.__data__,r=Dr(n,t);return r<0?(++this.size,n.push([t,e])):n[r][1]=e,this},_r.prototype.clear=function(){this.size=0,this.__data__={hash:new mr,map:new(Jn||vr),string:new mr}},_r.prototype.delete=function(t){var e=Po(this,t).delete(t);return this.size-=e?1:0,e},_r.prototype.get=function(t){return Po(this,t).get(t)},_r.prototype.has=function(t){return Po(this,t).has(t)},_r.prototype.set=function(t,e){var n=Po(this,t),r=n.size;return n.set(t,e),this.size+=n.size==r?0:1,this},wr.prototype.add=wr.prototype.push=function(t){return this.__data__.set(t,s),this},wr.prototype.has=function(t){return this.__data__.has(t)},xr.prototype.clear=function(){this.__data__=new vr,this.size=0},xr.prototype.delete=function(t){var e=this.__data__,n=e.delete(t);return this.size=e.size,n},xr.prototype.get=function(t){return this.__data__.get(t)},xr.prototype.has=function(t){return this.__data__.has(t)},xr.prototype.set=function(t,e){var n=this.__data__;if(n instanceof vr){var r=n.__data__;if(!Jn||r.length0&&n(s)?e>1?Vr(s,e-1,n,r,i):Je(i,s):r||(i[i.length]=s)}return i}var Hr=so(),$r=so(!0);function Gr(t,e){return t&&Hr(t,e,iu)}function Wr(t,e){return t&&$r(t,e,iu)}function Kr(t,e){return We(e,(function(e){return Es(t[e])}))}function Xr(t,e){for(var n=0,i=(e=$i(e,t)).length;null!=t&&ne}function ti(t,e){return null!=t&&fe.call(t,e)}function ei(t,e){return null!=t&&e in ee(t)}function ni(t,e,n){for(var i=n?Xe:Ke,o=t[0].length,a=t.length,s=a,u=Xt(a),c=1/0,f=[];s--;){var l=t[s];s&&e&&(l=Ze(l,gn(e))),c=$n(l.length,c),u[s]=!n&&(e||o>=120&&l.length>=120)?new wr(s&&l):r}l=t[0];var h=-1,d=u[0];t:for(;++h=s)return u;var c=n[r];return u*("desc"==c?-1:1)}}return t.index-e.index}(t,e,n)}))}function mi(t,e,n){for(var r=-1,i=e.length,o={};++r-1;)s!==t&&Le.call(s,u,1),Le.call(t,u,1);return t}function _i(t,e){for(var n=t?e.length:0,r=n-1;n--;){var i=e[n];if(n==r||i!==o){var o=i;$o(i)?Le.call(t,i,1):Fi(t,i)}}return t}function wi(t,e){return t+qn(Kn()*(e-t+1))}function xi(t,e){var n="";if(!t||e<1||e>R)return n;do{e%2&&(n+=t),(e=qn(e/2))&&(t+=t)}while(e);return n}function ki(t,e){return oa(ta(t,e,Cu),t+"")}function Ei(t){return Er(du(t))}function Ai(t,e){var n=du(t);return ua(n,Nr(e,0,n.length))}function Si(t,e,n,i){if(!Ts(t))return t;for(var o=-1,a=(e=$i(e,t)).length,s=a-1,u=t;null!=u&&++oi?0:i+e),(n=n>i?i:n)<0&&(n+=i),i=e>n?0:n-e>>>0,e>>>=0;for(var o=Xt(i);++r>>1,a=t[o];null!==a&&!Bs(a)&&(n?a<=e:a=i){var f=e?null:ko(t);if(f)return Tn(f);s=!1,o=bn,c=new wr}else c=e?[]:u;t:for(;++r=i?t:Ci(t,e,n)}var Ki=Bn||function(t){return Oe.clearTimeout(t)};function Xi(t,e){if(e)return t.slice();var n=t.length,r=Ce?Ce(n):new t.constructor(n);return t.copy(r),r}function Zi(t){var e=new t.constructor(t.byteLength);return new De(e).set(new De(t)),e}function Ji(t,e){var n=e?Zi(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.length)}function Qi(t,e){if(t!==e){var n=t!==r,i=null===t,o=t==t,a=Bs(t),s=e!==r,u=null===e,c=e==e,f=Bs(e);if(!u&&!f&&!a&&t>e||a&&s&&c&&!u&&!f||i&&s&&c||!n&&c||!o)return 1;if(!i&&!a&&!f&&t1?n[o-1]:r,s=o>2?n[2]:r;for(a=t.length>3&&"function"==typeof a?(o--,a):r,s&&Go(n[0],n[1],s)&&(a=o<3?r:a,o=1),e=ee(e);++i-1?o[a?e[s]:s]:r}}function ho(t){return Co((function(e){var n=e.length,i=n,o=yr.prototype.thru;for(t&&e.reverse();i--;){var s=e[i];if("function"!=typeof s)throw new ie(a);if(o&&!u&&"wrapper"==No(s))var u=new yr([],!0)}for(i=u?i:n;++i1&&m.reverse(),l&&cu))return!1;var f=a.get(t);if(f&&a.get(e))return f==e;var l=-1,h=!0,g=n&p?new wr:r;for(a.set(t,e),a.set(e,t);++l-1&&t%1==0&&t1?"& ":"")+e[r],e=e.join(n>2?", ":" "),t.replace(Bt,"{\n/* [wrapped with "+e+"] */\n")}(r,function(t,e){return He(F,(function(n){var r="_."+n[0];e&n[1]&&!Ke(t,r)&&t.push(r)})),t.sort()}(function(t){var e=t.match(Lt);return e?e[1].split(Pt):[]}(r),n)))}function sa(t){var e=0,n=0;return function(){var i=Gn(),o=M-(i-n);if(n=i,o>0){if(++e>=T)return arguments[0]}else e=0;return t.apply(r,arguments)}}function ua(t,e){var n=-1,i=t.length,o=i-1;for(e=e===r?i:e;++n1?t[e-1]:r;return n="function"==typeof n?(t.pop(),n):r,Ra(t,n)}));function qa(t){var e=dr(t);return e.__chain__=!0,e}function ja(t,e){return e(t)}var Ua=Co((function(t){var e=t.length,n=e?t[0]:0,i=this.__wrapped__,o=function(e){return Ir(e,t)};return!(e>1||this.__actions__.length)&&i instanceof br&&$o(n)?((i=i.slice(n,+n+(e?1:0))).__actions__.push({func:ja,args:[o],thisArg:r}),new yr(i,this.__chain__).thru((function(t){return e&&!t.length&&t.push(r),t}))):this.thru(o)}));var za=io((function(t,e,n){fe.call(t,n)?++t[n]:Rr(t,n,1)}));var Ya=lo(ya),Va=lo(ba);function Ha(t,e){return(bs(t)?He:qr)(t,Lo(e,3))}function $a(t,e){return(bs(t)?$e:jr)(t,Lo(e,3))}var Ga=io((function(t,e,n){fe.call(t,n)?t[n].push(e):Rr(t,n,[e])}));var Wa=ki((function(t,e,n){var r=-1,i="function"==typeof e,o=vs(t)?Xt(t.length):[];return qr(t,(function(t){o[++r]=i?Ye(e,t,n):ri(t,e,n)})),o})),Ka=io((function(t,e,n){Rr(t,n,e)}));function Xa(t,e){return(bs(t)?Ze:hi)(t,Lo(e,3))}var Za=io((function(t,e,n){t[n?0:1].push(e)}),(function(){return[[],[]]}));var Ja=ki((function(t,e){if(null==t)return[];var n=e.length;return n>1&&Go(t,e[0],e[1])?e=[]:n>2&&Go(e[0],e[1],e[2])&&(e=[e[0]]),bi(t,Vr(e,1),[])})),Qa=Ln||function(){return Oe.Date.now()};function ts(t,e,n){return e=n?r:e,e=t&&null==e?t.length:e,Ao(t,x,r,r,r,r,e)}function es(t,e){var n;if("function"!=typeof e)throw new ie(a);return t=Us(t),function(){return--t>0&&(n=e.apply(this,arguments)),t<=1&&(e=r),n}}var ns=ki((function(t,e,n){var r=g;if(n.length){var i=Sn(n,Bo(ns));r|=_}return Ao(t,r,e,n,i)})),rs=ki((function(t,e,n){var r=g|y;if(n.length){var i=Sn(n,Bo(rs));r|=_}return Ao(e,r,t,n,i)}));function is(t,e,n){var i,o,s,u,c,f,l=0,h=!1,d=!1,p=!0;if("function"!=typeof t)throw new ie(a);function g(e){var n=i,a=o;return i=o=r,l=e,u=t.apply(a,n)}function y(t){var n=t-f;return f===r||n>=e||n<0||d&&t-l>=s}function b(){var t=Qa();if(y(t))return m(t);c=ia(b,function(t){var n=e-(t-f);return d?$n(n,s-(t-l)):n}(t))}function m(t){return c=r,p&&i?g(t):(i=o=r,u)}function v(){var t=Qa(),n=y(t);if(i=arguments,o=this,f=t,n){if(c===r)return function(t){return l=t,c=ia(b,e),h?g(t):u}(f);if(d)return Ki(c),c=ia(b,e),g(f)}return c===r&&(c=ia(b,e)),u}return e=Ys(e)||0,Ts(n)&&(h=!!n.leading,s=(d="maxWait"in n)?Hn(Ys(n.maxWait)||0,e):s,p="trailing"in n?!!n.trailing:p),v.cancel=function(){c!==r&&Ki(c),l=0,i=f=o=c=r},v.flush=function(){return c===r?u:m(Qa())},v}var os=ki((function(t,e){return Pr(t,1,e)})),as=ki((function(t,e,n){return Pr(t,Ys(e)||0,n)}));function ss(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new ie(a);var n=function(){var r=arguments,i=e?e.apply(this,r):r[0],o=n.cache;if(o.has(i))return o.get(i);var a=t.apply(this,r);return n.cache=o.set(i,a)||o,a};return n.cache=new(ss.Cache||_r),n}function us(t){if("function"!=typeof t)throw new ie(a);return function(){var e=arguments;switch(e.length){case 0:return!t.call(this);case 1:return!t.call(this,e[0]);case 2:return!t.call(this,e[0],e[1]);case 3:return!t.call(this,e[0],e[1],e[2])}return!t.apply(this,e)}}ss.Cache=_r;var cs=Gi((function(t,e){var n=(e=1==e.length&&bs(e[0])?Ze(e[0],gn(Lo())):Ze(Vr(e,1),gn(Lo()))).length;return ki((function(r){for(var i=-1,o=$n(r.length,n);++i=e})),ys=ii(function(){return arguments}())?ii:function(t){return Ms(t)&&fe.call(t,"callee")&&!Be.call(t,"callee")},bs=Xt.isArray,ms=Pe?gn(Pe):function(t){return Ms(t)&&Jr(t)==at};function vs(t){return null!=t&&Ss(t.length)&&!Es(t)}function _s(t){return Ms(t)&&vs(t)}var ws=Un||Yu,xs=Fe?gn(Fe):function(t){return Ms(t)&&Jr(t)==Y};function ks(t){if(!Ms(t))return!1;var e=Jr(t);return e==H||e==V||"string"==typeof t.message&&"string"==typeof t.name&&!Os(t)}function Es(t){if(!Ts(t))return!1;var e=Jr(t);return e==$||e==G||e==U||e==J}function As(t){return"number"==typeof t&&t==Us(t)}function Ss(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=R}function Ts(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function Ms(t){return null!=t&&"object"==typeof t}var Ds=qe?gn(qe):function(t){return Ms(t)&&zo(t)==W};function Cs(t){return"number"==typeof t||Ms(t)&&Jr(t)==K}function Os(t){if(!Ms(t)||Jr(t)!=Z)return!1;var e=Re(t);if(null===e)return!0;var n=fe.call(e,"constructor")&&e.constructor;return"function"==typeof n&&n instanceof n&&ce.call(n)==pe}var Rs=je?gn(je):function(t){return Ms(t)&&Jr(t)==Q};var Is=Ue?gn(Ue):function(t){return Ms(t)&&zo(t)==tt};function Ns(t){return"string"==typeof t||!bs(t)&&Ms(t)&&Jr(t)==et}function Bs(t){return"symbol"==typeof t||Ms(t)&&Jr(t)==nt}var Ls=ze?gn(ze):function(t){return Ms(t)&&Ss(t.length)&&!!Ee[Jr(t)]};var Ps=_o(li),Fs=_o((function(t,e){return t<=e}));function qs(t){if(!t)return[];if(vs(t))return Ns(t)?Cn(t):no(t);if(ln&&t[ln])return function(t){for(var e,n=[];!(e=t.next()).done;)n.push(e.value);return n}(t[ln]());var e=zo(t);return(e==W?En:e==tt?Tn:du)(t)}function js(t){return t?(t=Ys(t))===O||t===-O?(t<0?-1:1)*I:t==t?t:0:0===t?t:0}function Us(t){var e=js(t),n=e%1;return e==e?n?e-n:e:0}function zs(t){return t?Nr(Us(t),0,B):0}function Ys(t){if("number"==typeof t)return t;if(Bs(t))return N;if(Ts(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=Ts(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(Rt,"");var n=Yt.test(t);return n||Ht.test(t)?Me(t.slice(2),n?2:8):zt.test(t)?N:+t}function Vs(t){return ro(t,ou(t))}function Hs(t){return null==t?"":Li(t)}var $s=oo((function(t,e){if(Zo(e)||vs(e))ro(e,iu(e),t);else for(var n in e)fe.call(e,n)&&Mr(t,n,e[n])})),Gs=oo((function(t,e){ro(e,ou(e),t)})),Ws=oo((function(t,e,n,r){ro(e,ou(e),t,r)})),Ks=oo((function(t,e,n,r){ro(e,iu(e),t,r)})),Xs=Co(Ir);var Zs=ki((function(t,e){t=ee(t);var n=-1,i=e.length,o=i>2?e[2]:r;for(o&&Go(e[0],e[1],o)&&(i=1);++n1),e})),ro(t,Ro(t),n),r&&(n=Br(n,f|l|h,Mo));for(var i=e.length;i--;)Fi(n,e[i]);return n}));var cu=Co((function(t,e){return null==t?{}:function(t,e){return mi(t,e,(function(e,n){return tu(t,n)}))}(t,e)}));function fu(t,e){if(null==t)return{};var n=Ze(Ro(t),(function(t){return[t]}));return e=Lo(e),mi(t,n,(function(t,n){return e(t,n[0])}))}var lu=Eo(iu),hu=Eo(ou);function du(t){return null==t?[]:yn(t,iu(t))}var pu=co((function(t,e,n){return e=e.toLowerCase(),t+(n?gu(e):e)}));function gu(t){return ku(Hs(t).toLowerCase())}function yu(t){return(t=Hs(t))&&t.replace(Gt,_n).replace(be,"")}var bu=co((function(t,e,n){return t+(n?"-":"")+e.toLowerCase()})),mu=co((function(t,e,n){return t+(n?" ":"")+e.toLowerCase()})),vu=uo("toLowerCase");var _u=co((function(t,e,n){return t+(n?"_":"")+e.toLowerCase()}));var wu=co((function(t,e,n){return t+(n?" ":"")+ku(e)}));var xu=co((function(t,e,n){return t+(n?" ":"")+e.toUpperCase()})),ku=uo("toUpperCase");function Eu(t,e,n){return t=Hs(t),(e=n?r:e)===r?function(t){return we.test(t)}(t)?function(t){return t.match(ve)||[]}(t):function(t){return t.match(Ft)||[]}(t):t.match(e)||[]}var Au=ki((function(t,e){try{return Ye(t,r,e)}catch(t){return ks(t)?t:new Jt(t)}})),Su=Co((function(t,e){return He(e,(function(e){e=fa(e),Rr(t,e,ns(t[e],t))})),t}));function Tu(t){return function(){return t}}var Mu=ho(),Du=ho(!0);function Cu(t){return t}function Ou(t){return ui("function"==typeof t?t:Br(t,f))}var Ru=ki((function(t,e){return function(n){return ri(n,t,e)}})),Iu=ki((function(t,e){return function(n){return ri(t,n,e)}}));function Nu(t,e,n){var r=iu(e),i=Kr(e,r);null!=n||Ts(e)&&(i.length||!r.length)||(n=e,e=t,t=this,i=Kr(e,iu(e)));var o=!(Ts(n)&&"chain"in n&&!n.chain),a=Es(t);return He(i,(function(n){var r=e[n];t[n]=r,a&&(t.prototype[n]=function(){var e=this.__chain__;if(o||e){var n=t(this.__wrapped__),i=n.__actions__=no(this.__actions__);return i.push({func:r,args:arguments,thisArg:t}),n.__chain__=e,n}return r.apply(t,Je([this.value()],arguments))})})),t}function Bu(){}var Lu=bo(Ze),Pu=bo(Ge),Fu=bo(en);function qu(t){return Wo(t)?fn(fa(t)):function(t){return function(e){return Xr(e,t)}}(t)}var ju=vo(),Uu=vo(!0);function zu(){return[]}function Yu(){return!1}var Vu=yo((function(t,e){return t+e}),0),Hu=xo("ceil"),$u=yo((function(t,e){return t/e}),1),Gu=xo("floor");var Wu,Ku=yo((function(t,e){return t*e}),1),Xu=xo("round"),Zu=yo((function(t,e){return t-e}),0);return dr.after=function(t,e){if("function"!=typeof e)throw new ie(a);return t=Us(t),function(){if(--t<1)return e.apply(this,arguments)}},dr.ary=ts,dr.assign=$s,dr.assignIn=Gs,dr.assignInWith=Ws,dr.assignWith=Ks,dr.at=Xs,dr.before=es,dr.bind=ns,dr.bindAll=Su,dr.bindKey=rs,dr.castArray=function(){if(!arguments.length)return[];var t=arguments[0];return bs(t)?t:[t]},dr.chain=qa,dr.chunk=function(t,e,n){e=(n?Go(t,e,n):e===r)?1:Hn(Us(e),0);var i=null==t?0:t.length;if(!i||e<1)return[];for(var o=0,a=0,s=Xt(Fn(i/e));oo?0:o+n),(i=i===r||i>o?o:Us(i))<0&&(i+=o),i=n>i?0:zs(i);n>>0)?(t=Hs(t))&&("string"==typeof e||null!=e&&!Rs(e))&&!(e=Li(e))&&kn(t)?Wi(Cn(t),0,n):t.split(e,n):[]},dr.spread=function(t,e){if("function"!=typeof t)throw new ie(a);return e=null==e?0:Hn(Us(e),0),ki((function(n){var r=n[e],i=Wi(n,0,e);return r&&Je(i,r),Ye(t,this,i)}))},dr.tail=function(t){var e=null==t?0:t.length;return e?Ci(t,1,e):[]},dr.take=function(t,e,n){return t&&t.length?Ci(t,0,(e=n||e===r?1:Us(e))<0?0:e):[]},dr.takeRight=function(t,e,n){var i=null==t?0:t.length;return i?Ci(t,(e=i-(e=n||e===r?1:Us(e)))<0?0:e,i):[]},dr.takeRightWhile=function(t,e){return t&&t.length?ji(t,Lo(e,3),!1,!0):[]},dr.takeWhile=function(t,e){return t&&t.length?ji(t,Lo(e,3)):[]},dr.tap=function(t,e){return e(t),t},dr.throttle=function(t,e,n){var r=!0,i=!0;if("function"!=typeof t)throw new ie(a);return Ts(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),is(t,e,{leading:r,maxWait:e,trailing:i})},dr.thru=ja,dr.toArray=qs,dr.toPairs=lu,dr.toPairsIn=hu,dr.toPath=function(t){return bs(t)?Ze(t,fa):Bs(t)?[t]:no(ca(Hs(t)))},dr.toPlainObject=Vs,dr.transform=function(t,e,n){var r=bs(t),i=r||ws(t)||Ls(t);if(e=Lo(e,4),null==n){var o=t&&t.constructor;n=i?r?new o:[]:Ts(t)&&Es(o)?pr(Re(t)):{}}return(i?He:Gr)(t,(function(t,r,i){return e(n,t,r,i)})),n},dr.unary=function(t){return ts(t,1)},dr.union=Ma,dr.unionBy=Da,dr.unionWith=Ca,dr.uniq=function(t){return t&&t.length?Pi(t):[]},dr.uniqBy=function(t,e){return t&&t.length?Pi(t,Lo(e,2)):[]},dr.uniqWith=function(t,e){return e="function"==typeof e?e:r,t&&t.length?Pi(t,r,e):[]},dr.unset=function(t,e){return null==t||Fi(t,e)},dr.unzip=Oa,dr.unzipWith=Ra,dr.update=function(t,e,n){return null==t?t:qi(t,e,Hi(n))},dr.updateWith=function(t,e,n,i){return i="function"==typeof i?i:r,null==t?t:qi(t,e,Hi(n),i)},dr.values=du,dr.valuesIn=function(t){return null==t?[]:yn(t,ou(t))},dr.without=Ia,dr.words=Eu,dr.wrap=function(t,e){return fs(Hi(e),t)},dr.xor=Na,dr.xorBy=Ba,dr.xorWith=La,dr.zip=Pa,dr.zipObject=function(t,e){return Yi(t||[],e||[],Mr)},dr.zipObjectDeep=function(t,e){return Yi(t||[],e||[],Si)},dr.zipWith=Fa,dr.entries=lu,dr.entriesIn=hu,dr.extend=Gs,dr.extendWith=Ws,Nu(dr,dr),dr.add=Vu,dr.attempt=Au,dr.camelCase=pu,dr.capitalize=gu,dr.ceil=Hu,dr.clamp=function(t,e,n){return n===r&&(n=e,e=r),n!==r&&(n=(n=Ys(n))==n?n:0),e!==r&&(e=(e=Ys(e))==e?e:0),Nr(Ys(t),e,n)},dr.clone=function(t){return Br(t,h)},dr.cloneDeep=function(t){return Br(t,f|h)},dr.cloneDeepWith=function(t,e){return Br(t,f|h,e="function"==typeof e?e:r)},dr.cloneWith=function(t,e){return Br(t,h,e="function"==typeof e?e:r)},dr.conformsTo=function(t,e){return null==e||Lr(t,e,iu(e))},dr.deburr=yu,dr.defaultTo=function(t,e){return null==t||t!=t?e:t},dr.divide=$u,dr.endsWith=function(t,e,n){t=Hs(t),e=Li(e);var i=t.length,o=n=n===r?i:Nr(Us(n),0,i);return(n-=e.length)>=0&&t.slice(n,o)==e},dr.eq=ds,dr.escape=function(t){return(t=Hs(t))&&kt.test(t)?t.replace(wt,wn):t},dr.escapeRegExp=function(t){return(t=Hs(t))&&Ot.test(t)?t.replace(Ct,"\\$&"):t},dr.every=function(t,e,n){var i=bs(t)?Ge:Ur;return n&&Go(t,e,n)&&(e=r),i(t,Lo(e,3))},dr.find=Ya,dr.findIndex=ya,dr.findKey=function(t,e){return rn(t,Lo(e,3),Gr)},dr.findLast=Va,dr.findLastIndex=ba,dr.findLastKey=function(t,e){return rn(t,Lo(e,3),Wr)},dr.floor=Gu,dr.forEach=Ha,dr.forEachRight=$a,dr.forIn=function(t,e){return null==t?t:Hr(t,Lo(e,3),ou)},dr.forInRight=function(t,e){return null==t?t:$r(t,Lo(e,3),ou)},dr.forOwn=function(t,e){return t&&Gr(t,Lo(e,3))},dr.forOwnRight=function(t,e){return t&&Wr(t,Lo(e,3))},dr.get=Qs,dr.gt=ps,dr.gte=gs,dr.has=function(t,e){return null!=t&&Yo(t,e,ti)},dr.hasIn=tu,dr.head=va,dr.identity=Cu,dr.includes=function(t,e,n,r){t=vs(t)?t:du(t),n=n&&!r?Us(n):0;var i=t.length;return n<0&&(n=Hn(i+n,0)),Ns(t)?n<=i&&t.indexOf(e,n)>-1:!!i&&an(t,e,n)>-1},dr.indexOf=function(t,e,n){var r=null==t?0:t.length;if(!r)return-1;var i=null==n?0:Us(n);return i<0&&(i=Hn(r+i,0)),an(t,e,i)},dr.inRange=function(t,e,n){return e=js(e),n===r?(n=e,e=0):n=js(n),function(t,e,n){return t>=$n(e,n)&&t=-R&&t<=R},dr.isSet=Is,dr.isString=Ns,dr.isSymbol=Bs,dr.isTypedArray=Ls,dr.isUndefined=function(t){return t===r},dr.isWeakMap=function(t){return Ms(t)&&zo(t)==it},dr.isWeakSet=function(t){return Ms(t)&&Jr(t)==ot},dr.join=function(t,e){return null==t?"":Yn.call(t,e)},dr.kebabCase=bu,dr.last=ka,dr.lastIndexOf=function(t,e,n){var i=null==t?0:t.length;if(!i)return-1;var o=i;return n!==r&&(o=(o=Us(n))<0?Hn(i+o,0):$n(o,i-1)),e==e?function(t,e,n){for(var r=n+1;r--;)if(t[r]===e)return r;return r}(t,e,o):on(t,un,o,!0)},dr.lowerCase=mu,dr.lowerFirst=vu,dr.lt=Ps,dr.lte=Fs,dr.max=function(t){return t&&t.length?zr(t,Cu,Qr):r},dr.maxBy=function(t,e){return t&&t.length?zr(t,Lo(e,2),Qr):r},dr.mean=function(t){return cn(t,Cu)},dr.meanBy=function(t,e){return cn(t,Lo(e,2))},dr.min=function(t){return t&&t.length?zr(t,Cu,li):r},dr.minBy=function(t,e){return t&&t.length?zr(t,Lo(e,2),li):r},dr.stubArray=zu,dr.stubFalse=Yu,dr.stubObject=function(){return{}},dr.stubString=function(){return""},dr.stubTrue=function(){return!0},dr.multiply=Ku,dr.nth=function(t,e){return t&&t.length?yi(t,Us(e)):r},dr.noConflict=function(){return Oe._===this&&(Oe._=ge),this},dr.noop=Bu,dr.now=Qa,dr.pad=function(t,e,n){t=Hs(t);var r=(e=Us(e))?Dn(t):0;if(!e||r>=e)return t;var i=(e-r)/2;return mo(qn(i),n)+t+mo(Fn(i),n)},dr.padEnd=function(t,e,n){t=Hs(t);var r=(e=Us(e))?Dn(t):0;return e&&re){var i=t;t=e,e=i}if(n||t%1||e%1){var o=Kn();return $n(t+o*(e-t+Te("1e-"+((o+"").length-1))),e)}return wi(t,e)},dr.reduce=function(t,e,n){var r=bs(t)?Qe:hn,i=arguments.length<3;return r(t,Lo(e,4),n,i,qr)},dr.reduceRight=function(t,e,n){var r=bs(t)?tn:hn,i=arguments.length<3;return r(t,Lo(e,4),n,i,jr)},dr.repeat=function(t,e,n){return e=(n?Go(t,e,n):e===r)?1:Us(e),xi(Hs(t),e)},dr.replace=function(){var t=arguments,e=Hs(t[0]);return t.length<3?e:e.replace(t[1],t[2])},dr.result=function(t,e,n){var i=-1,o=(e=$i(e,t)).length;for(o||(o=1,t=r);++iR)return[];var n=B,r=$n(t,B);e=Lo(e),t-=B;for(var i=pn(r,e);++n=a)return t;var u=n-Dn(i);if(u<1)return i;var c=s?Wi(s,0,u).join(""):t.slice(0,u);if(o===r)return c+i;if(s&&(u+=c.length-u),Rs(o)){if(t.slice(u).search(o)){var f,l=c;for(o.global||(o=ne(o.source,Hs(Ut.exec(o))+"g")),o.lastIndex=0;f=o.exec(l);)var h=f.index;c=c.slice(0,h===r?u:h)}}else if(t.indexOf(Li(o),u)!=u){var d=c.lastIndexOf(o);d>-1&&(c=c.slice(0,d))}return c+i},dr.unescape=function(t){return(t=Hs(t))&&xt.test(t)?t.replace(_t,On):t},dr.uniqueId=function(t){var e=++le;return Hs(t)+e},dr.upperCase=xu,dr.upperFirst=ku,dr.each=Ha,dr.eachRight=$a,dr.first=va,Nu(dr,(Wu={},Gr(dr,(function(t,e){fe.call(dr.prototype,e)||(Wu[e]=t)})),Wu),{chain:!1}),dr.VERSION="4.17.15",He(["bind","bindKey","curry","curryRight","partial","partialRight"],(function(t){dr[t].placeholder=dr})),He(["drop","take"],(function(t,e){br.prototype[t]=function(n){n=n===r?1:Hn(Us(n),0);var i=this.__filtered__&&!e?new br(this):this.clone();return i.__filtered__?i.__takeCount__=$n(n,i.__takeCount__):i.__views__.push({size:$n(n,B),type:t+(i.__dir__<0?"Right":"")}),i},br.prototype[t+"Right"]=function(e){return this.reverse()[t](e).reverse()}})),He(["filter","map","takeWhile"],(function(t,e){var n=e+1,r=n==D||3==n;br.prototype[t]=function(t){var e=this.clone();return e.__iteratees__.push({iteratee:Lo(t,3),type:n}),e.__filtered__=e.__filtered__||r,e}})),He(["head","last"],(function(t,e){var n="take"+(e?"Right":"");br.prototype[t]=function(){return this[n](1).value()[0]}})),He(["initial","tail"],(function(t,e){var n="drop"+(e?"":"Right");br.prototype[t]=function(){return this.__filtered__?new br(this):this[n](1)}})),br.prototype.compact=function(){return this.filter(Cu)},br.prototype.find=function(t){return this.filter(t).head()},br.prototype.findLast=function(t){return this.reverse().find(t)},br.prototype.invokeMap=ki((function(t,e){return"function"==typeof t?new br(this):this.map((function(n){return ri(n,t,e)}))})),br.prototype.reject=function(t){return this.filter(us(Lo(t)))},br.prototype.slice=function(t,e){t=Us(t);var n=this;return n.__filtered__&&(t>0||e<0)?new br(n):(t<0?n=n.takeRight(-t):t&&(n=n.drop(t)),e!==r&&(n=(e=Us(e))<0?n.dropRight(-e):n.take(e-t)),n)},br.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},br.prototype.toArray=function(){return this.take(B)},Gr(br.prototype,(function(t,e){var n=/^(?:filter|find|map|reject)|While$/.test(e),i=/^(?:head|last)$/.test(e),o=dr[i?"take"+("last"==e?"Right":""):e],a=i||/^find/.test(e);o&&(dr.prototype[e]=function(){var e=this.__wrapped__,s=i?[1]:arguments,u=e instanceof br,c=s[0],f=u||bs(e),l=function(t){var e=o.apply(dr,Je([t],s));return i&&h?e[0]:e};f&&n&&"function"==typeof c&&1!=c.length&&(u=f=!1);var h=this.__chain__,d=!!this.__actions__.length,p=a&&!h,g=u&&!d;if(!a&&f){e=g?e:new br(this);var y=t.apply(e,s);return y.__actions__.push({func:ja,args:[l],thisArg:r}),new yr(y,h)}return p&&g?t.apply(this,s):(y=this.thru(l),p?i?y.value()[0]:y.value():y)})})),He(["pop","push","shift","sort","splice","unshift"],(function(t){var e=oe[t],n=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",r=/^(?:pop|shift)$/.test(t);dr.prototype[t]=function(){var t=arguments;if(r&&!this.__chain__){var i=this.value();return e.apply(bs(i)?i:[],t)}return this[n]((function(n){return e.apply(bs(n)?n:[],t)}))}})),Gr(br.prototype,(function(t,e){var n=dr[e];if(n){var r=n.name+"";fe.call(ir,r)||(ir[r]=[]),ir[r].push({name:e,func:n})}})),ir[po(r,y).name]=[{name:"wrapper",func:r}],br.prototype.clone=function(){var t=new br(this.__wrapped__);return t.__actions__=no(this.__actions__),t.__dir__=this.__dir__,t.__filtered__=this.__filtered__,t.__iteratees__=no(this.__iteratees__),t.__takeCount__=this.__takeCount__,t.__views__=no(this.__views__),t},br.prototype.reverse=function(){if(this.__filtered__){var t=new br(this);t.__dir__=-1,t.__filtered__=!0}else(t=this.clone()).__dir__*=-1;return t},br.prototype.value=function(){var t=this.__wrapped__.value(),e=this.__dir__,n=bs(t),r=e<0,i=n?t.length:0,o=function(t,e,n){var r=-1,i=n.length;for(;++r=this.__values__.length;return{done:t,value:t?r:this.__values__[this.__index__++]}},dr.prototype.plant=function(t){for(var e,n=this;n instanceof gr;){var i=ha(n);i.__index__=0,i.__values__=r,e?o.__wrapped__=i:e=i;var o=i;n=n.__wrapped__}return o.__wrapped__=t,e},dr.prototype.reverse=function(){var t=this.__wrapped__;if(t instanceof br){var e=t;return this.__actions__.length&&(e=new br(this)),(e=e.reverse()).__actions__.push({func:ja,args:[Ta],thisArg:r}),new yr(e,this.__chain__)}return this.thru(Ta)},dr.prototype.toJSON=dr.prototype.valueOf=dr.prototype.value=function(){return Ui(this.__wrapped__,this.__actions__)},dr.prototype.first=dr.prototype.head,ln&&(dr.prototype[ln]=function(){return this}),dr}();"function"==typeof define&&"object"==typeof define.amd&&define.amd?(Oe._=Rn,define((function(){return Rn}))):Ie?((Ie.exports=Rn)._=Rn,Re._=Rn):Oe._=Rn}).call(this)}).call(this,n(11),n(9)(t))},function(t,e,n){var r=n(66),i=n(67);t.exports=function(t,e,n,o){var a=!n;n||(n={});for(var s=-1,u=e.length;++s=this._delta8){var n=(t=this.pending).length%this._delta8;this.pending=t.slice(t.length-n,t.length),0===this.pending.length&&(this.pending=null),t=r.join32(t,0,t.length-n,this.endian);for(var i=0;i>>24&255,r[i++]=t>>>16&255,r[i++]=t>>>8&255,r[i++]=255&t}else for(r[i++]=255&t,r[i++]=t>>>8&255,r[i++]=t>>>16&255,r[i++]=t>>>24&255,r[i++]=0,r[i++]=0,r[i++]=0,r[i++]=0,o=8;ol&&M.push("'"+this.terminals_[A]+"'");C=p.showPosition?"Parse error on line "+(u+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(u+1)+": Unexpected "+(_==h?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:b,expected:M})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),o.push(p.yylloc),n.push(k[1]),_=null,w?(_=w,w=null):(c=p.yyleng,s=p.yytext,u=p.yylineno,b=p.yylloc,f>0&&f--);break;case 2:if(S=this.productions_[k[1]][1],D.$=i[i.length-S],D._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},m&&(D._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(E=this.performAction.apply(D,[s,c,u,g.yy,k[1],i,o].concat(d))))return E;S&&(n=n.slice(0,-1*S*2),i=i.slice(0,-1*S),o=o.slice(0,-1*S)),n.push(this.productions_[k[1]][0]),i.push(D.$),o.push(D._$),T=a[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0}},Ut={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var o in i)this[o]=i[o];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),o=0;oe[0].length)){if(e=n,r=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,r){switch(n){case 0:break;case 1:this.begin("string");break;case 2:this.popState();break;case 3:return"STR";case 4:return 89;case 5:return 98;case 6:return 90;case 7:return 103;case 8:return 91;case 9:return 92;case 10:return 93;case 11:return t.lex.firstGraph()&&this.begin("dir"),12;case 12:return 26;case 13:return 30;case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:return this.popState(),13;case 24:return 106;case 25:return 114;case 26:return 34;case 27:return 111;case 28:return 8;case 29:return 107;case 30:return 125;case 31:return 55;case 32:return 51;case 33:return 74;case 34:return 76;case 35:return 75;case 36:return 78;case 37:return 80;case 38:return 81;case 39:return 82;case 40:case 41:return 79;case 42:case 43:return 77;case 44:return 78;case 45:return 53;case 46:return 57;case 47:return 63;case 48:return 59;case 49:return 61;case 50:return 65;case 51:return 63;case 52:return 59;case 53:return 61;case 54:return 65;case 55:return 71;case 56:return 67;case 57:return 69;case 58:return 73;case 59:return 52;case 60:return 56;case 61:return 54;case 62:return 60;case 63:return 64;case 64:return 62;case 65:return 68;case 66:return 72;case 67:return 70;case 68:return 50;case 69:return 58;case 70:return 66;case 71:return 38;case 72:return 39;case 73:return 112;case 74:return 115;case 75:return 126;case 76:return 123;case 77:return 105;case 78:case 79:return 124;case 80:return 117;case 81:return 42;case 82:return 95;case 83:return 94;case 84:return 110;case 85:return 44;case 86:return 43;case 87:return 46;case 88:return 45;case 89:return 121;case 90:return 122;case 91:return 83;case 92:return 36;case 93:return 37;case 94:return 28;case 95:return 29;case 96:return 40;case 97:return 41;case 98:return 127;case 99:return 9;case 100:return 10;case 101:return 11}},rules:[/^(?:%%[^\n]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:click\b)/,/^(?:graph\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*--[x]\s*)/,/^(?:\s*-->\s*)/,/^(?:\s*<-->\s*)/,/^(?:\s*[x]--[x]\s*)/,/^(?:\s*[o]--[o]\s*)/,/^(?:\s*[o]\.-[o]\s*)/,/^(?:\s*<==>\s*)/,/^(?:\s*[o]==[o]\s*)/,/^(?:\s*[x]==[x]\s*)/,/^(?:\s*[x].-[x]\s*)/,/^(?:\s*[x]-\.-[x]\s*)/,/^(?:\s*<\.->\s*)/,/^(?:\s*<-\.->\s*)/,/^(?:\s*[o]-\.-[o]\s*)/,/^(?:\s*--[o]\s*)/,/^(?:\s*---\s*)/,/^(?:\s*-\.-[x]\s*)/,/^(?:\s*-\.->\s*)/,/^(?:\s*-\.-[o]\s*)/,/^(?:\s*-\.-\s*)/,/^(?:\s*.-[x]\s*)/,/^(?:\s*\.->\s*)/,/^(?:\s*\.-[o]\s*)/,/^(?:\s*\.-\s*)/,/^(?:\s*==[x]\s*)/,/^(?:\s*==>\s*)/,/^(?:\s*==[o]\s*)/,/^(?:\s*==[\=]\s*)/,/^(?:\s*<--\s*)/,/^(?:\s*[x]--\s*)/,/^(?:\s*[o]--\s*)/,/^(?:\s*<-\.\s*)/,/^(?:\s*[x]-\.\s*)/,/^(?:\s*[o]-\.\s*)/,/^(?:\s*<==\s*)/,/^(?:\s*[x]==\s*)/,/^(?:\s*[o]==\s*)/,/^(?:\s*--\s*)/,/^(?:\s*-\.\s*)/,/^(?:\s*==\s*)/,/^(?:\(-)/,/^(?:-\))/,/^(?:-)/,/^(?:\.)/,/^(?:[\_])/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:v\b)/,/^(?:[A-Za-z]+)/,/^(?:\\\])/,/^(?:\[\/)/,/^(?:\/\])/,/^(?:\[\\)/,/^(?:[!"#$%&'*+,-.`?\\_\/])/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:(\r|\n|\r\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{dir:{rules:[14,15,16,17,18,19,20,21,22,23],inclusive:!1},string:{rules:[2,3],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,8,9,10,11,12,13,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101],inclusive:!0}}};function zt(){this.yy={}}return jt.lexer=Ut,zt.prototype=jt,jt.Parser=zt,new zt}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(28).readFileSync(n(29).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(7),n(9)(t))},function(t,e,n){var r=n(62),i=n(241),o=n(242),a=n(243),s=n(244),u=n(245);function c(t){var e=this.__data__=new r(t);this.size=e.size}c.prototype.clear=i,c.prototype.delete=o,c.prototype.get=a,c.prototype.has=s,c.prototype.set=u,t.exports=c},function(t,e,n){var r=n(236),i=n(237),o=n(238),a=n(239),s=n(240);function u(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t>>24]^f[p>>>16&255]^l[g>>>8&255]^h[255&y]^e[b++],a=c[p>>>24]^f[g>>>16&255]^l[y>>>8&255]^h[255&d]^e[b++],s=c[g>>>24]^f[y>>>16&255]^l[d>>>8&255]^h[255&p]^e[b++],u=c[y>>>24]^f[d>>>16&255]^l[p>>>8&255]^h[255&g]^e[b++],d=o,p=a,g=s,y=u;return o=(r[d>>>24]<<24|r[p>>>16&255]<<16|r[g>>>8&255]<<8|r[255&y])^e[b++],a=(r[p>>>24]<<24|r[g>>>16&255]<<16|r[y>>>8&255]<<8|r[255&d])^e[b++],s=(r[g>>>24]<<24|r[y>>>16&255]<<16|r[d>>>8&255]<<8|r[255&p])^e[b++],u=(r[y>>>24]<<24|r[d>>>16&255]<<16|r[p>>>8&255]<<8|r[255&g])^e[b++],[o>>>=0,a>>>=0,s>>>=0,u>>>=0]}var s=[0,1,2,4,8,16,32,64,128,27,54],u=function(){for(var t=new Array(256),e=0;e<256;e++)t[e]=e<128?e<<1:e<<1^283;for(var n=[],r=[],i=[[],[],[],[]],o=[[],[],[],[]],a=0,s=0,u=0;u<256;++u){var c=s^s<<1^s<<2^s<<3^s<<4;c=c>>>8^255&c^99,n[a]=c,r[c]=a;var f=t[a],l=t[f],h=t[l],d=257*t[c]^16843008*c;i[0][a]=d<<24|d>>>8,i[1][a]=d<<16|d>>>16,i[2][a]=d<<8|d>>>24,i[3][a]=d,d=16843009*h^65537*l^257*f^16843008*a,o[0][c]=d<<24|d>>>8,o[1][c]=d<<16|d>>>16,o[2][c]=d<<8|d>>>24,o[3][c]=d,0===a?a=s=1:(a=f^t[t[t[h^f]]],s^=t[t[s]])}return{SBOX:n,INV_SBOX:r,SUB_MIX:i,INV_SUB_MIX:o}}();function c(t){this._key=i(t),this._reset()}c.blockSize=16,c.keySize=32,c.prototype.blockSize=c.blockSize,c.prototype.keySize=c.keySize,c.prototype._reset=function(){for(var t=this._key,e=t.length,n=e+6,r=4*(n+1),i=[],o=0;o>>24,a=u.SBOX[a>>>24]<<24|u.SBOX[a>>>16&255]<<16|u.SBOX[a>>>8&255]<<8|u.SBOX[255&a],a^=s[o/e|0]<<24):e>6&&o%e==4&&(a=u.SBOX[a>>>24]<<24|u.SBOX[a>>>16&255]<<16|u.SBOX[a>>>8&255]<<8|u.SBOX[255&a]),i[o]=i[o-e]^a}for(var c=[],f=0;f>>24]]^u.INV_SUB_MIX[1][u.SBOX[h>>>16&255]]^u.INV_SUB_MIX[2][u.SBOX[h>>>8&255]]^u.INV_SUB_MIX[3][u.SBOX[255&h]]}this._nRounds=n,this._keySchedule=i,this._invKeySchedule=c},c.prototype.encryptBlockRaw=function(t){return a(t=i(t),this._keySchedule,u.SUB_MIX,u.SBOX,this._nRounds)},c.prototype.encryptBlock=function(t){var e=this.encryptBlockRaw(t),n=r.allocUnsafe(16);return n.writeUInt32BE(e[0],0),n.writeUInt32BE(e[1],4),n.writeUInt32BE(e[2],8),n.writeUInt32BE(e[3],12),n},c.prototype.decryptBlock=function(t){var e=(t=i(t))[1];t[1]=t[3],t[3]=e;var n=a(t,this._invKeySchedule,u.INV_SUB_MIX,u.INV_SBOX,this._nRounds),o=r.allocUnsafe(16);return o.writeUInt32BE(n[0],0),o.writeUInt32BE(n[3],4),o.writeUInt32BE(n[2],8),o.writeUInt32BE(n[1],12),o},c.prototype.scrub=function(){o(this._keySchedule),o(this._invKeySchedule),o(this._key)},t.exports.AES=c},function(t,e,n){var r=n(3).Buffer,i=n(111);t.exports=function(t,e,n,o){if(r.isBuffer(t)||(t=r.from(t,"binary")),e&&(r.isBuffer(e)||(e=r.from(e,"binary")),8!==e.length))throw new RangeError("salt should be Buffer with 8 byte length");for(var a=n/8,s=r.alloc(a),u=r.alloc(o||0),c=r.alloc(0);a>0||o>0;){var f=new i;f.update(c),f.update(t),e&&f.update(e),c=f.digest();var l=0;if(a>0){var h=s.length-a;l=Math.min(a,c.length),c.copy(s,h,0,l),a-=l}if(l0){var d=u.length-o,p=Math.min(o,c.length-l);c.copy(u,d,l,l+p),o-=p}}return c.fill(0),{key:s,iv:u}}},function(t,e,n){"use strict";var r=n(5),i=n(16),o=i.getNAF,a=i.getJSF,s=i.assert;function u(t,e){this.type=t,this.p=new r(e.p,16),this.red=e.prime?r.red(e.prime):r.mont(this.p),this.zero=new r(0).toRed(this.red),this.one=new r(1).toRed(this.red),this.two=new r(2).toRed(this.red),this.n=e.n&&new r(e.n,16),this.g=e.g&&this.pointFromJSON(e.g,e.gRed),this._wnafT1=new Array(4),this._wnafT2=new Array(4),this._wnafT3=new Array(4),this._wnafT4=new Array(4);var n=this.n&&this.p.div(this.n);!n||n.cmpn(100)>0?this.redN=null:(this._maxwellTrick=!0,this.redN=this.n.toRed(this.red))}function c(t,e){this.curve=t,this.type=e,this.precomputed=null}t.exports=u,u.prototype.point=function(){throw new Error("Not implemented")},u.prototype.validate=function(){throw new Error("Not implemented")},u.prototype._fixedNafMul=function(t,e){s(t.precomputed);var n=t._getDoubles(),r=o(e,1),i=(1<=u;e--)c=(c<<1)+r[e];a.push(c)}for(var f=this.jpoint(null,null,null),l=this.jpoint(null,null,null),h=i;h>0;h--){for(u=0;u=0;c--){for(e=0;c>=0&&0===a[c];c--)e++;if(c>=0&&e++,u=u.dblp(e),c<0)break;var f=a[c];s(0!==f),u="affine"===t.type?f>0?u.mixedAdd(i[f-1>>1]):u.mixedAdd(i[-f-1>>1].neg()):f>0?u.add(i[f-1>>1]):u.add(i[-f-1>>1].neg())}return"affine"===t.type?u.toP():u},u.prototype._wnafMulAdd=function(t,e,n,r,i){for(var s=this._wnafT1,u=this._wnafT2,c=this._wnafT3,f=0,l=0;l=1;l-=2){var d=l-1,p=l;if(1===s[d]&&1===s[p]){var g=[e[d],null,null,e[p]];0===e[d].y.cmp(e[p].y)?(g[1]=e[d].add(e[p]),g[2]=e[d].toJ().mixedAdd(e[p].neg())):0===e[d].y.cmp(e[p].y.redNeg())?(g[1]=e[d].toJ().mixedAdd(e[p]),g[2]=e[d].add(e[p].neg())):(g[1]=e[d].toJ().mixedAdd(e[p]),g[2]=e[d].toJ().mixedAdd(e[p].neg()));var y=[-3,-1,-5,-7,0,7,5,1,3],b=a(n[d],n[p]);f=Math.max(b[0].length,f),c[d]=new Array(f),c[p]=new Array(f);for(var m=0;m=0;l--){for(var k=0;l>=0;){var E=!0;for(m=0;m=0&&k++,w=w.dblp(k),l<0)break;for(m=0;m0?A=u[m][S-1>>1]:S<0&&(A=u[m][-S-1>>1].neg()),w="affine"===A.type?w.mixedAdd(A):w.add(A))}}for(l=0;l=Math.ceil((t.bitLength()+1)/e.step)},c.prototype._getDoubles=function(t,e){if(this.precomputed&&this.precomputed.doubles)return this.precomputed.doubles;for(var n=[this],r=this,i=0;i-1}(s)?s:(n=s.match(o))?(e=n[0],r.test(e)?"about:blank":s):"about:blank"}}},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[2,3],n=[1,7],r=[7,12,15,17,19,20,21],i=[7,11,12,15,17,19,20,21],o=[2,20],a=[1,32],s={trace:function(){},yy:{},symbols_:{error:2,start:3,GG:4,":":5,document:6,EOF:7,DIR:8,options:9,body:10,OPT:11,NL:12,line:13,statement:14,COMMIT:15,commit_arg:16,BRANCH:17,ID:18,CHECKOUT:19,MERGE:20,RESET:21,reset_arg:22,STR:23,HEAD:24,reset_parents:25,CARET:26,$accept:0,$end:1},terminals_:{2:"error",4:"GG",5:":",7:"EOF",8:"DIR",11:"OPT",12:"NL",15:"COMMIT",17:"BRANCH",18:"ID",19:"CHECKOUT",20:"MERGE",21:"RESET",23:"STR",24:"HEAD",26:"CARET"},productions_:[0,[3,4],[3,5],[6,0],[6,2],[9,2],[9,1],[10,0],[10,2],[13,2],[13,1],[14,2],[14,2],[14,2],[14,2],[14,2],[16,0],[16,1],[22,2],[22,2],[25,0],[25,2]],performAction:function(t,e,n,r,i,o,a){var s=o.length-1;switch(i){case 1:return o[s-1];case 2:return r.setDirection(o[s-3]),o[s-1];case 4:r.setOptions(o[s-1]),this.$=o[s];break;case 5:o[s-1]+=o[s],this.$=o[s-1];break;case 7:this.$=[];break;case 8:o[s-1].push(o[s]),this.$=o[s-1];break;case 9:this.$=o[s-1];break;case 11:r.commit(o[s]);break;case 12:r.branch(o[s]);break;case 13:r.checkout(o[s]);break;case 14:r.merge(o[s]);break;case 15:r.reset(o[s]);break;case 16:this.$="";break;case 17:this.$=o[s];break;case 18:this.$=o[s-1]+":"+o[s];break;case 19:this.$=o[s-1]+":"+r.count,r.count=0;break;case 20:r.count=0;break;case 21:r.count+=1}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3],8:[1,4]},{6:5,7:e,9:6,12:n},{5:[1,8]},{7:[1,9]},t(r,[2,7],{10:10,11:[1,11]}),t(i,[2,6]),{6:12,7:e,9:6,12:n},{1:[2,1]},{7:[2,4],12:[1,15],13:13,14:14,15:[1,16],17:[1,17],19:[1,18],20:[1,19],21:[1,20]},t(i,[2,5]),{7:[1,21]},t(r,[2,8]),{12:[1,22]},t(r,[2,10]),{12:[2,16],16:23,23:[1,24]},{18:[1,25]},{18:[1,26]},{18:[1,27]},{18:[1,30],22:28,24:[1,29]},{1:[2,2]},t(r,[2,9]),{12:[2,11]},{12:[2,17]},{12:[2,12]},{12:[2,13]},{12:[2,14]},{12:[2,15]},{12:o,25:31,26:a},{12:o,25:33,26:a},{12:[2,18]},{12:o,25:34,26:a},{12:[2,19]},{12:[2,21]}],defaultActions:{9:[2,1],21:[2,2],23:[2,11],24:[2,17],25:[2,12],26:[2,13],27:[2,14],28:[2,15],31:[2,18],33:[2,19],34:[2,21]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],o=[],a=this.table,s="",u=0,c=0,f=0,l=2,h=1,d=o.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var b=p.yylloc;o.push(b);var m=p.options&&p.options.ranges;function v(){var t;return"number"!=typeof(t=r.pop()||p.lex()||h)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,w,x,k,E,A,S,T,M,D={};;){if(x=n[n.length-1],this.defaultActions[x]?k=this.defaultActions[x]:(null==_&&(_=v()),k=a[x]&&a[x][_]),void 0===k||!k.length||!k[0]){var C="";for(A in M=[],a[x])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=p.showPosition?"Parse error on line "+(u+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(u+1)+": Unexpected "+(_==h?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:b,expected:M})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),o.push(p.yylloc),n.push(k[1]),_=null,w?(_=w,w=null):(c=p.yyleng,s=p.yytext,u=p.yylineno,b=p.yylloc,f>0&&f--);break;case 2:if(S=this.productions_[k[1]][1],D.$=i[i.length-S],D._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},m&&(D._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(E=this.performAction.apply(D,[s,c,u,g.yy,k[1],i,o].concat(d))))return E;S&&(n=n.slice(0,-1*S*2),i=i.slice(0,-1*S),o=o.slice(0,-1*S)),n.push(this.productions_[k[1]][0]),i.push(D.$),o.push(D._$),T=a[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0}},u={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var o in i)this[o]=i[o];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),o=0;oe[0].length)){if(e=n,r=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return 12;case 1:case 2:case 3:break;case 4:return 4;case 5:return 15;case 6:return 17;case 7:return 20;case 8:return 21;case 9:return 19;case 10:case 11:return 8;case 12:return 5;case 13:return 26;case 14:this.begin("options");break;case 15:this.popState();break;case 16:return 11;case 17:this.begin("string");break;case 18:this.popState();break;case 19:return 23;case 20:return 18;case 21:return 7}},rules:[/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit\b)/i,/^(?:branch\b)/i,/^(?:merge\b)/i,/^(?:reset\b)/i,/^(?:checkout\b)/i,/^(?:LR\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:end\r?\n)/i,/^(?:[^\n]+\r?\n)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[a-zA-Z][a-zA-Z0-9_]+)/i,/^(?:$)/i],conditions:{options:{rules:[15,16],inclusive:!1},string:{rules:[18,19],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,20,21],inclusive:!0}}};function c(){this.yy={}}return s.lexer=u,c.prototype=s,s.Parser=c,new c}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(28).readFileSync(n(29).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(7),n(9)(t))},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[6,9,10],n={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,e,n,r,i,o,a){o.length;switch(i){case 1:return r;case 4:break;case 6:r.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},t(e,[2,3]),t(e,[2,4]),t(e,[2,5]),t(e,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],o=[],a=this.table,s="",u=0,c=0,f=0,l=2,h=1,d=o.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var b=p.yylloc;o.push(b);var m=p.options&&p.options.ranges;function v(){var t;return"number"!=typeof(t=r.pop()||p.lex()||h)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,w,x,k,E,A,S,T,M,D={};;){if(x=n[n.length-1],this.defaultActions[x]?k=this.defaultActions[x]:(null==_&&(_=v()),k=a[x]&&a[x][_]),void 0===k||!k.length||!k[0]){var C="";for(A in M=[],a[x])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=p.showPosition?"Parse error on line "+(u+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(u+1)+": Unexpected "+(_==h?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:b,expected:M})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),o.push(p.yylloc),n.push(k[1]),_=null,w?(_=w,w=null):(c=p.yyleng,s=p.yytext,u=p.yylineno,b=p.yylloc,f>0&&f--);break;case 2:if(S=this.productions_[k[1]][1],D.$=i[i.length-S],D._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},m&&(D._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(E=this.performAction.apply(D,[s,c,u,g.yy,k[1],i,o].concat(d))))return E;S&&(n=n.slice(0,-1*S*2),i=i.slice(0,-1*S),o=o.slice(0,-1*S)),n.push(this.productions_[k[1]][0]),i.push(D.$),o.push(D._$),T=a[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0}},r={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var o in i)this[o]=i[o];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),o=0;oe[0].length)){if(e=n,r=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};function i(){this.yy={}}return n.lexer=r,i.prototype=n,n.Parser=i,new i}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(28).readFileSync(n(29).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(7),n(9)(t))},function(t,e,n){(function(t,r){var i=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[6,9,10,12],n={trace:function(){},yy:{},symbols_:{error:2,start:3,pie:4,document:5,EOF:6,line:7,statement:8,NL:9,STR:10,VALUE:11,title:12,$accept:0,$end:1},terminals_:{2:"error",4:"pie",6:"EOF",9:"NL",10:"STR",11:"VALUE",12:"title"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,2],[8,1]],performAction:function(t,e,n,r,i,o,a){var s=o.length-1;switch(i){case 4:break;case 6:console.log("str:"+o[s-1]+" value: "+o[s]),r.addSection(o[s-1],r.cleanupValue(o[s]));break;case 7:r.setTitle(o[s].substr(6)),this.$=o[s].substr(6)}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8],12:[1,9]},{1:[2,1]},t(e,[2,3]),t(e,[2,4]),t(e,[2,5]),{11:[1,10]},t(e,[2,7]),t(e,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],o=[],a=this.table,s="",u=0,c=0,f=0,l=2,h=1,d=o.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var b=p.yylloc;o.push(b);var m=p.options&&p.options.ranges;function v(){var t;return"number"!=typeof(t=r.pop()||p.lex()||h)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,w,x,k,E,A,S,T,M,D={};;){if(x=n[n.length-1],this.defaultActions[x]?k=this.defaultActions[x]:(null==_&&(_=v()),k=a[x]&&a[x][_]),void 0===k||!k.length||!k[0]){var C="";for(A in M=[],a[x])this.terminals_[A]&&A>l&&M.push("'"+this.terminals_[A]+"'");C=p.showPosition?"Parse error on line "+(u+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(u+1)+": Unexpected "+(_==h?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(C,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:b,expected:M})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),o.push(p.yylloc),n.push(k[1]),_=null,w?(_=w,w=null):(c=p.yyleng,s=p.yytext,u=p.yylineno,b=p.yylloc,f>0&&f--);break;case 2:if(S=this.productions_[k[1]][1],D.$=i[i.length-S],D._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},m&&(D._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(E=this.performAction.apply(D,[s,c,u,g.yy,k[1],i,o].concat(d))))return E;S&&(n=n.slice(0,-1*S*2),i=i.slice(0,-1*S),o=o.slice(0,-1*S)),n.push(this.productions_[k[1]][0]),i.push(D.$),o.push(D._$),T=a[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0}},r={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var o in i)this[o]=i[o];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),o=0;oe[0].length)){if(e=n,r=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:case 1:break;case 2:return 4;case 3:return 9;case 4:return"space";case 5:return 12;case 6:this.begin("string");break;case 7:this.popState();break;case 8:return"STR";case 9:return"VALUE";case 10:return 6}},rules:[/^(?:%%[^\n]*)/i,/^(?:\s+)/i,/^(?:pie\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:title\s[^#\n;]+)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{string:{rules:[7,8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,9,10],inclusive:!0}}};function i(){this.yy={}}return n.lexer=r,i.prototype=n,n.Parser=i,new i}();e.parser=i,e.Parser=i.Parser,e.parse=function(){return i.parse.apply(i,arguments)},e.main=function(r){r[1]||(console.log("Usage: "+r[0]+" FILE"),t.exit(1));var i=n(28).readFileSync(n(29).normalize(r[1]),"utf8");return e.parser.parse(i)},n.c[n.s]===r&&e.main(t.argv.slice(1))}).call(this,n(7),n(9)(t))},function(t){t.exports=JSON.parse('{"name":"mermaid","version":"8.4.3","description":"Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.","main":"dist/mermaid.core.js","keywords":["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph"],"scripts":{"build":"webpack --progress --colors","postbuild":"documentation build src/mermaidAPI.js --shallow -f md --markdown-toc false -o docs/mermaidAPI.md","build:watch":"yarn build --watch","minify":"minify ./dist/mermaid.js > ./dist/mermaid.min.js","release":"yarn build -p --config webpack.config.prod.babel.js","lint":"eslint src","e2e:depr":"yarn lint && jest e2e --config e2e/jest.config.js","cypress":"percy exec -- cypress run","e2e":"start-server-and-test dev http://localhost:9000/ cypress","e2e-upd":"yarn lint && jest e2e -u --config e2e/jest.config.js","dev":"webpack-dev-server --config webpack.config.e2e.js","test":"yarn lint && jest src/.*","test:watch":"jest --watch src","prepublishOnly":"yarn build && yarn release && yarn test && yarn e2e","prepush":"yarn test"},"repository":{"type":"git","url":"https://github.com/knsv/mermaid"},"author":"Knut Sveidqvist","license":"MIT","standard":{"ignore":["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],"globals":["page"]},"dependencies":{"@braintree/sanitize-url":"^3.1.0","crypto-random-string":"^3.0.1","d3":"^5.7.0","dagre-d3-unofficial":"0.6.4","dagre":"^0.8.4","graphlib":"^2.1.7","he":"^1.2.0","lodash":"^4.17.11","minify":"^4.1.1","moment-mini":"^2.22.1","scope-css":"^1.2.1"},"devDependencies":{"documentation":"^12.0.1","prettier":"^1.18.2","eslint":"^6.3.0","eslint-config-prettier":"^6.3.0","eslint-plugin-prettier":"^3.1.0","@babel/core":"^7.2.2","@babel/preset-env":"^7.2.0","@babel/register":"^7.0.0","@percy/cypress":"^2.0.1","babel-core":"7.0.0-bridge.0","babel-jest":"^23.6.0","babel-loader":"^8.0.4","coveralls":"^3.0.2","css-loader":"^2.0.1","css-to-string-loader":"^0.1.3","cypress":"3.4.0","husky":"^1.2.1","identity-obj-proxy":"^3.0.0","jest":"^24.9.0","jison":"^0.4.18","moment":"^2.23.0","node-sass":"^4.12.0","puppeteer":"^1.17.0","sass-loader":"^7.1.0","start-server-and-test":"^1.10.0","webpack":"^4.27.1","webpack-cli":"^3.1.2","webpack-dev-server":"^3.4.1","webpack-node-externals":"^1.7.2","yarn-upgrade-all":"^0.5.0"},"files":["dist"],"yarn-upgrade-all":{"ignore":["babel-core"]}}')},function(t,e,n){"use strict";var r=n(12);t.exports=s;var i="\0",o="\0",a="";function s(t){this._isDirected=!r.has(t,"directed")||t.directed,this._isMultigraph=!!r.has(t,"multigraph")&&t.multigraph,this._isCompound=!!r.has(t,"compound")&&t.compound,this._label=void 0,this._defaultNodeLabelFn=r.constant(void 0),this._defaultEdgeLabelFn=r.constant(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[o]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}function u(t,e){t[e]?t[e]++:t[e]=1}function c(t,e){--t[e]||delete t[e]}function f(t,e,n,o){var s=""+e,u=""+n;if(!t&&s>u){var c=s;s=u,u=c}return s+a+u+a+(r.isUndefined(o)?i:o)}function l(t,e,n,r){var i=""+e,o=""+n;if(!t&&i>o){var a=i;i=o,o=a}var s={v:i,w:o};return r&&(s.name=r),s}function h(t,e){return f(t,e.v,e.w,e.name)}s.prototype._nodeCount=0,s.prototype._edgeCount=0,s.prototype.isDirected=function(){return this._isDirected},s.prototype.isMultigraph=function(){return this._isMultigraph},s.prototype.isCompound=function(){return this._isCompound},s.prototype.setGraph=function(t){return this._label=t,this},s.prototype.graph=function(){return this._label},s.prototype.setDefaultNodeLabel=function(t){return r.isFunction(t)||(t=r.constant(t)),this._defaultNodeLabelFn=t,this},s.prototype.nodeCount=function(){return this._nodeCount},s.prototype.nodes=function(){return r.keys(this._nodes)},s.prototype.sources=function(){var t=this;return r.filter(this.nodes(),(function(e){return r.isEmpty(t._in[e])}))},s.prototype.sinks=function(){var t=this;return r.filter(this.nodes(),(function(e){return r.isEmpty(t._out[e])}))},s.prototype.setNodes=function(t,e){var n=arguments,i=this;return r.each(t,(function(t){n.length>1?i.setNode(t,e):i.setNode(t)})),this},s.prototype.setNode=function(t,e){return r.has(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=e),this):(this._nodes[t]=arguments.length>1?e:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=o,this._children[t]={},this._children[o][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)},s.prototype.node=function(t){return this._nodes[t]},s.prototype.hasNode=function(t){return r.has(this._nodes,t)},s.prototype.removeNode=function(t){var e=this;if(r.has(this._nodes,t)){var n=function(t){e.removeEdge(e._edgeObjs[t])};delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],r.each(this.children(t),(function(t){e.setParent(t)})),delete this._children[t]),r.each(r.keys(this._in[t]),n),delete this._in[t],delete this._preds[t],r.each(r.keys(this._out[t]),n),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this},s.prototype.setParent=function(t,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(r.isUndefined(e))e=o;else{for(var n=e+="";!r.isUndefined(n);n=this.parent(n))if(n===t)throw new Error("Setting "+e+" as parent of "+t+" would create a cycle");this.setNode(e)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=e,this._children[e][t]=!0,this},s.prototype._removeFromParentsChildList=function(t){delete this._children[this._parent[t]][t]},s.prototype.parent=function(t){if(this._isCompound){var e=this._parent[t];if(e!==o)return e}},s.prototype.children=function(t){if(r.isUndefined(t)&&(t=o),this._isCompound){var e=this._children[t];if(e)return r.keys(e)}else{if(t===o)return this.nodes();if(this.hasNode(t))return[]}},s.prototype.predecessors=function(t){var e=this._preds[t];if(e)return r.keys(e)},s.prototype.successors=function(t){var e=this._sucs[t];if(e)return r.keys(e)},s.prototype.neighbors=function(t){var e=this.predecessors(t);if(e)return r.union(e,this.successors(t))},s.prototype.isLeaf=function(t){return 0===(this.isDirected()?this.successors(t):this.neighbors(t)).length},s.prototype.filterNodes=function(t){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var n=this;r.each(this._nodes,(function(n,r){t(r)&&e.setNode(r,n)})),r.each(this._edgeObjs,(function(t){e.hasNode(t.v)&&e.hasNode(t.w)&&e.setEdge(t,n.edge(t))}));var i={};return this._isCompound&&r.each(e.nodes(),(function(t){e.setParent(t,function t(r){var o=n.parent(r);return void 0===o||e.hasNode(o)?(i[r]=o,o):o in i?i[o]:t(o)}(t))})),e},s.prototype.setDefaultEdgeLabel=function(t){return r.isFunction(t)||(t=r.constant(t)),this._defaultEdgeLabelFn=t,this},s.prototype.edgeCount=function(){return this._edgeCount},s.prototype.edges=function(){return r.values(this._edgeObjs)},s.prototype.setPath=function(t,e){var n=this,i=arguments;return r.reduce(t,(function(t,r){return i.length>1?n.setEdge(t,r,e):n.setEdge(t,r),r})),this},s.prototype.setEdge=function(){var t,e,n,i,o=!1,a=arguments[0];"object"==typeof a&&null!==a&&"v"in a?(t=a.v,e=a.w,n=a.name,2===arguments.length&&(i=arguments[1],o=!0)):(t=a,e=arguments[1],n=arguments[3],arguments.length>2&&(i=arguments[2],o=!0)),t=""+t,e=""+e,r.isUndefined(n)||(n=""+n);var s=f(this._isDirected,t,e,n);if(r.has(this._edgeLabels,s))return o&&(this._edgeLabels[s]=i),this;if(!r.isUndefined(n)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(e),this._edgeLabels[s]=o?i:this._defaultEdgeLabelFn(t,e,n);var c=l(this._isDirected,t,e,n);return t=c.v,e=c.w,Object.freeze(c),this._edgeObjs[s]=c,u(this._preds[e],t),u(this._sucs[t],e),this._in[e][s]=c,this._out[t][s]=c,this._edgeCount++,this},s.prototype.edge=function(t,e,n){var r=1===arguments.length?h(this._isDirected,arguments[0]):f(this._isDirected,t,e,n);return this._edgeLabels[r]},s.prototype.hasEdge=function(t,e,n){var i=1===arguments.length?h(this._isDirected,arguments[0]):f(this._isDirected,t,e,n);return r.has(this._edgeLabels,i)},s.prototype.removeEdge=function(t,e,n){var r=1===arguments.length?h(this._isDirected,arguments[0]):f(this._isDirected,t,e,n),i=this._edgeObjs[r];return i&&(t=i.v,e=i.w,delete this._edgeLabels[r],delete this._edgeObjs[r],c(this._preds[e],t),c(this._sucs[t],e),delete this._in[e][r],delete this._out[t][r],this._edgeCount--),this},s.prototype.inEdges=function(t,e){var n=this._in[t];if(n){var i=r.values(n);return e?r.filter(i,(function(t){return t.v===e})):i}},s.prototype.outEdges=function(t,e){var n=this._out[t];if(n){var i=r.values(n);return e?r.filter(i,(function(t){return t.w===e})):i}},s.prototype.nodeEdges=function(t,e){var n=this.inEdges(t,e);if(n)return n.concat(this.outEdges(t,e))}},function(t,e,n){var r=n(32)(n(18),"Map");t.exports=r},function(t,e,n){var r=n(252),i=n(259),o=n(261),a=n(262),s=n(263);function u(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t<=n}},function(t,e,n){(function(t){var r=n(131),i=e&&!e.nodeType&&e,o=i&&"object"==typeof t&&t&&!t.nodeType&&t,a=o&&o.exports===i&&r.process,s=function(){try{var t=o&&o.require&&o.require("util").types;return t||a&&a.binding&&a.binding("util")}catch(t){}}();t.exports=s}).call(this,n(9)(t))},function(t,e,n){var r=n(70),i=n(269),o=Object.prototype.hasOwnProperty;t.exports=function(t){if(!r(t))return i(t);var e=[];for(var n in Object(t))o.call(t,n)&&"constructor"!=n&&e.push(n);return e}},function(t,e,n){var r=n(138),i=n(139),o=Object.prototype.propertyIsEnumerable,a=Object.getOwnPropertySymbols,s=a?function(t){return null==t?[]:(t=Object(t),r(a(t),(function(e){return o.call(t,e)})))}:i;t.exports=s},function(t,e){t.exports=function(t,e){for(var n=-1,r=e.length,i=t.length;++n0&&o(f)?n>1?t(f,n-1,o,a,s):r(s,f):a||(s[s.length]=f)}return s}},function(t,e,n){var r=n(42);t.exports=function(t,e,n){for(var i=-1,o=t.length;++i>>32-e}function c(t,e,n,r,i,o,a){return u(t+(e&n|~e&r)+i+o|0,a)+e|0}function f(t,e,n,r,i,o,a){return u(t+(e&r|n&~r)+i+o|0,a)+e|0}function l(t,e,n,r,i,o,a){return u(t+(e^n^r)+i+o|0,a)+e|0}function h(t,e,n,r,i,o,a){return u(t+(n^(e|~r))+i+o|0,a)+e|0}r(s,i),s.prototype._update=function(){for(var t=a,e=0;e<16;++e)t[e]=this._block.readInt32LE(4*e);var n=this._a,r=this._b,i=this._c,o=this._d;n=c(n,r,i,o,t[0],3614090360,7),o=c(o,n,r,i,t[1],3905402710,12),i=c(i,o,n,r,t[2],606105819,17),r=c(r,i,o,n,t[3],3250441966,22),n=c(n,r,i,o,t[4],4118548399,7),o=c(o,n,r,i,t[5],1200080426,12),i=c(i,o,n,r,t[6],2821735955,17),r=c(r,i,o,n,t[7],4249261313,22),n=c(n,r,i,o,t[8],1770035416,7),o=c(o,n,r,i,t[9],2336552879,12),i=c(i,o,n,r,t[10],4294925233,17),r=c(r,i,o,n,t[11],2304563134,22),n=c(n,r,i,o,t[12],1804603682,7),o=c(o,n,r,i,t[13],4254626195,12),i=c(i,o,n,r,t[14],2792965006,17),n=f(n,r=c(r,i,o,n,t[15],1236535329,22),i,o,t[1],4129170786,5),o=f(o,n,r,i,t[6],3225465664,9),i=f(i,o,n,r,t[11],643717713,14),r=f(r,i,o,n,t[0],3921069994,20),n=f(n,r,i,o,t[5],3593408605,5),o=f(o,n,r,i,t[10],38016083,9),i=f(i,o,n,r,t[15],3634488961,14),r=f(r,i,o,n,t[4],3889429448,20),n=f(n,r,i,o,t[9],568446438,5),o=f(o,n,r,i,t[14],3275163606,9),i=f(i,o,n,r,t[3],4107603335,14),r=f(r,i,o,n,t[8],1163531501,20),n=f(n,r,i,o,t[13],2850285829,5),o=f(o,n,r,i,t[2],4243563512,9),i=f(i,o,n,r,t[7],1735328473,14),n=l(n,r=f(r,i,o,n,t[12],2368359562,20),i,o,t[5],4294588738,4),o=l(o,n,r,i,t[8],2272392833,11),i=l(i,o,n,r,t[11],1839030562,16),r=l(r,i,o,n,t[14],4259657740,23),n=l(n,r,i,o,t[1],2763975236,4),o=l(o,n,r,i,t[4],1272893353,11),i=l(i,o,n,r,t[7],4139469664,16),r=l(r,i,o,n,t[10],3200236656,23),n=l(n,r,i,o,t[13],681279174,4),o=l(o,n,r,i,t[0],3936430074,11),i=l(i,o,n,r,t[3],3572445317,16),r=l(r,i,o,n,t[6],76029189,23),n=l(n,r,i,o,t[9],3654602809,4),o=l(o,n,r,i,t[12],3873151461,11),i=l(i,o,n,r,t[15],530742520,16),n=h(n,r=l(r,i,o,n,t[2],3299628645,23),i,o,t[0],4096336452,6),o=h(o,n,r,i,t[7],1126891415,10),i=h(i,o,n,r,t[14],2878612391,15),r=h(r,i,o,n,t[5],4237533241,21),n=h(n,r,i,o,t[12],1700485571,6),o=h(o,n,r,i,t[3],2399980690,10),i=h(i,o,n,r,t[10],4293915773,15),r=h(r,i,o,n,t[1],2240044497,21),n=h(n,r,i,o,t[8],1873313359,6),o=h(o,n,r,i,t[15],4264355552,10),i=h(i,o,n,r,t[6],2734768916,15),r=h(r,i,o,n,t[13],1309151649,21),n=h(n,r,i,o,t[4],4149444226,6),o=h(o,n,r,i,t[11],3174756917,10),i=h(i,o,n,r,t[2],718787259,15),r=h(r,i,o,n,t[9],3951481745,21),this._a=this._a+n|0,this._b=this._b+r|0,this._c=this._c+i|0,this._d=this._d+o|0},s.prototype._digest=function(){this._block[this._blockOffset++]=128,this._blockOffset>56&&(this._block.fill(0,this._blockOffset,64),this._update(),this._blockOffset=0),this._block.fill(0,this._blockOffset,56),this._block.writeUInt32LE(this._length[0],56),this._block.writeUInt32LE(this._length[1],60),this._update();var t=o.allocUnsafe(16);return t.writeInt32LE(this._a,0),t.writeInt32LE(this._b,4),t.writeInt32LE(this._c,8),t.writeInt32LE(this._d,12),t},t.exports=s},function(t,e,n){t.exports=i;var r=n(113).EventEmitter;function i(){r.call(this)}n(2)(i,r),i.Readable=n(114),i.Writable=n(428),i.Duplex=n(429),i.Transform=n(430),i.PassThrough=n(431),i.Stream=i,i.prototype.pipe=function(t,e){var n=this;function i(e){t.writable&&!1===t.write(e)&&n.pause&&n.pause()}function o(){n.readable&&n.resume&&n.resume()}n.on("data",i),t.on("drain",o),t._isStdio||e&&!1===e.end||(n.on("end",s),n.on("close",u));var a=!1;function s(){a||(a=!0,t.end())}function u(){a||(a=!0,"function"==typeof t.destroy&&t.destroy())}function c(t){if(f(),0===r.listenerCount(this,"error"))throw t}function f(){n.removeListener("data",i),t.removeListener("drain",o),n.removeListener("end",s),n.removeListener("close",u),n.removeListener("error",c),t.removeListener("error",c),n.removeListener("end",f),n.removeListener("close",f),t.removeListener("close",f)}return n.on("error",c),t.on("error",c),n.on("end",f),n.on("close",f),t.on("close",f),t.emit("pipe",n),t}},function(t,e,n){"use strict";var r,i="object"==typeof Reflect?Reflect:null,o=i&&"function"==typeof i.apply?i.apply:function(t,e,n){return Function.prototype.apply.call(t,e,n)};r=i&&"function"==typeof i.ownKeys?i.ownKeys:Object.getOwnPropertySymbols?function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:function(t){return Object.getOwnPropertyNames(t)};var a=Number.isNaN||function(t){return t!=t};function s(){s.init.call(this)}t.exports=s,s.EventEmitter=s,s.prototype._events=void 0,s.prototype._eventsCount=0,s.prototype._maxListeners=void 0;var u=10;function c(t){return void 0===t._maxListeners?s.defaultMaxListeners:t._maxListeners}function f(t,e,n,r){var i,o,a,s;if("function"!=typeof n)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof n);if(void 0===(o=t._events)?(o=t._events=Object.create(null),t._eventsCount=0):(void 0!==o.newListener&&(t.emit("newListener",e,n.listener?n.listener:n),o=t._events),a=o[e]),void 0===a)a=o[e]=n,++t._eventsCount;else if("function"==typeof a?a=o[e]=r?[n,a]:[a,n]:r?a.unshift(n):a.push(n),(i=c(t))>0&&a.length>i&&!a.warned){a.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(e)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=t,u.type=e,u.count=a.length,s=u,console&&console.warn&&console.warn(s)}return t}function l(){for(var t=[],e=0;e0&&(a=e[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var u=i[t];if(void 0===u)return!1;if("function"==typeof u)o(u,this,e);else{var c=u.length,f=g(u,c);for(n=0;n=0;o--)if(n[o]===e||n[o].listener===e){a=n[o].listener,i=o;break}if(i<0)return this;0===i?n.shift():function(t,e){for(;e+1=0;r--)this.removeListener(t,e[r]);return this},s.prototype.listeners=function(t){return d(this,t,!0)},s.prototype.rawListeners=function(t){return d(this,t,!1)},s.listenerCount=function(t,e){return"function"==typeof t.listenerCount?t.listenerCount(e):p.call(t,e)},s.prototype.listenerCount=p,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(t,e,n){(e=t.exports=n(193)).Stream=e,e.Readable=e,e.Writable=n(116),e.Duplex=n(35),e.Transform=n(196),e.PassThrough=n(427)},function(t,e,n){var r=n(8),i=r.Buffer;function o(t,e){for(var n in t)e[n]=t[n]}function a(t,e,n){return i(t,e,n)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?t.exports=r:(o(r,e),e.Buffer=a),o(i,a),a.from=function(t,e,n){if("number"==typeof t)throw new TypeError("Argument must not be a number");return i(t,e,n)},a.alloc=function(t,e,n){if("number"!=typeof t)throw new TypeError("Argument must be a number");var r=i(t);return void 0!==e?"string"==typeof n?r.fill(e,n):r.fill(e):r.fill(0),r},a.allocUnsafe=function(t){if("number"!=typeof t)throw new TypeError("Argument must be a number");return i(t)},a.allocUnsafeSlow=function(t){if("number"!=typeof t)throw new TypeError("Argument must be a number");return r.SlowBuffer(t)}},function(t,e,n){"use strict";(function(e,r,i){var o=n(78);function a(t){var e=this;this.next=null,this.entry=null,this.finish=function(){!function(t,e,n){var r=t.entry;t.entry=null;for(;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}(e,t)}}t.exports=m;var s,u=!e.browser&&["v0.10","v0.9."].indexOf(e.version.slice(0,5))>-1?r:o.nextTick;m.WritableState=b;var c=n(54);c.inherits=n(2);var f={deprecate:n(426)},l=n(194),h=n(115).Buffer,d=i.Uint8Array||function(){};var p,g=n(195);function y(){}function b(t,e){s=s||n(35),t=t||{};var r=e instanceof s;this.objectMode=!!t.objectMode,r&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var i=t.highWaterMark,c=t.writableHighWaterMark,f=this.objectMode?16:16384;this.highWaterMark=i||0===i?i:r&&(c||0===c)?c:f,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var l=!1===t.decodeStrings;this.decodeStrings=!l,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(t){!function(t,e){var n=t._writableState,r=n.sync,i=n.writecb;if(function(t){t.writing=!1,t.writecb=null,t.length-=t.writelen,t.writelen=0}(n),e)!function(t,e,n,r,i){--e.pendingcb,n?(o.nextTick(i,r),o.nextTick(E,t,e),t._writableState.errorEmitted=!0,t.emit("error",r)):(i(r),t._writableState.errorEmitted=!0,t.emit("error",r),E(t,e))}(t,n,r,e,i);else{var a=x(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||w(t,n),r?u(_,t,n,a,i):_(t,n,a,i)}}(e,t)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function m(t){if(s=s||n(35),!(p.call(m,this)||this instanceof s))return new m(t);this._writableState=new b(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev),"function"==typeof t.destroy&&(this._destroy=t.destroy),"function"==typeof t.final&&(this._final=t.final)),l.call(this)}function v(t,e,n,r,i,o,a){e.writelen=r,e.writecb=a,e.writing=!0,e.sync=!0,n?t._writev(i,e.onwrite):t._write(i,o,e.onwrite),e.sync=!1}function _(t,e,n,r){n||function(t,e){0===e.length&&e.needDrain&&(e.needDrain=!1,t.emit("drain"))}(t,e),e.pendingcb--,r(),E(t,e)}function w(t,e){e.bufferProcessing=!0;var n=e.bufferedRequest;if(t._writev&&n&&n.next){var r=e.bufferedRequestCount,i=new Array(r),o=e.corkedRequestsFree;o.entry=n;for(var s=0,u=!0;n;)i[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;i.allBuffers=u,v(t,e,!0,e.length,i,"",o.finish),e.pendingcb++,e.lastBufferedRequest=null,o.next?(e.corkedRequestsFree=o.next,o.next=null):e.corkedRequestsFree=new a(e),e.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,f=n.encoding,l=n.callback;if(v(t,e,!1,e.objectMode?1:c.length,c,f,l),n=n.next,e.bufferedRequestCount--,e.writing)break}null===n&&(e.lastBufferedRequest=null)}e.bufferedRequest=n,e.bufferProcessing=!1}function x(t){return t.ending&&0===t.length&&null===t.bufferedRequest&&!t.finished&&!t.writing}function k(t,e){t._final((function(n){e.pendingcb--,n&&t.emit("error",n),e.prefinished=!0,t.emit("prefinish"),E(t,e)}))}function E(t,e){var n=x(e);return n&&(!function(t,e){e.prefinished||e.finalCalled||("function"==typeof t._final?(e.pendingcb++,e.finalCalled=!0,o.nextTick(k,t,e)):(e.prefinished=!0,t.emit("prefinish")))}(t,e),0===e.pendingcb&&(e.finished=!0,t.emit("finish"))),n}c.inherits(m,l),b.prototype.getBuffer=function(){for(var t=this.bufferedRequest,e=[];t;)e.push(t),t=t.next;return e},function(){try{Object.defineProperty(b.prototype,"buffer",{get:f.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(t){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(p=Function.prototype[Symbol.hasInstance],Object.defineProperty(m,Symbol.hasInstance,{value:function(t){return!!p.call(this,t)||this===m&&(t&&t._writableState instanceof b)}})):p=function(t){return t instanceof this},m.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},m.prototype.write=function(t,e,n){var r,i=this._writableState,a=!1,s=!i.objectMode&&(r=t,h.isBuffer(r)||r instanceof d);return s&&!h.isBuffer(t)&&(t=function(t){return h.from(t)}(t)),"function"==typeof e&&(n=e,e=null),s?e="buffer":e||(e=i.defaultEncoding),"function"!=typeof n&&(n=y),i.ended?function(t,e){var n=new Error("write after end");t.emit("error",n),o.nextTick(e,n)}(this,n):(s||function(t,e,n,r){var i=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||e.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(t.emit("error",a),o.nextTick(r,a),i=!1),i}(this,i,t,n))&&(i.pendingcb++,a=function(t,e,n,r,i,o){if(!n){var a=function(t,e,n){t.objectMode||!1===t.decodeStrings||"string"!=typeof e||(e=h.from(e,n));return e}(e,r,i);r!==a&&(n=!0,i="buffer",r=a)}var s=e.objectMode?1:r.length;e.length+=s;var u=e.length-1))throw new TypeError("Unknown encoding: "+t);return this._writableState.defaultEncoding=t,this},Object.defineProperty(m.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),m.prototype._write=function(t,e,n){n(new Error("_write() is not implemented"))},m.prototype._writev=null,m.prototype.end=function(t,e,n){var r=this._writableState;"function"==typeof t?(n=t,t=null,e=null):"function"==typeof e&&(n=e,e=null),null!=t&&this.write(t,e),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(t,e,n){e.ending=!0,E(t,e),n&&(e.finished?o.nextTick(n):t.once("finish",n));e.ended=!0,t.writable=!1}(this,r,n)},Object.defineProperty(m.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(t){this._writableState&&(this._writableState.destroyed=t)}}),m.prototype.destroy=g.destroy,m.prototype._undestroy=g.undestroy,m.prototype._destroy=function(t,e){this.end(),e(t)}}).call(this,n(7),n(424).setImmediate,n(11))},function(t,e,n){"use strict";var r=n(3).Buffer,i=r.isEncoding||function(t){switch((t=""+t)&&t.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function o(t){var e;switch(this.encoding=function(t){var e=function(t){if(!t)return"utf8";for(var e;;)switch(t){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return t;default:if(e)return;t=(""+t).toLowerCase(),e=!0}}(t);if("string"!=typeof e&&(r.isEncoding===i||!i(t)))throw new Error("Unknown encoding: "+t);return e||t}(t),this.encoding){case"utf16le":this.text=u,this.end=c,e=4;break;case"utf8":this.fillLast=s,e=4;break;case"base64":this.text=f,this.end=l,e=3;break;default:return this.write=h,void(this.end=d)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(e)}function a(t){return t<=127?0:t>>5==6?2:t>>4==14?3:t>>3==30?4:t>>6==2?-1:-2}function s(t){var e=this.lastTotal-this.lastNeed,n=function(t,e,n){if(128!=(192&e[0]))return t.lastNeed=0,"�";if(t.lastNeed>1&&e.length>1){if(128!=(192&e[1]))return t.lastNeed=1,"�";if(t.lastNeed>2&&e.length>2&&128!=(192&e[2]))return t.lastNeed=2,"�"}}(this,t);return void 0!==n?n:this.lastNeed<=t.length?(t.copy(this.lastChar,e,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(t.copy(this.lastChar,e,0,t.length),void(this.lastNeed-=t.length))}function u(t,e){if((t.length-e)%2==0){var n=t.toString("utf16le",e);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=t[t.length-1],t.toString("utf16le",e,t.length-1)}function c(t){var e=t&&t.length?this.write(t):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return e+this.lastChar.toString("utf16le",0,n)}return e}function f(t,e){var n=(t.length-e)%3;return 0===n?t.toString("base64",e):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=t[t.length-1]:(this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1]),t.toString("base64",e,t.length-n))}function l(t){var e=t&&t.length?this.write(t):"";return this.lastNeed?e+this.lastChar.toString("base64",0,3-this.lastNeed):e}function h(t){return t.toString(this.encoding)}function d(t){return t&&t.length?this.write(t):""}e.StringDecoder=o,o.prototype.write=function(t){if(0===t.length)return"";var e,n;if(this.lastNeed){if(void 0===(e=this.fillLast(t)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return i>0&&(t.lastNeed=i-1),i;if(--r=0)return i>0&&(t.lastNeed=i-2),i;if(--r=0)return i>0&&(2===i?i=0:t.lastNeed=i-3),i;return 0}(this,t,e);if(!this.lastNeed)return t.toString("utf8",e);this.lastTotal=n;var r=t.length-(n-this.lastNeed);return t.copy(this.lastChar,0,r),t.toString("utf8",e,r)},o.prototype.fillLast=function(t){if(this.lastNeed<=t.length)return t.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);t.copy(this.lastChar,this.lastTotal-this.lastNeed,0,t.length),this.lastNeed-=t.length}},function(t,e,n){"use strict";var r=n(8).Buffer,i=n(2),o=n(192),a=new Array(16),s=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],u=[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11],c=[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],f=[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11],l=[0,1518500249,1859775393,2400959708,2840853838],h=[1352829926,1548603684,1836072691,2053994217,0];function d(){o.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520}function p(t,e){return t<>>32-e}function g(t,e,n,r,i,o,a,s){return p(t+(e^n^r)+o+a|0,s)+i|0}function y(t,e,n,r,i,o,a,s){return p(t+(e&n|~e&r)+o+a|0,s)+i|0}function b(t,e,n,r,i,o,a,s){return p(t+((e|~n)^r)+o+a|0,s)+i|0}function m(t,e,n,r,i,o,a,s){return p(t+(e&r|n&~r)+o+a|0,s)+i|0}function v(t,e,n,r,i,o,a,s){return p(t+(e^(n|~r))+o+a|0,s)+i|0}i(d,o),d.prototype._update=function(){for(var t=a,e=0;e<16;++e)t[e]=this._block.readInt32LE(4*e);for(var n=0|this._a,r=0|this._b,i=0|this._c,o=0|this._d,d=0|this._e,_=0|this._a,w=0|this._b,x=0|this._c,k=0|this._d,E=0|this._e,A=0;A<80;A+=1){var S,T;A<16?(S=g(n,r,i,o,d,t[s[A]],l[0],c[A]),T=v(_,w,x,k,E,t[u[A]],h[0],f[A])):A<32?(S=y(n,r,i,o,d,t[s[A]],l[1],c[A]),T=m(_,w,x,k,E,t[u[A]],h[1],f[A])):A<48?(S=b(n,r,i,o,d,t[s[A]],l[2],c[A]),T=b(_,w,x,k,E,t[u[A]],h[2],f[A])):A<64?(S=m(n,r,i,o,d,t[s[A]],l[3],c[A]),T=y(_,w,x,k,E,t[u[A]],h[3],f[A])):(S=v(n,r,i,o,d,t[s[A]],l[4],c[A]),T=g(_,w,x,k,E,t[u[A]],h[4],f[A])),n=d,d=o,o=p(i,10),i=r,r=S,_=E,E=k,k=p(x,10),x=w,w=T}var M=this._b+i+k|0;this._b=this._c+o+E|0,this._c=this._d+d+_|0,this._d=this._e+n+w|0,this._e=this._a+r+x|0,this._a=M},d.prototype._digest=function(){this._block[this._blockOffset++]=128,this._blockOffset>56&&(this._block.fill(0,this._blockOffset,64),this._update(),this._blockOffset=0),this._block.fill(0,this._blockOffset,56),this._block.writeUInt32LE(this._length[0],56),this._block.writeUInt32LE(this._length[1],60),this._update();var t=r.alloc?r.alloc(20):new r(20);return t.writeInt32LE(this._a,0),t.writeInt32LE(this._b,4),t.writeInt32LE(this._c,8),t.writeInt32LE(this._d,12),t.writeInt32LE(this._e,16),t},t.exports=d},function(t,e,n){(e=t.exports=function(t){t=t.toLowerCase();var n=e[t];if(!n)throw new Error(t+" is not supported (we accept pull requests)");return new n}).sha=n(432),e.sha1=n(433),e.sha224=n(434),e.sha256=n(197),e.sha384=n(435),e.sha512=n(198)},function(t,e,n){"use strict";e.utils=n(441),e.Cipher=n(442),e.DES=n(443),e.CBC=n(444),e.EDE=n(445)},function(t,e,n){var r=n(446),i=n(454),o=n(208);e.createCipher=e.Cipher=r.createCipher,e.createCipheriv=e.Cipheriv=r.createCipheriv,e.createDecipher=e.Decipher=i.createDecipher,e.createDecipheriv=e.Decipheriv=i.createDecipheriv,e.listCiphers=e.getCiphers=function(){return Object.keys(o)}},function(t,e,n){var r={ECB:n(447),CBC:n(448),CFB:n(449),CFB8:n(450),CFB1:n(451),OFB:n(452),CTR:n(206),GCM:n(206)},i=n(208);for(var o in i)i[o].module=r[i[o].mode];t.exports=i},function(t,e,n){var r;function i(t){this.rand=t}if(t.exports=function(t){return r||(r=new i(null)),r.generate(t)},t.exports.Rand=i,i.prototype.generate=function(t){return this._rand(t)},i.prototype._rand=function(t){if(this.rand.getBytes)return this.rand.getBytes(t);for(var e=new Uint8Array(t),n=0;n=0||!n.umod(t.prime1)||!n.umod(t.prime2);)n=new r(i(e));return n}t.exports=o,o.getr=a}).call(this,n(8).Buffer)},function(t,e,n){"use strict";var r=e;r.version=n(463).version,r.utils=n(16),r.rand=n(123),r.curve=n(214),r.curves=n(126),r.ec=n(474),r.eddsa=n(478)},function(t,e,n){"use strict";var r,i=e,o=n(127),a=n(214),s=n(16).assert;function u(t){"short"===t.type?this.curve=new a.short(t):"edwards"===t.type?this.curve=new a.edwards(t):this.curve=new a.mont(t),this.g=this.curve.g,this.n=this.curve.n,this.hash=t.hash,s(this.g.validate(),"Invalid curve"),s(this.g.mul(this.n).isInfinity(),"Invalid curve, G*N != O")}function c(t,e){Object.defineProperty(i,t,{configurable:!0,enumerable:!0,get:function(){var n=new u(e);return Object.defineProperty(i,t,{configurable:!0,enumerable:!0,value:n}),n}})}i.PresetCurve=u,c("p192",{type:"short",prime:"p192",p:"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff",a:"ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc",b:"64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1",n:"ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831",hash:o.sha256,gRed:!1,g:["188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012","07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811"]}),c("p224",{type:"short",prime:"p224",p:"ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001",a:"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe",b:"b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4",n:"ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d",hash:o.sha256,gRed:!1,g:["b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21","bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34"]}),c("p256",{type:"short",prime:null,p:"ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff",a:"ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc",b:"5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b",n:"ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551",hash:o.sha256,gRed:!1,g:["6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296","4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5"]}),c("p384",{type:"short",prime:null,p:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ffffffff 00000000 00000000 ffffffff",a:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe ffffffff 00000000 00000000 fffffffc",b:"b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f 5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef",n:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 f4372ddf 581a0db2 48b0a77a ecec196a ccc52973",hash:o.sha384,gRed:!1,g:["aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 5502f25d bf55296c 3a545e38 72760ab7","3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 0a60b1ce 1d7e819d 7a431d7c 90ea0e5f"]}),c("p521",{type:"short",prime:null,p:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff",a:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffc",b:"00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b 99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd 3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00",n:"000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409",hash:o.sha512,gRed:!1,g:["000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66","00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 3fad0761 353c7086 a272c240 88be9476 9fd16650"]}),c("curve25519",{type:"mont",prime:"p25519",p:"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",a:"76d06",b:"1",n:"1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",hash:o.sha256,gRed:!1,g:["9"]}),c("ed25519",{type:"edwards",prime:"p25519",p:"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",a:"-1",c:"1",d:"52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3",n:"1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed",hash:o.sha256,gRed:!1,g:["216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a","6666666666666666666666666666666666666666666666666666666666666658"]});try{r=n(473)}catch(t){r=void 0}c("secp256k1",{type:"short",prime:"k256",p:"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f",a:"0",b:"7",n:"ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141",h:"1",hash:o.sha256,beta:"7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee",lambda:"5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72",basis:[{a:"3086d221a7d46bcde86c90e49284eb15",b:"-e4437ed6010e88286f547fa90abfe4c3"},{a:"114ca50f7a8e2f3f657c1108d9d44cfd8",b:"3086d221a7d46bcde86c90e49284eb15"}],gRed:!1,g:["79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",r]})},function(t,e,n){var r=e;r.utils=n(21),r.common=n(56),r.sha=n(467),r.ripemd=n(471),r.hmac=n(472),r.sha1=r.sha.sha1,r.sha256=r.sha.sha256,r.sha224=r.sha.sha224,r.sha384=r.sha.sha384,r.sha512=r.sha.sha512,r.ripemd160=r.ripemd.ripemd160},function(t,e,n){var r=n(14);t.exports=function(t,e){var n=t.append("foreignObject").attr("width","100000"),i=n.append("xhtml:div");i.attr("xmlns","http://www.w3.org/1999/xhtml");var o=e.label;switch(typeof o){case"function":i.insert(o);break;case"object":i.insert((function(){return o}));break;default:i.html(o)}r.applyStyle(i,e.labelStyle),i.style("display","inline-block"),i.style("white-space","nowrap");var a=i.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}},function(t,e){},function(t,e,n){var r=n(61),i=n(92),o=n(66),a=n(264),s=n(270),u=n(136),c=n(137),f=n(273),l=n(274),h=n(141),d=n(275),p=n(41),g=n(279),y=n(280),b=n(146),m=n(6),v=n(39),_=n(284),w=n(13),x=n(286),k=n(27),E=1,A=2,S=4,T="[object Arguments]",M="[object Function]",D="[object GeneratorFunction]",C="[object Object]",O={};O[T]=O["[object Array]"]=O["[object ArrayBuffer]"]=O["[object DataView]"]=O["[object Boolean]"]=O["[object Date]"]=O["[object Float32Array]"]=O["[object Float64Array]"]=O["[object Int8Array]"]=O["[object Int16Array]"]=O["[object Int32Array]"]=O["[object Map]"]=O["[object Number]"]=O[C]=O["[object RegExp]"]=O["[object Set]"]=O["[object String]"]=O["[object Symbol]"]=O["[object Uint8Array]"]=O["[object Uint8ClampedArray]"]=O["[object Uint16Array]"]=O["[object Uint32Array]"]=!0,O["[object Error]"]=O[M]=O["[object WeakMap]"]=!1,t.exports=function t(e,n,R,I,N,B){var L,P=n&E,F=n&A,q=n&S;if(R&&(L=N?R(e,I,N,B):R(e)),void 0!==L)return L;if(!w(e))return e;var j=m(e);if(j){if(L=g(e),!P)return c(e,L)}else{var U=p(e),z=U==M||U==D;if(v(e))return u(e,P);if(U==C||U==T||z&&!N){if(L=F||z?{}:b(e),!P)return F?l(e,s(L,e)):f(e,a(L,e))}else{if(!O[U])return N?e:{};L=y(e,U,P)}}B||(B=new r);var Y=B.get(e);if(Y)return Y;B.set(e,L),x(e)?e.forEach((function(r){L.add(t(r,n,R,r,e,B))})):_(e)&&e.forEach((function(r,i){L.set(i,t(r,n,R,i,e,B))}));var V=q?F?d:h:F?keysIn:k,H=j?void 0:V(e);return i(H||e,(function(r,i){H&&(r=e[i=r]),o(L,i,t(r,n,R,i,e,B))})),L}},function(t,e,n){(function(e){var n="object"==typeof e&&e&&e.Object===Object&&e;t.exports=n}).call(this,n(11))},function(t,e){var n=Function.prototype.toString;t.exports=function(t){if(null!=t){try{return n.call(t)}catch(t){}try{return t+""}catch(t){}}return""}},function(t,e,n){var r=n(32),i=function(){try{var t=r(Object,"defineProperty");return t({},"",{}),t}catch(t){}}();t.exports=i},function(t,e,n){var r=n(265),i=n(50),o=n(6),a=n(39),s=n(68),u=n(51),c=Object.prototype.hasOwnProperty;t.exports=function(t,e){var n=o(t),f=!n&&i(t),l=!n&&!f&&a(t),h=!n&&!f&&!l&&u(t),d=n||f||l||h,p=d?r(t.length,String):[],g=p.length;for(var y in t)!e&&!c.call(t,y)||d&&("length"==y||l&&("offset"==y||"parent"==y)||h&&("buffer"==y||"byteLength"==y||"byteOffset"==y)||s(y,g))||p.push(y);return p}},function(t,e){t.exports=function(t,e){return function(n){return t(e(n))}}},function(t,e,n){(function(t){var r=n(18),i=e&&!e.nodeType&&e,o=i&&"object"==typeof t&&t&&!t.nodeType&&t,a=o&&o.exports===i?r.Buffer:void 0,s=a?a.allocUnsafe:void 0;t.exports=function(t,e){if(e)return t.slice();var n=t.length,r=s?s(n):new t.constructor(n);return t.copy(r),r}}).call(this,n(9)(t))},function(t,e){t.exports=function(t,e){var n=-1,r=t.length;for(e||(e=Array(r));++nh))return!1;var p=f.get(t);if(p&&f.get(e))return p==e;var g=-1,y=!0,b=n&s?new r:void 0;for(f.set(t,e),f.set(e,t);++g0&&(o=u.removeMin(),(a=s[o]).distance!==Number.POSITIVE_INFINITY);)r(o).forEach(c);return s}(t,String(e),n||o,r||function(e){return t.outEdges(e)})};var o=r.constant(1)},function(t,e,n){var r=n(12);function i(){this._arr=[],this._keyIndices={}}t.exports=i,i.prototype.size=function(){return this._arr.length},i.prototype.keys=function(){return this._arr.map((function(t){return t.key}))},i.prototype.has=function(t){return r.has(this._keyIndices,t)},i.prototype.priority=function(t){var e=this._keyIndices[t];if(void 0!==e)return this._arr[e].priority},i.prototype.min=function(){if(0===this.size())throw new Error("Queue underflow");return this._arr[0].key},i.prototype.add=function(t,e){var n=this._keyIndices;if(t=String(t),!r.has(n,t)){var i=this._arr,o=i.length;return n[t]=o,i.push({key:t,priority:e}),this._decrease(o),!0}return!1},i.prototype.removeMin=function(){this._swap(0,this._arr.length-1);var t=this._arr.pop();return delete this._keyIndices[t.key],this._heapify(0),t.key},i.prototype.decrease=function(t,e){var n=this._keyIndices[t];if(e>this._arr[n].priority)throw new Error("New priority is greater than current priority. Key: "+t+" Old: "+this._arr[n].priority+" New: "+e);this._arr[n].priority=e,this._decrease(n)},i.prototype._heapify=function(t){var e=this._arr,n=2*t,r=n+1,i=t;n>1].priority2?e[2]:void 0;for(c&&o(e[0],e[1],c)&&(r=1);++n1&&a.sort((function(t,e){var r=t.x-n.x,i=t.y-n.y,o=Math.sqrt(r*r+i*i),a=e.x-n.x,s=e.y-n.y,u=Math.sqrt(a*a+s*s);return oMath.abs(a)*c?(s<0&&(c=-c),n=0===s?0:c*a/s,r=c):(a<0&&(u=-u),n=u,r=0===a?0:u*s/a);return{x:i+n,y:o+r}}},function(t,e){var n={}.toString;t.exports=Array.isArray||function(t){return"[object Array]"==n.call(t)}},function(t,e,n){"use strict";var r=n(3).Buffer,i=n(112).Transform;function o(t){i.call(this),this._block=r.allocUnsafe(t),this._blockSize=t,this._blockOffset=0,this._length=[0,0,0,0],this._finalized=!1}n(2)(o,i),o.prototype._transform=function(t,e,n){var r=null;try{this.update(t,e)}catch(t){r=t}n(r)},o.prototype._flush=function(t){var e=null;try{this.push(this.digest())}catch(t){e=t}t(e)},o.prototype.update=function(t,e){if(function(t,e){if(!r.isBuffer(t)&&"string"!=typeof t)throw new TypeError(e+" must be a string or a buffer")}(t,"Data"),this._finalized)throw new Error("Digest already called");r.isBuffer(t)||(t=r.from(t,e));for(var n=this._block,i=0;this._blockOffset+t.length-i>=this._blockSize;){for(var o=this._blockOffset;o0;++a)this._length[a]+=s,(s=this._length[a]/4294967296|0)>0&&(this._length[a]-=4294967296*s);return this},o.prototype._update=function(){throw new Error("_update is not implemented")},o.prototype.digest=function(t){if(this._finalized)throw new Error("Digest already called");this._finalized=!0;var e=this._digest();void 0!==t&&(e=e.toString(t)),this._block.fill(0),this._blockOffset=0;for(var n=0;n<4;++n)this._length[n]=0;return e},o.prototype._digest=function(){throw new Error("_digest is not implemented")},t.exports=o},function(t,e,n){"use strict";(function(e,r){var i=n(78);t.exports=v;var o,a=n(191);v.ReadableState=m;n(113).EventEmitter;var s=function(t,e){return t.listeners(e).length},u=n(194),c=n(115).Buffer,f=e.Uint8Array||function(){};var l=n(54);l.inherits=n(2);var h=n(421),d=void 0;d=h&&h.debuglog?h.debuglog("stream"):function(){};var p,g=n(422),y=n(195);l.inherits(v,u);var b=["error","close","destroy","pause","resume"];function m(t,e){t=t||{};var r=e instanceof(o=o||n(35));this.objectMode=!!t.objectMode,r&&(this.objectMode=this.objectMode||!!t.readableObjectMode);var i=t.highWaterMark,a=t.readableHighWaterMark,s=this.objectMode?16:16384;this.highWaterMark=i||0===i?i:r&&(a||0===a)?a:s,this.highWaterMark=Math.floor(this.highWaterMark),this.buffer=new g,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.destroyed=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(p||(p=n(117).StringDecoder),this.decoder=new p(t.encoding),this.encoding=t.encoding)}function v(t){if(o=o||n(35),!(this instanceof v))return new v(t);this._readableState=new m(t,this),this.readable=!0,t&&("function"==typeof t.read&&(this._read=t.read),"function"==typeof t.destroy&&(this._destroy=t.destroy)),u.call(this)}function _(t,e,n,r,i){var o,a=t._readableState;null===e?(a.reading=!1,function(t,e){if(e.ended)return;if(e.decoder){var n=e.decoder.end();n&&n.length&&(e.buffer.push(n),e.length+=e.objectMode?1:n.length)}e.ended=!0,E(t)}(t,a)):(i||(o=function(t,e){var n;r=e,c.isBuffer(r)||r instanceof f||"string"==typeof e||void 0===e||t.objectMode||(n=new TypeError("Invalid non-string/buffer chunk"));var r;return n}(a,e)),o?t.emit("error",o):a.objectMode||e&&e.length>0?("string"==typeof e||a.objectMode||Object.getPrototypeOf(e)===c.prototype||(e=function(t){return c.from(t)}(e)),r?a.endEmitted?t.emit("error",new Error("stream.unshift() after end event")):w(t,a,e,!0):a.ended?t.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(e=a.decoder.write(e),a.objectMode||0!==e.length?w(t,a,e,!1):S(t,a)):w(t,a,e,!1))):r||(a.reading=!1));return function(t){return!t.ended&&(t.needReadable||t.lengthe.highWaterMark&&(e.highWaterMark=function(t){return t>=x?t=x:(t--,t|=t>>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,t|=t>>>16,t++),t}(t)),t<=e.length?t:e.ended?e.length:(e.needReadable=!0,0))}function E(t){var e=t._readableState;e.needReadable=!1,e.emittedReadable||(d("emitReadable",e.flowing),e.emittedReadable=!0,e.sync?i.nextTick(A,t):A(t))}function A(t){d("emit readable"),t.emit("readable"),C(t)}function S(t,e){e.readingMore||(e.readingMore=!0,i.nextTick(T,t,e))}function T(t,e){for(var n=e.length;!e.reading&&!e.flowing&&!e.ended&&e.length=e.length?(n=e.decoder?e.buffer.join(""):1===e.buffer.length?e.buffer.head.data:e.buffer.concat(e.length),e.buffer.clear()):n=function(t,e,n){var r;to.length?o.length:t;if(a===o.length?i+=o:i+=o.slice(0,t),0===(t-=a)){a===o.length?(++r,n.next?e.head=n.next:e.head=e.tail=null):(e.head=n,n.data=o.slice(a));break}++r}return e.length-=r,i}(t,e):function(t,e){var n=c.allocUnsafe(t),r=e.head,i=1;r.data.copy(n),t-=r.data.length;for(;r=r.next;){var o=r.data,a=t>o.length?o.length:t;if(o.copy(n,n.length-t,0,a),0===(t-=a)){a===o.length?(++i,r.next?e.head=r.next:e.head=e.tail=null):(e.head=r,r.data=o.slice(a));break}++i}return e.length-=i,n}(t,e);return r}(t,e.buffer,e.decoder),n);var n}function R(t){var e=t._readableState;if(e.length>0)throw new Error('"endReadable()" called on non-empty stream');e.endEmitted||(e.ended=!0,i.nextTick(I,e,t))}function I(t,e){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))}function N(t,e){for(var n=0,r=t.length;n=e.highWaterMark||e.ended))return d("read: emitReadable",e.length,e.ended),0===e.length&&e.ended?R(this):E(this),null;if(0===(t=k(t,e))&&e.ended)return 0===e.length&&R(this),null;var r,i=e.needReadable;return d("need readable",i),(0===e.length||e.length-t0?O(t,e):null)?(e.needReadable=!0,t=0):e.length-=t,0===e.length&&(e.ended||(e.needReadable=!0),n!==t&&e.ended&&R(this)),null!==r&&this.emit("data",r),r},v.prototype._read=function(t){this.emit("error",new Error("_read() is not implemented"))},v.prototype.pipe=function(t,e){var n=this,o=this._readableState;switch(o.pipesCount){case 0:o.pipes=t;break;case 1:o.pipes=[o.pipes,t];break;default:o.pipes.push(t)}o.pipesCount+=1,d("pipe count=%d opts=%j",o.pipesCount,e);var u=(!e||!1!==e.end)&&t!==r.stdout&&t!==r.stderr?f:v;function c(e,r){d("onunpipe"),e===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,d("cleanup"),t.removeListener("close",b),t.removeListener("finish",m),t.removeListener("drain",l),t.removeListener("error",y),t.removeListener("unpipe",c),n.removeListener("end",f),n.removeListener("end",v),n.removeListener("data",g),h=!0,!o.awaitDrain||t._writableState&&!t._writableState.needDrain||l())}function f(){d("onend"),t.end()}o.endEmitted?i.nextTick(u):n.once("end",u),t.on("unpipe",c);var l=function(t){return function(){var e=t._readableState;d("pipeOnDrain",e.awaitDrain),e.awaitDrain&&e.awaitDrain--,0===e.awaitDrain&&s(t,"data")&&(e.flowing=!0,C(t))}}(n);t.on("drain",l);var h=!1;var p=!1;function g(e){d("ondata"),p=!1,!1!==t.write(e)||p||((1===o.pipesCount&&o.pipes===t||o.pipesCount>1&&-1!==N(o.pipes,t))&&!h&&(d("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,p=!0),n.pause())}function y(e){d("onerror",e),v(),t.removeListener("error",y),0===s(t,"error")&&t.emit("error",e)}function b(){t.removeListener("finish",m),v()}function m(){d("onfinish"),t.removeListener("close",b),v()}function v(){d("unpipe"),n.unpipe(t)}return n.on("data",g),function(t,e,n){if("function"==typeof t.prependListener)return t.prependListener(e,n);t._events&&t._events[e]?a(t._events[e])?t._events[e].unshift(n):t._events[e]=[n,t._events[e]]:t.on(e,n)}(t,"error",y),t.once("close",b),t.once("finish",m),t.emit("pipe",n),o.flowing||(d("pipe resume"),n.resume()),t},v.prototype.unpipe=function(t){var e=this._readableState,n={hasUnpiped:!1};if(0===e.pipesCount)return this;if(1===e.pipesCount)return t&&t!==e.pipes?this:(t||(t=e.pipes),e.pipes=null,e.pipesCount=0,e.flowing=!1,t&&t.emit("unpipe",this,n),this);if(!t){var r=e.pipes,i=e.pipesCount;e.pipes=null,e.pipesCount=0,e.flowing=!1;for(var o=0;o>>2|t<<30)^(t>>>13|t<<19)^(t>>>22|t<<10)}function h(t){return(t>>>6|t<<26)^(t>>>11|t<<21)^(t>>>25|t<<7)}function d(t){return(t>>>7|t<<25)^(t>>>18|t<<14)^t>>>3}r(u,i),u.prototype.init=function(){return this._a=1779033703,this._b=3144134277,this._c=1013904242,this._d=2773480762,this._e=1359893119,this._f=2600822924,this._g=528734635,this._h=1541459225,this},u.prototype._update=function(t){for(var e,n=this._w,r=0|this._a,i=0|this._b,o=0|this._c,s=0|this._d,u=0|this._e,p=0|this._f,g=0|this._g,y=0|this._h,b=0;b<16;++b)n[b]=t.readInt32BE(4*b);for(;b<64;++b)n[b]=0|(((e=n[b-2])>>>17|e<<15)^(e>>>19|e<<13)^e>>>10)+n[b-7]+d(n[b-15])+n[b-16];for(var m=0;m<64;++m){var v=y+h(u)+c(u,p,g)+a[m]+n[m]|0,_=l(r)+f(r,i,o)|0;y=g,g=p,p=u,u=s+v|0,s=o,o=i,i=r,r=v+_|0}this._a=r+this._a|0,this._b=i+this._b|0,this._c=o+this._c|0,this._d=s+this._d|0,this._e=u+this._e|0,this._f=p+this._f|0,this._g=g+this._g|0,this._h=y+this._h|0},u.prototype._hash=function(){var t=o.allocUnsafe(32);return t.writeInt32BE(this._a,0),t.writeInt32BE(this._b,4),t.writeInt32BE(this._c,8),t.writeInt32BE(this._d,12),t.writeInt32BE(this._e,16),t.writeInt32BE(this._f,20),t.writeInt32BE(this._g,24),t.writeInt32BE(this._h,28),t},t.exports=u},function(t,e,n){var r=n(2),i=n(45),o=n(3).Buffer,a=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591],s=new Array(160);function u(){this.init(),this._w=s,i.call(this,128,112)}function c(t,e,n){return n^t&(e^n)}function f(t,e,n){return t&e|n&(t|e)}function l(t,e){return(t>>>28|e<<4)^(e>>>2|t<<30)^(e>>>7|t<<25)}function h(t,e){return(t>>>14|e<<18)^(t>>>18|e<<14)^(e>>>9|t<<23)}function d(t,e){return(t>>>1|e<<31)^(t>>>8|e<<24)^t>>>7}function p(t,e){return(t>>>1|e<<31)^(t>>>8|e<<24)^(t>>>7|e<<25)}function g(t,e){return(t>>>19|e<<13)^(e>>>29|t<<3)^t>>>6}function y(t,e){return(t>>>19|e<<13)^(e>>>29|t<<3)^(t>>>6|e<<26)}function b(t,e){return t>>>0>>0?1:0}r(u,i),u.prototype.init=function(){return this._ah=1779033703,this._bh=3144134277,this._ch=1013904242,this._dh=2773480762,this._eh=1359893119,this._fh=2600822924,this._gh=528734635,this._hh=1541459225,this._al=4089235720,this._bl=2227873595,this._cl=4271175723,this._dl=1595750129,this._el=2917565137,this._fl=725511199,this._gl=4215389547,this._hl=327033209,this},u.prototype._update=function(t){for(var e=this._w,n=0|this._ah,r=0|this._bh,i=0|this._ch,o=0|this._dh,s=0|this._eh,u=0|this._fh,m=0|this._gh,v=0|this._hh,_=0|this._al,w=0|this._bl,x=0|this._cl,k=0|this._dl,E=0|this._el,A=0|this._fl,S=0|this._gl,T=0|this._hl,M=0;M<32;M+=2)e[M]=t.readInt32BE(4*M),e[M+1]=t.readInt32BE(4*M+4);for(;M<160;M+=2){var D=e[M-30],C=e[M-30+1],O=d(D,C),R=p(C,D),I=g(D=e[M-4],C=e[M-4+1]),N=y(C,D),B=e[M-14],L=e[M-14+1],P=e[M-32],F=e[M-32+1],q=R+L|0,j=O+B+b(q,R)|0;j=(j=j+I+b(q=q+N|0,N)|0)+P+b(q=q+F|0,F)|0,e[M]=j,e[M+1]=q}for(var U=0;U<160;U+=2){j=e[U],q=e[U+1];var z=f(n,r,i),Y=f(_,w,x),V=l(n,_),H=l(_,n),$=h(s,E),G=h(E,s),W=a[U],K=a[U+1],X=c(s,u,m),Z=c(E,A,S),J=T+G|0,Q=v+$+b(J,T)|0;Q=(Q=(Q=Q+X+b(J=J+Z|0,Z)|0)+W+b(J=J+K|0,K)|0)+j+b(J=J+q|0,q)|0;var tt=H+Y|0,et=V+z+b(tt,H)|0;v=m,T=S,m=u,S=A,u=s,A=E,s=o+Q+b(E=k+J|0,k)|0,o=i,k=x,i=r,x=w,r=n,w=_,n=Q+et+b(_=J+tt|0,J)|0}this._al=this._al+_|0,this._bl=this._bl+w|0,this._cl=this._cl+x|0,this._dl=this._dl+k|0,this._el=this._el+E|0,this._fl=this._fl+A|0,this._gl=this._gl+S|0,this._hl=this._hl+T|0,this._ah=this._ah+n+b(this._al,_)|0,this._bh=this._bh+r+b(this._bl,w)|0,this._ch=this._ch+i+b(this._cl,x)|0,this._dh=this._dh+o+b(this._dl,k)|0,this._eh=this._eh+s+b(this._el,E)|0,this._fh=this._fh+u+b(this._fl,A)|0,this._gh=this._gh+m+b(this._gl,S)|0,this._hh=this._hh+v+b(this._hl,T)|0},u.prototype._hash=function(){var t=o.allocUnsafe(64);function e(e,n,r){t.writeInt32BE(e,r),t.writeInt32BE(n,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),e(this._gh,this._gl,48),e(this._hh,this._hl,56),t},t.exports=u},function(t,e,n){"use strict";var r=n(2),i=n(436),o=n(31),a=n(3).Buffer,s=n(200),u=n(118),c=n(119),f=a.alloc(128);function l(t,e){o.call(this,"digest"),"string"==typeof e&&(e=a.from(e));var n="sha512"===t||"sha384"===t?128:64;(this._alg=t,this._key=e,e.length>n)?e=("rmd160"===t?new u:c(t)).update(e).digest():e.lengthn||o!=o)throw new TypeError("Bad key length")}}).call(this,n(8).Buffer)},function(t,e,n){(function(e){var n;e.browser?n="utf-8":n=parseInt(e.version.split(".")[0].slice(1),10)>=6?"utf-8":"binary";t.exports=n}).call(this,n(7))},function(t,e,n){var r=n(200),i=n(118),o=n(119),a=n(203),s=n(204),u=n(3).Buffer,c=u.alloc(128),f={md5:16,sha1:20,sha224:28,sha256:32,sha384:48,sha512:64,rmd160:20,ripemd160:20};function l(t,e,n){var a=function(t){return"rmd160"===t||"ripemd160"===t?function(t){return(new i).update(t).digest()}:"md5"===t?r:function(e){return o(t).update(e).digest()}}(t),s="sha512"===t||"sha384"===t?128:64;e.length>s?e=a(e):e.lengtht;)n.ishrn(1);if(n.isEven()&&n.iadd(s),n.testn(1)||n.iadd(u),e.cmp(u)){if(!e.cmp(c))for(;n.mod(f).cmp(l);)n.iadd(d)}else for(;n.mod(o).cmp(h);)n.iadd(d);if(y(p=n.shrn(1))&&y(n)&&b(p)&&b(n)&&a.test(p)&&a.test(n))return n}}},function(t,e,n){var r=n(5),i=n(123);function o(t){this.rand=t||new i.Rand}t.exports=o,o.create=function(t){return new o(t)},o.prototype._randbelow=function(t){var e=t.bitLength(),n=Math.ceil(e/8);do{var i=new r(this.rand.generate(n))}while(i.cmp(t)>=0);return i},o.prototype._randrange=function(t,e){var n=e.sub(t);return t.add(this._randbelow(n))},o.prototype.test=function(t,e,n){var i=t.bitLength(),o=r.mont(t),a=new r(1).toRed(o);e||(e=Math.max(1,i/48|0));for(var s=t.subn(1),u=0;!s.testn(u);u++);for(var c=t.shrn(u),f=s.toRed(o);e>0;e--){var l=this._randrange(new r(2),s);n&&n(l);var h=l.toRed(o).redPow(c);if(0!==h.cmp(a)&&0!==h.cmp(f)){for(var d=1;d0;e--){var f=this._randrange(new r(2),a),l=t.gcd(f);if(0!==l.cmpn(1))return l;var h=f.toRed(i).redPow(u);if(0!==h.cmp(o)&&0!==h.cmp(c)){for(var d=1;d>8,a=255&i;o?n.push(o,a):n.push(a)}return n},r.zero2=i,r.toHex=o,r.encode=function(t,e){return"hex"===e?o(t):t}},function(t,e,n){"use strict";var r=e;r.base=n(81),r.short=n(464),r.mont=n(465),r.edwards=n(466)},function(t,e,n){"use strict";var r=n(21).rotr32;function i(t,e,n){return t&e^~t&n}function o(t,e,n){return t&e^t&n^e&n}function a(t,e,n){return t^e^n}e.ft_1=function(t,e,n,r){return 0===t?i(e,n,r):1===t||3===t?a(e,n,r):2===t?o(e,n,r):void 0},e.ch32=i,e.maj32=o,e.p32=a,e.s0_256=function(t){return r(t,2)^r(t,13)^r(t,22)},e.s1_256=function(t){return r(t,6)^r(t,11)^r(t,25)},e.g0_256=function(t){return r(t,7)^r(t,18)^t>>>3},e.g1_256=function(t){return r(t,17)^r(t,19)^t>>>10}},function(t,e,n){"use strict";var r=n(21),i=n(56),o=n(215),a=n(15),s=r.sum32,u=r.sum32_4,c=r.sum32_5,f=o.ch32,l=o.maj32,h=o.s0_256,d=o.s1_256,p=o.g0_256,g=o.g1_256,y=i.BlockHash,b=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function m(){if(!(this instanceof m))return new m;y.call(this),this.h=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],this.k=b,this.W=new Array(64)}r.inherits(m,y),t.exports=m,m.blockSize=512,m.outSize=256,m.hmacStrength=192,m.padLength=64,m.prototype._update=function(t,e){for(var n=this.W,r=0;r<16;r++)n[r]=t[e+r];for(;r>6],i=0==(32&n);if(31==(31&n)){var o=n;for(n=0;128==(128&o);){if(o=t.readUInt8(e),t.isError(o))return o;n<<=7,n|=127&o}}else n&=31;return{cls:r,primitive:i,tag:n,tagStr:s.tag[n]}}function l(t,e,n){var r=t.readUInt8(n);if(t.isError(r))return r;if(!e&&128===r)return null;if(0==(128&r))return r;var i=127&r;if(i>4)return t.error("length octect is too long");r=0;for(var o=0;o=31)return r.error("Multi-octet tag encoding unsupported");e||(i|=32);return i|=s.tagClassByName[n||"universal"]<<6}(t,e,n,this.reporter);if(r.length<128)return(o=new i(2))[0]=a,o[1]=r.length,this._createEncoderBuffer([o,r]);for(var u=1,c=r.length;c>=256;c>>=8)u++;(o=new i(2+u))[0]=a,o[1]=128|u;c=1+u;for(var f=r.length;f>0;c--,f>>=8)o[c]=255&f;return this._createEncoderBuffer([o,r])},c.prototype._encodeStr=function(t,e){if("bitstr"===e)return this._createEncoderBuffer([0|t.unused,t.data]);if("bmpstr"===e){for(var n=new i(2*t.length),r=0;r=40)return this.reporter.error("Second objid identifier OOB");t.splice(0,2,40*t[0]+t[1])}var o=0;for(r=0;r=128;a>>=7)o++}var s=new i(o),u=s.length-1;for(r=t.length-1;r>=0;r--){a=t[r];for(s[u--]=127&a;(a>>=7)>0;)s[u--]=128|127&a}return this._createEncoderBuffer(s)},c.prototype._encodeTime=function(t,e){var n,r=new Date(t);return"gentime"===e?n=[f(r.getFullYear()),f(r.getUTCMonth()+1),f(r.getUTCDate()),f(r.getUTCHours()),f(r.getUTCMinutes()),f(r.getUTCSeconds()),"Z"].join(""):"utctime"===e?n=[f(r.getFullYear()%100),f(r.getUTCMonth()+1),f(r.getUTCDate()),f(r.getUTCHours()),f(r.getUTCMinutes()),f(r.getUTCSeconds()),"Z"].join(""):this.reporter.error("Encoding "+e+" time is not supported yet"),this._encodeStr(n,"octstr")},c.prototype._encodeNull=function(){return this._createEncoderBuffer("")},c.prototype._encodeInt=function(t,e){if("string"==typeof t){if(!e)return this.reporter.error("String int or enum given, but no values map");if(!e.hasOwnProperty(t))return this.reporter.error("Values map doesn't contain: "+JSON.stringify(t));t=e[t]}if("number"!=typeof t&&!i.isBuffer(t)){var n=t.toArray();!t.sign&&128&n[0]&&n.unshift(0),t=new i(n)}if(i.isBuffer(t)){var r=t.length;0===t.length&&r++;var o=new i(r);return t.copy(o),0===t.length&&(o[0]=0),this._createEncoderBuffer(o)}if(t<128)return this._createEncoderBuffer(t);if(t<256)return this._createEncoderBuffer([0,t]);r=1;for(var a=t;a>=256;a>>=8)r++;for(a=(o=new Array(r)).length-1;a>=0;a--)o[a]=255&t,t>>=8;return 128&o[0]&&o.unshift(0),this._createEncoderBuffer(new i(o))},c.prototype._encodeBool=function(t){return this._createEncoderBuffer(t?255:0)},c.prototype._use=function(t,e){return"function"==typeof t&&(t=t(e)),t._getEncoder("der").tree},c.prototype._skipDefault=function(t,e,n){var r,i=this._baseState;if(null===i.default)return!1;var o=t.join();if(void 0===i.defaultBuffer&&(i.defaultBuffer=this._encodeValue(i.default,e,n).join()),o.length!==i.defaultBuffer.length)return!1;for(r=0;r\u20D2|\u205F\u200A|\u219D\u0338|\u2202\u0338|\u2220\u20D2|\u2229\uFE00|\u222A\uFE00|\u223C\u20D2|\u223D\u0331|\u223E\u0333|\u2242\u0338|\u224B\u0338|\u224D\u20D2|\u224E\u0338|\u224F\u0338|\u2250\u0338|\u2261\u20E5|\u2264\u20D2|\u2265\u20D2|\u2266\u0338|\u2267\u0338|\u2268\uFE00|\u2269\uFE00|\u226A\u0338|\u226A\u20D2|\u226B\u0338|\u226B\u20D2|\u227F\u0338|\u2282\u20D2|\u2283\u20D2|\u228A\uFE00|\u228B\uFE00|\u228F\u0338|\u2290\u0338|\u2293\uFE00|\u2294\uFE00|\u22B4\u20D2|\u22B5\u20D2|\u22D8\u0338|\u22D9\u0338|\u22DA\uFE00|\u22DB\uFE00|\u22F5\u0338|\u22F9\u0338|\u2933\u0338|\u29CF\u0338|\u29D0\u0338|\u2A6D\u0338|\u2A70\u0338|\u2A7D\u0338|\u2A7E\u0338|\u2AA1\u0338|\u2AA2\u0338|\u2AAC\uFE00|\u2AAD\uFE00|\u2AAF\u0338|\u2AB0\u0338|\u2AC5\u0338|\u2AC6\u0338|\u2ACB\uFE00|\u2ACC\uFE00|\u2AFD\u20E5|[\xA0-\u0113\u0116-\u0122\u0124-\u012B\u012E-\u014D\u0150-\u017E\u0192\u01B5\u01F5\u0237\u02C6\u02C7\u02D8-\u02DD\u0311\u0391-\u03A1\u03A3-\u03A9\u03B1-\u03C9\u03D1\u03D2\u03D5\u03D6\u03DC\u03DD\u03F0\u03F1\u03F5\u03F6\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E\u045F\u2002-\u2005\u2007-\u2010\u2013-\u2016\u2018-\u201A\u201C-\u201E\u2020-\u2022\u2025\u2026\u2030-\u2035\u2039\u203A\u203E\u2041\u2043\u2044\u204F\u2057\u205F-\u2063\u20AC\u20DB\u20DC\u2102\u2105\u210A-\u2113\u2115-\u211E\u2122\u2124\u2127-\u2129\u212C\u212D\u212F-\u2131\u2133-\u2138\u2145-\u2148\u2153-\u215E\u2190-\u219B\u219D-\u21A7\u21A9-\u21AE\u21B0-\u21B3\u21B5-\u21B7\u21BA-\u21DB\u21DD\u21E4\u21E5\u21F5\u21FD-\u2205\u2207-\u2209\u220B\u220C\u220F-\u2214\u2216-\u2218\u221A\u221D-\u2238\u223A-\u2257\u2259\u225A\u225C\u225F-\u2262\u2264-\u228B\u228D-\u229B\u229D-\u22A5\u22A7-\u22B0\u22B2-\u22BB\u22BD-\u22DB\u22DE-\u22E3\u22E6-\u22F7\u22F9-\u22FE\u2305\u2306\u2308-\u2310\u2312\u2313\u2315\u2316\u231C-\u231F\u2322\u2323\u232D\u232E\u2336\u233D\u233F\u237C\u23B0\u23B1\u23B4-\u23B6\u23DC-\u23DF\u23E2\u23E7\u2423\u24C8\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2550-\u256C\u2580\u2584\u2588\u2591-\u2593\u25A1\u25AA\u25AB\u25AD\u25AE\u25B1\u25B3-\u25B5\u25B8\u25B9\u25BD-\u25BF\u25C2\u25C3\u25CA\u25CB\u25EC\u25EF\u25F8-\u25FC\u2605\u2606\u260E\u2640\u2642\u2660\u2663\u2665\u2666\u266A\u266D-\u266F\u2713\u2717\u2720\u2736\u2758\u2772\u2773\u27C8\u27C9\u27E6-\u27ED\u27F5-\u27FA\u27FC\u27FF\u2902-\u2905\u290C-\u2913\u2916\u2919-\u2920\u2923-\u292A\u2933\u2935-\u2939\u293C\u293D\u2945\u2948-\u294B\u294E-\u2976\u2978\u2979\u297B-\u297F\u2985\u2986\u298B-\u2996\u299A\u299C\u299D\u29A4-\u29B7\u29B9\u29BB\u29BC\u29BE-\u29C5\u29C9\u29CD-\u29D0\u29DC-\u29DE\u29E3-\u29E5\u29EB\u29F4\u29F6\u2A00-\u2A02\u2A04\u2A06\u2A0C\u2A0D\u2A10-\u2A17\u2A22-\u2A27\u2A29\u2A2A\u2A2D-\u2A31\u2A33-\u2A3C\u2A3F\u2A40\u2A42-\u2A4D\u2A50\u2A53-\u2A58\u2A5A-\u2A5D\u2A5F\u2A66\u2A6A\u2A6D-\u2A75\u2A77-\u2A9A\u2A9D-\u2AA2\u2AA4-\u2AB0\u2AB3-\u2AC8\u2ACB\u2ACC\u2ACF-\u2ADB\u2AE4\u2AE6-\u2AE9\u2AEB-\u2AF3\u2AFD\uFB00-\uFB04]|\uD835[\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDD6B]/g,l={"­":"shy","‌":"zwnj","‍":"zwj","‎":"lrm","⁣":"ic","⁢":"it","⁡":"af","‏":"rlm","​":"ZeroWidthSpace","⁠":"NoBreak","̑":"DownBreve","⃛":"tdot","⃜":"DotDot","\t":"Tab","\n":"NewLine"," ":"puncsp"," ":"MediumSpace"," ":"thinsp"," ":"hairsp"," ":"emsp13"," ":"ensp"," ":"emsp14"," ":"emsp"," ":"numsp"," ":"nbsp","  ":"ThickSpace","‾":"oline",_:"lowbar","‐":"dash","–":"ndash","—":"mdash","―":"horbar",",":"comma",";":"semi","⁏":"bsemi",":":"colon","⩴":"Colone","!":"excl","¡":"iexcl","?":"quest","¿":"iquest",".":"period","‥":"nldr","…":"mldr","·":"middot","'":"apos","‘":"lsquo","’":"rsquo","‚":"sbquo","‹":"lsaquo","›":"rsaquo",'"':"quot","“":"ldquo","”":"rdquo","„":"bdquo","«":"laquo","»":"raquo","(":"lpar",")":"rpar","[":"lsqb","]":"rsqb","{":"lcub","}":"rcub","⌈":"lceil","⌉":"rceil","⌊":"lfloor","⌋":"rfloor","⦅":"lopar","⦆":"ropar","⦋":"lbrke","⦌":"rbrke","⦍":"lbrkslu","⦎":"rbrksld","⦏":"lbrksld","⦐":"rbrkslu","⦑":"langd","⦒":"rangd","⦓":"lparlt","⦔":"rpargt","⦕":"gtlPar","⦖":"ltrPar","⟦":"lobrk","⟧":"robrk","⟨":"lang","⟩":"rang","⟪":"Lang","⟫":"Rang","⟬":"loang","⟭":"roang","❲":"lbbrk","❳":"rbbrk","‖":"Vert","§":"sect","¶":"para","@":"commat","*":"ast","/":"sol",undefined:null,"&":"amp","#":"num","%":"percnt","‰":"permil","‱":"pertenk","†":"dagger","‡":"Dagger","•":"bull","⁃":"hybull","′":"prime","″":"Prime","‴":"tprime","⁗":"qprime","‵":"bprime","⁁":"caret","`":"grave","´":"acute","˜":"tilde","^":"Hat","¯":"macr","˘":"breve","˙":"dot","¨":"die","˚":"ring","˝":"dblac","¸":"cedil","˛":"ogon","ˆ":"circ","ˇ":"caron","°":"deg","©":"copy","®":"reg","℗":"copysr","℘":"wp","℞":"rx","℧":"mho","℩":"iiota","←":"larr","↚":"nlarr","→":"rarr","↛":"nrarr","↑":"uarr","↓":"darr","↔":"harr","↮":"nharr","↕":"varr","↖":"nwarr","↗":"nearr","↘":"searr","↙":"swarr","↝":"rarrw","↝̸":"nrarrw","↞":"Larr","↟":"Uarr","↠":"Rarr","↡":"Darr","↢":"larrtl","↣":"rarrtl","↤":"mapstoleft","↥":"mapstoup","↦":"map","↧":"mapstodown","↩":"larrhk","↪":"rarrhk","↫":"larrlp","↬":"rarrlp","↭":"harrw","↰":"lsh","↱":"rsh","↲":"ldsh","↳":"rdsh","↵":"crarr","↶":"cularr","↷":"curarr","↺":"olarr","↻":"orarr","↼":"lharu","↽":"lhard","↾":"uharr","↿":"uharl","⇀":"rharu","⇁":"rhard","⇂":"dharr","⇃":"dharl","⇄":"rlarr","⇅":"udarr","⇆":"lrarr","⇇":"llarr","⇈":"uuarr","⇉":"rrarr","⇊":"ddarr","⇋":"lrhar","⇌":"rlhar","⇐":"lArr","⇍":"nlArr","⇑":"uArr","⇒":"rArr","⇏":"nrArr","⇓":"dArr","⇔":"iff","⇎":"nhArr","⇕":"vArr","⇖":"nwArr","⇗":"neArr","⇘":"seArr","⇙":"swArr","⇚":"lAarr","⇛":"rAarr","⇝":"zigrarr","⇤":"larrb","⇥":"rarrb","⇵":"duarr","⇽":"loarr","⇾":"roarr","⇿":"hoarr","∀":"forall","∁":"comp","∂":"part","∂̸":"npart","∃":"exist","∄":"nexist","∅":"empty","∇":"Del","∈":"in","∉":"notin","∋":"ni","∌":"notni","϶":"bepsi","∏":"prod","∐":"coprod","∑":"sum","+":"plus","±":"pm","÷":"div","×":"times","<":"lt","≮":"nlt","<⃒":"nvlt","=":"equals","≠":"ne","=⃥":"bne","⩵":"Equal",">":"gt","≯":"ngt",">⃒":"nvgt","¬":"not","|":"vert","¦":"brvbar","−":"minus","∓":"mp","∔":"plusdo","⁄":"frasl","∖":"setmn","∗":"lowast","∘":"compfn","√":"Sqrt","∝":"prop","∞":"infin","∟":"angrt","∠":"ang","∠⃒":"nang","∡":"angmsd","∢":"angsph","∣":"mid","∤":"nmid","∥":"par","∦":"npar","∧":"and","∨":"or","∩":"cap","∩︀":"caps","∪":"cup","∪︀":"cups","∫":"int","∬":"Int","∭":"tint","⨌":"qint","∮":"oint","∯":"Conint","∰":"Cconint","∱":"cwint","∲":"cwconint","∳":"awconint","∴":"there4","∵":"becaus","∶":"ratio","∷":"Colon","∸":"minusd","∺":"mDDot","∻":"homtht","∼":"sim","≁":"nsim","∼⃒":"nvsim","∽":"bsim","∽̱":"race","∾":"ac","∾̳":"acE","∿":"acd","≀":"wr","≂":"esim","≂̸":"nesim","≃":"sime","≄":"nsime","≅":"cong","≇":"ncong","≆":"simne","≈":"ap","≉":"nap","≊":"ape","≋":"apid","≋̸":"napid","≌":"bcong","≍":"CupCap","≭":"NotCupCap","≍⃒":"nvap","≎":"bump","≎̸":"nbump","≏":"bumpe","≏̸":"nbumpe","≐":"doteq","≐̸":"nedot","≑":"eDot","≒":"efDot","≓":"erDot","≔":"colone","≕":"ecolon","≖":"ecir","≗":"cire","≙":"wedgeq","≚":"veeeq","≜":"trie","≟":"equest","≡":"equiv","≢":"nequiv","≡⃥":"bnequiv","≤":"le","≰":"nle","≤⃒":"nvle","≥":"ge","≱":"nge","≥⃒":"nvge","≦":"lE","≦̸":"nlE","≧":"gE","≧̸":"ngE","≨︀":"lvnE","≨":"lnE","≩":"gnE","≩︀":"gvnE","≪":"ll","≪̸":"nLtv","≪⃒":"nLt","≫":"gg","≫̸":"nGtv","≫⃒":"nGt","≬":"twixt","≲":"lsim","≴":"nlsim","≳":"gsim","≵":"ngsim","≶":"lg","≸":"ntlg","≷":"gl","≹":"ntgl","≺":"pr","⊀":"npr","≻":"sc","⊁":"nsc","≼":"prcue","⋠":"nprcue","≽":"sccue","⋡":"nsccue","≾":"prsim","≿":"scsim","≿̸":"NotSucceedsTilde","⊂":"sub","⊄":"nsub","⊂⃒":"vnsub","⊃":"sup","⊅":"nsup","⊃⃒":"vnsup","⊆":"sube","⊈":"nsube","⊇":"supe","⊉":"nsupe","⊊︀":"vsubne","⊊":"subne","⊋︀":"vsupne","⊋":"supne","⊍":"cupdot","⊎":"uplus","⊏":"sqsub","⊏̸":"NotSquareSubset","⊐":"sqsup","⊐̸":"NotSquareSuperset","⊑":"sqsube","⋢":"nsqsube","⊒":"sqsupe","⋣":"nsqsupe","⊓":"sqcap","⊓︀":"sqcaps","⊔":"sqcup","⊔︀":"sqcups","⊕":"oplus","⊖":"ominus","⊗":"otimes","⊘":"osol","⊙":"odot","⊚":"ocir","⊛":"oast","⊝":"odash","⊞":"plusb","⊟":"minusb","⊠":"timesb","⊡":"sdotb","⊢":"vdash","⊬":"nvdash","⊣":"dashv","⊤":"top","⊥":"bot","⊧":"models","⊨":"vDash","⊭":"nvDash","⊩":"Vdash","⊮":"nVdash","⊪":"Vvdash","⊫":"VDash","⊯":"nVDash","⊰":"prurel","⊲":"vltri","⋪":"nltri","⊳":"vrtri","⋫":"nrtri","⊴":"ltrie","⋬":"nltrie","⊴⃒":"nvltrie","⊵":"rtrie","⋭":"nrtrie","⊵⃒":"nvrtrie","⊶":"origof","⊷":"imof","⊸":"mumap","⊹":"hercon","⊺":"intcal","⊻":"veebar","⊽":"barvee","⊾":"angrtvb","⊿":"lrtri","⋀":"Wedge","⋁":"Vee","⋂":"xcap","⋃":"xcup","⋄":"diam","⋅":"sdot","⋆":"Star","⋇":"divonx","⋈":"bowtie","⋉":"ltimes","⋊":"rtimes","⋋":"lthree","⋌":"rthree","⋍":"bsime","⋎":"cuvee","⋏":"cuwed","⋐":"Sub","⋑":"Sup","⋒":"Cap","⋓":"Cup","⋔":"fork","⋕":"epar","⋖":"ltdot","⋗":"gtdot","⋘":"Ll","⋘̸":"nLl","⋙":"Gg","⋙̸":"nGg","⋚︀":"lesg","⋚":"leg","⋛":"gel","⋛︀":"gesl","⋞":"cuepr","⋟":"cuesc","⋦":"lnsim","⋧":"gnsim","⋨":"prnsim","⋩":"scnsim","⋮":"vellip","⋯":"ctdot","⋰":"utdot","⋱":"dtdot","⋲":"disin","⋳":"isinsv","⋴":"isins","⋵":"isindot","⋵̸":"notindot","⋶":"notinvc","⋷":"notinvb","⋹":"isinE","⋹̸":"notinE","⋺":"nisd","⋻":"xnis","⋼":"nis","⋽":"notnivc","⋾":"notnivb","⌅":"barwed","⌆":"Barwed","⌌":"drcrop","⌍":"dlcrop","⌎":"urcrop","⌏":"ulcrop","⌐":"bnot","⌒":"profline","⌓":"profsurf","⌕":"telrec","⌖":"target","⌜":"ulcorn","⌝":"urcorn","⌞":"dlcorn","⌟":"drcorn","⌢":"frown","⌣":"smile","⌭":"cylcty","⌮":"profalar","⌶":"topbot","⌽":"ovbar","⌿":"solbar","⍼":"angzarr","⎰":"lmoust","⎱":"rmoust","⎴":"tbrk","⎵":"bbrk","⎶":"bbrktbrk","⏜":"OverParenthesis","⏝":"UnderParenthesis","⏞":"OverBrace","⏟":"UnderBrace","⏢":"trpezium","⏧":"elinters","␣":"blank","─":"boxh","│":"boxv","┌":"boxdr","┐":"boxdl","└":"boxur","┘":"boxul","├":"boxvr","┤":"boxvl","┬":"boxhd","┴":"boxhu","┼":"boxvh","═":"boxH","║":"boxV","╒":"boxdR","╓":"boxDr","╔":"boxDR","╕":"boxdL","╖":"boxDl","╗":"boxDL","╘":"boxuR","╙":"boxUr","╚":"boxUR","╛":"boxuL","╜":"boxUl","╝":"boxUL","╞":"boxvR","╟":"boxVr","╠":"boxVR","╡":"boxvL","╢":"boxVl","╣":"boxVL","╤":"boxHd","╥":"boxhD","╦":"boxHD","╧":"boxHu","╨":"boxhU","╩":"boxHU","╪":"boxvH","╫":"boxVh","╬":"boxVH","▀":"uhblk","▄":"lhblk","█":"block","░":"blk14","▒":"blk12","▓":"blk34","□":"squ","▪":"squf","▫":"EmptyVerySmallSquare","▭":"rect","▮":"marker","▱":"fltns","△":"xutri","▴":"utrif","▵":"utri","▸":"rtrif","▹":"rtri","▽":"xdtri","▾":"dtrif","▿":"dtri","◂":"ltrif","◃":"ltri","◊":"loz","○":"cir","◬":"tridot","◯":"xcirc","◸":"ultri","◹":"urtri","◺":"lltri","◻":"EmptySmallSquare","◼":"FilledSmallSquare","★":"starf","☆":"star","☎":"phone","♀":"female","♂":"male","♠":"spades","♣":"clubs","♥":"hearts","♦":"diams","♪":"sung","✓":"check","✗":"cross","✠":"malt","✶":"sext","❘":"VerticalSeparator","⟈":"bsolhsub","⟉":"suphsol","⟵":"xlarr","⟶":"xrarr","⟷":"xharr","⟸":"xlArr","⟹":"xrArr","⟺":"xhArr","⟼":"xmap","⟿":"dzigrarr","⤂":"nvlArr","⤃":"nvrArr","⤄":"nvHarr","⤅":"Map","⤌":"lbarr","⤍":"rbarr","⤎":"lBarr","⤏":"rBarr","⤐":"RBarr","⤑":"DDotrahd","⤒":"UpArrowBar","⤓":"DownArrowBar","⤖":"Rarrtl","⤙":"latail","⤚":"ratail","⤛":"lAtail","⤜":"rAtail","⤝":"larrfs","⤞":"rarrfs","⤟":"larrbfs","⤠":"rarrbfs","⤣":"nwarhk","⤤":"nearhk","⤥":"searhk","⤦":"swarhk","⤧":"nwnear","⤨":"toea","⤩":"tosa","⤪":"swnwar","⤳":"rarrc","⤳̸":"nrarrc","⤵":"cudarrr","⤶":"ldca","⤷":"rdca","⤸":"cudarrl","⤹":"larrpl","⤼":"curarrm","⤽":"cularrp","⥅":"rarrpl","⥈":"harrcir","⥉":"Uarrocir","⥊":"lurdshar","⥋":"ldrushar","⥎":"LeftRightVector","⥏":"RightUpDownVector","⥐":"DownLeftRightVector","⥑":"LeftUpDownVector","⥒":"LeftVectorBar","⥓":"RightVectorBar","⥔":"RightUpVectorBar","⥕":"RightDownVectorBar","⥖":"DownLeftVectorBar","⥗":"DownRightVectorBar","⥘":"LeftUpVectorBar","⥙":"LeftDownVectorBar","⥚":"LeftTeeVector","⥛":"RightTeeVector","⥜":"RightUpTeeVector","⥝":"RightDownTeeVector","⥞":"DownLeftTeeVector","⥟":"DownRightTeeVector","⥠":"LeftUpTeeVector","⥡":"LeftDownTeeVector","⥢":"lHar","⥣":"uHar","⥤":"rHar","⥥":"dHar","⥦":"luruhar","⥧":"ldrdhar","⥨":"ruluhar","⥩":"rdldhar","⥪":"lharul","⥫":"llhard","⥬":"rharul","⥭":"lrhard","⥮":"udhar","⥯":"duhar","⥰":"RoundImplies","⥱":"erarr","⥲":"simrarr","⥳":"larrsim","⥴":"rarrsim","⥵":"rarrap","⥶":"ltlarr","⥸":"gtrarr","⥹":"subrarr","⥻":"suplarr","⥼":"lfisht","⥽":"rfisht","⥾":"ufisht","⥿":"dfisht","⦚":"vzigzag","⦜":"vangrt","⦝":"angrtvbd","⦤":"ange","⦥":"range","⦦":"dwangle","⦧":"uwangle","⦨":"angmsdaa","⦩":"angmsdab","⦪":"angmsdac","⦫":"angmsdad","⦬":"angmsdae","⦭":"angmsdaf","⦮":"angmsdag","⦯":"angmsdah","⦰":"bemptyv","⦱":"demptyv","⦲":"cemptyv","⦳":"raemptyv","⦴":"laemptyv","⦵":"ohbar","⦶":"omid","⦷":"opar","⦹":"operp","⦻":"olcross","⦼":"odsold","⦾":"olcir","⦿":"ofcir","⧀":"olt","⧁":"ogt","⧂":"cirscir","⧃":"cirE","⧄":"solb","⧅":"bsolb","⧉":"boxbox","⧍":"trisb","⧎":"rtriltri","⧏":"LeftTriangleBar","⧏̸":"NotLeftTriangleBar","⧐":"RightTriangleBar","⧐̸":"NotRightTriangleBar","⧜":"iinfin","⧝":"infintie","⧞":"nvinfin","⧣":"eparsl","⧤":"smeparsl","⧥":"eqvparsl","⧫":"lozf","⧴":"RuleDelayed","⧶":"dsol","⨀":"xodot","⨁":"xoplus","⨂":"xotime","⨄":"xuplus","⨆":"xsqcup","⨍":"fpartint","⨐":"cirfnint","⨑":"awint","⨒":"rppolint","⨓":"scpolint","⨔":"npolint","⨕":"pointint","⨖":"quatint","⨗":"intlarhk","⨢":"pluscir","⨣":"plusacir","⨤":"simplus","⨥":"plusdu","⨦":"plussim","⨧":"plustwo","⨩":"mcomma","⨪":"minusdu","⨭":"loplus","⨮":"roplus","⨯":"Cross","⨰":"timesd","⨱":"timesbar","⨳":"smashp","⨴":"lotimes","⨵":"rotimes","⨶":"otimesas","⨷":"Otimes","⨸":"odiv","⨹":"triplus","⨺":"triminus","⨻":"tritime","⨼":"iprod","⨿":"amalg","⩀":"capdot","⩂":"ncup","⩃":"ncap","⩄":"capand","⩅":"cupor","⩆":"cupcap","⩇":"capcup","⩈":"cupbrcap","⩉":"capbrcup","⩊":"cupcup","⩋":"capcap","⩌":"ccups","⩍":"ccaps","⩐":"ccupssm","⩓":"And","⩔":"Or","⩕":"andand","⩖":"oror","⩗":"orslope","⩘":"andslope","⩚":"andv","⩛":"orv","⩜":"andd","⩝":"ord","⩟":"wedbar","⩦":"sdote","⩪":"simdot","⩭":"congdot","⩭̸":"ncongdot","⩮":"easter","⩯":"apacir","⩰":"apE","⩰̸":"napE","⩱":"eplus","⩲":"pluse","⩳":"Esim","⩷":"eDDot","⩸":"equivDD","⩹":"ltcir","⩺":"gtcir","⩻":"ltquest","⩼":"gtquest","⩽":"les","⩽̸":"nles","⩾":"ges","⩾̸":"nges","⩿":"lesdot","⪀":"gesdot","⪁":"lesdoto","⪂":"gesdoto","⪃":"lesdotor","⪄":"gesdotol","⪅":"lap","⪆":"gap","⪇":"lne","⪈":"gne","⪉":"lnap","⪊":"gnap","⪋":"lEg","⪌":"gEl","⪍":"lsime","⪎":"gsime","⪏":"lsimg","⪐":"gsiml","⪑":"lgE","⪒":"glE","⪓":"lesges","⪔":"gesles","⪕":"els","⪖":"egs","⪗":"elsdot","⪘":"egsdot","⪙":"el","⪚":"eg","⪝":"siml","⪞":"simg","⪟":"simlE","⪠":"simgE","⪡":"LessLess","⪡̸":"NotNestedLessLess","⪢":"GreaterGreater","⪢̸":"NotNestedGreaterGreater","⪤":"glj","⪥":"gla","⪦":"ltcc","⪧":"gtcc","⪨":"lescc","⪩":"gescc","⪪":"smt","⪫":"lat","⪬":"smte","⪬︀":"smtes","⪭":"late","⪭︀":"lates","⪮":"bumpE","⪯":"pre","⪯̸":"npre","⪰":"sce","⪰̸":"nsce","⪳":"prE","⪴":"scE","⪵":"prnE","⪶":"scnE","⪷":"prap","⪸":"scap","⪹":"prnap","⪺":"scnap","⪻":"Pr","⪼":"Sc","⪽":"subdot","⪾":"supdot","⪿":"subplus","⫀":"supplus","⫁":"submult","⫂":"supmult","⫃":"subedot","⫄":"supedot","⫅":"subE","⫅̸":"nsubE","⫆":"supE","⫆̸":"nsupE","⫇":"subsim","⫈":"supsim","⫋︀":"vsubnE","⫋":"subnE","⫌︀":"vsupnE","⫌":"supnE","⫏":"csub","⫐":"csup","⫑":"csube","⫒":"csupe","⫓":"subsup","⫔":"supsub","⫕":"subsub","⫖":"supsup","⫗":"suphsub","⫘":"supdsub","⫙":"forkv","⫚":"topfork","⫛":"mlcp","⫤":"Dashv","⫦":"Vdashl","⫧":"Barv","⫨":"vBar","⫩":"vBarv","⫫":"Vbar","⫬":"Not","⫭":"bNot","⫮":"rnmid","⫯":"cirmid","⫰":"midcir","⫱":"topcir","⫲":"nhpar","⫳":"parsim","⫽":"parsl","⫽⃥":"nparsl","♭":"flat","♮":"natur","♯":"sharp","¤":"curren","¢":"cent",$:"dollar","£":"pound","¥":"yen","€":"euro","¹":"sup1","½":"half","⅓":"frac13","¼":"frac14","⅕":"frac15","⅙":"frac16","⅛":"frac18","²":"sup2","⅔":"frac23","⅖":"frac25","³":"sup3","¾":"frac34","⅗":"frac35","⅜":"frac38","⅘":"frac45","⅚":"frac56","⅝":"frac58","⅞":"frac78","𝒶":"ascr","𝕒":"aopf","𝔞":"afr","𝔸":"Aopf","𝔄":"Afr","𝒜":"Ascr","ª":"ordf","á":"aacute","Á":"Aacute","à":"agrave","À":"Agrave","ă":"abreve","Ă":"Abreve","â":"acirc","Â":"Acirc","å":"aring","Å":"angst","ä":"auml","Ä":"Auml","ã":"atilde","Ã":"Atilde","ą":"aogon","Ą":"Aogon","ā":"amacr","Ā":"Amacr","æ":"aelig","Æ":"AElig","𝒷":"bscr","𝕓":"bopf","𝔟":"bfr","𝔹":"Bopf","ℬ":"Bscr","𝔅":"Bfr","𝔠":"cfr","𝒸":"cscr","𝕔":"copf","ℭ":"Cfr","𝒞":"Cscr","ℂ":"Copf","ć":"cacute","Ć":"Cacute","ĉ":"ccirc","Ĉ":"Ccirc","č":"ccaron","Č":"Ccaron","ċ":"cdot","Ċ":"Cdot","ç":"ccedil","Ç":"Ccedil","℅":"incare","𝔡":"dfr","ⅆ":"dd","𝕕":"dopf","𝒹":"dscr","𝒟":"Dscr","𝔇":"Dfr","ⅅ":"DD","𝔻":"Dopf","ď":"dcaron","Ď":"Dcaron","đ":"dstrok","Đ":"Dstrok","ð":"eth","Ð":"ETH","ⅇ":"ee","ℯ":"escr","𝔢":"efr","𝕖":"eopf","ℰ":"Escr","𝔈":"Efr","𝔼":"Eopf","é":"eacute","É":"Eacute","è":"egrave","È":"Egrave","ê":"ecirc","Ê":"Ecirc","ě":"ecaron","Ě":"Ecaron","ë":"euml","Ë":"Euml","ė":"edot","Ė":"Edot","ę":"eogon","Ę":"Eogon","ē":"emacr","Ē":"Emacr","𝔣":"ffr","𝕗":"fopf","𝒻":"fscr","𝔉":"Ffr","𝔽":"Fopf","ℱ":"Fscr","ff":"fflig","ffi":"ffilig","ffl":"ffllig","fi":"filig",fj:"fjlig","fl":"fllig","ƒ":"fnof","ℊ":"gscr","𝕘":"gopf","𝔤":"gfr","𝒢":"Gscr","𝔾":"Gopf","𝔊":"Gfr","ǵ":"gacute","ğ":"gbreve","Ğ":"Gbreve","ĝ":"gcirc","Ĝ":"Gcirc","ġ":"gdot","Ġ":"Gdot","Ģ":"Gcedil","𝔥":"hfr","ℎ":"planckh","𝒽":"hscr","𝕙":"hopf","ℋ":"Hscr","ℌ":"Hfr","ℍ":"Hopf","ĥ":"hcirc","Ĥ":"Hcirc","ℏ":"hbar","ħ":"hstrok","Ħ":"Hstrok","𝕚":"iopf","𝔦":"ifr","𝒾":"iscr","ⅈ":"ii","𝕀":"Iopf","ℐ":"Iscr","ℑ":"Im","í":"iacute","Í":"Iacute","ì":"igrave","Ì":"Igrave","î":"icirc","Î":"Icirc","ï":"iuml","Ï":"Iuml","ĩ":"itilde","Ĩ":"Itilde","İ":"Idot","į":"iogon","Į":"Iogon","ī":"imacr","Ī":"Imacr","ij":"ijlig","IJ":"IJlig","ı":"imath","𝒿":"jscr","𝕛":"jopf","𝔧":"jfr","𝒥":"Jscr","𝔍":"Jfr","𝕁":"Jopf","ĵ":"jcirc","Ĵ":"Jcirc","ȷ":"jmath","𝕜":"kopf","𝓀":"kscr","𝔨":"kfr","𝒦":"Kscr","𝕂":"Kopf","𝔎":"Kfr","ķ":"kcedil","Ķ":"Kcedil","𝔩":"lfr","𝓁":"lscr","ℓ":"ell","𝕝":"lopf","ℒ":"Lscr","𝔏":"Lfr","𝕃":"Lopf","ĺ":"lacute","Ĺ":"Lacute","ľ":"lcaron","Ľ":"Lcaron","ļ":"lcedil","Ļ":"Lcedil","ł":"lstrok","Ł":"Lstrok","ŀ":"lmidot","Ŀ":"Lmidot","𝔪":"mfr","𝕞":"mopf","𝓂":"mscr","𝔐":"Mfr","𝕄":"Mopf","ℳ":"Mscr","𝔫":"nfr","𝕟":"nopf","𝓃":"nscr","ℕ":"Nopf","𝒩":"Nscr","𝔑":"Nfr","ń":"nacute","Ń":"Nacute","ň":"ncaron","Ň":"Ncaron","ñ":"ntilde","Ñ":"Ntilde","ņ":"ncedil","Ņ":"Ncedil","№":"numero","ŋ":"eng","Ŋ":"ENG","𝕠":"oopf","𝔬":"ofr","ℴ":"oscr","𝒪":"Oscr","𝔒":"Ofr","𝕆":"Oopf","º":"ordm","ó":"oacute","Ó":"Oacute","ò":"ograve","Ò":"Ograve","ô":"ocirc","Ô":"Ocirc","ö":"ouml","Ö":"Ouml","ő":"odblac","Ő":"Odblac","õ":"otilde","Õ":"Otilde","ø":"oslash","Ø":"Oslash","ō":"omacr","Ō":"Omacr","œ":"oelig","Œ":"OElig","𝔭":"pfr","𝓅":"pscr","𝕡":"popf","ℙ":"Popf","𝔓":"Pfr","𝒫":"Pscr","𝕢":"qopf","𝔮":"qfr","𝓆":"qscr","𝒬":"Qscr","𝔔":"Qfr","ℚ":"Qopf","ĸ":"kgreen","𝔯":"rfr","𝕣":"ropf","𝓇":"rscr","ℛ":"Rscr","ℜ":"Re","ℝ":"Ropf","ŕ":"racute","Ŕ":"Racute","ř":"rcaron","Ř":"Rcaron","ŗ":"rcedil","Ŗ":"Rcedil","𝕤":"sopf","𝓈":"sscr","𝔰":"sfr","𝕊":"Sopf","𝔖":"Sfr","𝒮":"Sscr","Ⓢ":"oS","ś":"sacute","Ś":"Sacute","ŝ":"scirc","Ŝ":"Scirc","š":"scaron","Š":"Scaron","ş":"scedil","Ş":"Scedil","ß":"szlig","𝔱":"tfr","𝓉":"tscr","𝕥":"topf","𝒯":"Tscr","𝔗":"Tfr","𝕋":"Topf","ť":"tcaron","Ť":"Tcaron","ţ":"tcedil","Ţ":"Tcedil","™":"trade","ŧ":"tstrok","Ŧ":"Tstrok","𝓊":"uscr","𝕦":"uopf","𝔲":"ufr","𝕌":"Uopf","𝔘":"Ufr","𝒰":"Uscr","ú":"uacute","Ú":"Uacute","ù":"ugrave","Ù":"Ugrave","ŭ":"ubreve","Ŭ":"Ubreve","û":"ucirc","Û":"Ucirc","ů":"uring","Ů":"Uring","ü":"uuml","Ü":"Uuml","ű":"udblac","Ű":"Udblac","ũ":"utilde","Ũ":"Utilde","ų":"uogon","Ų":"Uogon","ū":"umacr","Ū":"Umacr","𝔳":"vfr","𝕧":"vopf","𝓋":"vscr","𝔙":"Vfr","𝕍":"Vopf","𝒱":"Vscr","𝕨":"wopf","𝓌":"wscr","𝔴":"wfr","𝒲":"Wscr","𝕎":"Wopf","𝔚":"Wfr","ŵ":"wcirc","Ŵ":"Wcirc","𝔵":"xfr","𝓍":"xscr","𝕩":"xopf","𝕏":"Xopf","𝔛":"Xfr","𝒳":"Xscr","𝔶":"yfr","𝓎":"yscr","𝕪":"yopf","𝒴":"Yscr","𝔜":"Yfr","𝕐":"Yopf","ý":"yacute","Ý":"Yacute","ŷ":"ycirc","Ŷ":"Ycirc","ÿ":"yuml","Ÿ":"Yuml","𝓏":"zscr","𝔷":"zfr","𝕫":"zopf","ℨ":"Zfr","ℤ":"Zopf","𝒵":"Zscr","ź":"zacute","Ź":"Zacute","ž":"zcaron","Ž":"Zcaron","ż":"zdot","Ż":"Zdot","Ƶ":"imped","þ":"thorn","Þ":"THORN","ʼn":"napos","α":"alpha","Α":"Alpha","β":"beta","Β":"Beta","γ":"gamma","Γ":"Gamma","δ":"delta","Δ":"Delta","ε":"epsi","ϵ":"epsiv","Ε":"Epsilon","ϝ":"gammad","Ϝ":"Gammad","ζ":"zeta","Ζ":"Zeta","η":"eta","Η":"Eta","θ":"theta","ϑ":"thetav","Θ":"Theta","ι":"iota","Ι":"Iota","κ":"kappa","ϰ":"kappav","Κ":"Kappa","λ":"lambda","Λ":"Lambda","μ":"mu","µ":"micro","Μ":"Mu","ν":"nu","Ν":"Nu","ξ":"xi","Ξ":"Xi","ο":"omicron","Ο":"Omicron","π":"pi","ϖ":"piv","Π":"Pi","ρ":"rho","ϱ":"rhov","Ρ":"Rho","σ":"sigma","Σ":"Sigma","ς":"sigmaf","τ":"tau","Τ":"Tau","υ":"upsi","Υ":"Upsilon","ϒ":"Upsi","φ":"phi","ϕ":"phiv","Φ":"Phi","χ":"chi","Χ":"Chi","ψ":"psi","Ψ":"Psi","ω":"omega","Ω":"ohm","а":"acy","А":"Acy","б":"bcy","Б":"Bcy","в":"vcy","В":"Vcy","г":"gcy","Г":"Gcy","ѓ":"gjcy","Ѓ":"GJcy","д":"dcy","Д":"Dcy","ђ":"djcy","Ђ":"DJcy","е":"iecy","Е":"IEcy","ё":"iocy","Ё":"IOcy","є":"jukcy","Є":"Jukcy","ж":"zhcy","Ж":"ZHcy","з":"zcy","З":"Zcy","ѕ":"dscy","Ѕ":"DScy","и":"icy","И":"Icy","і":"iukcy","І":"Iukcy","ї":"yicy","Ї":"YIcy","й":"jcy","Й":"Jcy","ј":"jsercy","Ј":"Jsercy","к":"kcy","К":"Kcy","ќ":"kjcy","Ќ":"KJcy","л":"lcy","Л":"Lcy","љ":"ljcy","Љ":"LJcy","м":"mcy","М":"Mcy","н":"ncy","Н":"Ncy","њ":"njcy","Њ":"NJcy","о":"ocy","О":"Ocy","п":"pcy","П":"Pcy","р":"rcy","Р":"Rcy","с":"scy","С":"Scy","т":"tcy","Т":"Tcy","ћ":"tshcy","Ћ":"TSHcy","у":"ucy","У":"Ucy","ў":"ubrcy","Ў":"Ubrcy","ф":"fcy","Ф":"Fcy","х":"khcy","Х":"KHcy","ц":"tscy","Ц":"TScy","ч":"chcy","Ч":"CHcy","џ":"dzcy","Џ":"DZcy","ш":"shcy","Ш":"SHcy","щ":"shchcy","Щ":"SHCHcy","ъ":"hardcy","Ъ":"HARDcy","ы":"ycy","Ы":"Ycy","ь":"softcy","Ь":"SOFTcy","э":"ecy","Э":"Ecy","ю":"yucy","Ю":"YUcy","я":"yacy","Я":"YAcy","ℵ":"aleph","ℶ":"beth","ℷ":"gimel","ℸ":"daleth"},h=/["&'<>`]/g,d={'"':""","&":"&","'":"'","<":"<",">":">","`":"`"},p=/&#(?:[xX][^a-fA-F0-9]|[^0-9xX])/,g=/[\0-\x08\x0B\x0E-\x1F\x7F-\x9F\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,y=/&(CounterClockwiseContourIntegral|DoubleLongLeftRightArrow|ClockwiseContourIntegral|NotNestedGreaterGreater|NotSquareSupersetEqual|DiacriticalDoubleAcute|NotRightTriangleEqual|NotSucceedsSlantEqual|NotPrecedesSlantEqual|CloseCurlyDoubleQuote|NegativeVeryThinSpace|DoubleContourIntegral|FilledVerySmallSquare|CapitalDifferentialD|OpenCurlyDoubleQuote|EmptyVerySmallSquare|NestedGreaterGreater|DoubleLongRightArrow|NotLeftTriangleEqual|NotGreaterSlantEqual|ReverseUpEquilibrium|DoubleLeftRightArrow|NotSquareSubsetEqual|NotDoubleVerticalBar|RightArrowLeftArrow|NotGreaterFullEqual|NotRightTriangleBar|SquareSupersetEqual|DownLeftRightVector|DoubleLongLeftArrow|leftrightsquigarrow|LeftArrowRightArrow|NegativeMediumSpace|blacktriangleright|RightDownVectorBar|PrecedesSlantEqual|RightDoubleBracket|SucceedsSlantEqual|NotLeftTriangleBar|RightTriangleEqual|SquareIntersection|RightDownTeeVector|ReverseEquilibrium|NegativeThickSpace|longleftrightarrow|Longleftrightarrow|LongLeftRightArrow|DownRightTeeVector|DownRightVectorBar|GreaterSlantEqual|SquareSubsetEqual|LeftDownVectorBar|LeftDoubleBracket|VerticalSeparator|rightleftharpoons|NotGreaterGreater|NotSquareSuperset|blacktriangleleft|blacktriangledown|NegativeThinSpace|LeftDownTeeVector|NotLessSlantEqual|leftrightharpoons|DoubleUpDownArrow|DoubleVerticalBar|LeftTriangleEqual|FilledSmallSquare|twoheadrightarrow|NotNestedLessLess|DownLeftTeeVector|DownLeftVectorBar|RightAngleBracket|NotTildeFullEqual|NotReverseElement|RightUpDownVector|DiacriticalTilde|NotSucceedsTilde|circlearrowright|NotPrecedesEqual|rightharpoondown|DoubleRightArrow|NotSucceedsEqual|NonBreakingSpace|NotRightTriangle|LessEqualGreater|RightUpTeeVector|LeftAngleBracket|GreaterFullEqual|DownArrowUpArrow|RightUpVectorBar|twoheadleftarrow|GreaterEqualLess|downharpoonright|RightTriangleBar|ntrianglerighteq|NotSupersetEqual|LeftUpDownVector|DiacriticalAcute|rightrightarrows|vartriangleright|UpArrowDownArrow|DiacriticalGrave|UnderParenthesis|EmptySmallSquare|LeftUpVectorBar|leftrightarrows|DownRightVector|downharpoonleft|trianglerighteq|ShortRightArrow|OverParenthesis|DoubleLeftArrow|DoubleDownArrow|NotSquareSubset|bigtriangledown|ntrianglelefteq|UpperRightArrow|curvearrowright|vartriangleleft|NotLeftTriangle|nleftrightarrow|LowerRightArrow|NotHumpDownHump|NotGreaterTilde|rightthreetimes|LeftUpTeeVector|NotGreaterEqual|straightepsilon|LeftTriangleBar|rightsquigarrow|ContourIntegral|rightleftarrows|CloseCurlyQuote|RightDownVector|LeftRightVector|nLeftrightarrow|leftharpoondown|circlearrowleft|SquareSuperset|OpenCurlyQuote|hookrightarrow|HorizontalLine|DiacriticalDot|NotLessGreater|ntriangleright|DoubleRightTee|InvisibleComma|InvisibleTimes|LowerLeftArrow|DownLeftVector|NotSubsetEqual|curvearrowleft|trianglelefteq|NotVerticalBar|TildeFullEqual|downdownarrows|NotGreaterLess|RightTeeVector|ZeroWidthSpace|looparrowright|LongRightArrow|doublebarwedge|ShortLeftArrow|ShortDownArrow|RightVectorBar|GreaterGreater|ReverseElement|rightharpoonup|LessSlantEqual|leftthreetimes|upharpoonright|rightarrowtail|LeftDownVector|Longrightarrow|NestedLessLess|UpperLeftArrow|nshortparallel|leftleftarrows|leftrightarrow|Leftrightarrow|LeftRightArrow|longrightarrow|upharpoonleft|RightArrowBar|ApplyFunction|LeftTeeVector|leftarrowtail|NotEqualTilde|varsubsetneqq|varsupsetneqq|RightTeeArrow|SucceedsEqual|SucceedsTilde|LeftVectorBar|SupersetEqual|hookleftarrow|DifferentialD|VerticalTilde|VeryThinSpace|blacktriangle|bigtriangleup|LessFullEqual|divideontimes|leftharpoonup|UpEquilibrium|ntriangleleft|RightTriangle|measuredangle|shortparallel|longleftarrow|Longleftarrow|LongLeftArrow|DoubleLeftTee|Poincareplane|PrecedesEqual|triangleright|DoubleUpArrow|RightUpVector|fallingdotseq|looparrowleft|PrecedesTilde|NotTildeEqual|NotTildeTilde|smallsetminus|Proportional|triangleleft|triangledown|UnderBracket|NotHumpEqual|exponentiale|ExponentialE|NotLessTilde|HilbertSpace|RightCeiling|blacklozenge|varsupsetneq|HumpDownHump|GreaterEqual|VerticalLine|LeftTeeArrow|NotLessEqual|DownTeeArrow|LeftTriangle|varsubsetneq|Intersection|NotCongruent|DownArrowBar|LeftUpVector|LeftArrowBar|risingdotseq|GreaterTilde|RoundImplies|SquareSubset|ShortUpArrow|NotSuperset|quaternions|precnapprox|backepsilon|preccurlyeq|OverBracket|blacksquare|MediumSpace|VerticalBar|circledcirc|circleddash|CircleMinus|CircleTimes|LessGreater|curlyeqprec|curlyeqsucc|diamondsuit|UpDownArrow|Updownarrow|RuleDelayed|Rrightarrow|updownarrow|RightVector|nRightarrow|nrightarrow|eqslantless|LeftCeiling|Equilibrium|SmallCircle|expectation|NotSucceeds|thickapprox|GreaterLess|SquareUnion|NotPrecedes|NotLessLess|straightphi|succnapprox|succcurlyeq|SubsetEqual|sqsupseteq|Proportion|Laplacetrf|ImaginaryI|supsetneqq|NotGreater|gtreqqless|NotElement|ThickSpace|TildeEqual|TildeTilde|Fouriertrf|rmoustache|EqualTilde|eqslantgtr|UnderBrace|LeftVector|UpArrowBar|nLeftarrow|nsubseteqq|subsetneqq|nsupseteqq|nleftarrow|succapprox|lessapprox|UpTeeArrow|upuparrows|curlywedge|lesseqqgtr|varepsilon|varnothing|RightFloor|complement|CirclePlus|sqsubseteq|Lleftarrow|circledast|RightArrow|Rightarrow|rightarrow|lmoustache|Bernoullis|precapprox|mapstoleft|mapstodown|longmapsto|dotsquare|downarrow|DoubleDot|nsubseteq|supsetneq|leftarrow|nsupseteq|subsetneq|ThinSpace|ngeqslant|subseteqq|HumpEqual|NotSubset|triangleq|NotCupCap|lesseqgtr|heartsuit|TripleDot|Leftarrow|Coproduct|Congruent|varpropto|complexes|gvertneqq|LeftArrow|LessTilde|supseteqq|MinusPlus|CircleDot|nleqslant|NotExists|gtreqless|nparallel|UnionPlus|LeftFloor|checkmark|CenterDot|centerdot|Mellintrf|gtrapprox|bigotimes|OverBrace|spadesuit|therefore|pitchfork|rationals|PlusMinus|Backslash|Therefore|DownBreve|backsimeq|backprime|DownArrow|nshortmid|Downarrow|lvertneqq|eqvparsl|imagline|imagpart|infintie|integers|Integral|intercal|LessLess|Uarrocir|intlarhk|sqsupset|angmsdaf|sqsubset|llcorner|vartheta|cupbrcap|lnapprox|Superset|SuchThat|succnsim|succneqq|angmsdag|biguplus|curlyvee|trpezium|Succeeds|NotTilde|bigwedge|angmsdah|angrtvbd|triminus|cwconint|fpartint|lrcorner|smeparsl|subseteq|urcorner|lurdshar|laemptyv|DDotrahd|approxeq|ldrushar|awconint|mapstoup|backcong|shortmid|triangle|geqslant|gesdotol|timesbar|circledR|circledS|setminus|multimap|naturals|scpolint|ncongdot|RightTee|boxminus|gnapprox|boxtimes|andslope|thicksim|angmsdaa|varsigma|cirfnint|rtriltri|angmsdab|rppolint|angmsdac|barwedge|drbkarow|clubsuit|thetasym|bsolhsub|capbrcup|dzigrarr|doteqdot|DotEqual|dotminus|UnderBar|NotEqual|realpart|otimesas|ulcorner|hksearow|hkswarow|parallel|PartialD|elinters|emptyset|plusacir|bbrktbrk|angmsdad|pointint|bigoplus|angmsdae|Precedes|bigsqcup|varkappa|notindot|supseteq|precneqq|precnsim|profalar|profline|profsurf|leqslant|lesdotor|raemptyv|subplus|notnivb|notnivc|subrarr|zigrarr|vzigzag|submult|subedot|Element|between|cirscir|larrbfs|larrsim|lotimes|lbrksld|lbrkslu|lozenge|ldrdhar|dbkarow|bigcirc|epsilon|simrarr|simplus|ltquest|Epsilon|luruhar|gtquest|maltese|npolint|eqcolon|npreceq|bigodot|ddagger|gtrless|bnequiv|harrcir|ddotseq|equivDD|backsim|demptyv|nsqsube|nsqsupe|Upsilon|nsubset|upsilon|minusdu|nsucceq|swarrow|nsupset|coloneq|searrow|boxplus|napprox|natural|asympeq|alefsym|congdot|nearrow|bigstar|diamond|supplus|tritime|LeftTee|nvinfin|triplus|NewLine|nvltrie|nvrtrie|nwarrow|nexists|Diamond|ruluhar|Implies|supmult|angzarr|suplarr|suphsub|questeq|because|digamma|Because|olcross|bemptyv|omicron|Omicron|rotimes|NoBreak|intprod|angrtvb|orderof|uwangle|suphsol|lesdoto|orslope|DownTee|realine|cudarrl|rdldhar|OverBar|supedot|lessdot|supdsub|topfork|succsim|rbrkslu|rbrksld|pertenk|cudarrr|isindot|planckh|lessgtr|pluscir|gesdoto|plussim|plustwo|lesssim|cularrp|rarrsim|Cayleys|notinva|notinvb|notinvc|UpArrow|Uparrow|uparrow|NotLess|dwangle|precsim|Product|curarrm|Cconint|dotplus|rarrbfs|ccupssm|Cedilla|cemptyv|notniva|quatint|frac35|frac38|frac45|frac56|frac58|frac78|tridot|xoplus|gacute|gammad|Gammad|lfisht|lfloor|bigcup|sqsupe|gbreve|Gbreve|lharul|sqsube|sqcups|Gcedil|apacir|llhard|lmidot|Lmidot|lmoust|andand|sqcaps|approx|Abreve|spades|circeq|tprime|divide|topcir|Assign|topbot|gesdot|divonx|xuplus|timesd|gesles|atilde|solbar|SOFTcy|loplus|timesb|lowast|lowbar|dlcorn|dlcrop|softcy|dollar|lparlt|thksim|lrhard|Atilde|lsaquo|smashp|bigvee|thinsp|wreath|bkarow|lsquor|lstrok|Lstrok|lthree|ltimes|ltlarr|DotDot|simdot|ltrPar|weierp|xsqcup|angmsd|sigmav|sigmaf|zeetrf|Zcaron|zcaron|mapsto|vsupne|thetav|cirmid|marker|mcomma|Zacute|vsubnE|there4|gtlPar|vsubne|bottom|gtrarr|SHCHcy|shchcy|midast|midcir|middot|minusb|minusd|gtrdot|bowtie|sfrown|mnplus|models|colone|seswar|Colone|mstpos|searhk|gtrsim|nacute|Nacute|boxbox|telrec|hairsp|Tcedil|nbumpe|scnsim|ncaron|Ncaron|ncedil|Ncedil|hamilt|Scedil|nearhk|hardcy|HARDcy|tcedil|Tcaron|commat|nequiv|nesear|tcaron|target|hearts|nexist|varrho|scedil|Scaron|scaron|hellip|Sacute|sacute|hercon|swnwar|compfn|rtimes|rthree|rsquor|rsaquo|zacute|wedgeq|homtht|barvee|barwed|Barwed|rpargt|horbar|conint|swarhk|roplus|nltrie|hslash|hstrok|Hstrok|rmoust|Conint|bprime|hybull|hyphen|iacute|Iacute|supsup|supsub|supsim|varphi|coprod|brvbar|agrave|Supset|supset|igrave|Igrave|notinE|Agrave|iiiint|iinfin|copysr|wedbar|Verbar|vangrt|becaus|incare|verbar|inodot|bullet|drcorn|intcal|drcrop|cularr|vellip|Utilde|bumpeq|cupcap|dstrok|Dstrok|CupCap|cupcup|cupdot|eacute|Eacute|supdot|iquest|easter|ecaron|Ecaron|ecolon|isinsv|utilde|itilde|Itilde|curarr|succeq|Bumpeq|cacute|ulcrop|nparsl|Cacute|nprcue|egrave|Egrave|nrarrc|nrarrw|subsup|subsub|nrtrie|jsercy|nsccue|Jsercy|kappav|kcedil|Kcedil|subsim|ulcorn|nsimeq|egsdot|veebar|kgreen|capand|elsdot|Subset|subset|curren|aacute|lacute|Lacute|emptyv|ntilde|Ntilde|lagran|lambda|Lambda|capcap|Ugrave|langle|subdot|emsp13|numero|emsp14|nvdash|nvDash|nVdash|nVDash|ugrave|ufisht|nvHarr|larrfs|nvlArr|larrhk|larrlp|larrpl|nvrArr|Udblac|nwarhk|larrtl|nwnear|oacute|Oacute|latail|lAtail|sstarf|lbrace|odblac|Odblac|lbrack|udblac|odsold|eparsl|lcaron|Lcaron|ograve|Ograve|lcedil|Lcedil|Aacute|ssmile|ssetmn|squarf|ldquor|capcup|ominus|cylcty|rharul|eqcirc|dagger|rfloor|rfisht|Dagger|daleth|equals|origof|capdot|equest|dcaron|Dcaron|rdquor|oslash|Oslash|otilde|Otilde|otimes|Otimes|urcrop|Ubreve|ubreve|Yacute|Uacute|uacute|Rcedil|rcedil|urcorn|parsim|Rcaron|Vdashl|rcaron|Tstrok|percnt|period|permil|Exists|yacute|rbrack|rbrace|phmmat|ccaron|Ccaron|planck|ccedil|plankv|tstrok|female|plusdo|plusdu|ffilig|plusmn|ffllig|Ccedil|rAtail|dfisht|bernou|ratail|Rarrtl|rarrtl|angsph|rarrpl|rarrlp|rarrhk|xwedge|xotime|forall|ForAll|Vvdash|vsupnE|preceq|bigcap|frac12|frac13|frac14|primes|rarrfs|prnsim|frac15|Square|frac16|square|lesdot|frac18|frac23|propto|prurel|rarrap|rangle|puncsp|frac25|Racute|qprime|racute|lesges|frac34|abreve|AElig|eqsim|utdot|setmn|urtri|Equal|Uring|seArr|uring|searr|dashv|Dashv|mumap|nabla|iogon|Iogon|sdote|sdotb|scsim|napid|napos|equiv|natur|Acirc|dblac|erarr|nbump|iprod|erDot|ucirc|awint|esdot|angrt|ncong|isinE|scnap|Scirc|scirc|ndash|isins|Ubrcy|nearr|neArr|isinv|nedot|ubrcy|acute|Ycirc|iukcy|Iukcy|xutri|nesim|caret|jcirc|Jcirc|caron|twixt|ddarr|sccue|exist|jmath|sbquo|ngeqq|angst|ccaps|lceil|ngsim|UpTee|delta|Delta|rtrif|nharr|nhArr|nhpar|rtrie|jukcy|Jukcy|kappa|rsquo|Kappa|nlarr|nlArr|TSHcy|rrarr|aogon|Aogon|fflig|xrarr|tshcy|ccirc|nleqq|filig|upsih|nless|dharl|nlsim|fjlig|ropar|nltri|dharr|robrk|roarr|fllig|fltns|roang|rnmid|subnE|subne|lAarr|trisb|Ccirc|acirc|ccups|blank|VDash|forkv|Vdash|langd|cedil|blk12|blk14|laquo|strns|diams|notin|vDash|larrb|blk34|block|disin|uplus|vdash|vBarv|aelig|starf|Wedge|check|xrArr|lates|lbarr|lBarr|notni|lbbrk|bcong|frasl|lbrke|frown|vrtri|vprop|vnsup|gamma|Gamma|wedge|xodot|bdquo|srarr|doteq|ldquo|boxdl|boxdL|gcirc|Gcirc|boxDl|boxDL|boxdr|boxdR|boxDr|TRADE|trade|rlhar|boxDR|vnsub|npart|vltri|rlarr|boxhd|boxhD|nprec|gescc|nrarr|nrArr|boxHd|boxHD|boxhu|boxhU|nrtri|boxHu|clubs|boxHU|times|colon|Colon|gimel|xlArr|Tilde|nsime|tilde|nsmid|nspar|THORN|thorn|xlarr|nsube|nsubE|thkap|xhArr|comma|nsucc|boxul|boxuL|nsupe|nsupE|gneqq|gnsim|boxUl|boxUL|grave|boxur|boxuR|boxUr|boxUR|lescc|angle|bepsi|boxvh|varpi|boxvH|numsp|Theta|gsime|gsiml|theta|boxVh|boxVH|boxvl|gtcir|gtdot|boxvL|boxVl|boxVL|crarr|cross|Cross|nvsim|boxvr|nwarr|nwArr|sqsup|dtdot|Uogon|lhard|lharu|dtrif|ocirc|Ocirc|lhblk|duarr|odash|sqsub|Hacek|sqcup|llarr|duhar|oelig|OElig|ofcir|boxvR|uogon|lltri|boxVr|csube|uuarr|ohbar|csupe|ctdot|olarr|olcir|harrw|oline|sqcap|omacr|Omacr|omega|Omega|boxVR|aleph|lneqq|lnsim|loang|loarr|rharu|lobrk|hcirc|operp|oplus|rhard|Hcirc|orarr|Union|order|ecirc|Ecirc|cuepr|szlig|cuesc|breve|reals|eDDot|Breve|hoarr|lopar|utrif|rdquo|Umacr|umacr|efDot|swArr|ultri|alpha|rceil|ovbar|swarr|Wcirc|wcirc|smtes|smile|bsemi|lrarr|aring|parsl|lrhar|bsime|uhblk|lrtri|cupor|Aring|uharr|uharl|slarr|rbrke|bsolb|lsime|rbbrk|RBarr|lsimg|phone|rBarr|rbarr|icirc|lsquo|Icirc|emacr|Emacr|ratio|simne|plusb|simlE|simgE|simeq|pluse|ltcir|ltdot|empty|xharr|xdtri|iexcl|Alpha|ltrie|rarrw|pound|ltrif|xcirc|bumpe|prcue|bumpE|asymp|amacr|cuvee|Sigma|sigma|iiint|udhar|iiota|ijlig|IJlig|supnE|imacr|Imacr|prime|Prime|image|prnap|eogon|Eogon|rarrc|mdash|mDDot|cuwed|imath|supne|imped|Amacr|udarr|prsim|micro|rarrb|cwint|raquo|infin|eplus|range|rangd|Ucirc|radic|minus|amalg|veeeq|rAarr|epsiv|ycirc|quest|sharp|quot|zwnj|Qscr|race|qscr|Qopf|qopf|qint|rang|Rang|Zscr|zscr|Zopf|zopf|rarr|rArr|Rarr|Pscr|pscr|prop|prod|prnE|prec|ZHcy|zhcy|prap|Zeta|zeta|Popf|popf|Zdot|plus|zdot|Yuml|yuml|phiv|YUcy|yucy|Yscr|yscr|perp|Yopf|yopf|part|para|YIcy|Ouml|rcub|yicy|YAcy|rdca|ouml|osol|Oscr|rdsh|yacy|real|oscr|xvee|andd|rect|andv|Xscr|oror|ordm|ordf|xscr|ange|aopf|Aopf|rHar|Xopf|opar|Oopf|xopf|xnis|rhov|oopf|omid|xmap|oint|apid|apos|ogon|ascr|Ascr|odot|odiv|xcup|xcap|ocir|oast|nvlt|nvle|nvgt|nvge|nvap|Wscr|wscr|auml|ntlg|ntgl|nsup|nsub|nsim|Nscr|nscr|nsce|Wopf|ring|npre|wopf|npar|Auml|Barv|bbrk|Nopf|nopf|nmid|nLtv|beta|ropf|Ropf|Beta|beth|nles|rpar|nleq|bnot|bNot|nldr|NJcy|rscr|Rscr|Vscr|vscr|rsqb|njcy|bopf|nisd|Bopf|rtri|Vopf|nGtv|ngtr|vopf|boxh|boxH|boxv|nges|ngeq|boxV|bscr|scap|Bscr|bsim|Vert|vert|bsol|bull|bump|caps|cdot|ncup|scnE|ncap|nbsp|napE|Cdot|cent|sdot|Vbar|nang|vBar|chcy|Mscr|mscr|sect|semi|CHcy|Mopf|mopf|sext|circ|cire|mldr|mlcp|cirE|comp|shcy|SHcy|vArr|varr|cong|copf|Copf|copy|COPY|malt|male|macr|lvnE|cscr|ltri|sime|ltcc|simg|Cscr|siml|csub|Uuml|lsqb|lsim|uuml|csup|Lscr|lscr|utri|smid|lpar|cups|smte|lozf|darr|Lopf|Uscr|solb|lopf|sopf|Sopf|lneq|uscr|spar|dArr|lnap|Darr|dash|Sqrt|LJcy|ljcy|lHar|dHar|Upsi|upsi|diam|lesg|djcy|DJcy|leqq|dopf|Dopf|dscr|Dscr|dscy|ldsh|ldca|squf|DScy|sscr|Sscr|dsol|lcub|late|star|Star|Uopf|Larr|lArr|larr|uopf|dtri|dzcy|sube|subE|Lang|lang|Kscr|kscr|Kopf|kopf|KJcy|kjcy|KHcy|khcy|DZcy|ecir|edot|eDot|Jscr|jscr|succ|Jopf|jopf|Edot|uHar|emsp|ensp|Iuml|iuml|eopf|isin|Iscr|iscr|Eopf|epar|sung|epsi|escr|sup1|sup2|sup3|Iota|iota|supe|supE|Iopf|iopf|IOcy|iocy|Escr|esim|Esim|imof|Uarr|QUOT|uArr|uarr|euml|IEcy|iecy|Idot|Euml|euro|excl|Hscr|hscr|Hopf|hopf|TScy|tscy|Tscr|hbar|tscr|flat|tbrk|fnof|hArr|harr|half|fopf|Fopf|tdot|gvnE|fork|trie|gtcc|fscr|Fscr|gdot|gsim|Gscr|gscr|Gopf|gopf|gneq|Gdot|tosa|gnap|Topf|topf|geqq|toea|GJcy|gjcy|tint|gesl|mid|Sfr|ggg|top|ges|gla|glE|glj|geq|gne|gEl|gel|gnE|Gcy|gcy|gap|Tfr|tfr|Tcy|tcy|Hat|Tau|Ffr|tau|Tab|hfr|Hfr|ffr|Fcy|fcy|icy|Icy|iff|ETH|eth|ifr|Ifr|Eta|eta|int|Int|Sup|sup|ucy|Ucy|Sum|sum|jcy|ENG|ufr|Ufr|eng|Jcy|jfr|els|ell|egs|Efr|efr|Jfr|uml|kcy|Kcy|Ecy|ecy|kfr|Kfr|lap|Sub|sub|lat|lcy|Lcy|leg|Dot|dot|lEg|leq|les|squ|div|die|lfr|Lfr|lgE|Dfr|dfr|Del|deg|Dcy|dcy|lne|lnE|sol|loz|smt|Cup|lrm|cup|lsh|Lsh|sim|shy|map|Map|mcy|Mcy|mfr|Mfr|mho|gfr|Gfr|sfr|cir|Chi|chi|nap|Cfr|vcy|Vcy|cfr|Scy|scy|ncy|Ncy|vee|Vee|Cap|cap|nfr|scE|sce|Nfr|nge|ngE|nGg|vfr|Vfr|ngt|bot|nGt|nis|niv|Rsh|rsh|nle|nlE|bne|Bfr|bfr|nLl|nlt|nLt|Bcy|bcy|not|Not|rlm|wfr|Wfr|npr|nsc|num|ocy|ast|Ocy|ofr|xfr|Xfr|Ofr|ogt|ohm|apE|olt|Rho|ape|rho|Rfr|rfr|ord|REG|ang|reg|orv|And|and|AMP|Rcy|amp|Afr|ycy|Ycy|yen|yfr|Yfr|rcy|par|pcy|Pcy|pfr|Pfr|phi|Phi|afr|Acy|acy|zcy|Zcy|piv|acE|acd|zfr|Zfr|pre|prE|psi|Psi|qfr|Qfr|zwj|Or|ge|Gg|gt|gg|el|oS|lt|Lt|LT|Re|lg|gl|eg|ne|Im|it|le|DD|wp|wr|nu|Nu|dd|lE|Sc|sc|pi|Pi|ee|af|ll|Ll|rx|gE|xi|pm|Xi|ic|pr|Pr|in|ni|mp|mu|ac|Mu|or|ap|Gt|GT|ii);|&(Aacute|Agrave|Atilde|Ccedil|Eacute|Egrave|Iacute|Igrave|Ntilde|Oacute|Ograve|Oslash|Otilde|Uacute|Ugrave|Yacute|aacute|agrave|atilde|brvbar|ccedil|curren|divide|eacute|egrave|frac12|frac14|frac34|iacute|igrave|iquest|middot|ntilde|oacute|ograve|oslash|otilde|plusmn|uacute|ugrave|yacute|AElig|Acirc|Aring|Ecirc|Icirc|Ocirc|THORN|Ucirc|acirc|acute|aelig|aring|cedil|ecirc|icirc|iexcl|laquo|micro|ocirc|pound|raquo|szlig|thorn|times|ucirc|Auml|COPY|Euml|Iuml|Ouml|QUOT|Uuml|auml|cent|copy|euml|iuml|macr|nbsp|ordf|ordm|ouml|para|quot|sect|sup1|sup2|sup3|uuml|yuml|AMP|ETH|REG|amp|deg|eth|not|reg|shy|uml|yen|GT|LT|gt|lt)(?!;)([=a-zA-Z0-9]?)|&#([0-9]+)(;?)|&#[xX]([a-fA-F0-9]+)(;?)|&([0-9a-zA-Z]+)/g,b={aacute:"á",Aacute:"Á",abreve:"ă",Abreve:"Ă",ac:"∾",acd:"∿",acE:"∾̳",acirc:"â",Acirc:"Â",acute:"´",acy:"а",Acy:"А",aelig:"æ",AElig:"Æ",af:"⁡",afr:"𝔞",Afr:"𝔄",agrave:"à",Agrave:"À",alefsym:"ℵ",aleph:"ℵ",alpha:"α",Alpha:"Α",amacr:"ā",Amacr:"Ā",amalg:"⨿",amp:"&",AMP:"&",and:"∧",And:"⩓",andand:"⩕",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsd:"∡",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",aogon:"ą",Aogon:"Ą",aopf:"𝕒",Aopf:"𝔸",ap:"≈",apacir:"⩯",ape:"≊",apE:"⩰",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",aring:"å",Aring:"Å",ascr:"𝒶",Ascr:"𝒜",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",atilde:"ã",Atilde:"Ã",auml:"ä",Auml:"Ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",bcy:"б",Bcy:"Б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",beta:"β",Beta:"Β",beth:"ℶ",between:"≬",bfr:"𝔟",Bfr:"𝔅",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bnot:"⌐",bNot:"⫭",bopf:"𝕓",Bopf:"𝔹",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxhD:"╥",boxHd:"╤",boxHD:"╦",boxhu:"┴",boxhU:"╨",boxHu:"╧",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsol:"\\",bsolb:"⧅",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpe:"≏",bumpE:"⪮",bumpeq:"≏",Bumpeq:"≎",cacute:"ć",Cacute:"Ć",cap:"∩",Cap:"⋒",capand:"⩄",capbrcup:"⩉",capcap:"⩋",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",ccaron:"č",Ccaron:"Č",ccedil:"ç",Ccedil:"Ç",ccirc:"ĉ",Ccirc:"Ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",cdot:"ċ",Cdot:"Ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",chcy:"ч",CHcy:"Ч",check:"✓",checkmark:"✓",chi:"χ",Chi:"Χ",cir:"○",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cire:"≗",cirE:"⧃",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",colone:"≔",Colone:"⩴",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",cscr:"𝒸",Cscr:"𝒞",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cup:"∪",Cup:"⋓",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",dArr:"⇓",Darr:"↡",dash:"‐",dashv:"⊣",Dashv:"⫤",dbkarow:"⤏",dblac:"˝",dcaron:"ď",Dcaron:"Ď",dcy:"д",Dcy:"Д",dd:"ⅆ",DD:"ⅅ",ddagger:"‡",ddarr:"⇊",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",delta:"δ",Delta:"Δ",demptyv:"⦱",dfisht:"⥿",dfr:"𝔡",Dfr:"𝔇",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",djcy:"ђ",DJcy:"Ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",dopf:"𝕕",Dopf:"𝔻",dot:"˙",Dot:"¨",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",downarrow:"↓",Downarrow:"⇓",DownArrow:"↓",DownArrowBar:"⤓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVector:"↽",DownLeftVectorBar:"⥖",DownRightTeeVector:"⥟",DownRightVector:"⇁",DownRightVectorBar:"⥗",DownTee:"⊤",DownTeeArrow:"↧",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",dscr:"𝒹",Dscr:"𝒟",dscy:"ѕ",DScy:"Ѕ",dsol:"⧶",dstrok:"đ",Dstrok:"Đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",dzcy:"џ",DZcy:"Џ",dzigrarr:"⟿",eacute:"é",Eacute:"É",easter:"⩮",ecaron:"ě",Ecaron:"Ě",ecir:"≖",ecirc:"ê",Ecirc:"Ê",ecolon:"≕",ecy:"э",Ecy:"Э",eDDot:"⩷",edot:"ė",eDot:"≑",Edot:"Ė",ee:"ⅇ",efDot:"≒",efr:"𝔢",Efr:"𝔈",eg:"⪚",egrave:"è",Egrave:"È",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",emacr:"ē",Emacr:"Ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp:" ",emsp13:" ",emsp14:" ",eng:"ŋ",ENG:"Ŋ",ensp:" ",eogon:"ę",Eogon:"Ę",eopf:"𝕖",Eopf:"𝔼",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",epsilon:"ε",Epsilon:"Ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",esim:"≂",Esim:"⩳",eta:"η",Eta:"Η",eth:"ð",ETH:"Ð",euml:"ë",Euml:"Ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",fcy:"ф",Fcy:"Ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",ffr:"𝔣",Ffr:"𝔉",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",fopf:"𝕗",Fopf:"𝔽",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",gamma:"γ",Gamma:"Γ",gammad:"ϝ",Gammad:"Ϝ",gap:"⪆",gbreve:"ğ",Gbreve:"Ğ",Gcedil:"Ģ",gcirc:"ĝ",Gcirc:"Ĝ",gcy:"г",Gcy:"Г",gdot:"ġ",Gdot:"Ġ",ge:"≥",gE:"≧",gel:"⋛",gEl:"⪌",geq:"≥",geqq:"≧",geqslant:"⩾",ges:"⩾",gescc:"⪩",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",gfr:"𝔤",Gfr:"𝔊",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",gjcy:"ѓ",GJcy:"Ѓ",gl:"≷",gla:"⪥",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",gopf:"𝕘",Gopf:"𝔾",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",gscr:"ℊ",Gscr:"𝒢",gsim:"≳",gsime:"⪎",gsiml:"⪐",gt:">",Gt:"≫",GT:">",gtcc:"⪧",gtcir:"⩺",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",hardcy:"ъ",HARDcy:"Ъ",harr:"↔",hArr:"⇔",harrcir:"⥈",harrw:"↭",Hat:"^",hbar:"ℏ",hcirc:"ĥ",Hcirc:"Ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",hstrok:"ħ",Hstrok:"Ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",iacute:"í",Iacute:"Í",ic:"⁣",icirc:"î",Icirc:"Î",icy:"и",Icy:"И",Idot:"İ",iecy:"е",IEcy:"Е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",igrave:"ì",Igrave:"Ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",ijlig:"ij",IJlig:"IJ",Im:"ℑ",imacr:"ī",Imacr:"Ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",imof:"⊷",imped:"Ƶ",Implies:"⇒",in:"∈",incare:"℅",infin:"∞",infintie:"⧝",inodot:"ı",int:"∫",Int:"∬",intcal:"⊺",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",iocy:"ё",IOcy:"Ё",iogon:"į",Iogon:"Į",iopf:"𝕚",Iopf:"𝕀",iota:"ι",Iota:"Ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",itilde:"ĩ",Itilde:"Ĩ",iukcy:"і",Iukcy:"І",iuml:"ï",Iuml:"Ï",jcirc:"ĵ",Jcirc:"Ĵ",jcy:"й",Jcy:"Й",jfr:"𝔧",Jfr:"𝔍",jmath:"ȷ",jopf:"𝕛",Jopf:"𝕁",jscr:"𝒿",Jscr:"𝒥",jsercy:"ј",Jsercy:"Ј",jukcy:"є",Jukcy:"Є",kappa:"κ",Kappa:"Κ",kappav:"ϰ",kcedil:"ķ",Kcedil:"Ķ",kcy:"к",Kcy:"К",kfr:"𝔨",Kfr:"𝔎",kgreen:"ĸ",khcy:"х",KHcy:"Х",kjcy:"ќ",KJcy:"Ќ",kopf:"𝕜",Kopf:"𝕂",kscr:"𝓀",Kscr:"𝒦",lAarr:"⇚",lacute:"ĺ",Lacute:"Ĺ",laemptyv:"⦴",lagran:"ℒ",lambda:"λ",Lambda:"Λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larr:"←",lArr:"⇐",Larr:"↞",larrb:"⇤",larrbfs:"⤟",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",lat:"⪫",latail:"⤙",lAtail:"⤛",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",lcaron:"ľ",Lcaron:"Ľ",lcedil:"ļ",Lcedil:"Ļ",lceil:"⌈",lcub:"{",lcy:"л",Lcy:"Л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",leftarrow:"←",Leftarrow:"⇐",LeftArrow:"←",LeftArrowBar:"⇤",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVector:"⇃",LeftDownVectorBar:"⥙",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",Leftrightarrow:"⇔",LeftRightArrow:"↔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTee:"⊣",LeftTeeArrow:"↤",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangle:"⊲",LeftTriangleBar:"⧏",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVector:"↿",LeftUpVectorBar:"⥘",LeftVector:"↼",LeftVectorBar:"⥒",leg:"⋚",lEg:"⪋",leq:"≤",leqq:"≦",leqslant:"⩽",les:"⩽",lescc:"⪨",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",lfr:"𝔩",Lfr:"𝔏",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",ljcy:"љ",LJcy:"Љ",ll:"≪",Ll:"⋘",llarr:"⇇",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",lmidot:"ŀ",Lmidot:"Ŀ",lmoust:"⎰",lmoustache:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",Longleftarrow:"⟸",LongLeftArrow:"⟵",longleftrightarrow:"⟷",Longleftrightarrow:"⟺",LongLeftRightArrow:"⟷",longmapsto:"⟼",longrightarrow:"⟶",Longrightarrow:"⟹",LongRightArrow:"⟶",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",lopf:"𝕝",Lopf:"𝕃",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",lstrok:"ł",Lstrok:"Ł",lt:"<",Lt:"≪",LT:"<",ltcc:"⪦",ltcir:"⩹",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",map:"↦",Map:"⤅",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",mcy:"м",Mcy:"М",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",mfr:"𝔪",Mfr:"𝔐",mho:"℧",micro:"µ",mid:"∣",midast:"*",midcir:"⫰",middot:"·",minus:"−",minusb:"⊟",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",mopf:"𝕞",Mopf:"𝕄",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",mu:"μ",Mu:"Μ",multimap:"⊸",mumap:"⊸",nabla:"∇",nacute:"ń",Nacute:"Ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natur:"♮",natural:"♮",naturals:"ℕ",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",ncaron:"ň",Ncaron:"Ň",ncedil:"ņ",Ncedil:"Ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",ncy:"н",Ncy:"Н",ndash:"–",ne:"≠",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",nfr:"𝔫",Nfr:"𝔑",nge:"≱",ngE:"≧̸",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",ngt:"≯",nGt:"≫⃒",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",njcy:"њ",NJcy:"Њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nle:"≰",nlE:"≦̸",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nlt:"≮",nLt:"≪⃒",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",not:"¬",Not:"⫬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangle:"⋪",NotLeftTriangleBar:"⧏̸",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangle:"⋫",NotRightTriangleBar:"⧐̸",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",npar:"∦",nparallel:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",npre:"⪯̸",nprec:"⊀",npreceq:"⪯̸",nrarr:"↛",nrArr:"⇏",nrarrc:"⤳̸",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",nscr:"𝓃",Nscr:"𝒩",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsube:"⊈",nsubE:"⫅̸",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupe:"⊉",nsupE:"⫆̸",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",ntilde:"ñ",Ntilde:"Ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",nu:"ν",Nu:"Ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",oacute:"ó",Oacute:"Ó",oast:"⊛",ocir:"⊚",ocirc:"ô",Ocirc:"Ô",ocy:"о",Ocy:"О",odash:"⊝",odblac:"ő",Odblac:"Ő",odiv:"⨸",odot:"⊙",odsold:"⦼",oelig:"œ",OElig:"Œ",ofcir:"⦿",ofr:"𝔬",Ofr:"𝔒",ogon:"˛",ograve:"ò",Ograve:"Ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",omacr:"ō",Omacr:"Ō",omega:"ω",Omega:"Ω",omicron:"ο",Omicron:"Ο",omid:"⦶",ominus:"⊖",oopf:"𝕠",Oopf:"𝕆",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",or:"∨",Or:"⩔",orarr:"↻",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",oscr:"ℴ",Oscr:"𝒪",oslash:"ø",Oslash:"Ø",osol:"⊘",otilde:"õ",Otilde:"Õ",otimes:"⊗",Otimes:"⨷",otimesas:"⨶",ouml:"ö",Ouml:"Ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",par:"∥",para:"¶",parallel:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",pcy:"п",Pcy:"П",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",pfr:"𝔭",Pfr:"𝔓",phi:"φ",Phi:"Φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",pi:"π",Pi:"Π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plus:"+",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",pr:"≺",Pr:"⪻",prap:"⪷",prcue:"≼",pre:"⪯",prE:"⪳",prec:"≺",precapprox:"⪷",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportion:"∷",Proportional:"∝",propto:"∝",prsim:"≾",prurel:"⊰",pscr:"𝓅",Pscr:"𝒫",psi:"ψ",Psi:"Ψ",puncsp:" ",qfr:"𝔮",Qfr:"𝔔",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",qscr:"𝓆",Qscr:"𝒬",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",racute:"ŕ",Racute:"Ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarr:"→",rArr:"⇒",Rarr:"↠",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",rarrtl:"↣",Rarrtl:"⤖",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",rcaron:"ř",Rcaron:"Ř",rcedil:"ŗ",Rcedil:"Ŗ",rceil:"⌉",rcub:"}",rcy:"р",Rcy:"Р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",Re:"ℜ",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",rho:"ρ",Rho:"Ρ",rhov:"ϱ",RightAngleBracket:"⟩",rightarrow:"→",Rightarrow:"⇒",RightArrow:"→",RightArrowBar:"⇥",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVector:"⇂",RightDownVectorBar:"⥕",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTee:"⊢",RightTeeArrow:"↦",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangle:"⊳",RightTriangleBar:"⧐",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVector:"↾",RightUpVectorBar:"⥔",RightVector:"⇀",RightVectorBar:"⥓",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoust:"⎱",rmoustache:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",sacute:"ś",Sacute:"Ś",sbquo:"‚",sc:"≻",Sc:"⪼",scap:"⪸",scaron:"š",Scaron:"Š",sccue:"≽",sce:"⪰",scE:"⪴",scedil:"ş",Scedil:"Ş",scirc:"ŝ",Scirc:"Ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",scy:"с",Scy:"С",sdot:"⋅",sdotb:"⊡",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",sfr:"𝔰",Sfr:"𝔖",sfrown:"⌢",sharp:"♯",shchcy:"щ",SHCHcy:"Щ",shcy:"ш",SHcy:"Ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",sigma:"σ",Sigma:"Σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",softcy:"ь",SOFTcy:"Ь",sol:"/",solb:"⧄",solbar:"⌿",sopf:"𝕤",Sopf:"𝕊",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",squ:"□",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squf:"▪",srarr:"→",sscr:"𝓈",Sscr:"𝒮",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",star:"☆",Star:"⋆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",sube:"⊆",subE:"⫅",subedot:"⫃",submult:"⫁",subne:"⊊",subnE:"⫋",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succ:"≻",succapprox:"⪸",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup:"⊃",Sup:"⋑",sup1:"¹",sup2:"²",sup3:"³",supdot:"⪾",supdsub:"⫘",supe:"⊇",supE:"⫆",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supne:"⊋",supnE:"⫌",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",tau:"τ",Tau:"Τ",tbrk:"⎴",tcaron:"ť",Tcaron:"Ť",tcedil:"ţ",Tcedil:"Ţ",tcy:"т",Tcy:"Т",tdot:"⃛",telrec:"⌕",tfr:"𝔱",Tfr:"𝔗",there4:"∴",therefore:"∴",Therefore:"∴",theta:"θ",Theta:"Θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",thinsp:" ",ThinSpace:" ",thkap:"≈",thksim:"∼",thorn:"þ",THORN:"Þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",times:"×",timesb:"⊠",timesbar:"⨱",timesd:"⨰",tint:"∭",toea:"⤨",top:"⊤",topbot:"⌶",topcir:"⫱",topf:"𝕥",Topf:"𝕋",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",tscr:"𝓉",Tscr:"𝒯",tscy:"ц",TScy:"Ц",tshcy:"ћ",TSHcy:"Ћ",tstrok:"ŧ",Tstrok:"Ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",uacute:"ú",Uacute:"Ú",uarr:"↑",uArr:"⇑",Uarr:"↟",Uarrocir:"⥉",ubrcy:"ў",Ubrcy:"Ў",ubreve:"ŭ",Ubreve:"Ŭ",ucirc:"û",Ucirc:"Û",ucy:"у",Ucy:"У",udarr:"⇅",udblac:"ű",Udblac:"Ű",udhar:"⥮",ufisht:"⥾",ufr:"𝔲",Ufr:"𝔘",ugrave:"ù",Ugrave:"Ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",umacr:"ū",Umacr:"Ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",uogon:"ų",Uogon:"Ų",uopf:"𝕦",Uopf:"𝕌",uparrow:"↑",Uparrow:"⇑",UpArrow:"↑",UpArrowBar:"⤒",UpArrowDownArrow:"⇅",updownarrow:"↕",Updownarrow:"⇕",UpDownArrow:"↕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",upsilon:"υ",Upsilon:"Υ",UpTee:"⊥",UpTeeArrow:"↥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",uring:"ů",Uring:"Ů",urtri:"◹",uscr:"𝓊",Uscr:"𝒰",utdot:"⋰",utilde:"ũ",Utilde:"Ũ",utri:"▵",utrif:"▴",uuarr:"⇈",uuml:"ü",Uuml:"Ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",vcy:"в",Vcy:"В",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",vee:"∨",Vee:"⋁",veebar:"⊻",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",vfr:"𝔳",Vfr:"𝔙",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",vopf:"𝕧",Vopf:"𝕍",vprop:"∝",vrtri:"⊳",vscr:"𝓋",Vscr:"𝒱",vsubne:"⊊︀",vsubnE:"⫋︀",vsupne:"⊋︀",vsupnE:"⫌︀",Vvdash:"⊪",vzigzag:"⦚",wcirc:"ŵ",Wcirc:"Ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",wfr:"𝔴",Wfr:"𝔚",wopf:"𝕨",Wopf:"𝕎",wp:"℘",wr:"≀",wreath:"≀",wscr:"𝓌",Wscr:"𝒲",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",xfr:"𝔵",Xfr:"𝔛",xharr:"⟷",xhArr:"⟺",xi:"ξ",Xi:"Ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",xopf:"𝕩",Xopf:"𝕏",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",xscr:"𝓍",Xscr:"𝒳",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",yacute:"ý",Yacute:"Ý",yacy:"я",YAcy:"Я",ycirc:"ŷ",Ycirc:"Ŷ",ycy:"ы",Ycy:"Ы",yen:"¥",yfr:"𝔶",Yfr:"𝔜",yicy:"ї",YIcy:"Ї",yopf:"𝕪",Yopf:"𝕐",yscr:"𝓎",Yscr:"𝒴",yucy:"ю",YUcy:"Ю",yuml:"ÿ",Yuml:"Ÿ",zacute:"ź",Zacute:"Ź",zcaron:"ž",Zcaron:"Ž",zcy:"з",Zcy:"З",zdot:"ż",Zdot:"Ż",zeetrf:"ℨ",ZeroWidthSpace:"​",zeta:"ζ",Zeta:"Ζ",zfr:"𝔷",Zfr:"ℨ",zhcy:"ж",ZHcy:"Ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",zscr:"𝓏",Zscr:"𝒵",zwj:"‍",zwnj:"‌"},m={aacute:"á",Aacute:"Á",acirc:"â",Acirc:"Â",acute:"´",aelig:"æ",AElig:"Æ",agrave:"à",Agrave:"À",amp:"&",AMP:"&",aring:"å",Aring:"Å",atilde:"ã",Atilde:"Ã",auml:"ä",Auml:"Ä",brvbar:"¦",ccedil:"ç",Ccedil:"Ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",eacute:"é",Eacute:"É",ecirc:"ê",Ecirc:"Ê",egrave:"è",Egrave:"È",eth:"ð",ETH:"Ð",euml:"ë",Euml:"Ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",iacute:"í",Iacute:"Í",icirc:"î",Icirc:"Î",iexcl:"¡",igrave:"ì",Igrave:"Ì",iquest:"¿",iuml:"ï",Iuml:"Ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",ntilde:"ñ",Ntilde:"Ñ",oacute:"ó",Oacute:"Ó",ocirc:"ô",Ocirc:"Ô",ograve:"ò",Ograve:"Ò",ordf:"ª",ordm:"º",oslash:"ø",Oslash:"Ø",otilde:"õ",Otilde:"Õ",ouml:"ö",Ouml:"Ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",thorn:"þ",THORN:"Þ",times:"×",uacute:"ú",Uacute:"Ú",ucirc:"û",Ucirc:"Û",ugrave:"ù",Ugrave:"Ù",uml:"¨",uuml:"ü",Uuml:"Ü",yacute:"ý",Yacute:"Ý",yen:"¥",yuml:"ÿ"},v={0:"�",128:"€",130:"‚",131:"ƒ",132:"„",133:"…",134:"†",135:"‡",136:"ˆ",137:"‰",138:"Š",139:"‹",140:"Œ",142:"Ž",145:"‘",146:"’",147:"“",148:"”",149:"•",150:"–",151:"—",152:"˜",153:"™",154:"š",155:"›",156:"œ",158:"ž",159:"Ÿ"},_=[1,2,3,4,5,6,7,8,11,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986,64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999,65e3,65001,65002,65003,65004,65005,65006,65007,65534,65535,131070,131071,196606,196607,262142,262143,327678,327679,393214,393215,458750,458751,524286,524287,589822,589823,655358,655359,720894,720895,786430,786431,851966,851967,917502,917503,983038,983039,1048574,1048575,1114110,1114111],w=String.fromCharCode,x={}.hasOwnProperty,k=function(t,e){return x.call(t,e)},E=function(t,e){if(!t)return e;var n,r={};for(n in e)r[n]=k(t,n)?t[n]:e[n];return r},A=function(t,e){var n="";return t>=55296&&t<=57343||t>1114111?(e&&M("character reference outside the permissible Unicode range"),"�"):k(v,t)?(e&&M("disallowed character reference"),v[t]):(e&&function(t,e){for(var n=-1,r=t.length;++n65535&&(n+=w((t-=65536)>>>10&1023|55296),t=56320|1023&t),n+=w(t))},S=function(t){return"&#x"+t.toString(16).toUpperCase()+";"},T=function(t){return"&#"+t+";"},M=function(t){throw Error("Parse error: "+t)},D=function(t,e){(e=E(e,D.options)).strict&&g.test(t)&&M("forbidden code point");var n=e.encodeEverything,r=e.useNamedReferences,i=e.allowUnsafeSymbols,o=e.decimal?T:S,a=function(t){return o(t.charCodeAt(0))};return n?(t=t.replace(u,(function(t){return r&&k(l,t)?"&"+l[t]+";":a(t)})),r&&(t=t.replace(/>\u20D2/g,">⃒").replace(/<\u20D2/g,"<⃒").replace(/fj/g,"fj")),r&&(t=t.replace(f,(function(t){return"&"+l[t]+";"})))):r?(i||(t=t.replace(h,(function(t){return"&"+l[t]+";"}))),t=(t=t.replace(/>\u20D2/g,">⃒").replace(/<\u20D2/g,"<⃒")).replace(f,(function(t){return"&"+l[t]+";"}))):i||(t=t.replace(h,a)),t.replace(s,(function(t){var e=t.charCodeAt(0),n=t.charCodeAt(1);return o(1024*(e-55296)+n-56320+65536)})).replace(c,a)};D.options={allowUnsafeSymbols:!1,encodeEverything:!1,strict:!1,useNamedReferences:!1,decimal:!1};var C=function(t,e){var n=(e=E(e,C.options)).strict;return n&&p.test(t)&&M("malformed character reference"),t.replace(y,(function(t,r,i,o,a,s,u,c,f){var l,h,d,p,g,y;return r?b[g=r]:i?(g=i,(y=o)&&e.isAttributeValue?(n&&"="==y&&M("`&` did not start a character reference"),t):(n&&M("named character reference was not terminated by a semicolon"),m[g]+(y||""))):a?(d=a,h=s,n&&!h&&M("character reference was not terminated by a semicolon"),l=parseInt(d,10),A(l,n)):u?(p=u,h=c,n&&!h&&M("character reference was not terminated by a semicolon"),l=parseInt(p,16),A(l,n)):(n&&M("named character reference was not terminated by a semicolon"),t)}))};C.options={isAttributeValue:!1,strict:!1};var O={version:"1.2.0",encode:D,decode:C,escape:function(t){return t.replace(h,(function(t){return d[t]}))},unescape:C};if("function"==typeof define&&"object"==typeof define.amd&&define.amd)define((function(){return O}));else if(i&&!i.nodeType)if(o)o.exports=O;else for(var R in O)k(O,R)&&(i[R]=O[R]);else r.he=O}(this)}).call(this,n(9)(t),n(11))},function(t,e,n){"use strict";var r=n(229),i=n(230),o=n(231);function a(t,e,n){if(!t)return t;if(!e)return t;"string"==typeof n&&(n={keyframes:n}),n||(n={keyframes:!1}),t=s(t,e+" $1$2");var i=e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&");t=(t=(t=(t=t.replace(new RegExp("("+i+")\\s*\\1(?=[\\s\\r\\n,{])","g"),"$1")).replace(new RegExp("("+i+")\\s*:host","g"),"$1")).replace(new RegExp("("+i+")\\s*@","g"),"@")).replace(new RegExp("("+i+")\\s*:root","g"),":root");for(var o,a=[],u=/@keyframes\s+([a-zA-Z0-9_-]+)\s*{/g;null!==(o=u.exec(t));)a.indexOf(o[1])<0&&a.push(o[1]);var c=r(e);return a.forEach((function(e){var r=(!0===n.keyframes?c+"-":"string"==typeof n.keyframes?n.keyframes:"")+e;t=(t=t.replace(new RegExp("(@keyframes\\s+)"+e+"(\\s*{)","g"),"$1"+r+"$2")).replace(new RegExp("(animation(?:-name)?\\s*:[^;]*\\s*)"+e+"([\\s;}])","g"),"$1"+r+"$2")})),t=t.replace(new RegExp("("+i+" )(\\s*(?:to|from|[+-]?(?:(?:\\.\\d+)|(?:\\d+(?:\\.\\d*)?))%))(?=[\\s\\r\\n,{])","g"),"$2")}function s(t,e){var n=[];return t=o(t),t=(t=i.replace(t,!0,n)).replace(/([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/g,e),t=i.paste(t,n)}t.exports=a,a.replace=s},function(t,e,n){"use strict";const r=n(418),i="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~".split(""),o=(t,e)=>{const n=e.length,i=Math.floor(65536/n)*n-1,o=2*Math.ceil(1.1*t);let a="",s=0;for(;si||(a+=e[t%n],s++)}}return a},a=[void 0,"hex","base64","url-safe"];t.exports=({length:t,type:e,characters:n})=>{if(!(t>=0&&Number.isFinite(t)))throw new TypeError("Expected a `length` to be a non-negative finite number");if(void 0!==e&&void 0!==n)throw new TypeError("Expected either `type` or `characters`");if(void 0!==n&&"string"!=typeof n)throw new TypeError("Expected `characters` to be string");if(!a.includes(e))throw new TypeError(`Unknown type: ${e}`);if(void 0===e&&void 0===n&&(e="hex"),"hex"===e||void 0===e&&void 0===n)return r.randomBytes(Math.ceil(.5*t)).toString("hex").slice(0,t);if("base64"===e)return r.randomBytes(Math.ceil(.75*t)).toString("base64").slice(0,t);if("url-safe"===e)return o(t,i);if(0===n.length)throw new TypeError("Expected `characters` string length to be greater than or equal to 1");if(n.length>65536)throw new TypeError("Expected `characters` string length to be less or equal to 65536");return o(t,n.split(""))}},function(t,e,n){var r;r=function(){var t=JSON.parse('{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","џ":"dz","Ґ":"G","ґ":"g","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","‘":"\'","’":"\'","“":"\\"","”":"\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₹":"indian rupee","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial"}'),e=JSON.parse('{"bg":{"locale":"Bulgarian","ѝ":"u"}}');function n(n,r){if("string"!=typeof n)throw new Error("slugify: string argument expected");var i=e[(r="string"==typeof r?{replacement:r}:r||{}).locale]||{},o=n.split("").reduce((function(e,n){return e+(i[n]||t[n]||n).replace(r.remove||/[^\w\s$*_+~.()'"!\-:@]/g,"")}),"").trim().replace(/[-\s]+/g,r.replacement||"-");return r.lower?o.toLowerCase():o}return n.extend=function(e){for(var n in e)t[n]=e[n]},n},t.exports=r(),t.exports.default=r()},function(t,e,n){ -/*! - * Escaper v2.5.3 - * https://github.com/kobezzza/Escaper - * - * Released under the MIT license - * https://github.com/kobezzza/Escaper/blob/master/LICENSE - * - * Date: Tue, 23 Jan 2018 15:58:45 GMT - */ -!function(t){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n=void 0,r=n={VERSION:[2,5,3],content:[],cache:{},snakeskinRgxp:null,symbols:null,replace:M,paste:C},i={'"':!0,"'":!0,"`":!0},o={"/":!0};for(var a in i){if(!i.hasOwnProperty(a))break;o[a]=!0}var s={"//":!0,"//*":!0,"//!":!0,"//#":!0,"//@":!0,"//$":!0},u={"/*":!0,"/**":!0,"/*!":!0,"/*#":!0,"/*@":!0,"/*$":!0},c=[],f={};for(var l in o){if(!o.hasOwnProperty(l))break;c.push(l),f[l]=!0}for(var h in s){if(!s.hasOwnProperty(h))break;c.push(h),f[h]=!0}for(var d in u){if(!u.hasOwnProperty(d))break;c.push(d),f[d]=!0}var p=[],g={g:!0,m:!0,i:!0,y:!0,u:!0};for(var y in g){if(!g.hasOwnProperty(y))break;p.push(y)}var b={"-":!0,"+":!0,"*":!0,"%":!0,"~":!0,">":!0,"<":!0,"^":!0,",":!0,";":!0,"=":!0,"|":!0,"&":!0,"!":!0,"?":!0,":":!0,"(":!0,"{":!0,"[":!0},m={return:!0,yield:!0,await:!0,typeof:!0,void:!0,instanceof:!0,delete:!0,in:!0,new:!0,of:!0};function v(t,e,n){for(var r in t){if(!t.hasOwnProperty(r))break;r in e==0&&(e[r]=n)}}var _=void 0,w=void 0,x=/[^\s/]/,k=/[a-z]/,E=/\s/,A=/[\r\n]/,S=/\${pos}/g,T={object:!0,function:!0};function M(t,r,a,l){_=_||n.symbols||"a-z",w=w||n.snakeskinRgxp||new RegExp("[!$"+_+"_]","i");var h=n,d=h.cache,y=h.content,M=Boolean(r&&T[void 0===r?"undefined":e(r)]),D=M?Object(r):{};function C(t){return D["@label"]?D["@label"].replace(S,t):"__ESCAPER_QUOT__"+t+"_"}var O=!1;"boolean"==typeof r&&(O=Boolean(r)),"@comments"in D&&(v(u,D,D["@comments"]),v(s,D,D["@comments"]),delete D["@comments"]),"@strings"in D&&(v(i,D,D["@strings"]),delete D["@strings"]),"@literals"in D&&(v(o,D,D["@literals"]),delete D["@literals"]),"@all"in D&&(v(f,D,D["@all"]),delete D["@all"]);for(var R="",I=-1;++I2&&u[j])&&(D[j]&&(H=t.substring(U,K+1),-1===D[j]?$="":($=C(L.length),L.push(H)),t=t.substring(0,U)+$+t.substring(K+1),K+=$.length-H.length),j=!1);else{if(!P){if("/"===X&&((s[J]||u[J])&&(j=s[Q]||u[Q]?Q:J),j)){U=K;continue}b[X]||m[W]?(F=!0,W=""):x.test(X)&&(F=!1),k.test(X)?G+=X:(W=G,G="");var tt=!1;l&&("|"===X&&w.test(Z)?(V=!0,F=!1,tt=!0):V&&E.test(X)&&(V=!1,F=!0,tt=!0)),tt||(b[X]?F=!0:x.test(X)&&(F=!1))}if("/"!==P||q||("["===X?z=!0:"]"===X&&(z=!1)),!P&&Y&&("}"===X?Y--:"{"===X&&Y++,Y||(X="`")),"`"!==P||q||"${"!==J||(X="`",K++,Y++),!f[X]||"/"===X&&!F||P){if(P&&("\\"===X||q))q=!q;else if(f[X]&&P===X&&!q&&("/"!==P||!z)){if("/"===X)for(var et=-1;++et-1}},function(t,e,n){var r=n(63);t.exports=function(t,e){var n=this.__data__,i=r(n,t);return i<0?(++this.size,n.push([t,e])):n[i][1]=e,this}},function(t,e,n){var r=n(62);t.exports=function(){this.__data__=new r,this.size=0}},function(t,e){t.exports=function(t){var e=this.__data__,n=e.delete(t);return this.size=e.size,n}},function(t,e){t.exports=function(t){return this.__data__.get(t)}},function(t,e){t.exports=function(t){return this.__data__.has(t)}},function(t,e,n){var r=n(62),i=n(90),o=n(91),a=200;t.exports=function(t,e){var n=this.__data__;if(n instanceof r){var s=n.__data__;if(!i||s.length0){if(++e>=n)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}},function(t,e,n){var r=n(153),i=n(327),o=n(331),a=n(154),s=n(332),u=n(103),c=200;t.exports=function(t,e,n){var f=-1,l=i,h=t.length,d=!0,p=[],g=p;if(n)d=!1,l=o;else if(h>=c){var y=e?null:s(t);if(y)return u(y);d=!1,l=a,g=new r}else g=e?[]:p;t:for(;++f-1}},function(t,e,n){var r=n(167),i=n(329),o=n(330);t.exports=function(t,e,n){return e==e?o(t,e,n):r(t,i,n)}},function(t,e){t.exports=function(t){return t!=t}},function(t,e){t.exports=function(t,e,n){for(var r=n-1,i=t.length;++r1||1===e.length&&t.hasEdge(e[0],e[0])}))}},function(t,e,n){var r=n(12);t.exports=function(t,e,n){return function(t,e,n){var r={},i=t.nodes();return i.forEach((function(t){r[t]={},r[t][t]={distance:0},i.forEach((function(e){t!==e&&(r[t][e]={distance:Number.POSITIVE_INFINITY})})),n(t).forEach((function(n){var i=n.v===t?n.w:n.v,o=e(n);r[t][i]={distance:o,predecessor:t}}))})),i.forEach((function(t){var e=r[t];i.forEach((function(n){var o=r[n];i.forEach((function(n){var r=o[t],i=e[n],a=o[n],s=r.distance+i.distance;s0;){if(n=u.removeMin(),r.has(s,n))a.setEdge(n,s[n]);else{if(f)throw new Error("Input graph is not connected: "+t);f=!0}t.nodeEdges(n).forEach(c)}return a}},function(t,e,n){var r;try{r=n(22)}catch(t){}r||(r=window.graphlib),t.exports=r},function(t,e,n){"use strict";var r=n(4),i=n(380),o=n(383),a=n(384),s=n(10).normalizeRanks,u=n(386),c=n(10).removeEmptyRanks,f=n(387),l=n(388),h=n(389),d=n(390),p=n(399),g=n(10),y=n(19).Graph;t.exports=function(t,e){var n=e&&e.debugTiming?g.time:g.notime;n("layout",(function(){var e=n(" buildLayoutGraph",(function(){return function(t){var e=new y({multigraph:!0,compound:!0}),n=S(t.graph());return e.setGraph(r.merge({},m,A(n,b),r.pick(n,v))),r.forEach(t.nodes(),(function(n){var i=S(t.node(n));e.setNode(n,r.defaults(A(i,_),w)),e.setParent(n,t.parent(n))})),r.forEach(t.edges(),(function(n){var i=S(t.edge(n));e.setEdge(n,r.merge({},k,A(i,x),r.pick(i,E)))})),e}(t)}));n(" runLayout",(function(){!function(t,e){e(" makeSpaceForEdgeLabels",(function(){!function(t){var e=t.graph();e.ranksep/=2,r.forEach(t.edges(),(function(n){var r=t.edge(n);r.minlen*=2,"c"!==r.labelpos.toLowerCase()&&("TB"===e.rankdir||"BT"===e.rankdir?r.width+=r.labeloffset:r.height+=r.labeloffset)}))}(t)})),e(" removeSelfEdges",(function(){!function(t){r.forEach(t.edges(),(function(e){if(e.v===e.w){var n=t.node(e.v);n.selfEdges||(n.selfEdges=[]),n.selfEdges.push({e:e,label:t.edge(e)}),t.removeEdge(e)}}))}(t)})),e(" acyclic",(function(){i.run(t)})),e(" nestingGraph.run",(function(){f.run(t)})),e(" rank",(function(){a(g.asNonCompoundGraph(t))})),e(" injectEdgeLabelProxies",(function(){!function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);if(n.width&&n.height){var r=t.node(e.v),i={rank:(t.node(e.w).rank-r.rank)/2+r.rank,e:e};g.addDummyNode(t,"edge-proxy",i,"_ep")}}))}(t)})),e(" removeEmptyRanks",(function(){c(t)})),e(" nestingGraph.cleanup",(function(){f.cleanup(t)})),e(" normalizeRanks",(function(){s(t)})),e(" assignRankMinMax",(function(){!function(t){var e=0;r.forEach(t.nodes(),(function(n){var i=t.node(n);i.borderTop&&(i.minRank=t.node(i.borderTop).rank,i.maxRank=t.node(i.borderBottom).rank,e=r.max(e,i.maxRank))})),t.graph().maxRank=e}(t)})),e(" removeEdgeLabelProxies",(function(){!function(t){r.forEach(t.nodes(),(function(e){var n=t.node(e);"edge-proxy"===n.dummy&&(t.edge(n.e).labelRank=n.rank,t.removeNode(e))}))}(t)})),e(" normalize.run",(function(){o.run(t)})),e(" parentDummyChains",(function(){u(t)})),e(" addBorderSegments",(function(){l(t)})),e(" order",(function(){d(t)})),e(" insertSelfEdges",(function(){!function(t){var e=g.buildLayerMatrix(t);r.forEach(e,(function(e){var n=0;r.forEach(e,(function(e,i){var o=t.node(e);o.order=i+n,r.forEach(o.selfEdges,(function(e){g.addDummyNode(t,"selfedge",{width:e.label.width,height:e.label.height,rank:o.rank,order:i+ ++n,e:e.e,label:e.label},"_se")})),delete o.selfEdges}))}))}(t)})),e(" adjustCoordinateSystem",(function(){h.adjust(t)})),e(" position",(function(){p(t)})),e(" positionSelfEdges",(function(){!function(t){r.forEach(t.nodes(),(function(e){var n=t.node(e);if("selfedge"===n.dummy){var r=t.node(n.e.v),i=r.x+r.width/2,o=r.y,a=n.x-i,s=r.height/2;t.setEdge(n.e,n.label),t.removeNode(e),n.label.points=[{x:i+2*a/3,y:o-s},{x:i+5*a/6,y:o-s},{x:i+a,y:o},{x:i+5*a/6,y:o+s},{x:i+2*a/3,y:o+s}],n.label.x=n.x,n.label.y=n.y}}))}(t)})),e(" removeBorderNodes",(function(){!function(t){r.forEach(t.nodes(),(function(e){if(t.children(e).length){var n=t.node(e),i=t.node(n.borderTop),o=t.node(n.borderBottom),a=t.node(r.last(n.borderLeft)),s=t.node(r.last(n.borderRight));n.width=Math.abs(s.x-a.x),n.height=Math.abs(o.y-i.y),n.x=a.x+n.width/2,n.y=i.y+n.height/2}})),r.forEach(t.nodes(),(function(e){"border"===t.node(e).dummy&&t.removeNode(e)}))}(t)})),e(" normalize.undo",(function(){o.undo(t)})),e(" fixupEdgeLabelCoords",(function(){!function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);if(r.has(n,"x"))switch("l"!==n.labelpos&&"r"!==n.labelpos||(n.width-=n.labeloffset),n.labelpos){case"l":n.x-=n.width/2+n.labeloffset;break;case"r":n.x+=n.width/2+n.labeloffset}}))}(t)})),e(" undoCoordinateSystem",(function(){h.undo(t)})),e(" translateGraph",(function(){!function(t){var e=Number.POSITIVE_INFINITY,n=0,i=Number.POSITIVE_INFINITY,o=0,a=t.graph(),s=a.marginx||0,u=a.marginy||0;function c(t){var r=t.x,a=t.y,s=t.width,u=t.height;e=Math.min(e,r-s/2),n=Math.max(n,r+s/2),i=Math.min(i,a-u/2),o=Math.max(o,a+u/2)}r.forEach(t.nodes(),(function(e){c(t.node(e))})),r.forEach(t.edges(),(function(e){var n=t.edge(e);r.has(n,"x")&&c(n)})),e-=s,i-=u,r.forEach(t.nodes(),(function(n){var r=t.node(n);r.x-=e,r.y-=i})),r.forEach(t.edges(),(function(n){var o=t.edge(n);r.forEach(o.points,(function(t){t.x-=e,t.y-=i})),r.has(o,"x")&&(o.x-=e),r.has(o,"y")&&(o.y-=i)})),a.width=n-e+s,a.height=o-i+u}(t)})),e(" assignNodeIntersects",(function(){!function(t){r.forEach(t.edges(),(function(e){var n,r,i=t.edge(e),o=t.node(e.v),a=t.node(e.w);i.points?(n=i.points[0],r=i.points[i.points.length-1]):(i.points=[],n=a,r=o),i.points.unshift(g.intersectRect(o,n)),i.points.push(g.intersectRect(a,r))}))}(t)})),e(" reversePoints",(function(){!function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);n.reversed&&n.points.reverse()}))}(t)})),e(" acyclic.undo",(function(){i.undo(t)}))}(e,n)})),n(" updateInputGraph",(function(){!function(t,e){r.forEach(t.nodes(),(function(n){var r=t.node(n),i=e.node(n);r&&(r.x=i.x,r.y=i.y,e.children(n).length&&(r.width=i.width,r.height=i.height))})),r.forEach(t.edges(),(function(n){var i=t.edge(n),o=e.edge(n);i.points=o.points,r.has(o,"x")&&(i.x=o.x,i.y=o.y)})),t.graph().width=e.graph().width,t.graph().height=e.graph().height}(t,e)}))}))};var b=["nodesep","edgesep","ranksep","marginx","marginy"],m={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},v=["acyclicer","ranker","rankdir","align"],_=["width","height"],w={width:0,height:0},x=["minlen","weight","width","height","labeloffset"],k={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},E=["labelpos"];function A(t,e){return r.mapValues(r.pick(t,e),Number)}function S(t){var e={};return r.forEach(t,(function(t,n){e[n.toLowerCase()]=t})),e}},function(t,e,n){var r=n(130),i=1,o=4;t.exports=function(t){return r(t,i|o)}},function(t,e,n){var r=n(350)(n(351));t.exports=r},function(t,e,n){var r=n(25),i=n(24),o=n(27);t.exports=function(t){return function(e,n,a){var s=Object(e);if(!i(e)){var u=r(n,3);e=o(e),n=function(t){return u(s[t],t,s)}}var c=t(e,n,a);return c>-1?s[u?e[c]:c]:void 0}}},function(t,e,n){var r=n(167),i=n(25),o=n(352),a=Math.max;t.exports=function(t,e,n){var s=null==t?0:t.length;if(!s)return-1;var u=null==n?0:o(n);return u<0&&(u=a(s+u,0)),r(t,i(e,3),u)}},function(t,e,n){var r=n(177);t.exports=function(t){var e=r(t),n=e%1;return e==e?n?e-n:e:0}},function(t,e,n){var r=n(13),i=n(42),o=NaN,a=/^\s+|\s+$/g,s=/^[-+]0x[0-9a-f]+$/i,u=/^0b[01]+$/i,c=/^0o[0-7]+$/i,f=parseInt;t.exports=function(t){if("number"==typeof t)return t;if(i(t))return o;if(r(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=r(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(a,"");var n=u.test(t);return n||c.test(t)?f(t.slice(2),n?2:8):s.test(t)?o:+t}},function(t,e,n){var r=n(102),i=n(149),o=n(40);t.exports=function(t,e){return null==t?t:r(t,i(e),o)}},function(t,e){t.exports=function(t){var e=null==t?0:t.length;return e?t[e-1]:void 0}},function(t,e,n){var r=n(67),i=n(101),o=n(25);t.exports=function(t,e){var n={};return e=o(e,3),i(t,(function(t,i,o){r(n,i,e(t,i,o))})),n}},function(t,e,n){var r=n(108),i=n(358),o=n(34);t.exports=function(t){return t&&t.length?r(t,o,i):void 0}},function(t,e){t.exports=function(t,e){return t>e}},function(t,e,n){var r=n(360),i=n(363)((function(t,e,n){r(t,e,n)}));t.exports=i},function(t,e,n){var r=n(61),i=n(179),o=n(102),a=n(361),s=n(13),u=n(40),c=n(181);t.exports=function t(e,n,f,l,h){e!==n&&o(n,(function(o,u){if(h||(h=new r),s(o))a(e,n,u,f,t,l,h);else{var d=l?l(c(e,u),o,u+"",e,n,h):void 0;void 0===d&&(d=o),i(e,u,d)}}),u)}},function(t,e,n){var r=n(179),i=n(136),o=n(145),a=n(137),s=n(146),u=n(50),c=n(6),f=n(168),l=n(39),h=n(37),d=n(13),p=n(180),g=n(51),y=n(181),b=n(362);t.exports=function(t,e,n,m,v,_,w){var x=y(t,n),k=y(e,n),E=w.get(k);if(E)r(t,n,E);else{var A=_?_(x,k,n+"",t,e,w):void 0,S=void 0===A;if(S){var T=c(k),M=!T&&l(k),D=!T&&!M&&g(k);A=k,T||M||D?c(x)?A=x:f(x)?A=a(x):M?(S=!1,A=i(k,!0)):D?(S=!1,A=o(k,!0)):A=[]:p(k)||u(k)?(A=x,u(x)?A=b(x):d(x)&&!h(x)||(A=s(k))):S=!1}S&&(w.set(k,A),v(A,k,m,_,w),w.delete(k)),r(t,n,A)}}},function(t,e,n){var r=n(49),i=n(40);t.exports=function(t){return r(t,i(t))}},function(t,e,n){var r=n(75),i=n(76);t.exports=function(t){return r((function(e,n){var r=-1,o=n.length,a=o>1?n[o-1]:void 0,s=o>2?n[2]:void 0;for(a=t.length>3&&"function"==typeof a?(o--,a):void 0,s&&i(n[0],n[1],s)&&(a=o<3?void 0:a,o=1),e=Object(e);++r1&&a(t,e[0],e[1])?e=[]:n>2&&a(e[0],e[1],e[2])&&(e=[e[0]]),i(t,r(e,1),[])}));t.exports=s},function(t,e,n){var r=n(74),i=n(25),o=n(163),a=n(375),s=n(69),u=n(376),c=n(34);t.exports=function(t,e,n){var f=-1;e=r(e.length?e:[c],s(i));var l=o(t,(function(t,n,i){return{criteria:r(e,(function(e){return e(t)})),index:++f,value:t}}));return a(l,(function(t,e){return u(t,e,n)}))}},function(t,e){t.exports=function(t,e){var n=t.length;for(t.sort(e);n--;)t[n]=t[n].value;return t}},function(t,e,n){var r=n(377);t.exports=function(t,e,n){for(var i=-1,o=t.criteria,a=e.criteria,s=o.length,u=n.length;++i=u?c:c*("desc"==n[i]?-1:1)}return t.index-e.index}},function(t,e,n){var r=n(42);t.exports=function(t,e){if(t!==e){var n=void 0!==t,i=null===t,o=t==t,a=r(t),s=void 0!==e,u=null===e,c=e==e,f=r(e);if(!u&&!f&&!a&&t>e||a&&s&&c&&!u&&!f||i&&s&&c||!n&&c||!o)return 1;if(!i&&!a&&!f&&t0;--u)if(r=e[u].dequeue()){i=i.concat(s(t,e,n,r,!0));break}}return i}(n.graph,n.buckets,n.zeroIdx);return r.flatten(r.map(c,(function(e){return t.outEdges(e.v,e.w)})),!0)};var a=r.constant(1);function s(t,e,n,i,o){var a=o?[]:void 0;return r.forEach(t.inEdges(i.v),(function(r){var i=t.edge(r),s=t.node(r.v);o&&a.push({v:r.v,w:r.w}),s.out-=i,u(e,n,s)})),r.forEach(t.outEdges(i.v),(function(r){var i=t.edge(r),o=r.w,a=t.node(o);a.in-=i,u(e,n,a)})),t.removeNode(i.v),a}function u(t,e,n){n.out?n.in?t[n.out-n.in+e].enqueue(n):t[t.length-1].enqueue(n):t[0].enqueue(n)}},function(t,e){function n(){var t={};t._next=t._prev=t,this._sentinel=t}function r(t){t._prev._next=t._next,t._next._prev=t._prev,delete t._next,delete t._prev}function i(t,e){if("_next"!==t&&"_prev"!==t)return e}t.exports=n,n.prototype.dequeue=function(){var t=this._sentinel,e=t._prev;if(e!==t)return r(e),e},n.prototype.enqueue=function(t){var e=this._sentinel;t._prev&&t._next&&r(t),t._next=e._next,e._next._prev=t,e._next=t,t._prev=e},n.prototype.toString=function(){for(var t=[],e=this._sentinel,n=e._prev;n!==e;)t.push(JSON.stringify(n,i)),n=n._prev;return"["+t.join(", ")+"]"}},function(t,e,n){"use strict";var r=n(4),i=n(10);t.exports={run:function(t){t.graph().dummyChains=[],r.forEach(t.edges(),(function(e){!function(t,e){var n,r,o,a=e.v,s=t.node(a).rank,u=e.w,c=t.node(u).rank,f=e.name,l=t.edge(e),h=l.labelRank;if(c===s+1)return;for(t.removeEdge(e),o=0,++s;su.lim&&(c=u,f=!0);var l=r.filter(e.edges(),(function(e){return f===b(t,t.node(e.v),c)&&f!==b(t,t.node(e.w),c)}));return r.minBy(l,(function(t){return o(e,t)}))}function y(t,e,n,i){var o=n.v,a=n.w;t.removeEdge(o,a),t.setEdge(i.v,i.w,{}),d(t),l(t,e),function(t,e){var n=r.find(t.nodes(),(function(t){return!e.node(t).parent})),i=s(t,n);i=i.slice(1),r.forEach(i,(function(n){var r=t.node(n).parent,i=e.edge(n,r),o=!1;i||(i=e.edge(r,n),o=!0),e.node(n).rank=e.node(r).rank+(o?i.minlen:-i.minlen)}))}(t,e)}function b(t,e,n){return n.low<=e.lim&&e.lim<=n.lim}t.exports=f,f.initLowLimValues=d,f.initCutValues=l,f.calcCutValue=h,f.leaveEdge=p,f.enterEdge=g,f.exchangeEdges=y},function(t,e,n){var r=n(4);t.exports=function(t){var e=function(t){var e={},n=0;return r.forEach(t.children(),(function i(o){var a=n;r.forEach(t.children(o),i);e[o]={low:a,lim:n++}})),e}(t);r.forEach(t.graph().dummyChains,(function(n){for(var r=t.node(n),i=r.edgeObj,o=function(t,e,n,r){var i,o,a=[],s=[],u=Math.min(e[n].low,e[r].low),c=Math.max(e[n].lim,e[r].lim);i=n;do{i=t.parent(i),a.push(i)}while(i&&(e[i].low>u||c>e[i].lim));o=i,i=r;for(;(i=t.parent(i))!==o;)s.push(i);return{path:a.concat(s.reverse()),lca:o}}(t,e,i.v,i.w),a=o.path,s=o.lca,u=0,c=a[u],f=!0;n!==i.w;){if(r=t.node(n),f){for(;(c=a[u])!==s&&t.node(c).maxRank=2),s=f.buildLayerMatrix(t);var y=o(t,s);y0;)e%2&&(n+=u[e+1]),u[e=e-1>>1]+=t.weight;c+=t.weight*n}))),c}t.exports=function(t,e){for(var n=0,r=1;r=t.barycenter)&&function(t,e){var n=0,r=0;t.weight&&(n+=t.barycenter*t.weight,r+=t.weight);e.weight&&(n+=e.barycenter*e.weight,r+=e.weight);t.vs=e.vs.concat(t.vs),t.barycenter=n/r,t.weight=r,t.i=Math.min(e.i,t.i),e.merged=!0}(t,e)}}function i(e){return function(n){n.in.push(e),0==--n.indegree&&t.push(n)}}for(;t.length;){var o=t.pop();e.push(o),r.forEach(o.in.reverse(),n(o)),r.forEach(o.out,i(o))}return r.map(r.filter(e,(function(t){return!t.merged})),(function(t){return r.pick(t,["vs","i","barycenter","weight"])}))}(r.filter(n,(function(t){return!t.indegree})))}},function(t,e,n){var r=n(4),i=n(10);function o(t,e,n){for(var i;e.length&&(i=r.last(e)).i<=n;)e.pop(),t.push(i.vs),n++;return n}t.exports=function(t,e){var n=i.partition(t,(function(t){return r.has(t,"barycenter")})),a=n.lhs,s=r.sortBy(n.rhs,(function(t){return-t.i})),u=[],c=0,f=0,l=0;a.sort((h=!!e,function(t,e){return t.barycentere.barycenter?1:h?e.i-t.i:t.i-e.i})),l=o(u,s,l),r.forEach(a,(function(t){l+=t.vs.length,u.push(t.vs),c+=t.barycenter*t.weight,f+=t.weight,l=o(u,s,l)}));var h;var d={vs:r.flatten(u,!0)};f&&(d.barycenter=c/f,d.weight=f);return d}},function(t,e,n){var r=n(4),i=n(19).Graph;t.exports=function(t,e,n){var o=function(t){var e;for(;t.hasNode(e=r.uniqueId("_root")););return e}(t),a=new i({compound:!0}).setGraph({root:o}).setDefaultNodeLabel((function(e){return t.node(e)}));return r.forEach(t.nodes(),(function(i){var s=t.node(i),u=t.parent(i);(s.rank===e||s.minRank<=e&&e<=s.maxRank)&&(a.setNode(i),a.setParent(i,u||o),r.forEach(t[n](i),(function(e){var n=e.v===i?e.w:e.v,o=a.edge(n,i),s=r.isUndefined(o)?0:o.weight;a.setEdge(n,i,{weight:t.edge(e).weight+s})})),r.has(s,"minRank")&&a.setNode(i,{borderLeft:s.borderLeft[e],borderRight:s.borderRight[e]}))})),a}},function(t,e,n){var r=n(4);t.exports=function(t,e,n){var i,o={};r.forEach(n,(function(n){for(var r,a,s=t.parent(n);s;){if((r=t.parent(s))?(a=o[r],o[r]=s):(a=i,i=s),a&&a!==s)return void e.setEdge(a,s);s=r}}))}},function(t,e,n){"use strict";var r=n(4),i=n(10),o=n(400).positionX;t.exports=function(t){(function(t){var e=i.buildLayerMatrix(t),n=t.graph().ranksep,o=0;r.forEach(e,(function(e){var i=r.max(r.map(e,(function(e){return t.node(e).height})));r.forEach(e,(function(e){t.node(e).y=o+i/2})),o+=i+n}))})(t=i.asNonCompoundGraph(t)),r.forEach(o(t),(function(e,n){t.node(n).x=e}))}},function(t,e,n){"use strict";var r=n(4),i=n(19).Graph,o=n(10);function a(t,e){var n={};return r.reduce(e,(function(e,i){var o=0,a=0,s=e.length,c=r.last(i);return r.forEach(i,(function(e,f){var l=function(t,e){if(t.node(e).dummy)return r.find(t.predecessors(e),(function(e){return t.node(e).dummy}))}(t,e),h=l?t.node(l).order:s;(l||e===c)&&(r.forEach(i.slice(a,f+1),(function(e){r.forEach(t.predecessors(e),(function(r){var i=t.node(r),a=i.order;!(as)&&u(n,e,c)}))}))}return r.reduce(e,(function(e,n){var o,a=-1,s=0;return r.forEach(n,(function(r,u){if("border"===t.node(r).dummy){var c=t.predecessors(r);c.length&&(o=t.node(c[0]).order,i(n,s,u,a,o),s=u,a=o)}i(n,s,n.length,o,e.length)})),n})),n}function u(t,e,n){if(e>n){var r=e;e=n,n=r}var i=t[e];i||(t[e]=i={}),i[n]=!0}function c(t,e,n){if(e>n){var i=e;e=n,n=i}return r.has(t[e],n)}function f(t,e,n,i){var o={},a={},s={};return r.forEach(e,(function(t){r.forEach(t,(function(t,e){o[t]=t,a[t]=t,s[t]=e}))})),r.forEach(e,(function(t){var e=-1;r.forEach(t,(function(t){var u=i(t);if(u.length)for(var f=((u=r.sortBy(u,(function(t){return s[t]}))).length-1)/2,l=Math.floor(f),h=Math.ceil(f);l<=h;++l){var d=u[l];a[t]===t&&e0}t.exports=function(t,e,r,i){var o,a,s,u,c,f,l,h,d,p,g,y,b;if(o=e.y-t.y,s=t.x-e.x,c=e.x*t.y-t.x*e.y,d=o*r.x+s*r.y+c,p=o*i.x+s*i.y+c,0!==d&&0!==p&&n(d,p))return;if(a=i.y-r.y,u=r.x-i.x,f=i.x*r.y-r.x*i.y,l=a*t.x+u*t.y+f,h=a*e.x+u*e.y+f,0!==l&&0!==h&&n(l,h))return;if(0===(g=o*u-a*s))return;return y=Math.abs(g/2),{x:(b=s*f-u*c)<0?(b-y)/g:(b+y)/g,y:(b=a*c-o*f)<0?(b-y)/g:(b+y)/g}}},function(t,e,n){var r=n(43),i=n(30),o=n(175).layout;t.exports=function(){var t=n(406),e=n(409),i=n(410),c=n(411),f=n(412),l=n(413),h=n(414),d=n(415),p=n(416),g=function(n,g){!function(t){t.nodes().forEach((function(e){var n=t.node(e);r.has(n,"label")||t.children(e).length||(n.label=e),r.has(n,"paddingX")&&r.defaults(n,{paddingLeft:n.paddingX,paddingRight:n.paddingX}),r.has(n,"paddingY")&&r.defaults(n,{paddingTop:n.paddingY,paddingBottom:n.paddingY}),r.has(n,"padding")&&r.defaults(n,{paddingLeft:n.padding,paddingRight:n.padding,paddingTop:n.padding,paddingBottom:n.padding}),r.defaults(n,a),r.each(["paddingLeft","paddingRight","paddingTop","paddingBottom"],(function(t){n[t]=Number(n[t])})),r.has(n,"width")&&(n._prevWidth=n.width),r.has(n,"height")&&(n._prevHeight=n.height)})),t.edges().forEach((function(e){var n=t.edge(e);r.has(n,"label")||(n.label=""),r.defaults(n,s)}))}(g);var y=u(n,"output"),b=u(y,"clusters"),m=u(y,"edgePaths"),v=i(u(y,"edgeLabels"),g),_=t(u(y,"nodes"),g,d);o(g),f(_,g),l(v,g),c(m,g,p);var w=e(b,g);h(w,g),function(t){r.each(t.nodes(),(function(e){var n=t.node(e);r.has(n,"_prevWidth")?n.width=n._prevWidth:delete n.width,r.has(n,"_prevHeight")?n.height=n._prevHeight:delete n.height,delete n._prevWidth,delete n._prevHeight}))}(g)};return g.createNodes=function(e){return arguments.length?(t=e,g):t},g.createClusters=function(t){return arguments.length?(e=t,g):e},g.createEdgeLabels=function(t){return arguments.length?(i=t,g):i},g.createEdgePaths=function(t){return arguments.length?(c=t,g):c},g.shapes=function(t){return arguments.length?(d=t,g):d},g.arrows=function(t){return arguments.length?(p=t,g):p},g};var a={paddingLeft:10,paddingRight:10,paddingTop:10,paddingBottom:10,rx:0,ry:0,shape:"rect"},s={arrowhead:"normal",curve:i.curveLinear};function u(t,e){var n=t.select("g."+e);return n.empty()&&(n=t.append("g").attr("class",e)),n}},function(t,e,n){"use strict";var r=n(43),i=n(110),o=n(14),a=n(30);t.exports=function(t,e,n){var s,u=e.nodes().filter((function(t){return!o.isSubgraph(e,t)})),c=t.selectAll("g.node").data(u,(function(t){return t})).classed("update",!0);c.exit().remove(),c.enter().append("g").attr("class","node").style("opacity",0),(c=t.selectAll("g.node")).each((function(t){var s=e.node(t),u=a.select(this);o.applyClass(u,s.class,(u.classed("update")?"update ":"")+"node"),u.select("g.label").remove();var c=u.append("g").attr("class","label"),f=i(c,s),l=n[s.shape],h=r.pick(f.node().getBBox(),"width","height");s.elem=this,s.id&&u.attr("id",s.id),s.labelId&&c.attr("id",s.labelId),r.has(s,"width")&&(h.width=s.width),r.has(s,"height")&&(h.height=s.height),h.width+=s.paddingLeft+s.paddingRight,h.height+=s.paddingTop+s.paddingBottom,c.attr("transform","translate("+(s.paddingLeft-s.paddingRight)/2+","+(s.paddingTop-s.paddingBottom)/2+")");var d=a.select(this);d.select(".label-container").remove();var p=l(d,h,s).classed("label-container",!0);o.applyStyle(p,s.style);var g=p.node().getBBox();s.width=g.width,s.height=g.height})),s=c.exit?c.exit():c.selectAll(null);return o.applyTransition(s,e).style("opacity",0).remove(),c}},function(t,e,n){var r=n(14);t.exports=function(t,e){for(var n=t.append("text"),i=function(t){for(var e,n="",r=!1,i=0;i0?a-4:a;for(n=0;n>16&255,u[f++]=e>>8&255,u[f++]=255&e;2===s&&(e=i[t.charCodeAt(n)]<<2|i[t.charCodeAt(n+1)]>>4,u[f++]=255&e);1===s&&(e=i[t.charCodeAt(n)]<<10|i[t.charCodeAt(n+1)]<<4|i[t.charCodeAt(n+2)]>>2,u[f++]=e>>8&255,u[f++]=255&e);return u},e.fromByteArray=function(t){for(var e,n=t.length,i=n%3,o=[],a=0,s=n-i;as?s:a+16383));1===i?(e=t[n-1],o.push(r[e>>2]+r[e<<4&63]+"==")):2===i&&(e=(t[n-2]<<8)+t[n-1],o.push(r[e>>10]+r[e>>4&63]+r[e<<2&63]+"="));return o.join("")};for(var r=[],i=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,u=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=t.indexOf("=");return-1===n&&(n=e),[n,n===e?0:4-n%4]}function f(t,e,n){for(var i,o,a=[],s=e;s>18&63]+r[o>>12&63]+r[o>>6&63]+r[63&o]);return a.join("")}i["-".charCodeAt(0)]=62,i["_".charCodeAt(0)]=63},function(t,e){e.read=function(t,e,n,r,i){var o,a,s=8*i-r-1,u=(1<>1,f=-7,l=n?i-1:0,h=n?-1:1,d=t[e+l];for(l+=h,o=d&(1<<-f)-1,d>>=-f,f+=s;f>0;o=256*o+t[e+l],l+=h,f-=8);for(a=o&(1<<-f)-1,o>>=-f,f+=r;f>0;a=256*a+t[e+l],l+=h,f-=8);if(0===o)o=1-c;else{if(o===u)return a?NaN:1/0*(d?-1:1);a+=Math.pow(2,r),o-=c}return(d?-1:1)*a*Math.pow(2,o-r)},e.write=function(t,e,n,r,i,o){var a,s,u,c=8*o-i-1,f=(1<>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=r?0:o-1,p=r?1:-1,g=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(s=isNaN(e)?1:0,a=f):(a=Math.floor(Math.log(e)/Math.LN2),e*(u=Math.pow(2,-a))<1&&(a--,u*=2),(e+=a+l>=1?h/u:h*Math.pow(2,1-l))*u>=2&&(a++,u/=2),a+l>=f?(s=0,a=f):a+l>=1?(s=(e*u-1)*Math.pow(2,i),a+=l):(s=e*Math.pow(2,l-1)*Math.pow(2,i),a=0));i>=8;t[n+d]=255&s,d+=p,s/=256,i-=8);for(a=a<0;t[n+d]=255&a,d+=p,a/=256,c-=8);t[n+d-p]|=128*g}},function(t,e){},function(t,e,n){"use strict";var r=n(115).Buffer,i=n(423);t.exports=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.head=null,this.tail=null,this.length=0}return t.prototype.push=function(t){var e={data:t,next:null};this.length>0?this.tail.next=e:this.head=e,this.tail=e,++this.length},t.prototype.unshift=function(t){var e={data:t,next:this.head};0===this.length&&(this.tail=e),this.head=e,++this.length},t.prototype.shift=function(){if(0!==this.length){var t=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,t}},t.prototype.clear=function(){this.head=this.tail=null,this.length=0},t.prototype.join=function(t){if(0===this.length)return"";for(var e=this.head,n=""+e.data;e=e.next;)n+=t+e.data;return n},t.prototype.concat=function(t){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var e,n,i,o=r.allocUnsafe(t>>>0),a=this.head,s=0;a;)e=a.data,n=o,i=s,e.copy(n,i),s+=a.data.length,a=a.next;return o},t}(),i&&i.inspect&&i.inspect.custom&&(t.exports.prototype[i.inspect.custom]=function(){var t=i.inspect({length:this.length});return this.constructor.name+" "+t})},function(t,e){},function(t,e,n){(function(t){var r=void 0!==t&&t||"undefined"!=typeof self&&self||window,i=Function.prototype.apply;function o(t,e){this._id=t,this._clearFn=e}e.setTimeout=function(){return new o(i.call(setTimeout,r,arguments),clearTimeout)},e.setInterval=function(){return new o(i.call(setInterval,r,arguments),clearInterval)},e.clearTimeout=e.clearInterval=function(t){t&&t.close()},o.prototype.unref=o.prototype.ref=function(){},o.prototype.close=function(){this._clearFn.call(r,this._id)},e.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},e.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},e._unrefActive=e.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout((function(){t._onTimeout&&t._onTimeout()}),e))},n(425),e.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==t&&t.setImmediate||this&&this.setImmediate,e.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==t&&t.clearImmediate||this&&this.clearImmediate}).call(this,n(11))},function(t,e,n){(function(t,e){!function(t,n){"use strict";if(!t.setImmediate){var r,i,o,a,s,u=1,c={},f=!1,l=t.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(t);h=h&&h.setTimeout?h:t,"[object process]"==={}.toString.call(t.process)?r=function(t){e.nextTick((function(){p(t)}))}:!function(){if(t.postMessage&&!t.importScripts){var e=!0,n=t.onmessage;return t.onmessage=function(){e=!1},t.postMessage("","*"),t.onmessage=n,e}}()?t.MessageChannel?((o=new MessageChannel).port1.onmessage=function(t){p(t.data)},r=function(t){o.port2.postMessage(t)}):l&&"onreadystatechange"in l.createElement("script")?(i=l.documentElement,r=function(t){var e=l.createElement("script");e.onreadystatechange=function(){p(t),e.onreadystatechange=null,i.removeChild(e),e=null},i.appendChild(e)}):r=function(t){setTimeout(p,0,t)}:(a="setImmediate$"+Math.random()+"$",s=function(e){e.source===t&&"string"==typeof e.data&&0===e.data.indexOf(a)&&p(+e.data.slice(a.length))},t.addEventListener?t.addEventListener("message",s,!1):t.attachEvent("onmessage",s),r=function(e){t.postMessage(a+e,"*")}),h.setImmediate=function(t){"function"!=typeof t&&(t=new Function(""+t));for(var e=new Array(arguments.length-1),n=0;n>>2}function f(t,e,n,r){return 0===t?e&n|~e&r:2===t?e&n|e&r|n&r:e^n^r}r(u,i),u.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},u.prototype._update=function(t){for(var e,n=this._w,r=0|this._a,i=0|this._b,o=0|this._c,s=0|this._d,u=0|this._e,l=0;l<16;++l)n[l]=t.readInt32BE(4*l);for(;l<80;++l)n[l]=n[l-3]^n[l-8]^n[l-14]^n[l-16];for(var h=0;h<80;++h){var d=~~(h/20),p=0|((e=r)<<5|e>>>27)+f(d,i,o,s)+u+n[h]+a[d];u=s,s=o,o=c(i),i=r,r=p}this._a=r+this._a|0,this._b=i+this._b|0,this._c=o+this._c|0,this._d=s+this._d|0,this._e=u+this._e|0},u.prototype._hash=function(){var t=o.allocUnsafe(20);return t.writeInt32BE(0|this._a,0),t.writeInt32BE(0|this._b,4),t.writeInt32BE(0|this._c,8),t.writeInt32BE(0|this._d,12),t.writeInt32BE(0|this._e,16),t},t.exports=u},function(t,e,n){var r=n(2),i=n(45),o=n(3).Buffer,a=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function u(){this.init(),this._w=s,i.call(this,64,56)}function c(t){return t<<5|t>>>27}function f(t){return t<<30|t>>>2}function l(t,e,n,r){return 0===t?e&n|~e&r:2===t?e&n|e&r|n&r:e^n^r}r(u,i),u.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},u.prototype._update=function(t){for(var e,n=this._w,r=0|this._a,i=0|this._b,o=0|this._c,s=0|this._d,u=0|this._e,h=0;h<16;++h)n[h]=t.readInt32BE(4*h);for(;h<80;++h)n[h]=(e=n[h-3]^n[h-8]^n[h-14]^n[h-16])<<1|e>>>31;for(var d=0;d<80;++d){var p=~~(d/20),g=c(r)+l(p,i,o,s)+u+n[d]+a[p]|0;u=s,s=o,o=f(i),i=r,r=g}this._a=r+this._a|0,this._b=i+this._b|0,this._c=o+this._c|0,this._d=s+this._d|0,this._e=u+this._e|0},u.prototype._hash=function(){var t=o.allocUnsafe(20);return t.writeInt32BE(0|this._a,0),t.writeInt32BE(0|this._b,4),t.writeInt32BE(0|this._c,8),t.writeInt32BE(0|this._d,12),t.writeInt32BE(0|this._e,16),t},t.exports=u},function(t,e,n){var r=n(2),i=n(197),o=n(45),a=n(3).Buffer,s=new Array(64);function u(){this.init(),this._w=s,o.call(this,64,56)}r(u,i),u.prototype.init=function(){return this._a=3238371032,this._b=914150663,this._c=812702999,this._d=4144912697,this._e=4290775857,this._f=1750603025,this._g=1694076839,this._h=3204075428,this},u.prototype._hash=function(){var t=a.allocUnsafe(28);return t.writeInt32BE(this._a,0),t.writeInt32BE(this._b,4),t.writeInt32BE(this._c,8),t.writeInt32BE(this._d,12),t.writeInt32BE(this._e,16),t.writeInt32BE(this._f,20),t.writeInt32BE(this._g,24),t},t.exports=u},function(t,e,n){var r=n(2),i=n(198),o=n(45),a=n(3).Buffer,s=new Array(160);function u(){this.init(),this._w=s,o.call(this,128,112)}r(u,i),u.prototype.init=function(){return this._ah=3418070365,this._bh=1654270250,this._ch=2438529370,this._dh=355462360,this._eh=1731405415,this._fh=2394180231,this._gh=3675008525,this._hh=1203062813,this._al=3238371032,this._bl=914150663,this._cl=812702999,this._dl=4144912697,this._el=4290775857,this._fl=1750603025,this._gl=1694076839,this._hl=3204075428,this},u.prototype._hash=function(){var t=a.allocUnsafe(48);function e(e,n,r){t.writeInt32BE(e,r),t.writeInt32BE(n,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),t},t.exports=u},function(t,e,n){"use strict";var r=n(2),i=n(3).Buffer,o=n(31),a=i.alloc(128),s=64;function u(t,e){o.call(this,"digest"),"string"==typeof e&&(e=i.from(e)),this._alg=t,this._key=e,e.length>s?e=t(e):e.length>>0},e.writeUInt32BE=function(t,e,n){t[0+n]=e>>>24,t[1+n]=e>>>16&255,t[2+n]=e>>>8&255,t[3+n]=255&e},e.ip=function(t,e,n,r){for(var i=0,o=0,a=6;a>=0;a-=2){for(var s=0;s<=24;s+=8)i<<=1,i|=e>>>s+a&1;for(s=0;s<=24;s+=8)i<<=1,i|=t>>>s+a&1}for(a=6;a>=0;a-=2){for(s=1;s<=25;s+=8)o<<=1,o|=e>>>s+a&1;for(s=1;s<=25;s+=8)o<<=1,o|=t>>>s+a&1}n[r+0]=i>>>0,n[r+1]=o>>>0},e.rip=function(t,e,n,r){for(var i=0,o=0,a=0;a<4;a++)for(var s=24;s>=0;s-=8)i<<=1,i|=e>>>s+a&1,i<<=1,i|=t>>>s+a&1;for(a=4;a<8;a++)for(s=24;s>=0;s-=8)o<<=1,o|=e>>>s+a&1,o<<=1,o|=t>>>s+a&1;n[r+0]=i>>>0,n[r+1]=o>>>0},e.pc1=function(t,e,n,r){for(var i=0,o=0,a=7;a>=5;a--){for(var s=0;s<=24;s+=8)i<<=1,i|=e>>s+a&1;for(s=0;s<=24;s+=8)i<<=1,i|=t>>s+a&1}for(s=0;s<=24;s+=8)i<<=1,i|=e>>s+a&1;for(a=1;a<=3;a++){for(s=0;s<=24;s+=8)o<<=1,o|=e>>s+a&1;for(s=0;s<=24;s+=8)o<<=1,o|=t>>s+a&1}for(s=0;s<=24;s+=8)o<<=1,o|=t>>s+a&1;n[r+0]=i>>>0,n[r+1]=o>>>0},e.r28shl=function(t,e){return t<>>28-e};var r=[14,11,17,4,27,23,25,0,13,22,7,18,5,9,16,24,2,20,12,21,1,8,15,26,15,4,25,19,9,1,26,16,5,11,23,8,12,7,17,0,22,3,10,14,6,20,27,24];e.pc2=function(t,e,n,i){for(var o=0,a=0,s=r.length>>>1,u=0;u>>r[u]&1;for(u=s;u>>r[u]&1;n[i+0]=o>>>0,n[i+1]=a>>>0},e.expand=function(t,e,n){var r=0,i=0;r=(1&t)<<5|t>>>27;for(var o=23;o>=15;o-=4)r<<=6,r|=t>>>o&63;for(o=11;o>=3;o-=4)i|=t>>>o&63,i<<=6;i|=(31&t)<<1|t>>>31,e[n+0]=r>>>0,e[n+1]=i>>>0};var i=[14,0,4,15,13,7,1,4,2,14,15,2,11,13,8,1,3,10,10,6,6,12,12,11,5,9,9,5,0,3,7,8,4,15,1,12,14,8,8,2,13,4,6,9,2,1,11,7,15,5,12,11,9,3,7,14,3,10,10,0,5,6,0,13,15,3,1,13,8,4,14,7,6,15,11,2,3,8,4,14,9,12,7,0,2,1,13,10,12,6,0,9,5,11,10,5,0,13,14,8,7,10,11,1,10,3,4,15,13,4,1,2,5,11,8,6,12,7,6,12,9,0,3,5,2,14,15,9,10,13,0,7,9,0,14,9,6,3,3,4,15,6,5,10,1,2,13,8,12,5,7,14,11,12,4,11,2,15,8,1,13,1,6,10,4,13,9,0,8,6,15,9,3,8,0,7,11,4,1,15,2,14,12,3,5,11,10,5,14,2,7,12,7,13,13,8,14,11,3,5,0,6,6,15,9,0,10,3,1,4,2,7,8,2,5,12,11,1,12,10,4,14,15,9,10,3,6,15,9,0,0,6,12,10,11,1,7,13,13,8,15,9,1,4,3,5,14,11,5,12,2,7,8,2,4,14,2,14,12,11,4,2,1,12,7,4,10,7,11,13,6,1,8,5,5,0,3,15,15,10,13,3,0,9,14,8,9,6,4,11,2,8,1,12,11,7,10,1,13,14,7,2,8,13,15,6,9,15,12,0,5,9,6,10,3,4,0,5,14,3,12,10,1,15,10,4,15,2,9,7,2,12,6,9,8,5,0,6,13,1,3,13,4,14,14,0,7,11,5,3,11,8,9,4,14,3,15,2,5,12,2,9,8,5,12,15,3,10,7,11,0,14,4,1,10,7,1,6,13,0,11,8,6,13,4,13,11,0,2,11,14,7,15,4,0,9,8,1,13,10,3,14,12,3,9,5,7,12,5,2,10,15,6,8,1,6,1,6,4,11,11,13,13,8,12,1,3,4,7,10,14,7,10,9,15,5,6,0,8,15,0,14,5,2,9,3,2,12,13,1,2,15,8,13,4,8,6,10,15,3,11,7,1,4,10,12,9,5,3,6,14,11,5,0,0,14,12,9,7,2,7,2,11,1,4,14,1,7,9,4,12,10,14,8,2,13,0,15,6,12,10,9,13,0,15,3,3,5,5,6,8,11];e.substitute=function(t,e){for(var n=0,r=0;r<4;r++){n<<=4,n|=i[64*r+(t>>>18-6*r&63)]}for(r=0;r<4;r++){n<<=4,n|=i[256+64*r+(e>>>18-6*r&63)]}return n>>>0};var o=[16,25,12,11,3,20,4,15,31,17,9,6,27,14,1,22,30,24,8,18,0,5,29,23,13,19,2,26,10,21,28,7];e.permute=function(t){for(var e=0,n=0;n>>o[n]&1;return e>>>0},e.padSplit=function(t,e,n){for(var r=t.toString(2);r.length0;r--)e+=this._buffer(t,e),n+=this._flushBuffer(i,n);return e+=this._buffer(t,e),i},i.prototype.final=function(t){var e,n;return t&&(e=this.update(t)),n="encrypt"===this.type?this._finalEncrypt():this._finalDecrypt(),e?e.concat(n):n},i.prototype._pad=function(t,e){if(0===e)return!1;for(;e>>1];n=a.r28shl(n,s),i=a.r28shl(i,s),a.pc2(n,i,t.keys,o)}},c.prototype._update=function(t,e,n,r){var i=this._desState,o=a.readUInt32BE(t,e),s=a.readUInt32BE(t,e+4);a.ip(o,s,i.tmp,0),o=i.tmp[0],s=i.tmp[1],"encrypt"===this.type?this._encrypt(i,o,s,i.tmp,0):this._decrypt(i,o,s,i.tmp,0),o=i.tmp[0],s=i.tmp[1],a.writeUInt32BE(n,o,r),a.writeUInt32BE(n,s,r+4)},c.prototype._pad=function(t,e){for(var n=t.length-e,r=e;r>>0,o=h}a.rip(s,o,r,i)},c.prototype._decrypt=function(t,e,n,r,i){for(var o=n,s=e,u=t.keys.length-2;u>=0;u-=2){var c=t.keys[u],f=t.keys[u+1];a.expand(o,t.tmp,0),c^=t.tmp[0],f^=t.tmp[1];var l=a.substitute(c,f),h=o;o=(s^a.permute(l))>>>0,s=h}a.rip(o,s,r,i)}},function(t,e,n){"use strict";var r=n(15),i=n(2),o={};function a(t){r.equal(t.length,8,"Invalid IV length"),this.iv=new Array(8);for(var e=0;e15){var t=this.cache.slice(0,16);return this.cache=this.cache.slice(16),t}return null},h.prototype.flush=function(){for(var t=16-this.cache.length,e=o.allocUnsafe(t),n=-1;++n>a%8,t._prev=o(t._prev,n?r:i);return s}function o(t,e){var n=t.length,i=-1,o=r.allocUnsafe(t.length);for(t=r.concat([t,r.from([e])]);++i>7;return o}e.encrypt=function(t,e,n){for(var o=e.length,a=r.allocUnsafe(o),s=-1;++s>>0,0),e.writeUInt32BE(t[1]>>>0,4),e.writeUInt32BE(t[2]>>>0,8),e.writeUInt32BE(t[3]>>>0,12),e}function a(t){this.h=t,this.state=r.alloc(16,0),this.cache=r.allocUnsafe(0)}a.prototype.ghash=function(t){for(var e=-1;++e0;e--)r[e]=r[e]>>>1|(1&r[e-1])<<31;r[0]=r[0]>>>1,n&&(r[0]=r[0]^225<<24)}this.state=o(i)},a.prototype.update=function(t){var e;for(this.cache=r.concat([this.cache,t]);this.cache.length>=16;)e=this.cache.slice(0,16),this.cache=this.cache.slice(16),this.ghash(e)},a.prototype.final=function(t,e){return this.cache.length&&this.ghash(r.concat([this.cache,i],16)),this.ghash(o([0,t,0,e])),this.state},t.exports=a},function(t,e,n){var r=n(209),i=n(3).Buffer,o=n(122),a=n(210),s=n(31),u=n(79),c=n(80);function f(t,e,n){s.call(this),this._cache=new l,this._last=void 0,this._cipher=new u.AES(e),this._prev=i.from(n),this._mode=t,this._autopadding=!0}function l(){this.cache=i.allocUnsafe(0)}function h(t,e,n){var s=o[t.toLowerCase()];if(!s)throw new TypeError("invalid suite type");if("string"==typeof n&&(n=i.from(n)),"GCM"!==s.mode&&n.length!==s.iv)throw new TypeError("invalid iv length "+n.length);if("string"==typeof e&&(e=i.from(e)),e.length!==s.key/8)throw new TypeError("invalid key length "+e.length);return"stream"===s.type?new a(s.module,e,n,!0):"auth"===s.type?new r(s.module,e,n,!0):new f(s.module,e,n)}n(2)(f,s),f.prototype._update=function(t){var e,n;this._cache.add(t);for(var r=[];e=this._cache.get(this._autopadding);)n=this._mode.decrypt(this,e),r.push(n);return i.concat(r)},f.prototype._final=function(){var t=this._cache.flush();if(this._autopadding)return function(t){var e=t[15];if(e<1||e>16)throw new Error("unable to decrypt data");var n=-1;for(;++n16)return e=this.cache.slice(0,16),this.cache=this.cache.slice(16),e}else if(this.cache.length>=16)return e=this.cache.slice(0,16),this.cache=this.cache.slice(16),e;return null},l.prototype.flush=function(){if(this.cache.length)return this.cache},e.createDecipher=function(t,e){var n=o[t.toLowerCase()];if(!n)throw new TypeError("invalid suite type");var r=c(e,!1,n.key,n.iv);return h(t,r.key,r.iv)},e.createDecipheriv=h},function(t,e){e["des-ecb"]={key:8,iv:0},e["des-cbc"]=e.des={key:8,iv:8},e["des-ede3-cbc"]=e.des3={key:24,iv:8},e["des-ede3"]={key:24,iv:0},e["des-ede-cbc"]={key:16,iv:8},e["des-ede"]={key:16,iv:0}},function(t,e,n){(function(t){var r=n(211),i=n(459),o=n(460);var a={binary:!0,hex:!0,base64:!0};e.DiffieHellmanGroup=e.createDiffieHellmanGroup=e.getDiffieHellman=function(e){var n=new t(i[e].prime,"hex"),r=new t(i[e].gen,"hex");return new o(n,r)},e.createDiffieHellman=e.DiffieHellman=function e(n,i,s,u){return t.isBuffer(i)||void 0===a[i]?e(n,"binary",i,s):(i=i||"binary",u=u||"binary",s=s||new t([2]),t.isBuffer(s)||(s=new t(s,u)),"number"==typeof n?new o(r(n,s),s,!0):(t.isBuffer(n)||(n=new t(n,i)),new o(n,s,!0)))}}).call(this,n(8).Buffer)},function(t,e){},function(t,e){},function(t){t.exports=JSON.parse('{"modp1":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff"},"modp2":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff"},"modp5":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff"},"modp14":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff"},"modp15":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"},"modp16":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff"},"modp17":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"},"modp18":{"gen":"02","prime":"ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"}}')},function(t,e,n){(function(e){var r=n(5),i=new(n(212)),o=new r(24),a=new r(11),s=new r(10),u=new r(3),c=new r(7),f=n(211),l=n(44);function h(t,n){return n=n||"utf8",e.isBuffer(t)||(t=new e(t,n)),this._pub=new r(t),this}function d(t,n){return n=n||"utf8",e.isBuffer(t)||(t=new e(t,n)),this._priv=new r(t),this}t.exports=g;var p={};function g(t,e,n){this.setGenerator(e),this.__prime=new r(t),this._prime=r.mont(this.__prime),this._primeLen=t.length,this._pub=void 0,this._priv=void 0,this._primeCode=void 0,n?(this.setPublicKey=h,this.setPrivateKey=d):this._primeCode=8}function y(t,n){var r=new e(t.toArray());return n?r.toString(n):r}Object.defineProperty(g.prototype,"verifyError",{enumerable:!0,get:function(){return"number"!=typeof this._primeCode&&(this._primeCode=function(t,e){var n=e.toString("hex"),r=[n,t.toString(16)].join("_");if(r in p)return p[r];var l,h=0;if(t.isEven()||!f.simpleSieve||!f.fermatTest(t)||!i.test(t))return h+=1,h+="02"===n||"05"===n?8:4,p[r]=h,h;switch(i.test(t.shrn(1))||(h+=2),n){case"02":t.mod(o).cmp(a)&&(h+=8);break;case"05":(l=t.mod(s)).cmp(u)&&l.cmp(c)&&(h+=8);break;default:h+=4}return p[r]=h,h}(this.__prime,this.__gen)),this._primeCode}}),g.prototype.generateKeys=function(){return this._priv||(this._priv=new r(l(this._primeLen))),this._pub=this._gen.toRed(this._prime).redPow(this._priv).fromRed(),this.getPublicKey()},g.prototype.computeSecret=function(t){var n=(t=(t=new r(t)).toRed(this._prime)).redPow(this._priv).fromRed(),i=new e(n.toArray()),o=this.getPrime();if(i.length0&&n.ishrn(r),n}function l(t,n,i){var o,a;do{for(o=new e(0);8*o.length","license":"MIT","bugs":{"url":"https://github.com/indutny/elliptic/issues"},"homepage":"https://github.com/indutny/elliptic","devDependencies":{"brfs":"^1.4.3","coveralls":"^3.0.4","grunt":"^1.0.4","grunt-browserify":"^5.0.0","grunt-cli":"^1.2.0","grunt-contrib-connect":"^1.0.0","grunt-contrib-copy":"^1.0.0","grunt-contrib-uglify":"^1.0.1","grunt-mocha-istanbul":"^3.0.1","grunt-saucelabs":"^9.0.1","istanbul":"^0.4.2","jscs":"^3.0.7","jshint":"^2.6.0","mocha":"^6.1.4"},"dependencies":{"bn.js":"^4.4.0","brorand":"^1.0.1","hash.js":"^1.0.0","hmac-drbg":"^1.0.0","inherits":"^2.0.1","minimalistic-assert":"^1.0.0","minimalistic-crypto-utils":"^1.0.0"}}')},function(t,e,n){"use strict";var r=n(16),i=n(5),o=n(2),a=n(81),s=r.assert;function u(t){a.call(this,"short",t),this.a=new i(t.a,16).toRed(this.red),this.b=new i(t.b,16).toRed(this.red),this.tinv=this.two.redInvm(),this.zeroA=0===this.a.fromRed().cmpn(0),this.threeA=0===this.a.fromRed().sub(this.p).cmpn(-3),this.endo=this._getEndomorphism(t),this._endoWnafT1=new Array(4),this._endoWnafT2=new Array(4)}function c(t,e,n,r){a.BasePoint.call(this,t,"affine"),null===e&&null===n?(this.x=null,this.y=null,this.inf=!0):(this.x=new i(e,16),this.y=new i(n,16),r&&(this.x.forceRed(this.curve.red),this.y.forceRed(this.curve.red)),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.inf=!1)}function f(t,e,n,r){a.BasePoint.call(this,t,"jacobian"),null===e&&null===n&&null===r?(this.x=this.curve.one,this.y=this.curve.one,this.z=new i(0)):(this.x=new i(e,16),this.y=new i(n,16),this.z=new i(r,16)),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)),this.zOne=this.z===this.curve.one}o(u,a),t.exports=u,u.prototype._getEndomorphism=function(t){if(this.zeroA&&this.g&&this.n&&1===this.p.modn(3)){var e,n;if(t.beta)e=new i(t.beta,16).toRed(this.red);else{var r=this._getEndoRoots(this.p);e=(e=r[0].cmp(r[1])<0?r[0]:r[1]).toRed(this.red)}if(t.lambda)n=new i(t.lambda,16);else{var o=this._getEndoRoots(this.n);0===this.g.mul(o[0]).x.cmp(this.g.x.redMul(e))?n=o[0]:(n=o[1],s(0===this.g.mul(n).x.cmp(this.g.x.redMul(e))))}return{beta:e,lambda:n,basis:t.basis?t.basis.map((function(t){return{a:new i(t.a,16),b:new i(t.b,16)}})):this._getEndoBasis(n)}}},u.prototype._getEndoRoots=function(t){var e=t===this.p?this.red:i.mont(t),n=new i(2).toRed(e).redInvm(),r=n.redNeg(),o=new i(3).toRed(e).redNeg().redSqrt().redMul(n);return[r.redAdd(o).fromRed(),r.redSub(o).fromRed()]},u.prototype._getEndoBasis=function(t){for(var e,n,r,o,a,s,u,c,f,l=this.n.ushrn(Math.floor(this.n.bitLength()/2)),h=t,d=this.n.clone(),p=new i(1),g=new i(0),y=new i(0),b=new i(1),m=0;0!==h.cmpn(0);){var v=d.div(h);c=d.sub(v.mul(h)),f=y.sub(v.mul(p));var _=b.sub(v.mul(g));if(!r&&c.cmp(l)<0)e=u.neg(),n=p,r=c.neg(),o=f;else if(r&&2==++m)break;u=c,d=h,h=c,y=p,p=f,b=g,g=_}a=c.neg(),s=f;var w=r.sqr().add(o.sqr());return a.sqr().add(s.sqr()).cmp(w)>=0&&(a=e,s=n),r.negative&&(r=r.neg(),o=o.neg()),a.negative&&(a=a.neg(),s=s.neg()),[{a:r,b:o},{a:a,b:s}]},u.prototype._endoSplit=function(t){var e=this.endo.basis,n=e[0],r=e[1],i=r.b.mul(t).divRound(this.n),o=n.b.neg().mul(t).divRound(this.n),a=i.mul(n.a),s=o.mul(r.a),u=i.mul(n.b),c=o.mul(r.b);return{k1:t.sub(a).sub(s),k2:u.add(c).neg()}},u.prototype.pointFromX=function(t,e){(t=new i(t,16)).red||(t=t.toRed(this.red));var n=t.redSqr().redMul(t).redIAdd(t.redMul(this.a)).redIAdd(this.b),r=n.redSqrt();if(0!==r.redSqr().redSub(n).cmp(this.zero))throw new Error("invalid point");var o=r.fromRed().isOdd();return(e&&!o||!e&&o)&&(r=r.redNeg()),this.point(t,r)},u.prototype.validate=function(t){if(t.inf)return!0;var e=t.x,n=t.y,r=this.a.redMul(e),i=e.redSqr().redMul(e).redIAdd(r).redIAdd(this.b);return 0===n.redSqr().redISub(i).cmpn(0)},u.prototype._endoWnafMulAdd=function(t,e,n){for(var r=this._endoWnafT1,i=this._endoWnafT2,o=0;o":""},c.prototype.isInfinity=function(){return this.inf},c.prototype.add=function(t){if(this.inf)return t;if(t.inf)return this;if(this.eq(t))return this.dbl();if(this.neg().eq(t))return this.curve.point(null,null);if(0===this.x.cmp(t.x))return this.curve.point(null,null);var e=this.y.redSub(t.y);0!==e.cmpn(0)&&(e=e.redMul(this.x.redSub(t.x).redInvm()));var n=e.redSqr().redISub(this.x).redISub(t.x),r=e.redMul(this.x.redSub(n)).redISub(this.y);return this.curve.point(n,r)},c.prototype.dbl=function(){if(this.inf)return this;var t=this.y.redAdd(this.y);if(0===t.cmpn(0))return this.curve.point(null,null);var e=this.curve.a,n=this.x.redSqr(),r=t.redInvm(),i=n.redAdd(n).redIAdd(n).redIAdd(e).redMul(r),o=i.redSqr().redISub(this.x.redAdd(this.x)),a=i.redMul(this.x.redSub(o)).redISub(this.y);return this.curve.point(o,a)},c.prototype.getX=function(){return this.x.fromRed()},c.prototype.getY=function(){return this.y.fromRed()},c.prototype.mul=function(t){return t=new i(t,16),this.isInfinity()?this:this._hasDoubles(t)?this.curve._fixedNafMul(this,t):this.curve.endo?this.curve._endoWnafMulAdd([this],[t]):this.curve._wnafMul(this,t)},c.prototype.mulAdd=function(t,e,n){var r=[this,e],i=[t,n];return this.curve.endo?this.curve._endoWnafMulAdd(r,i):this.curve._wnafMulAdd(1,r,i,2)},c.prototype.jmulAdd=function(t,e,n){var r=[this,e],i=[t,n];return this.curve.endo?this.curve._endoWnafMulAdd(r,i,!0):this.curve._wnafMulAdd(1,r,i,2,!0)},c.prototype.eq=function(t){return this===t||this.inf===t.inf&&(this.inf||0===this.x.cmp(t.x)&&0===this.y.cmp(t.y))},c.prototype.neg=function(t){if(this.inf)return this;var e=this.curve.point(this.x,this.y.redNeg());if(t&&this.precomputed){var n=this.precomputed,r=function(t){return t.neg()};e.precomputed={naf:n.naf&&{wnd:n.naf.wnd,points:n.naf.points.map(r)},doubles:n.doubles&&{step:n.doubles.step,points:n.doubles.points.map(r)}}}return e},c.prototype.toJ=function(){return this.inf?this.curve.jpoint(null,null,null):this.curve.jpoint(this.x,this.y,this.curve.one)},o(f,a.BasePoint),u.prototype.jpoint=function(t,e,n){return new f(this,t,e,n)},f.prototype.toP=function(){if(this.isInfinity())return this.curve.point(null,null);var t=this.z.redInvm(),e=t.redSqr(),n=this.x.redMul(e),r=this.y.redMul(e).redMul(t);return this.curve.point(n,r)},f.prototype.neg=function(){return this.curve.jpoint(this.x,this.y.redNeg(),this.z)},f.prototype.add=function(t){if(this.isInfinity())return t;if(t.isInfinity())return this;var e=t.z.redSqr(),n=this.z.redSqr(),r=this.x.redMul(e),i=t.x.redMul(n),o=this.y.redMul(e.redMul(t.z)),a=t.y.redMul(n.redMul(this.z)),s=r.redSub(i),u=o.redSub(a);if(0===s.cmpn(0))return 0!==u.cmpn(0)?this.curve.jpoint(null,null,null):this.dbl();var c=s.redSqr(),f=c.redMul(s),l=r.redMul(c),h=u.redSqr().redIAdd(f).redISub(l).redISub(l),d=u.redMul(l.redISub(h)).redISub(o.redMul(f)),p=this.z.redMul(t.z).redMul(s);return this.curve.jpoint(h,d,p)},f.prototype.mixedAdd=function(t){if(this.isInfinity())return t.toJ();if(t.isInfinity())return this;var e=this.z.redSqr(),n=this.x,r=t.x.redMul(e),i=this.y,o=t.y.redMul(e).redMul(this.z),a=n.redSub(r),s=i.redSub(o);if(0===a.cmpn(0))return 0!==s.cmpn(0)?this.curve.jpoint(null,null,null):this.dbl();var u=a.redSqr(),c=u.redMul(a),f=n.redMul(u),l=s.redSqr().redIAdd(c).redISub(f).redISub(f),h=s.redMul(f.redISub(l)).redISub(i.redMul(c)),d=this.z.redMul(a);return this.curve.jpoint(l,h,d)},f.prototype.dblp=function(t){if(0===t)return this;if(this.isInfinity())return this;if(!t)return this.dbl();if(this.curve.zeroA||this.curve.threeA){for(var e=this,n=0;n=0)return!1;if(n.redIAdd(i),0===this.x.cmp(n))return!0}},f.prototype.inspect=function(){return this.isInfinity()?"":""},f.prototype.isInfinity=function(){return 0===this.z.cmpn(0)}},function(t,e,n){"use strict";var r=n(5),i=n(2),o=n(81),a=n(16);function s(t){o.call(this,"mont",t),this.a=new r(t.a,16).toRed(this.red),this.b=new r(t.b,16).toRed(this.red),this.i4=new r(4).toRed(this.red).redInvm(),this.two=new r(2).toRed(this.red),this.a24=this.i4.redMul(this.a.redAdd(this.two))}function u(t,e,n){o.BasePoint.call(this,t,"projective"),null===e&&null===n?(this.x=this.curve.one,this.z=this.curve.zero):(this.x=new r(e,16),this.z=new r(n,16),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)))}i(s,o),t.exports=s,s.prototype.validate=function(t){var e=t.normalize().x,n=e.redSqr(),r=n.redMul(e).redAdd(n.redMul(this.a)).redAdd(e);return 0===r.redSqrt().redSqr().cmp(r)},i(u,o.BasePoint),s.prototype.decodePoint=function(t,e){return this.point(a.toArray(t,e),1)},s.prototype.point=function(t,e){return new u(this,t,e)},s.prototype.pointFromJSON=function(t){return u.fromJSON(this,t)},u.prototype.precompute=function(){},u.prototype._encode=function(){return this.getX().toArray("be",this.curve.p.byteLength())},u.fromJSON=function(t,e){return new u(t,e[0],e[1]||t.one)},u.prototype.inspect=function(){return this.isInfinity()?"":""},u.prototype.isInfinity=function(){return 0===this.z.cmpn(0)},u.prototype.dbl=function(){var t=this.x.redAdd(this.z).redSqr(),e=this.x.redSub(this.z).redSqr(),n=t.redSub(e),r=t.redMul(e),i=n.redMul(e.redAdd(this.curve.a24.redMul(n)));return this.curve.point(r,i)},u.prototype.add=function(){throw new Error("Not supported on Montgomery curve")},u.prototype.diffAdd=function(t,e){var n=this.x.redAdd(this.z),r=this.x.redSub(this.z),i=t.x.redAdd(t.z),o=t.x.redSub(t.z).redMul(n),a=i.redMul(r),s=e.z.redMul(o.redAdd(a).redSqr()),u=e.x.redMul(o.redISub(a).redSqr());return this.curve.point(s,u)},u.prototype.mul=function(t){for(var e=t.clone(),n=this,r=this.curve.point(null,null),i=[];0!==e.cmpn(0);e.iushrn(1))i.push(e.andln(1));for(var o=i.length-1;o>=0;o--)0===i[o]?(n=n.diffAdd(r,this),r=r.dbl()):(r=n.diffAdd(r,this),n=n.dbl());return r},u.prototype.mulAdd=function(){throw new Error("Not supported on Montgomery curve")},u.prototype.jumlAdd=function(){throw new Error("Not supported on Montgomery curve")},u.prototype.eq=function(t){return 0===this.getX().cmp(t.getX())},u.prototype.normalize=function(){return this.x=this.x.redMul(this.z.redInvm()),this.z=this.curve.one,this},u.prototype.getX=function(){return this.normalize(),this.x.fromRed()}},function(t,e,n){"use strict";var r=n(16),i=n(5),o=n(2),a=n(81),s=r.assert;function u(t){this.twisted=1!=(0|t.a),this.mOneA=this.twisted&&-1==(0|t.a),this.extended=this.mOneA,a.call(this,"edwards",t),this.a=new i(t.a,16).umod(this.red.m),this.a=this.a.toRed(this.red),this.c=new i(t.c,16).toRed(this.red),this.c2=this.c.redSqr(),this.d=new i(t.d,16).toRed(this.red),this.dd=this.d.redAdd(this.d),s(!this.twisted||0===this.c.fromRed().cmpn(1)),this.oneC=1==(0|t.c)}function c(t,e,n,r,o){a.BasePoint.call(this,t,"projective"),null===e&&null===n&&null===r?(this.x=this.curve.zero,this.y=this.curve.one,this.z=this.curve.one,this.t=this.curve.zero,this.zOne=!0):(this.x=new i(e,16),this.y=new i(n,16),this.z=r?new i(r,16):this.curve.one,this.t=o&&new i(o,16),this.x.red||(this.x=this.x.toRed(this.curve.red)),this.y.red||(this.y=this.y.toRed(this.curve.red)),this.z.red||(this.z=this.z.toRed(this.curve.red)),this.t&&!this.t.red&&(this.t=this.t.toRed(this.curve.red)),this.zOne=this.z===this.curve.one,this.curve.extended&&!this.t&&(this.t=this.x.redMul(this.y),this.zOne||(this.t=this.t.redMul(this.z.redInvm()))))}o(u,a),t.exports=u,u.prototype._mulA=function(t){return this.mOneA?t.redNeg():this.a.redMul(t)},u.prototype._mulC=function(t){return this.oneC?t:this.c.redMul(t)},u.prototype.jpoint=function(t,e,n,r){return this.point(t,e,n,r)},u.prototype.pointFromX=function(t,e){(t=new i(t,16)).red||(t=t.toRed(this.red));var n=t.redSqr(),r=this.c2.redSub(this.a.redMul(n)),o=this.one.redSub(this.c2.redMul(this.d).redMul(n)),a=r.redMul(o.redInvm()),s=a.redSqrt();if(0!==s.redSqr().redSub(a).cmp(this.zero))throw new Error("invalid point");var u=s.fromRed().isOdd();return(e&&!u||!e&&u)&&(s=s.redNeg()),this.point(t,s)},u.prototype.pointFromY=function(t,e){(t=new i(t,16)).red||(t=t.toRed(this.red));var n=t.redSqr(),r=n.redSub(this.c2),o=n.redMul(this.d).redMul(this.c2).redSub(this.a),a=r.redMul(o.redInvm());if(0===a.cmp(this.zero)){if(e)throw new Error("invalid point");return this.point(this.zero,t)}var s=a.redSqrt();if(0!==s.redSqr().redSub(a).cmp(this.zero))throw new Error("invalid point");return s.fromRed().isOdd()!==e&&(s=s.redNeg()),this.point(s,t)},u.prototype.validate=function(t){if(t.isInfinity())return!0;t.normalize();var e=t.x.redSqr(),n=t.y.redSqr(),r=e.redMul(this.a).redAdd(n),i=this.c2.redMul(this.one.redAdd(this.d.redMul(e).redMul(n)));return 0===r.cmp(i)},o(c,a.BasePoint),u.prototype.pointFromJSON=function(t){return c.fromJSON(this,t)},u.prototype.point=function(t,e,n,r){return new c(this,t,e,n,r)},c.fromJSON=function(t,e){return new c(t,e[0],e[1],e[2])},c.prototype.inspect=function(){return this.isInfinity()?"":""},c.prototype.isInfinity=function(){return 0===this.x.cmpn(0)&&(0===this.y.cmp(this.z)||this.zOne&&0===this.y.cmp(this.curve.c))},c.prototype._extDbl=function(){var t=this.x.redSqr(),e=this.y.redSqr(),n=this.z.redSqr();n=n.redIAdd(n);var r=this.curve._mulA(t),i=this.x.redAdd(this.y).redSqr().redISub(t).redISub(e),o=r.redAdd(e),a=o.redSub(n),s=r.redSub(e),u=i.redMul(a),c=o.redMul(s),f=i.redMul(s),l=a.redMul(o);return this.curve.point(u,c,l,f)},c.prototype._projDbl=function(){var t,e,n,r=this.x.redAdd(this.y).redSqr(),i=this.x.redSqr(),o=this.y.redSqr();if(this.curve.twisted){var a=(c=this.curve._mulA(i)).redAdd(o);if(this.zOne)t=r.redSub(i).redSub(o).redMul(a.redSub(this.curve.two)),e=a.redMul(c.redSub(o)),n=a.redSqr().redSub(a).redSub(a);else{var s=this.z.redSqr(),u=a.redSub(s).redISub(s);t=r.redSub(i).redISub(o).redMul(u),e=a.redMul(c.redSub(o)),n=a.redMul(u)}}else{var c=i.redAdd(o);s=this.curve._mulC(this.z).redSqr(),u=c.redSub(s).redSub(s);t=this.curve._mulC(r.redISub(c)).redMul(u),e=this.curve._mulC(c).redMul(i.redISub(o)),n=c.redMul(u)}return this.curve.point(t,e,n)},c.prototype.dbl=function(){return this.isInfinity()?this:this.curve.extended?this._extDbl():this._projDbl()},c.prototype._extAdd=function(t){var e=this.y.redSub(this.x).redMul(t.y.redSub(t.x)),n=this.y.redAdd(this.x).redMul(t.y.redAdd(t.x)),r=this.t.redMul(this.curve.dd).redMul(t.t),i=this.z.redMul(t.z.redAdd(t.z)),o=n.redSub(e),a=i.redSub(r),s=i.redAdd(r),u=n.redAdd(e),c=o.redMul(a),f=s.redMul(u),l=o.redMul(u),h=a.redMul(s);return this.curve.point(c,f,h,l)},c.prototype._projAdd=function(t){var e,n,r=this.z.redMul(t.z),i=r.redSqr(),o=this.x.redMul(t.x),a=this.y.redMul(t.y),s=this.curve.d.redMul(o).redMul(a),u=i.redSub(s),c=i.redAdd(s),f=this.x.redAdd(this.y).redMul(t.x.redAdd(t.y)).redISub(o).redISub(a),l=r.redMul(u).redMul(f);return this.curve.twisted?(e=r.redMul(c).redMul(a.redSub(this.curve._mulA(o))),n=u.redMul(c)):(e=r.redMul(c).redMul(a.redSub(o)),n=this.curve._mulC(u).redMul(c)),this.curve.point(l,e,n)},c.prototype.add=function(t){return this.isInfinity()?t:t.isInfinity()?this:this.curve.extended?this._extAdd(t):this._projAdd(t)},c.prototype.mul=function(t){return this._hasDoubles(t)?this.curve._fixedNafMul(this,t):this.curve._wnafMul(this,t)},c.prototype.mulAdd=function(t,e,n){return this.curve._wnafMulAdd(1,[this,e],[t,n],2,!1)},c.prototype.jmulAdd=function(t,e,n){return this.curve._wnafMulAdd(1,[this,e],[t,n],2,!0)},c.prototype.normalize=function(){if(this.zOne)return this;var t=this.z.redInvm();return this.x=this.x.redMul(t),this.y=this.y.redMul(t),this.t&&(this.t=this.t.redMul(t)),this.z=this.curve.one,this.zOne=!0,this},c.prototype.neg=function(){return this.curve.point(this.x.redNeg(),this.y,this.z,this.t&&this.t.redNeg())},c.prototype.getX=function(){return this.normalize(),this.x.fromRed()},c.prototype.getY=function(){return this.normalize(),this.y.fromRed()},c.prototype.eq=function(t){return this===t||0===this.getX().cmp(t.getX())&&0===this.getY().cmp(t.getY())},c.prototype.eqXToP=function(t){var e=t.toRed(this.curve.red).redMul(this.z);if(0===this.x.cmp(e))return!0;for(var n=t.clone(),r=this.curve.redN.redMul(this.z);;){if(n.iadd(this.curve.n),n.cmp(this.curve.p)>=0)return!1;if(e.redIAdd(r),0===this.x.cmp(e))return!0}},c.prototype.toP=c.prototype.normalize,c.prototype.mixedAdd=c.prototype.add},function(t,e,n){"use strict";e.sha1=n(468),e.sha224=n(469),e.sha256=n(216),e.sha384=n(470),e.sha512=n(217)},function(t,e,n){"use strict";var r=n(21),i=n(56),o=n(215),a=r.rotl32,s=r.sum32,u=r.sum32_5,c=o.ft_1,f=i.BlockHash,l=[1518500249,1859775393,2400959708,3395469782];function h(){if(!(this instanceof h))return new h;f.call(this),this.h=[1732584193,4023233417,2562383102,271733878,3285377520],this.W=new Array(80)}r.inherits(h,f),t.exports=h,h.blockSize=512,h.outSize=160,h.hmacStrength=80,h.padLength=64,h.prototype._update=function(t,e){for(var n=this.W,r=0;r<16;r++)n[r]=t[e+r];for(;rthis.blockSize&&(t=(new this.Hash).update(t).digest()),i(t.length<=this.blockSize);for(var e=t.length;e0))return a.iaddn(1),this.keyFromPrivate(a)}},l.prototype._truncateToN=function(t,e){var n=8*t.byteLength()-this.n.bitLength();return n>0&&(t=t.ushrn(n)),!e&&t.cmp(this.n)>=0?t.sub(this.n):t},l.prototype.sign=function(t,e,n,o){"object"==typeof n&&(o=n,n=null),o||(o={}),e=this.keyFromPrivate(e,n),t=this._truncateToN(new r(t,16));for(var a=this.n.byteLength(),s=e.getPrivate().toArray("be",a),u=t.toArray("be",a),c=new i({hash:this.hash,entropy:s,nonce:u,pers:o.pers,persEnc:o.persEnc||"utf8"}),l=this.n.sub(new r(1)),h=0;;h++){var d=o.k?o.k(h):new r(c.generate(this.n.byteLength()));if(!((d=this._truncateToN(d,!0)).cmpn(1)<=0||d.cmp(l)>=0)){var p=this.g.mul(d);if(!p.isInfinity()){var g=p.getX(),y=g.umod(this.n);if(0!==y.cmpn(0)){var b=d.invm(this.n).mul(y.mul(e.getPrivate()).iadd(t));if(0!==(b=b.umod(this.n)).cmpn(0)){var m=(p.getY().isOdd()?1:0)|(0!==g.cmp(y)?2:0);return o.canonical&&b.cmp(this.nh)>0&&(b=this.n.sub(b),m^=1),new f({r:y,s:b,recoveryParam:m})}}}}}},l.prototype.verify=function(t,e,n,i){t=this._truncateToN(new r(t,16)),n=this.keyFromPublic(n,i);var o=(e=new f(e,"hex")).r,a=e.s;if(o.cmpn(1)<0||o.cmp(this.n)>=0)return!1;if(a.cmpn(1)<0||a.cmp(this.n)>=0)return!1;var s,u=a.invm(this.n),c=u.mul(t).umod(this.n),l=u.mul(o).umod(this.n);return this.curve._maxwellTrick?!(s=this.g.jmulAdd(c,n.getPublic(),l)).isInfinity()&&s.eqXToP(o):!(s=this.g.mulAdd(c,n.getPublic(),l)).isInfinity()&&0===s.getX().umod(this.n).cmp(o)},l.prototype.recoverPubKey=function(t,e,n,i){u((3&n)===n,"The recovery param is more than two bits"),e=new f(e,i);var o=this.n,a=new r(t),s=e.r,c=e.s,l=1&n,h=n>>1;if(s.cmp(this.curve.p.umod(this.curve.n))>=0&&h)throw new Error("Unable to find sencond key candinate");s=h?this.curve.pointFromX(s.add(this.curve.n),l):this.curve.pointFromX(s,l);var d=e.r.invm(o),p=o.sub(a).mul(d).umod(o),g=c.mul(d).umod(o);return this.g.mulAdd(p,s,g)},l.prototype.getKeyRecoveryParam=function(t,e,n,r){if(null!==(e=new f(e,r)).recoveryParam)return e.recoveryParam;for(var i=0;i<4;i++){var o;try{o=this.recoverPubKey(t,e,i)}catch(t){continue}if(o.eq(n))return i}throw new Error("Unable to find valid recovery factor")}},function(t,e,n){"use strict";var r=n(127),i=n(213),o=n(15);function a(t){if(!(this instanceof a))return new a(t);this.hash=t.hash,this.predResist=!!t.predResist,this.outLen=this.hash.outSize,this.minEntropy=t.minEntropy||this.hash.hmacStrength,this._reseed=null,this.reseedInterval=null,this.K=null,this.V=null;var e=i.toArray(t.entropy,t.entropyEnc||"hex"),n=i.toArray(t.nonce,t.nonceEnc||"hex"),r=i.toArray(t.pers,t.persEnc||"hex");o(e.length>=this.minEntropy/8,"Not enough entropy. Minimum is: "+this.minEntropy+" bits"),this._init(e,n,r)}t.exports=a,a.prototype._init=function(t,e,n){var r=t.concat(e).concat(n);this.K=new Array(this.outLen/8),this.V=new Array(this.outLen/8);for(var i=0;i=this.minEntropy/8,"Not enough entropy. Minimum is: "+this.minEntropy+" bits"),this._update(t.concat(n||[])),this._reseed=1},a.prototype.generate=function(t,e,n,r){if(this._reseed>this.reseedInterval)throw new Error("Reseed is required");"string"!=typeof e&&(r=n,n=e,e=null),n&&(n=i.toArray(n,r||"hex"),this._update(n));for(var o=[];o.length"}},function(t,e,n){"use strict";var r=n(5),i=n(16),o=i.assert;function a(t,e){if(t instanceof a)return t;this._importDER(t,e)||(o(t.r&&t.s,"Signature without r or s"),this.r=new r(t.r,16),this.s=new r(t.s,16),void 0===t.recoveryParam?this.recoveryParam=null:this.recoveryParam=t.recoveryParam)}function s(){this.place=0}function u(t,e){var n=t[e.place++];if(!(128&n))return n;for(var r=15&n,i=0,o=0,a=e.place;o>>3);for(t.push(128|n);--n;)t.push(e>>>(n<<3)&255);t.push(e)}}t.exports=a,a.prototype._importDER=function(t,e){t=i.toArray(t,e);var n=new s;if(48!==t[n.place++])return!1;if(u(t,n)+n.place!==t.length)return!1;if(2!==t[n.place++])return!1;var o=u(t,n),a=t.slice(n.place,o+n.place);if(n.place+=o,2!==t[n.place++])return!1;var c=u(t,n);if(t.length!==c+n.place)return!1;var f=t.slice(n.place,c+n.place);return 0===a[0]&&128&a[1]&&(a=a.slice(1)),0===f[0]&&128&f[1]&&(f=f.slice(1)),this.r=new r(a),this.s=new r(f),this.recoveryParam=null,!0},a.prototype.toDER=function(t){var e=this.r.toArray(),n=this.s.toArray();for(128&e[0]&&(e=[0].concat(e)),128&n[0]&&(n=[0].concat(n)),e=c(e),n=c(n);!(n[0]||128&n[1]);)n=n.slice(1);var r=[2];f(r,e.length),(r=r.concat(e)).push(2),f(r,n.length);var o=r.concat(n),a=[48];return f(a,o.length),a=a.concat(o),i.encode(a,t)}},function(t,e,n){"use strict";var r=n(127),i=n(126),o=n(16),a=o.assert,s=o.parseBytes,u=n(479),c=n(480);function f(t){if(a("ed25519"===t,"only tested with ed25519 so far"),!(this instanceof f))return new f(t);t=i[t].curve;this.curve=t,this.g=t.g,this.g.precompute(t.n.bitLength()+1),this.pointClass=t.point().constructor,this.encodingLength=Math.ceil(t.n.bitLength()/8),this.hash=r.sha512}t.exports=f,f.prototype.sign=function(t,e){t=s(t);var n=this.keyFromSecret(e),r=this.hashInt(n.messagePrefix(),t),i=this.g.mul(r),o=this.encodePoint(i),a=this.hashInt(o,n.pubBytes(),t).mul(n.priv()),u=r.add(a).umod(this.curve.n);return this.makeSignature({R:i,S:u,Rencoded:o})},f.prototype.verify=function(t,e,n){t=s(t),e=this.makeSignature(e);var r=this.keyFromPublic(n),i=this.hashInt(e.Rencoded(),r.pubBytes(),t),o=this.g.mul(e.S());return e.R().add(r.pub().mul(i)).eq(o)},f.prototype.hashInt=function(){for(var t=this.hash(),e=0;e=e)throw new Error("invalid sig")}t.exports=function(t,n,u,c,f){var l=o(u);if("ec"===l.type){if("ecdsa"!==c&&"ecdsa/rsa"!==c)throw new Error("wrong public key type");return function(t,e,n){var r=a[n.data.algorithm.curve.join(".")];if(!r)throw new Error("unknown curve "+n.data.algorithm.curve.join("."));var o=new i(r),s=n.data.subjectPrivateKey.data;return o.verify(e,t,s)}(t,n,l)}if("dsa"===l.type){if("dsa"!==c)throw new Error("wrong public key type");return function(t,e,n){var i=n.data.p,a=n.data.q,u=n.data.g,c=n.data.pub_key,f=o.signature.decode(t,"der"),l=f.s,h=f.r;s(l,a),s(h,a);var d=r.mont(i),p=l.invm(a);return 0===u.toRed(d).redPow(new r(e).mul(p).mod(a)).fromRed().mul(c.toRed(d).redPow(h.mul(p).mod(a)).fromRed()).mod(i).mod(a).cmp(h)}(t,n,l)}if("rsa"!==c&&"ecdsa/rsa"!==c)throw new Error("wrong public key type");n=e.concat([f,n]);for(var h=l.modulus.byteLength(),d=[1],p=0;n.length+d.length+2n-h-2)throw new Error("message too long");var d=l.alloc(n-r-h-2),p=n-f-1,g=i(f),y=s(l.concat([c,d,l.alloc(1,1),e],p),a(g,p)),b=s(g,a(y,f));return new u(l.concat([l.alloc(1),b,y],n))}(p,e);else if(1===h)d=function(t,e,n){var r,o=e.length,a=t.modulus.byteLength();if(o>a-11)throw new Error("message too long");r=n?l.alloc(a-o-3,255):function(t){var e,n=l.allocUnsafe(t),r=0,o=i(2*t),a=0;for(;r=0)throw new Error("data too long for modulus")}return n?f(d,p):c(d,p)}},function(t,e,n){var r=n(82),i=n(223),o=n(224),a=n(5),s=n(124),u=n(53),c=n(225),f=n(3).Buffer;t.exports=function(t,e,n){var l;l=t.padding?t.padding:n?1:4;var h,d=r(t),p=d.modulus.byteLength();if(e.length>p||new a(e).cmp(d.modulus)>=0)throw new Error("decryption error");h=n?c(new a(e),d):s(e,d);var g=f.alloc(p-h.length);if(h=f.concat([g,h],p),4===l)return function(t,e){var n=t.modulus.byteLength(),r=u("sha1").update(f.alloc(0)).digest(),a=r.length;if(0!==e[0])throw new Error("decryption error");var s=e.slice(1,a+1),c=e.slice(a+1),l=o(s,i(c,a)),h=o(c,i(l,n-a-1));if(function(t,e){t=f.from(t),e=f.from(e);var n=0,r=t.length;t.length!==e.length&&(n++,r=Math.min(t.length,e.length));var i=-1;for(;++i=e.length){o++;break}var a=e.slice(2,i-1);("0002"!==r.toString("hex")&&!n||"0001"!==r.toString("hex")&&n)&&o++;a.length<8&&o++;if(o)throw new Error("decryption error");return e.slice(i)}(0,h,n);if(3===l)return h;throw new Error("unknown padding")}},function(t,e,n){"use strict";(function(t,r){function i(){throw new Error("secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11")}var o=n(3),a=n(44),s=o.Buffer,u=o.kMaxLength,c=t.crypto||t.msCrypto,f=Math.pow(2,32)-1;function l(t,e){if("number"!=typeof t||t!=t)throw new TypeError("offset must be a number");if(t>f||t<0)throw new TypeError("offset must be a uint32");if(t>u||t>e)throw new RangeError("offset out of range")}function h(t,e,n){if("number"!=typeof t||t!=t)throw new TypeError("size must be a number");if(t>f||t<0)throw new TypeError("size must be a uint32");if(t+e>n||t>u)throw new RangeError("buffer too small")}function d(t,e,n,i){if(r.browser){var o=t.buffer,s=new Uint8Array(o,e,n);return c.getRandomValues(s),i?void r.nextTick((function(){i(null,t)})):t}if(!i)return a(n).copy(t,e),t;a(n,(function(n,r){if(n)return i(n);r.copy(t,e),i(null,t)}))}c&&c.getRandomValues||!r.browser?(e.randomFill=function(e,n,r,i){if(!(s.isBuffer(e)||e instanceof t.Uint8Array))throw new TypeError('"buf" argument must be a Buffer or Uint8Array');if("function"==typeof n)i=n,n=0,r=e.length;else if("function"==typeof r)i=r,r=e.length-n;else if("function"!=typeof i)throw new TypeError('"cb" argument must be a function');return l(n,e.length),h(r,n,e.length),d(e,n,r,i)},e.randomFillSync=function(e,n,r){void 0===n&&(n=0);if(!(s.isBuffer(e)||e instanceof t.Uint8Array))throw new TypeError('"buf" argument must be a Buffer or Uint8Array');l(n,e.length),void 0===r&&(r=e.length-n);return h(r,n,e.length),d(e,n,r)}):(e.randomFill=i,e.randomFillSync=i)}).call(this,n(11),n(7))},function(t,e,n){var r={"./dark/index.scss":501,"./default/index.scss":503,"./forest/index.scss":505,"./neutral/index.scss":507};function i(t){var e=o(t);return n(e)}function o(t){if(!n.o(r,t)){var e=new Error("Cannot find module '"+t+"'");throw e.code="MODULE_NOT_FOUND",e}return r[t]}i.keys=function(){return Object.keys(r)},i.resolve=o,t.exports=i,i.id=500},function(t,e,n){var r=n(502);t.exports="string"==typeof r?r:r.toString()},function(t,e,n){(t.exports=n(83)(!1)).push([t.i,".label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);color:#333}.label text{fill:#333}.node rect,.node circle,.node ellipse,.node polygon{fill:#BDD5EA;stroke:purple;stroke-width:1px}.node .label{text-align:center}.node.clickable{cursor:pointer}.arrowheadPath{fill:#d3d3d3}.edgePath .path{stroke:#d3d3d3;stroke-width:1.5px}.edgeLabel{background-color:#e8e8e8;text-align:center}.cluster rect{fill:#6D6D65;stroke:rgba(255,255,255,0.25);stroke-width:1px}.cluster text{fill:#F9FFFE}div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#6D6D65;border:1px solid rgba(255,255,255,0.25);border-radius:2px;pointer-events:none;z-index:100}.actor{stroke:#81B1DB;fill:#BDD5EA}text.actor{fill:#000;stroke:none}.actor-line{stroke:#d3d3d3}.messageLine0{stroke-width:1.5;stroke-dasharray:'2 2';stroke:#d3d3d3}.messageLine1{stroke-width:1.5;stroke-dasharray:'2 2';stroke:#d3d3d3}#arrowhead{fill:#d3d3d3}.sequenceNumber{fill:#fff}#sequencenumber{fill:#d3d3d3}#crosshead path{fill:#d3d3d3 !important;stroke:#d3d3d3 !important}.messageText{fill:#d3d3d3;stroke:none}.labelBox{stroke:#81B1DB;fill:#BDD5EA}.labelText{fill:#323D47;stroke:none}.loopText{fill:#d3d3d3;stroke:none}.loopLine{stroke-width:2;stroke-dasharray:'2 2';stroke:#81B1DB}.note{stroke:rgba(255,255,255,0.25);fill:#fff5ad}.noteText{fill:black;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:14px}.activation0{fill:#f4f4f4;stroke:#666}.activation1{fill:#f4f4f4;stroke:#666}.activation2{fill:#f4f4f4;stroke:#666}.mermaid-main-font{font-family:\"trebuchet ms\", verdana, arial;font-family:var(--mermaid-font-family)}.section{stroke:none;opacity:0.2}.section0{fill:rgba(255,255,255,0.3)}.section2{fill:#EAE8B9}.section1,.section3{fill:#fff;opacity:0.2}.sectionTitle0{fill:#F9FFFE}.sectionTitle1{fill:#F9FFFE}.sectionTitle2{fill:#F9FFFE}.sectionTitle3{fill:#F9FFFE}.sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.grid .tick{stroke:#d3d3d3;opacity:0.3;shape-rendering:crispEdges}.grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.grid path{stroke-width:0}.today{fill:none;stroke:#DB5757;stroke-width:2px}.task{stroke-width:2}.taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.taskText:not([font-size]){font-size:11px}.taskTextOutsideRight{fill:#323D47;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.taskTextOutsideLeft{fill:#323D47;text-anchor:end;font-size:11px}.task.clickable{cursor:pointer}.taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskText0,.taskText1,.taskText2,.taskText3{fill:#323D47}.task0,.task1,.task2,.task3{fill:#BDD5EA;stroke:rgba(255,255,255,0.5)}.taskTextOutside0,.taskTextOutside2{fill:#d3d3d3}.taskTextOutside1,.taskTextOutside3{fill:#d3d3d3}.active0,.active1,.active2,.active3{fill:#81B1DB;stroke:rgba(255,255,255,0.5)}.activeText0,.activeText1,.activeText2,.activeText3{fill:#323D47 !important}.done0,.done1,.done2,.done3{stroke:grey;fill:#d3d3d3;stroke-width:2}.doneText0,.doneText1,.doneText2,.doneText3{fill:#323D47 !important}.crit0,.crit1,.crit2,.crit3{stroke:#E83737;fill:#E83737;stroke-width:2}.activeCrit0,.activeCrit1,.activeCrit2,.activeCrit3{stroke:#E83737;fill:#81B1DB;stroke-width:2}.doneCrit0,.doneCrit1,.doneCrit2,.doneCrit3{stroke:#E83737;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}.milestone{transform:rotate(45deg) scale(0.8, 0.8)}.milestoneText{font-style:italic}.doneCritText0,.doneCritText1,.doneCritText2,.doneCritText3{fill:#323D47 !important}.activeCritText0,.activeCritText1,.activeCritText2,.activeCritText3{fill:#323D47 !important}.titleText{text-anchor:middle;font-size:18px;fill:#323D47;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.classGroup text{fill:purple;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}g.classGroup text .title{font-weight:bolder}g.classGroup rect{fill:#BDD5EA;stroke:purple}g.classGroup line{stroke:purple;stroke-width:1}.classLabel .box{stroke:none;stroke-width:0;fill:#BDD5EA;opacity:0.5}.classLabel .label{fill:purple;font-size:10px}.relation{stroke:purple;stroke-width:1;fill:none}#compositionStart{fill:purple;stroke:purple;stroke-width:1}#compositionEnd{fill:purple;stroke:purple;stroke-width:1}#aggregationStart{fill:#BDD5EA;stroke:purple;stroke-width:1}#aggregationEnd{fill:#BDD5EA;stroke:purple;stroke-width:1}#dependencyStart{fill:purple;stroke:purple;stroke-width:1}#dependencyEnd{fill:purple;stroke:purple;stroke-width:1}#extensionStart{fill:purple;stroke:purple;stroke-width:1}#extensionEnd{fill:purple;stroke:purple;stroke-width:1}.commit-id,.commit-msg,.branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.pieTitleText{text-anchor:middle;font-size:25px;fill:#323D47;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.stateGroup text{fill:purple;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.stateGroup text{fill:purple;stroke:none;font-size:10px}g.stateGroup .state-title{font-weight:bolder;fill:#000}g.stateGroup rect{fill:#BDD5EA;stroke:purple}g.stateGroup line{stroke:purple;stroke-width:1}.transition{stroke:purple;stroke-width:1;fill:none}.stateGroup .composit{fill:white;border-bottom:1px}.state-note{stroke:rgba(255,255,255,0.25);fill:#fff5ad}.state-note text{fill:black;stroke:none;font-size:10px}.stateLabel .box{stroke:none;stroke-width:0;fill:#BDD5EA;opacity:0.5}.stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}:root{--mermaid-font-family: '\"trebuchet ms\", verdana, arial';--mermaid-font-family: \"Comic Sans MS\", \"Comic Sans\", cursive}\n",""])},function(t,e,n){var r=n(504);t.exports="string"==typeof r?r:r.toString()},function(t,e,n){(t.exports=n(83)(!1)).push([t.i,".label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);color:#333}.label text{fill:#333}.node rect,.node circle,.node ellipse,.node polygon{fill:#ECECFF;stroke:#9370db;stroke-width:1px}.node .label{text-align:center}.node.clickable{cursor:pointer}.arrowheadPath{fill:#333}.edgePath .path{stroke:#333;stroke-width:1.5px}.edgeLabel{background-color:#e8e8e8;text-align:center}.cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}.cluster text{fill:#333}div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}.actor{stroke:#ccf;fill:#ECECFF}text.actor{fill:#000;stroke:none}.actor-line{stroke:grey}.messageLine0{stroke-width:1.5;stroke-dasharray:'2 2';stroke:#333}.messageLine1{stroke-width:1.5;stroke-dasharray:'2 2';stroke:#333}#arrowhead{fill:#333}.sequenceNumber{fill:#fff}#sequencenumber{fill:#333}#crosshead path{fill:#333 !important;stroke:#333 !important}.messageText{fill:#333;stroke:none}.labelBox{stroke:#ccf;fill:#ECECFF}.labelText{fill:#000;stroke:none}.loopText{fill:#000;stroke:none}.loopLine{stroke-width:2;stroke-dasharray:'2 2';stroke:#ccf}.note{stroke:#aa3;fill:#fff5ad}.noteText{fill:black;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:14px}.activation0{fill:#f4f4f4;stroke:#666}.activation1{fill:#f4f4f4;stroke:#666}.activation2{fill:#f4f4f4;stroke:#666}.mermaid-main-font{font-family:\"trebuchet ms\", verdana, arial;font-family:var(--mermaid-font-family)}.section{stroke:none;opacity:0.2}.section0{fill:rgba(102,102,255,0.49)}.section2{fill:#fff400}.section1,.section3{fill:#fff;opacity:0.2}.sectionTitle0{fill:#333}.sectionTitle1{fill:#333}.sectionTitle2{fill:#333}.sectionTitle3{fill:#333}.sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.grid .tick{stroke:#d3d3d3;opacity:0.3;shape-rendering:crispEdges}.grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.grid path{stroke-width:0}.today{fill:none;stroke:red;stroke-width:2px}.task{stroke-width:2}.taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.taskText:not([font-size]){font-size:11px}.taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}.task.clickable{cursor:pointer}.taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskText0,.taskText1,.taskText2,.taskText3{fill:#fff}.task0,.task1,.task2,.task3{fill:#8a90dd;stroke:#534fbc}.taskTextOutside0,.taskTextOutside2{fill:#000}.taskTextOutside1,.taskTextOutside3{fill:#000}.active0,.active1,.active2,.active3{fill:#bfc7ff;stroke:#534fbc}.activeText0,.activeText1,.activeText2,.activeText3{fill:#000 !important}.done0,.done1,.done2,.done3{stroke:grey;fill:#d3d3d3;stroke-width:2}.doneText0,.doneText1,.doneText2,.doneText3{fill:#000 !important}.crit0,.crit1,.crit2,.crit3{stroke:#f88;fill:red;stroke-width:2}.activeCrit0,.activeCrit1,.activeCrit2,.activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}.doneCrit0,.doneCrit1,.doneCrit2,.doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}.milestone{transform:rotate(45deg) scale(0.8, 0.8)}.milestoneText{font-style:italic}.doneCritText0,.doneCritText1,.doneCritText2,.doneCritText3{fill:#000 !important}.activeCritText0,.activeCritText1,.activeCritText2,.activeCritText3{fill:#000 !important}.titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}g.classGroup text .title{font-weight:bolder}g.classGroup rect{fill:#ECECFF;stroke:#9370db}g.classGroup line{stroke:#9370db;stroke-width:1}.classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}.classLabel .label{fill:#9370db;font-size:10px}.relation{stroke:#9370db;stroke-width:1;fill:none}#compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}.commit-id,.commit-msg,.branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.stateGroup text{fill:#9370db;stroke:none;font-size:10px}g.stateGroup .state-title{font-weight:bolder;fill:#000}g.stateGroup rect{fill:#ECECFF;stroke:#9370db}g.stateGroup line{stroke:#9370db;stroke-width:1}.transition{stroke:#9370db;stroke-width:1;fill:none}.stateGroup .composit{fill:white;border-bottom:1px}.state-note{stroke:#aa3;fill:#fff5ad}.state-note text{fill:black;stroke:none;font-size:10px}.stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}.stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}:root{--mermaid-font-family: '\"trebuchet ms\", verdana, arial';--mermaid-font-family: \"Comic Sans MS\", \"Comic Sans\", cursive}\n",""])},function(t,e,n){var r=n(506);t.exports="string"==typeof r?r:r.toString()},function(t,e,n){(t.exports=n(83)(!1)).push([t.i,".label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);color:#333}.label text{fill:#333}.node rect,.node circle,.node ellipse,.node polygon{fill:#cde498;stroke:#13540c;stroke-width:1px}.node .label{text-align:center}.node.clickable{cursor:pointer}.arrowheadPath{fill:green}.edgePath .path{stroke:green;stroke-width:1.5px}.edgeLabel{background-color:#e8e8e8;text-align:center}.cluster rect{fill:#cdffb2;stroke:#6eaa49;stroke-width:1px}.cluster text{fill:#333}div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#cdffb2;border:1px solid #6eaa49;border-radius:2px;pointer-events:none;z-index:100}.actor{stroke:#13540c;fill:#cde498}text.actor{fill:#000;stroke:none}.actor-line{stroke:grey}.messageLine0{stroke-width:1.5;stroke-dasharray:'2 2';stroke:#333}.messageLine1{stroke-width:1.5;stroke-dasharray:'2 2';stroke:#333}#arrowhead{fill:#333}.sequenceNumber{fill:#fff}#sequencenumber{fill:#333}#crosshead path{fill:#333 !important;stroke:#333 !important}.messageText{fill:#333;stroke:none}.labelBox{stroke:#326932;fill:#cde498}.labelText{fill:#000;stroke:none}.loopText{fill:#000;stroke:none}.loopLine{stroke-width:2;stroke-dasharray:'2 2';stroke:#326932}.note{stroke:#6eaa49;fill:#fff5ad}.noteText{fill:black;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:14px}.activation0{fill:#f4f4f4;stroke:#666}.activation1{fill:#f4f4f4;stroke:#666}.activation2{fill:#f4f4f4;stroke:#666}.mermaid-main-font{font-family:\"trebuchet ms\", verdana, arial;font-family:var(--mermaid-font-family)}.section{stroke:none;opacity:0.2}.section0{fill:#6eaa49}.section2{fill:#6eaa49}.section1,.section3{fill:#fff;opacity:0.2}.sectionTitle0{fill:#333}.sectionTitle1{fill:#333}.sectionTitle2{fill:#333}.sectionTitle3{fill:#333}.sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.grid .tick{stroke:#d3d3d3;opacity:0.3;shape-rendering:crispEdges}.grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.grid path{stroke-width:0}.today{fill:none;stroke:red;stroke-width:2px}.task{stroke-width:2}.taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.taskText:not([font-size]){font-size:11px}.taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}.task.clickable{cursor:pointer}.taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskText0,.taskText1,.taskText2,.taskText3{fill:#fff}.task0,.task1,.task2,.task3{fill:#487e3a;stroke:#13540c}.taskTextOutside0,.taskTextOutside2{fill:#000}.taskTextOutside1,.taskTextOutside3{fill:#000}.active0,.active1,.active2,.active3{fill:#cde498;stroke:#13540c}.activeText0,.activeText1,.activeText2,.activeText3{fill:#000 !important}.done0,.done1,.done2,.done3{stroke:grey;fill:#d3d3d3;stroke-width:2}.doneText0,.doneText1,.doneText2,.doneText3{fill:#000 !important}.crit0,.crit1,.crit2,.crit3{stroke:#f88;fill:red;stroke-width:2}.activeCrit0,.activeCrit1,.activeCrit2,.activeCrit3{stroke:#f88;fill:#cde498;stroke-width:2}.doneCrit0,.doneCrit1,.doneCrit2,.doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}.milestone{transform:rotate(45deg) scale(0.8, 0.8)}.milestoneText{font-style:italic}.doneCritText0,.doneCritText1,.doneCritText2,.doneCritText3{fill:#000 !important}.activeCritText0,.activeCritText1,.activeCritText2,.activeCritText3{fill:#000 !important}.titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.classGroup text{fill:#13540c;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}g.classGroup text .title{font-weight:bolder}g.classGroup rect{fill:#cde498;stroke:#13540c}g.classGroup line{stroke:#13540c;stroke-width:1}.classLabel .box{stroke:none;stroke-width:0;fill:#cde498;opacity:0.5}.classLabel .label{fill:#13540c;font-size:10px}.relation{stroke:#13540c;stroke-width:1;fill:none}#compositionStart{fill:#13540c;stroke:#13540c;stroke-width:1}#compositionEnd{fill:#13540c;stroke:#13540c;stroke-width:1}#aggregationStart{fill:#cde498;stroke:#13540c;stroke-width:1}#aggregationEnd{fill:#cde498;stroke:#13540c;stroke-width:1}#dependencyStart{fill:#13540c;stroke:#13540c;stroke-width:1}#dependencyEnd{fill:#13540c;stroke:#13540c;stroke-width:1}#extensionStart{fill:#13540c;stroke:#13540c;stroke-width:1}#extensionEnd{fill:#13540c;stroke:#13540c;stroke-width:1}.commit-id,.commit-msg,.branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.stateGroup text{fill:#13540c;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.stateGroup text{fill:#13540c;stroke:none;font-size:10px}g.stateGroup .state-title{font-weight:bolder;fill:#000}g.stateGroup rect{fill:#cde498;stroke:#13540c}g.stateGroup line{stroke:#13540c;stroke-width:1}.transition{stroke:#13540c;stroke-width:1;fill:none}.stateGroup .composit{fill:white;border-bottom:1px}.state-note{stroke:#6eaa49;fill:#fff5ad}.state-note text{fill:black;stroke:none;font-size:10px}.stateLabel .box{stroke:none;stroke-width:0;fill:#cde498;opacity:0.5}.stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}:root{--mermaid-font-family: '\"trebuchet ms\", verdana, arial';--mermaid-font-family: \"Comic Sans MS\", \"Comic Sans\", cursive}\n",""])},function(t,e,n){var r=n(508);t.exports="string"==typeof r?r:r.toString()},function(t,e,n){(t.exports=n(83)(!1)).push([t.i,".label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);color:#333}.label text{fill:#333}.node rect,.node circle,.node ellipse,.node polygon{fill:#eee;stroke:#999;stroke-width:1px}.node .label{text-align:center}.node.clickable{cursor:pointer}.arrowheadPath{fill:#333}.edgePath .path{stroke:#666;stroke-width:1.5px}.edgeLabel{background-color:#fff;text-align:center}.cluster rect{fill:#eaf2fb;stroke:#26a;stroke-width:1px}.cluster text{fill:#333}div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#eaf2fb;border:1px solid #26a;border-radius:2px;pointer-events:none;z-index:100}.actor{stroke:#999;fill:#eee}text.actor{fill:#333;stroke:none}.actor-line{stroke:#666}.messageLine0{stroke-width:1.5;stroke-dasharray:'2 2';stroke:#333}.messageLine1{stroke-width:1.5;stroke-dasharray:'2 2';stroke:#333}#arrowhead{fill:#333}.sequenceNumber{fill:#fff}#sequencenumber{fill:#333}#crosshead path{fill:#333 !important;stroke:#333 !important}.messageText{fill:#333;stroke:none}.labelBox{stroke:#999;fill:#eee}.labelText{fill:#333;stroke:none}.loopText{fill:#333;stroke:none}.loopLine{stroke-width:2;stroke-dasharray:'2 2';stroke:#999}.note{stroke:#770;fill:#ffa}.noteText{fill:black;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:14px}.activation0{fill:#f4f4f4;stroke:#666}.activation1{fill:#f4f4f4;stroke:#666}.activation2{fill:#f4f4f4;stroke:#666}.mermaid-main-font{font-family:\"trebuchet ms\", verdana, arial;font-family:var(--mermaid-font-family)}.section{stroke:none;opacity:0.2}.section0{fill:#80b3e6}.section2{fill:#80b3e6}.section1,.section3{fill:#fff;opacity:0.2}.sectionTitle0{fill:#333}.sectionTitle1{fill:#333}.sectionTitle2{fill:#333}.sectionTitle3{fill:#333}.sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.grid .tick{stroke:#e6e6e6;opacity:0.3;shape-rendering:crispEdges}.grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.grid path{stroke-width:0}.today{fill:none;stroke:#d42;stroke-width:2px}.task{stroke-width:2}.taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.taskText:not([font-size]){font-size:11px}.taskTextOutsideRight{fill:#333;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.taskTextOutsideLeft{fill:#333;text-anchor:end;font-size:11px}.task.clickable{cursor:pointer}.taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}.taskText0,.taskText1,.taskText2,.taskText3{fill:#fff}.task0,.task1,.task2,.task3{fill:#26a;stroke:#1a4d80}.taskTextOutside0,.taskTextOutside2{fill:#333}.taskTextOutside1,.taskTextOutside3{fill:#333}.active0,.active1,.active2,.active3{fill:#eee;stroke:#1a4d80}.activeText0,.activeText1,.activeText2,.activeText3{fill:#333 !important}.done0,.done1,.done2,.done3{stroke:#666;fill:#bbb;stroke-width:2}.doneText0,.doneText1,.doneText2,.doneText3{fill:#333 !important}.crit0,.crit1,.crit2,.crit3{stroke:#b1361b;fill:#d42;stroke-width:2}.activeCrit0,.activeCrit1,.activeCrit2,.activeCrit3{stroke:#b1361b;fill:#eee;stroke-width:2}.doneCrit0,.doneCrit1,.doneCrit2,.doneCrit3{stroke:#b1361b;fill:#bbb;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}.milestone{transform:rotate(45deg) scale(0.8, 0.8)}.milestoneText{font-style:italic}.doneCritText0,.doneCritText1,.doneCritText2,.doneCritText3{fill:#333 !important}.activeCritText0,.activeCritText1,.activeCritText2,.activeCritText3{fill:#333 !important}.titleText{text-anchor:middle;font-size:18px;fill:#333;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.classGroup text{fill:#999;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}g.classGroup text .title{font-weight:bolder}g.classGroup rect{fill:#eee;stroke:#999}g.classGroup line{stroke:#999;stroke-width:1}.classLabel .box{stroke:none;stroke-width:0;fill:#eee;opacity:0.5}.classLabel .label{fill:#999;font-size:10px}.relation{stroke:#999;stroke-width:1;fill:none}#compositionStart{fill:#999;stroke:#999;stroke-width:1}#compositionEnd{fill:#999;stroke:#999;stroke-width:1}#aggregationStart{fill:#eee;stroke:#999;stroke-width:1}#aggregationEnd{fill:#eee;stroke:#999;stroke-width:1}#dependencyStart{fill:#999;stroke:#999;stroke-width:1}#dependencyEnd{fill:#999;stroke:#999;stroke-width:1}#extensionStart{fill:#999;stroke:#999;stroke-width:1}#extensionEnd{fill:#999;stroke:#999;stroke-width:1}.commit-id,.commit-msg,.branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.pieTitleText{text-anchor:middle;font-size:25px;fill:#333;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}.slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.stateGroup text{fill:#999;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}g.stateGroup text{fill:#999;stroke:none;font-size:10px}g.stateGroup .state-title{font-weight:bolder;fill:#000}g.stateGroup rect{fill:#eee;stroke:#999}g.stateGroup line{stroke:#999;stroke-width:1}.transition{stroke:#999;stroke-width:1;fill:none}.stateGroup .composit{fill:white;border-bottom:1px}.state-note{stroke:#770;fill:#ffa}.state-note text{fill:black;stroke:none;font-size:10px}.stateLabel .box{stroke:none;stroke-width:0;fill:#eee;opacity:0.5}.stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}:root{--mermaid-font-family: '\"trebuchet ms\", verdana, arial';--mermaid-font-family: \"Comic Sans MS\", \"Comic Sans\", cursive}\n",""])},function(t,e,n){"use strict";n.r(e);var r=n(226),i=n.n(r),o=n(0),a=n(227),s=n.n(a),u=n(88);let c={};const f=t=>{!function(t){const e=Object.keys(t);for(let n=0;nc;var h=n(23),d=n.n(h);const p=1,g=2,y=3,b=4,m=5,v={debug:()=>{},info:()=>{},warn:()=>{},error:()=>{},fatal:()=>{}},_=function(t){v.debug=()=>{},v.info=()=>{},v.warn=()=>{},v.error=()=>{},v.fatal=()=>{},t<=m&&(v.fatal=console.log.bind(console,"",w("FATAL"))),t<=b&&(v.error=console.log.bind(console,"",w("ERROR"))),t<=y&&(v.warn=console.log.bind(console,"",w("WARN"))),t<=g&&(v.info=console.log.bind(console,"",w("INFO"))),t<=p&&(v.debug=console.log.bind(console,"",w("DEBUG")))},w=t=>{return`${d()().format("HH:mm:ss.SSS")} : ${t} : `},x=(t,e)=>{if(!t)return e;const n=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return o[n]||e},k=(t,e)=>t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0;var E={detectType:function(t){return t=t.replace(/^\s*%%.*\n/g,"\n"),v.debug("Detecting diagram type based on the text "+t),t.match(/^\s*sequenceDiagram/)?"sequence":t.match(/^\s*gantt/)?"gantt":t.match(/^\s*classDiagram/)?"class":t.match(/^\s*stateDiagram/)?"state":t.match(/^\s*gitGraph/)?"git":t.match(/^\s*info/)?"info":t.match(/^\s*pie/)?"pie":"flowchart"},isSubstringInArray:function(t,e){for(let n=0;n{return(t=>{let e,n=0;t.forEach(t=>{n+=k(t,e),e=t});let r,i=n/2;return e=void 0,t.forEach(t=>{if(e&&!r){const n=k(t,e);if(n=1&&(r={x:t.x,y:t.y}),o>0&&o<1&&(r={x:(1-o)*e.x+o*t.x,y:(1-o)*e.y+o*t.y})}}e=t}),r})(t)},calcCardinalityPosition:(t,e,n)=>{let r,i=0;e[0]!==n&&(e=e.reverse()),e.forEach(t=>{i+=k(t,r),r=t});let o,a=25;r=void 0,e.forEach(t=>{if(r&&!o){const e=k(t,r);if(e=1&&(o={x:t.x,y:t.y}),n>0&&n<1&&(o={x:(1-n)*r.x+n*t.x,y:(1-n)*r.y+n*t.y})}}r=t});let s=t?10:5,u=Math.atan2(e[0].y-o.y,e[0].x-o.x),c={x:0,y:0};return c.x=Math.sin(u)*s+(e[0].x+o.x)/2,c.y=-Math.cos(u)*s+(e[0].y+o.y)/2,c}},A=n(22),S=n.n(A),T=n(84);const M=l();let D,C={},O=[],R=[],I=[],N={},B={},L=0,P=!0,F=[];const q=t=>{let e=t;return"loose"!==M.securityLevel&&(e=(e=(e=(e=(e=e.replace(/
    /g,"#br#")).replace(//g,"#br#")).replace(//g,">")).replace(/=/g,"=")).replace(/#br#/g,"
    ")),e},j=function(t,e){t.split(",").forEach((function(t){let n=t;t[0].match(/\d/)&&(n=""+n),void 0!==C[n]&&C[n].classes.push(e),void 0!==N[n]&&N[n].classes.push(e)}))},U=function(t,e){t.split(",").forEach((function(t){void 0!==e&&(B[t]=q(e))}))},z=function(t){let e=o.select(".mermaidTooltip");null===(e._groups||e)[0][0]&&(e=o.select("body").append("div").attr("class","mermaidTooltip").style("opacity",0)),o.select(t).select("svg").selectAll("g.node").on("mouseover",(function(){const t=o.select(this);if(null===t.attr("title"))return;const n=this.getBoundingClientRect();e.transition().duration(200).style("opacity",".9"),e.html(t.attr("title")).style("left",n.left+(n.right-n.left)/2+"px").style("top",n.top-14+document.body.scrollTop+"px"),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0),o.select(this).classed("hover",!1)}))};F.push(z);const Y=function(t){for(let e=0;e2e3)return;if(H[V]=e,I[e].id===t)return{result:!0,count:0};let r=0,i=1;for(;r=0){const n=$(t,e);if(n.result)return{result:!0,count:i+n.count};i+=n.count}r+=1}return{result:!1,count:i}};var G={addVertex:function(t,e,n,r,i){let o,a=t;void 0!==a&&0!==a.trim().length&&(a[0].match(/\d/)&&(a=""+a),void 0===C[a]&&(C[a]={id:a,styles:[],classes:[]}),void 0!==e?('"'===(o=q(e.trim()))[0]&&'"'===o[o.length-1]&&(o=o.substring(1,o.length-1)),C[a].text=o):C[a].text||(C[a].text=t),void 0!==n&&(C[a].type=n),null!=r&&r.forEach((function(t){C[a].styles.push(t)})),null!=i&&i.forEach((function(t){C[a].classes.push(t)})))},addLink:function(t,e,n,r){let i=t,o=e;i[0].match(/\d/)&&(i=""+i),o[0].match(/\d/)&&(o=""+o),v.info("Got edge...",i,o);const a={start:i,end:o,type:void 0,text:""};void 0!==(r=n.text)&&(a.text=q(r.trim()),'"'===a.text[0]&&'"'===a.text[a.text.length-1]&&(a.text=a.text.substring(1,a.text.length-1))),void 0!==n&&(a.type=n.type,a.stroke=n.stroke),O.push(a)},updateLinkInterpolate:function(t,e){t.forEach((function(t){"default"===t?O.defaultInterpolate=e:O[t].interpolate=e}))},updateLink:function(t,e){t.forEach((function(t){"default"===t?O.defaultStyle=e:(-1===E.isSubstringInArray("fill",e)&&e.push("fill:none"),O[t].style=e)}))},addClass:function(t,e){void 0===R[t]&&(R[t]={id:t,styles:[]}),null!=e&&e.forEach((function(e){R[t].styles.push(e)}))},setDirection:function(t){(D=t).match(/.*/)&&(D="LR"),D.match(/.*v/)&&(D="TB")},setClass:j,getTooltip:function(t){return B[t]},setClickEvent:function(t,e,n){t.split(",").forEach((function(t){!function(t,e){let n=t;t[0].match(/\d/)&&(n=""+n),"loose"===M.securityLevel&&void 0!==e&&void 0!==C[n]&&F.push((function(){const t=document.querySelector(`[id="${n}"]`);null!==t&&t.addEventListener("click",(function(){window[e](n)}),!1)}))}(t,e)})),U(t,n),j(t,"clickable")},setLink:function(t,e,n){t.split(",").forEach((function(t){let n=t;t[0].match(/\d/)&&(n=""+n),void 0!==C[n]&&("loose"!==M.securityLevel?C[n].link=Object(T.sanitizeUrl)(e):C[n].link=e)})),U(t,n),j(t,"clickable")},bindFunctions:function(t){F.forEach((function(e){e(t)}))},getDirection:function(){return D.trim()},getVertices:function(){return C},getEdges:function(){return O},getClasses:function(){return R},clear:function(){C={},R={},O=[],(F=[]).push(z),I=[],N={},L=0,B=[],P=!0},defaultStyle:function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},addSubGraph:function(t,e,n){let r=t,i=n;t===n&&n.match(/\s/)&&(r=void 0);let o=[];o=function(t){const e={boolean:{},number:{},string:{}},n=[];return t.filter((function(t){const r=typeof t;return""!==t.trim()&&(r in e?!e[r].hasOwnProperty(t)&&(e[r][t]=!0):!(n.indexOf(t)>=0)&&n.push(t))}))}(o.concat.apply(o,e));for(let t=0;t0&&$("none",I.length-1,0)},getSubGraphs:function(){return I},lex:{firstGraph:()=>!!P&&(P=!1,!0)}},W=n(60),K=n.n(W),X=n(17),Z=n.n(X),J=n(128),Q=n.n(J);function tt(t,e,n){const r=.9*(e.width+e.height),i=[{x:r/2,y:0},{x:r,y:-r/2},{x:r/2,y:-r},{x:0,y:-r/2}],o=ut(t,r,r,i);return n.intersect=function(t){return Z.a.intersect.polygon(n,i,t)},o}function et(t,e,n){const r=e.height,i=r/4,o=e.width+2*i,a=[{x:i,y:0},{x:o-i,y:0},{x:o,y:-r/2},{x:o-i,y:-r},{x:i,y:-r},{x:0,y:-r/2}],s=ut(t,o,r,a);return n.intersect=function(t){return Z.a.intersect.polygon(n,a,t)},s}function nt(t,e,n){const r=e.width,i=e.height,o=[{x:-i/2,y:0},{x:r,y:0},{x:r,y:-i},{x:-i/2,y:-i},{x:0,y:-i/2}],a=ut(t,r,i,o);return n.intersect=function(t){return Z.a.intersect.polygon(n,o,t)},a}function rt(t,e,n){const r=e.width,i=e.height,o=[{x:-2*i/6,y:0},{x:r-i/6,y:0},{x:r+2*i/6,y:-i},{x:i/6,y:-i}],a=ut(t,r,i,o);return n.intersect=function(t){return Z.a.intersect.polygon(n,o,t)},a}function it(t,e,n){const r=e.width,i=e.height,o=[{x:2*i/6,y:0},{x:r+i/6,y:0},{x:r-2*i/6,y:-i},{x:-i/6,y:-i}],a=ut(t,r,i,o);return n.intersect=function(t){return Z.a.intersect.polygon(n,o,t)},a}function ot(t,e,n){const r=e.width,i=e.height,o=[{x:-2*i/6,y:0},{x:r+2*i/6,y:0},{x:r-i/6,y:-i},{x:i/6,y:-i}],a=ut(t,r,i,o);return n.intersect=function(t){return Z.a.intersect.polygon(n,o,t)},a}function at(t,e,n){const r=e.width,i=e.height,o=[{x:i/6,y:0},{x:r-i/6,y:0},{x:r+2*i/6,y:-i},{x:-2*i/6,y:-i}],a=ut(t,r,i,o);return n.intersect=function(t){return Z.a.intersect.polygon(n,o,t)},a}function st(t,e,n){const r=e.width,i=e.height,o=[{x:0,y:0},{x:r+i/2,y:0},{x:r,y:-i/2},{x:r+i/2,y:-i},{x:0,y:-i}],a=ut(t,r,i,o);return n.intersect=function(t){return Z.a.intersect.polygon(n,o,t)},a}function ut(t,e,n,r){return t.insert("polygon",":first-child").attr("points",r.map((function(t){return t.x+","+t.y})).join(" ")).attr("transform","translate("+-e/2+","+n/2+")")}var ct={addToRender:function(t){t.shapes().question=tt,t.shapes().hexagon=et,t.shapes().rect_left_inv_arrow=nt,t.shapes().lean_right=rt,t.shapes().lean_left=it,t.shapes().trapezoid=ot,t.shapes().inv_trapezoid=at,t.shapes().rect_right_inv_arrow=st}};const ft={},lt=function(t,e,n){const r=o.select(`[id="${n}"]`),i=Object.keys(t),a=function(t,e,{label:n}){if(n)for(let n=0;n0&&(o=i.classes.join(" "));let s="";s=a(s,i.styles,{label:!1});let u="";u=a(u,i.styles,{label:!0});let c,f=void 0!==i.text?i.text:i.id;if(l().flowchart.htmlLabels){const t={label:f.replace(/fa[lrsb]?:fa-[\w-]+/g,t=>``)};(c=Q()(r,t).node()).parentNode.removeChild(c)}else{const t=document.createElementNS("http://www.w3.org/2000/svg","text"),e=f.split(//);for(let n=0;n'+i.text+""):(a.labelType="text",a.style=a.style||"stroke: #333; stroke-width: 1.5px;fill:none",a.label=i.text.replace(/
    /g,"\n"))):a.label=i.text.replace(/
    /g,"\n")),e.setEdge(i.start,i.end,a,r)}))};var dt=function(t){const e=Object.keys(t);for(let n=0;n=0;t--)i=s[t],G.addVertex(i.id,i.title,"group",void 0,i.classes);const u=G.getVertices(),c=G.getEdges();let f=0;for(f=s.length-1;f>=0;f--){i=s[f],o.selectAll("cluster").append("text");for(let t=0;t/gi," "),r=t.append("text");r.attr("x",e.x),r.attr("y",e.y),r.style("text-anchor",e.anchor),r.attr("fill",e.fill),void 0!==e.class&&r.attr("class",e.class);const i=r.append("tspan");return i.attr("x",e.x+2*e.textMargin),i.attr("fill",e.fill),i.text(n),r},mt=function(t,e){const n=t.append("polygon");var r,i,o,a,s;n.attr("points",(r=e.x,i=e.y,r+","+i+" "+(r+(o=50))+","+i+" "+(r+o)+","+(i+(a=20)-(s=7))+" "+(r+o-1.2*s)+","+(i+a)+" "+r+","+(i+a))),n.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,bt(t,e)};let vt=-1;const _t=function(){return{x:0,y:0,fill:void 0,"text-anchor":"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0}},wt=function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},xt=function(){function t(t,e,n,i,o,a,s){r(e.append("text").attr("x",n+o/2).attr("y",i+a/2+5).style("text-anchor","middle").text(t),s)}function e(t,e,n,i,o,a,s,u){const{actorFontSize:c,actorFontFamily:f}=u,l=t.split(//gi);for(let t=0;t{let o=0;const a=t.split(//gi);for(const t of a){const a=kt.getTextObj();a.x=e,a.y=n+o,a.textMargin=Pt.noteMargin,a.dy="1em",a.text=t,a.class="noteText";const s=kt.drawText(r,a,i);o+=(s._groups||s)[0][0].getBBox().height}return o})(r.message,e-4,n+24,a,o.width-Pt.noteMargin);Ft.insert(e,n,e+o.width,n+2*Pt.noteMargin+u),s.attr("height",u+2*Pt.noteMargin),Ft.bumpVerticalPos(u+2*Pt.noteMargin)},jt=function(t,e,n,r){for(let i=0;ie&&(r.starty=e-6,e+=12),kt.drawActivation(n,r,e,Pt,Ut(t.from.actor).length),Ft.insert(r.startx,e-10,r.stopx,e)}(t,Ft.getVerticalPos());break;case Et.parser.yy.LINETYPE.LOOP_START:Ft.bumpVerticalPos(Pt.boxMargin),Ft.newLoop(t.message),Ft.bumpVerticalPos(Pt.boxMargin+Pt.boxTextMargin);break;case Et.parser.yy.LINETYPE.LOOP_END:e=Ft.endLoop(),kt.drawLoop(n,e,"loop",Pt),Ft.bumpVerticalPos(Pt.boxMargin);break;case Et.parser.yy.LINETYPE.RECT_START:Ft.bumpVerticalPos(Pt.boxMargin),Ft.newLoop(void 0,t.message),Ft.bumpVerticalPos(Pt.boxMargin);break;case Et.parser.yy.LINETYPE.RECT_END:{const t=Ft.endLoop();kt.drawBackgroundRect(n,t),Ft.bumpVerticalPos(Pt.boxMargin);break}case Et.parser.yy.LINETYPE.OPT_START:Ft.bumpVerticalPos(Pt.boxMargin),Ft.newLoop(t.message),Ft.bumpVerticalPos(Pt.boxMargin+Pt.boxTextMargin);break;case Et.parser.yy.LINETYPE.OPT_END:e=Ft.endLoop(),kt.drawLoop(n,e,"opt",Pt),Ft.bumpVerticalPos(Pt.boxMargin);break;case Et.parser.yy.LINETYPE.ALT_START:Ft.bumpVerticalPos(Pt.boxMargin),Ft.newLoop(t.message),Ft.bumpVerticalPos(Pt.boxMargin+Pt.boxTextMargin);break;case Et.parser.yy.LINETYPE.ALT_ELSE:Ft.bumpVerticalPos(Pt.boxMargin),e=Ft.addSectionToLoop(t.message),Ft.bumpVerticalPos(Pt.boxMargin);break;case Et.parser.yy.LINETYPE.ALT_END:e=Ft.endLoop(),kt.drawLoop(n,e,"alt",Pt),Ft.bumpVerticalPos(Pt.boxMargin);break;case Et.parser.yy.LINETYPE.PAR_START:Ft.bumpVerticalPos(Pt.boxMargin),Ft.newLoop(t.message),Ft.bumpVerticalPos(Pt.boxMargin+Pt.boxTextMargin);break;case Et.parser.yy.LINETYPE.PAR_AND:Ft.bumpVerticalPos(Pt.boxMargin),e=Ft.addSectionToLoop(t.message),Ft.bumpVerticalPos(Pt.boxMargin);break;case Et.parser.yy.LINETYPE.PAR_END:e=Ft.endLoop(),kt.drawLoop(n,e,"par",Pt),Ft.bumpVerticalPos(Pt.boxMargin);break;default:try{Ft.bumpVerticalPos(Pt.messageMargin);const e=zt(t.from),o=zt(t.to),a=e[0]<=o[0]?1:0,s=e[0]/gi);for(const t of f)u=a.append("text").attr("x",s).attr("y",r-7+17*c).style("text-anchor","middle").attr("class","messageText").text(t.trim()),c++;const l=17*(c-1);let h,d=(u._groups||u)[0][0].getBBox().width;if(e===n){h=Pt.rightAngles?a.append("path").attr("d",`M ${e},${r+l} H ${e+Pt.width/2} V ${r+25+l} H ${e}`):a.append("path").attr("d","M "+e+","+(r+l)+" C "+(e+60)+","+(r-10+l)+" "+(e+60)+","+(r+30+l)+" "+e+","+(r+20+l)),Ft.bumpVerticalPos(30+l);const t=Math.max(d/2,100);Ft.insert(e-t,Ft.getVerticalPos()-10+l,n+t,Ft.getVerticalPos()+l)}else(h=a.append("line")).attr("x1",e),h.attr("y1",r),h.attr("x2",n),h.attr("y2",r),Ft.insert(e,Ft.getVerticalPos()-10+l,n,Ft.getVerticalPos()+l);i.type===Et.parser.yy.LINETYPE.DOTTED||i.type===Et.parser.yy.LINETYPE.DOTTED_CROSS||i.type===Et.parser.yy.LINETYPE.DOTTED_OPEN?(h.style("stroke-dasharray","3, 3"),h.attr("class","messageLine1")):h.attr("class","messageLine0");let p="";Pt.arrowMarkerAbsolute&&(p=(p=(p=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search).replace(/\(/g,"\\(")).replace(/\)/g,"\\)")),h.attr("stroke-width",2),h.attr("stroke","black"),h.style("fill","none"),i.type!==Et.parser.yy.LINETYPE.SOLID&&i.type!==Et.parser.yy.LINETYPE.DOTTED||h.attr("marker-end","url("+p+"#arrowhead)"),i.type!==Et.parser.yy.LINETYPE.SOLID_CROSS&&i.type!==Et.parser.yy.LINETYPE.DOTTED_CROSS||h.attr("marker-end","url("+p+"#crosshead)"),Pt.showSequenceNumbers&&(h.attr("marker-start","url("+p+"#sequencenumber)"),a.append("text").attr("x",e).attr("y",r+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("textLength","16px").attr("class","sequenceNumber").text(o))}(n,r,i,u,t,l);const c=e.concat(o);Ft.insert(Math.min.apply(null,c),u,Math.max.apply(null,c),u)}catch(t){v.error("error while drawing message",t)}}[Et.parser.yy.LINETYPE.SOLID_OPEN,Et.parser.yy.LINETYPE.DOTTED_OPEN,Et.parser.yy.LINETYPE.SOLID,Et.parser.yy.LINETYPE.DOTTED,Et.parser.yy.LINETYPE.SOLID_CROSS,Et.parser.yy.LINETYPE.DOTTED_CROSS].includes(t.type)&&l++})),Pt.mirrorActors&&(Ft.bumpVerticalPos(2*Pt.boxMargin),jt(n,s,u,Ft.getVerticalPos()));const h=Ft.getBounds();v.debug("For line height fix Querying: #"+e+" .actor-line"),o.selectAll("#"+e+" .actor-line").attr("y2",h.stopy);let d=h.stopy-h.starty+2*Pt.diagramMarginY;Pt.mirrorActors&&(d=d-Pt.boxMargin+Pt.bottomMarginAdj);const p=h.stopx-h.startx+2*Pt.diagramMarginX;f&&n.append("text").text(f).attr("x",(h.stopx-h.startx)/2-2*Pt.diagramMarginX).attr("y",-25),Pt.useMaxWidth?(n.attr("height","100%"),n.attr("width","100%"),n.attr("style","max-width:"+p+"px;")):(n.attr("height",d),n.attr("width",p));const g=f?40:0;n.attr("viewBox",h.startx-Pt.diagramMarginX+" -"+(Pt.diagramMarginY+g)+" "+p+" "+(d+g))},Ht=n(26),$t=n.n(Ht);const Gt=l();let Wt="",Kt="",Xt=[],Zt="",Jt=[],Qt=[],te="";const ee=["active","done","crit","milestone"];let ne=[],re=!1;const ie=function(t,e,n){return t.isoWeekday()>=6&&n.indexOf("weekends")>=0||(n.indexOf(t.format("dddd").toLowerCase())>=0||n.indexOf(t.format(e.trim()))>=0)},oe=function(t,e,n){if(!n.length||t.manualEndTime)return;let r=d()(t.startTime,e,!0);r.add(1,"d");let i=d()(t.endTime,e,!0),o=ae(r,i,e,n);t.endTime=i.toDate(),t.renderEndTime=o},ae=function(t,e,n,r){let i=!1,o=null;for(;t.date()<=e.date();)i||(o=e.toDate()),(i=ie(t,n,r))&&e.add(1,"d"),t.add(1,"d");return o},se=function(t,e,n){n=n.trim();const r=/^after\s+([\d\w-]+)/.exec(n.trim());if(null!==r){const t=ye(r[1]);if(void 0===t){const t=new Date;return t.setHours(0,0,0,0),t}return t.endTime}let i=d()(n,e.trim(),!0);return i.isValid()?i.toDate():(v.debug("Invalid date:"+n),v.debug("With date format:"+e.trim()),new Date)},ue=function(t,e){if(null!==t)switch(t[2]){case"s":e.add(t[1],"seconds");break;case"m":e.add(t[1],"minutes");break;case"h":e.add(t[1],"hours");break;case"d":e.add(t[1],"days");break;case"w":e.add(t[1],"weeks")}return e.toDate()},ce=function(t,e,n,r){r=r||!1,n=n.trim();let i=d()(n,e.trim(),!0);return i.isValid()?(r&&i.add(1,"d"),i.toDate()):ue(/^([\d]+)([wdhms])/.exec(n.trim()),d()(t))};let fe=0;const le=function(t){return void 0===t?"task"+(fe+=1):t};let he,de,pe=[];const ge={},ye=function(t){const e=ge[t];return pe[e]},be=function(){const t=function(t){const e=pe[t];let n="";switch(pe[t].raw.startTime.type){case"prevTaskEnd":{const t=ye(e.prevTaskId);e.startTime=t.endTime;break}case"getStartDate":(n=se(0,Wt,pe[t].raw.startTime.startData))&&(pe[t].startTime=n)}return pe[t].startTime&&(pe[t].endTime=ce(pe[t].startTime,Wt,pe[t].raw.endTime.data,re),pe[t].endTime&&(pe[t].processed=!0,pe[t].manualEndTime=d()(pe[t].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),oe(pe[t],Wt,Xt))),pe[t].processed};let e=!0;for(let n=0;n{window[e](...r)})}(t,e,n)})),me(t,"clickable")},setLink:function(t,e){let n=e;"loose"!==Gt.securityLevel&&(n=Object(T.sanitizeUrl)(e)),t.split(",").forEach((function(t){void 0!==ye(t)&&ve(t,()=>{window.open(n,"_self")})})),me(t,"clickable")},bindFunctions:function(t){ne.forEach((function(e){e(t)}))},durationToDate:ue};function we(t,e,n){let r=!0;for(;r;)r=!1,n.forEach((function(n){const i=new RegExp("^\\s*"+n+"\\s*$");t[0].match(i)&&(e[n]=!0,t.shift(1),r=!0)}))}Ht.parser.yy=_e;const xe={titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,fontFamily:'"Open-Sans", "sans-serif"'};let ke;var Ee=function(t){Object.keys(t).forEach((function(e){xe[e]=t[e]}))},Ae=function(t,e){Ht.parser.yy.clear(),Ht.parser.parse(t);const n=document.getElementById(e);void 0===(ke=n.parentElement.offsetWidth)&&(ke=1200),void 0!==xe.useWidth&&(ke=xe.useWidth);const r=Ht.parser.yy.getTasks(),i=r.length*(xe.barHeight+xe.barGap)+2*xe.topPadding;n.setAttribute("height","100%"),n.setAttribute("viewBox","0 0 "+ke+" "+i);const a=o.select(`[id="${e}"]`),s=o.scaleTime().domain([o.min(r,(function(t){return t.startTime})),o.max(r,(function(t){return t.endTime}))]).rangeRound([0,ke-xe.leftPadding-xe.rightPadding]);let u=[];for(let t=0;t0&&(e=t.classes.join(" "));let n=0;for(let e=0;en-e?n+o+1.5*xe.leftPadding>c?e+r-5:n+r+5:(n-e)/2+e+r})).attr("y",(function(t,r){return r*e+xe.barHeight/2+(xe.fontSize/2-2)+n})).attr("text-height",i).attr("class",(function(t){const e=s(t.startTime);let n=s(t.endTime);t.milestone&&(n=e+i);const r=this.getBBox().width;let o="";t.classes.length>0&&(o=t.classes.join(" "));let a=0;for(let e=0;en-e?n+r+1.5*xe.leftPadding>c?o+" taskTextOutsideLeft taskTextOutside"+a+" "+f:o+" taskTextOutsideRight taskTextOutside"+a+" "+f+" width-"+r:o+" taskText taskText"+a+" "+f+" width-"+r}))}(t,i,l,h,r,0,e),function(t,e){const n=[];let r=0;for(let t=0;t0))return i[1]*t/2+e;for(let a=0;a>")?n.annotations.push(t.substring(2,t.length-2)):t.endsWith(")")?n.methods.push(t):t&&n.members.push(t)}};var Re={addClass:Ce,clear:function(){Me=[],De={}},getClass:function(t){return De[t]},getClasses:function(){return De},addAnnotation:function(t,e){De[t].annotations.push(e)},getRelations:function(){return Me},addRelation:function(t){v.debug("Adding relation: "+JSON.stringify(t)),Ce(t.id1),Ce(t.id2),Me.push(t)},addMember:Oe,addMembers:function(t,e){Array.isArray(e)&&(e.reverse(),e.forEach(e=>Oe(t,e)))},cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3}},Ie=n(46),Ne=n.n(Ie);Ie.parser.yy=Re;let Be={},Le=0;const Pe={dividerMargin:10,padding:5,textHeight:10},Fe=function(t){const e=Object.keys(Be);for(let n=0;n "+t.w+": "+JSON.stringify(i.edge(t))),function(t,e,n){const r=function(t){switch(t){case Re.relationType.AGGREGATION:return"aggregation";case Re.relationType.EXTENSION:return"extension";case Re.relationType.COMPOSITION:return"composition";case Re.relationType.DEPENDENCY:return"dependency"}};e.points=e.points.filter(t=>!Number.isNaN(t.y));const i=e.points,a=o.line().x((function(t){return t.x})).y((function(t){return t.y})).curve(o.curveBasis),s=t.append("path").attr("d",a(i)).attr("id","edge"+qe).attr("class","relation");let u,c,f="";Pe.arrowMarkerAbsolute&&(f=(f=(f=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search).replace(/\(/g,"\\(")).replace(/\)/g,"\\)")),"none"!==n.relation.type1&&s.attr("marker-start","url("+f+"#"+r(n.relation.type1)+"Start)"),"none"!==n.relation.type2&&s.attr("marker-end","url("+f+"#"+r(n.relation.type2)+"End)");const l=e.points.length;let h,d,p,g,y=E.calcLabelPosition(e.points);if(u=y.x,c=y.y,l%2!=0&&l>1){let t=E.calcCardinalityPosition("none"!==n.relation.type1,e.points,e.points[0]),r=E.calcCardinalityPosition("none"!==n.relation.type2,e.points,e.points[l-1]);v.debug("cardinality_1_point "+JSON.stringify(t)),v.debug("cardinality_2_point "+JSON.stringify(r)),h=t.x,d=t.y,p=r.x,g=r.y}if(void 0!==n.title){const e=t.append("g").attr("class","classLabel"),r=e.append("text").attr("class","label").attr("x",u).attr("y",c).attr("fill","red").attr("text-anchor","middle").text(n.title);window.label=r;const i=r.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",i.x-Pe.padding/2).attr("y",i.y-Pe.padding/2).attr("width",i.width+Pe.padding).attr("height",i.height+Pe.padding)}if(v.info("Rendering relation "+JSON.stringify(n)),void 0!==n.relationTitle1&&"none"!==n.relationTitle1){t.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",h).attr("y",d).attr("fill","black").attr("font-size","6").text(n.relationTitle1)}if(void 0!==n.relationTitle2&&"none"!==n.relationTitle2){t.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",p).attr("y",g).attr("fill","black").attr("font-size","6").text(n.relationTitle2)}qe++}(n,i.edge(t),i.edge(t).relation))})),n.attr("height","100%"),n.attr("width",`${1.5*i.graph().width+20}`),n.attr("viewBox","-10 -10 "+(i.graph().width+20)+" "+(i.graph().height+20))};let Ye=[];let Ve={root:{relations:[],states:{},documents:{}}},He=Ve.root,$e=0;const Ge=function(t,e,n,r,i){void 0===He.states[t]?He.states[t]={id:t,descriptions:[],type:e,doc:n,note:i}:(He.states[t].doc||(He.states[t].doc=n),He.states[t].type||(He.states[t].type=e)),r&&("string"==typeof r&&Xe(t,r.trim()),"object"==typeof r&&r.forEach(e=>Xe(t,e.trim()))),i&&(He.states[t].note=i)},We=function(){He=(Ve={root:{relations:[],states:{},documents:{}}}).root},Ke=function(t,e,n){let r=t,i=e,o="default",a="default";"[*]"===t&&(r="start"+ ++$e,o="start"),"[*]"===e&&(i="end"+$e,a="end"),Ge(r,o),Ge(i,a),He.relations.push({id1:r,id2:i,title:n})},Xe=function(t,e){const n=He.states[t];let r=e;":"===r[0]&&(r=r.substr(1).trim()),n.descriptions.push(r)};let Ze=0;var Je={addState:Ge,clear:We,getState:function(t){return He.states[t]},getStates:function(){return He.states},getRelations:function(){return He.relations},addRelation:Ke,getDividerId:()=>"divider-id-"+ ++Ze,cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},logDocuments:function(){v.info("Documents = ",Ve)},getRootDoc:()=>Ye,setRootDoc:t=>{v.info("Setting root doc",t),Ye=t},extract:t=>{We(),t.forEach(t=>{"state"===t.stmt&&Ge(t.id,t.type,t.doc,t.description,t.note),"relation"===t.stmt&&Ke(t.state1.id,t.state2.id,t.description)})}},Qe=n(47),tn=n.n(Qe);const en={};var nn=(t,e)=>{en[t]=e};const rn=(t,e)=>{const n=t.append("text").attr("x",2*l().state.padding).attr("y",l().state.textHeight+1.5*l().state.padding).attr("font-size",l().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),r=n.height,i=t.append("text").attr("x",l().state.padding).attr("y",r+.2*l().state.padding+l().state.dividerMargin+l().state.textHeight).attr("class","state-description");let o=!0,a=!0;e.descriptions.forEach((function(t){o||(!function(t,e,n){const r=t.append("tspan").attr("x",2*l().state.padding).text(e);n||r.attr("dy",l().state.textHeight)}(i,t,a),a=!1),o=!1}));const s=t.append("line").attr("x1",l().state.padding).attr("y1",l().state.padding+r+l().state.dividerMargin/2).attr("y2",l().state.padding+r+l().state.dividerMargin/2).attr("class","descr-divider"),u=i.node().getBBox(),c=Math.max(u.width,n.width);return s.attr("x2",c+3*l().state.padding),t.insert("rect",":first-child").attr("x",l().state.padding).attr("y",l().state.padding).attr("width",c+2*l().state.padding).attr("height",u.height+r+2*l().state.padding).attr("rx",l().state.radius),t},on=(t,e)=>{const n=t.append("text").attr("x",2*l().state.padding).attr("y",l().state.titleShift).attr("font-size",l().state.fontSize).attr("class","state-title").text(e.id),r=n.node().getBBox(),i=1-l().state.textHeight,o=t.append("line").attr("x1",0).attr("y1",i).attr("y2",i).attr("class","descr-divider"),a=t.node().getBBox();return n.attr("x",a.width/2-r.width/2),o.attr("x2",a.width+l().state.padding),t.insert("rect",":first-child").attr("x",a.x).attr("y",i).attr("class","composit").attr("width",a.width+l().state.padding).attr("height",a.height+l().state.textHeight+l().state.titleShift+1).attr("rx","0"),t.insert("rect",":first-child").attr("x",a.x).attr("y",l().state.titleShift-l().state.textHeight-l().state.padding).attr("width",a.width+l().state.padding).attr("height",3*l().state.textHeight).attr("rx",l().state.radius),t.insert("rect",":first-child").attr("x",a.x).attr("y",l().state.titleShift-l().state.textHeight-l().state.padding).attr("width",a.width+l().state.padding).attr("height",a.height+3+2*l().state.textHeight).attr("rx",l().state.radius),t},an=(t,e)=>{e.attr("class","state-note");const n=e.append("rect").attr("x",0).attr("y",l().state.padding),r=e.append("g"),{textWidth:i,textHeight:o}=((t,e,n,r)=>{let i=0;const o=r.append("text");o.style("text-anchor","start"),o.attr("class","noteText");let a=t.replace(/\r\n/g,"
    ");const s=(a=a.replace(/\n/g,"
    ")).split(//gi);let u=1.25*l().state.noteMargin;for(const t of s){const r=t.trim();if(r.length>0){const t=o.append("tspan");if(t.text(r),0===u){u+=t.node().getBBox().height}i+=u,t.attr("x",e+l().state.noteMargin),t.attr("y",n+i+1.25*l().state.noteMargin)}}return{textWidth:o.node().getBBox().width,textHeight:i}})(t,0,0,r);return n.attr("height",o+2*l().state.noteMargin),n.attr("width",i+2*l().state.noteMargin),n},sn=function(t,e){const n=e.id,r={id:n,label:e.id,width:0,height:0},i=t.append("g").attr("id",n).attr("class","stateGroup");"start"===e.type&&(t=>t.append("circle").style("stroke","black").style("fill","black").attr("r",l().state.sizeUnit).attr("cx",l().state.padding+l().state.sizeUnit).attr("cy",l().state.padding+l().state.sizeUnit))(i),"end"===e.type&&(t=>(t.append("circle").style("stroke","black").style("fill","white").attr("r",l().state.sizeUnit+l().state.miniPadding).attr("cx",l().state.padding+l().state.sizeUnit+l().state.miniPadding).attr("cy",l().state.padding+l().state.sizeUnit+l().state.miniPadding),t.append("circle").style("stroke","black").style("fill","black").attr("r",l().state.sizeUnit).attr("cx",l().state.padding+l().state.sizeUnit+2).attr("cy",l().state.padding+l().state.sizeUnit+2)))(i),"fork"!==e.type&&"join"!==e.type||((t,e)=>{let n=l().state.forkWidth,r=l().state.forkHeight;if(e.parentId){let t=n;n=r,r=t}t.append("rect").style("stroke","black").style("fill","black").attr("width",n).attr("height",r).attr("x",l().state.padding).attr("y",l().state.padding)})(i,e),"note"===e.type&&an(e.note.text,i),"divider"===e.type&&(t=>t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",l().state.textHeight).attr("class","divider").attr("x2",2*l().state.textHeight).attr("y1",0).attr("y2",0))(i),"default"===e.type&&0===e.descriptions.length&&((t,e)=>{const n=t.append("text").attr("x",2*l().state.padding).attr("y",l().state.textHeight+2*l().state.padding).attr("font-size",l().state.fontSize).attr("class","state-title").text(e.id),r=n.node().getBBox();t.insert("rect",":first-child").attr("x",l().state.padding).attr("y",l().state.padding).attr("width",r.width+2*l().state.padding).attr("height",r.height+2*l().state.padding).attr("rx",l().state.radius)})(i,e),"default"===e.type&&e.descriptions.length>0&&rn(i,e);const o=i.node().getBBox();return r.width=o.width+2*l().state.padding,r.height=o.height+2*l().state.padding,nn(n,r),r};let un=0;let cn;Qe.parser.yy=Je;const fn={},ln=t=>t?t.length*cn.fontSizeFactor:1,hn=t=>{if(!t)return 1;let e=t.replace(//gi,"#br#");return(e=e.replace(/\\n/g,"#br#")).split("#br#")},dn=(t,e,n)=>{const r=new S.a.Graph({compound:!0});n?r.setGraph({rankdir:"LR",compound:!0,ranker:"tight-tree",ranksep:cn.edgeLengthFactor}):r.setGraph({rankdir:"TB",compound:!0,ranksep:cn.edgeLengthFactor,ranker:"tight-tree"}),r.setDefaultEdgeLabel((function(){return{}})),Je.extract(t);const i=Je.getStates(),a=Je.getRelations(),s=Object.keys(i);for(let t=0;t{const e=t.parentElement;let n=0,r=0;e&&(e.parentElement&&(n=e.parentElement.getBBox().width),r=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(r)&&(r=0)),t.setAttribute("x1",0-r),t.setAttribute("x2",n-r)})}else v.debug("No Node "+t+": "+JSON.stringify(r.node(t)))}));let c=u.getBBox();r.edges().forEach((function(t){void 0!==t&&void 0!==r.edge(t)&&(v.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(r.edge(t))),function(t,e,n){e.points=e.points.filter(t=>!Number.isNaN(t.y));const r=e.points,i=o.line().x((function(t){return t.x})).y((function(t){return t.y})).curve(o.curveBasis),a=t.append("path").attr("d",i(r)).attr("id","edge"+un).attr("class","transition");let s="";if(l().state.arrowMarkerAbsolute&&(s=(s=(s=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search).replace(/\(/g,"\\(")).replace(/\)/g,"\\)")),a.attr("marker-end","url("+s+"#"+function(t){switch(t){case Je.relationType.AGGREGATION:return"aggregation";case Je.relationType.EXTENSION:return"extension";case Je.relationType.COMPOSITION:return"composition";case Je.relationType.DEPENDENCY:return"dependency"}}(Je.relationType.DEPENDENCY)+"End)"),void 0!==n.title){const r=t.append("g").attr("class","stateLabel"),{x:i,y:o}=E.calcLabelPosition(e.points),a=(t=>{let e=t.replace(//gi,"#br#");return(e=e.replace(/\\n/g,"#br#")).split("#br#")})(n.title);let s=0;const u=[];for(let t=0;t<=a.length;t++){const e=r.append("text").attr("text-anchor","middle").text(a[t]).attr("x",i).attr("y",o+s);if(0===s){const t=e.node().getBBox();s=t.height}u.push(e)}if(a.length>1){const t=a.length*s*.25;u.forEach((e,n)=>e.attr("y",o+n*s-t))}const c=r.node().getBBox();r.insert("rect",":first-child").attr("class","box").attr("x",c.x-l().state.padding/2).attr("y",c.y-l().state.padding/2).attr("width",c.width+l().state.padding).attr("height",c.height+l().state.padding)}un++}(e,r.edge(t),r.edge(t).relation))})),c=u.getBBox();const f={id:n||"root",label:n||"root",width:0,height:0};return f.width=c.width+2*cn.padding,f.height=c.height+2*cn.padding,v.info("Doc rendered",f,r),f};var pn=function(){},gn=function(t,e){cn=l().state,Qe.parser.yy.clear(),Qe.parser.parse(t),v.debug("Rendering diagram "+t);const n=o.select(`[id='${e}']`);n.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z"),new S.a.Graph({multigraph:!1,compound:!0,rankdir:"RL"}).setDefaultEdgeLabel((function(){return{}}));const r=Je.getRootDoc();dn(r,n);const i=cn.padding,a=n.node().getBBox(),s=a.width+2*i,u=a.height+2*i;n.attr("width",2*s),n.attr("viewBox",`${a.x-cn.padding} ${a.y-cn.padding} `+s+" "+u)},yn=n(48),bn=n.n(yn),mn=n(228),vn=n.n(mn);let _n={},wn=null,xn={master:wn},kn="master",En="LR",An=0;function Sn(){return vn()({length:7,characters:"0123456789abcdef"})}function Tn(t,e){for(v.debug("Entering isfastforwardable:",t.id,e.id);t.seq<=e.seq&&t!==e&&null!=e.parent;){if(Array.isArray(e.parent))return v.debug("In merge commit:",e.parent),Tn(t,_n[e.parent[0]])||Tn(t,_n[e.parent[1]]);e=_n[e.parent]}return v.debug(t.id,e.id),t.id===e.id}let Mn={};function Dn(t,e,n){const r=t.indexOf(e);-1===r?t.push(n):t.splice(r,1,n)}const Cn=function(){const t=Object.keys(_n).map((function(t){return _n[t]}));return t.forEach((function(t){v.debug(t.id)})),bn.a.orderBy(t,["seq"],["desc"])};var On={setDirection:function(t){En=t},setOptions:function(t){v.debug("options str",t),t=(t=t&&t.trim())||"{}";try{Mn=JSON.parse(t)}catch(t){v.error("error while parsing gitGraph options",t.message)}},getOptions:function(){return Mn},commit:function(t){const e={id:Sn(),message:t,seq:An++,parent:null==wn?null:wn.id};wn=e,_n[e.id]=e,xn[kn]=e.id,v.debug("in pushCommit "+e.id)},branch:function(t){xn[t]=null!=wn?wn.id:null,v.debug("in createBranch")},merge:function(t){const e=_n[xn[kn]],n=_n[xn[t]];if(function(t,e){return t.seq>e.seq&&Tn(e,t)}(e,n))v.debug("Already merged");else{if(Tn(e,n))xn[kn]=xn[t],wn=_n[xn[kn]];else{const e={id:Sn(),message:"merged branch "+t+" into "+kn,seq:An++,parent:[null==wn?null:wn.id,xn[t]]};wn=e,_n[e.id]=e,xn[kn]=e.id}v.debug(xn),v.debug("in mergeBranch")}},checkout:function(t){v.debug("in checkout");const e=xn[kn=t];wn=_n[e]},reset:function(t){v.debug("in reset",t);const e=t.split(":")[0];let n=parseInt(t.split(":")[1]),r="HEAD"===e?wn:_n[xn[e]];for(v.debug(r,n);n>0;)if(n--,!(r=_n[r.parent])){const t="Critical error - unique parent commit not found during reset";throw v.error(t),t}wn=r,xn[kn]=r.id},prettyPrint:function(){v.debug(_n),function t(e){const n=bn.a.maxBy(e,"seq");let r="";e.forEach((function(t){r+=t===n?"\t*":"\t|"}));const i=[r,n.id,n.seq];for(let t in xn)xn[t]===n.id&&i.push(t);if(v.debug(i.join(" ")),Array.isArray(n.parent)){const t=_n[n.parent[0]];Dn(e,n,t),e.push(_n[n.parent[1]])}else{if(null==n.parent)return;{const t=_n[n.parent];Dn(e,n,t)}}t(e=bn.a.uniqBy(e,"id"))}([Cn()[0]])},clear:function(){_n={},xn={master:wn=null},kn="master",An=0},getBranchesAsObjArray:function(){const t=[];for(let e in xn)t.push({name:e,commit:_n[xn[e]]});return t},getBranches:function(){return xn},getCommits:function(){return _n},getCommitsArray:Cn,getCurrentBranch:function(){return kn},getDirection:function(){return En},getHead:function(){return wn}},Rn=n(85),In=n.n(Rn);let Nn,Bn={},Ln={nodeSpacing:150,nodeFillColor:"yellow",nodeStrokeWidth:2,nodeStrokeColor:"grey",lineStrokeWidth:4,branchOffset:50,lineColor:"grey",leftMargin:50,branchColors:["#442f74","#983351","#609732","#AA9A39"],nodeRadius:10,nodeLabel:{width:75,height:100,x:-25,y:0}},Pn={};function Fn(t,e,n,r){const i=x(r,o.curveBasis),a=Ln.branchColors[n%Ln.branchColors.length],s=o.line().x((function(t){return Math.round(t.x)})).y((function(t){return Math.round(t.y)})).curve(i);t.append("svg:path").attr("d",s(e)).style("stroke",a).style("stroke-width",Ln.lineStrokeWidth).style("fill","none")}function qn(t,e){e=e||t.node().getBBox();const n=t.node().getCTM();return{left:n.e+e.x*n.a,top:n.f+e.y*n.d,width:e.width,height:e.height}}function jn(t,e,n,r,i){v.debug("svgDrawLineForCommits: ",e,n);const o=qn(t.select("#node-"+e+" circle")),a=qn(t.select("#node-"+n+" circle"));switch(r){case"LR":if(o.left-a.left>Ln.nodeSpacing){const e={x:o.left-Ln.nodeSpacing,y:a.top+a.height/2};Fn(t,[e,{x:a.left+a.width,y:a.top+a.height/2}],i,"linear"),Fn(t,[{x:o.left,y:o.top+o.height/2},{x:o.left-Ln.nodeSpacing/2,y:o.top+o.height/2},{x:o.left-Ln.nodeSpacing/2,y:e.y},e],i)}else Fn(t,[{x:o.left,y:o.top+o.height/2},{x:o.left-Ln.nodeSpacing/2,y:o.top+o.height/2},{x:o.left-Ln.nodeSpacing/2,y:a.top+a.height/2},{x:a.left+a.width,y:a.top+a.height/2}],i);break;case"BT":if(a.top-o.top>Ln.nodeSpacing){const e={x:a.left+a.width/2,y:o.top+o.height+Ln.nodeSpacing};Fn(t,[e,{x:a.left+a.width/2,y:a.top}],i,"linear"),Fn(t,[{x:o.left+o.width/2,y:o.top+o.height},{x:o.left+o.width/2,y:o.top+o.height+Ln.nodeSpacing/2},{x:a.left+a.width/2,y:e.y-Ln.nodeSpacing/2},e],i)}else Fn(t,[{x:o.left+o.width/2,y:o.top+o.height},{x:o.left+o.width/2,y:o.top+Ln.nodeSpacing/2},{x:a.left+a.width/2,y:a.top-Ln.nodeSpacing/2},{x:a.left+a.width/2,y:a.top}],i)}}function Un(t,e){return t.select(e).node().cloneNode(!0)}function zn(t,e,n,r){let i;const o=Object.keys(Bn).length;if("string"==typeof e)do{if(i=Bn[e],v.debug("in renderCommitHistory",i.id,i.seq),t.select("#node-"+e).size()>0)return;let a;t.append((function(){return Un(t,"#def-commit")})).attr("class","commit").attr("id",(function(){return"node-"+i.id})).attr("transform",(function(){switch(r){case"LR":return"translate("+(i.seq*Ln.nodeSpacing+Ln.leftMargin)+", "+Nn*Ln.branchOffset+")";case"BT":return"translate("+(Nn*Ln.branchOffset+Ln.leftMargin)+", "+(o-i.seq)*Ln.nodeSpacing+")"}})).attr("fill",Ln.nodeFillColor).attr("stroke",Ln.nodeStrokeColor).attr("stroke-width",Ln.nodeStrokeWidth);for(let t in n)if(n[t].commit===i){a=n[t];break}a&&(v.debug("found branch ",a.name),t.select("#node-"+i.id+" p").append("xhtml:span").attr("class","branch-label").text(a.name+", ")),t.select("#node-"+i.id+" p").append("xhtml:span").attr("class","commit-id").text(i.id),""!==i.message&&"BT"===r&&t.select("#node-"+i.id+" p").append("xhtml:span").attr("class","commit-msg").text(", "+i.message),e=i.parent}while(e&&Bn[e]);Array.isArray(e)&&(v.debug("found merge commmit",e),zn(t,e[0],n,r),Nn++,zn(t,e[1],n,r),Nn--)}function Yn(t,e,n,r){for(r=r||0;e.seq>0&&!e.lineDrawn;)"string"==typeof e.parent?(jn(t,e.id,e.parent,n,r),e.lineDrawn=!0,e=Bn[e.parent]):Array.isArray(e.parent)&&(jn(t,e.id,e.parent[0],n,r),jn(t,e.id,e.parent[1],n,r+1),Yn(t,Bn[e.parent[1]],n,r+1),e.lineDrawn=!0,e=Bn[e.parent[0]])}var Vn=function(t){Pn=t},Hn=function(t,e,n){try{const r=In.a.parser;r.yy=On,v.debug("in gitgraph renderer",t+"\n","id:",e,n),r.parse(t+"\n"),Ln=bn.a.assign(Ln,Pn,On.getOptions()),v.debug("effective options",Ln);const i=On.getDirection();Bn=On.getCommits();const a=On.getBranchesAsObjArray();"BT"===i&&(Ln.nodeLabel.x=a.length*Ln.branchOffset,Ln.nodeLabel.width="100%",Ln.nodeLabel.y=-2*Ln.nodeRadius);const s=o.select(`[id="${e}"]`);!function(t){t.append("defs").append("g").attr("id","def-commit").append("circle").attr("r",Ln.nodeRadius).attr("cx",0).attr("cy",0),t.select("#def-commit").append("foreignObject").attr("width",Ln.nodeLabel.width).attr("height",Ln.nodeLabel.height).attr("x",Ln.nodeLabel.x).attr("y",Ln.nodeLabel.y).attr("class","node-label").attr("requiredFeatures","http://www.w3.org/TR/SVG11/feature#Extensibility").append("p").html("")}(s),Nn=1;for(let t in a){const e=a[t];zn(s,e.commit.id,a,i),Yn(s,e.commit,i),Nn++}s.attr("height",(function(){return"BT"===i?Object.keys(Bn).length*Ln.nodeSpacing:(a.length+1)*Ln.branchOffset}))}catch(t){v.error("Error while rendering gitgraph"),v.error(t.message)}},$n="",Gn=!1;var Wn={setMessage:t=>{v.debug("Setting message to: "+t),$n=t},getMessage:()=>$n,setInfo:t=>{Gn=t},getInfo:()=>Gn},Kn=n(86),Xn=n.n(Kn);const Zn={};var Jn=function(t){Object.keys(t).forEach((function(e){Zn[e]=t[e]}))},Qn=(t,e,n)=>{try{const r=Xn.a.parser;r.yy=Wn,v.debug("Renering info diagram\n"+t),r.parse(t),v.debug("Parsed info diagram");const i=o.select("#"+e);i.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size","32px").style("text-anchor","middle").text("v "+n),i.attr("height",100),i.attr("width",400)}catch(t){v.error("Error while rendering info diagram"),v.error(t.message)}};let tr={},er="";var nr={addSection:function(t,e){void 0===tr[t]&&(tr[t]=e,v.debug("Added new section :",t))},getSections:()=>tr,cleanupValue:function(t){return":"===t.substring(0,1)?(t=t.substring(1).trim(),Number(t.trim())):Number(t.trim())},clear:function(){tr={},er=""},setTitle:function(t){er=t},getTitle:function(){return er}},rr=n(87),ir=n.n(rr);const or={};let ar;var sr=function(t){Object.keys(t).forEach((function(e){or[e]=t[e]}))},ur=(t,e)=>{try{const h=ir.a.parser;h.yy=nr,v.debug("Rendering info diagram\n"+t),h.yy.clear(),h.parse(t),v.debug("Parsed info diagram");const d=document.getElementById(e);void 0===(ar=d.parentElement.offsetWidth)&&(ar=1200),void 0!==or.useWidth&&(ar=or.useWidth);const p=450;d.setAttribute("height","100%"),d.setAttribute("viewBox","0 0 "+ar+" "+p);var n=ar,r=Math.min(n,450)/2-40,i=o.select("#"+e).append("svg").attr("width",n).attr("height",450).append("g").attr("transform","translate("+n/2+",225)"),a=nr.getSections(),s=0;Object.keys(a).forEach((function(t){s+=a[t]})),v.info(a);var u=o.scaleOrdinal().domain(a).range(o.schemeSet2),c=o.pie().value((function(t){return t.value}))(o.entries(a)),f=o.arc().innerRadius(0).outerRadius(r);i.selectAll("mySlices").data(c).enter().append("path").attr("d",f).attr("fill",(function(t){return u(t.data.key)})).attr("stroke","black").style("stroke-width","2px").style("opacity",.7),i.selectAll("mySlices").data(c).enter().append("text").text((function(t){return(t.data.value/s*100).toFixed(0)+"%"})).attr("transform",(function(t){return"translate("+f.centroid(t)+")"})).style("text-anchor","middle").attr("class","slice").style("font-size",17),i.append("text").text(h.yy.getTitle()).attr("x",0).attr("y",-(p-50)/2).attr("class","pieTitleText");var l=i.selectAll(".legend").data(u.domain()).enter().append("g").attr("class","legend").attr("transform",(function(t,e){return"translate(216,"+(22*e-22*u.domain().length/2)+")"}));l.append("rect").attr("width",18).attr("height",18).style("fill",u).style("stroke",u),l.append("text").attr("x",22).attr("y",14).text((function(t){return t}))}catch(t){v.error("Error while rendering info diagram"),v.error(t.message)}};const cr={};for(const t of["default","forest","dark","neutral"])cr[t]=n(500)(`./${t}/index.scss`);const fr={theme:"default",themeCSS:void 0,fontFamily:'"trebuchet ms", verdana, arial;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,flowchart:{htmlLabels:!0,curve:"linear"},sequence:{diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,mirrorActors:!0,bottomMarginAdj:1,useMaxWidth:!0,rightAngles:!1,showSequenceNumbers:!1},gantt:{titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,leftPadding:75,gridLineStartPadding:35,fontSize:11,fontFamily:'"Open-Sans", "sans-serif"',numberSectionStyles:4,axisFormat:"%Y-%m-%d"},class:{},git:{},state:{dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5}};_(fr.logLevel),f(fr);const lr=function(t){const e=Object.keys(t);for(let n=0;n * { ${t[e].styles.join(" !important; ")} !important; }`}const h=document.createElement("style");h.innerHTML=s()(l,`#${t}`),c.insertBefore(h,f);const d=document.createElement("style"),p=window.getComputedStyle(c);switch(d.innerHTML=`#${t} {\n color: ${p.color};\n font: ${p.font};\n }`,c.insertBefore(d,f),a){case"git":fr.flowchart.arrowMarkerAbsolute=fr.arrowMarkerAbsolute,Vn(fr.git),Hn(e,t,!1);break;case"flowchart":fr.flowchart.arrowMarkerAbsolute=fr.arrowMarkerAbsolute,dt(fr.flowchart),gt(e,t,!1);break;case"sequence":fr.sequence.arrowMarkerAbsolute=fr.arrowMarkerAbsolute,fr.sequenceDiagram?(Yt(Object.assign(fr.sequence,fr.sequenceDiagram)),console.error("`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.")):Yt(fr.sequence),Vt(e,t);break;case"gantt":fr.gantt.arrowMarkerAbsolute=fr.arrowMarkerAbsolute,Ee(fr.gantt),Ae(e,t);break;case"class":fr.class.arrowMarkerAbsolute=fr.arrowMarkerAbsolute,Ue(fr.class),ze(e,t);break;case"state":pn(fr.state),gn(e,t);break;case"info":fr.class.arrowMarkerAbsolute=fr.arrowMarkerAbsolute,Jn(fr.class),Qn(e,t,u.version);break;case"pie":fr.class.arrowMarkerAbsolute=fr.arrowMarkerAbsolute,sr(fr.class),ur(e,t,u.version)}o.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");let g=o.select("#d"+t).node().innerHTML;if(fr.arrowMarkerAbsolute&&"false"!==fr.arrowMarkerAbsolute||(g=g.replace(/marker-end="url\(.*?#/g,'marker-end="url(#',"g")),g=function(t){let e=t;return e=(e=(e=e.replace(/fl°°/g,(function(){return"&#"}))).replace(/fl°/g,(function(){return"&"}))).replace(/¶ß/g,(function(){return";"}))}(g),void 0!==n)switch(a){case"flowchart":n(g,G.bindFunctions);break;case"gantt":n(g,_e.bindFunctions);break;default:n(g)}else v.debug("CB = undefined!");const y=o.select("#d"+t).node();return null!==y&&"function"==typeof y.remove&&o.select("#d"+t).node().remove(),g},parse:function(t){const e=E.detectType(t);let n;switch(v.debug("Type "+e),e){case"git":(n=In.a).parser.yy=On;break;case"flowchart":G.clear(),(n=K.a).parser.yy=G;break;case"sequence":(n=At.a).parser.yy=Lt;break;case"gantt":(n=$t.a).parser.yy=_e;break;case"class":(n=Ne.a).parser.yy=Re;break;case"state":(n=tn.a).parser.yy=Je;break;case"info":v.debug("info info info"),(n=Xn.a).parser.yy=Wn;break;case"pie":v.debug("pie"),(n=ir.a).parser.yy=nr}n.parser.yy.parseError=(t,e)=>{throw{str:t,hash:e}},n.parse(t)},initialize:function(t){v.debug("Initializing mermaidAPI ",u.version),"object"==typeof t&&lr(t),f(fr),_(fr.logLevel)},getConfig:l};const dr=function(){let t;pr.startOnLoad?(t=hr.getConfig()).startOnLoad&&pr.init():void 0===pr.startOnLoad&&(v.debug("In start, no config"),(t=hr.getConfig()).startOnLoad&&pr.init())};"undefined"!=typeof document&& -/*! - * Wait for document loaded before starting the execution - */ -window.addEventListener("load",(function(){dr()}),!1);const pr={startOnLoad:!0,htmlLabels:!0,mermaidAPI:hr,parse:hr.parse,render:hr.render,init:function(){const t=hr.getConfig();let e,n,r;v.debug("Starting rendering diagrams"),arguments.length>=2?( -/*! sequence config was passed as #1 */ -void 0!==arguments[0]&&(pr.sequenceConfig=arguments[0]),e=arguments[1]):e=arguments[0],"function"==typeof arguments[arguments.length-1]?(n=arguments[arguments.length-1],v.debug("Callback function found")):void 0!==t.mermaid&&("function"==typeof t.mermaid.callback?(n=t.mermaid.callback,v.debug("Callback function found")):v.debug("No Callback function found")),e=void 0===e?document.querySelectorAll(".mermaid"):"string"==typeof e?document.querySelectorAll(e):e instanceof window.Node?[e]:e,v.debug("Start On Load before: "+pr.startOnLoad),void 0!==pr.startOnLoad&&(v.debug("Start On Load inner: "+pr.startOnLoad),hr.initialize({startOnLoad:pr.startOnLoad})),void 0!==pr.ganttConfig&&hr.initialize({gantt:pr.ganttConfig});for(let t=0;t/gi,"
    "),hr.render(a,r,(t,e)=>{o.innerHTML=t,void 0!==n&&n(a),e&&e(o)},o)}},initialize:function(t){v.debug("Initializing mermaid "),void 0!==t.mermaid&&(void 0!==t.mermaid.startOnLoad&&(pr.startOnLoad=t.mermaid.startOnLoad),void 0!==t.mermaid.htmlLabels&&(pr.htmlLabels=t.mermaid.htmlLabels)),hr.initialize(t)},contentLoaded:dr};e.default=pr}]).default})); -//# sourceMappingURL=mermaid.min.js.map \ No newline at end of file diff --git a/src/utils/plantuml/synchro2.js b/src/utils/plantuml/synchro2.js deleted file mode 100644 index 3cedf80d..00000000 --- a/src/utils/plantuml/synchro2.js +++ /dev/null @@ -1,50 +0,0 @@ -GID = function(id){ return document.getElementById(id) }; - -function encode64_(data) { - r = ""; - for (i=0; i> 2; -c2 = ((b1 & 0x3) << 4) | (b2 >> 4); -c3 = ((b2 & 0xF) << 2) | (b3 >> 6); -c4 = b3 & 0x3F; -r = ""; -r += encode6bit(c1 & 0x3F); -r += encode6bit(c2 & 0x3F); -r += encode6bit(c3 & 0x3F); -r += encode6bit(c4 & 0x3F); -return r; -} - -function encode6bit(b) { -if (b < 10) { - return String.fromCharCode(48 + b); -} -b -= 10; -if (b < 26) { - return String.fromCharCode(65 + b); -} -b -= 26; -if (b < 26) { - return String.fromCharCode(97 + b); -} -b -= 26; -if (b == 0) { - return '-'; -} -if (b == 1) { - return '_'; -} -return '?'; -} \ No newline at end of file diff --git a/src/utils/plantuml/zopfli.raw.min.js b/src/utils/plantuml/zopfli.raw.min.js deleted file mode 100644 index e80d6147..00000000 --- a/src/utils/plantuml/zopfli.raw.min.js +++ /dev/null @@ -1,238 +0,0 @@ -/** - * @license zopfli.js 2013 - imaya [ https://github.com/imaya/zopfli.js ] The Apache License 2.0 - * Original C implementation: Google Inc. [ https://code.google.com/p/zopfli/ ] The Apache License 2.0 - */ -(function() {function da(b){throw b;}var a=void 0,E=!0,F=null,G=!1,fa=this;function ha(b,c){var d=b.split("."),e=fa;!(d[0]in e)&&e.execScript&&e.execScript("var "+d[0]);for(var f;d.length&&(f=d.shift());)!d.length&&c!==a?e[f]=c:e=e[f]?e[f]:e[f]={}};try{this.Module=Module}catch(ka){this.Module=Module={}}var la="object"===typeof process&&"function"===typeof require,ma="object"===typeof window,na="function"===typeof importScripts,oa=!ma&&!la&&!na; -if(la){Module.print=function(b){process.stdout.write(b+"\n")};Module.printErr=function(b){process.stderr.write(b+"\n")};var pa=require("fs"),qa=require("path");Module.read=function(b){var b=qa.normalize(b),c=pa.readFileSync(b).toString();!c&&b!=qa.resolve(b)&&(b=path.join(__dirname,"..","src",b),c=pa.readFileSync(b).toString());return c};Module.load=function(b){ra(read(b))};Module.arguments||(Module.arguments=process.argv.slice(2))} -oa&&(Module.print=print,"undefined"!=typeof printErr&&(Module.printErr=printErr),Module.read="undefined"!=typeof read?read:function(b){snarf(b)},Module.arguments||("undefined"!=typeof scriptArgs?Module.arguments=scriptArgs:"undefined"!=typeof arguments&&(Module.arguments=arguments)));ma&&!na&&(Module.print||(Module.print=function(b){console.log(b)}),Module.printErr||(Module.printErr=function(b){console.log(b)})); -if(ma||na)Module.read=function(b){var c=new XMLHttpRequest;c.open("GET",b,G);c.send(F);return c.responseText},Module.arguments||"undefined"!=typeof arguments&&(Module.arguments=arguments);na&&(Module.print||(Module.print=function(){}),Module.load=importScripts);!na&&(!ma&&!la&&!oa)&&da("Unknown runtime environment. Where are we?");function ra(b){eval.call(F,b)}"undefined"==!Module.load&&Module.read&&(Module.load=function(b){ra(Module.read(b))});Module.print||(Module.print=function(){}); -Module.printErr||(Module.printErr=Module.print);Module.arguments||(Module.arguments=[]);Module.print=Module.print;Module.c=Module.printErr;Module.preRun||(Module.preRun=[]);Module.postRun||(Module.postRun=[]);function sa(b){if(1==va)return 1;var c={"%i1":1,"%i8":1,"%i16":2,"%i32":4,"%i64":8,"%float":4,"%double":8}["%"+b];c||("*"==b.charAt(b.length-1)?c=va:"i"==b[0]&&(b=parseInt(b.substr(1)),wa(0==b%8),c=b/8));return c}function ya(b,c){return c&&c.length?za[b].apply(F,c):za[b]()}var Aa; -function Ba(){var b=[],c=0;this.v=function(d){d&=255;c&&(b.push(d),c--);if(0==b.length){if(128>d)return String.fromCharCode(d);b.push(d);c=191d?1:2;return""}if(0d?String.fromCharCode((d&31)<<6|e&63):String.fromCharCode((d&15)<<12|(e&63)<<6|f&63);b.length=0;return d};this.G=function(b){for(var b=unescape(encodeURIComponent(b)),c=[],f=0;f>2<<2;return c} -function Ea(b){var c=Fa;Fa=Fa+b|0;Fa=Fa+3>>2<<2;if(Fa>=Ga){for(;Ga<=Fa;)Ga=2*Ga+4095>>12<<12;wa(Ga<=Math.pow(2,30));var b=J,d=new ArrayBuffer(Ga);Module.HEAP8=J=new Int8Array(d);Module.HEAP16=K=new Int16Array(d);Module.HEAP32=L=new Int32Array(d);Module.HEAPU8=Ha=new Uint8Array(d);Module.HEAPU16=Ia=new Uint16Array(d);Module.HEAPU32=Ja=new Uint32Array(d);Module.HEAPF32=Ka=new Float32Array(d);Module.HEAPF64=La=new Float64Array(d);J.set(b)}return c}var va=4,Ma={},Na,Oa; -function Qa(b){Module.print(b+":\n"+Error().stack);da("Assertion: "+b)}function wa(b,c){b||Qa("Assertion failed: "+c)}var Ra=this;Module.ccall=function(b,c,d,e){return Sa(Ta(b),c,d,e)};function Ta(b){try{var c=Ra.Module["_"+b];c||(c=eval("_"+b))}catch(d){}wa(c,"Cannot call unknown function "+b+" (perhaps LLVM optimizations or closure removed it?)");return c} -function Sa(b,c,d,e){function f(b,d){if("string"==d){if(b===F||b===a||0===b)return 0;h||(h=I);var c=Da(b.length+1);Ua(b,c);return c}return"array"==d?(h||(h=I),c=Da(b.length),Va(b,c),c):b}var h=0,j=0,e=e?e.map(function(b){return f(b,d[j++])}):[];b=b.apply(F,e);"string"==c?c=Wa(b):(wa("array"!=c),c=b);h&&(I=h);return c}Module.cwrap=function(b,c,d){var e=Ta(b);return function(){return Sa(e,c,d,Array.prototype.slice.call(arguments))}}; -function Xa(b,c,d){d=d||"i8";"*"===d.charAt(d.length-1)&&(d="i32");switch(d){case "i1":J[b]=c;break;case "i8":J[b]=c;break;case "i16":K[b>>1]=c;break;case "i32":L[b>>2]=c;break;case "i64":Oa=[c>>>0,Math.min(Math.floor(c/4294967296),4294967295)>>>0];L[b>>2]=Oa[0];L[b+4>>2]=Oa[1];break;case "float":Ka[b>>2]=c;break;case "double":La[M>>3]=c;L[b>>2]=L[M>>2];L[b+4>>2]=L[M+4>>2];break;default:Qa("invalid type for setValue: "+d)}}Module.setValue=Xa; -Module.getValue=function(b,c){c=c||"i8";"*"===c.charAt(c.length-1)&&(c="i32");switch(c){case "i1":return J[b];case "i8":return J[b];case "i16":return K[b>>1];case "i32":return L[b>>2];case "i64":return L[b>>2];case "float":return Ka[b>>2];case "double":return L[M>>2]=L[b>>2],L[M+4>>2]=L[b+4>>2],La[M>>3];default:Qa("invalid type for setValue: "+c)}return F};var Ya=1,Za=2,P=3;Module.ALLOC_NORMAL=0;Module.ALLOC_STACK=Ya;Module.ALLOC_STATIC=Za;Module.ALLOC_NONE=P; -function Q(b,c,d,e){var f,h;"number"===typeof b?(f=E,h=b):(f=G,h=b.length);var j="string"===typeof c?c:F,d=d==P?e:[R,Da,Ea][d===a?Za:d](Math.max(h,j?1:c.length));if(f){e=d;wa(0==(d&3));for(b=d+(h&-4);e>2]=0;for(b=d+h;e=c?2*Math.abs(1<=b)return b;var d=32>=c?Math.abs(1<=d&&(32>=c||b>d))b=-2*d+b;return b}Math.g||(Math.g=function(b,c){var d=b&65535,e=c&65535;return d*e+((b>>>16)*e+d*(c>>>16)<<16)|0});var mb=0,nb={},ob=G,pb=F; -function qb(b){mb++;Module.monitorRunDependencies&&Module.monitorRunDependencies(mb);b?(wa(!nb[b]),nb[b]=1,pb===F&&"undefined"!==typeof setInterval&&(pb=setInterval(function(){var b=G,d;for(d in nb)b||(b=E,Module.c("still waiting on run dependencies:")),Module.c("dependency: "+d);b&&Module.c("(end of list)")},6E3))):Module.c("warning: run dependency added without ID")}Module.addRunDependency=qb; -function rb(b){mb--;Module.monitorRunDependencies&&Module.monitorRunDependencies(mb);b?(wa(nb[b]),delete nb[b]):Module.c("warning: run dependency removed without ID");0==mb&&(pb!==F&&(clearInterval(pb),pb=F),!ob&&sb&&tb())}Module.removeRunDependency=rb;Module.preloadedImages={};Module.preloadedAudios={};wa(Fa==ab);wa(ab==ab);Fa+=7528;wa(Fa>2]=b}var Eb,Fb=Q(1,"i32*",Ya),Gb=Q(1,"i32*",Ya);ub=Q(1,"i32*",Ya);var Hb=Q(1,"i32*",Ya),Ib=2,Jb=[F],Kb=E; -function Lb(b,c){if("string"!==typeof b)return F;c===a&&(c="/");b&&"/"==b[0]&&(c="");for(var d=(c+"/"+b).split("/").reverse(),e=[""];d.length;){var f=d.pop();""==f||"."==f||(".."==f?1d)return Db(zb),-1;if(e.object.b){if(e.object.e){for(var f=0;fd||0>f)Db(zb),c=-1;else{for(var j=b.object.a;j.length>2]=L[d+f>>2],L[M+4>>2]=L[d+(f+4)>>2],La[M>>3]):"i64"==b?c=[L[d+f>>2],L[d+(f+4)>>2]]:(b="i32",c=L[d+f>>2]);f+=Math.max(sa(b),va);return c}for(var f=0,h=[],j,g;;){var i=c;j=J[c];if(0===j)break;g=J[c+1|0];if(37==j){var l=G,m=G,k=G,n=G;a:for(;;){switch(g){case 43:l=E;break;case 45:m=E;break;case 35:k=E;break;case 48:if(n)break a;else{n=E;break}default:break a}c++;g=J[c+1|0]}var q=0;if(42==g)q=e("i32"),c++,g=J[c+1|0];else for(;48<=g&&57>=g;)q= -10*q+(g-48),c++,g=J[c+1|0];var v=G;if(46==g){var u=0,v=E;c++;g=J[c+1|0];if(42==g)u=e("i32"),c++;else for(;;){g=J[c+1|0];if(48>g||57>>0)+4294967296*(j[1]>>>0):(j[0]>>>0)+4294967296*(j[1]|0));4>=s&&(j=(i?lb:kb)(j&Math.pow(256,s)-1,8*s));var y=Math.abs(j),i="";if(100==g||105==g)p=8==s&&$b?$b.stringify(r[0],r[1],F):lb(j,8*s).toString(10);else if(117==g)p=8==s&&$b?$b.stringify(r[0],r[1],E):kb(j,8*s).toString(10),j=Math.abs(j);else if(111==g)p=(k?"0":"")+y.toString(8);else if(120==g||88==g){i=k?"0x":"";if(8==s&&$b)p=(r[1]>>>0).toString(16)+(r[0]>>>0).toString(16);else if(0>j){j=-j;p=(y-1).toString(16); -r=[];for(k=0;kj?"-"+i:"+"+i);i.length+p.lengths&&-4<=s?(g=(103==g?"f":"F").charCodeAt(0),u-=s+1):(g=(103==g?"e":"E").charCodeAt(0),u--),s=Math.min(u,20);if(101==g||69==g)p=j.toExponential(s),/[eE][-+]\d$/.test(p)&&(p=p.slice(0,-1)+"0"+p.slice(-1));else if(102==g||70==g)p=j.toFixed(s);i=p.split("e");if(v&&!k)for(;1s++;)i[0]+="0";p=i[0]+(1j?"-":"")+"inf",n=G;for(;p.lengthg&&(p=p.toUpperCase());p.split("").forEach(function(b){h.push(b.charCodeAt(0))})}else if(115==g){n=l=e("i8*")||eb;n|=0;g=0;for(g=n;J[g]|0;)g=g+1|0;n=g-n|0;v&&(n=Math.min(n,u));if(!m)for(;n>2]=h.length;else if(37==g)h.push(j);else for(k=i;k>2]=L[c>>2],b=b+4|0,c=c+4|0,d=d-4|0}for(;0<(d|0);)J[b]=J[c],b=b+1|0,c=c+1|0,d=d-1|0} -function bc(b,c){var d,b=b|0;d=0;var c=c|0,e=0,f=0,h=0,j=0,e=b+c|0;if(20<=(c|0)){d&=255;j=b&3;f=d|d<<8|d<<16|d<<24;h=e&-4;if(j)for(j=b+4-j|0;(b|0)<(j|0);)J[b]=d,b=b+1|0;for(;(b|0)<(h|0);)L[b>>2]=f,b=b+4|0}for(;(b|0)<(e|0);)J[b]=d,b=b+1|0} -var cc=[8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0];function dc(b){var c=cc[b>>>24];if(8>c)return c;c=cc[b>>16&255];if(8>c)return c+8;c=cc[b>>8&255];return 8>c?c+16:cc[b&255]+24}function W(){da("abort() at "+Error().stack)} -function ec(){switch(8){case 8:return $a;case 54:case 56:case 21:case 61:case 63:case 22:case 67:case 23:case 24:case 25:case 26:case 27:case 69:case 28:case 101:case 70:case 71:case 29:case 30:case 199:case 75:case 76:case 32:case 43:case 44:case 80:case 46:case 47:case 45:case 48:case 49:case 42:case 82:case 33:case 7:case 108:case 109:case 107:case 112:case 119:case 121:return 200809;case 13:case 104:case 94:case 95:case 34:case 35:case 77:case 81:case 83:case 84:case 85:case 86:case 87:case 88:case 89:case 90:case 91:case 94:case 95:case 110:case 111:case 113:case 114:case 115:case 116:case 117:case 118:case 120:case 40:case 16:case 79:case 19:return-1; -case 92:case 93:case 5:case 72:case 6:case 74:case 92:case 93:case 96:case 97:case 98:case 99:case 102:case 103:case 105:return 1;case 38:case 66:case 50:case 51:case 4:return 1024;case 15:case 64:case 41:return 32;case 55:case 37:case 17:return 2147483647;case 18:case 1:return 47839;case 59:case 57:return 99;case 68:case 58:return 2048;case 0:return 2097152;case 3:return 65536;case 14:return 32768;case 73:return 32767;case 39:return 16384;case 60:return 1E3;case 106:return 700;case 52:return 256; -case 62:return 255;case 2:return 100;case 65:return 64;case 36:return 20;case 100:return 16;case 20:return 6;case 53:return 4}Db(zb);return-1}function fc(b){gc||(Fa=Fa+4095>>12<<12,gc=E);var c=Fa;0!=b&&Ea(b);return c}var gc,hc=G,ic,jc,kc,lc; -hb.unshift({m:function(){if(!Module.noFSInit&&!Wb){var b,c,d,e=function(b){b===F||10===b?(c.i(c.buffer.join("")),c.buffer=[]):c.buffer.push(g.v(b))};wa(!Wb,"FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)");Wb=E;Pb();b=b||Module.stdin;c=c||Module.stdout;d=d||Module.stderr;var f=E,h=E,j=E;b||(f=G,b=function(){if(!b.k||!b.k.length){var c;"undefined"!=typeof window&&"function"== -typeof window.prompt?(c=window.prompt("Input: "),c===F&&(c=String.fromCharCode(0))):"function"==typeof readline&&(c=readline());c||(c="");b.k=db(c+"\n",E)}return b.k.shift()});var g=new Ba;c||(h=G,c=e);c.i||(c.i=Module.print);c.buffer||(c.buffer=[]);d||(j=G,d=e);d.i||(d.i=Module.print);d.buffer||(d.buffer=[]);try{Rb("/","tmp",E,E)}catch(i){}var e=Rb("/","dev",E,E),l=Vb(e,"stdin",b),m=Vb(e,"stdout",F,c);d=Vb(e,"stderr",F,d);Vb(e,"tty",b,c);Jb[1]={path:"/dev/stdin",object:l,position:0,q:E,h:G,p:G,r:!f, -error:G,o:G,z:[]};Jb[2]={path:"/dev/stdout",object:m,position:0,q:G,h:E,p:G,r:!h,error:G,o:G,z:[]};Jb[3]={path:"/dev/stderr",object:d,position:0,q:G,h:E,p:G,r:!j,error:G,o:G,z:[]};wa(128>Math.max(Fb,Gb,ub));L[Fb>>2]=1;L[Gb>>2]=2;L[ub>>2]=3;Sb("/","dev/shm/tmp",E,E);for(f=Jb.length;f>g-6&63,g=g-6,d=d+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[j]}2==g?(d+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&3)<<4],d+="=="):4==g&&(d+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(e&15)<<2],d+="=");l.src="data:audio/x-"+c.substr(-3)+";base64,"+d;f(l)}};l.src=j;setTimeout(function(){f(l)},1E4)}else return g()}})}for(var k, -n=[b,c],q=n[0],v=1;vj.status||304===j.status||da(Error("Couldn't load "+d+". Status: "+j.status));var g=Number(j.getResponseHeader("Content-length")), -i,l=1048576;if(!((i=j.getResponseHeader("Accept-Ranges"))&&"bytes"===i))l=g;var m=new h(l,g);m.J(function(b){var c=b*m.n,e=(b+1)*m.n-1,e=Math.min(e,g-1);if("undefined"===typeof m.f[b]){var f=m.f;c>e&&da(Error("invalid range ("+c+", "+e+") or no bytes requested!"));e>g-1&&da(Error("only "+g+" bytes available! programmer error!"));var h=new XMLHttpRequest;h.open("GET",d,G);g!==l&&h.setRequestHeader("Range","bytes="+c+"-"+e);"undefined"!=typeof Uint8Array&&(h.responseType="arraybuffer");h.overrideMimeType&& -h.overrideMimeType("text/plain; charset=x-user-defined");h.send(F);200<=h.status&&300>h.status||304===h.status||da(Error("Couldn't load "+d+". Status: "+h.status));c=h.response!==a?new Uint8Array(h.response||[]):db(h.responseText||"",E);f[b]=c}"undefined"===typeof m.f[b]&&da(Error("doXHR failed!"));return m.f[b]});h={b:G,a:m}}else h={b:G,url:d};return Tb(b,c,h,e,f)};Module.FS_createLink=function(b,c,d,e,f){return Tb(b,c,{b:G,link:d},e,f)};Module.FS_createDevice=Vb;Db(0);Q(12,"void*",Za); -Module.requestFullScreen=function(){function b(){}function c(){var b=G;if((document.webkitFullScreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.mozFullscreenElement||document.fullScreenElement||document.fullscreenElement)===d)d.I=d.requestPointerLock||d.mozRequestPointerLock||d.webkitRequestPointerLock,d.I(),b=E;if(Module.onFullScreen)Module.onFullScreen(b)}var d=Module.canvas;document.addEventListener("fullscreenchange",c,G);document.addEventListener("mozfullscreenchange", -c,G);document.addEventListener("webkitfullscreenchange",c,G);document.addEventListener("pointerlockchange",b,G);document.addEventListener("mozpointerlockchange",b,G);document.addEventListener("webkitpointerlockchange",b,G);d.H=d.requestFullScreen||d.mozRequestFullScreen||(d.webkitRequestFullScreen?function(){d.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:F);d.H()}; -Module.requestAnimationFrame=function(b){window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||window.setTimeout);window.requestAnimationFrame(b)};Module.pauseMainLoop=function(){};Module.resumeMainLoop=function(){hc&&(hc=G,F())};var za=[0,0,mc,0,nc,0,oc,0,pc,0,qc,0,rc,0,sc,0,tc,0,uc,0]; -function vc(b,c){var d=0,d=24*c&-1,c=L[b+8>>2];return 0==J[c+(d|1)|0]<<24>>24&&0==J[c+(d|2)|0]<<24>>24?0:d=Ha[d+(c+21)|0]+3|0} -function wc(b,c,d){var e,f,h,j,g,i,l,m,k,n,q,v,u,s,r,p,y,w,t,x,z;e=0;f=I;I=I+108|0;h=f>>2;j=f+36;if(1024>(d-c|0)>>>0){if(c>>>0>>0)g=1E30,l=i=c;else return I=f,c;for(;;)if(k=xc(l,b),n=(c=kl>>>0)return I=f,c;i=j|0;g=c;q=d;d=1E30;n=c;for(c=l;;){l=Math.floor((c>>>0)/10);k=l+g|0;L[h]=k;c=xc(k,b);k=j|0;La[M>>3]=c;L[k>>2]=L[M>>2];L[k+4>>2]=L[M+4>>2];k=(l<<1)+g|0;L[h+1]=k;c=xc(k,b);k=j+8|0;La[M>>3]=c;L[k>>2]=L[M>>2]; -L[k+4>>2]=L[M+4>>2];k=(3*l&-1)+g|0;L[h+2]=k;c=xc(k,b);k=j+16|0;La[M>>3]=c;L[k>>2]=L[M>>2];L[k+4>>2]=L[M+4>>2];k=(l<<2)+g|0;L[h+3]=k;c=xc(k,b);k=j+24|0;La[M>>3]=c;L[k>>2]=L[M>>2];L[k+4>>2]=L[M+4>>2];k=(5*l&-1)+g|0;L[h+4]=k;c=xc(k,b);k=j+32|0;La[M>>3]=c;L[k>>2]=L[M>>2];L[k+4>>2]=L[M+4>>2];k=(6*l&-1)+g|0;L[h+5]=k;c=xc(k,b);k=j+40|0;La[M>>3]=c;L[k>>2]=L[M>>2];L[k+4>>2]=L[M+4>>2];k=(7*l&-1)+g|0;L[h+6]=k;c=xc(k,b);k=j+48|0;La[M>>3]=c;L[k>>2]=L[M>>2];L[k+4>>2]=L[M+4>>2];k=(l<<3)+g|0;L[h+7]=k;c=xc(k,b);k= -j+56|0;La[M>>3]=c;L[k>>2]=L[M>>2];L[k+4>>2]=L[M+4>>2];k=(9*l&-1)+g|0;L[h+8]=k;l=xc(k,b);k=j+64|0;La[M>>3]=l;L[k>>2]=L[M>>2];L[k+4>>2]=L[M+4>>2];k=(L[M>>2]=L[i>>2],L[M+4>>2]=L[i+4>>2],La[M>>3]);l=j+8|0;c=(L[M>>2]=L[l>>2],L[M+4>>2]=L[l+4>>2],La[M>>3]);v=(l=c>2]=L[k>>2],L[M+4>>2]=L[k+4>>2],La[M>>3]);u=(k=c>2]=L[v>>2],L[M+4>>2]=L[v+4>>2],La[M>>3]);s=(v=c>2]=L[u>>2],L[M+4>>2]=L[u+4>>2],La[M>>3]);r=(u=c>2]=L[s>> -2],L[M+4>>2]=L[s+4>>2],La[M>>3]);p=(s=c>2]=L[r>>2],L[M+4>>2]=L[r+4>>2],La[M>>3]);y=(r=c>2]=L[p>>2],L[M+4>>2]=L[p+4>>2],La[M>>3]);w=(p=c>2]=L[y>>2],L[M+4>>2]=L[y+4>>2],La[M>>3]);k=(y=cd){m=n;e=30;break}0==(k|0)?(t=g,e=25):(w=L[(k-1<<2>>2)+h],8==(k|0)?(x=q,z=w):(t=w,e=25));25==e&&(e=0,x=L[(k+1<<2>>2)+h],z=t);w=L[(k<<2>>2)+h];c=x-z|0;if(10>c>>>0){m=w;e=32;break}else g=z,q=x,d=l,n=w}if(30== -e||32==e)return I=f,m}function xc(b,c){var d;d=c+4|0;return yc(L[c>>2],L[d>>2],L[c+12>>2],b,2)+yc(L[c>>2],L[d>>2],b,L[c+16>>2],2)}function zc(b,c){var d,e,f,h,j;d=b<<1;e=R(d);f=c|0;L[f>>2]=e;e=R(d);d=c+4|0;L[d>>2]=e;e=24*b&-1;h=R(e);j=c+8|0;L[j>>2]=h;a:do if(0!=(b|0)){for(h=0;!(K[L[f>>2]+(h<<1)>>1]=1,c=h+1|0,(c|0)==(b|0));)h=c;if(0!=(b|0))for(h=0;;)if(K[L[d>>2]+(h<<1)>>1]=0,h=h+1|0,(h|0)==(b|0))break a}while(0);if(0!=(e|0)){e=24*b&-1;for(b=0;!(J[L[j>>2]+b|0]=0,h=b+1|0,(h|0)==(e|0));)b=h}} -function Ac(b){Z(L[b>>2]);Z(L[b+4>>2]);Z(L[b+8>>2])} -function Bc(b,c,d,e,f,h,j){var g,i,l,m,k,n,q,v,u,s,r,p,y,w,t,x;g=0;i=I;I=I+28|0;l=i>>2;m=i+4;k=m>>2;n=i+8;if(!(10>e>>>0)){q=R(e);0==(q|0)&&wb();0!=(e|0)&&bc(q,e);L[l]=0;L[k]=e;v=0==(f|0);u=n|0;s=n+4|0;r=n+8|0;p=n+12|0;y=n+16|0;w=n;for(n=1;v|n>>>0>>0;){L[u>>2]=c;L[s>>2]=d;L[r>>2]=e;L[p>>2]=L[l];L[y>>2]=L[k];L[l]>>>0>=L[k]>>>0&&V(5245952,252,5246684,5245936);t=wc(w,L[l]+1|0,L[k]);t>>>0<=L[l]>>>0&&V(5245952,255,5246684,5245188);t>>>0>=L[k]>>>0&&V(5245952,256,5246684,5245036);if(yc(c,d,L[l],t,2)+yc(c, -d,t,L[k],2)>yc(c,d,L[l],L[k],2))g=146;else if((t|0)==(L[l]+1|0)|(t|0)==(L[k]|0))g=146;else{x=t;t=h;var z=j,A=a,B=a,C=a,D=a,A=z>>2,z=t>>2;t=0;B=L[A];0==(B-1&B|0)&&(C=0==(B|0)?R(4):Cc(L[z],B<<3),L[z]=C);L[L[z]+(L[A]<<2)>>2]=x;C=L[A]+1|0;L[A]=C;if(0!=(C|0)){C=L[A]-1|0;for(A=0;;){if(A>>>0>=C>>>0){t=49;break}if(L[L[z]+(A<<2)>>2]>>>0>x>>>0)break;else A=A+1|0}if(49!=t){a:do if(C>>>0>A>>>0)for(t=C;;)if(B=t-1|0,D=L[z],L[D+(t<<2)>>2]=L[D+(B<<2)>>2],B>>>0>A>>>0)t=B;else break a;while(0);L[L[z]+(A<<2)>>2]=x}}x= -n+1|0}146==g&&(g=0,J[q+L[l]|0]=1,x=n);n=e;t=q;for(var z=L[h>>2],A=L[j>>2],B=i,C=m,H=D=a,N=a,O=a,X=a,$=a,O=N=a,D=n-1|0,N=H=n=0;!(O=0==(n|0)?0:L[z+(n-1<<2)>>2],X=(n|0)==(A|0)?D:L[z+(n<<2)>>2],0==J[t+O|0]<<24>>24?($=X-O|0,$>>>0<=N>>>0?O=H:(L[B>>2]=O,L[C>>2]=X,N=$,O=1)):O=H,$=n+1|0,$>>>0>A>>>0);)n=$,H=O;if(0==(O|0))break;if(10>(L[k]-L[l]|0)>>>0)break;else n=x}if(0!=(L[b>>2]|0)){var b=L[h>>2],f=L[j>>2],Y,S,U,ea,j=I;a:do if(0==(f|0)|0==(e|0))S=Y=0;else for(k=g=h=m=0;;){l=0==K[d+(h<<1)>>1]<<16>>16?1:Ia[c+ -(h<<1)>>1];if((L[b+(m<<2)>>2]|0)==(h|0))if(0==(m-1&m|0)&&(k=0==(m|0)?R(4):Cc(k,m<<3)),v=k,L[v+(m<<2)>>2]=g,k=m+1|0,(k|0)==(f|0)){Y=v;S=k;break a}else m=k;else v=k;k=h+1|0;if(k>>>0>>0)h=k,g=l+g|0,k=v;else{Y=v;S=m;break a}}while(0);(S|0)!=(f|0)&&V(5245952,172,5246800,5244604);Yb(5244428,20,1,L[ub>>2]);f=L[ub>>2];if(0==(S|0))Yb(5244212,5,1,f),U=L[ub>>2];else{c=0;for(d=f;!(Zb(d,5244328,(Na=I,I=I+4|0,L[Na>>2]=L[Y+(c<<2)>>2],Na)),f=c+1|0,ea=L[ub>>2],(f|0)==(S|0));)c=f,d=ea;Yb(5244212,5,1,ea);ea=L[ub>> -2];if(0==(S|0))U=ea;else for(c=0;;)if(Zb(ea,5244156,(Na=I,I=I+4|0,L[Na>>2]=L[Y+(c<<2)>>2],Na)),ea=c+1|0,d=L[ub>>2],(ea|0)==(S|0)){U=d;break}else c=ea,ea=d}Yb(5245932,2,1,U);Z(Y);I=j}Z(q)}I=i} -function Dc(b,c){var d,e,f;d=b>>2;for(b=0;;)if(L[(b<<2>>2)+d]=8,e=b+1|0,144==(e|0)){f=144;break}else b=e;for(;!(L[(f<<2>>2)+d]=9,b=f+1|0,256==(b|0));)f=b;L[d+256]=7;L[d+257]=7;L[d+258]=7;L[d+259]=7;L[d+260]=7;L[d+261]=7;L[d+262]=7;L[d+263]=7;L[d+264]=7;L[d+265]=7;L[d+266]=7;L[d+267]=7;L[d+268]=7;L[d+269]=7;L[d+270]=7;L[d+271]=7;L[d+272]=7;L[d+273]=7;L[d+274]=7;L[d+275]=7;L[d+276]=7;L[d+277]=7;L[d+278]=7;L[d+279]=7;L[d+280]=8;L[d+281]=8;L[d+282]=8;L[d+283]=8;L[d+284]=8;L[d+285]=8;L[d+286]=8;L[d+287]= -8;for(d=0;!(L[c+(d<<2)>>2]=5,f=d+1|0,32==(f|0));)d=f}function Ec(b){var c,d,e,f;c=b>>2;for(e=d=b=0;!(30<=(d|0));)if(f=(0!=(L[(d<<2>>2)+c]|0)&1)+e|0,1<(f|0)){b=172;break}else d=d+1|0,e=f;172!=b&&(1==(e|0)?L[((0!=(L[c]|0)&1)<<2>>2)+c]=1:0==(e|0)&&(L[c+1]=1,L[c]=1))} -function yc(b,c,d,e,f){var h,j,g,i,l;h=I;I=I+2560|0;j=h+1280;g=h+2432;2<=(f-1|0)>>>0&&V(5245480,324,5246628,5245732);if(1==(f|0))Dc(j|0,g|0),f=3;else{f=h|0;i=h+1152|0;Fc(b,c,d,e,f,i);l=j|0;Gc(f,288,15,l);f=g|0;Gc(i,32,15,f);Ec(f);var m,k;i=I;I=I+12|0;m=i+4;k=i+8;L[i>>2]=0;L[m>>2]=0;J[k]=0;Hc(l,f,k,i,m);Z(L[i>>2]);I=i;f=((J[k]&7|L[m>>2]<<3)>>>0)+3}j|=0;i=d;var n;if(i>>>0>>0){k=0;for(d=i;;)if(i=K[c+(d<<1)>>1],m=Ia[b+(d<<1)>>1],0==i<<16>>16?i=L[j+(m<<2)>>2]+k|0:(l=(Ic(m)<<2)+j|0,k=L[l>>2]+k|0,l=i& -65535,i=(Jc(l)<<2)+(g|0)|0,i=((k+L[i>>2]|0)+L[(m<<2)+5248140>>2]|0)+Kc(l)|0),l=d+1|0,(l|0)==(e|0)){n=i;break}else k=i,d=l}else n=0;b=L[(j+1024|0)>>2]+n|0;I=h;return f+(b>>>0)} -function Lc(b,c,d,e,f,h,j,g){var i,l,m,k,n,q,v,u;i=I;I=I+40|0;l=i+16;m=l>>2;k=i+28;n=k>>2;q=f-e|0;Mc(l);v=i|0;L[v>>2]=b;L[i+8>>2]=e;L[i+12>>2]=f;b=R(12);u=(i+4|0)>>2;L[u]=b;zc(q,b);Nc(i,d,e,f,l);b=(l+8|0)>>2;1E3>L[b]>>>0?(Mc(k),Oc(i,d,e,f,k),d=yc(L[m],L[m+1],0,L[b],2),yc(L[n],L[n+1],0,L[n+2],1)>2,e=k>>2,L[d]=L[e],L[d+1]=L[e+1],L[d+2]=L[e+2],d=1):(Pc(k),d=2)):d=2;Qc(L[v>>2],d,c,L[m],L[m+1],0,L[b],q,h,j,g);Ac(L[u]);Z(L[u]);Pc(l);I=i} -function Qc(b,c,d,e,f,h,j,g,i,l,m){var k,n,q,v,u,s,r,p,y,w;k=0;n=I;I=I+3840|0;q=n+1152;v=n+1280;u=n+2432;s=n+2560;r=n+3712;Rc(d,i,l,m);Rc(c&1,i,l,m);Rc(c>>>1&1,i,l,m);1==(c|0)?Dc(v|0,u|0):(2!=(c|0)&&V(5245480,386,5246948,5245152),k=292);a:do if(292==k){c=n|0;d=q|0;Fc(e,f,h,j,c,d);p=v|0;Gc(c,288,15,p);c=u|0;Gc(d,32,15,c);Ec(c);d=L[m>>2];Hc(p,c,i,l,m);0!=(L[b>>2]|0)&&Zb(L[ub>>2],5244852,(Na=I,I=I+4|0,L[Na>>2]=L[m>>2]-d|0,Na));for(c=0;;)if(0!=(L[n+(c<<2)>>2]|0)&&0==(L[v+(c<<2)>>2]|0)&&V(5245480,399, -5246948,5244680),d=c+1|0,288==(d|0)){y=0;break}else c=d;for(;;)if(0!=(L[q+(y<<2)>>2]|0)&&0==(L[u+(y<<2)>>2]|0)&&V(5245480,400,5246948,5244564),d=y+1|0,32==(d|0))break a;else y=d}while(0);y=v|0;q=s|0;Sc(y,288,15,q);c=u|0;u=r|0;Sc(c,32,15,u);r=L[m>>2];k=j;d=i;p=l;var t,x,z,A,B,C,D,H,N;a:do if(h>>>0>>0){t=h;for(x=0;;)if(z=K[f+(t<<1)>>1],A=z&65535,B=K[e+(t<<1)>>1],C=B&65535,0==z<<16>>16?(256<=(B&65535)&&V(5245480,256,5246936,5244264),z=(C<<2)+y|0,0==(L[z>>2]|0)&&V(5245480,257,5246936,5244188),Tc(L[q+ -(C<<2)>>2],L[z>>2],d,p,m),x=x+1|0):(z=Ic(C),D=Jc(A),286<=(B-3&65535)&&V(5245480,263,5246936,5244124),B=(z<<2)+y|0,0==(L[B>>2]|0)&&V(5245480,264,5246936,5245912),H=(D<<2)+c|0,0==(L[H>>2]|0)&&V(5245480,265,5246936,5245780),Tc(L[q+(z<<2)>>2],L[B>>2],d,p,m),Uc(L[(C<<2)+5249176>>2],L[(C<<2)+5248140>>2],d,p,m),Tc(L[u+(D<<2)>>2],L[H>>2],d,p,m),z=z=a,5>(A|0)?z=0:(z=dc(A-1|0)^31,z=(1<>2],L[v+1024>>2],i,l,m);a:do if(h>>>0>>0){l=0;for(i=h;;)if(g=0==K[f+(i<<1)>>1]<<16>>16?1:Ia[e+(i<<1)>>1],v=g+l|0,s=i+1|0,(s|0)==(j|0)){w=v;break a}else l=v,i=s}else w=0;while(0);j=L[m>>2]-r|0;0!=(L[b>>2]|0)&&Zb(L[ub>>2],5244384,(Na=I,I=I+12|0,L[Na>>2]=j,L[Na+4>>2]=j>>>10,L[Na+8>>2]=w,Na));I=n} -function Rc(b,c,d,e){var f;f=e>>2;0==(J[c]&7)<<24>>24&&(e=L[f],0==(e-1&e|0)&&(e=0==(e|0)?R(1):Cc(L[d>>2],e<<1),L[d>>2]=e),J[L[d>>2]+L[f]|0]=0,L[f]=L[f]+1|0);e=L[d>>2]+(L[f]-1)|0;J[e]=(Ha[e]|b<<(J[c]&7))&255;J[c]=J[c]+1&255} -function Hc(b,c,d,e,f){var h,j,g,i,l,m,k,n,q,v,u,s,r,p,y,w,t,x,z,A,B,C,D,H,N,O,X,$,Y,S,U,ea,T,ga,ba,ja,ia,ca,aa,ta,Ca,xa,ua,Pa,fb;h=0;j=I;g=I=I+76|0;i=I=I+76|0;I=I+76|0;l=29;for(m=316;;){if(0==(l|0)){k=29;n=m;break}if(0==(L[b+(l+256<<2)>>2]|0))l=l-1|0,m=m-1|0;else{k=29;n=m;break}}for(;0!=(k|0);)if(0==(L[c+(k<<2)>>2]|0))k=k-1|0,n=n-1|0;else break;m=l+257|0;q=k+(l+258)|0;v=R(q<<2);u=v>>2;0==(v|0)&&wb();a:do if(0==(q|0))h=429;else{s=-257-l|0;for(r=0;!(p=r>>>0>>0?(r<<2)+b|0:(s+r<<2)+c|0,p=L[p>>2], -L[(r<<2>>2)+u]=p,16<=p>>>0&&V(5245480,134,5246964,5245640),p=r+1|0,(p|0)==(n|0));)r=p;if(0==(q|0))h=429;else{for(z=x=t=w=y=0;;){do if(z>>>0>>0){r=L[(z<<2>>2)+u];s=z;for(p=0;;){if((r|0)!=(L[(s<<2>>2)+u]|0)){A=p;break}B=p+1|0;C=s+1|0;if(C>>>0>>0)s=C,p=B;else{A=B;break}}if(3>=A>>>0){if(2>=A>>>0){h=415;break}if(0!=(L[(z<<2>>2)+u]|0)){h=415;break}}p=((z<<2)+v|0)>>2;do if(0==(L[p]|0))10>>0?(s=138>>0?138:A,D=0==(t-1&t|0)?r=0==(t|0)?R(4):Cc(y,t<<3):y,L[D+(t<<2)>>2]=18,r=t+1|0,H=0==(x-1&x|0)?B= -0==(x|0)?R(4):Cc(w,x<<3):w,L[H+(x<<2)>>2]=s-11|0):(D=0==(t-1&t|0)?r=0==(t|0)?R(4):Cc(y,t<<3):y,L[D+(t<<2)>>2]=17,r=t+1|0,H=0==(x-1&x|0)?B=0==(x|0)?R(4):Cc(w,x<<3):w,L[H+(x<<2)>>2]=A-3|0,s=A),B=x+1|0,C=H,N=D;else{r=A-1|0;O=0==(t-1&t|0)?B=0==(t|0)?R(4):Cc(y,t<<3):y;L[O+(t<<2)>>2]=L[p];X=0==(x-1&x|0)?B=0==(x|0)?R(4):Cc(w,x<<3):w;L[X+(x<<2)>>2]=0;s=x+1|0;B=t+1|0;b:do if(5>>0){C=O;$=X;Y=t;N=x;S=r;D=s;for(H=B;;)if(0==(H&Y|0)&&(C=0==(H|0)?R(4):Cc(C,H<<3)),L[C+(H<<2)>>2]=16,N=0==(D&N|0)?0==(D|0)?R(4): -Cc($,D<<3):$,L[N+(D<<2)>>2]=3,S=S-6|0,U=D+1|0,ea=H+1|0,5>>0)$=N,Y=H,N=D,D=U,H=ea;else{T=C;ga=N;ba=H;ja=D;ia=S;ca=U;aa=ea;break b}}else T=O,ga=X,ba=t,ja=x,ia=r,ca=s,aa=B;while(0);2>>0?(r=0==(aa&ba|0)?0==(aa|0)?R(4):Cc(T,aa<<3):T,L[r+(aa<<2)>>2]=16,B=ba+2|0,s=0==(ca&ja|0)?0==(ca|0)?R(4):Cc(ga,ca<<3):ga,L[s+(ca<<2)>>2]=0,C=ia-3|0,H=ja+2|0,O=B,D=s,S=r):(C=ia,H=ca,O=aa,D=ga,S=T);if(0==(C|0))s=A,B=H,r=O,C=D,N=S;else{B=C+H|0;s=S;r=D;D=O;for(S=C;!(ta=0==(D-1&D|0)?0==(D|0)?R(4):Cc(s,D<<3):s,L[ta+(D<< -2)>>2]=L[p],N=D+1|0,Ca=0==(H-1&H|0)?0==(H|0)?R(4):Cc(r,H<<3):r,L[Ca+(H<<2)>>2]=0,Y=S-1|0,0==(Y|0));)s=ta,r=Ca,D=N,H=H+1|0,S=Y;s=A;r=C+O|0;C=Ca;N=ta}}while(0);D=z-1+s|0;H=B;S=r;O=C}else h=415;while(0);415==h&&(h=0,0==(t-1&t|0)&&(y=p=0==(t|0)?R(4):Cc(y,t<<3)),L[y+(t<<2)>>2]=L[(z<<2>>2)+u],p=t+1|0,0==(x-1&x|0)&&(w=0==(x|0)?R(4):Cc(w,x<<3)),L[w+(x<<2)>>2]=0,D=z,H=x+1|0,S=p,O=w,N=y);19<=L[N+(S-1<<2)>>2]>>>0&&V(5245480,178,5246964,5245568);p=D+1|0;if(p>>>0>>0)y=N,w=O,t=S,x=H,z=p;else break}p=j>>2;for(x= -p+19;p>2,fb=N;else for(x=0;;)if(p=(L[N+(x<<2)>>2]<<2)+j|0,L[p>>2]=L[p>>2]+1|0,p=x+1|0,(p|0)==(S|0)){xa=S;ua=O;Pa=ua>>2;fb=N;break a}else x=p}}while(0);if(429==h){p=j>>2;for(x=p+19;p>2;fb=0}p=g|0;Gc(j|0,19,7,p);Sc(p,19,7,i|0);p=15;for(x=19;0!=(p|0);)if(0==(L[j+(L[(p+3<<2)+5250332>>2]<<2)>>2]|0))p=p-1|0,x=x-1|0;else break;Uc(l,5,d,e,f);Uc(k,5,d,e,f);Uc(p,4,d,e,f);a:do if(-4!=(p|0))for(k=0;;)if(Uc(L[g+(L[(k<<2)+5250332>>2]<<2)>>2], -3,d,e,f),l=k+1|0,(l|0)==(x|0))break a;else k=l;while(0);if(0!=(xa|0))for(b=0;!(x=(b<<2)+fb|0,p=L[x>>2],Tc(L[i+(p<<2)>>2],L[g+(p<<2)>>2],d,e,f),p=L[x>>2],16==(p|0)?Uc(L[(b<<2>>2)+Pa],2,d,e,f):17==(p|0)?Uc(L[(b<<2>>2)+Pa],3,d,e,f):18==(p|0)&&Uc(L[(b<<2>>2)+Pa],7,d,e,f),p=b+1|0,(p|0)==(xa|0));)b=p;Z(v);Z(fb);Z(ua);I=j} -function Tc(b,c,d,e,f){var h,j,g,i;h=f>>2;if(0!=(c|0)){f=c-1|0;for(j=0;!(g=b>>>((f-j|0)>>>0)&1,0==(J[d]&7)<<24>>24&&(i=L[h],0==(i-1&i|0)&&(i=0==(i|0)?R(1):Cc(L[e>>2],i<<1),L[e>>2]=i),J[L[e>>2]+L[h]|0]=0,L[h]=L[h]+1|0),i=L[e>>2]+(L[h]-1)|0,J[i]=(Ha[i]|g<<(J[d]&7))&255,J[d]=J[d]+1&255,g=j+1|0,(g|0)==(c|0));)j=g}} -function Uc(b,c,d,e,f){var h,j,g;h=f>>2;if(0!=(c|0))for(j=0;!(f=b>>>(j>>>0)&1,0==(J[d]&7)<<24>>24&&(g=L[h],0==(g-1&g|0)&&(g=0==(g|0)?R(1):Cc(L[e>>2],g<<1),L[e>>2]=g),J[L[e>>2]+L[h]|0]=0,L[h]=L[h]+1|0),g=L[e>>2]+(L[h]-1)|0,J[g]=(Ha[g]|f<<(J[d]&7))&255,J[d]=J[d]+1&255,f=j+1|0,(f|0)==(c|0));)j=f}function sc(b,c){return L[b>>2]-L[c>>2]|0}function Vc(b,c){var d;d=b+12|0;L[d>>2]=L[d>>2]<<5&32736^c&255} -function Wc(b,c,d){var e,f,h,j,g,i,l;e=(d+4|0)>>2;f=(d+8|0)>>2;h=(d|0)>>2;d=0==(b|0);j=c<<1;for(g=c<<1;;){if(L[e]>>>0>=((L[f]<<4)+L[h]|0)>>>0){a:do if(0<(L[f]|0))for(c=0;;)if(J[(c<<4)+L[h]+12|0]=0,i=c+1|0,(i|0)<(L[f]|0))c=i;else break a;while(0);a:do if(!(d|1>(j|0)))for(c=0;;){i=L[b+(((c|0)/2&-1)<<3)+((c|0)%2<<2)>>2];b:do if(0!=(i|0))for(l=i;;)if(J[l+12|0]=1,l=L[l+4>>2],0==(l|0))break b;while(0);i=c+1|0;if((i|0)==(g|0))break a;else c=i}while(0);L[e]=L[h]}i=L[e];c=0==J[i+12|0]<<24>>24;L[e]=i+16|0; -if(c)break}return i}function Xc(b,c,d,e){L[e>>2]=b;L[e+8>>2]=c;L[e+4>>2]=d;J[e+12|0]=1}function Mc(b){L[b+8>>2]=0;L[b>>2]=0;L[b+4>>2]=0} -function Yc(b){var c,d,e,f,h,j;L[b+12>>2]=0;c=R(262144);d=b|0;L[d>>2]=c;c=65536;e=R(c);f=b+4|0;L[f>>2]=e;e=131072;h=R(e);j=b+8|0;L[j>>2]=h;for(h=0;!(L[L[d>>2]+(h<<2)>>2]=-1,h=h+1|0,65536==(h|0)););a:do for(h=0;;)if(K[L[f>>2]+(h<<1)>>1]=h&65535,L[L[j>>2]+(h<<2)>>2]=-1,d=h+1|0,32768==(d|0))break a;else h=d;while(0);j=R(c);f=b+32|0;L[f>>2]=j;a:do for(j=0;;)if(K[L[f>>2]+(j<<1)>>1]=0,h=j+1|0,32768==(h|0))break a;else j=h;while(0);L[b+28>>2]=0;f=R(262144);j=b+16|0;L[j>>2]=f;f=R(c);c=b+20|0;L[c>>2]=f;f= -R(e);e=b+24|0;L[e>>2]=f;for(f=0;!(L[L[j>>2]+(f<<2)>>2]=-1,b=f+1|0,65536==(b|0));)f=b;for(b=0;!(K[L[c>>2]+(b<<1)>>1]=b&65535,L[L[e>>2]+(b<<2)>>2]=-1,f=b+1|0,32768==(f|0));)b=f}function Zc(b){b>>=2;Z(L[b]);Z(L[b+1]);Z(L[b+2]);Z(L[b+4]);Z(L[b+5]);Z(L[b+6]);Z(L[b+8])} -function $c(b,c,d,e){var f,h,j,g,i,l,m,k;f=0;h=c&32767;j=(c+3|0)>>>0>d>>>0?0:J[c+(b+2)|0];Vc(e,j);j=(e+12|0)>>2;g=h&65535;i=e+8|0;L[L[i>>2]+(g<<2)>>2]=L[j];l=L[j];m=e|0;k=L[L[m>>2]+(l<<2)>>2];-1==(k|0)?f=639:(L[L[i>>2]+(k<<2)>>2]|0)!=(l|0)?f=639:K[L[e+4>>2]+(g<<1)>>1]=k&65535;639==f&&(K[L[e+4>>2]+(g<<1)>>1]=h);L[L[m>>2]+(L[j]<<2)>>2]=g;m=(e+32|0)>>2;f=K[L[m]+((c+32767&32767)<<1)>>1];i=1<(f&65535)?(f&65535)-1|0:0;f=c+1|0;k=b+c|0;for(c=i;;){i=f+c|0;if(i>>>0>=d>>>0)break;if(J[k]<<24>>24==J[b+i|0]<<24>> -24&65535>c>>>0)c=c+1|0;else break}K[L[m]+(g<<1)>>1]=c&65535;c=Ia[L[m]+(g<<1)>>1]+253&255^L[j];j=(e+28|0)>>2;L[j]=c;m=e+24|0;L[L[m>>2]+(g<<2)>>2]=c;c=L[j];b=(e+16|0)>>2;k=L[L[b]+(c<<2)>>2];K[L[e+20>>2]+(g<<1)>>1]=-1!=(k|0)&&(L[L[m>>2]+(k<<2)>>2]|0)==(c|0)?k&65535:h;L[((L[j]<<2)+L[b]|0)>>2]=g}function ad(b,c,d){Vc(d,J[b+c|0]);Vc(d,J[c+(b+1)|0])} -function bd(b,c,d,e,f,h,j){var g,i,l,m,k,n,q,v,u,s,r;g=0;i=(h<<3)+b+4|0;l=L[L[i>>2]+8>>2];m=0==(h|0);k=(l|0)<(e|0);if(k|m^1){n=j;q=i;v=l;l=m;for(j=k;;){u=Wc(b,c,f);s=L[q>>2];L[b+(h<<3)>>2]=s;L[q>>2]=u;if(l){g=681;break}k=h-1|0;m=(k<<3)+b+4|0;l=L[L[m>>2]>>2]+L[L[b+(k<<3)>>2]>>2]|0;if(j&&(r=L[d+(v<<4)>>2],l>>>0>r>>>0)){g=684;break}Xc(l,v,L[m>>2],u);if(0!=n<<24>>24){g=690;break}bd(b,c,d,e,f,k,0);m=(k<<3)+b+4|0;l=L[L[m>>2]+8>>2];i=0==(k|0);j=(l|0)<(e|0);if(j|i^1)h=k,n=0,q=m,v=l,l=i;else{g=691;break}}681== -g?Xc(L[d+(v<<4)>>2],v+1|0,0,u):684==g&&Xc(r,v+1|0,L[s+4>>2],u)}}function Pc(b){Z(L[b>>2]);Z(L[b+4>>2])}function cd(b,c,d){var e,f,h,j,g;e=d>>2;f=(d+8|0)>>2;d=L[f];(h=0!=(d-1&d|0))?(K[L[e]+(d<<1)>>1]=b,L[f]=L[f]+1|0):(g=(j=0==(d|0))?R(2):Cc(L[e],d<<2),L[e]=g,K[g+(L[f]<<1)>>1]=b,L[f]=L[f]+1|0,h||(b=j?R(2):Cc(L[e+1],d<<2),L[e+1]=b));K[L[e+1]+(d<<1)>>1]=c} -function dd(b,c,d,e,f){var h;h=0;f&=65535;(f+d|0)>>>0>c>>>0&&V(5244924,87,5246480,5245612);c=d-(e&65535)|0;for(e=0;;){if(e>>>0>=f>>>0){h=713;break}if(J[b+c+e|0]<<24>>24==J[b+e+d|0]<<24>>24)e=e+1|0;else break}713!=h&&V(5244924,90,5246480,5245112)} -function ed(b,c,d,e,f,h,j,g,i){var l,m,k,n,q,v,u,s,r,p,y,w,t,x,z,A,B,C,D,H,N,O,X,$,Y,S,U,ea,T,ga,ba;l=I;I=I+4|0;m=l;k=m>>2;L[k]=h;h=e&32767;n=L[c>>2];q=L[c+4>>2];v=L[c+8>>2];u=L[c+12>>2];if(0!=(fd(b,e,m,j,g,i)|0))(Ia[i>>1]+e|0)>>>0<=f>>>0||V(5244924,243,5246564,5244828);else if(m=L[k],259>m>>>0?s=m:(V(5244924,248,5246564,5244652),s=L[k]),2>=s>>>0&&V(5244924,249,5246564,5244536),(s=e>>>0>>0)||V(5244924,250,5246564,5244372),m=f-e|0,3>m>>>0)K[i>>1]=0,K[g>>1]=0;else{(L[k]+e|0)>>>0>f>>>0&&(L[k]=m); -m=d+e|0;r=L[k]+e|0;p=d+r|0;y=d+(r-8)|0;65536<=(u|0)&&V(5244924,266,5246564,5244248);r=L[n+(u<<2)>>2];w=r&65535;t=K[q+(w<<1)>>1];(w|0)!=(h|0)&&V(5244924,271,5246564,5244176);x=t&65535;z=c+16|0;A=c+32|0;B=c+28|0;C=c+24|0;D=c+20|0;H=c+32|0;c=m;N=0==(j|0);O=t;t=r&65535;r=u;u=v;v=q;q=n;n=(x>>>0>>0?w:w+32768|0)-x|0;x=8192;w=0;X=1;a:for(;;){if(32768<=n>>>0){$=w;Y=X;break}S=O&65535;-1>=O<<16>>16&&V(5244924,279,5246564,5243984);O<<16>>16!=K[v+((t&65535)<<1)>>1]<<16>>16&&V(5244924,280,5246564,5245896);(L[u+ -(S<<2)>>2]|0)!=(r|0)&&V(5244924,281,5246564,5245760);do if(0==(n|0))U=w,ea=X;else if(s||V(5244924,284,5246564,5244372),n>>>0>e>>>0&&V(5244924,285,5246564,5245660),t=e-n|0,T=d+t|0,ga=X&65535,U=ga+e|0,U>>>0>>0&&J[d+U|0]<<24>>24!=J[d+t+ga|0]<<24>>24)U=w,ea=X;else{ga=L[H>>2];U=K[ga+(h<<1)>>1];2<(U&65535)?J[m]<<24>>24!=J[T]<<24>>24?ba=m:(T=K[ga+((t&32767)<<1)>>1],ba=(U&65535)<(T&65535)?U:T,T=L[k],ba=((ba&65535)>>>0>T>>>0?T&65535:ba)&65535,T=d+ba+t|0,ba=d+ba+e|0):ba=m;var ja=ga=a,ia=a,ca=t=U=a,aa=a, -ia=ja=ea=a;ga=0;c:do if(ba>>>0>>0){ja=T;for(ia=ba;;){if(J[ia]<<24>>24!=J[ja]<<24>>24){U=ia;t=ja;break c}ca=ia+1|0;aa=ja+1|0;if(J[ca]<<24>>24!=J[aa]<<24>>24){U=ca;t=aa;break c}aa=ia+2|0;ca=ja+2|0;if(J[aa]<<24>>24!=J[ca]<<24>>24){U=aa;t=ca;break c}ca=ia+3|0;aa=ja+3|0;if(J[ca]<<24>>24!=J[aa]<<24>>24){U=ca;t=aa;break c}aa=ia+4|0;ca=ja+4|0;if(J[aa]<<24>>24!=J[ca]<<24>>24){U=aa;t=ca;break c}ca=ia+5|0;aa=ja+5|0;if(J[ca]<<24>>24!=J[aa]<<24>>24){U=ca;t=aa;break c}aa=ia+6|0;ca=ja+6|0;if(J[aa]<<24>>24!=J[ca]<< -24>>24){U=aa;t=ca;break c}ca=ia+7|0;aa=ja+7|0;if(J[ca]<<24>>24!=J[aa]<<24>>24){U=ca;t=aa;break c}aa=ia+8|0;ca=ja+8|0;if(aa>>>0>>0)ja=ca,ia=aa;else{U=aa;t=ca;break c}}}else U=ba,t=T;while(0);if((U|0)==(p|0))T=ea=U;else{ja=t;for(ia=U;;){if(J[ia]<<24>>24!=J[ja]<<24>>24){ea=ia;ga=737;break}U=ia+1|0;if((U|0)==(p|0)){ea=U;ga=738;break}else ja=ja+1|0,ia=U}T=737==ga||738==ga?ea:a}T=T-c|0;t=T&65535;U=T&65535;if((t&65535)<=(X&65535))U=w,ea=X;else{b:do if(!N&&(T=X+1&65535,!((T&65535)>(t&65535)))){ga=n&65535; -for(ba=T;;)if(K[j+((ba&65535)<<1)>>1]=ga,T=ba+1&65535,(T&65535)>(t&65535))break b;else ba=T}while(0);ba=n&65535;if(U>>>0>>0)U=ba,ea=t;else{$=ba;Y=t;break a}}}while(0);ba=L[z>>2];(q|0)!=(ba|0)&&!((ea&65535)>2]+(h<<1)>>1])&&(ga=L[B>>2],T=L[C>>2],(ga|0)==(L[T+(S<<2)>>2]|0)&&(r=ga,u=T,v=L[D>>2],q=ba));ba=K[v+(S<<1)>>1];if(ba<<16>>16==O<<16>>16){$=U;Y=ea;break}T=((ba&65535)<(O&65535)?S:S+32768|0)-(ba&65535)+n|0;ga=x-1|0;if(1>(ga|0)){$=U;Y=ea;break}else t=O,O=ba,n=T,x=ga,w=U,X=ea}c=b;h=$; -m=Y;n=0;b=e-L[c+8>>2]|0;d=(c+4|0)>>2;c=L[d];s=0==(c|0)?0:0==K[L[c>>2]+(b<<1)>>1]<<16>>16?1:0!=K[L[c+4>>2]+(b<<1)>>1]<<16>>16;c=L[d];if(!(258!=(L[k]|0)|0==(c|0)|0==(j|0)|s)){1==K[L[c>>2]+(b<<1)>>1]<<16>>16?0!=K[L[c+4>>2]+(b<<1)>>1]<<16>>16&&(n=833):n=833;833==n&&V(5244924,210,5246772,5245400);n=m&65535;c=3>(m&65535);K[L[L[d]+4>>2]+(b<<1)>>1]=c?0:h;K[L[L[d]>>2]+(b<<1)>>1]=c?0:m;m=L[d];1==K[L[m>>2]+(b<<1)>>1]<<16>>16&&0==K[L[m+4>>2]+(b<<1)>>1]<<16>>16&&V(5244924,213,5246772,5245300);var c=n,d=L[d],ta, -Ca,xa,ua,h=0;m=24*b&-1;n=L[d+8>>2];if(!(3>c>>>0)){s=m|1;p=m|2;A=y=0;for(x=3;;){(x|0)==(c|0)?h=117:K[j+(x<<1)>>1]<<16>>16==K[j+(x+1<<1)>>1]<<16>>16?(ta=A,Ca=y):h=117;if(117==h)if(h=0,A=3*y&-1,J[n+A+m|0]=x+253&255,z=(x<<1)+j|0,J[n+s+A|0]=K[z>>1]&255,J[n+p+A|0]=Ia[z>>1]>>>8&255,z=y+1|0,7>>0){xa=x;h=123;break}else ta=x,Ca=z;z=x+1|0;if(z>>>0>c>>>0){h=119;break}else y=Ca,A=ta,x=z}119==h&&(8<=Ca>>>0?(xa=ta,h=123):((ta|0)!=(c|0)&&V(5245824,73,5246500,5245800),J[m+(n+21)|0]=ta+253&255,ua=ta));123==h&&(xa>>> -0<=c>>>0||V(5245824,76,5246500,5245164),ua=xa);(ua|0)!=(vc(d,b)|0)&&V(5245824,78,5246500,5244868)}}j=Y&65535;j>>>0>L[k]>>>0&&V(5244924,349,5246564,5245592);K[g>>1]=$;K[i>>1]=Y;(j+e|0)>>>0<=f>>>0||V(5244924,353,5246564,5244828)}I=l} -function fd(b,c,d,e,f,h){var j,g,i;j=h>>1;h=c-L[b+8>>2]|0;c=(b+4|0)>>2;b=L[c];if(0==(b|0)||0!=K[L[b>>2]+(h<<1)>>1]<<16>>16&&0==K[L[b+4>>2]+(h<<1)>>1]<<16>>16)return 0;b=L[d>>2];if(258==(b|0))g=0;else if(i=L[c],Ia[L[i>>2]+(h<<1)>>1]>>>0<=b>>>0)g=0;else{if(0==(e|0))return 0;g=vc(i,h)>>>0>>0}b=L[c];if(0==(b|0)|g)return 0;if(g=0!=(e|0))if(i=Ia[L[b>>2]+(h<<1)>>1],!(i>>>0<=vc(b,h)>>>0))return L[d>>2]=i,0;b=K[L[L[c]>>2]+(h<<1)>>1];K[j]=b;i=L[d>>2];(b&65535)>>>0>i>>>0&&(K[j]=i&65535);i=L[c];if(!g)return K[f>> -1]=K[L[i+4>>2]+(h<<1)>>1],1;b=i;g=h;i=Ia[j];var l,m,k,n,q,v,u,s,r,p;l=vc(b,g);if(!(3>i>>>0)){i=24*g&-1;g=L[b+8>>2];b=i|1;m=i|2;for(n=k=0;;){q=3*n&-1;v=J[g+q+i|0];u=v&255;s=u+3|0;r=Ha[g+m+q|0]<<8|Ha[g+b+q|0];a:do if(k>>>0<=s>>>0){q=(v&255)+4|0;for(p=k;;)if(K[e+(p<<1)>>1]=r,p=p+1|0,(p|0)==(q|0))break a}while(0);if((s|0)==(l|0))break;r=n+1|0;if(8>r>>>0)k=u+4|0,n=r;else break}}K[f>>1]=K[e+(Ia[j]<<1)>>1];if(258!=(L[d>>2]|0))return 1;d=K[j];if(2>=(d&65535)||K[e+((d&65535)<<1)>>1]<<16>>16==K[L[L[c]+4>>2]+ -(h<<1)>>1]<<16>>16)return 1;V(5244924,177,5246728,5245260);return 1} -function gd(b,c,d,e,f){var h,j,g,i,l,m,k,n,q,v,u,s,r,p,y,w,t,x,z,A;h=0;j=I;I=I+564|0;g=j>>1;i=j+4;l=i>>1;m=j+8;k=j+528;n=32768>>0?d-32768|0:0;if((d|0)!=(e|0)){Yc(k);ad(c,n,k);a:do if(n>>>0>>0)for(q=n;;)if($c(c,q,e,k),v=q+1|0,(v|0)==(d|0))break a;else q=v;while(0);a:do if(d>>>0>>0){n=m|0;v=q=0;u=d;for(s=0;;){$c(c,u,e,k);ed(b,k,c,u,e,258,n,i,j);r=K[g];p=r&65535;y=Ia[l];w=((1024<(y|0))<<31>>31)+p|0;if(0==(s|0))2>=(w|0)?h=859:258>(r&65535)?(t=1,x=u,z=y,A=p):h=858;else if((w|0)>((((1024<(v|0))<< -31>>31)+q|0)+1|0))cd(Ha[c+(u-1)|0],0,f),255>(w-3|0)>>>0?(t=1,x=u,z=Ia[l],A=Ia[g]):h=2<(w|0)?858:859;else{x=q&65535;K[g]=x;t=v&65535;K[l]=t;dd(c,e,u-1|0,t,x);cd(K[g],K[l],f);if(2>=Ia[g])t=0,x=u;else{x=K[g];t=x&65535;z=x&65535;x=3>>0?z:3;z=2;for(A=u;!(A>>>0>=e>>>0&&V(5244924,415,5246544,5245532),A=A+1|0,$c(c,A,e,k),z=z+1|0,!(z>>>0>>0)););t=0;x=u-2+x|0}z=v;A=q}858==h?(dd(c,e,u,K[l],K[g]),cd(K[g],K[l],f),h=860):859==h&&(K[g]=1,cd(Ha[c+u|0],0,f),h=860);do if(860==h){h=0;if(1>=Ia[g])t=0,x=u;else{w= -K[g];p=w&65535;y=w&65535;w=2>>0?y:2;y=1;for(r=u;;)if(r>>>0>=e>>>0&&V(5244924,440,5246544,5245532),A=r+1|0,$c(c,A,e,k),z=y+1|0,z>>>0

    >>0)y=z,r=A;else break;t=0;x=u-1+w|0}z=v;A=q}while(0);r=x+1|0;if(r>>>0>>0)q=A,v=z,u=r,s=t;else break a}}while(0);Zc(k)}I=j} -function Fc(b,c,d,e,f,h){var j,g,i;j=f>>2;for(g=j+288;j>2;for(g=j+32;j>>0>>0)for(i=d;!(d=(i<<1)+c|0,j=Ia[b+(i<<1)>>1],0==K[d>>1]<<16>>16?g=(j<<2)+f|0:(g=(Ic(j)<<2)+f|0,L[g>>2]=L[g>>2]+1|0,g=(Jc(Ia[d>>1])<<2)+h|0),L[g>>2]=L[g>>2]+1|0,g=i+1|0,(g|0)==(e|0));)i=g;L[(f+1024|0)>>2]=1}function hd(b){var c,d;c=(b+4|0)>>2;d=L[c];L[c]=(36969*(d&65535)&-1)+(d>>>16)|0;d=b|0;b=L[d>>2];b=(18E3*(b&65535)&-1)+(b>>>16)|0;L[d>>2]=b;return(L[c]<<16)+b|0} -function id(b,c){var d,e,f,h;d=b+8|0;if(0!=(L[d>>2]|0)){e=b+4|0;f=b|0;for(b=0;;)if(h=Ia[L[f>>2]+(b<<1)>>1],0==K[L[e>>2]+(b<<1)>>1]<<16>>16?h=(h<<2)+c|0:(h=(Ic(h)<<2)+c|0,L[h>>2]=L[h>>2]+1|0,h=(Jc(Ia[L[e>>2]+(b<<1)>>1])<<2)+c+1152|0),L[h>>2]=L[h>>2]+1|0,h=b+1|0,h>>>0>2]>>>0)b=h;else break}L[(c+1024|0)>>2]=1;jd(c)} -function kd(b,c,d,e,f,h,j,g,i,l){var m;var k=e,n,q,v,u,s,r,p,y,w,t,x,z,A,B,C,D,H,N,O,X,$,Y,S;m=I;I=I+564|0;n=m+4;q=m+8;v=m+528;u=k-d|0;s=32768>>0?d-32768|0:0;B=3;C=0;for(r=1E30;;)if(x=za[g](B,1,i),p=(z=x>2],i),C>2]):(x=A,t=y),r=w+1|0,30==(r|0));)y=t,w=r,A=x;r=za[g](p,t,i);if((d|0)==(k|0))g=0;else{p=u+1|0;w=y=R(p<<2);t=w>>2;0==(y|0)&&wb();Yc(v);ad(c,s,v);b:do if(s>>>0>>0)for(x= -s;;)if($c(c,x,k,v),z=x+1|0,(z|0)==(d|0))break b;else x=z;while(0);b:do if(1

    >>0){s=k+1-d|0;for(x=1;;)if(Ka[(x<<2>>2)+t]=1.0000000150474662E30,z=x+1|0,(z|0)==(s|0))break b;else x=z}while(0);Ka[t]=0;K[j>>1]=0;b:do if(d>>>0>>0){p=v+32|0;x=d+259|0;s=q|0;z=258-d|0;for(A=d;;){B=A-d|0;$c(c,A,k,v);C=L[p>>2];if(516>1])if(A>>>0>x>>>0&(A+517|0)>>>0>>0)if(258>=Ia[C+((A+32510&32767)<<1)>>1])D=A,H=B;else{N=za[g](258,1,i);H=z+A|0;O=B;X=0;for($=A;!(Y=O+258|0,Ka[(Y<<2>>2)+t]=N+Ka[(O<< -2>>2)+t],K[j+(Y<<1)>>1]=258,Y=$+1|0,$c(c,Y,k,v),S=X+1|0,258==(S|0));)O=O+1|0,X=S,$=Y;D=A+258|0}else D=A,H=B;else D=A,H=B;ed(b,v,c,D,k,258,s,n,m);B=D+1|0;B>>>0<=k>>>0&&(C=Ka[(H<<2>>2)+t]+za[g](Ha[c+D|0],0,i),0>C&&V(5244484,274,5246840,5244160),$=H+1|0,X=($<<2)+w|0,C>=Ka[X>>2]||(Ka[X>>2]=C,K[j+($<<1)>>1]=1));c:do if(3<=Ia[m>>1]){$=(H<<2)+w|0;C=Ia[m>>1];for(X=3;;){if((X+D|0)>>>0>k>>>0)break c;O=X+H|0;N=((O<<2)+w|0)>>2;Y=Ka[$>>2];Ka[N]-Y>r&&(S=Y+za[g](X,Ia[q+(X<<1)>>1],i),0>S&&V(5244484,289,5246840,5244160), -S>=Ka[N]||(259<=X>>>0&&V(5244484,291,5246840,5243932),Ka[N]=S,K[j+(O<<1)>>1]=X&65535));O=X+1|0;if(O>>>0>C>>>0)break c;else X=O}}while(0);if(B>>>0>>0)A=B;else break b}}while(0);k=(u<<2)+w|0;0>Ka[k>>2]&&V(5244484,298,5246840,5245872);w=Ka[k>>2];Zc(v);Z(y);g=w}I=m;m=g;Z(L[f>>2]);L[f>>2]=0;L[h>>2]=0;q=e-d|0;i=h>>2;g=f>>2;if(0!=(q|0)){for(k=q;!(q=L[i],0==(q-1&q|0)&&(n=0==(q|0)?R(2):Cc(L[g],q<<2),L[g]=n),q=((k<<1)+j|0)>>1,K[L[g]+(L[i]<<1)>>1]=K[q],L[i]=L[i]+1|0,n=K[q],(n&65535)>>>0>k>>>0&&(V(5244484, -319,5246756,5244452),n=K[q]),259<=(n&65535)&&V(5244484,320,5246756,5244332),0==K[q]<<16>>16&&V(5244484,321,5246756,5244220),n=Ia[q],(k|0)==(n|0));)k=k-n|0;k=L[i];if(1>>0){v=q=0;for(u=k;;)if(k=L[g],n=(q<<1)+k|0,j=K[n>>1],K[n>>1]=K[k+(v-1+u<<1)>>1],K[L[g]+(v-1+L[i]<<1)>>1]=j,j=q+1|0,k=q^-1,n=L[i],j>>>0>>1>>>0)q=j,v=k,u=n;else break}}f=L[f>>2];h=L[h>>2];j=I;I=I+44|0;g=j+36;i=j+40;k=32768>>0?d-32768|0:0;if((d|0)!=(e|0)){Yc(j);ad(c,k,j);a:do if(k>>>0>>0)for(n=k;;)if($c(c,n,e,j),q=n+1|0,(q| -0)==(d|0))break a;else n=q;while(0);a:do if(0!=(h|0)){k=d;for(n=0;;){q=K[f+(n<<1)>>1];k>>>0>=e>>>0&&V(5244484,360,5246856,5245100);$c(c,k,e,j);(s=2<(q&65535))?(v=q&65535,ed(b,j,c,k,e,v,0,i,g),u=K[g>>1],u<<16>>16!=q<<16>>16&s&2<(u&65535)&&V(5244484,370,5246856,5244768),dd(c,e,k,K[i>>1],q),cd(q,K[i>>1],l),s=v):(cd(Ha[c+k|0],0,l),s=1);v=s+k|0;v>>>0>e>>>0&&V(5244484,381,5246856,5244628);b:do if(1>>0)for(q=1;;)if($c(c,q+k|0,e,j),u=q+1|0,(u|0)==(s|0))break b;else q=u;while(0);q=n+1|0;if((q|0)==(h|0))break a; -else k=v,n=q}}while(0);Zc(j)}I=j;1E30>m||V(5244484,443,5246824,5245372)}function oc(b,c,d){var e,f,h;0==(c|0)?(e=(b<<3)+d+1280|0,b=(L[M>>2]=L[e>>2],L[M+4>>2]=L[e+4>>2],La[M>>3])):(e=Ic(b),f=L[(b<<2)+5248140>>2],b=Jc(c),h=Kc(c),c=(e<<3)+d+1280|0,e=(b<<3)+d+3584|0,b=(f|0)+(L[M>>2]=L[c>>2],L[M+4>>2]=L[c+4>>2],La[M>>3])+(h|0)+(L[M>>2]=L[e>>2],L[M+4>>2]=L[e+4>>2],La[M>>3]));return b}function ld(b,c){ac(c,b,1152);ac(c+1152|0,b+1152|0,128);ac(c+1280|0,b+1280|0,2304);ac(c+3584|0,b+3584|0,256)} -function jd(b){md(b|0,288,b+1280|0);md(b+1152|0,32,b+3584|0)}function uc(b,c,d){0==(c|0)?d=144>b>>>0?8:9:(c=Kc(c),d=(L[(b<<2)+5248140>>2]|0)+(c|0)+(280>(Ic(b)|0)?12:13));return d}function nd(b,c,d){var e,f;if(0<(d|0))for(e=0;!(0==((hd(b)>>>4>>>0)%3|0)&&(f=((hd(b)>>>0)%(d>>>0)<<2)+c|0,L[c+(e<<2)>>2]=L[f>>2]),f=e+1|0,(f|0)==(d|0));)e=f} -function Nc(b,c,d,e,f){var h,j,g,i,l,m,k,n,q,v,u,s,r,p,y,w,t,x;h=I;I=I+11548|0;j=h>>2;g=h+4;i=h+8;l=h+20;m=h+3860;k=h+7700;n=h+11540;q=R((e-d<<1)+2|0);L[j]=0;L[g>>2]=0;0==(q|0)&&wb();L[n>>2]=1;L[n+4>>2]=2;bc(l,3840);Mc(i);gd(b,c,d,e,i);id(i,l);v=b|0;if(!(0>=(L[L[v>>2]+4>>2]|0))){u=i|0;s=i+4|0;r=i+8|0;p=0;y=1E30;w=0;for(t=-1;;){Pc(i);Mc(i);kd(b,c,d,e,h,g,q,6,l,i);x=yc(L[u>>2],L[s>>2],0,L[r>>2],2);if(x>2;B=R(L[A]<<1);C=(z|0)>>2;L[C]=B;B=R(L[A]<<1); -D=z+4|0;L[D>>2]=B;0==(L[C]|0)|0==(B|0)&&wb();L[z+8>>2]=L[A];if(0!=(L[A]|0)){z=y|0;B=y+4|0;for(y=0;;)if(K[L[C]+(y<<1)>>1]=K[L[z>>2]+(y<<1)>>1],K[L[D>>2]+(y<<1)>>1]=K[L[B>>2]+(y<<1)>>1],H=y+1|0,H>>>0>>0)y=H;else break}ld(l,m);y=x}ld(l,k);z=l;B=A=A=a;A=z;A>>=2;for(B=A+288;A>=2;for(B=A+32;A>2]>>>0)+0.5*(L[A+(C<<2)>>2]>>>0),H=0<=H?Math.floor(H):Math.ceil(H),L[B+(C<<2)>>2]=H,H=C+1|0,288== -(H|0)){D=0;break}else C=H;for(;!(C=(L[z+(D<<2)+1152>>2]>>>0)+0.5*(L[A+(D<<2)+1152>>2]>>>0),H=0<=C?Math.floor(C):Math.ceil(C),L[B+(D<<2)+1152>>2]=H,H=D+1|0,32==(H|0));)D=H;L[B+1024>>2]=1;jd(l)}5<(p|0)&x==w&&(ld(m,l),w=n,t=l,nd(w,t|0,288),nd(w,t+1152|0,32),L[t+1024>>2]=1,jd(l),t=p);p=p+1|0;if((p|0)<(L[L[v>>2]+4>>2]|0))w=x;else break}}Z(q);Z(L[j]);Pc(i);I=h} -function Oc(b,c,d,e,f){var h,j,g;h=I;I=I+8|0;j=h+4;g=R((e-d<<1)+2|0);L[h>>2]=0;L[j>>2]=0;0==(g|0)?wb():(L[b+8>>2]=d,L[b+12>>2]=e,kd(b,c,d,e,h,j,g,18,0,f),Z(g),Z(L[h>>2]),I=h)}function Ic(b){return L[(b<<2)+5247104>>2]} -function Sc(b,c,d,e){var f,h,j,g,i,l,m,k;f=(d<<2)+4|0;j=h=R(f);g=j>>2;f=i=R(f);0!=(c|0)&&bc(e,c<<2);for(l=0;!(L[(l<<2>>2)+g]=0,m=l+1|0,m>>>0>d>>>0);)l=m;a:do if(0!=(c|0))for(l=0;;)if(m=(l<<2)+b|0,L[m>>2]>>>0>d>>>0&&V(5244280,47,5246520,5245236),k=(L[m>>2]<<2)+j|0,L[k>>2]=L[k>>2]+1|0,k=l+1|0,(k|0)==(c|0))break a;else l=k;while(0);L[g]=0;a:do if(0!=(d|0)){j=0;for(l=1;;)if(k=L[(l-1<<2>>2)+g]+j<<1,L[f+(l<<2)>>2]=k,m=l+1|0,m>>>0>d>>>0)break a;else j=k,l=m}while(0);if(0!=(c|0))for(j=0;!(d=L[b+(j<<2)>>2], -0!=(d|0)&&(g=((d<<2)+f|0)>>2,L[e+(j<<2)>>2]=L[g],L[g]=L[g]+1|0),g=j+1|0,(g|0)==(c|0));)j=g;Z(h);Z(i)} -function md(b,c,d){var e,f,h,j,g;e=0;if(0==(c|0))e=1060;else{for(h=f=0;!(j=L[b+(f<<2)>>2]+h|0,f=f+1|0,(f|0)==(c|0));)h=j;0==(j|0)?e=1060:g=Math.log(j>>>0)}1060==e&&(g=Math.log(c>>>0));e=1.4426950408889*g;if(0!=(c|0))for(f=0;!(g=L[b+(f<<2)>>2],0==(g|0)?(j=(f<<3)+d|0,La[M>>3]=e,L[j>>2]=L[M>>2],L[j+4>>2]=L[M+4>>2]):(j=e-1.4426950408889*Math.log(g>>>0),g=(f<<3)+d|0,La[M>>3]=j,L[g>>2]=L[M>>2],L[g+4>>2]=L[M+4>>2]),g=((f<<3)+d|0)>>2,j=(L[M>>2]=L[g],L[M+4>>2]=L[g+1],La[M>>3]),0>j&-1E-5>3]=0,L[g]= -L[M>>2],L[g+1]=L[M+4>>2]):0<=j||V(5244280,92,5246604,5245080),j=f+1|0,(j|0)==(c|0));)f=j} -function Gc(b,c,d,e){var f=b,b=c,h,j,g,i,l,m,k,n,c=I;I=I+12|0;h=R(b<<4);b:do if(0<(b|0)){bc(e,b<<2);for(g=j=0;;)if(i=L[f+(g<<2)>>2],0==(i|0)?l=j:(L[h+(j<<4)>>2]=i,L[h+(j<<4)+8>>2]=g,l=j+1|0),i=g+1|0,(i|0)==(b|0)){m=l;break b}else j=l,g=i}else m=0;while(0);if((1<>2]<<2)>>2]=1,Z(h);else{b=m;if(0!=b){l=[];for(f=0;f>2;L[b]=l;f=R(l<<4);l=(c|0)>>2;L[l]=f;L[c+4>>2]=f;b:do if(0<(L[b]|0))for(f=0;;)if(J[(f<<4)+L[l]+12|0]=0,g=f+1|0,(g|0)<(L[b]|0))f=g;else break b;while(0);f=b=R(d<<3);k=h;j=f;g=Wc(0,d,c);i=Wc(0,d,c);Xc(L[k>>2],1,0,g);Xc(L[k+16>>2],2,0,i);if(0<(d|0))for(k=0;!(L[j+(k<<3)>>2]=g,L[j+(k<<3)+4>>2]=i,k=k+1|0,(k|0)==(d|0)););g=m<<1;b:do if(0<(g-4|0)){j=g-5|0;i=d-1|0;k=(m<<1)-4|0;for(n=0;;)if(bd(f,d,h,m,c,i,(n|0)==(j|0)&1),n=n+1|0,(n|0)==(k|0))break b}while(0); -d=L[f+(d-1<<3)+4>>2];if(0!=(d|0))for(m=d;;){d=m+8|0;b:do if(0<(L[d>>2]|0))for(f=0;;)if(j=(L[h+(f<<4)+8>>2]<<2)+e|0,L[j>>2]=L[j>>2]+1|0,j=f+1|0,(j|0)<(L[d>>2]|0))f=j;else break b;while(0);d=L[m+4>>2];if(0==(d|0))break;else m=d}Z(b);Z(h);Z(L[l])}e=0}I=c;0!=(e|0)&&V(5244280,100,5246656,5244760)}function Kc(b){return 5>(b|0)?0:b=(dc(b-1|0)^31)-1|0}function Jc(b){var c;c=b-1|0;if(5>(b|0))return c;b=dc(c)^31;return c>>>((b-1|0)>>>0)&1|b<<1} -function od(b,c,d,e){var f,h,j,g;f=I;I=I+32|0;h=f+20;j=f+24;g=f+28;J[g]=0;L[j>>2]=0;L[h>>2]=0;var i,l;l=I;I=I+20|0;i=l>>2;L[i]=0;L[i+1]=15;L[i+2]=1;L[i+3]=0;L[i+4]=15;L[l+4>>2]=e;i=f>>2;e=l>>2;L[i]=L[e];L[i+1]=L[e+1];L[i+2]=L[e+2];L[i+3]=L[e+3];L[i+4]=L[e+4];I=l;var m,k;if(0!=(d|0)){l=!0;for(m=0;;){k=(m+2E7|0)>>>0>=d>>>0;e=(k?d-m|0:2E7)+m|0;i=f;k=k&l&1;var n=c,q=e,v=g,u=h,s=j;if(0==(L[i+8>>2]|0))Lc(i,k,n,m,q,v,u,s);else{if(0==(L[i+12>>2]|0)){var r=a,p=a,y=a,w=a,t=a,x=a,z=a,t=a,r=I;I=I+8|0;p=r;y=p>> -2;w=r+4;L[y]=0;L[w>>2]=0;var t=i,x=n,z=q,A=L[i+16>>2],B=w,C=a,D=a,H=a,N=a,O=a,X=a,$=a,Y=a,S=a,U=a,ea=a,T=a,T=a,C=B>>2,B=I;I=I+36|0;D=B;H=D>>2;N=B+16;O=N>>2;X=B+20;$=X>>2;Y=B+24;L[O]=0;L[$]=0;Mc(Y);L[H]=t;L[H+2]=m;L[H+3]=z;L[H+1]=0;L[C]=0;L[p>>2]=0;gd(D,x,m,z,Y);z=Y|0;x=Y+4|0;D=(Y+8|0)>>2;Bc(t,L[z>>2],L[x>>2],L[D],A,N,X);a:do if(0!=(L[$]|0)&&0!=(L[D]|0)){X=L[x>>2];N=L[O];A=L[$];t=L[D];H=L[z>>2];S=0;for(U=m;;){ea=0==K[X+(S<<1)>>1]<<16>>16?1:Ia[H+(S<<1)>>1];T=L[C];if((L[N+(T<<2)>>2]|0)==(S|0)&&(0==(T- -1&T|0)&&(T=0==(T|0)?R(4):Cc(L[p>>2],T<<3),L[p>>2]=T),L[L[p>>2]+(L[C]<<2)>>2]=U,T=L[C]+1|0,L[C]=T,(T|0)==(A|0)))break a;T=S+1|0;if(T>>>0>>0)S=T,U=ea+U|0;else break a}}while(0);(L[C]|0)!=(L[$]|0)&&V(5245952,328,5246708,5244720);Z(L[O]);Pc(Y);I=B;p=L[w>>2];w=0!=(k|0);k=L[y];for(t=0;!(x=0==(t|0)?m:L[k+(t-1<<2)>>2],z=(t|0)==(p|0)?q:L[k+(t<<2)>>2],Lc(i,(t|0)==(p|0)&w&1,n,x,z,v,u,s),t=t+1|0,t>>>0>p>>>0););Z(L[y])}else{C=B=D=p=D=p=A=z=x=t=w=y=C=r=B=a;B=0;r=I;I=I+36|0;C=r>>2;y=r+16;w=y>>2;t=r+28;x=r+32; -z=x>>2;L[t>>2]=0;L[z]=0;p=G;D=E;211==B&&(V(5245480,612,5246868,5245732),p=a,D=A);Mc(y);L[C]=i;L[C+2]=m;L[C+3]=q;C=R(12);A=(r+4|0)>>2;L[A]=C;zc(q-m|0,C);D?Nc(r,n,m,q,y):(p||V(5245480,627,5246868,5245360),Oc(r,n,m,q,y));p||Bc(i,L[w],L[w+1],L[w+2],L[i+16>>2],t,x);x=L[z];p=L[w+2];q=0!=(k|0);k=L[w];m=L[w+1];w=L[z];z=L[t>>2];for(t=0;!(B=0==(t|0)?0:L[z+(t-1<<2)>>2],C=(t|0)==(x|0)?p:L[z+(t<<2)>>2],Qc(i,2,(t|0)==(x|0)&q&1,k,m,B,C,0,v,u,s),n=t+1|0,n>>>0>w>>>0);)t=n;Ac(L[A]);Z(L[A]);Pc(y)}I=r}if(e>>>0>>0)m= -e;else break}}L[b>>2]=L[h>>2];L[b+4>>2]=L[j>>2];I=f} -function R(b){var c,d,e,f,h,j,g,i,l,m;do if(245>b>>>0){c=11>b>>>0?16:b+11&-8;d=c>>>3;e=L[1311502];f=e>>>(d>>>0);if(0!=(f&3|0))return h=(f&1^1)+d|0,c=h<<1,b=(c<<2)+5246048|0,j=(c+2<<2)+5246048|0,c=L[j>>2],g=c+8|0,i=L[g>>2],(b|0)==(i|0)?L[1311502]=e&(1<>>0>>0&&W(),l=i+12|0,(L[l>>2]|0)==(c|0)?(L[l>>2]=b,L[j>>2]=i):W()),i=h<<3,L[c+4>>2]=i|3,j=c+(i|4)|0,L[j>>2]|=1,h=g;if(c>>>0<=L[1311504]>>>0)e=c;else{if(0==(f|0)){if(0==(L[1311503]|0)){e=c;break}h=c;var k=d=f=m=l=i=g=j=a,n=a,q=a, -v=a,u=a,s=j=j=n=v=u=e=b=a;j=L[1311503];g=(j&-j)-1|0;j=g>>>12&16;i=g>>>(j>>>0);g=i>>>5&8;l=i>>>(g>>>0);i=l>>>2&4;m=l>>>(i>>>0);l=m>>>1&2;f=m>>>(l>>>0);m=f>>>1&1;f=m=d=L[((g|j|i|l|m)+(f>>>(m>>>0))<<2)+5246312>>2];l=f>>2;for(i=(L[d+4>>2]&-8)-h|0;;){d=L[m+16>>2];if(0==(d|0))if(j=L[m+20>>2],0==(j|0))break;else k=j;else k=d;d=(L[k+4>>2]&-8)-h|0;j=d>>>0>>0;m=k;f=j?k:f;l=f>>2;i=j?d:i}k=f;m=L[1311506];k>>>0>>0&&W();j=d=k+h|0;k>>>0>=d>>>0&&W();d=L[l+6];g=L[l+3];b:do if((g|0)==(f|0)){n=f+20|0;q=L[n>>2]; -do if(0==(q|0)){if(v=f+16|0,u=L[v>>2],0==(u|0)){b=0;e=b>>2;break b}}else u=q,v=n;while(0);for(;;){n=u+20|0;if(0==(L[n>>2]|0))if(q=u+16|0,0==(L[q>>2]|0))break;else n=q;u=L[n>>2];v=n}v>>>0>>0?W():(L[v>>2]=0,b=u,e=b>>2)}else n=L[l+2],n>>>0>>0&&W(),q=n+12|0,(L[q>>2]|0)!=(f|0)&&W(),v=g+8|0,(L[v>>2]|0)==(f|0)?(L[q>>2]=g,L[v>>2]=n,b=g,e=b>>2):W();while(0);b:do if(0!=(d|0)){g=f+28|0;m=(L[g>>2]<<2)+5246312|0;do if((f|0)==(L[m>>2]|0)){if(L[m>>2]=b,0==(b|0)){L[1311503]&=1<>2]^-1;break b}}else if(d>>> -0>>0&&W(),u=d+16|0,(L[u>>2]|0)==(f|0)?L[u>>2]=b:L[d+20>>2]=b,0==(b|0))break b;while(0);b>>>0>>0&&W();L[e+6]=d;g=L[l+4];0!=(g|0)&&(g>>>0>>0?W():(L[e+4]=g,L[g+24>>2]=b));g=L[l+5];0!=(g|0)&&(g>>>0>>0?W():(L[e+5]=g,L[g+24>>2]=b))}while(0);16>i>>>0?(b=i+h|0,L[l+1]=b|3,e=b+(k+4)|0,L[e>>2]|=1):(L[l+1]=h|3,L[h+(k+4)>>2]=i|1,L[k+i+h>>2]=i,h=L[1311504],0!=(h|0)&&(k=L[1311507],l=h>>>3,h=l<<1,e=(h<<2)+5246048|0,b=L[1311502],d=1<>2],l>>>0>=L[1311506]>>>0?s=l:W()),L[(h+2<<2)+5246048>>2]=k,L[s+12>>2]=k,L[k+8>>2]=s,L[k+12>>2]=e),L[1311504]=i,L[1311507]=j);j=f+8|0;if(0==(j|0)){e=c;break}else h=j;return h}j=2<>>12&16;b=j>>>(i>>>0);j=b>>>5&8;l=b>>>(j>>>0);b=l>>>2&4;g=l>>>(b>>>0);l=g>>>1&2;m=g>>>(l>>>0);g=m>>>1&1;f=(j|i|b|l|g)+(m>>>(g>>>0))|0;g=f<<1;m=(g<<2)+5246048|0;l=(g+2<<2)+5246048|0;g=L[l>>2];b=g+8|0;i=L[b>>2];(m|0)==(i|0)?L[1311502]=e&(1<>>0>>0&& -W(),j=i+12|0,(L[j>>2]|0)==(g|0)?(L[j>>2]=m,L[l>>2]=i):W());i=f<<3;l=i-c|0;L[g+4>>2]=c|3;m=g;e=m+c|0;L[m+(c|4)>>2]=l|1;L[m+i>>2]=l;i=L[1311504];0!=(i|0)&&(m=L[1311507],d=i>>>3,i=d<<1,f=(i<<2)+5246048|0,g=L[1311502],c=1<>2],d>>>0>=L[1311506]>>>0?h=d:W()),L[(i+2<<2)+5246048>>2]=m,L[h+12>>2]=m,L[m+8>>2]=h,L[m+12>>2]=f);L[1311504]=l;L[1311507]=e;return h=b}}else if(4294967231>>0)e=-1;else if(c=b+11&-8,0==(L[1311503]|0))e=c;else{e=c;var r=s=k= -d=a,p=n=a,y=a,w=a,t=a,x=a,z=w=i=g=j=a,A=a,B=a,C=r=r=v=r=w=y=u=q=d=f=m=l=p=z=y=x=a;d=e>>2;k=0;s=-e|0;r=e>>>8;0==(r|0)?n=0:16777215>>0?n=31:(p=(r+1048320|0)>>>16&8,y=r<>>16&4,t=y<>>16&2,x=14-(w|p|y)+(t<>>15)|0,n=e>>>((x+7|0)>>>0)&1|x<<1);r=L[(n<<2)+5246312>>2];b:do if(0==(r|0))j=0,g=s,i=0;else{w=31==(n|0)?0:25-(n>>>1)|0;x=0;y=s;t=r;p=t>>2;w=e<>>0>>0)if((A|0)==(e|0)){j=t;g=B;i=t;break b}else x=t,y=B;B=L[p+5];A=L[((w>>> -31<<2)+16>>2)+p];z=0==(B|0)|(B|0)==(A|0)?z:B;if(0==(A|0)){j=x;g=y;i=z;break b}else t=A,p=t>>2,w<<=1}}while(0);0==(i|0)&0==(j|0)?(y=2<>>12&16,w=y>>>(x>>>0),y=w>>>5&8,r=w>>>(y>>>0),w=r>>>2&4,s=r>>>(w>>>0),r=s>>>1&2,z=s>>>(r>>>0),s=z>>>1&1,p=L[((y|x|w|r|s)+(z>>>(s>>>0))<<2)+5246312>>2])):p=i;b:do if(0==(p|0))l=g,m=j,f=m>>2;else{i=p;n=i>>2;s=g;for(z=j;;)if(r=(L[n+1]&-8)-e|0,x=(w=r>>>0>>0)?r:s,r=w?i:z,w=L[n+4],0!=(w|0))i=w,n=i>>2,s=x,z=r;else if(w= -L[n+5],0==(w|0)){l=x;m=r;f=m>>2;break b}else i=w,n=i>>2,s=x,z=r}while(0);if(0==(m|0))d=0;else if(l>>>0>=(L[1311504]-e|0)>>>0)d=0;else{j=m;g=j>>2;p=L[1311506];j>>>0

    >>0&&W();s=z=j+e|0;j>>>0>=z>>>0&&W();i=L[f+6];n=L[f+3];b:do if((n|0)==(m|0)){r=m+20|0;x=L[r>>2];do if(0==(x|0)){if(w=m+16|0,y=L[w>>2],0==(y|0)){q=0;u=q>>2;break b}}else y=x,w=r;while(0);for(;;){r=y+20|0;if(0==(L[r>>2]|0))if(x=y+16|0,0==(L[x>>2]|0))break;else r=x;y=L[r>>2];w=r}w>>>0>>0?W():(L[w>>2]=0,q=y,u=q>>2)}else r=L[f+ -2],r>>>0

    >>0&&W(),x=r+12|0,(L[x>>2]|0)!=(m|0)&&W(),w=n+8|0,(L[w>>2]|0)==(m|0)?(L[x>>2]=n,L[w>>2]=r,q=n,u=q>>2):W();while(0);b:do if(0!=(i|0)){n=m+28|0;p=(L[n>>2]<<2)+5246312|0;do if((m|0)==(L[p>>2]|0)){if(L[p>>2]=q,0==(q|0)){L[1311503]&=1<>2]^-1;break b}}else if(i>>>0>>0&&W(),y=i+16|0,(L[y>>2]|0)==(m|0)?L[y>>2]=q:L[i+20>>2]=q,0==(q|0))break b;while(0);q>>>0>>0&&W();L[u+6]=i;n=L[f+4];0!=(n|0)&&(n>>>0>>0?W():(L[u+4]=n,L[n+24>>2]=q));n=L[f+5];0!=(n|0)&&(n>>> -0>>0?W():(L[u+5]=n,L[n+24>>2]=q))}while(0);do if(16>l>>>0)q=l+e|0,L[f+1]=q|3,u=q+(j+4)|0,L[u>>2]|=1;else if(L[f+1]=e|3,L[d+(g+1)]=l|1,L[(l>>2)+g+d]=l,u=l>>>3,256>l>>>0)q=u<<1,i=(q<<2)+5246048|0,n=L[1311502],p=1<>2],u>>>0>=L[1311506]>>>0?v=u:W()),L[(q+2<<2)+5246048>>2]=s,L[v+12>>2]=s,L[d+(g+2)]=v,L[d+(g+3)]=i;else if(p=z,n=l>>>8,0==(n|0)?r=0:16777215>>0?r=31:(u=(n+1048320|0)>>>16&8,y=n<>>16&4,r=y<>>16&2,r=14-(w|u|y)+(r<>>15)|0,r=l>>>((r+7|0)>>>0)&1|r<<1),n=(r<<2)+5246312|0,L[d+(g+7)]=r,L[d+(g+5)]=0,L[d+(g+4)]=0,i=L[1311503],q=1<>2]=p,L[d+(g+6)]=n,L[d+(g+3)]=p,L[d+(g+2)]=p;else{r=31==(r|0)?0:25-(r>>>1)|0;q=l<>2];(L[i+4>>2]&-8|0)!=(l|0);)if(C=(q>>>31<<2)+i+16|0,n=L[C>>2],0==(n|0)){k=1328;break}else q<<=1,i=n;if(1328==k)if(C>>>0>>0)W();else{L[C>>2]=p;L[d+(g+6)]=i;L[d+(g+3)]=p;L[d+(g+2)]=p;break}q=i+8|0;n=L[q>>2];r=L[1311506];i>>> -0>>0&&W();n>>>0>>0?W():(L[n+12>>2]=p,L[q>>2]=p,L[d+(g+2)]=n,L[d+(g+3)]=i,L[d+(g+6)]=0)}while(0);d=m+8|0}g=d;if(0==(g|0))e=c;else return h=g}while(0);b=L[1311504];e>>>0>b>>>0?(h=L[1311505],e>>>0>>0?(c=h-e|0,L[1311505]=c,g=h=L[1311508],L[1311508]=g+e|0,L[e+(g+4)>>2]=c|1,L[h+4>>2]=e|3,h=h+8|0):h=pd(e)):(h=b-e|0,c=L[1311507],15>>0?(g=c,L[1311507]=g+e|0,L[1311504]=h,L[e+(g+4)>>2]=h|1,L[g+b>>2]=h,L[c+4>>2]=e|3):(L[1311504]=0,L[1311507]=0,L[c+4>>2]=b|3,e=b+(c+4)|0,L[e>>2]|=1),h=c+8|0);return h} -function pd(b){var c,d,e,f,h,j,g,i,l,m,k,n,q,v,u,s,r,p,y,w,t,x;c=0;0==(L[1310720]|0)&&qd();d=b+48|0;e=L[1310722];f=e+(b+47)&-e;if(f>>>0<=b>>>0)return 0;e=L[1311612];if(0!=(e|0)&&(h=L[1311610],j=h+f|0,j>>>0<=h>>>0|j>>>0>e>>>0))return 0;a:do{if(0==(L[1311613]&4|0)){e=L[1311508];0==(e|0)?c=1356:(j=rd(e),0==(j|0)?c=1356:(h=L[1310722],g=b+47-L[1311505]+h&-h,2147483647<=g>>>0?i=0:(h=fc(g),l=(j=(h|0)==(L[j>>2]+L[j+4>>2]|0))?h:-1,m=j?g:0,k=h,n=g,c=1365)));1356==c&&(e=fc(0),-1==(e|0)?i=0:(g=e,h=L[1310721], -j=h-1|0,q=0==(j&g|0)?f:f-g+(j+g&-h)|0,h=L[1311610],g=h+q|0,q>>>0>b>>>0&2147483647>q>>>0?(j=L[1311612],0!=(j|0)&&g>>>0<=h>>>0|g>>>0>j>>>0?i=0:(j=fc(q),l=(g=(j|0)==(e|0))?e:-1,m=g?q:0,k=j,n=q,c=1365)):i=0));b:do if(1365==c){j=-n|0;if(-1!=(l|0)){v=m;u=l;c=1376;break a}do if(-1!=(k|0)&2147483647>n>>>0&n>>>0>>0)if(g=L[1310722],e=b+47-n+g&-g,2147483647<=e>>>0)e=n;else if(-1==(fc(e)|0)){fc(j);i=m;break b}else e=e+n|0;else e=n;while(0);if(-1==(k|0))i=m;else{v=e;u=k;c=1376;break a}}while(0);L[1311613]|= -4;s=i}else s=0;c=1373}while(0);1373==c&&!(2147483647<=f>>>0)&&(i=fc(f),k=fc(0),-1!=(k|0)&-1!=(i|0)&i>>>0>>0&&(e=k-i|0,m=(k=e>>>0>(b+40|0)>>>0)?i:-1,-1!=(m|0)&&(v=k?e:s,u=m,c=1376)));do if(1376==c){s=L[1311610]+v|0;L[1311610]=s;s>>>0>L[1311611]>>>0&&(L[1311611]=s);a:do if(0==(L[1311508]|0)){s=L[1311506];0==(s|0)|u>>>0>>0&&(L[1311506]=u);L[1311614]=u;L[1311615]=v;L[1311617]=0;L[1311511]=L[1310720];L[1311510]=-1;i=f=d=a;for(d=0;!(f=d<<1,i=(f<<2)+5246048|0,L[(f+3<<2)+5246048>>2]=i,L[(f+2<<2)+5246048>> -2]=i,i=d+1|0,32==(i|0));)d=i;sd(u,v-40|0)}else{s=5246456;for(f=s>>2;;){r=L[f];p=s+4|0;y=L[p>>2];w=r+y|0;if((u|0)==(w|0)){c=1384;break}m=L[f+2];if(0==(m|0))break;else s=m,f=s>>2}do if(1384==c&&0==(L[f+3]&8|0)&&(s=L[1311508],s>>>0>=r>>>0&s>>>0>>0)){L[p>>2]=y+v|0;sd(L[1311508],L[1311505]+v|0);break a}while(0);u>>>0>>0&&(L[1311506]=u);f=u+v|0;for(s=5246456;;){t=s|0;x=L[t>>2];if((x|0)==(f|0)){c=1392;break}m=L[s+8>>2];if(0==(m|0))break;else s=m}if(1392==c&&0==(L[s+12>>2]&8|0))return L[t>> -2]=u,f=s+4|0,L[f>>2]=L[f>>2]+v|0,b=td(u,x,b);d=u;f=v;e=h=g=s=q=n=h=j=k=g=m=l=i=a;i=0;l=L[1311508];m=l>>2;g=l;k=rd(g);j=L[k>>2];h=L[k+4>>2];k=j+h|0;n=j+(h-39)|0;q=0==(n&7|0)?0:-n&7;n=j+(h-47)+q|0;q=n>>>0<(l+16|0)>>>0?g:n;n=q+8|0;h=n>>2;sd(d,f-40|0);L[q+4>>2]=27;L[h]=L[1311614];L[h+1]=L[1311615];L[h+2]=L[1311616];L[h+3]=L[1311617];L[1311614]=d;L[1311615]=f;L[1311617]=0;L[1311616]=n;n=q+28|0;L[n>>2]=7;b:do if((q+32|0)>>>0>>0)for(f=n;;)if(d=f+4|0,L[d>>2]=7,(f+8|0)>>>0>>0)f=d;else break b;while(0); -if((q|0)!=(g|0))if(k=q-l|0,q=k+(g+4)|0,L[q>>2]&=-2,L[m+1]=k|1,L[g+k>>2]=k,g=k>>>3,256>k>>>0)q=g<<1,n=(q<<2)+5246048|0,f=L[1311502],d=1<>2],g>>>0>=L[1311506]>>>0?s=g:W()),L[(q+2<<2)+5246048>>2]=l,L[s+12>>2]=l,L[m+2]=s,L[m+3]=n;else if(n=l,s=k>>>8,0==(s|0)?g=0:16777215>>0?g=31:(q=(s+1048320|0)>>>16&8,d=s<>>16&4,g=d<>>16&2,h=14-(f|q|d)+(g<>>15)|0,g=k>>>((h+7|0)>>>0)&1|h<<1),s=(g<<2)+5246312|0,L[m+7]=g, -L[m+5]=0,L[m+4]=0,h=L[1311503],d=1<>2]=n,L[m+6]=s,L[m+3]=l,L[m+2]=l;else{h=31==(g|0)?0:25-(g>>>1)|0;g=k<>2];(L[h+4>>2]&-8|0)!=(k|0);)if(e=(g>>>31<<2)+h+16|0,s=L[e>>2],0==(s|0)){i=2187;break}else g<<=1,h=s;2187==i?(e>>>0>>0&&W(),L[e>>2]=n,L[m+6]=h,L[m+3]=l,L[m+2]=l):(l=h+8|0,e=L[l>>2],i=L[1311506],h>>>0>>0&&W(),e>>>0>>0&&W(),L[e+12>>2]=n,L[l>>2]=n,L[m+2]=e,L[m+3]=h,L[m+6]=0)}}while(0);s=L[1311505];if(!(s>>>0<=b>>>0))return f=s-b|0,L[1311505]= -f,m=s=L[1311508],L[1311508]=m+b|0,L[b+(m+4)>>2]=f|1,L[s+4>>2]=b|3,b=s+8|0}while(0);b=Eb;L[b>>2]=12;return 0} -function Z(b){var c,d,e,f,h,j,g,i,l,m,k,n,q,v,u,s,r,p,y,w,t,x,z,A,B,C,D,H,N,O;c=b>>2;d=0;if(0!=(b|0)){f=e=b-8|0;h=L[1311506];e>>>0>>0&&W();j=L[b-4>>2];g=j&3;1==(g|0)&&W();i=j&-8;l=i>>2;m=b+(i-8)|0;a:do if(0==(j&1|0)){k=L[e>>2];if(0==(g|0))return;n=-8-k|0;q=n>>2;u=v=b+n|0;s=k+i|0;v>>>0>>0&&W();if((u|0)==(L[1311507]|0)){r=(b+(i-4)|0)>>2;if(3!=(L[r]&3|0)){p=u;y=p>>2;w=s;break}L[1311504]=s;L[r]&=-2;L[q+(c+1)]=s|1;L[m>>2]=s;return}r=k>>>3;if(256>k>>>0)k=L[q+(c+2)],p=L[q+(c+3)],t=(r<<3)+5246048|0, -(k|0)!=(t|0)&&(k>>>0>>0&&W(),(L[k+12>>2]|0)!=(u|0)&&W()),(p|0)==(k|0)?L[1311502]&=1<>>0>>0&&W(),(L[p+8>>2]|0)!=(u|0)&&W()),L[k+12>>2]=p,L[p+8>>2]=k),p=u,y=p>>2,w=s;else{t=v;r=L[q+(c+6)];x=L[q+(c+3)];b:do if((x|0)==(t|0)){v=n+(b+20)|0;z=L[v>>2];do if(0==(z|0)){if(A=n+(b+16)|0,k=L[A>>2],0==(k|0)){B=0;C=B>>2;break b}}else k=z,A=v;while(0);for(;;){v=k+20|0;if(0==(L[v>>2]|0))if(z=k+16|0,0==(L[z>>2]|0))break;else v=z;k=L[v>>2];A=v}A>>>0>>0?W():(L[A>>2]= -0,B=k,C=B>>2)}else v=L[q+(c+2)],v>>>0>>0&&W(),z=v+12|0,(L[z>>2]|0)!=(t|0)&&W(),A=x+8|0,(L[A>>2]|0)==(t|0)?(L[z>>2]=x,L[A>>2]=v,B=x,C=B>>2):W();while(0);if(0==(r|0))p=u,y=p>>2,w=s;else{x=n+(b+28)|0;v=(L[x>>2]<<2)+5246312|0;do if((t|0)==(L[v>>2]|0)){if(L[v>>2]=B,0==(B|0)){L[1311503]&=1<>2]^-1;p=u;y=p>>2;w=s;break a}}else if(r>>>0>>0&&W(),k=r+16|0,(L[k>>2]|0)==(t|0)?L[k>>2]=B:L[r+20>>2]=B,0==(B|0)){p=u;y=p>>2;w=s;break a}while(0);B>>>0>>0&&W();L[C+6]=r;t=L[q+(c+4)];0!= -(t|0)&&(t>>>0>>0?W():(L[C+4]=t,L[t+24>>2]=B));t=L[q+(c+5)];0==(t|0)?(p=u,y=p>>2,w=s):t>>>0>>0?W():(L[C+5]=t,L[t+24>>2]=B,p=u,y=p>>2,w=s)}}}else p=f,y=p>>2,w=i;while(0);f=p;B=f>>2;f>>>0>=m>>>0&&W();f=b+(i-4)|0;C=L[f>>2];0==(C&1|0)&&W();do if(0==(C&2|0)){if((m|0)==(L[1311508]|0)){h=L[1311505]+w|0;L[1311505]=h;L[1311508]=p;L[y+1]=h|1;(p|0)==(L[1311507]|0)&&(L[1311507]=0,L[1311504]=0);if(h>>>0<=L[1311509]>>>0)return;a:if(N=H=D=C=d=C=D=a,0==(L[1310720]|0)&&qd(),D=L[1311508],0!= -(D|0)){C=L[1311505];if(40>>0&&(d=L[1310722],C=Math.g(Math.floor(((-41+C+d|0)>>>0)/(d>>>0))-1|0,d),D=rd(D),H=D>>2,0==(L[H+3]&8|0)&&(N=fc(0),(N|0)==(L[H]+L[H+1]|0)&&(H=fc(-(2147483646>>0?-2147483648-d|0:C)|0),C=fc(0),-1!=(H|0)&C>>>0>>0&&(H=N-C|0,(N|0)!=(C|0)))))){d=D+4|0;L[d>>2]=L[d>>2]-H|0;L[1311610]=L[1311610]-H|0;sd(L[1311508],L[1311505]-H|0);break a}L[1311505]>>>0<=L[1311509]>>>0||(L[1311509]=-1)}return}if((m|0)==(L[1311507]|0)){h=L[1311504]+w|0;L[1311504]=h;L[1311507]=p;L[y+1]=h|1;L[(h>> -2)+B]=h;return}h=(C&-8)+w|0;k=C>>>3;a:do if(256>C>>>0)A=L[c+l],v=L[((i|4)>>2)+c],g=(k<<3)+5246048|0,(A|0)!=(g|0)&&(A>>>0>>0&&W(),(L[A+12>>2]|0)!=(m|0)&&W()),(v|0)==(A|0)?L[1311502]&=1<>>0>>0&&W(),(L[v+8>>2]|0)!=(m|0)&&W()),L[A+12>>2]=v,L[v+8>>2]=A);else{g=m;e=L[l+(c+4)];j=L[((i|4)>>2)+c];b:do if((j|0)==(g|0)){t=i+(b+12)|0;r=L[t>>2];do if(0==(r|0))if(x=i+(b+8)|0,v=L[x>>2],0==(v|0)){D=0;H=D>>2;break b}else u=v,s=x;else u=r,s=t;while(0);for(;;){t=u+20| -0;if(0==(L[t>>2]|0)){if(r=u+16|0,0==(L[r>>2]|0))break}else r=t;u=L[r>>2];s=r}s>>>0>>0?W():(L[s>>2]=0,D=u,H=D>>2)}else t=L[c+l],t>>>0>>0&&W(),r=t+12|0,(L[r>>2]|0)!=(g|0)&&W(),x=j+8|0,(L[x>>2]|0)==(g|0)?(L[r>>2]=j,L[x>>2]=t,D=j,H=D>>2):W();while(0);if(0!=(e|0)){j=i+(b+20)|0;A=(L[j>>2]<<2)+5246312|0;do if((g|0)==(L[A>>2]|0)){if(L[A>>2]=D,0==(D|0)){L[1311503]&=1<>2]^-1;break a}}else if(e>>>0>>0&&W(),v=e+16|0,(L[v>>2]|0)==(g|0)?L[v>>2]=D:L[e+20>>2]=D,0==(D|0))break a; -while(0);D>>>0>>0&&W();L[H+6]=e;g=L[l+(c+2)];0!=(g|0)&&(g>>>0>>0?W():(L[H+4]=g,L[g+24>>2]=D));g=L[l+(c+3)];0!=(g|0)&&(g>>>0>>0?W():(L[H+5]=g,L[g+24>>2]=D))}}while(0);L[y+1]=h|1;L[(h>>2)+B]=h;if((p|0)!=(L[1311507]|0))e=h;else{L[1311504]=h;return}}else L[f>>2]=C&-2,L[y+1]=w|1,e=L[(w>>2)+B]=w;while(0);w=e>>>3;if(256>e>>>0)B=w<<1,C=(B<<2)+5246048|0,f=L[1311502],D=1<>2],w>>>0>=L[1311506]>>>0?N=w:W()),L[(B+2<<2)+ -5246048>>2]=p,L[N+12>>2]=p,L[y+2]=N,L[y+3]=C;else{C=p;N=e>>>8;0==(N|0)?b=0:16777215>>0?b=31:(B=(N+1048320|0)>>>16&8,D=N<>>16&4,w=D<>>16&2,H=14-(f|B|D)+(w<>>15)|0,b=e>>>((H+7|0)>>>0)&1|H<<1);N=(b<<2)+5246312|0;L[y+7]=b;L[y+5]=0;L[y+4]=0;H=L[1311503];D=1<>2]=C,L[y+6]=N,L[y+3]=p,L[y+2]=p;else{f=31==(b|0)?0:25-(b>>>1)|0;w=e<>2];(L[B+4>>2]&-8|0)!=(e|0);)if(O=(w>>>31<<2)+B+16|0,f=L[O>>2],0==(f|0)){d=1534;break}else w<<= -1,B=f;if(1534==d)if(O>>>0>>0)W();else{L[O>>2]=C;L[y+6]=B;L[y+3]=p;L[y+2]=p;break}w=B+8|0;h=L[w>>2];f=L[1311506];B>>>0>>0&&W();h>>>0>>0?W():(L[h+12>>2]=C,L[w>>2]=C,L[y+2]=h,L[y+3]=B,L[y+6]=0)}while(0);y=L[1311510]-1|0;L[1311510]=y;if(0==(y|0)){for(d=5246464;!(d=L[d>>2],0==(d|0));)d=d+8|0;L[1311510]=-1}}}} -Module._calloc=function(b,c){var d;0==(b|0)?d=0:(d=Math.g(c,b),d=65535>=(c|b)>>>0?d:(Math.floor((d>>>0)/(b>>>0))|0)==(c|0)?d:-1);c=R(d);if(0==(c|0)||0==(L[c-4>>2]&3|0))return c;bc(c,d);return c};function Cc(b,c){var d,e;if(0==(b|0))return d=R(c);if(4294967231>>0)return d=Eb,L[d>>2]=12,0;d=ud(b-8|0,11>c>>>0?16:c+11&-8);if(0!=(d|0))return d+8|0;d=R(c);if(0==(d|0))return 0;e=L[b-4>>2];e=(e&-8)-(0==(e&3|0)?8:4)|0;ac(d,b,e>>>0>>0?e:c);Z(b);return d}Module._realloc=Cc; -function ud(b,c){var d,e,f,h,j,g,i,l,m,k,n,q,v,u,s,r,p,y,w;d=(b+4|0)>>2;e=L[d];f=e&-8;h=f>>2;j=b>>2;g=b+f|0;i=L[1311506];b>>>0>>0&&W();l=e&3;1!=(l|0)&b>>>0>>0||W();m=(b+(f|4)|0)>>2;k=L[m];0==(k&1|0)&&W();if(0==(l|0))return d=L[b+4>>2]&-8,d=256>c>>>0?0:d>>>0>=(c+4|0)>>>0&&!((d-c|0)>>>0>L[1310722]<<1>>>0)?b:0,d;if(f>>>0>=c>>>0){l=f-c|0;if(15>=l>>>0)return b;L[d]=e&1|c|2;L[(c+4>>2)+j]=l|3;L[m]|=1;vd(b+c|0,l);return b}if((g|0)==(L[1311508]|0)){l=L[1311505]+f|0;if(l>>>0<=c>>>0)return 0;m=l-c|0;L[d]= -e&1|c|2;L[(c+4>>2)+j]=m|1;L[1311508]=b+c|0;L[1311505]=m;return b}if((g|0)==(L[1311507]|0)){m=L[1311504]+f|0;if(m>>>0>>0)return 0;l=m-c|0;15>>0?(L[d]=e&1|c|2,L[(c+4>>2)+j]=l|1,L[(m>>2)+j]=l,n=m+(b+4)|0,L[n>>2]&=-2,q=b+c|0,v=l):(L[d]=e&1|m|2,e=m+(b+4)|0,L[e>>2]|=1,v=q=0);L[1311504]=v;L[1311507]=q;return b}if(0!=(k&2|0))return 0;q=(k&-8)+f|0;if(q>>>0>>0)return 0;v=q-c|0;e=k>>>3;a:do if(256>k>>>0)m=L[h+(j+2)],l=L[h+(j+3)],n=(e<<3)+5246048|0,(m|0)!=(n|0)&&(m>>>0>>0&&W(),(L[m+12>>2]|0)!=(g| -0)&&W()),(l|0)==(m|0)?L[1311502]&=1<>>0>>0&&W(),(L[l+8>>2]|0)!=(g|0)&&W()),L[m+12>>2]=l,L[l+8>>2]=m);else{n=g;u=L[h+(j+6)];s=L[h+(j+3)];b:do if((s|0)==(n|0)){l=f+(b+20)|0;m=L[l>>2];do if(0==(m|0)){if(r=f+(b+16)|0,p=L[r>>2],0==(p|0)){y=0;w=y>>2;break b}}else p=m,r=l;while(0);for(;;){l=p+20|0;if(0==(L[l>>2]|0))if(m=p+16|0,0==(L[m>>2]|0))break;else l=m;p=L[l>>2];r=l}r>>>0>>0?W():(L[r>>2]=0,y=p,w=y>>2)}else l=L[h+(j+2)],l>>>0>>0&&W(),m=l+12|0,(L[m>>2]| -0)!=(n|0)&&W(),r=s+8|0,(L[r>>2]|0)==(n|0)?(L[m>>2]=s,L[r>>2]=l,y=s,w=y>>2):W();while(0);if(0!=(u|0)){s=f+(b+28)|0;m=(L[s>>2]<<2)+5246312|0;do if((n|0)==(L[m>>2]|0)){if(L[m>>2]=y,0==(y|0)){L[1311503]&=1<>2]^-1;break a}}else if(u>>>0>>0&&W(),l=u+16|0,(L[l>>2]|0)==(n|0)?L[l>>2]=y:L[u+20>>2]=y,0==(y|0))break a;while(0);y>>>0>>0&&W();L[w+6]=u;n=L[h+(j+4)];0!=(n|0)&&(n>>>0>>0?W():(L[w+4]=n,L[n+24>>2]=y));n=L[h+(j+5)];0!=(n|0)&&(n>>>0>>0?W():(L[w+5]=n, -L[n+24>>2]=y))}}while(0);16>v>>>0?(L[d]=q|L[d]&1|2,y=b+(q|4)|0,L[y>>2]|=1):(L[d]=L[d]&1|c|2,L[(c+4>>2)+j]=v|3,j=b+(q|4)|0,L[j>>2]|=1,vd(b+c|0,v));return b}function qd(){var b;0==(L[1310720]|0)&&(b=ec(),0!=(b-1&b|0)&&W(),L[1310722]=b,L[1310721]=b,L[1310723]=-1,L[1310724]=2097152,L[1310725]=0,L[1311613]=0,b=Math.floor(Date.now()/1E3)&-16^1431655768,L[1310720]=b)} -function rd(b){var c,d,e,f,h;c=0;d=5246456;for(e=d>>2;;){f=L[e];if(f>>>0<=b>>>0&&(f+L[e+1]|0)>>>0>b>>>0){h=d;c=1902;break}f=L[e+2];if(0==(f|0)){h=0;c=1903;break}else d=f,e=d>>2}if(1903==c||1902==c)return h} -function vd(b,c){var d,e,f,h,j,g,i,l,m,k,n,q,v,u,s,r,p,y,w,t,x,z,A,B,C,D,H;d=c>>2;e=0;f=b;h=f>>2;j=f+c|0;g=L[b+4>>2];a:do if(0==(g&1|0)){i=L[b>>2];if(0==(g&3|0))return;m=l=f+-i|0;k=i+c|0;n=L[1311506];l>>>0>>0&&W();if((m|0)==(L[1311507]|0)){q=(c+(f+4)|0)>>2;if(3!=(L[q]&3|0)){v=m;u=v>>2;s=k;break}L[1311504]=k;L[q]&=-2;L[(4-i>>2)+h]=k|1;L[j>>2]=k;return}q=i>>>3;if(256>i>>>0)r=L[(8-i>>2)+h],p=L[(12-i>>2)+h],y=(q<<3)+5246048|0,(r|0)!=(y|0)&&(r>>>0>>0&&W(),(L[r+12>>2]|0)!=(m|0)&&W()),(p|0)==(r|0)? -L[1311502]&=1<>>0>>0&&W(),(L[p+8>>2]|0)!=(m|0)&&W()),L[r+12>>2]=p,L[p+8>>2]=r),v=m,u=v>>2,s=k;else{y=l;q=L[(24-i>>2)+h];w=L[(12-i>>2)+h];b:do if((w|0)==(y|0)){l=16-i|0;r=l+(f+4)|0;p=L[r>>2];do if(0==(p|0)){if(t=f+l|0,x=L[t>>2],0==(x|0)){z=0;A=z>>2;break b}}else x=p,t=r;while(0);for(;;){r=x+20|0;if(0==(L[r>>2]|0))if(p=x+16|0,0==(L[p>>2]|0))break;else l=p;else l=r;x=L[l>>2];t=l}t>>>0>>0?W():(L[t>>2]=0,z=x,A=z>>2)}else r=L[(8-i>>2)+h],r>>>0>>0&&W(), -p=r+12|0,(L[p>>2]|0)!=(y|0)&&W(),l=w+8|0,(L[l>>2]|0)==(y|0)?(L[p>>2]=w,L[l>>2]=r,z=w,A=z>>2):W();while(0);if(0==(q|0))v=m,u=v>>2,s=k;else{w=f+(28-i)|0;n=(L[w>>2]<<2)+5246312|0;do if((y|0)==(L[n>>2]|0)){if(L[n>>2]=z,0==(z|0)){L[1311503]&=1<>2]^-1;v=m;u=v>>2;s=k;break a}}else if(q>>>0>>0&&W(),l=q+16|0,(L[l>>2]|0)==(y|0)?L[l>>2]=z:L[q+20>>2]=z,0==(z|0)){v=m;u=v>>2;s=k;break a}while(0);z>>>0>>0&&W();L[A+6]=q;y=16-i|0;w=L[(y>>2)+h];0!=(w|0)&&(w>>>0>>0?W():(L[A+ -4]=w,L[w+24>>2]=z));w=L[(y+4>>2)+h];0==(w|0)?(v=m,u=v>>2,s=k):w>>>0>>0?W():(L[A+5]=w,L[w+24>>2]=z,v=m,u=v>>2,s=k)}}}else v=b,u=v>>2,s=c;while(0);b=L[1311506];j>>>0>>0&&W();z=c+(f+4)|0;A=L[z>>2];do if(0==(A&2|0)){if((j|0)==(L[1311508]|0)){x=L[1311505]+s|0;L[1311505]=x;L[1311508]=v;L[u+1]=x|1;if((v|0)!=(L[1311507]|0))return;L[1311507]=0;L[1311504]=0;return}if((j|0)==(L[1311507]|0)){x=L[1311504]+s|0;L[1311504]=x;L[1311507]=v;L[u+1]=x|1;L[(x>>2)+u]=x;return}x=(A&-8)+s|0;t=A>>>3;a:do if(256> -A>>>0)l=L[d+(h+2)],g=L[d+(h+3)],w=(t<<3)+5246048|0,(l|0)!=(w|0)&&(l>>>0>>0&&W(),(L[l+12>>2]|0)!=(j|0)&&W()),(g|0)==(l|0)?L[1311502]&=1<>>0>>0&&W(),(L[g+8>>2]|0)!=(j|0)&&W()),L[l+12>>2]=g,L[g+8>>2]=l);else{w=j;i=L[d+(h+6)];q=L[d+(h+3)];b:do if((q|0)==(w|0)){n=c+(f+20)|0;l=L[n>>2];do if(0==(l|0))if(r=c+(f+16)|0,p=L[r>>2],0==(p|0)){B=0;C=B>>2;break b}else g=p,m=r;else g=l,m=n;while(0);for(;;){n=g+20|0;if(0==(L[n>>2]|0))if(l=g+16|0,0==(L[l>>2]|0))break;else n=l; -g=L[n>>2];m=n}m>>>0>>0?W():(L[m>>2]=0,B=g,C=B>>2)}else n=L[d+(h+2)],n>>>0>>0&&W(),l=n+12|0,(L[l>>2]|0)!=(w|0)&&W(),r=q+8|0,(L[r>>2]|0)==(w|0)?(L[l>>2]=q,L[r>>2]=n,B=q,C=B>>2):W();while(0);if(0!=(i|0)){q=c+(f+28)|0;l=(L[q>>2]<<2)+5246312|0;do if((w|0)==(L[l>>2]|0)){if(L[l>>2]=B,0==(B|0)){L[1311503]&=1<>2]^-1;break a}}else if(i>>>0>>0&&W(),g=i+16|0,(L[g>>2]|0)==(w|0)?L[g>>2]=B:L[i+20>>2]=B,0==(B|0))break a;while(0);B>>>0>>0&&W();L[C+6]=i;w=L[d+(h+4)];0!=(w| -0)&&(w>>>0>>0?W():(L[C+4]=w,L[w+24>>2]=B));w=L[d+(h+5)];0!=(w|0)&&(w>>>0>>0?W():(L[C+5]=w,L[w+24>>2]=B))}}while(0);L[u+1]=x|1;L[(x>>2)+u]=x;if((v|0)!=(L[1311507]|0))i=x;else{L[1311504]=x;return}}else L[z>>2]=A&-2,L[u+1]=s|1,i=L[(s>>2)+u]=s;while(0);s=i>>>3;if(256>i>>>0)A=s<<1,z=(A<<2)+5246048|0,B=L[1311502],C=1<>2],s>>>0>=L[1311506]>>>0?D=s:W()),L[(A+2<<2)+5246048>>2]=v,L[D+12>>2]=v,L[u+2]=D,L[u+3]=z;else if(z=v,D=i>>> -8,0==(D|0)?d=0:16777215>>0?d=31:(A=(D+1048320|0)>>>16&8,C=D<>>16&4,s=C<>>16&2,h=14-(B|A|C)+(s<>>15)|0,d=i>>>((h+7|0)>>>0)&1|h<<1),D=(d<<2)+5246312|0,L[u+7]=d,L[u+5]=0,L[u+4]=0,h=L[1311503],C=1<>2]=z,L[u+6]=D,L[u+3]=v,L[u+2]=v;else{d=i<<(31==(d|0)?0:25-(d>>>1)|0);for(h=L[D>>2];(L[h+4>>2]&-8|0)!=(i|0);)if(H=(d>>>31<<2)+h+16|0,D=L[H>>2],0==(D|0)){e=2029;break}else d<<=1,h=D;2029==e?(H>>>0>>0&&W(),L[H>>2]=z,L[u+6]= -h,L[u+3]=v,L[u+2]=v):(v=h+8|0,H=L[v>>2],e=L[1311506],h>>>0>>0&&W(),H>>>0>>0&&W(),L[H+12>>2]=z,L[v>>2]=z,L[u+2]=H,L[u+3]=h,L[u+6]=0)}}function sd(b,c){var d,e;d=b+8|0;e=0==(d&7|0)?0:-d&7;d=c-e|0;L[1311508]=b+e|0;L[1311505]=d;L[e+(b+4)>>2]=d|1;L[c+(b+4)>>2]=40;L[1311509]=L[1310724]} -function td(b,c,d){var e,f,h,j,g,i,l,m,k,n,q,v,u,s,r,p,y,w,t,x,z,A,B,C,D,H;e=c>>2;f=b>>2;h=0;j=b+8|0;g=0==(j&7|0)?0:-j&7;j=c+8|0;i=0==(j&7|0)?0:-j&7;l=i>>2;m=j=c+i|0;k=g+d|0;n=k>>2;k=q=b+k|0;v=j-(b+g)-d|0;L[(g+4>>2)+f]=d|3;if((m|0)==(L[1311508]|0))return d=L[1311505]+v|0,L[1311505]=d,L[1311508]=k,L[n+(f+1)]=d|1,b=b+(g|8)|0;if((m|0)==(L[1311507]|0))return d=L[1311504]+v|0,L[1311504]=d,L[1311507]=k,L[n+(f+1)]=d|1,L[(d>>2)+f+n]=d,b=b+(g|8)|0;d=L[l+(e+1)];if(1==(d&3|0)){u=d&-8;s=d>>>3;a:do if(256>d>>> -0)r=L[((i|8)>>2)+e],p=L[l+(e+3)],y=(s<<3)+5246048|0,(r|0)!=(y|0)&&(r>>>0>>0&&W(),(L[r+12>>2]|0)!=(m|0)&&W()),(p|0)==(r|0)?L[1311502]&=1<>>0>>0&&W(),(L[p+8>>2]|0)!=(m|0)&&W()),L[r+12>>2]=p,L[p+8>>2]=r);else{y=j;w=L[((i|24)>>2)+e];t=L[l+(e+3)];b:do if((t|0)==(y|0)){r=i|16;p=r+(c+4)|0;x=L[p>>2];do if(0==(x|0)){if(z=c+r|0,A=L[z>>2],0==(A|0)){B=0;C=B>>2;break b}}else A=x,z=p;while(0);for(;;){p=A+20|0;if(0==(L[p>>2]|0))if(x=A+16|0,0==(L[x>>2]|0))break;else r= -x;else r=p;A=L[r>>2];z=r}z>>>0>>0?W():(L[z>>2]=0,B=A,C=B>>2)}else p=L[((i|8)>>2)+e],p>>>0>>0&&W(),x=p+12|0,(L[x>>2]|0)!=(y|0)&&W(),r=t+8|0,(L[r>>2]|0)==(y|0)?(L[x>>2]=t,L[r>>2]=p,B=t,C=B>>2):W();while(0);if(0!=(w|0)){t=i+(c+28)|0;r=(L[t>>2]<<2)+5246312|0;do if((y|0)==(L[r>>2]|0)){if(L[r>>2]=B,0==(B|0)){L[1311503]&=1<>2]^-1;break a}}else if(w>>>0>>0&&W(),p=w+16|0,(L[p>>2]|0)==(y|0)?L[p>>2]=B:L[w+20>>2]=B,0==(B|0))break a;while(0);B>>>0>>0&&W();L[C+ -6]=w;y=i|16;t=L[(y>>2)+e];0!=(t|0)&&(t>>>0>>0?W():(L[C+4]=t,L[t+24>>2]=B));t=L[(y+4>>2)+e];0!=(t|0)&&(t>>>0>>0?W():(L[C+5]=t,L[t+24>>2]=B))}}while(0);d=c+(u|i)|0;c=u+v|0}else d=m,c=v;v=d+4|0;L[v>>2]&=-2;L[n+(f+1)]=c|1;L[(c>>2)+f+n]=c;v=c>>>3;if(256>c>>>0)return d=v<<1,m=(d<<2)+5246048|0,u=L[1311502],i=1<>2],v>>>0>=L[1311506]>>>0?D=v:W()),L[(d+2<<2)+5246048>>2]=k,L[D+12>>2]=k,L[n+(f+2)]=D,L[n+(f+3)]=m,b=b+(g|8)|0;m=q; -q=c>>>8;0==(q|0)?i=0:16777215>>0?i=31:(D=(q+1048320|0)>>>16&8,k=q<>>16&4,i=k<>>16&2,u=14-(d|D|k)+(i<>>15)|0,i=c>>>((u+7|0)>>>0)&1|u<<1);q=(i<<2)+5246312|0;L[n+(f+7)]=i;L[n+(f+5)]=0;L[n+(f+4)]=0;u=L[1311503];k=1<>2]=m,L[n+(f+6)]=q,L[n+(f+3)]=m,L[n+(f+2)]=m,b=b+(g|8)|0;i=c<<(31==(i|0)?0:25-(i>>>1)|0);for(k=L[q>>2];(L[k+4>>2]&-8|0)!=(c|0);)if(H=(i>>>31<<2)+k+16|0,q=L[H>>2],0==(q|0)){h=2143;break}else i<<=1,k=q;if(2143== -h)return H>>>0>>0&&W(),L[H>>2]=m,L[n+(f+6)]=k,L[n+(f+3)]=m,L[n+(f+2)]=m,b=b+(g|8)|0;H=k+8|0;h=L[H>>2];i=L[1311506];k>>>0>>0&&W();h>>>0>>0&&W();L[h+12>>2]=m;L[H>>2]=m;L[n+(f+2)]=h;L[n+(f+3)]=k;L[n+(f+6)]=0;return b=b+(g|8)|0}function pc(){return 5244744}function qc(){return 5245544}function nc(){}function rc(b){0!=(b|0)&&Z(b)}function mc(b){0!=(b|0)&&Z(b)}function tc(){}var $b=F; -Module.A=function(b){function c(){for(var b=0;3>b;b++)e.push(0)}var d=b.length+1,e=[Q(db("/bin/this.program"),"i8",Za)];c();for(var f=0;f>2],d=L[e+4>>2],f=new Uint8Array(J.subarray(c,c+d))}finally{0!=(e|0)&&(b=e|0,c=L[b>>2],0!=(c|0)&&(Z(c),L[b>>2]=0),Z(e))}return f};ha("Zopfli.RawDeflate",wd);ha("Zopfli.RawDeflate.prototype.compress",wd.prototype.B);}).call(this); \ No newline at end of file diff --git a/src/utils/showdown/README.md b/src/utils/showdown/README.md deleted file mode 100644 index f2f8e67f..00000000 --- a/src/utils/showdown/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# [showdown](https://github.com/showdownjs/showdown) -v1.6.4 diff --git a/src/utils/showdown/showdown-headinganchor.js b/src/utils/showdown/showdown-headinganchor.js deleted file mode 100644 index c5260be8..00000000 --- a/src/utils/showdown/showdown-headinganchor.js +++ /dev/null @@ -1,50 +0,0 @@ -(function (extension) { - if (typeof showdown !== 'undefined') { - // global (browser or nodejs global) - extension(showdown); - } else if (typeof define === 'function' && define.amd) { - // AMD - define(['showdown'], extension); - } else if (typeof exports === 'object') { - // Node, CommonJS-like - module.exports = extension(require('showdown')); - } else { - // showdown was not found so we throw - throw Error('Could not find showdown library'); - } -}(function (showdown) { - // loading extension into shodown - showdown.extension('headinganchor', function () { - var headinganchor = { - type: 'output', - filter: function(source) { - var nameCounter = 0; - var parser = new DOMParser(); - var htmlDoc = parser.parseFromString("

    " + source + "
    ", 'text/html'); - var eles = htmlDoc.querySelectorAll("h1, h2, h3, h4, h5, h6"); - - for (var i = 0; i < eles.length; ++i) { - var ele = eles[i]; - var level = parseInt(ele.tagName.substr(1)); - var escapedText = 'toc_' + nameCounter++; - - toc.push({ - level: level, - anchor: escapedText, - title: ele.innerText - }); - - ele.setAttribute('id', escapedText); - } - - var html = htmlDoc.getElementById('showdown-container').innerHTML; - - delete parser; - - return html; - } - }; - - return [headinganchor]; - }); -})); diff --git a/src/utils/showdown/showdown.min.js b/src/utils/showdown/showdown.min.js deleted file mode 100644 index 5faf821c..00000000 --- a/src/utils/showdown/showdown.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! showdown 23-04-2017 */ - -(function(){function a(a){"use strict";var b={omitExtraWLInCodeBlocks:{defaultValue:!1,describe:"Omit the default extra whiteline added to code blocks",type:"boolean"},noHeaderId:{defaultValue:!1,describe:"Turn on/off generated header id",type:"boolean"},prefixHeaderId:{defaultValue:!1,describe:"Specify a prefix to generated header ids",type:"string"},ghCompatibleHeaderId:{defaultValue:!1,describe:"Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)",type:"boolean"},headerLevelStart:{defaultValue:!1,describe:"The header blocks level start",type:"integer"},parseImgDimensions:{defaultValue:!1,describe:"Turn on/off image dimension parsing",type:"boolean"},simplifiedAutoLink:{defaultValue:!1,describe:"Turn on/off GFM autolink style",type:"boolean"},excludeTrailingPunctuationFromURLs:{defaultValue:!1,describe:"Excludes trailing punctuation from links generated with autoLinking",type:"boolean"},literalMidWordUnderscores:{defaultValue:!1,describe:"Parse midword underscores as literal underscores",type:"boolean"},literalMidWordAsterisks:{defaultValue:!1,describe:"Parse midword asterisks as literal asterisks",type:"boolean"},strikethrough:{defaultValue:!1,describe:"Turn on/off strikethrough support",type:"boolean"},tables:{defaultValue:!1,describe:"Turn on/off tables support",type:"boolean"},tablesHeaderId:{defaultValue:!1,describe:"Add an id to table headers",type:"boolean"},ghCodeBlocks:{defaultValue:!0,describe:"Turn on/off GFM fenced code blocks support",type:"boolean"},tasklists:{defaultValue:!1,describe:"Turn on/off GFM tasklist support",type:"boolean"},smoothLivePreview:{defaultValue:!1,describe:"Prevents weird effects in live previews due to incomplete input",type:"boolean"},smartIndentationFix:{defaultValue:!1,description:"Tries to smartly fix indentation in es6 strings",type:"boolean"},disableForced4SpacesIndentedSublists:{defaultValue:!1,description:"Disables the requirement of indenting nested sublists by 4 spaces",type:"boolean"},simpleLineBreaks:{defaultValue:!1,description:"Parses simple line breaks as
    (GFM Style)",type:"boolean"},requireSpaceBeforeHeadingText:{defaultValue:!1,description:"Makes adding a space between `#` and the header text mandatory (GFM Style)",type:"boolean"},ghMentions:{defaultValue:!1,description:"Enables github @mentions",type:"boolean"},ghMentionsLink:{defaultValue:"https://github.com/{u}",description:"Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",type:"string"},encodeEmails:{defaultValue:!0,description:"Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",type:"boolean"},openLinksInNewWindow:{defaultValue:!1,description:"Open all links in new windows",type:"boolean"}};if(a===!1)return JSON.parse(JSON.stringify(b));var c={};for(var d in b)b.hasOwnProperty(d)&&(c[d]=b[d].defaultValue);return c}function b(){"use strict";var b=a(!0),c={};for(var d in b)b.hasOwnProperty(d)&&(c[d]=!0);return c}function c(a,b){"use strict";var c=b?"Error in "+b+" extension->":"Error in unnamed extension",d={valid:!0,error:""};e.helper.isArray(a)||(a=[a]);for(var f=0;f-1,l=new RegExp(b+"|"+c,"g"+j.replace(/g/g,"")),m=new RegExp(b,j.replace(/g/g,"")),n=[];do for(e=0;g=l.exec(a);)if(m.test(g[0]))e++||(f=l.lastIndex,h=f-g[0].length);else if(e&&!--e){i=g.index+g[0].length;var o={left:{start:h,end:f},match:{start:f,end:g.index},right:{start:g.index,end:i},wholeMatch:{start:h,end:i}};if(n.push(o),!k)return n}while(e&&(l.lastIndex=f));return n};e.helper.matchRecursiveRegExp=function(a,b,c,d){"use strict";for(var e=k(a,b,c,d),f=[],g=0;g0){var l=[];0!==h[0].wholeMatch.start&&l.push(a.slice(0,h[0].wholeMatch.start));for(var m=0;m.9?b[2](a):c>.45?b[1](a):b[0](a)}return a})},"undefined"==typeof console&&(console={warn:function(a){"use strict";alert(a)},log:function(a){"use strict";alert(a)},error:function(a){"use strict";throw a}}),e.helper.regexes={asteriskAndDash:/([*_])/g},e.Converter=function(a){"use strict";function b(){a=a||{};for(var b in h)h.hasOwnProperty(b)&&(m[b]=h[b]);if("object"!=typeof a)throw Error("Converter expects the passed parameter to be an object, but "+typeof a+" was passed instead.");for(var c in a)a.hasOwnProperty(c)&&(m[c]=a[c]);m.extensions&&e.helper.forEach(m.extensions,d)}function d(a,b){if(b=b||null,e.helper.isString(a)){if(a=e.helper.stdExtName(a),b=a,e.extensions[a])return console.warn("DEPRECATION WARNING: "+a+" is an old extension that uses a deprecated loading method.Please inform the developer that the extension should be updated!"),void f(e.extensions[a],a);if(e.helper.isUndefined(g[a]))throw Error('Extension "'+a+'" could not be loaded. It was either not found or is not a valid extension.');a=g[a]}"function"==typeof a&&(a=a()),e.helper.isArray(a)||(a=[a]);var d=c(a,b);if(!d.valid)throw Error(d.error);for(var h=0;h-1))return a;n=""}else n=c.gUrls[m],e.helper.isUndefined(c.gTitles[m])||(o=c.gTitles[m]);n=n.replace(e.helper.regexes.asteriskAndDash,e.helper.escapeCharactersCallback);var p='
    "};return a=a.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)][ ]?(?:\n[ ]*)?\[(.*?)])()()()()/g,d),a=a.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)]\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,d),a=a.replace(/(\[([^\[\]]+)])()()()()()/g,d),b.ghMentions&&(a=a.replace(/(^|\s)(\\)?(@([a-z\d\-]+))(?=[.!?;,[\]()]|\s|$)/gim,function(a,c,d,f,g){if("\\"===d)return c+f;if(!e.helper.isString(b.ghMentionsLink))throw new Error("ghMentionsLink option must be a string");var h=b.ghMentionsLink.replace(/\{u}/g,g);return c+''+f+""})),a=c.converter._dispatch("anchors.after",a,b,c)});var l=/\b(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+)()(?=\s|$)(?!["<>])/gi,m=/\b(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]]?)(?=\s|$)(?!["<>])/gi,n=/<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)>/gi,o=/(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-\/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gim,p=/<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,q=function(a){"use strict";return function(b,c,d,e,f){var g=c,h="",i="";return/^www\./i.test(c)&&(c=c.replace(/^www\./i,"http://www.")),a.excludeTrailingPunctuationFromURLs&&f&&(h=f),a.openLinksInNewWindow&&(i=' target="_blank"'),'"+g+""+h}},r=function(a,b){"use strict";return function(c,d,f){var g="mailto:";return d=d||"",f=e.subParser("unescapeSpecialChars")(f,a,b),a.encodeEmails?(g=e.helper.encodeEmailAddress(g+f),f=e.helper.encodeEmailAddress(f)):g+=f,d+''+f+""}};e.subParser("autoLinks",function(a,b,c){"use strict";return a=c.converter._dispatch("autoLinks.before",a,b,c),a=a.replace(n,q(b)),a=a.replace(p,r(b,c)),a=c.converter._dispatch("autoLinks.after",a,b,c)}),e.subParser("simplifiedAutoLinks",function(a,b,c){"use strict";return b.simplifiedAutoLink?(a=c.converter._dispatch("simplifiedAutoLinks.before",a,b,c),a=b.excludeTrailingPunctuationFromURLs?a.replace(m,q(b)):a.replace(l,q(b)),a=a.replace(o,r(b,c)),a=c.converter._dispatch("simplifiedAutoLinks.after",a,b,c)):a}),e.subParser("blockGamut",function(a,b,c){"use strict";return a=c.converter._dispatch("blockGamut.before",a,b,c),a=e.subParser("blockQuotes")(a,b,c),a=e.subParser("headers")(a,b,c),a=e.subParser("horizontalRule")(a,b,c),a=e.subParser("lists")(a,b,c),a=e.subParser("codeBlocks")(a,b,c),a=e.subParser("tables")(a,b,c),a=e.subParser("hashHTMLBlocks")(a,b,c),a=e.subParser("paragraphs")(a,b,c),a=c.converter._dispatch("blockGamut.after",a,b,c)}),e.subParser("blockQuotes",function(a,b,c){"use strict";return a=c.converter._dispatch("blockQuotes.before",a,b,c),a=a.replace(/((^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+)/gm,function(a,d){var f=d;return f=f.replace(/^[ \t]*>[ \t]?/gm,"¨0"),f=f.replace(/¨0/g,""),f=f.replace(/^[ \t]+$/gm,""),f=e.subParser("githubCodeBlocks")(f,b,c),f=e.subParser("blockGamut")(f,b,c),f=f.replace(/(^|\n)/g,"$1 "),f=f.replace(/(\s*
    [^\r]+?<\/pre>)/gm,function(a,b){var c=b;return c=c.replace(/^  /gm,"¨0"),c=c.replace(/¨0/g,"")}),e.subParser("hashBlock")("
    \n"+f+"\n
    ",b,c)}),a=c.converter._dispatch("blockQuotes.after",a,b,c)}),e.subParser("codeBlocks",function(a,b,c){"use strict";a=c.converter._dispatch("codeBlocks.before",a,b,c),a+="¨0";var d=/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g;return a=a.replace(d,function(a,d,f){var g=d,h=f,i="\n";return g=e.subParser("outdent")(g,b,c),g=e.subParser("encodeCode")(g,b,c),g=e.subParser("detab")(g,b,c),g=g.replace(/^\n+/g,""),g=g.replace(/\n+$/g,""),b.omitExtraWLInCodeBlocks&&(i=""),g="
    "+g+i+"
    ",e.subParser("hashBlock")(g,b,c)+h}),a=a.replace(/¨0/,""),a=c.converter._dispatch("codeBlocks.after",a,b,c)}),e.subParser("codeSpans",function(a,b,c){"use strict";return a=c.converter._dispatch("codeSpans.before",a,b,c),"undefined"==typeof a&&(a=""),a=a.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(a,d,f,g){var h=g;return h=h.replace(/^([ \t]*)/g,""),h=h.replace(/[ \t]*$/g,""),h=e.subParser("encodeCode")(h,b,c),d+""+h+""}),a=c.converter._dispatch("codeSpans.after",a,b,c)}),e.subParser("detab",function(a,b,c){"use strict";return a=c.converter._dispatch("detab.before",a,b,c),a=a.replace(/\t(?=\t)/g," "),a=a.replace(/\t/g,"¨A¨B"),a=a.replace(/¨B(.+?)¨A/g,function(a,b){for(var c=b,d=4-c.length%4,e=0;e/g,">"),a=c.converter._dispatch("encodeAmpsAndAngles.after",a,b,c)}),e.subParser("encodeBackslashEscapes",function(a,b,c){"use strict";return a=c.converter._dispatch("encodeBackslashEscapes.before",a,b,c),a=a.replace(/\\(\\)/g,e.helper.escapeCharactersCallback),a=a.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g,e.helper.escapeCharactersCallback),a=c.converter._dispatch("encodeBackslashEscapes.after",a,b,c)}),e.subParser("encodeCode",function(a,b,c){"use strict";return a=c.converter._dispatch("encodeCode.before",a,b,c),a=a.replace(/&/g,"&").replace(//g,">").replace(/([*_{}\[\]\\=~-])/g,e.helper.escapeCharactersCallback),a=c.converter._dispatch("encodeCode.after",a,b,c)}),e.subParser("escapeSpecialCharsWithinTagAttributes",function(a,b,c){"use strict";a=c.converter._dispatch("escapeSpecialCharsWithinTagAttributes.before",a,b,c);var d=/(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|)/gi;return a=a.replace(d,function(a){return a.replace(/(.)<\/?code>(?=.)/g,"$1`").replace(/([\\`*_~=|])/g,e.helper.escapeCharactersCallback)}),a=c.converter._dispatch("escapeSpecialCharsWithinTagAttributes.after",a,b,c)}),e.subParser("githubCodeBlocks",function(a,b,c){"use strict";return b.ghCodeBlocks?(a=c.converter._dispatch("githubCodeBlocks.before",a,b,c),a+="¨0",a=a.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g,function(a,d,f){var g=b.omitExtraWLInCodeBlocks?"":"\n";return f=e.subParser("encodeCode")(f,b,c),f=e.subParser("detab")(f,b,c),f=f.replace(/^\n+/g,""),f=f.replace(/\n+$/g,""),f="
    "+f+g+"
    ",f=e.subParser("hashBlock")(f,b,c),"\n\n¨G"+(c.ghCodeBlocks.push({text:a,codeblock:f})-1)+"G\n\n"}),a=a.replace(/¨0/,""),c.converter._dispatch("githubCodeBlocks.after",a,b,c)):a}),e.subParser("hashBlock",function(a,b,c){"use strict";return a=c.converter._dispatch("hashBlock.before",a,b,c),a=a.replace(/(^\n+|\n+$)/g,""),a="\n\n¨K"+(c.gHtmlBlocks.push(a)-1)+"K\n\n",a=c.converter._dispatch("hashBlock.after",a,b,c)}),e.subParser("hashCodeTags",function(a,b,c){"use strict";a=c.converter._dispatch("hashCodeTags.before",a,b,c);var d=function(a,d,f,g){var h=f+e.subParser("encodeCode")(d,b,c)+g;return"¨C"+(c.gHtmlSpans.push(h)-1)+"C"};return a=e.helper.replaceRecursiveRegExp(a,d,"]*>","","gim"),a=c.converter._dispatch("hashCodeTags.after",a,b,c)}),e.subParser("hashElement",function(a,b,c){"use strict";return function(a,b){var d=b;return d=d.replace(/\n\n/g,"\n"),d=d.replace(/^\n/,""),d=d.replace(/\n+$/g,""),d="\n\n¨K"+(c.gHtmlBlocks.push(d)-1)+"K\n\n"}}),e.subParser("hashHTMLBlocks",function(a,b,c){"use strict";a=c.converter._dispatch("hashHTMLBlocks.before",a,b,c);for(var d=["pre","div","h1","h2","h3","h4","h5","h6","blockquote","table","dl","ol","ul","script","noscript","form","fieldset","iframe","math","style","section","header","footer","nav","article","aside","address","audio","canvas","figure","hgroup","output","video","p"],f=function(a,b,d,e){var f=a;return d.search(/\bmarkdown\b/)!==-1&&(f=d+c.converter.makeHtml(b)+e),"\n\n¨K"+(c.gHtmlBlocks.push(f)-1)+"K\n\n"},g=0;g]*>","","gim");return a=a.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,e.subParser("hashElement")(a,b,c)),a=e.helper.replaceRecursiveRegExp(a,function(a){return"\n\n¨K"+(c.gHtmlBlocks.push(a)-1)+"K\n\n"},"^ {0,3}","gm"),a=a.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,e.subParser("hashElement")(a,b,c)),a=c.converter._dispatch("hashHTMLBlocks.after",a,b,c)}),e.subParser("hashHTMLSpans",function(a,b,c){"use strict";function d(a){return"¨C"+(c.gHtmlSpans.push(a)-1)+"C"}return a=c.converter._dispatch("hashHTMLSpans.before",a,b,c),a=a.replace(/<[^>]+?\/>/gi,function(a){return d(a)}),a=a.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g,function(a){return d(a)}),a=a.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g,function(a){return d(a)}),a=a.replace(/<[^>]+?>/gi,function(a){return d(a)}),a=c.converter._dispatch("hashHTMLSpans.after",a,b,c)}),e.subParser("unhashHTMLSpans",function(a,b,c){"use strict";a=c.converter._dispatch("unhashHTMLSpans.before",a,b,c);for(var d=0;d]*>\\s*]*>","^ {0,3}\\s*
    ","gim"),a=c.converter._dispatch("hashPreCodeTags.after",a,b,c)}),e.subParser("headers",function(a,b,c){"use strict";function d(a){var d;return d=e.helper.isString(b.prefixHeaderId)?b.prefixHeaderId+a:b.prefixHeaderId===!0?"section "+a:a,d=g?d.replace(/ /g,"-").replace(/&/g,"").replace(/¨T/g,"").replace(/¨D/g,"").replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g,"").toLowerCase():d.replace(/[^\w]/g,"").toLowerCase(),c.hashLinkCounts[d]?d=d+"-"+c.hashLinkCounts[d]++:c.hashLinkCounts[d]=1,d}a=c.converter._dispatch("headers.before",a,b,c);var f=isNaN(parseInt(b.headerLevelStart))?1:parseInt(b.headerLevelStart),g=b.ghCompatibleHeaderId,h=b.smoothLivePreview?/^(.+)[ \t]*\n={2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n=+[ \t]*\n+/gm,i=b.smoothLivePreview?/^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n-+[ \t]*\n+/gm;a=a.replace(h,function(a,g){var h=e.subParser("spanGamut")(g,b,c),i=b.noHeaderId?"":' id="'+d(g)+'"',j=f,k=""+h+"";return e.subParser("hashBlock")(k,b,c)}),a=a.replace(i,function(a,g){var h=e.subParser("spanGamut")(g,b,c),i=b.noHeaderId?"":' id="'+d(g)+'"',j=f+1,k=""+h+"";return e.subParser("hashBlock")(k,b,c)});var j=b.requireSpaceBeforeHeadingText?/^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm:/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;return a=a.replace(j,function(a,g,h){var i=e.subParser("spanGamut")(h,b,c),j=b.noHeaderId?"":' id="'+d(h)+'"',k=f-1+g.length,l=""+i+"";return e.subParser("hashBlock")(l,b,c)}),a=c.converter._dispatch("headers.after",a,b,c)}),e.subParser("horizontalRule",function(a,b,c){"use strict";a=c.converter._dispatch("horizontalRule.before",a,b,c);var d=e.subParser("hashBlock")("
    ",b,c);return a=a.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm,d),a=a.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm,d),a=a.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm,d),a=c.converter._dispatch("horizontalRule.after",a,b,c)}),e.subParser("images",function(a,b,c){"use strict";function d(a,b,d,f,g,h,i,j){var k=c.gUrls,l=c.gTitles,m=c.gDimensions;if(d=d.toLowerCase(),j||(j=""),""===f||null===f){if(""!==d&&null!==d||(d=b.toLowerCase().replace(/ ?\n/g," ")),f="#"+d,e.helper.isUndefined(k[d]))return a;f=k[d],e.helper.isUndefined(l[d])||(j=l[d]),e.helper.isUndefined(m[d])||(g=m[d].width,h=m[d].height)}b=b.replace(/"/g,""").replace(e.helper.regexes.asteriskAndDash,e.helper.escapeCharactersCallback),f=f.replace(e.helper.regexes.asteriskAndDash,e.helper.escapeCharactersCallback);var n=''+b+'?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(['"])(.*?)\6[ \t]*)?\)/g,g=/!\[([^\]]*?)] ?(?:\n *)?\[(.*?)]()()()()()/g,h=/!\[([^\[\]]+)]()()()()()/g;return a=a.replace(g,d),a=a.replace(f,d),a=a.replace(h,d),a=c.converter._dispatch("images.after",a,b,c)}),e.subParser("italicsAndBold",function(a,b,c){"use strict";function d(a,d,f){return b.simplifiedAutoLink&&(a=e.subParser("simplifiedAutoLinks")(a,b,c)),d+a+f}return a=c.converter._dispatch("italicsAndBold.before",a,b,c),b.literalMidWordUnderscores?(a=a.replace(/\b___(\S[\s\S]*)___\b/g,function(a,b){return d(b,"","")}),a=a.replace(/\b__(\S[\s\S]*)__\b/g,function(a,b){return d(b,"","")}),a=a.replace(/\b_(\S[\s\S]*?)_\b/g,function(a,b){return d(b,"","")})):(a=a.replace(/___(\S[\s\S]*?)___/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a}),a=a.replace(/__(\S[\s\S]*?)__/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a}),a=a.replace(/_([^\s_][\s\S]*?)_/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a})),b.literalMidWordAsterisks?(a=a.trim().replace(/(?:^| +)\*{3}(\S[\s\S]*?)\*{3}(?: +|$)/g,function(a,b){return d(b," "," ")}),a=a.trim().replace(/(?:^| +)\*{2}(\S[\s\S]*?)\*{2}(?: +|$)/g,function(a,b){return d(b," "," ")}),a=a.trim().replace(/(?:^| +)\*{1}(\S[\s\S]*?)\*{1}(?: +|$)/g,function(a,b){return d(b," ",""+(" "===a.slice(-1)?" ":""))})):(a=a.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a}),a=a.replace(/\*\*(\S[\s\S]*?)\*\*/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a}),a=a.replace(/\*([^\s*][\s\S]*?)\*/g,function(a,b){return/\S$/.test(b)?d(b,"",""):a})),a=c.converter._dispatch("italicsAndBold.after",a,b,c)}),e.subParser("lists",function(a,b,c){"use strict";function d(a,d){c.gListLevel++,a=a.replace(/\n{2,}$/,"\n"),a+="¨0";var f=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,g=/\n[ \t]*\n(?!¨0)/.test(a);return b.disableForced4SpacesIndentedSublists&&(f=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm),a=a.replace(f,function(a,d,f,h,i,j,k){k=k&&""!==k.trim();var l=e.subParser("outdent")(i,b,c),m="";return j&&b.tasklists&&(m=' class="task-list-item" style="list-style-type: none;"',l=l.replace(/^[ \t]*\[(x|X| )?]/m,function(){var a='-1?(l=e.subParser("githubCodeBlocks")(l,b,c),l=e.subParser("blockGamut")(l,b,c)):(l=e.subParser("lists")(l,b,c),l=l.replace(/\n$/,""),l=e.subParser("hashHTMLBlocks")(l,b,c),l=l.replace(/\n\n+/g,"\n\n"),l=l.replace(/\n\n/g,"¨B"),l=g?e.subParser("paragraphs")(l,b,c):e.subParser("spanGamut")(l,b,c),l=l.replace(/¨B/g,"\n\n")),l=l.replace("¨A",""),l=""+l+"\n"}),a=a.replace(/¨0/g,""),c.gListLevel--,d&&(a=a.replace(/\s+$/,"")),a}function f(a,c,e){var f=b.disableForced4SpacesIndentedSublists?/^ ?\d+\.[ \t]/gm:/^ {0,3}\d+\.[ \t]/gm,g=b.disableForced4SpacesIndentedSublists?/^ ?[*+-][ \t]/gm:/^ {0,3}[*+-][ \t]/gm,h="ul"===c?f:g,i="";return a.search(h)!==-1?!function a(b){var j=b.search(h);j!==-1?(i+="\n<"+c+">\n"+d(b.slice(0,j),!!e)+"\n",c="ul"===c?"ol":"ul",h="ul"===c?f:g,a(b.slice(j))):i+="\n<"+c+">\n"+d(b,!!e)+"\n"}(a):i="\n<"+c+">\n"+d(a,!!e)+"\n",i}return a=c.converter._dispatch("lists.before",a,b,c),a+="¨0",a=c.gListLevel?a.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(a,b,c){var d=c.search(/[*+-]/g)>-1?"ul":"ol";return f(b,d,!0)}):a.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(a,b,c,d){var e=d.search(/[*+-]/g)>-1?"ul":"ol";return f(c,e,!1)}),a=a.replace(/¨0/,""),a=c.converter._dispatch("lists.after",a,b,c)}),e.subParser("outdent",function(a,b,c){"use strict";return a=c.converter._dispatch("outdent.before",a,b,c),a=a.replace(/^(\t|[ ]{1,4})/gm,"¨0"),a=a.replace(/¨0/g,""),a=c.converter._dispatch("outdent.after",a,b,c)}),e.subParser("paragraphs",function(a,b,c){"use strict";a=c.converter._dispatch("paragraphs.before",a,b,c),a=a.replace(/^\n+/g,""),a=a.replace(/\n+$/g,"");for(var d=a.split(/\n{2,}/g),f=[],g=d.length,h=0;h=0?f.push(i):i.search(/\S/)>=0&&(i=e.subParser("spanGamut")(i,b,c),i=i.replace(/^([ \t]*)/g,"

    "),i+="

    ",f.push(i))}for(g=f.length,h=0;h]*>\s*]*>/.test(k)&&(l=!0)}f[h]=k}return a=f.join("\n"),a=a.replace(/^\n+/g,""),a=a.replace(/\n+$/g,""),c.converter._dispatch("paragraphs.after",a,b,c)}),e.subParser("runExtension",function(a,b,c,d){"use strict";if(a.filter)b=a.filter(b,d.converter,c);else if(a.regex){var e=a.regex;e instanceof RegExp||(e=new RegExp(e,"g")),b=b.replace(e,a.replace)}return b}),e.subParser("spanGamut",function(a,b,c){"use strict";return a=c.converter._dispatch("spanGamut.before",a,b,c),a=e.subParser("codeSpans")(a,b,c),a=e.subParser("escapeSpecialCharsWithinTagAttributes")(a,b,c),a=e.subParser("encodeBackslashEscapes")(a,b,c),a=e.subParser("images")(a,b,c),a=e.subParser("anchors")(a,b,c),a=e.subParser("autoLinks")(a,b,c),a=e.subParser("italicsAndBold")(a,b,c),a=e.subParser("strikethrough")(a,b,c),a=e.subParser("simplifiedAutoLinks")(a,b,c),a=e.subParser("hashHTMLSpans")(a,b,c),a=e.subParser("encodeAmpsAndAngles")(a,b,c),a=b.simpleLineBreaks?a.replace(/\n/g,"
    \n"):a.replace(/ +\n/g,"
    \n"),a=c.converter._dispatch("spanGamut.after",a,b,c)}),e.subParser("strikethrough",function(a,b,c){"use strict";function d(a){return b.simplifiedAutoLink&&(a=e.subParser("simplifiedAutoLinks")(a,b,c)),""+a+""}return b.strikethrough&&(a=c.converter._dispatch("strikethrough.before",a,b,c),a=a.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g,function(a,b){return d(b)}),a=c.converter._dispatch("strikethrough.after",a,b,c)),a}),e.subParser("stripLinkDefinitions",function(a,b,c){"use strict";var d=/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm;return a+="¨0",a=a.replace(d,function(a,d,f,g,h,i,j){return d=d.toLowerCase(),c.gUrls[d]=e.subParser("encodeAmpsAndAngles")(f,b,c),i?i+j:(j&&(c.gTitles[d]=j.replace(/"|'/g,""")),b.parseImgDimensions&&g&&h&&(c.gDimensions[d]={width:g,height:h}),"")}),a=a.replace(/¨0/,"")}),e.subParser("tables",function(a,b,c){"use strict";function d(a){return/^:[ \t]*--*$/.test(a)?' style="text-align:left;"':/^--*[ \t]*:[ \t]*$/.test(a)?' style="text-align:right;"':/^:[ \t]*--*[ \t]*:$/.test(a)?' style="text-align:center;"':""}function f(a,d){var f="";return a=a.trim(),b.tableHeaderId&&(f=' id="'+a.replace(/ /g,"_").toLowerCase()+'"'),a=e.subParser("spanGamut")(a,b,c),""+a+"\n"}function g(a,d){var f=e.subParser("spanGamut")(a,b,c);return""+f+"\n"}function h(a,b){for(var c="\n\n\n",d=a.length,e=0;e\n\n\n",e=0;e\n";for(var f=0;f\n"}return c+="\n
    \n"}if(!b.tables)return a;var i=/^ {0,3}\|?.+\|.+\n[ \t]{0,3}\|?[ \t]*:?[ \t]*(?:-|=){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:-|=){2,}[\s\S]+?(?:\n\n|¨0)/gm;return a=c.converter._dispatch("tables.before",a,b,c),a=a.replace(/\\(\|)/g,e.helper.escapeCharactersCallback),a=a.replace(i,function(a){var b,c=a.split("\n");for(b=0;b', node.childNodes[i]); - - var border = '---'; - var align = ( - node.childNodes[i].getAttribute('align') || '' - ).toLowerCase(); - - if (align) border = alignMap[align] || border; - - borderCells += cell(border, node.childNodes[i]); - } - - return '\n' + fakeHead + '\n' + borderCells + '\n' + content; - } - - return '\n' + content + (borderCells ? '\n' + borderCells : '') - } -}; - -rules.table = { - // If configs.autoHead is false, only convert tables with a heading row. - // Tables with no heading row are kept using `keep` (see below). - filter: function (node) { - return node.nodeName === 'TABLE' - && (configs.autoHead || isHeadingRow(node.rows[0])) - }, - - replacement: function (content) { - // Ensure there are no blank lines - content = content.replace('\n\n', '\n'); - return '\n\n' + content + '\n\n' - } -}; - -rules.tableSection = { - filter: ['thead', 'tbody', 'tfoot'], - replacement: function (content) { - return content - } -}; - -function isFirstRow (tr) { - var parentNode = tr.parentNode; - return parentNode.firstChild === tr - && (parentNode.nodeName === 'TABLE' || isFirstTbody(parentNode)); -} - -// A tr is a heading row if: -// - the parent is a THEAD -// - or if its the first child of the TABLE or the first TBODY (possibly -// following a blank THEAD) -// - and every cell is a TH -function isHeadingRow (tr) { - var parentNode = tr.parentNode; - return ( - parentNode.nodeName === 'THEAD' || - ( - parentNode.firstChild === tr && - (parentNode.nodeName === 'TABLE' || isFirstTbody(parentNode)) && - every.call(tr.childNodes, function (n) { return n.nodeName === 'TH' }) - ) - ) -} - -function isFirstTbody (element) { - var previousSibling = element.previousSibling; - return ( - element.nodeName === 'TBODY' && ( - !previousSibling || - ( - previousSibling.nodeName === 'THEAD' && - /^\s*$/i.test(previousSibling.textContent) - ) || - // For parsting table from Microsoft Excel. - previousSibling.nodeName == 'COLGROUP' - ) - ) -} - -function cell (content, node) { - var index = indexOf.call(node.parentNode.childNodes, node); - var prefix = ' '; - if (index === 0) prefix = '| '; - return prefix + content + ' |' -} - -function tables (turndownService) { - if (!configs.autoHead) { - turndownService.keep(function (node) { - return node.nodeName === 'TABLE' && !isHeadingRow(node.rows[0]) - }); - } - - for (var key in rules) turndownService.addRule(key, rules[key]); -} - -function taskListItems (turndownService) { - turndownService.addRule('taskListItems', { - filter: function (node) { - return node.type === 'checkbox' && node.parentNode.nodeName === 'LI' - }, - replacement: function (content, node) { - return (node.checked ? '[x]' : '[ ]') + ' ' - } - }); -} - -function gfm (turndownService) { - turndownService.use([ - highlightedCodeBlock, - strikethrough, - tables, - taskListItems - ]); -} - -exports.gfm = gfm; -exports.highlightedCodeBlock = highlightedCodeBlock; -exports.strikethrough = strikethrough; -exports.tables = tables; -exports.taskListItems = taskListItems; -exports.options = configs; - -return exports; - -}({})); diff --git a/src/utils/turndown/turndown.js b/src/utils/turndown/turndown.js deleted file mode 100644 index 9d8c9753..00000000 --- a/src/utils/turndown/turndown.js +++ /dev/null @@ -1,932 +0,0 @@ -var TurndownService = (function () { -'use strict'; - -function extend (destination) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (source.hasOwnProperty(key)) destination[key] = source[key]; - } - } - return destination -} - -function repeat (character, count) { - return Array(count + 1).join(character) -} - -var blockElements = [ - 'address', 'article', 'aside', 'audio', 'blockquote', 'body', 'canvas', - 'center', 'dd', 'dir', 'div', 'dl', 'dt', 'fieldset', 'figcaption', - 'figure', 'footer', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', - 'header', 'hgroup', 'hr', 'html', 'isindex', 'li', 'main', 'menu', 'nav', - 'noframes', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table', - 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'ul' -]; - -function isBlock (node) { - return blockElements.indexOf(node.nodeName.toLowerCase()) !== -1 -} - -var voidElements = [ - 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', - 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr' -]; - -function isVoid (node) { - return voidElements.indexOf(node.nodeName.toLowerCase()) !== -1 -} - -var voidSelector = voidElements.join(); -function hasVoid (node) { - return node.querySelector && node.querySelector(voidSelector) -} - -var rules = {}; - -rules.paragraph = { - filter: 'p', - - replacement: function (content) { - return '\n\n' + content + '\n\n' - } -}; - -rules.lineBreak = { - filter: 'br', - - replacement: function (content, node, options) { - return options.br + '\n' - } -}; - -rules.heading = { - filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'], - - replacement: function (content, node, options) { - var hLevel = Number(node.nodeName.charAt(1)); - - if (options.headingStyle === 'setext' && hLevel < 3) { - var underline = repeat((hLevel === 1 ? '=' : '-'), content.length); - return ( - '\n\n' + content + '\n' + underline + '\n\n' - ) - } else { - return '\n\n' + repeat('#', hLevel) + ' ' + content + '\n\n' - } - } -}; - -rules.blockquote = { - filter: 'blockquote', - - replacement: function (content) { - content = content.replace(/^\n+|\n+$/g, ''); - content = content.replace(/^/gm, '> '); - return '\n\n' + content + '\n\n' - } -}; - -rules.list = { - filter: ['ul', 'ol'], - - replacement: function (content, node) { - var parent = node.parentNode; - if (parent.nodeName === 'LI' && parent.lastElementChild === node) { - return '\n' + content - } else { - return '\n\n' + content + '\n\n' - } - } -}; - -rules.listItem = { - filter: 'li', - - replacement: function (content, node, options) { - content = content - .replace(/^\n+/, '') // remove leading newlines - .replace(/\n+$/, '\n') // replace trailing newlines with just a single one - .replace(/\n/gm, '\n '); // indent - var prefix = options.bulletListMarker + ' '; - var parent = node.parentNode; - if (parent.nodeName === 'OL') { - var start = parent.getAttribute('start'); - var index = Array.prototype.indexOf.call(parent.children, node); - prefix = (start ? Number(start) + index : index + 1) + '. '; - } - return ( - prefix + content + (node.nextSibling && !/\n$/.test(content) ? '\n' : '') - ) - } -}; - -rules.indentedCodeBlock = { - filter: function (node, options) { - return ( - options.codeBlockStyle === 'indented' && - node.nodeName === 'PRE' && - node.firstChild && - node.firstChild.nodeName === 'CODE' - ) - }, - - replacement: function (content, node, options) { - return ( - '\n\n ' + - node.firstChild.textContent.replace(/\n/g, '\n ') + - '\n\n' - ) - } -}; - -rules.fencedCodeBlock = { - filter: function (node, options) { - return ( - options.codeBlockStyle === 'fenced' && - node.nodeName === 'PRE' && - node.firstChild && - node.firstChild.nodeName === 'CODE' - ) - }, - - replacement: function (content, node, options) { - var className = node.firstChild.className || ''; - var language = (className.match(/language-(\S+)/) || [null, ''])[1]; - - return ( - '\n\n' + options.fence + language + '\n' + - node.firstChild.textContent + - '\n' + options.fence + '\n\n' - ) - } -}; - -rules.horizontalRule = { - filter: 'hr', - - replacement: function (content, node, options) { - return '\n\n' + options.hr + '\n\n' - } -}; - -rules.inlineLink = { - filter: function (node, options) { - return ( - options.linkStyle === 'inlined' && - node.nodeName === 'A' && - node.getAttribute('href') - ) - }, - - replacement: function (content, node) { - var href = node.getAttribute('href'); - var title = node.title ? ' "' + node.title + '"' : ''; - return '[' + content + '](' + href + title + ')' - } -}; - -rules.referenceLink = { - filter: function (node, options) { - return ( - options.linkStyle === 'referenced' && - node.nodeName === 'A' && - node.getAttribute('href') - ) - }, - - replacement: function (content, node, options) { - var href = node.getAttribute('href'); - var title = node.title ? ' "' + node.title + '"' : ''; - var replacement; - var reference; - - switch (options.linkReferenceStyle) { - case 'collapsed': - replacement = '[' + content + '][]'; - reference = '[' + content + ']: ' + href + title; - break - case 'shortcut': - replacement = '[' + content + ']'; - reference = '[' + content + ']: ' + href + title; - break - default: - var id = this.references.length + 1; - replacement = '[' + content + '][' + id + ']'; - reference = '[' + id + ']: ' + href + title; - } - - this.references.push(reference); - return replacement - }, - - references: [], - - append: function (options) { - var references = ''; - if (this.references.length) { - references = '\n\n' + this.references.join('\n') + '\n\n'; - this.references = []; // Reset references - } - return references - } -}; - -rules.emphasis = { - filter: ['em', 'i'], - - replacement: function (content, node, options) { - if (!content.trim()) return '' - return options.emDelimiter + content + options.emDelimiter - } -}; - -rules.strong = { - filter: ['strong', 'b'], - - replacement: function (content, node, options) { - if (!content.trim()) return '' - return options.strongDelimiter + content + options.strongDelimiter - } -}; - -rules.code = { - filter: function (node) { - var hasSiblings = node.previousSibling || node.nextSibling; - var isCodeBlock = node.parentNode.nodeName === 'PRE' && !hasSiblings; - - return node.nodeName === 'CODE' && !isCodeBlock - }, - - replacement: function (content) { - if (!content.trim()) return '' - - var delimiter = '`'; - var leadingSpace = ''; - var trailingSpace = ''; - var matches = content.match(/`+/gm); - if (matches) { - if (/^`/.test(content)) leadingSpace = ' '; - if (/`$/.test(content)) trailingSpace = ' '; - while (matches.indexOf(delimiter) !== -1) delimiter = delimiter + '`'; - } - - return delimiter + leadingSpace + content + trailingSpace + delimiter - } -}; - -rules.image = { - filter: 'img', - - replacement: function (content, node) { - var alt = node.alt || ''; - var src = node.getAttribute('src') || ''; - var title = node.title || ''; - var titlePart = title ? ' "' + title + '"' : ''; - return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : '' - } -}; - -/** - * Manages a collection of rules used to convert HTML to Markdown - */ - -function Rules (options) { - this.options = options; - this._keep = []; - this._remove = []; - - this.blankRule = { - replacement: options.blankReplacement - }; - - this.keepReplacement = options.keepReplacement; - - this.defaultRule = { - replacement: options.defaultReplacement - }; - - this.array = []; - for (var key in options.rules) this.array.push(options.rules[key]); -} - -Rules.prototype = { - add: function (key, rule) { - this.array.unshift(rule); - }, - - keep: function (filter) { - this._keep.unshift({ - filter: filter, - replacement: this.keepReplacement - }); - }, - - remove: function (filter) { - this._remove.unshift({ - filter: filter, - replacement: function () { - return '' - } - }); - }, - - forNode: function (node) { - if (node.isBlank) return this.blankRule - var rule; - - if ((rule = findRule(this.array, node, this.options))) return rule - if ((rule = findRule(this._keep, node, this.options))) return rule - if ((rule = findRule(this._remove, node, this.options))) return rule - - return this.defaultRule - }, - - forEach: function (fn) { - for (var i = 0; i < this.array.length; i++) fn(this.array[i], i); - } -}; - -function findRule (rules, node, options) { - for (var i = 0; i < rules.length; i++) { - var rule = rules[i]; - if (filterValue(rule, node, options)) return rule - } - return void 0 -} - -function filterValue (rule, node, options) { - var filter = rule.filter; - if (typeof filter === 'string') { - if (filter === node.nodeName.toLowerCase()) return true - } else if (Array.isArray(filter)) { - if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true - } else if (typeof filter === 'function') { - if (filter.call(rule, node, options)) return true - } else { - throw new TypeError('`filter` needs to be a string, array, or function') - } -} - -/** - * The collapseWhitespace function is adapted from collapse-whitespace - * by Luc Thevenard. - * - * The MIT License (MIT) - * - * Copyright (c) 2014 Luc Thevenard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * collapseWhitespace(options) removes extraneous whitespace from an the given element. - * - * @param {Object} options - */ -function collapseWhitespace (options) { - var element = options.element; - var isBlock = options.isBlock; - var isVoid = options.isVoid; - var isPre = options.isPre || function (node) { - return node.nodeName === 'PRE' - }; - - if (!element.firstChild || isPre(element)) return - - var prevText = null; - var prevVoid = false; - - var prev = null; - var node = next(prev, element, isPre); - - while (node !== element) { - if (node.nodeType === 3 || node.nodeType === 4) { // Node.TEXT_NODE or Node.CDATA_SECTION_NODE - var text = node.data.replace(/[ \r\n\t]+/g, ' '); - - if ((!prevText || / $/.test(prevText.data)) && - !prevVoid && text[0] === ' ') { - text = text.substr(1); - } - - // `text` might be empty at this point. - if (!text) { - node = remove(node); - continue - } - - node.data = text; - - prevText = node; - } else if (node.nodeType === 1) { // Node.ELEMENT_NODE - if (isBlock(node) || node.nodeName === 'BR') { - if (prevText) { - prevText.data = prevText.data.replace(/ $/, ''); - } - - prevText = null; - prevVoid = false; - } else if (isVoid(node)) { - // Avoid trimming space around non-block, non-BR void elements. - prevText = null; - prevVoid = true; - } - } else { - node = remove(node); - continue - } - - var nextNode = next(prev, node, isPre); - prev = node; - node = nextNode; - } - - if (prevText) { - prevText.data = prevText.data.replace(/ $/, ''); - if (!prevText.data) { - remove(prevText); - } - } -} - -/** - * remove(node) removes the given node from the DOM and returns the - * next node in the sequence. - * - * @param {Node} node - * @return {Node} node - */ -function remove (node) { - var next = node.nextSibling || node.parentNode; - - node.parentNode.removeChild(node); - - return next -} - -/** - * next(prev, current, isPre) returns the next node in the sequence, given the - * current and previous nodes. - * - * @param {Node} prev - * @param {Node} current - * @param {Function} isPre - * @return {Node} - */ -function next (prev, current, isPre) { - if ((prev && prev.parentNode === current) || isPre(current)) { - return current.nextSibling || current.parentNode - } - - return current.firstChild || current.nextSibling || current.parentNode -} - -/* - * Set up window for Node.js - */ - -var root = (typeof window !== 'undefined' ? window : {}); - -/* - * Parsing HTML strings - */ - -function canParseHTMLNatively () { - var Parser = root.DOMParser; - var canParse = false; - - // Adapted from https://gist.github.com/1129031 - // Firefox/Opera/IE throw errors on unsupported types - try { - // WebKit returns null on unsupported types - if (new Parser().parseFromString('', 'text/html')) { - canParse = true; - } - } catch (e) {} - - return canParse -} - -function createHTMLParser () { - var Parser = function () {}; - - { - if (shouldUseActiveX()) { - Parser.prototype.parseFromString = function (string) { - var doc = new window.ActiveXObject('htmlfile'); - doc.designMode = 'on'; // disable on-page scripts - doc.open(); - doc.write(string); - doc.close(); - return doc - }; - } else { - Parser.prototype.parseFromString = function (string) { - var doc = document.implementation.createHTMLDocument(''); - doc.open(); - doc.write(string); - doc.close(); - return doc - }; - } - } - return Parser -} - -function shouldUseActiveX () { - var useActiveX = false; - try { - document.implementation.createHTMLDocument('').open(); - } catch (e) { - if (window.ActiveXObject) useActiveX = true; - } - return useActiveX -} - -var HTMLParser = canParseHTMLNatively() ? root.DOMParser : createHTMLParser(); - -function RootNode (input) { - var root; - if (typeof input === 'string') { - var doc = htmlParser().parseFromString( - // DOM parsers arrange elements in the and . - // Wrapping in a custom element ensures elements are reliably arranged in - // a single element. - '' + input + '', - 'text/html' - ); - root = doc.getElementById('turndown-root'); - } else { - root = input.cloneNode(true); - } - collapseWhitespace({ - element: root, - isBlock: isBlock, - isVoid: isVoid - }); - - return root -} - -var _htmlParser; -function htmlParser () { - _htmlParser = _htmlParser || new HTMLParser(); - return _htmlParser -} - -function Node (node) { - node.isBlock = isBlock(node); - node.isCode = node.nodeName.toLowerCase() === 'code' || node.parentNode.isCode; - node.isBlank = isBlank(node); - node.flankingWhitespace = flankingWhitespace(node); - return node -} - -function isBlank (node) { - return ( - ['A', 'TH', 'TD'].indexOf(node.nodeName) === -1 && - /^\s*$/i.test(node.textContent) && - !isVoid(node) && - !hasVoid(node) - ) -} - -function flankingWhitespace (node) { - var leading = ''; - var trailing = ''; - - if (!node.isBlock) { - var hasLeading = /^[ \r\n\t]/.test(node.textContent); - var hasTrailing = /[ \r\n\t]$/.test(node.textContent); - - if (hasLeading && !isFlankedByWhitespace('left', node)) { - leading = ' '; - } - if (hasTrailing && !isFlankedByWhitespace('right', node)) { - trailing = ' '; - } - } - - return { leading: leading, trailing: trailing } -} - -function isFlankedByWhitespace (side, node) { - var sibling; - var regExp; - var isFlanked; - - if (side === 'left') { - sibling = node.previousSibling; - regExp = / $/; - } else { - sibling = node.nextSibling; - regExp = /^ /; - } - - if (sibling) { - if (sibling.nodeType === 3) { - isFlanked = regExp.test(sibling.nodeValue); - } else if (sibling.nodeType === 1 && !isBlock(sibling)) { - isFlanked = regExp.test(sibling.textContent); - } - } - return isFlanked -} - -var reduce = Array.prototype.reduce; -var leadingNewLinesRegExp = /^\n*/; -var trailingNewLinesRegExp = /\n*$/; - -function TurndownService (options) { - if (!(this instanceof TurndownService)) return new TurndownService(options) - - var defaults = { - rules: rules, - headingStyle: 'setext', - hr: '* * *', - bulletListMarker: '*', - codeBlockStyle: 'indented', - fence: '```', - emDelimiter: '_', - strongDelimiter: '**', - linkStyle: 'inlined', - linkReferenceStyle: 'full', - br: ' ', - blankReplacement: function (content, node) { - return node.isBlock ? '\n\n' : '' - }, - keepReplacement: function (content, node) { - return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML - }, - defaultReplacement: function (content, node) { - return node.isBlock ? '\n\n' + content + '\n\n' : content - } - }; - this.options = extend({}, defaults, options); - this.rules = new Rules(this.options); -} - -TurndownService.prototype = { - /** - * The entry point for converting a string or DOM node to Markdown - * @public - * @param {String|HTMLElement} input The string or DOM node to convert - * @returns A Markdown representation of the input - * @type String - */ - - turndown: function (input) { - if (!canConvert(input)) { - throw new TypeError( - input + ' is not a string, or an element/document/fragment node.' - ) - } - - if (input === '') return '' - - var output = process.call(this, new RootNode(input)); - return postProcess.call(this, output) - }, - - /** - * Add one or more plugins - * @public - * @param {Function|Array} plugin The plugin or array of plugins to add - * @returns The Turndown instance for chaining - * @type Object - */ - - use: function (plugin) { - if (Array.isArray(plugin)) { - for (var i = 0; i < plugin.length; i++) this.use(plugin[i]); - } else if (typeof plugin === 'function') { - plugin(this); - } else { - throw new TypeError('plugin must be a Function or an Array of Functions') - } - return this - }, - - /** - * Adds a rule - * @public - * @param {String} key The unique key of the rule - * @param {Object} rule The rule - * @returns The Turndown instance for chaining - * @type Object - */ - - addRule: function (key, rule) { - this.rules.add(key, rule); - return this - }, - - /** - * Keep a node (as HTML) that matches the filter - * @public - * @param {String|Array|Function} filter The unique key of the rule - * @returns The Turndown instance for chaining - * @type Object - */ - - keep: function (filter) { - this.rules.keep(filter); - return this - }, - - /** - * Remove a node that matches the filter - * @public - * @param {String|Array|Function} filter The unique key of the rule - * @returns The Turndown instance for chaining - * @type Object - */ - - remove: function (filter) { - this.rules.remove(filter); - return this - }, - - /** - * Escapes Markdown syntax - * @public - * @param {String} string The string to escape - * @returns A string with Markdown syntax escaped - * @type String - */ - - escape: function (string) { - return ( - string - // Escape backslash escapes! - .replace(/\\(\S)/g, '\\\\$1') - - // Escape headings - .replace(/^(#{1,6} )/gm, '\\$1') - - // Escape hr - .replace(/^([-*_] *){3,}$/gm, function (match, character) { - return match.split(character).join('\\' + character) - }) - - // Escape ol bullet points - .replace(/^(\W* {0,3})(\d+)\. /gm, '$1$2\\. ') - - // Escape ul bullet points - .replace(/^([^\\\w]*)[*+-] /gm, function (match) { - return match.replace(/([*+-])/g, '\\$1') - }) - - // Escape blockquote indents - .replace(/^(\W* {0,3})> /gm, '$1\\> ') - - // Escape em/strong * - .replace(/\*+(?![*\s\W]).+?\*+/g, function (match) { - return match.replace(/\*/g, '\\*') - }) - - // Escape em/strong _ - .replace(/_+(?![_\s\W]).+?_+/g, function (match) { - return match.replace(/_/g, '\\_') - }) - - // Escape code _ - .replace(/`+(?![`\s\W]).+?`+/g, function (match) { - return match.replace(/`/g, '\\`') - }) - - // Escape link brackets - .replace(/[\[\]]/g, '\\$&') // eslint-disable-line no-useless-escape - ) - } -}; - -/** - * Reduces a DOM node down to its Markdown string equivalent - * @private - * @param {HTMLElement} parentNode The node to convert - * @returns A Markdown representation of the node - * @type String - */ - -function process (parentNode) { - var self = this; - return reduce.call(parentNode.childNodes, function (output, node) { - node = new Node(node); - - var replacement = ''; - if (node.nodeType === 3) { - replacement = node.isCode ? node.nodeValue : self.escape(node.nodeValue); - } else if (node.nodeType === 1) { - replacement = replacementForNode.call(self, node); - } - - return join(output, replacement) - }, '') -} - -/** - * Appends strings as each rule requires and trims the output - * @private - * @param {String} output The conversion output - * @returns A trimmed version of the ouput - * @type String - */ - -function postProcess (output) { - var self = this; - this.rules.forEach(function (rule) { - if (typeof rule.append === 'function') { - output = join(output, rule.append(self.options)); - } - }); - - return output.replace(/^[\t\r\n]+/, '').replace(/[\t\r\n\s]+$/, '') -} - -/** - * Converts an element node to its Markdown equivalent - * @private - * @param {HTMLElement} node The node to convert - * @returns A Markdown representation of the node - * @type String - */ - -function replacementForNode (node) { - var rule = this.rules.forNode(node); - var content = process.call(this, node); - var whitespace = node.flankingWhitespace; - if (whitespace.leading || whitespace.trailing) content = content.trim(); - return ( - whitespace.leading + - rule.replacement(content, node, this.options) + - whitespace.trailing - ) -} - -/** - * Determines the new lines between the current output and the replacement - * @private - * @param {String} output The current conversion output - * @param {String} replacement The string to append to the output - * @returns The whitespace to separate the current output and the replacement - * @type String - */ - -function separatingNewlines (output, replacement) { - var newlines = [ - output.match(trailingNewLinesRegExp)[0], - replacement.match(leadingNewLinesRegExp)[0] - ].sort(); - var maxNewlines = newlines[newlines.length - 1]; - return maxNewlines.length < 2 ? maxNewlines : '\n\n' -} - -function join (string1, string2) { - var separator = separatingNewlines(string1, string2); - - // Remove trailing/leading newlines and replace with separator - string1 = string1.replace(trailingNewLinesRegExp, ''); - string2 = string2.replace(leadingNewLinesRegExp, ''); - - return string1 + separator + string2 -} - -/** - * Determines whether an input can be converted - * @private - * @param {String|HTMLElement} input Describe this parameter - * @returns Describe what it returns - * @type String|Object|Array|Boolean|Number - */ - -function canConvert (input) { - return ( - input != null && ( - typeof input === 'string' || - (input.nodeType && ( - input.nodeType === 1 || input.nodeType === 9 || input.nodeType === 11 - )) - ) - ) -} - -return TurndownService; - -}()); diff --git a/src/utils/vSync.cpp b/src/utils/vSync.cpp deleted file mode 100644 index dce5d086..00000000 --- a/src/utils/vSync.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include "vSync.h" -#include -#include -#include -#include -#include -#include - -VSync::VSync(QWidget *parent) : QObject(parent) -{ - m_process = new QProcess(this); - connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(onReadOutput())); - connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(onReadError())); - connect(m_process, SIGNAL(finished(int)), this, SLOT(onProcessFinish(int))); - - m_messageBox = new QMessageBox(parent); - m_messageBox->setModal(true); - m_messageBox->setWindowTitle(tr("Sync")); - m_messageBox->setStandardButtons(QMessageBox::NoButton); - m_messageButton = new QPushButton(m_messageBox); - m_messageButton->setText(tr("Sure")); - connect(m_messageButton, &QPushButton::clicked, this, &VSync::onMessageButtonClick); -} - -VSync::~VSync() -{ - m_process->close(); -} - -void VSync::status() -{ - this->m_type = SyncType::Status; - this->start(getSyncHead("status")); -} - -void VSync::add() -{ - this->m_type = SyncType::Add; - this->start(getSyncHead("add -A")); -} - -void VSync::commit() -{ - this->m_type = SyncType::Commit; - QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"); - this->start(getSyncHead(QString("commit -m %1").arg(time))); -} - -void VSync::push() -{ - this->m_type = SyncType::Push; - this->start(getSyncHead("push")); -} - -void VSync::pull() -{ - this->m_type = SyncType::Pull; - this->start(getSyncHead("pull")); -} - -void VSync::authentication() -{ - this->m_type = SyncType::Authentication; - this->start("git config --global credential.helper store"); -} - -void VSync::download() -{ - showMessageBox(tr("Downloading"), false); - this->m_target = SyncTarget::Download; - this->status(); -} - -void VSync::upload() -{ - showMessageBox(tr("Uploading"), false); - this->m_target = SyncTarget::Upload; - this->status(); -} - -void VSync::onReadOutput() -{ - QString output = m_process->readAllStandardOutput(); - qDebug() << "VSync.onReadOutput: " << output; - m_output.append(output); -} - -void VSync::onReadError() -{ - QString error = m_process->readAllStandardError(); - qDebug() << "VSync.onReadError: " << error; - m_error.append(error); -} - -void VSync::onProcessFinish(int exitCode) -{ - qInfo() << "VSync.onProcessFinish: " << exitCode; - if (exitCode == 0) - { - switch (this->m_target) - { - case SyncTarget::Download: - this->processDownload(); - break; - case SyncTarget::Upload: - this->processUpload(); - break; - default: - break; - } - } - else - { - /* code */ - qCritical() << "sync failed, error: " << m_error << ", info: " << m_output; - QString message = QString("sync failed, exitCode: %1, error: %2, info: %3").arg(exitCode).arg(m_error).arg(m_output); - showMessageBox(message, true); - } - - m_error.clear(); - m_output.clear(); -} - -void VSync::start(const QString &cmd) -{ -#if defined(Q_OS_WIN) - m_process->start("cmd", QStringList() << "/c" << cmd); -#else - m_process->start("/bin/sh", QStringList() << "-c" << cmd); -#endif - m_process->waitForStarted(); -} - -void VSync::showMessageBox(const QString &message, bool showButton) -{ - m_messageBox->setText(message); - if (showButton) - { - m_messageBox->addButton(m_messageButton, QMessageBox::ButtonRole::YesRole); - } - else - { - m_messageBox->removeButton(m_messageButton); - } - - if (!m_messageBox->isVisible()) - { - m_messageBox->setVisible(true); - } -} - -void VSync::hideMessageBox() -{ - m_messageBox->removeButton(m_messageButton); - m_messageBox->setVisible(false); -} - -void VSync::onMessageButtonClick() -{ - m_messageBox->hide(); -} - -void VSync::processDownload() -{ - switch (this->m_type) - { - case SyncType::Status: - this->authentication(); - break; - case SyncType::Authentication: - this->pull(); - break; - case SyncType::Pull: - this->downloadFinish(); - break; - default: - break; - } -} - -void VSync::processUpload() -{ - switch (this->m_type) - { - case SyncType::Status: - this->add(); - break; - case SyncType::Add: - this->commit(); - break; - case SyncType::Commit: - this->authentication(); - break; - case SyncType::Authentication: - this->push(); - break; - case SyncType::Push: - this->uploadFinish(); - break; - default: - break; - } -} - -void VSync::downloadFinish() -{ - qInfo() << "download finish"; - showMessageBox(tr("Download Success"), true); - m_type = VSync::SyncType::None; - m_target = VSync::SyncTarget::None; - emit this->downloadSuccess(); -} - -void VSync::uploadFinish() -{ - qInfo() << "upload finish"; - showMessageBox(tr("Upload Success"), true); - m_type = VSync::SyncType::None; - m_target = VSync::SyncTarget::None; - emit this->uploadSuccess(); -} diff --git a/src/utils/vSync.h b/src/utils/vSync.h deleted file mode 100644 index e93e5ded..00000000 --- a/src/utils/vSync.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _V_SYNC_H_ -#define _V_SYNC_H_ -#include -#include -#include - -class QMessageBox; -class QPushButton; -class VSync : public QObject -{ - Q_OBJECT -private: - enum class SyncType - { - None, - Status, - Add, - Commit, - Push, - Pull, - Authentication - }; - - enum class SyncTarget - { - None, - Upload, - Download, - }; -signals: - void downloadSuccess(); - void uploadSuccess(); -public: - VSync(QWidget *parent = NULL); - ~VSync(); - void setDir(const QString &dir); - void upload(); - void download(); -private slots: - void onReadOutput(); - void onReadError(); - void onProcessFinish(int exitCode); - -private: - void status(); - void add(); - void commit(); - void push(); - void pull(); - void authentication(); - void processDownload(); - void processUpload(); - void downloadFinish(); - void uploadFinish(); - - void start(const QString &cmd); - void showMessageBox(const QString &message, bool showButton); - void hideMessageBox(); - void onMessageButtonClick(); - QString getSyncHead(const QString &args) const; - -private: - QString m_dir; - - QMessageBox *m_messageBox; - QPushButton *m_messageButton; - QProcess *m_process; - SyncType m_type; - SyncTarget m_target; - QString m_output; - QString m_error; -}; - -inline void VSync::setDir(const QString &dir) -{ - this->m_dir = dir; -}; - -inline QString VSync::getSyncHead(const QString &args) const -{ - return QString("git -C %1 %2").arg(this->m_dir).arg(args); -} - -#endif diff --git a/src/utils/vclipboardutils.cpp b/src/utils/vclipboardutils.cpp deleted file mode 100644 index c8c8128c..00000000 --- a/src/utils/vclipboardutils.cpp +++ /dev/null @@ -1,228 +0,0 @@ -#include "vclipboardutils.h" - -#include -#include - -#include "vutils.h" - -void VClipboardUtils::setImageToClipboard(QClipboard *p_clipboard, - const QImage &p_image, - QClipboard::Mode p_mode) -{ -#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) - // On Windows, setImage() may fail. We will repeatedly retry until succeed. - // On Linux, QXcbClipboard::setMimeData: Cannot set X11 selection owner. - setImageLoop(p_clipboard, p_image, p_mode); -#else - p_clipboard->setImage(p_image, p_mode); -#endif -} - -void VClipboardUtils::setImageLoop(QClipboard *p_clipboard, - const QImage &p_image, - QClipboard::Mode p_mode) -{ - for (int i = 0; i < 100; ++i) { - p_clipboard->setImage(p_image, p_mode); - - QImage image = p_clipboard->image(p_mode); - if (!image.isNull()) { - break; - } - - qWarning() << "fail to set image, retry" << i; - - VUtils::sleepWait(100 /* ms */); - } -} - -void VClipboardUtils::setImageToClipboard(QClipboard *p_clipboard, - const QPixmap &p_image, - QClipboard::Mode p_mode) -{ - QImage img(p_image.toImage()); - -#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) - // On Windows, setImage() may fail. We will repeatedly retry until succeed. - // On Linux, QXcbClipboard::setMimeData: Cannot set X11 selection owner. - setImageLoop(p_clipboard, img, p_mode); -#else - p_clipboard->setImage(img, p_mode); -#endif -} - -void VClipboardUtils::setMimeDataToClipboard(QClipboard *p_clipboard, - QMimeData *p_mimeData, - QClipboard::Mode p_mode) -{ -#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) - // On Windows, setMimeData() may fail. We will repeatedly retry until succeed. - // On Linux, QXcbClipboard::setMimeData: Cannot set X11 selection owner. - setMimeDataLoop(p_clipboard, p_mimeData, p_mode); -#else - p_clipboard->setMimeData(p_mimeData, p_mode); -#endif -} - -QMimeData *VClipboardUtils::cloneMimeData(const QMimeData *p_mimeData) -{ - QMimeData *da = new QMimeData(); - if (p_mimeData->hasUrls()) { - da->setUrls(p_mimeData->urls()); - } - - if (p_mimeData->hasText()) { - da->setText(p_mimeData->text()); - } - - if (p_mimeData->hasColor()) { - da->setColorData(p_mimeData->colorData()); - } - - if (p_mimeData->hasHtml()) { - da->setHtml(p_mimeData->html()); - } - - if (p_mimeData->hasImage()) { - da->setImageData(p_mimeData->imageData()); - } - - return da; -} - -static bool mimeDataEquals(const QMimeData *p_a, const QMimeData *p_b) -{ - if ((p_a && !p_b) || (!p_a && p_b)) { - return false; - } - - if (p_a->hasUrls()) { - if (!p_b->hasUrls()) { - return false; - } - - if (p_a->urls() != p_b->urls()) { - return false; - } - } else if (p_b->hasUrls()) { - return false; - } - - if (p_a->hasText()) { - if (!p_b->hasText()) { - return false; - } - - if (p_a->text() != p_b->text()) { - return false; - } - } else if (p_b->hasText()) { - return false; - } - - if (p_a->hasColor()) { - if (!p_b->hasColor()) { - return false; - } - - if (p_a->colorData() != p_b->colorData()) { - return false; - } - } else if (p_b->hasColor()) { - return false; - } - - if (p_a->hasHtml()) { - if (!p_b->hasHtml()) { - return false; - } - - if (p_a->html() != p_b->html()) { - return false; - } - } else if (p_b->hasHtml()) { - return false; - } - - if (p_a->hasImage()) { - if (!p_b->hasImage()) { - return false; - } - - if (p_a->imageData() != p_b->imageData()) { - return false; - } - } else if (p_b->hasImage()) { - return false; - } - - return true; -} - -void VClipboardUtils::setMimeDataLoop(QClipboard *p_clipboard, - QMimeData *p_mimeData, - QClipboard::Mode p_mode) -{ - for (int i = 0; i < 100; ++i) { - // Make a backup. - QMimeData *tmp = cloneMimeData(p_mimeData); - - p_clipboard->setMimeData(p_mimeData, p_mode); - const QMimeData *out = p_clipboard->mimeData(p_mode); - if (mimeDataEquals(tmp, out)) { - delete tmp; - break; - } - - qDebug() << "fail to set mimeData, retry" << i; - p_mimeData = tmp; - - VUtils::sleepWait(100 /* ms */); - } -} - -QMimeData *linkMimeData(const QString &p_link) -{ - QList urls; - urls.append(VUtils::pathToUrl(p_link)); - QMimeData *data = new QMimeData(); - data->setUrls(urls); - - QString text = urls[0].toEncoded(); -#if defined(Q_OS_WIN) - if (urls[0].isLocalFile()) { - text = urls[0].toString(QUrl::EncodeSpaces); - } -#endif - - data->setText(text); - return data; -} - -void VClipboardUtils::setLinkToClipboard(QClipboard *p_clipboard, - const QString &p_link, - QClipboard::Mode p_mode) -{ - VClipboardUtils::setMimeDataToClipboard(p_clipboard, - linkMimeData(p_link), - p_mode); -} - -void VClipboardUtils::setImageAndLinkToClipboard(QClipboard *p_clipboard, - const QImage &p_image, - const QString &p_link, - QClipboard::Mode p_mode) -{ - QMimeData *data = linkMimeData(p_link); - data->setImageData(p_image); - VClipboardUtils::setMimeDataToClipboard(p_clipboard, - data, - p_mode); -} - -void VClipboardUtils::setTextToClipboard(QClipboard *p_clipboard, - const QString &p_text, - QClipboard::Mode p_mode) -{ - p_clipboard->setText(p_text, p_mode); -} diff --git a/src/utils/vclipboardutils.h b/src/utils/vclipboardutils.h deleted file mode 100644 index 080efedc..00000000 --- a/src/utils/vclipboardutils.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef VCLIPBOARDUTILS_H -#define VCLIPBOARDUTILS_H - -#include -#include -#include - -class QMimeData; - - -class VClipboardUtils -{ -public: - static void setImageToClipboard(QClipboard *p_clipboard, - const QImage &p_image, - QClipboard::Mode p_mode = QClipboard::Clipboard); - - static void setImageToClipboard(QClipboard *p_clipboard, - const QPixmap &p_image, - QClipboard::Mode p_mode = QClipboard::Clipboard); - - static void setImageAndLinkToClipboard(QClipboard *p_clipboard, - const QImage &p_image, - const QString &p_link, - QClipboard::Mode p_mode = QClipboard::Clipboard); - - static void setMimeDataToClipboard(QClipboard *p_clipboard, - QMimeData *p_mimeData, - QClipboard::Mode p_mode = QClipboard::Clipboard); - - static QMimeData *cloneMimeData(const QMimeData *p_mimeData); - - static void setLinkToClipboard(QClipboard *p_clipboard, - const QString &p_link, - QClipboard::Mode p_mode = QClipboard::Clipboard); - - static void setTextToClipboard(QClipboard *p_clipboard, - const QString &p_text, - QClipboard::Mode p_mode = QClipboard::Clipboard); - -private: - VClipboardUtils() - { - } - - static void setImageLoop(QClipboard *p_clipboard, - const QImage &p_image, - QClipboard::Mode p_mode); - - static void setMimeDataLoop(QClipboard *p_clipboard, - QMimeData *p_mimeData, - QClipboard::Mode p_mode); -}; - -#endif // VCLIPBOARDUTILS_H diff --git a/src/utils/veditutils.cpp b/src/utils/veditutils.cpp deleted file mode 100644 index 47c08ff7..00000000 --- a/src/utils/veditutils.cpp +++ /dev/null @@ -1,1148 +0,0 @@ -#include "veditutils.h" - -#include -#include -#include -#include -#include - -#include "vutils.h" -#include "vcodeblockhighlighthelper.h" - -void VEditUtils::removeBlock(QTextBlock &p_block, QString *p_text) -{ - QTextCursor cursor(p_block); - removeBlock(cursor, p_text); -} - -void VEditUtils::removeBlock(QTextCursor &p_cursor, QString *p_text) -{ - const QTextDocument *doc = p_cursor.document(); - int blockCount = doc->blockCount(); - int blockNum = p_cursor.block().blockNumber(); - - p_cursor.select(QTextCursor::BlockUnderCursor); - if (p_text) { - *p_text = selectedText(p_cursor) + "\n"; - } - - p_cursor.deleteChar(); - - // Deleting the first block will leave an empty block. - // Deleting the last empty block will not work with deleteChar(). - if (blockCount == doc->blockCount()) { - if (blockNum == blockCount - 1) { - // The last block. - p_cursor.deletePreviousChar(); - } else { - p_cursor.deleteChar(); - } - } - - if (p_cursor.block().blockNumber() < blockNum) { - p_cursor.movePosition(QTextCursor::NextBlock); - } - - p_cursor.movePosition(QTextCursor::StartOfBlock); -} - -bool VEditUtils::insertBlockWithIndent(QTextCursor &p_cursor) -{ - V_ASSERT(!p_cursor.hasSelection()); - p_cursor.insertBlock(); - return indentBlockAsBlock(p_cursor, false); -} - -bool VEditUtils::insertListMarkAsPreviousBlock(QTextCursor &p_cursor) -{ - bool ret = false; - QTextBlock block = p_cursor.block(); - QTextBlock preBlock = block.previous(); - if (!preBlock.isValid()) { - return false; - } - - QString text = preBlock.text(); - QRegExp regExp(VUtils::c_listRegExp); - int regIdx = regExp.indexIn(text); - if (regIdx != -1) { - ret = true; - V_ASSERT(regExp.captureCount() == 1); - QString markText = regExp.capturedTexts()[1]; - if (isListBullet(markText)) { - // Insert bullet in front. - p_cursor.insertText(markText + " "); - } else { - // markText is like "123.". - V_ASSERT(markText.endsWith('.')); - bool ok = false; - int num = markText.left(markText.size() - 1).toInt(&ok, 10); - V_ASSERT(ok); - num++; - p_cursor.insertText(QString::number(num, 10) + ". "); - } - } - - return ret; -} - -bool VEditUtils::insertQuoteMarkAsPreviousBlock(QTextCursor &p_cursor) -{ - bool ret = false; - QTextBlock block = p_cursor.block(); - QTextBlock preBlock = block.previous(); - if (!preBlock.isValid()) { - return false; - } - - QString text = preBlock.text(); - QRegExp regExp(VUtils::c_blockQuoteRegExp); - int regIdx = regExp.indexIn(text); - if (regIdx != -1) { - ret = true; - Q_ASSERT(regExp.captureCount() == 1); - QString markText = regExp.capturedTexts()[1]; - p_cursor.insertText(markText); - } - - return ret; -} - -bool VEditUtils::indentBlockAsBlock(QTextCursor &p_cursor, bool p_next) -{ - QTextBlock block = p_cursor.block(); - QTextBlock refBlock = p_next ? block.next() : block.previous(); - return indentBlockAsBlock(p_cursor, refBlock); -} - -bool VEditUtils::indentBlockAsBlock(QTextCursor &p_cursor, const QTextBlock &p_refBlock) -{ - if (!p_refBlock.isValid()) { - return false; - } - - Q_ASSERT(!p_cursor.hasSelection()); - - bool changed = false; - QString leadingSpaces = fetchIndentSpaces(p_refBlock); - - moveCursorFirstNonSpaceCharacter(p_cursor, QTextCursor::MoveAnchor); - if (!p_cursor.atBlockStart()) { - p_cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); - p_cursor.removeSelectedText(); - changed = true; - } - - if (!leadingSpaces.isEmpty()) { - p_cursor.insertText(leadingSpaces); - changed = true; - } - - return changed; -} - -// Use another QTextCursor to remain the selection. -void VEditUtils::indentSelectedBlocksAsBlock(const QTextCursor &p_cursor, bool p_next) -{ - int nrBlocks = 1; - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - - QTextDocument *doc = p_cursor.document(); - QTextBlock sBlock = doc->findBlock(start); - QTextBlock refBlock; - if (!p_next) { - refBlock = sBlock.previous(); - } - - if (start != end) { - QTextBlock eBlock = doc->findBlock(end); - nrBlocks = eBlock.blockNumber() - sBlock.blockNumber() + 1; - - if (p_next) { - refBlock = eBlock.next(); - } - } else { - refBlock = sBlock.next(); - } - - QTextCursor bCursor(sBlock); - bCursor.beginEditBlock(); - for (int i = 0; i < nrBlocks; ++i) { - indentBlockAsBlock(bCursor, refBlock); - - bCursor.movePosition(QTextCursor::NextBlock); - } - - bCursor.endEditBlock(); -} - -bool VEditUtils::hasSameIndent(const QTextBlock &p_blocka, const QTextBlock &p_blockb) -{ - int nonSpaceIdxa = 0; - int nonSpaceIdxb = 0; - - QString texta = p_blocka.text(); - for (int i = 0; i < texta.size(); ++i) { - if (!texta[i].isSpace()) { - nonSpaceIdxa = i; - break; - } - } - - QString textb = p_blockb.text(); - for (int i = 0; i < textb.size(); ++i) { - if (!textb[i].isSpace()) { - nonSpaceIdxb = i; - break; - } else if (i >= nonSpaceIdxa || texta[i] != textb[i]) { - return false; - } - } - - return nonSpaceIdxa == nonSpaceIdxb; -} - -void VEditUtils::moveCursorFirstNonSpaceCharacter(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int idx = 0; - for (; idx < text.size(); ++idx) { - if (text[idx].isSpace()) { - continue; - } else { - break; - } - } - - p_cursor.setPosition(block.position() + idx, p_mode); -} - -void VEditUtils::removeObjectReplacementCharacter(QString &p_text) -{ - QRegExp orcBlockExp(VUtils::c_previewImageBlockRegExp); - p_text.remove(orcBlockExp); - p_text.remove(QChar::ObjectReplacementCharacter); -} - -QString VEditUtils::selectedText(const QTextCursor &p_cursor) -{ - QString text = p_cursor.selectedText(); - text.replace(QChar::ParagraphSeparator, '\n'); - return text; -} - -// Use another QTextCursor to remain the selection. -void VEditUtils::indentSelectedBlocks(const QTextCursor &p_cursor, - const QString &p_indentationText, - bool p_isIndent) -{ - int nrBlocks = 1; - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - - QTextDocument *doc = p_cursor.document(); - QTextBlock sBlock = doc->findBlock(start); - if (start != end) { - QTextBlock eBlock = doc->findBlock(end); - nrBlocks = eBlock.blockNumber() - sBlock.blockNumber() + 1; - } - - QTextCursor bCursor(sBlock); - bCursor.beginEditBlock(); - for (int i = 0; i < nrBlocks; ++i) { - if (p_isIndent) { - indentBlock(bCursor, p_indentationText); - } else { - unindentBlock(bCursor, p_indentationText); - } - - bCursor.movePosition(QTextCursor::NextBlock); - } - - bCursor.endEditBlock(); -} - -void VEditUtils::indentBlock(QTextCursor &p_cursor, - const QString &p_indentationText, - bool p_skipEmpty) -{ - QTextBlock block = p_cursor.block(); - if (block.length() > 1 || !p_skipEmpty) { - p_cursor.movePosition(QTextCursor::StartOfBlock); - p_cursor.insertText(p_indentationText); - } -} - -void VEditUtils::unindentBlock(QTextCursor &p_cursor, - const QString &p_indentationText) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - if (text.isEmpty()) { - return; - } - - p_cursor.movePosition(QTextCursor::StartOfBlock); - if (text[0] == '\t') { - p_cursor.deleteChar(); - } else if (text[0].isSpace()) { - int width = p_indentationText.size(); - for (int i = 0; i < width; ++i) { - if (text[i] == ' ') { - p_cursor.deleteChar(); - } else { - break; - } - } - } -} - -bool VEditUtils::findTargetWithinBlock(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode, - QChar p_target, - bool p_forward, - bool p_inclusive, - bool p_leftSideOfCursor, - int p_repeat) -{ - if (p_repeat < 1) { - return false; - } - - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - int delta = p_forward ? 1 : -1; - - // The index to start searching. - int idx = pib + (p_inclusive ? delta : 2 * delta); - if (p_leftSideOfCursor) { - --idx; - } - - for (; idx < text.size() && idx >= 0; idx += delta) { - if (text[idx] == p_target) { - if (--p_repeat == 0) { - break; - } - } - } - - if (idx < 0 || idx >= text.size() || p_repeat > 0) { - return false; - } - - // text[idx] is the target character. - if ((p_forward && p_inclusive && p_mode == QTextCursor::KeepAnchor) - || (!p_forward && !p_inclusive)) { - ++idx; - } else if (p_forward && !p_inclusive && p_mode == QTextCursor::MoveAnchor) { - --idx; - } - - p_cursor.setPosition(block.position() + idx, p_mode); - return true; -} - -int VEditUtils::findTargetsWithinBlock(QTextCursor &p_cursor, - const QList &p_targets, - bool p_forward, - bool p_leftSideOfCursor, - bool p_inclusive) -{ - if (p_targets.isEmpty()) { - return -1; - } - - int targetIdx = -1; - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - int delta = p_forward ? 1 : -1; - - // The index to start searching. - int idx = pib + (p_inclusive ? delta : 2 * delta); - if (p_leftSideOfCursor) { - --idx; - } - - for (; idx < text.size() && idx >= 0; idx += delta) { - int index = p_targets.indexOf(text[idx]); - if (index != -1) { - targetIdx = index; - break; - } - } - - if (idx < 0 || idx >= text.size()) { - return -1; - } - - // text[idx] is the target character. - if (p_forward && !p_inclusive) { - --idx; - } - - p_cursor.setPosition(block.position() + idx); - return targetIdx; -} - - -int VEditUtils::selectedBlockCount(const QTextCursor &p_cursor) -{ - if (!p_cursor.hasSelection()) { - return 0; - } - - QTextDocument *doc = p_cursor.document(); - int sbNum = doc->findBlock(p_cursor.selectionStart()).blockNumber(); - int ebNum = doc->findBlock(p_cursor.selectionEnd()).blockNumber(); - - return ebNum - sbNum + 1; -} - -void VEditUtils::scrollBlockInPage(QTextEdit *p_edit, - int p_blockNum, - int p_dest, - int p_margin) -{ - QTextDocument *doc = p_edit->document(); - QTextCursor cursor = p_edit->textCursor(); - if (p_blockNum >= doc->blockCount()) { - p_blockNum = doc->blockCount() - 1; - } - - QTextBlock block = doc->findBlockByNumber(p_blockNum); - - if (cursor.block().blockNumber() != p_blockNum) { - // Move the cursor to the block. - int pib = cursor.positionInBlock(); - if (pib >= block.length()) { - pib = block.length() - 1; - } - - cursor.setPosition(block.position() + pib); - p_edit->setTextCursor(cursor); - } - - QScrollBar *vsbar = p_edit->verticalScrollBar(); - if (!vsbar || !vsbar->isVisible()) { - // No vertical scrollbar. No need to scroll. - return; - } - - int sstep = vsbar->singleStep(); - if (p_margin < sstep) { - p_margin = sstep; - } - - // Scroll to let current cursor locate in proper position. - p_edit->ensureCursorVisible(); - - QRect rect = p_edit->cursorRect(); - int height = p_edit->rect().height(); - QScrollBar *sbar = p_edit->horizontalScrollBar(); - if (sbar && sbar->isVisible()) { - height -= sbar->height(); - } - - bool moved = false; - switch (p_dest) { - case 0: - { - // Top. - while (rect.y() > p_margin && vsbar->value() < vsbar->maximum()) { - vsbar->setValue(vsbar->value() + sstep); - rect = p_edit->cursorRect(); - moved = true; - } - - break; - } - - case 1: - { - // Center. - height = qMax(height / 2, 1); - int upBound = height + p_margin; - int lowBound = height - p_margin; - if (rect.y() > upBound) { - while (rect.y() > upBound && vsbar->value() < vsbar->maximum()) { - vsbar->setValue(vsbar->value() + sstep); - rect = p_edit->cursorRect(); - moved = true; - } - } else if (rect.y() < lowBound) { - while (rect.y() < lowBound && vsbar->value() > vsbar->minimum()) { - vsbar->setValue(vsbar->value() - sstep); - rect = p_edit->cursorRect(); - moved = true; - } - } - - break; - } - - case 2: - { - // Bottom. - int lowBound = height - p_margin; - while (rect.y() < lowBound && vsbar->value() > vsbar->minimum()) { - vsbar->setValue(vsbar->value() - sstep); - rect = p_edit->cursorRect(); - moved = true; - } - - break; - } - - default: - break; - } - - if (moved) { - p_edit->ensureCursorVisible(); - } -} - -void VEditUtils::scrollBlockInPage(QPlainTextEdit *p_edit, - int p_blockNum, - int p_dest, - int p_margin) -{ - QTextDocument *doc = p_edit->document(); - QTextCursor cursor = p_edit->textCursor(); - if (p_blockNum >= doc->blockCount()) { - p_blockNum = doc->blockCount() - 1; - } - - QTextBlock block = doc->findBlockByNumber(p_blockNum); - - if (cursor.block().blockNumber() != p_blockNum) { - // Move the cursor to the block. - int pib = cursor.positionInBlock(); - if (pib >= block.length()) { - pib = block.length() - 1; - } - - cursor.setPosition(block.position() + pib); - p_edit->setTextCursor(cursor); - } - - QScrollBar *vsbar = p_edit->verticalScrollBar(); - if (!vsbar || !vsbar->isVisible()) { - // No vertical scrollbar. No need to scroll. - return; - } - - int sstep = vsbar->singleStep(); - if (p_margin < sstep) { - p_margin = sstep; - } - - // Scroll to let current cursor locate in proper position. - p_edit->ensureCursorVisible(); - - QRect rect = p_edit->cursorRect(); - int height = p_edit->rect().height(); - QScrollBar *sbar = p_edit->horizontalScrollBar(); - if (sbar && sbar->isVisible()) { - height -= sbar->height(); - } - - bool moved = false; - switch (p_dest) { - case 0: - { - // Top. - while (rect.y() > p_margin && vsbar->value() < vsbar->maximum()) { - vsbar->setValue(vsbar->value() + sstep); - rect = p_edit->cursorRect(); - } - - break; - } - - case 1: - { - // Center. - height = qMax(height / 2, 1); - int upBound = height + p_margin; - int lowBound = height - p_margin; - if (rect.y() > upBound) { - while (rect.y() > upBound && vsbar->value() < vsbar->maximum()) { - vsbar->setValue(vsbar->value() + sstep); - rect = p_edit->cursorRect(); - moved = true; - } - } else if (rect.y() < lowBound) { - while (rect.y() < lowBound && vsbar->value() > vsbar->minimum()) { - vsbar->setValue(vsbar->value() - sstep); - rect = p_edit->cursorRect(); - moved = true; - } - } - - break; - } - - case 2: - { - // Bottom. - int lowBound = height - p_margin; - while (rect.y() < lowBound && vsbar->value() > vsbar->minimum()) { - vsbar->setValue(vsbar->value() - sstep); - rect = p_edit->cursorRect(); - moved = true; - } - - break; - } - - default: - break; - } - - if (moved) { - p_edit->ensureCursorVisible(); - } -} - -bool VEditUtils::isBlockQuoteBlock(const QTextBlock &p_block) -{ - QString text = p_block.text(); - QRegExp regExp(VUtils::c_blockQuoteRegExp); - int regIdx = regExp.indexIn(text); - return regIdx >= 0; -} - -bool VEditUtils::isListBlock(const QTextBlock &p_block, int *p_seq) -{ - QString text = p_block.text(); - QRegExp regExp(VUtils::c_listRegExp); - - if (p_seq) { - *p_seq = -1; - } - - int regIdx = regExp.indexIn(text); - if (regIdx == -1) { - return false; - } - - V_ASSERT(regExp.captureCount() == 1); - QString markText = regExp.capturedTexts()[1]; - if (!isListBullet(markText)) { - V_ASSERT(markText.endsWith('.')); - bool ok = false; - int num = markText.left(markText.size() - 1).toInt(&ok, 10); - V_ASSERT(ok); - if (p_seq) { - *p_seq = num; - } - } - - return true; -} - -bool VEditUtils::isListBullet(const QString &p_str) -{ - return p_str == "-" || p_str == "*"; -} - -bool VEditUtils::isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock) -{ - if (p_posInBlock <= 0) { - return true; - } - - QString text = p_block.text(); - V_ASSERT(text.size() >= p_posInBlock); - return text.left(p_posInBlock).trimmed().isEmpty(); -} - -bool VEditUtils::isSpaceBlock(const QTextBlock &p_block) -{ - return p_block.text().trimmed().isEmpty(); -} - -void VEditUtils::deleteIndentAndListMark(QTextCursor &p_cursor) -{ - V_ASSERT(!p_cursor.hasSelection()); - p_cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); - p_cursor.removeSelectedText(); -} - - -bool VEditUtils::selectPairTargetAround(QTextCursor &p_cursor, - QChar p_opening, - QChar p_closing, - bool p_inclusive, - bool p_crossBlock, - int p_repeat) -{ - Q_ASSERT(p_repeat >= 1); - - QTextDocument *doc = p_cursor.document(); - int pos = p_cursor.position(); - - // Search range [start, end]. - int start = 0; - int end = doc->characterCount() - 1; - if (!p_crossBlock) { - QTextBlock block = p_cursor.block(); - start = block.position(); - end = block.position() + block.length() - 1; - } - - if (start == end || pos > end) { - return false; - } - - Q_ASSERT(!doc->characterAt(pos).isNull()); - - bool found = false; - - // The number of un-paired symbols before we meet a target. - // For example, when we are searching the `(`, nrPair is the number of - // the un-paired `)` currently. - int nrPair = 0; - - // The absolute position of the found target. - // vnote|(vnote|)vnote - int opening = pos; - int closing = pos; - -round: - // "abc|"def", after `di"`, becomes "|"def" - // So we need to try closing first. - QChar ch = doc->characterAt(closing); - Q_ASSERT(!ch.isNull()); - if (ch == p_closing) { - // Try to find the opening. - nrPair = 1; - int i = opening; - if (opening == closing) { - --i; - } - - for (; i >= start; --i) { - ch = doc->characterAt(i); - Q_ASSERT(!ch.isNull()); - if (ch == p_opening) { - if (--nrPair == 0) { - break; - } - } else if (ch == p_closing) { - ++nrPair; - } - } - - if (i >= start) { - // Found the opening. Done. - opening = i; - found = true; - } - } - - ch = doc->characterAt(opening); - Q_ASSERT(!ch.isNull()); - if (!found && ch == p_opening) { - // Try to find the closing. - nrPair = 1; - int j = closing; - if (opening == closing) { - ++j; - } - - for (; j <= end; ++j) { - ch = doc->characterAt(j); - Q_ASSERT(!ch.isNull()); - if (ch == p_closing) { - if (--nrPair == 0) { - break; - } - } else if (ch == p_opening) { - ++nrPair; - } - } - - if (j <= end) { - // Foudnd the closing. Done. - closing = j; - found = true; - } - } - - if (!found - && doc->characterAt(opening) != p_opening - && doc->characterAt(closing) != p_closing) { - // Need to find both the opening and closing. - int i = opening - 1; - int j = closing + 1; - // Pretend that we have found one. - nrPair = 1; - for (; i >= start; --i) { - ch = doc->characterAt(i); - Q_ASSERT(!ch.isNull()); - if (ch == p_opening) { - if (--nrPair == 0) { - break; - } - } else if (ch == p_closing) { - ++nrPair; - } - } - - if (i >= start) { - opening = i; - // Continue to find the closing. - nrPair = 1; - for (; j <= end; ++j) { - ch = doc->characterAt(j); - Q_ASSERT(!ch.isNull()); - if (ch == p_closing) { - if (--nrPair == 0) { - break; - } - } else if (ch == p_opening) { - ++nrPair; - } - } - - if (j <= end) { - closing = j; - found = true; - } - } - } - - if (!found) { - return false; - } else if (--p_repeat) { - // Need to find more. - found = false; - --opening; - ++closing; - - if (opening < start && closing > end) { - return false; - } - - goto round; - } - - if (p_inclusive) { - ++closing; - } else { - ++opening; - } - - p_cursor.setPosition(opening, QTextCursor::MoveAnchor); - p_cursor.setPosition(closing, QTextCursor::KeepAnchor); - return true; -} - -int VEditUtils::findNextEmptyBlock(const QTextCursor &p_cursor, - bool p_forward, - int p_repeat) -{ - Q_ASSERT(p_repeat > 0); - int res = -1; - QTextBlock block = p_cursor.block(); - if (p_forward) { - block = block.next(); - } else { - block = block.previous(); - } - - while (block.isValid()) { - if (block.length() == 1) { - res = block.position(); - if (--p_repeat == 0) { - break; - } - } - - if (p_forward) { - block = block.next(); - } else { - block = block.previous(); - } - } - - return p_repeat > 0 ? -1 : res; -} - -bool VEditUtils::needToCancelAutoIndent(int p_autoIndentPos, const QTextCursor &p_cursor) -{ - // Cancel the auto indent/list if the pos is the same and cursor is at - // the end of a block. - QTextBlock block = p_cursor.block(); - if (p_cursor.position() == p_autoIndentPos - && !p_cursor.hasSelection() - && p_cursor.atBlockEnd()) { - if (isListBlock(block) || isBlockQuoteBlock(block)) { - return true; - } else if (isSpaceToBlockStart(block, - p_cursor.positionInBlock())) { - return true; - } - } - - return false; -} - -void VEditUtils::insertTitleMark(QTextCursor &p_cursor, - const QTextBlock &p_block, - int p_level) -{ - if (!p_block.isValid()) { - return; - } - - Q_ASSERT(p_level >= 0 && p_level <= 6); - - bool needInsert = true; - - p_cursor.setPosition(p_block.position()); - - // Test if this block contains title marks. - QRegExp headerReg(VUtils::c_headerRegExp); - QString text = p_block.text(); - bool matched = headerReg.exactMatch(text); - if (matched) { - int level = headerReg.cap(1).length(); - if (level == p_level) { - needInsert = false; - } else { - // Remove the title mark. - int length = level; - if (p_level == 0) { - // Remove all the prefix. - QRegExp prefixReg(VUtils::c_headerPrefixRegExp); - bool preMatched = prefixReg.exactMatch(text); - Q_UNUSED(preMatched); - Q_ASSERT(preMatched); - length = prefixReg.cap(1).length(); - } - - p_cursor.movePosition(QTextCursor::NextCharacter, - QTextCursor::KeepAnchor, - length); - p_cursor.removeSelectedText(); - } - } - - // Insert titleMark + " " at the front of the block. - if (p_level > 0 && needInsert) { - // Remove the spaces at front. - // insertText() will remove the selection. - moveCursorFirstNonSpaceCharacter(p_cursor, QTextCursor::KeepAnchor); - - // Insert. - const QString titleMark(p_level, '#'); - p_cursor.insertText(titleMark + " "); - } - - // Go to the end of this block. - p_cursor.movePosition(QTextCursor::EndOfBlock); -} - -void VEditUtils::findCurrentWord(QTextCursor p_cursor, - int &p_start, - int &p_end, - bool p_findPrecedingWord) -{ - QString text = p_cursor.block().text(); - int pib = p_cursor.positionInBlock(); - - if (pib < text.size() && isSpaceOrWordSeparator(text[pib])) { - if (!p_findPrecedingWord - || pib == 0 - || isSpaceOrWordSeparator(text[pib - 1])) { - p_start = p_end = p_cursor.position(); - return; - } - - p_cursor.movePosition(QTextCursor::PreviousCharacter); - } - - p_cursor.movePosition(QTextCursor::StartOfWord); - p_start = p_cursor.position(); - p_cursor.movePosition(QTextCursor::EndOfWord); - p_end = p_cursor.position(); -} - -void VEditUtils::findCurrentWORD(const QTextCursor &p_cursor, - int &p_start, - int &p_end) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - - if (pib < text.size() && text[pib].isSpace()) { - p_start = p_end = p_cursor.position(); - return; - } - - // Find the start. - p_start = 0; - for (int i = pib - 1; i >= 0; --i) { - if (text[i].isSpace()) { - p_start = i + 1; - break; - } - } - - // Find the end. - p_end = block.length() - 1; - for (int i = pib; i < text.size(); ++i) { - if (text[i].isSpace()) { - p_end = i; - break; - } - } - - p_start += block.position(); - p_end += block.position(); -} - -QString VEditUtils::fetchIndentSpaces(const QTextBlock &p_block) -{ - QString text = p_block.text(); - QRegExp regExp("(^\\s*)"); - regExp.indexIn(text); - Q_ASSERT(regExp.captureCount() == 1); - return regExp.capturedTexts()[1]; -} - -int VEditUtils::fetchIndentation(const QString &p_text) -{ - int idx = 0; - for (; idx < p_text.size(); ++idx) { - if (!p_text[idx].isSpace()) { - break; - } - } - - return idx; -} - -int VEditUtils::fetchIndentation(const QTextBlock &p_block) -{ - return fetchIndentation(p_block.text()); -} - -void VEditUtils::insertBlock(QTextCursor &p_cursor, - bool p_above) -{ - p_cursor.movePosition(p_above ? QTextCursor::StartOfBlock - : QTextCursor::EndOfBlock, - QTextCursor::MoveAnchor, - 1); - - p_cursor.insertBlock(); - - if (p_above) { - p_cursor.movePosition(QTextCursor::PreviousBlock, - QTextCursor::MoveAnchor, - 1); - } - - p_cursor.movePosition(QTextCursor::EndOfBlock); -} - -void VEditUtils::insertBeforeEachLine(QString &p_text, const QString &p_str) -{ - int pos = 0; - while (pos < p_text.size()) { - int idx = p_text.indexOf("\n", pos); - if (idx == -1) { - break; - } - - ++idx; - if (idx == p_text.size()) { - break; - } - - p_text.insert(idx, p_str); - pos = idx + p_str.size(); - } - - p_text.prepend(p_str); -} - -bool VEditUtils::isEmptyBlock(const QTextBlock &p_block) -{ - return p_block.length() == 1; -} - -// Copy from QTextEngine::atWordSeparator(int position). -bool VEditUtils::isWordSeparator(QChar p_char) -{ - switch (p_char.unicode()) { - case '.': - case ',': - case '?': - case '!': - case '@': - case '#': - case '$': - case ':': - case ';': - case '-': - case '<': - case '>': - case '[': - case ']': - case '(': - case ')': - case '{': - case '}': - case '=': - case '/': - case '+': - case '%': - case '&': - case '^': - case '*': - case '\'': - case '"': - case '`': - case '~': - case '|': - case '\\': - return true; - - default: - break; - } - - return false; -} - -QString VEditUtils::removeCodeBlockFence(const QString &p_text) -{ - QString text = VCodeBlockHighlightHelper::unindentCodeBlock(p_text); - Q_ASSERT(text.startsWith("```") || text.startsWith("~~~")); - int idx = text.indexOf('\n') + 1; - int lidx = text.size() - 1; - // Trim spaces at the end. - while (lidx >= 0 && text[lidx].isSpace()) { - --lidx; - } - - Q_ASSERT(text[lidx] == '`' || text[lidx] == '~'); - return text.mid(idx, lidx + 1 - idx - 3); -} - -bool VEditUtils::isSpaceOrWordSeparator(QChar p_char) -{ - return p_char.isSpace() || isWordSeparator(p_char); -} diff --git a/src/utils/veditutils.h b/src/utils/veditutils.h deleted file mode 100644 index 0825ca35..00000000 --- a/src/utils/veditutils.h +++ /dev/null @@ -1,226 +0,0 @@ -#ifndef VEDITUTILS_H -#define VEDITUTILS_H - -#include -#include - -class QTextDocument; -class QTextEdit; -class QPlainTextEdit; - -// Utils for text edit. -class VEditUtils -{ -public: - // Remove the whole block @p_block. - // If @p_text is not NULL, return the deleted text here. - static void removeBlock(QTextBlock &p_block, QString *p_text = NULL); - - // Remove the whole block under @p_cursor. - // If @p_text is not NULL, return the deleted text here. - // Need to call setTextCursor() to make it take effect. - static void removeBlock(QTextCursor &p_cursor, QString *p_text = NULL); - - // Move @p_cursor to the first non-space character of current block. - // Need to call setTextCursor() to make it take effect. - static void moveCursorFirstNonSpaceCharacter(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode); - - // Indent current block as next/previous block. - // Return true if some changes have been made. - // @p_cursor will be placed at the position after inserting leading spaces. - // @p_next: indent as next block or previous block. - static bool indentBlockAsBlock(QTextCursor &p_cursor, bool p_next); - - // Indent current block as @p_refBlock. - static bool indentBlockAsBlock(QTextCursor &p_cursor, const QTextBlock &p_refBlock); - - // Returns true if two blocks has the same indent. - static bool hasSameIndent(const QTextBlock &p_blocka, const QTextBlock &p_blockb); - - // Insert a new block at current position with the same indentation as - // current block. Should clear the selection before calling this. - // Returns true if non-empty indentation has been inserted. - // Need to call setTextCursor() to make it take effect. - static bool insertBlockWithIndent(QTextCursor &p_cursor); - - // Fetch the list mark of previous block, and insert it at current position. - // Returns true if list mark has been inserted. - // Need to call setTextCursor() to make it take effect. - static bool insertListMarkAsPreviousBlock(QTextCursor &p_cursor); - - // Fetch the block quote mark of previous block, and insert it at current position. - // Returns true if quote mark has been inserted. - // Need to call setTextCursor() to make it take effect. - static bool insertQuoteMarkAsPreviousBlock(QTextCursor &p_cursor); - - // Remove ObjectReplaceCharacter in p_text. - // If the ObjectReplaceCharacter is in a block with only other spaces, remove the - // whole block. - static void removeObjectReplacementCharacter(QString &p_text); - - // p_cursor.selectedText() will use U+2029 (QChar::ParagraphSeparator) - // instead of \n for a new line. - // This function will translate it to \n. - static QString selectedText(const QTextCursor &p_cursor); - - // Indent selected blocks. If no selection, indent current block. - // Cursor position and selection is not changed. - // @p_isIndent: whether it is indentation or unindentation. - static void indentSelectedBlocks(const QTextCursor &p_cursor, - const QString &p_indentationText, - bool p_isIndent); - - // Indent seleced block as next/previous block. - // Cursor position and selection is not changed. - // Return true if some changes have been made. - // @p_next: indent as next block or previous block. - static void indentSelectedBlocksAsBlock(const QTextCursor &p_cursor, bool p_next); - - // Indent current block. - // @p_skipEmpty: skip empty block. - static void indentBlock(QTextCursor &p_cursor, - const QString &p_indentationText, - bool p_skipEmpty = true); - - static void unindentBlock(QTextCursor &p_cursor, - const QString &p_indentationText); - - // Find @p_repeat th occurence of a char within a block. - // Returns true if target is found. - // Please pay attention to the one-step-forward/backward in KeepAnchor mode - // and exclusive case. - static bool findTargetWithinBlock(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode, - QChar p_target, - bool p_forward, - bool p_inclusive, - bool p_leftSideOfCursor, - int p_repeat); - - // Find th first occurence of a char in @p_targets within a block. - // Returns the index of the found char in @p_targets if found. - // Returns -1 if none of the @p_targets is found. - // Different from findTargetWithinBlock(), will not modify the ucrsor position - // even in KeepAnchor mode. - static int findTargetsWithinBlock(QTextCursor &p_cursor, - const QList &p_targets, - bool p_forward, - bool p_leftSideOfCursor, - bool p_inclusive); - - // Find a pair target (@p_opening, @p_closing) containing current cursor and - // select the range between them. - // Need to call setTextCursor() to make it take effect. - // Returns true if target is found. - static bool selectPairTargetAround(QTextCursor &p_cursor, - QChar p_opening, - QChar p_closing, - bool p_inclusive, - bool p_crossBlock, - int p_repeat); - - // Get the count of blocks selected. - static int selectedBlockCount(const QTextCursor &p_cursor); - - // Scroll block @p_blockNum into the visual window. - // @p_dest is the position of the window: 0 for top, 1 for center, 2 for bottom. - // @p_blockNum is based on 0. - // Will set the cursor to the block. - static void scrollBlockInPage(QTextEdit *p_edit, - int p_blockNum, - int p_dest, - int p_margin = 0); - - // Scroll block @p_blockNum into the visual window. - // @p_dest is the position of the window: 0 for top, 1 for center, 2 for bottom. - // @p_blockNum is based on 0. - // Will set the cursor to the block. - static void scrollBlockInPage(QPlainTextEdit *p_edit, - int p_blockNum, - int p_dest, - int p_margin = 0); - - // Check if @p_block is a auto list block. - // @p_seq will be the seq number of the ordered list, or -1. - // Returns true if it is an auto list block. - static bool isListBlock(const QTextBlock &p_block, int *p_seq = NULL); - - static bool isListBullet(const QString &p_str); - - static bool isBlockQuoteBlock(const QTextBlock &p_block); - - // If the start of @p_block to postition @p_posInBlock are spaces. - static bool isSpaceToBlockStart(const QTextBlock &p_block, int p_posInBlock); - - // If block @p_block only contains spaces. - static bool isSpaceBlock(const QTextBlock &p_block); - - // @p_cursor is positioned right after auto indetn and auto list. - // Need to call setTextCursor() to make it take effect. - static void deleteIndentAndListMark(QTextCursor &p_cursor); - - // Find next @p_repeat empty block. - // Returns the position of that block if found. Otherwise, returns -1. - static int findNextEmptyBlock(const QTextCursor &p_cursor, - bool p_forward, - int p_repeat); - - // Check if we need to cancel auto indent. - // @p_autoIndentPos: the position of the cursor after auto indent. - static bool needToCancelAutoIndent(int p_autoIndentPos, - const QTextCursor &p_cursor); - - // Insert title Mark at level @p_level in front of block @p_block - // If there already exists title marks, remove it first. - // Move cursor at the end of the block after insertion. - // If @p_level is 0, remove the title mark. - static void insertTitleMark(QTextCursor &p_cursor, - const QTextBlock &p_block, - int p_level); - - // Find the start and end of the word @p_cursor locates in (within a single block). - // @p_start and @p_end will be the global position of the start and end of the word. - // @p_start will equals to @p_end if @p_cursor is a space. - static void findCurrentWord(QTextCursor p_cursor, - int &p_start, - int &p_end, - bool p_findPrecedingWord = false); - - // Find the start and end of the WORD @p_cursor locates in (within a single block). - // @p_start and @p_end will be the global position of the start and end of the WORD. - // @p_start will equals to @p_end if @p_cursor is a space. - static void findCurrentWORD(const QTextCursor &p_cursor, - int &p_start, - int &p_end); - - // Return the leading spaces of @p_block. - static QString fetchIndentSpaces(const QTextBlock &p_block); - - static int fetchIndentation(const QString &p_text); - - static int fetchIndentation(const QTextBlock &p_block); - - // Insert a block above/below current block. Move the cursor to the start of - // the new block after insertion. - static void insertBlock(QTextCursor &p_cursor, - bool p_above); - - // Insert @p_str in the front of each line of @p_text. - static void insertBeforeEachLine(QString &p_text, const QString &p_str); - - // Whether @p_block is empty. - static bool isEmptyBlock(const QTextBlock &p_block); - - static bool isWordSeparator(QChar p_char); - - static bool isSpaceOrWordSeparator(QChar p_char); - - // Remove the fence of fenced code block. - static QString removeCodeBlockFence(const QString &p_text); - -private: - VEditUtils() {} -}; - -#endif // VEDITUTILS_H diff --git a/src/utils/viconutils.cpp b/src/utils/viconutils.cpp deleted file mode 100644 index 081d6556..00000000 --- a/src/utils/viconutils.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "viconutils.h" - -#include -#include -#include -#include - -#include "vutils.h" - -QHash VIconUtils::m_cache; - -VIconUtils::VIconUtils() -{ -} - -QIcon VIconUtils::icon(const QString &p_file, const QString &p_fg, bool p_addDisabled) -{ - const QString key = cacheKey(p_file, p_fg, p_addDisabled); - auto it = m_cache.find(key); - if (it != m_cache.end()) { - return it.value(); - } - - QFileInfo fi(p_file); - bool isSvg = fi.suffix().toLower() == "svg"; - if (p_fg.isEmpty() || !isSvg) { - return QIcon(p_file); - } - - QString content = VUtils::readFileFromDisk(p_file); - Q_ASSERT(!content.isEmpty()); - // Must have a # to avoid fill="none". - QRegExp reg("(\\s|\")(fill|stroke)(:|(=\"))#[^#\"\\s]+"); - if (content.indexOf(reg) == -1) { - return QIcon(p_file); - } - - content.replace(reg, QString("\\1\\2\\3%1").arg(p_fg)); - QByteArray data = content.toLocal8Bit(); - QPixmap pixmap; - pixmap.loadFromData(data, "svg"); - - // Disabled. - QPixmap disabledPixmap; - if (p_addDisabled) { - content.replace(reg, QString("\\1\\2\\3%1").arg(g_palette->color("icon_disabled_fg"))); - data = content.toLocal8Bit(); - disabledPixmap.loadFromData(data, "svg"); - } - - QIcon icon; - icon.addPixmap(pixmap, QIcon::Normal); - if (p_addDisabled) { - icon.addPixmap(disabledPixmap, QIcon::Disabled); - } - - // Add to cache. - m_cache.insert(key, icon); - - return icon; -} diff --git a/src/utils/viconutils.h b/src/utils/viconutils.h deleted file mode 100644 index 4e0d0b73..00000000 --- a/src/utils/viconutils.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef VICONUTILS_H -#define VICONUTILS_H - -#include -#include -#include - -#include "vpalette.h" - -extern VPalette *g_palette; - -class VIconUtils -{ -public: - // Get an icon from @p_file file. May change the foreground of the icon. - static QIcon icon(const QString &p_file, - const QString &p_fg = QString(), - bool p_addDisabled = true); - - static QIcon toolButtonIcon(const QString &p_file, bool p_addDisabled = true) - { - return icon(p_file, g_palette->color("toolbutton_icon_fg"), p_addDisabled); - } - - static QIcon toolButtonDangerIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("toolbutton_icon_danger_fg")); - } - - static QIcon menuIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("menu_icon_fg")); - } - - static QIcon menuDangerIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("menu_icon_danger_fg")); - } - - static QIcon toolBoxIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("toolbox_icon_fg")); - } - - static QIcon toolBoxActiveIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("toolbox_icon_active_fg")); - } - - static QIcon comboBoxIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("combobox_item_icon_fg")); - } - - static QIcon treeViewIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("treeview_item_icon_fg")); - } - - static QIcon tabBarIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("tabbar_icon_fg")); - } - - static QIcon tabBarSpecialIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("tabbar_icon_special_fg")); - } - - static QIcon editWindowCornerIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("editwindow_corner_icon_fg")); - } - - static QIcon editWindowCornerInactiveIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("editwindow_corner_icon_inactive_fg")); - } - - static QIcon titleIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("title_icon_fg")); - } - - static QIcon buttonIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("button_icon_fg")); - } - - static QIcon buttonDangerIcon(const QString &p_file) - { - return icon(p_file, g_palette->color("button_icon_danger_fg")); - } - -private: - VIconUtils(); - - static QString cacheKey(const QString &p_file, const QString &p_fg, bool p_addDisabled) - { - return p_file + "_" + p_fg + "_" + (p_addDisabled ? "1" : "0"); - } - - // file_fg_addDisabled as key. - static QHash m_cache; -}; - -#endif // VICONUTILS_H diff --git a/src/utils/vimnavigationforwidget.cpp b/src/utils/vimnavigationforwidget.cpp deleted file mode 100644 index 34df417e..00000000 --- a/src/utils/vimnavigationforwidget.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "vimnavigationforwidget.h" - -#include -#include -#include -#include - -#include "vutils.h" - -VimNavigationForWidget::VimNavigationForWidget() -{ -} - -bool VimNavigationForWidget::injectKeyPressEventForVim(QWidget *p_widget, - QKeyEvent *p_event, - QWidget *p_escWidget) -{ - Q_ASSERT(p_widget); - - bool ret = false; - int key = p_event->key(); - int modifiers = p_event->modifiers(); - if (!p_escWidget) { - p_escWidget = p_widget; - } - - switch (key) { - case Qt::Key_BracketLeft: - { - if (VUtils::isControlModifierForVim(modifiers)) { - QKeyEvent *escEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, - Qt::NoModifier); - QCoreApplication::postEvent(p_escWidget, escEvent); - ret = true; - } - - break; - } - - case Qt::Key_J: - { - if (VUtils::isControlModifierForVim(modifiers)) { - QKeyEvent *downEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, - Qt::NoModifier); - QCoreApplication::postEvent(p_widget, downEvent); - ret = true; - } - - break; - } - - case Qt::Key_K: - { - if (VUtils::isControlModifierForVim(modifiers)) { - QKeyEvent *upEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, - Qt::NoModifier); - QCoreApplication::postEvent(p_widget, upEvent); - ret = true; - } - - break; - } - - default: - break; - } - - return ret; -} diff --git a/src/utils/vimnavigationforwidget.h b/src/utils/vimnavigationforwidget.h deleted file mode 100644 index 86028e60..00000000 --- a/src/utils/vimnavigationforwidget.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef VIMNAVIGATIONFORWIDGET_H -#define VIMNAVIGATIONFORWIDGET_H - -class QWidget; -class QKeyEvent; - - -// Provide simple Vim mode navigation for widgets. -class VimNavigationForWidget -{ -public: - // Try to handle @p_event and inject proper event instead if it triggers - // Vim operation. - // Return true if @p_event is handled properly. - // @p_escWidget: the widget to accept the ESC event. - static bool injectKeyPressEventForVim(QWidget *p_widget, - QKeyEvent *p_event, - QWidget *p_escWidget = nullptr); - -private: - VimNavigationForWidget(); -}; - -#endif // VIMNAVIGATIONFORWIDGET_H diff --git a/src/utils/vkeyboardlayoutmanager.cpp b/src/utils/vkeyboardlayoutmanager.cpp deleted file mode 100644 index d507b8ec..00000000 --- a/src/utils/vkeyboardlayoutmanager.cpp +++ /dev/null @@ -1,298 +0,0 @@ -#include "vkeyboardlayoutmanager.h" - -#include -#include -#include -#include - -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VKeyboardLayoutManager *VKeyboardLayoutManager::s_inst = NULL; - -VKeyboardLayoutManager *VKeyboardLayoutManager::inst() -{ - if (!s_inst) { - s_inst = new VKeyboardLayoutManager(); - s_inst->update(g_config); - } - - return s_inst; -} - -static QSharedPointer layoutSettings(const VConfigManager *p_config, - bool p_create = false) -{ - QSharedPointer settings; - QString file = p_config->getKeyboardLayoutConfigFilePath(); - if (file.isEmpty()) { - return settings; - } - - if (!QFileInfo::exists(file) && !p_create) { - return settings; - } - - settings.reset(new QSettings(file, QSettings::IniFormat)); - return settings; -} - -static void clearLayoutMapping(const QSharedPointer &p_settings, - const QString &p_name) -{ - p_settings->beginGroup(p_name); - p_settings->remove(""); - p_settings->endGroup(); -} - -static QHash readLayoutMappingInternal(const QSharedPointer &p_settings, - const QString &p_name) -{ - QHash mappings; - - p_settings->beginGroup(p_name); - QStringList keys = p_settings->childKeys(); - for (auto const & key : keys) { - if (key.isEmpty()) { - continue; - } - - bool ok; - int keyNum = key.toInt(&ok); - if (!ok) { - qWarning() << "readLayoutMappingInternal() skip bad key" << key << "in layout" << p_name; - continue; - } - - int valNum = p_settings->value(key).toInt(); - mappings.insert(keyNum, valNum); - } - - p_settings->endGroup(); - - return mappings; -} - -static bool writeLayoutMapping(const QSharedPointer &p_settings, - const QString &p_name, - const QHash &p_mappings) -{ - clearLayoutMapping(p_settings, p_name); - - p_settings->beginGroup(p_name); - for (auto it = p_mappings.begin(); it != p_mappings.end(); ++it) { - p_settings->setValue(QString::number(it.key()), it.value()); - } - p_settings->endGroup(); - - return true; -} - -void VKeyboardLayoutManager::update(VConfigManager *p_config) -{ - m_layout.clear(); - - m_layout.m_name = p_config->getKeyboardLayout(); - if (m_layout.m_name.isEmpty()) { - // No mapping. - return; - } - - qDebug() << "using keyboard layout mapping" << m_layout.m_name; - - auto settings = layoutSettings(p_config); - if (settings.isNull()) { - return; - } - - m_layout.setMapping(readLayoutMappingInternal(settings, m_layout.m_name)); -} - -void VKeyboardLayoutManager::update() -{ - inst()->update(g_config); -} - -const VKeyboardLayoutManager::Layout &VKeyboardLayoutManager::currentLayout() -{ - return inst()->m_layout; -} - -static QStringList readAvailableLayoutMappings(const QSharedPointer &p_settings) -{ - QString fullKey("global/layout_mappings"); - return p_settings->value(fullKey).toStringList(); -} - -static void writeAvailableLayoutMappings(const QSharedPointer &p_settings, - const QStringList &p_layouts) -{ - QString fullKey("global/layout_mappings"); - return p_settings->setValue(fullKey, p_layouts); -} - -QStringList VKeyboardLayoutManager::availableLayouts() -{ - QStringList layouts; - auto settings = layoutSettings(g_config); - if (settings.isNull()) { - return layouts; - } - - layouts = readAvailableLayoutMappings(settings); - return layouts; -} - -void VKeyboardLayoutManager::setCurrentLayout(const QString &p_name) -{ - auto mgr = inst(); - if (mgr->m_layout.m_name == p_name) { - return; - } - - g_config->setKeyboardLayout(p_name); - mgr->update(g_config); -} - -static bool isValidLayoutName(const QString &p_name) -{ - return !p_name.isEmpty() && p_name.toLower() != "global"; -} - -bool VKeyboardLayoutManager::addLayout(const QString &p_name) -{ - Q_ASSERT(isValidLayoutName(p_name)); - - auto settings = layoutSettings(g_config, true); - if (settings.isNull()) { - qWarning() << "fail to open keyboard layout QSettings"; - return false; - } - - QStringList layouts = readAvailableLayoutMappings(settings); - if (layouts.contains(p_name)) { - qWarning() << "Keyboard layout mapping" << p_name << "already exists"; - return false; - } - - layouts.append(p_name); - writeAvailableLayoutMappings(settings, layouts); - - clearLayoutMapping(settings, p_name); - return true; -} - -bool VKeyboardLayoutManager::removeLayout(const QString &p_name) -{ - Q_ASSERT(isValidLayoutName(p_name)); - - auto settings = layoutSettings(g_config, true); - if (settings.isNull()) { - qWarning() << "fail to open keyboard layout QSettings"; - return false; - } - - QStringList layouts = readAvailableLayoutMappings(settings); - int idx = layouts.indexOf(p_name); - if (idx == -1) { - return true; - } - - layouts.removeAt(idx); - writeAvailableLayoutMappings(settings, layouts); - - clearLayoutMapping(settings, p_name); - return true; -} - -bool VKeyboardLayoutManager::renameLayout(const QString &p_name, const QString &p_newName) -{ - Q_ASSERT(isValidLayoutName(p_name)); - Q_ASSERT(isValidLayoutName(p_newName)); - - auto settings = layoutSettings(g_config, true); - if (settings.isNull()) { - qWarning() << "fail to open keyboard layout QSettings"; - return false; - } - - QStringList layouts = readAvailableLayoutMappings(settings); - int idx = layouts.indexOf(p_name); - if (idx == -1) { - qWarning() << "fail to find keyboard layout mapping" << p_name << "to rename"; - return false; - } - - if (layouts.indexOf(p_newName) != -1) { - qWarning() << "keyboard layout mapping" << p_newName << "already exists"; - return false; - } - - auto content = readLayoutMappingInternal(settings, p_name); - // Copy the group. - if (!writeLayoutMapping(settings, p_newName, content)) { - qWarning() << "fail to write new layout mapping" << p_newName; - return false; - } - - clearLayoutMapping(settings, p_name); - - layouts.replace(idx, p_newName); - writeAvailableLayoutMappings(settings, layouts); - - // Check current layout. - if (g_config->getKeyboardLayout() == p_name) { - Q_ASSERT(inst()->m_layout.m_name == p_name); - g_config->setKeyboardLayout(p_newName); - inst()->m_layout.m_name = p_newName; - } - - return true; -} - -QHash VKeyboardLayoutManager::readLayoutMapping(const QString &p_name) -{ - QHash mappings; - if (p_name.isEmpty()) { - return mappings; - } - - auto settings = layoutSettings(g_config); - if (settings.isNull()) { - return mappings; - } - - return readLayoutMappingInternal(settings, p_name); -} - -bool VKeyboardLayoutManager::updateLayout(const QString &p_name, - const QHash &p_mapping) -{ - Q_ASSERT(isValidLayoutName(p_name)); - - auto settings = layoutSettings(g_config, true); - if (settings.isNull()) { - qWarning() << "fail to open keyboard layout QSettings"; - return false; - } - - QStringList layouts = readAvailableLayoutMappings(settings); - int idx = layouts.indexOf(p_name); - if (idx == -1) { - qWarning() << "fail to find keyboard layout mapping" << p_name << "to update"; - return false; - } - - if (!writeLayoutMapping(settings, p_name, p_mapping)) { - qWarning() << "fail to write layout mapping" << p_name; - return false; - } - - // Check current layout. - if (inst()->m_layout.m_name == p_name) { - inst()->m_layout.setMapping(p_mapping); - } - - return true; -} diff --git a/src/utils/vkeyboardlayoutmanager.h b/src/utils/vkeyboardlayoutmanager.h deleted file mode 100644 index 162060ca..00000000 --- a/src/utils/vkeyboardlayoutmanager.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef VKEYBOARDLAYOUTMANAGER_H -#define VKEYBOARDLAYOUTMANAGER_H - -#include -#include -#include - -class VConfigManager; - -class VKeyboardLayoutManager -{ -public: - struct Layout - { - void clear() - { - m_name.clear(); - m_mapping.clear(); - } - - void setMapping(const QHash &p_mapping) - { - m_mapping.clear(); - - for (auto it = p_mapping.begin(); it != p_mapping.end(); ++it) { - m_mapping.insert(it.value(), it.key()); - } - } - - QString m_name; - // Reversed mapping. - QHash m_mapping; - }; - - static void update(); - - static const VKeyboardLayoutManager::Layout ¤tLayout(); - - static void setCurrentLayout(const QString &p_name); - - static QStringList availableLayouts(); - - static bool addLayout(const QString &p_name); - - static bool removeLayout(const QString &p_name); - - static bool renameLayout(const QString &p_name, const QString &p_newName); - - static bool updateLayout(const QString &p_name, const QHash &p_mapping); - - static QHash readLayoutMapping(const QString &p_name); - - static int mapKey(int p_key); - -private: - VKeyboardLayoutManager() {} - - static VKeyboardLayoutManager *inst(); - - void update(VConfigManager *p_config); - - Layout m_layout; - - static VKeyboardLayoutManager *s_inst; -}; - -inline int VKeyboardLayoutManager::mapKey(int p_key) -{ - const Layout &layout = inst()->m_layout; - if (!layout.m_name.isEmpty()) { - auto it = layout.m_mapping.find(p_key); - if (it != layout.m_mapping.end()) { - return it.value(); - } - } - - return p_key; -} -#endif // VKEYBOARDLAYOUTMANAGER_H diff --git a/src/utils/vmetawordmanager.cpp b/src/utils/vmetawordmanager.cpp deleted file mode 100644 index 4ddec9dc..00000000 --- a/src/utils/vmetawordmanager.cpp +++ /dev/null @@ -1,703 +0,0 @@ -#include "vmetawordmanager.h" - -#include -#include -#include -#include -#include - -#include "vconfigmanager.h" -#include "vmainwindow.h" -#include "vnotefile.h" -#include "vnotebook.h" - -extern VConfigManager *g_config; - -extern VMainWindow *g_mainWin; - - -// Used as the function template for some date/time related meta words. -static QString formattedDateTime(const VMetaWord *p_metaWord, - const QString &p_format) -{ - return p_metaWord->getManager()->getDateTime().toString(p_format); -} - -static QString allMetaWordsInfo(const VMetaWord *p_metaWord) -{ - QString msg = QObject::tr("All magic words:"); - - const VMetaWordManager *mgr = p_metaWord->getManager(); - QList keys = mgr->getAllMetaWords().keys(); - keys.sort(Qt::CaseInsensitive); - - for (auto const & key : keys) { - const VMetaWord *word = mgr->findMetaWord(key); - Q_ASSERT(word); - msg += QString("\n%1:\t%2").arg(word->getWord()).arg(word->getDefinition()); - } - - QWidget *focusWid = QApplication::focusWidget(); - if (focusWid) { - QPoint pos = focusWid->mapToGlobal(QPoint(0, focusWid->height())); - QToolTip::showText(pos, msg, focusWid); - } - - // Just return the same word. - return QString("%1help%1").arg(VMetaWordManager::c_delimiter); -} - -const QChar VMetaWordManager::c_delimiter = '%'; - -VMetaWordManager::VMetaWordManager(QObject *p_parent) - : QObject(p_parent), - m_initialized(false) -{ -} - -void VMetaWordManager::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - using namespace std::placeholders; - - // %d%. - addMetaWord(MetaWordType::FunctionBased, - "d", - tr("the day as number without a leading zero (`1` to `31`)"), - std::bind(formattedDateTime, _1, "d")); - - // %dd%. - addMetaWord(MetaWordType::FunctionBased, - "dd", - tr("the day as number with a leading zero (`01` to `31`)"), - std::bind(formattedDateTime, _1, "dd")); - - // %ddd%. - addMetaWord(MetaWordType::FunctionBased, - "ddd", - tr("the abbreviated localized day name (e.g. `Mon` to `Sun`)"), - std::bind(formattedDateTime, _1, "ddd")); - - // %dddd%. - addMetaWord(MetaWordType::FunctionBased, - "dddd", - tr("the long localized day name (e.g. `Monday` to `Sunday`)"), - std::bind(formattedDateTime, _1, "dddd")); - - // %M%. - addMetaWord(MetaWordType::FunctionBased, - "M", - tr("the month as number without a leading zero (`1` to `12`)"), - std::bind(formattedDateTime, _1, "M")); - - // %MM%. - addMetaWord(MetaWordType::FunctionBased, - "MM", - tr("the month as number with a leading zero (`01` to `12`)"), - std::bind(formattedDateTime, _1, "MM")); - - // %MMM%. - addMetaWord(MetaWordType::FunctionBased, - "MMM", - tr("the abbreviated localized month name (e.g. `Jan` to `Dec`)"), - std::bind(formattedDateTime, _1, "MMM")); - - // %MMMM%. - addMetaWord(MetaWordType::FunctionBased, - "MMMM", - tr("the long localized month name (e.g. `January` to `December`)"), - std::bind(formattedDateTime, _1, "MMMM")); - - // %yy%. - addMetaWord(MetaWordType::FunctionBased, - "yy", - tr("the year as two digit number (`00` to `99`)"), - std::bind(formattedDateTime, _1, "yy")); - - // %yyyy%. - addMetaWord(MetaWordType::FunctionBased, - "yyyy", - tr("the year as four digit number"), - std::bind(formattedDateTime, _1, "yyyy")); - - // %h%. - addMetaWord(MetaWordType::FunctionBased, - "h", - tr("the hour without a leading zero (`0` to `23` or `1` to `12` if AM/PM display)"), - std::bind(formattedDateTime, _1, "h")); - - // %hh%. - addMetaWord(MetaWordType::FunctionBased, - "hh", - tr("the hour with a leading zero (`00` to `23` or `01` to `12` if AM/PM display)"), - std::bind(formattedDateTime, _1, "hh")); - - // %H%. - addMetaWord(MetaWordType::FunctionBased, - "H", - tr("the hour without a leading zero (`0` to `23` even with AM/PM display)"), - std::bind(formattedDateTime, _1, "H")); - - // %HH%. - addMetaWord(MetaWordType::FunctionBased, - "HH", - tr("the hour with a leading zero (`00` to `23` even with AM/PM display)"), - std::bind(formattedDateTime, _1, "HH")); - - // %m%. - addMetaWord(MetaWordType::FunctionBased, - "m", - tr("the minute without a leading zero (`0` to `59`)"), - std::bind(formattedDateTime, _1, "m")); - - // %mm%. - addMetaWord(MetaWordType::FunctionBased, - "mm", - tr("the minute with a leading zero (`00` to `59`)"), - std::bind(formattedDateTime, _1, "mm")); - - // %s%. - addMetaWord(MetaWordType::FunctionBased, - "s", - tr("the second without a leading zero (`0` to `59`)"), - std::bind(formattedDateTime, _1, "s")); - - // %ss%. - addMetaWord(MetaWordType::FunctionBased, - "ss", - tr("the second with a leading zero (`00` to `59`)"), - std::bind(formattedDateTime, _1, "ss")); - - // %z%. - addMetaWord(MetaWordType::FunctionBased, - "z", - tr("the milliseconds without leading zeroes (`0` to `999`)"), - std::bind(formattedDateTime, _1, "z")); - - // %zzz%. - addMetaWord(MetaWordType::FunctionBased, - "zzz", - tr("the milliseconds with leading zeroes (`000` to `999`)"), - std::bind(formattedDateTime, _1, "zzz")); - - // %AP%. - addMetaWord(MetaWordType::FunctionBased, - "AP", - tr("use AM/PM display (`AM` or `PM`)"), - std::bind(formattedDateTime, _1, "AP")); - - // %A%. - addMetaWord(MetaWordType::FunctionBased, - "A", - tr("use AM/PM display (`AM` or `PM`)"), - std::bind(formattedDateTime, _1, "A")); - - // %ap%. - addMetaWord(MetaWordType::FunctionBased, - "ap", - tr("use am/pm display (`am` or `pm`)"), - std::bind(formattedDateTime, _1, "ap")); - - // %a%. - addMetaWord(MetaWordType::FunctionBased, - "a", - tr("use am/pm display (`am` or `pm`)"), - std::bind(formattedDateTime, _1, "a")); - - // %t%. - addMetaWord(MetaWordType::FunctionBased, - "t", - tr("the timezone (e.g. `CEST`)"), - std::bind(formattedDateTime, _1, "t")); - - // %random%. - addMetaWord(MetaWordType::FunctionBased, - "random", - tr("a random number"), - [](const VMetaWord *) { - return QString::number(qrand()); - }); - - // %random_d%. - addMetaWord(MetaWordType::Dynamic, - "random_d", - tr("dynamic version of `random`"), - [](const VMetaWord *) { - return QString::number(qrand()); - }); - - // %date%. - addMetaWord(MetaWordType::Compound, - "date", - QString("%1yyyy%1-%1MM%1-%1dd%1").arg(c_delimiter)); - - // %da%. - addMetaWord(MetaWordType::Compound, - "da", - QString("%1yyyy%1%1MM%1%1dd%1").arg(c_delimiter)); - - // %time%. - addMetaWord(MetaWordType::Compound, - "time", - QString("%1hh%1:%1mm%1:%1ss%1").arg(c_delimiter)); - - // %datetime%. - addMetaWord(MetaWordType::Compound, - "datetime", - QString("%1date%1 %1time%1").arg(c_delimiter)); - - // %dt%. - addMetaWord(MetaWordType::Compound, - "dt", - QString("%1da%1-%1time%1").arg(c_delimiter)); - - // %note%. - addMetaWord(MetaWordType::FunctionBased, - "note", - tr("name of current note"), - [](const VMetaWord *) { - const VFile *file = g_mainWin->getCurrentFile(); - if (file) { - return file->getName(); - } - - return QString(); - }); - - // %no%. - addMetaWord(MetaWordType::FunctionBased, - "no", - tr("complete base name of current note"), - [](const VMetaWord *) { - const VFile *file = g_mainWin->getCurrentFile(); - if (file) { - return QFileInfo(file->getName()).completeBaseName(); - } - - return QString(); - }); - - // %att%. - addMetaWord(MetaWordType::FunctionBased, - "att", - tr("relative path of current note's attachment folder"), - [](const VMetaWord *) { - const VFile *file = g_mainWin->getCurrentFile(); - if (file && file->getType() == FileType::Note) { - const VNoteFile *nfile = static_cast(file); - const QString &folder = nfile->getAttachmentFolder(); - if (!folder.isEmpty()) { - return nfile->getNotebook()->getAttachmentFolder() - + "/" - + folder; - } - } - - return QString(); - }); - - // %w% - addMetaWord(MetaWordType::FunctionBased, - "w", - tr("the week number (`1` to `53`)"), - [](const VMetaWord *p_metaWord) { - return QString::number(p_metaWord->getManager()->getDateTime().date().weekNumber()); - }); - - // Custom meta words. - initCustomMetaWords(); - - // %help% to print all metaword info. - addMetaWord(MetaWordType::FunctionBased, - "help", - tr("information about all defined magic words"), - allMetaWordsInfo); -} - -void VMetaWordManager::initCustomMetaWords() -{ - QVector words = g_config->getCustomMagicWords(); - for (auto const & item : words) { - addMetaWord(MetaWordType::Compound, - item.m_name, - item.m_definition); - } -} - -QString VMetaWordManager::evaluate(const QString &p_text, - const QHash &p_overriddenWords) const -{ - if (p_text.isEmpty()) { - return p_text; - } - - const_cast(this)->init(); - - // Update datetime for later parse. - const_cast(this)->m_dateTime = QDateTime::currentDateTime(); - - // Update overriden table. - const_cast(this)->m_overriddenWords = p_overriddenWords; - - // Treat the text as a Compound meta word. - const QString tmpWord("vnote_tmp_metaword"); - Q_ASSERT(!contains(tmpWord)); - VMetaWord metaWord(this, - MetaWordType::Compound, - tmpWord, - p_text, - nullptr, - true); - - QString val; - if (metaWord.isValid()) { - val = metaWord.evaluate(); - } else { - val = p_text; - } - - const_cast(this)->m_overriddenWords.clear(); - - return val; -} - -bool VMetaWordManager::contains(const QString &p_word) const -{ - const_cast(this)->init(); - - return m_metaWords.contains(p_word); -} - -const VMetaWord *VMetaWordManager::findMetaWord(const QString &p_word) const -{ - const_cast(this)->init(); - - auto it = m_metaWords.find(p_word); - if (it != m_metaWords.end()) { - return &it.value(); - } - - return NULL; -} - -void VMetaWordManager::addMetaWord(MetaWordType p_type, - const QString &p_word, - const QString &p_definition, - MetaWordFunc p_function) -{ - if (p_word.isEmpty() || contains(p_word)) { - return; - } - - VMetaWord metaWord(this, - p_type, - p_word, - p_definition, - p_function); - - if (metaWord.isValid()) { - m_metaWords.insert(p_word, metaWord); - qDebug() << QString("MetaWord %1%2%1[%3] added") - .arg(c_delimiter).arg(p_word).arg(p_definition); - } -} - -bool VMetaWordManager::findOverriddenValue(const QString &p_word, - QString &p_value) const -{ - const_cast(this)->init(); - - auto it = m_overriddenWords.find(p_word); - if (it != m_overriddenWords.end()) { - p_value = it.value(); - return true; - } - - return false; -} - -VMetaWord::VMetaWord(const VMetaWordManager *p_manager, - MetaWordType p_type, - const QString &p_word, - const QString &p_definition, - MetaWordFunc p_function, - bool p_allowAllSpaces) - : m_manager(p_manager), - m_type(p_type), - m_word(p_word), - m_definition(p_definition), - m_valid(false) -{ - m_function = p_function; - - if (checkType(MetaWordType::Simple) - || checkType(MetaWordType::Compound)) { - Q_ASSERT(!m_function); - } else { - Q_ASSERT(m_function); - } - - checkAndParseDefinition(p_allowAllSpaces); -} - -bool VMetaWord::checkType(MetaWordType p_type) -{ - return m_type == p_type; -} - -void VMetaWord::checkAndParseDefinition(bool p_allowAllSpaces) -{ - if (m_word.contains(VMetaWordManager::c_delimiter)) { - m_valid = false; - return; - } - - m_valid = true; - m_tokens.clear(); - - // We do not accept \n and \t in the definition. - QRegExp defReg("[\\S ]*"); - if (!defReg.exactMatch(m_definition) && !p_allowAllSpaces) { - m_valid = false; - return; - } - - if (checkType(MetaWordType::FunctionBased) - || checkType(MetaWordType::Dynamic)) { - if (!m_function) { - m_valid = false; - } - } else if (checkType(MetaWordType::Compound)) { - m_tokens = parseToTokens(m_definition); - if (m_tokens.isEmpty()) { - m_valid = false; - return; - } - - for (auto const & to : m_tokens) { - if (to.isMetaWord()) { - if (!m_manager->contains(to.m_value)) { - // Dependency not defined. - m_valid = false; - break; - } - } - } - } -} - -bool VMetaWord::isValid() const -{ - return m_valid; -} - -QString VMetaWord::evaluate() const -{ - Q_ASSERT(m_valid); - - // Check overridden table first. - QString overriddenVal; - if (m_manager->findOverriddenValue(m_word, overriddenVal)) { - return overriddenVal; - } - - switch (m_type) { - case MetaWordType::Simple: - return m_definition; - - case MetaWordType::FunctionBased: - case MetaWordType::Dynamic: - return m_function(this); - - case MetaWordType::Compound: - { - QHash cache; - return evaluateTokens(m_tokens, cache); - } - - default: - return ""; - } -} - -MetaWordType VMetaWord::getType() const -{ - return m_type; -} - -const QString &VMetaWord::getWord() const -{ - return m_word; -} - -const QString &VMetaWord::getDefinition() const -{ - return m_definition; -} - -const VMetaWordManager *VMetaWord::getManager() const -{ - return m_manager; -} - - -QString VMetaWord::toString() const -{ - QChar typeChar('U'); - switch (m_type) { - case MetaWordType::Simple: - typeChar = 'S'; - break; - - case MetaWordType::FunctionBased: - typeChar = 'F'; - break; - - case MetaWordType::Dynamic: - typeChar = 'D'; - break; - - case MetaWordType::Compound: - typeChar = 'C'; - break; - - default: - break; - } - - return QString("%1%2%1[%3]: %4").arg(VMetaWordManager::c_delimiter) - .arg(m_word) - .arg(typeChar) - .arg(m_definition); -} - -QVector VMetaWord::parseToTokens(const QString &p_text) -{ - QVector tokens; - - TokenType type = TokenType::Raw; - QString value; - value.reserve(p_text.size()); - for (int idx = 0; idx < p_text.size(); ++idx) { - const QChar &ch = p_text[idx]; - if (ch == VMetaWordManager::c_delimiter) { - // Check if it is single or double. - int next = idx + 1; - if (next == p_text.size() - || p_text[next] != VMetaWordManager::c_delimiter) { - // Single delimiter. - if (type == TokenType::Raw) { - // End of a raw token, begin of a MetaWord token. - if (!value.isEmpty()) { - tokens.push_back(Token(type, value)); - } - - type = TokenType::MetaWord; - } else { - // End of a MetaWord token, begin of a Raw token. - Q_ASSERT(!value.isEmpty()); - - tokens.push_back(Token(type, value)); - type = TokenType::Raw; - } - - value.clear(); - } else { - // Double delimiter. - // If now is parsing a MetaWord token, treat the first delimiter - // as the end of a token. - // Otherwise, store one single delimiter in value and skip next char. - if (type == TokenType::MetaWord) { - Q_ASSERT(!value.isEmpty()); - tokens.push_back(Token(type, value)); - type = TokenType::Raw; - value.clear(); - } else { - value.push_back(ch); - ++idx; - } - } - } else { - // Push ch in value. - value.push_back(ch); - } - } - - if (!value.isEmpty()) { - if (type == TokenType::Raw) { - tokens.push_back(Token(type, value)); - } else { - // An imcomplete metaword token. - // Treat it as raw. - tokens.push_back(Token(TokenType::Raw, "%" + value)); - } - - value.clear(); - } - - return tokens; -} - -QString VMetaWord::evaluateTokens(const QVector &p_tokens, - QHash &p_cache) const -{ - QString val; - - for (auto const & to : p_tokens) { - switch (to.m_type) { - case TokenType::Raw: - val += to.m_value; - break; - - case TokenType::MetaWord: - { - const VMetaWord *metaWord = m_manager->findMetaWord(to.m_value); - if (!metaWord) { - // Invalid meta word. Treat it as literal value. - val += VMetaWordManager::c_delimiter + to.m_value + VMetaWordManager::c_delimiter; - break; - } - - QString wordVal; - switch (metaWord->getType()) { - case MetaWordType::FunctionBased: - { - auto it = p_cache.find(metaWord->getWord()); - if (it != p_cache.end()) { - // Find it in the cache. - wordVal = it.value(); - } else { - // First evaluate this meta word. - wordVal = metaWord->evaluate(); - p_cache.insert(metaWord->getWord(), wordVal); - } - - break; - } - - case MetaWordType::Compound: - wordVal = evaluateTokens(metaWord->m_tokens, p_cache); - break; - - default: - wordVal = metaWord->evaluate(); - break; - } - - val += wordVal; - break; - } - - default: - Q_ASSERT(false); - break; - } - } - - return val; -} diff --git a/src/utils/vmetawordmanager.h b/src/utils/vmetawordmanager.h deleted file mode 100644 index c7995f24..00000000 --- a/src/utils/vmetawordmanager.h +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef VMETAWORDMANAGER_H -#define VMETAWORDMANAGER_H - -#include - -#include -#include -#include -#include -#include -#include - - -enum class MetaWordType -{ - // Definition is plain text. - Simple = 0, - - // Definition is a function call to get the value. - FunctionBased, - - // Like FunctionBased, but should re-evaluate the value for each occurence. - Dynamic, - - // Consists of other meta words. - Compound, - - Invalid -}; - -// We call meta word "magic word" in user interaction. -struct VMagicWord -{ - QString m_name; - QString m_definition; -}; - -class VMetaWordManager; -class VMetaWord; - -typedef std::function MetaWordFunc; - -// A Meta Word is surrounded by %. -// - Use %% for an escaped %; -// - Built-in or user-defined; -// - A meta word could contain other meta words as definition. -class VMetaWord -{ -public: - VMetaWord(const VMetaWordManager *p_manager, - MetaWordType p_type, - const QString &p_word, - const QString &p_definition, - MetaWordFunc p_function = nullptr, - bool p_allowAllSpaces = false); - - bool isValid() const; - - QString evaluate() const; - - MetaWordType getType() const; - - const QString &getWord() const; - - const QString &getDefinition() const; - - const VMetaWordManager *getManager() const; - - QString toString() const; - - enum class TokenType - { - Raw = 0, - MetaWord - }; - - struct Token - { - Token() - : m_type(TokenType::Raw) - { - } - - Token(VMetaWord::TokenType p_type, const QString &p_value) - : m_type(p_type), - m_value(p_value) - { - } - - QString toString() const - { - return QString("token %1[%2]").arg(m_type == TokenType::Raw - ? "Raw" : "MetaWord") - .arg(m_value); - } - - bool isRaw() const - { - return m_type == TokenType::Raw; - } - - bool isMetaWord() const - { - return m_type == TokenType::MetaWord; - } - - TokenType m_type; - - // For Raw type, m_value is the raw string of this token; - // For MetaWord type, m_value is the word of the meta word pointed to by - // this token. - QString m_value; - }; - -private: - // Check if m_type is @p_type. - bool checkType(MetaWordType p_type); - - // Parse children word from definition. - // Children word MUST be defined in m_manager already. - // @p_allowAllSpaces: if true then we allow all spaces including \n and \t - // to appear in the definition. - void checkAndParseDefinition(bool p_allowAllSpaces); - - // Parse @p_text to a list of tokens. - static QVector parseToTokens(const QString &p_text); - - // Used for Compound meta word with cache @p_cache. - // @p_cache: value cache for FunctionBased Token. - // For a meta word occuring more than once, we should evaluate it once for - // FunctionBased meta word. - QString evaluateTokens(const QVector &p_tokens, - QHash &p_cache) const; - - const VMetaWordManager *m_manager; - - MetaWordType m_type; - - // Word could contains spaces but no %. - QString m_word; - - // For Simple/Compound meta word, this contains the definition; - // For FunctionBased/Dynamic meta word, this makes no sense and is used - // for description. - QString m_definition; - - // For FunctionBased and Dynamic meta word. - MetaWordFunc m_function; - - bool m_valid; - - // Tokens used for Compound meta word. - QVector m_tokens; -}; - - -// Manager of meta word. -class VMetaWordManager : public QObject -{ - Q_OBJECT -public: - explicit VMetaWordManager(QObject *p_parent = nullptr); - - // Expand meta words in @p_text and return the expanded text. - // @p_overriddenWords: a table containing overridden meta words. - QString evaluate(const QString &p_text, - const QHash &p_overriddenWords = QHash()) const; - - const VMetaWord *findMetaWord(const QString &p_word) const; - - bool contains(const QString &p_word) const; - - const QDateTime &getDateTime() const; - - const QHash &getAllMetaWords() const; - - // Find @p_word in the overridden table. - // Return true if found and set @p_value to the overridden value. - bool findOverriddenValue(const QString &p_word, QString &p_value) const; - - // % by default. - static const QChar c_delimiter; - -private: - void init(); - - void addMetaWord(MetaWordType p_type, - const QString &p_word, - const QString &p_definition, - MetaWordFunc p_function = nullptr); - - void initCustomMetaWords(); - - bool m_initialized; - - // Map using word as key. - QHash m_metaWords; - - // Used for data/time related evaluate. - // Will be updated before each evaluation. - QDateTime m_dateTime; - - // Overridden table containing meta words with their designated value. - // Will be updated before each evaluation and clear after the evaluation. - QHash m_overriddenWords; -}; - -inline const QDateTime &VMetaWordManager::getDateTime() const -{ - return m_dateTime; -} - -inline const QHash &VMetaWordManager::getAllMetaWords() const -{ - const_cast(this)->init(); - - return m_metaWords; -} - -#endif // VMETAWORDMANAGER_H diff --git a/src/utils/vpreviewutils.cpp b/src/utils/vpreviewutils.cpp deleted file mode 100644 index 94445516..00000000 --- a/src/utils/vpreviewutils.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "vpreviewutils.h" - -#include -#include - -QTextImageFormat VPreviewUtils::fetchFormatFromPosition(QTextDocument *p_doc, - int p_position) -{ - if (p_doc->characterAt(p_position) != QChar::ObjectReplacementCharacter) { - return QTextImageFormat(); - } - - QTextCursor cursor(p_doc); - cursor.setPosition(p_position); - if (cursor.atBlockEnd()) { - return QTextImageFormat(); - } - - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - - return cursor.charFormat().toImageFormat(); -} - -PreviewImageType VPreviewUtils::getPreviewImageType(const QTextImageFormat &p_format) -{ - Q_ASSERT(p_format.isValid()); - bool ok = true; - int type = p_format.property((int)ImageProperty::ImageType).toInt(&ok); - if (ok) { - return (PreviewImageType)type; - } else { - return PreviewImageType::Invalid; - } -} - -PreviewImageSource VPreviewUtils::getPreviewImageSource(const QTextImageFormat &p_format) -{ - Q_ASSERT(p_format.isValid()); - bool ok = true; - int src = p_format.property((int)ImageProperty::ImageSource).toInt(&ok); - if (ok) { - return (PreviewImageSource)src; - } else { - return PreviewImageSource::Invalid; - } -} - -long long VPreviewUtils::getPreviewImageID(const QTextImageFormat &p_format) -{ - if (!p_format.isValid()) { - return -1; - } - - bool ok = true; - long long id = p_format.property((int)ImageProperty::ImageID).toLongLong(&ok); - if (ok) { - return id; - } else { - return -1; - } -} diff --git a/src/utils/vpreviewutils.h b/src/utils/vpreviewutils.h deleted file mode 100644 index 3cb2a0e6..00000000 --- a/src/utils/vpreviewutils.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef VPREVIEWUTILS_H -#define VPREVIEWUTILS_H - -#include -#include "vconstants.h" - -class QTextDocument; - -class VPreviewUtils -{ -public: - // Fetch the text image format from an image preview position. - static QTextImageFormat fetchFormatFromPosition(QTextDocument *p_doc, - int p_position); - - static PreviewImageType getPreviewImageType(const QTextImageFormat &p_format); - - static PreviewImageSource getPreviewImageSource(const QTextImageFormat &p_format); - - // Fetch the ImageID from an image format. - // Returns -1 if not valid. - static long long getPreviewImageID(const QTextImageFormat &p_format); - -private: - VPreviewUtils() {} -}; - -#endif // VPREVIEWUTILS_H diff --git a/src/utils/vprocessutils.cpp b/src/utils/vprocessutils.cpp deleted file mode 100644 index 9b358857..00000000 --- a/src/utils/vprocessutils.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "vprocessutils.h" - -#include -#include -#include - -int VProcessUtils::startProcess(const QString &p_program, - const QStringList &p_args, - const QByteArray &p_in, - int &p_exitCode, - QByteArray &p_out, - QByteArray &p_err) -{ - QScopedPointer process(new QProcess()); - process->start(p_program, p_args); - return startProcess(process.data(), - p_in, - p_exitCode, - p_out, - p_err); -} - -int VProcessUtils::startProcess(QProcess *p_process, - const QByteArray &p_in, - int &p_exitCode, - QByteArray &p_out, - QByteArray &p_err) -{ - int ret = 0; - if (!p_in.isEmpty()) { - if (p_process->write(p_in) == -1) { - p_process->closeWriteChannel(); - qWarning() << "fail to write to QProcess:" << p_process->errorString(); - return -1; - } else { - p_process->closeWriteChannel(); - } - } - - bool finished = false; - bool started = false; - while (true) { - QProcess::ProcessError err = p_process->error(); - if (err == QProcess::FailedToStart - || err == QProcess::Crashed) { - if (err == QProcess::FailedToStart) { - ret = -2; - } else { - ret = -1; - } - - break; - } - - if (started) { - if (p_process->state() == QProcess::NotRunning) { - finished = true; - } - } else { - if (p_process->state() != QProcess::NotRunning) { - started = true; - } - } - - if (p_process->waitForFinished(500)) { - // Finished. - finished = true; - } - - if (finished) { - QProcess::ExitStatus sta = p_process->exitStatus(); - if (sta == QProcess::CrashExit) { - ret = -1; - break; - } - - p_exitCode = p_process->exitCode(); - break; - } - } - - p_out = p_process->readAllStandardOutput(); - p_err = p_process->readAllStandardError(); - - return ret; -} - -int VProcessUtils::startProcess(const QString &p_program, - const QStringList &p_args, - int &p_exitCode, - QByteArray &p_out, - QByteArray &p_err) -{ - return startProcess(p_program, - p_args, - QByteArray(), - p_exitCode, - p_out, - p_err); -} - -int VProcessUtils::startProcess(const QString &p_cmd, - const QByteArray &p_in, - int &p_exitCode, - QByteArray &p_out, - QByteArray &p_err) -{ - QScopedPointer process(new QProcess()); - process->start(p_cmd); - return startProcess(process.data(), - p_in, - p_exitCode, - p_out, - p_err); -} diff --git a/src/utils/vprocessutils.h b/src/utils/vprocessutils.h deleted file mode 100644 index cb7924f4..00000000 --- a/src/utils/vprocessutils.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef VPROCESSUTILS_H -#define VPROCESSUTILS_H - -#include -#include - -class QProcess; - -class VProcessUtils -{ -public: - // p_exitCode: exit code of the program, valid only when returning 0. - // 0: execute successfully; - // -1: crashed; - // -2: fail to start. - static int startProcess(const QString &p_program, - const QStringList &p_args, - int &p_exitCode, - QByteArray &p_out, - QByteArray &p_err); - - static int startProcess(const QString &p_program, - const QStringList &p_args, - const QByteArray &p_in, - int &p_exitCode, - QByteArray &p_out, - QByteArray &p_err); - - static int startProcess(const QString &p_cmd, - const QByteArray &p_in, - int &p_exitCode, - QByteArray &p_out, - QByteArray &p_err); - -private: - VProcessUtils() {} - - static int startProcess(QProcess *p_process, - const QByteArray &p_in, - int &p_exitCode, - QByteArray &p_out, - QByteArray &p_err); -}; - -#endif // VPROCESSUTILS_H diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp deleted file mode 100644 index f8d9ce74..00000000 --- a/src/utils/vutils.cpp +++ /dev/null @@ -1,1896 +0,0 @@ -#include "vutils.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vorphanfile.h" -#include "vnote.h" -#include "vnotebook.h" -#include "vpreviewpage.h" -#include "pegparser.h" -#include "widgets/vcombobox.h" - -extern VConfigManager *g_config; - -QVector> VUtils::s_availableLanguages; - -const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\[\\]]*)\\]" - "\\(\\s*" - "([^\\)\"'\\s]+)" - "(\\s*(\"[^\"\\)\\n\\r]*\")|('[^'\\)\\n\\r]*'))?" - "(\\s*=(\\d*)x(\\d*))?" - "\\s*\\)"); - -const QString VUtils::c_imageTitleRegExp = QString("[^\\[\\]]*"); - -const QString VUtils::c_linkRegExp = QString("\\[([^\\]]*)\\]" - "\\(\\s*(\\S+)" - "(?:\\s+((\"[^\"\\n\\r]*\")" - "|('[^'\\n\\r]*')))?\\s*" - "\\)"); - -const QString VUtils::c_fileNameRegExp = QString("(?:[^\\\\/:\\*\\?\"<>\\|\\s]| )*"); - -const QString VUtils::c_fencedCodeBlockStartRegExp = QString("^(\\s*)([`~])\\2{2}((?:(?!\\2)[^\\r\\n])*)$"); - -const QString VUtils::c_fencedCodeBlockEndRegExp = QString("^(\\s*)([`~])\\2{2}\\s*$"); - -const QString VUtils::c_previewImageBlockRegExp = QString("[\\n|^][ |\\t]*\\xfffc[ |\\t]*(?=\\n)"); - -const QString VUtils::c_headerRegExp = QString("^(#{1,6})\\s+(((\\d+\\.)+(?=\\s))?\\s*(\\S.*)?)$"); - -const QString VUtils::c_headerPrefixRegExp = QString("^(#{1,6}\\s+((\\d+\\.)+(?=\\s))?\\s*)($|(\\S.*)?$)"); - -const QString VUtils::c_listRegExp = QString("^\\s*(-|\\*|\\d+\\.)\\s"); - -const QString VUtils::c_blockQuoteRegExp = QString("^\\s*(\\>\\s?)"); - -void VUtils::initAvailableLanguage() -{ - if (!s_availableLanguages.isEmpty()) { - return; - } - - s_availableLanguages.append(QPair("en_US", "English (US)")); - s_availableLanguages.append(QPair("zh_CN", "Chinese")); - s_availableLanguages.append(QPair("ja_JP", "Japanese")); -} - -QString VUtils::readFileFromDisk(const QString &filePath) -{ - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << "fail to open file" << filePath << "to read"; - return QString(); - } - QString fileText(file.readAll()); - file.close(); - qDebug() << "read file content:" << filePath; - return fileText; -} - -bool VUtils::writeFileToDisk(const QString &p_filePath, const QString &p_text) -{ - QFile file(p_filePath); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - qWarning() << "fail to open file" << p_filePath << "to write"; - return false; - } - - QTextStream stream(&file); - stream << p_text; - file.close(); - qDebug() << "write file content:" << p_filePath; - return true; -} - -bool VUtils::writeFileToDisk(const QString &p_filePath, const QByteArray &p_data) -{ - QFile file(p_filePath); - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "fail to open file" << p_filePath << "to write"; - return false; - } - - file.write(p_data); - file.close(); - qDebug() << "write file content:" << p_filePath; - return true; -} - -bool VUtils::writeJsonToDisk(const QString &p_filePath, const QJsonObject &p_json) -{ - QFile file(p_filePath); - // We use Unix LF for config file. - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "fail to open file" << p_filePath << "to write"; - return false; - } - - QJsonDocument doc(p_json); - if (-1 == file.write(doc.toJson())) { - return false; - } - - return true; -} - -QJsonObject VUtils::readJsonFromDisk(const QString &p_filePath) -{ - QFile file(p_filePath); - if (!file.open(QIODevice::ReadOnly)) { - qWarning() << "fail to open file" << p_filePath << "to read"; - return QJsonObject(); - } - - return QJsonDocument::fromJson(file.readAll()).object(); -} - -QString VUtils::generateImageFileName(const QString &path, - const QString &title, - const QString &format) -{ - Q_UNUSED(title); - - const QChar sep('_'); - - QString baseName(g_config->getImageNamePrefix()); - if (!baseName.isEmpty() - && !(baseName.size() == 1 && baseName[0] == sep)) { - baseName += sep; - } - - // Add current time at fixed length. - baseName += QDateTime::currentDateTime().toString("yyyyMMddHHmmsszzz"); - - // Add random number to make the name be most likely unique. - baseName += (sep + QString::number(qrand())); - - QString suffix; - if (!format.isEmpty()) { - suffix = "." + format.toLower(); - } - - QString imageName(baseName + suffix); - int index = 1; - QDir dir(path); - while (fileExists(dir, imageName, true)) { - imageName = QString("%1_%2%3").arg(baseName).arg(index++).arg(suffix); - } - - return imageName; -} - -QString VUtils::fileNameFromPath(const QString &p_path) -{ - if (p_path.isEmpty()) { - return p_path; - } - - return QFileInfo(QDir::cleanPath(p_path)).fileName(); -} - -QString VUtils::basePathFromPath(const QString &p_path) -{ - if (p_path.isEmpty()) { - return p_path; - } - - return QFileInfo(QDir::cleanPath(p_path)).path(); -} - -QVector VUtils::fetchImagesFromMarkdownFile(VFile *p_file, - ImageLink::ImageLinkType p_type) -{ - Q_ASSERT(p_file->getDocType() == DocType::Markdown); - QVector images; - - bool isOpened = p_file->isOpened(); - if (!isOpened && !p_file->open()) { - return images; - } - - const QString &text = p_file->getContent(); - if (text.isEmpty()) { - if (!isOpened) { - p_file->close(); - } - - return images; - } - - // Used to de-duplicate the links. Url as the key. - QSet fetchedLinks; - - QVector regions = fetchImageRegionsUsingParser(text); - QRegExp regExp(c_imageLinkRegExp); - QString basePath = p_file->fetchBasePath(); - for (int i = 0; i < regions.size(); ++i) { - const VElementRegion ® = regions[i]; - QString linkText = text.mid(reg.m_startPos, reg.m_endPos - reg.m_startPos); - bool matched = regExp.exactMatch(linkText); - if (!matched) { - // Image links with reference format will not match. - continue; - } - - QString imageUrl = regExp.capturedTexts()[2].trimmed(); - - ImageLink link; - link.m_url = imageUrl; - QFileInfo info(basePath, purifyUrl(imageUrl)); - if (info.exists()) { - if (info.isNativePath()) { - // Local file. - link.m_path = QDir::cleanPath(info.absoluteFilePath()); - - if (QDir::isRelativePath(imageUrl)) { - link.m_type = p_file->isInternalImageFolder(VUtils::basePathFromPath(link.m_path)) ? - ImageLink::LocalRelativeInternal : ImageLink::LocalRelativeExternal; - } else { - link.m_type = ImageLink::LocalAbsolute; - } - } else { - link.m_type = ImageLink::Resource; - link.m_path = imageUrl; - } - } else { - QUrl url(imageUrl); - link.m_path = url.toString(); - link.m_type = ImageLink::Remote; - } - - if (link.m_type & p_type) { - if (!fetchedLinks.contains(link.m_url)) { - fetchedLinks.insert(link.m_url); - images.push_back(link); - qDebug() << "fetch one image:" << link.m_type << link.m_path << link.m_url; - } - } - } - - if (!isOpened) { - p_file->close(); - } - - return images; -} - -QString VUtils::linkUrlToPath(const QString &p_basePath, const QString &p_url) -{ - QString fullPath; - QFileInfo info(p_basePath, purifyUrl(p_url)); - if (info.exists()) { - if (info.isNativePath()) { - // Local file. - fullPath = QDir::cleanPath(info.absoluteFilePath()); - } else { - fullPath = p_url; - } - } else { - QString decodedUrl(p_url); - VUtils::decodeUrl(decodedUrl); - QFileInfo dinfo(p_basePath, decodedUrl); - if (dinfo.exists()) { - if (dinfo.isNativePath()) { - // Local file. - fullPath = QDir::cleanPath(dinfo.absoluteFilePath()); - } else { - fullPath = p_url; - } - } else { - QUrl url(p_url); - if (url.isLocalFile()) { - fullPath = url.toLocalFile(); - } else { - fullPath = url.toString(); - } - } - } - - return fullPath; -} - -bool VUtils::makePath(const QString &p_path) -{ - if (p_path.isEmpty()) { - return true; - } - - bool ret = true; - QDir dir; - if (dir.mkpath(p_path)) { - qDebug() << "make path" << p_path; - } else { - qWarning() << "fail to make path" << p_path; - ret = false; - } - - return ret; -} - -QJsonObject VUtils::clipboardToJson() -{ - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - - QJsonObject obj; - if (mimeData->hasText()) { - QString text = mimeData->text(); - obj = QJsonDocument::fromJson(text.toUtf8()).object(); - qDebug() << "Json object in clipboard" << obj; - } - - return obj; -} - -ClipboardOpType VUtils::operationInClipboard() -{ - QJsonObject obj = clipboardToJson(); - if (obj.contains(ClipboardConfig::c_type)) { - return (ClipboardOpType)obj[ClipboardConfig::c_type].toInt(); - } - - return ClipboardOpType::Invalid; -} - -bool VUtils::copyFile(const QString &p_srcFilePath, const QString &p_destFilePath, bool p_isCut) -{ - QString srcPath = QDir::cleanPath(p_srcFilePath); - QString destPath = QDir::cleanPath(p_destFilePath); - - if (srcPath == destPath) { - return true; - } - - QDir dir; - if (!dir.mkpath(basePathFromPath(p_destFilePath))) { - qWarning() << "fail to create directory" << basePathFromPath(p_destFilePath); - return false; - } - - if (p_isCut) { - QFile file(srcPath); - if (!file.rename(destPath)) { - qWarning() << "fail to copy file" << srcPath << destPath; - return false; - } - } else { - if (!QFile::copy(srcPath, destPath)) { - qWarning() << "fail to copy file" << srcPath << destPath; - return false; - } - } - - return true; -} - -bool VUtils::copyDirectory(const QString &p_srcDirPath, const QString &p_destDirPath, bool p_isCut) -{ - QString srcPath = QDir::cleanPath(p_srcDirPath); - QString destPath = QDir::cleanPath(p_destDirPath); - if (srcPath == destPath) { - return true; - } - - if (QFileInfo::exists(destPath)) { - qWarning() << QString("target directory %1 already exists").arg(destPath); - return false; - } - - // QDir.rename() could not move directory across drives. - - // Make sure target directory exists. - QDir destDir(destPath); - if (!destDir.exists()) { - if (!destDir.mkpath(destPath)) { - qWarning() << QString("fail to create target directory %1").arg(destPath); - return false; - } - } - - // Handle directory recursively. - QDir srcDir(srcPath); - Q_ASSERT(srcDir.exists() && destDir.exists()); - QFileInfoList nodes = srcDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden - | QDir::NoSymLinks | QDir::NoDotAndDotDot); - for (int i = 0; i < nodes.size(); ++i) { - const QFileInfo &fileInfo = nodes.at(i); - QString name = fileInfo.fileName(); - if (fileInfo.isDir()) { - if (!copyDirectory(srcDir.filePath(name), destDir.filePath(name), p_isCut)) { - return false; - } - } else { - Q_ASSERT(fileInfo.isFile()); - if (!copyFile(srcDir.filePath(name), destDir.filePath(name), p_isCut)) { - return false; - } - } - } - - if (p_isCut) { - if (!destDir.rmdir(srcPath)) { - qWarning() << QString("fail to delete source directory %1 after cut").arg(srcPath); - return false; - } - } - - return true; -} - -int VUtils::showMessage(QMessageBox::Icon p_icon, - const QString &p_title, - const QString &p_text, - const QString &p_infoText, - QMessageBox::StandardButtons p_buttons, - QMessageBox::StandardButton p_defaultBtn, - QWidget *p_parent, - MessageBoxType p_type) -{ - QMessageBox msgBox(p_icon, p_title, p_text, p_buttons, p_parent); - msgBox.setInformativeText(p_infoText); - msgBox.setDefaultButton(p_defaultBtn); - - if (p_type == MessageBoxType::Danger) { - QPushButton *okBtn = dynamic_cast(msgBox.button(QMessageBox::Ok)); - if (okBtn) { - setDynamicProperty(okBtn, "DangerBtn"); - } - } - - QPushButton *defaultBtn = dynamic_cast(msgBox.button(p_defaultBtn)); - if (defaultBtn) { - setDynamicProperty(defaultBtn, "SpecialBtn"); - } - - return msgBox.exec(); -} - -void VUtils::promptForReopen(QWidget *p_parent) -{ - VUtils::showMessage(QMessageBox::Information, - QObject::tr("Information"), - QObject::tr("Please re-open current opened tabs to make it work."), - "", - QMessageBox::Ok, - QMessageBox::Ok, - p_parent); -} - -QString VUtils::generateCopiedFileName(const QString &p_dirPath, - const QString &p_fileName, - bool p_completeBaseName) -{ - QDir dir(p_dirPath); - if (!dir.exists() || !dir.exists(p_fileName)) { - return p_fileName; - } - - QFileInfo fi(p_fileName); - QString baseName = p_completeBaseName ? fi.completeBaseName() : fi.baseName(); - QString suffix = p_completeBaseName ? fi.suffix() : fi.completeSuffix(); - - int index = 0; - QString fileName; - do { - QString seq; - if (index > 0) { - seq = QString("%1").arg(QString::number(index), 3, '0'); - } - - index++; - fileName = QString("%1_copy%2").arg(baseName).arg(seq); - if (!suffix.isEmpty()) { - fileName = fileName + "." + suffix; - } - } while (fileExists(dir, fileName, true)); - - return fileName; -} - -QString VUtils::generateCopiedDirName(const QString &p_parentDirPath, const QString &p_dirName) -{ - QDir dir(p_parentDirPath); - QString name = p_dirName; - QString dirPath = dir.filePath(name); - int index = 0; - while (QDir(dirPath).exists()) { - QString seq; - if (index > 0) { - seq = QString::number(index); - } - index++; - name = QString("%1_copy%2").arg(p_dirName).arg(seq); - dirPath = dir.filePath(name); - } - return name; -} - -const QVector>& VUtils::getAvailableLanguages() -{ - if (s_availableLanguages.isEmpty()) { - initAvailableLanguage(); - } - - return s_availableLanguages; -} - -bool VUtils::isValidLanguage(const QString &p_lang) -{ - for (auto const &lang : getAvailableLanguages()) { - if (lang.first == p_lang) { - return true; - } - } - - return false; -} - -bool VUtils::isImageURL(const QUrl &p_url) -{ - QString urlStr; - if (p_url.isLocalFile()) { - urlStr = p_url.toLocalFile(); - } else { - urlStr = p_url.toString(); - } - return isImageURLText(urlStr); -} - -bool VUtils::isImageURLText(const QString &p_url) -{ - QFileInfo info(purifyUrl(p_url)); - return QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1()); -} - -qreal VUtils::calculateScaleFactor() -{ - static qreal factor = -1; - - if (factor < 0) { - const qreal refDpi = 96; - qreal dpi = QGuiApplication::primaryScreen()->logicalDotsPerInch(); - factor = dpi / refDpi; - if (factor < 1) { - factor = 1; - } else { - // Keep only two digits after the dot. - factor = (int)(factor * 100) / 100.0; - } - } - - return factor; -} - -bool VUtils::realEqual(qreal p_a, qreal p_b) -{ - return std::abs(p_a - p_b) < 1e-8; -} - -QChar VUtils::keyToChar(int p_key, bool p_smallCase) -{ - QString key = QKeySequence(p_key).toString(); - if (key.size() == 1) { - return p_smallCase ? key[0].toLower() : key[0]; - } - - return QChar(); -} - -QString VUtils::getLocale() -{ - QString locale = g_config->getLanguage(); - if (locale == "System" || !isValidLanguage(locale)) { - locale = QLocale::system().name(); - } - - return locale; -} - -void VUtils::sleepWait(int p_milliseconds) -{ - if (p_milliseconds <= 0) { - return; - } - - QElapsedTimer t; - t.start(); - while (t.elapsed() < p_milliseconds) { - QCoreApplication::processEvents(); - } -} - -DocType VUtils::docTypeFromName(const QString &p_name) -{ - if (p_name.isEmpty()) { - return DocType::Unknown; - } - - const QHash> &suffixes = g_config->getDocSuffixes(); - - QString suf = QFileInfo(p_name).suffix().toLower(); - for (auto it = suffixes.begin(); it != suffixes.end(); ++it) { - if (it.value().contains(suf)) { - return DocType(it.key()); - } - } - - return DocType::Unknown; -} - -QString VUtils::generateSimpleHtmlTemplate(const QString &p_body) -{ - QString html(VNote::s_simpleHtmlTemplate); - return html.replace(HtmlHolder::c_bodyHolder, p_body); -} - -QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType) -{ - return generateHtmlTemplate(VNote::s_markdownTemplate, p_conType); -} - -QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType, - const QString &p_renderBg, - const QString &p_renderStyle, - const QString &p_renderCodeBlockStyle, - bool p_isPDF, - bool p_wkhtmltopdf, - bool p_addToc) -{ - Q_ASSERT((p_isPDF && p_wkhtmltopdf) || !p_wkhtmltopdf); - - QString templ = VNote::generateHtmlTemplate(g_config->getRenderBackgroundColor(p_renderBg), - g_config->getCssStyleUrl(p_renderStyle), - g_config->getCodeBlockCssStyleUrl(p_renderCodeBlockStyle), - p_isPDF); - - return generateHtmlTemplate(templ, p_conType, p_isPDF, p_wkhtmltopdf, p_addToc); -} - -QString VUtils::generateHtmlTemplate(const QString &p_template, - MarkdownConverterType p_conType, - bool p_isPDF, - bool p_wkhtmltopdf, - bool p_addToc) -{ - bool mathjaxTypeSetOnLoad = true; - - QString jsFile, extraFile; - switch (p_conType) { - case MarkdownConverterType::Marked: - jsFile = "qrc" + VNote::c_markedJsFile; - extraFile = "\n"; - break; - - case MarkdownConverterType::Hoedown: - jsFile = "qrc" + VNote::c_hoedownJsFile; - // Use Marked to highlight code blocks. - extraFile = "\n"; - break; - - case MarkdownConverterType::MarkdownIt: - { - jsFile = "qrc" + VNote::c_markdownitJsFile; - extraFile = "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n"; - - if (g_config->getEnableMathjax()) { - extraFile += "\n"; - } - - const MarkdownitOption &opt = g_config->getMarkdownitOption(); - - if (opt.m_sup) { - extraFile += "\n"; - } - - if (opt.m_sub) { - extraFile += "\n"; - } - - if (opt.m_metadata) { - extraFile += "\n"; - } - - if (opt.m_emoji) { - extraFile += "\n"; - } - - QString optJs = QString("\n") - .arg(opt.m_html ? QStringLiteral("true") : QStringLiteral("false")) - .arg(opt.m_breaks ? QStringLiteral("true") : QStringLiteral("false")) - .arg(opt.m_linkify ? QStringLiteral("true") : QStringLiteral("false")) - .arg(opt.m_sub ? QStringLiteral("true") : QStringLiteral("false")) - .arg(opt.m_sup ? QStringLiteral("true") : QStringLiteral("false")) - .arg(opt.m_metadata ? QStringLiteral("true") : QStringLiteral("false")) - .arg(opt.m_emoji ? QStringLiteral("true") : QStringLiteral("false")); - extraFile += optJs; - - mathjaxTypeSetOnLoad = false; - break; - } - - case MarkdownConverterType::Showdown: - jsFile = "qrc" + VNote::c_showdownJsFile; - extraFile = "\n" + - "\n"; - - break; - - default: - Q_ASSERT(false); - } - - extraFile += "\n"; - extraFile += "\n"; - - if (g_config->getEnableMermaid()) { - extraFile += "getMermaidCssStyleUrl() + "\"/>\n" + - "\n" + - "\n"; - } - - if (g_config->getEnableFlowchart()) { - extraFile += "\n" + - "\n" + - "\n"; - } - - if (g_config->getEnableMathjax()) { - QString mj = g_config->getMathjaxJavascript(); - if (p_wkhtmltopdf) { - // Chante MathJax to be rendered as SVG. - // If rendered as HTML, it will make the font of messy. - QRegExp reg("(Mathjax\\.js\\?config=)\\S+", Qt::CaseInsensitive); - mj.replace(reg, QString("\\1%1").arg("TeX-MML-AM_SVG")); - } - - extraFile += "\n" - "\n" + - "\n"; - - if (p_wkhtmltopdf) { - extraFile += "\n"; - } - } - - if (g_config->getEnableWavedrom()) { - extraFile += "\n" + - "\n" + - "\n"; - } - - int plantUMLMode = g_config->getPlantUMLMode(); - if (plantUMLMode != PlantUMLMode::DisablePlantUML) { - if (plantUMLMode == PlantUMLMode::OnlinePlantUML) { - extraFile += "\n" + - "\n" + - "\n"; - } - - extraFile += QString("\n").arg(plantUMLMode); - - QString format = p_isPDF ? "png" : "svg"; - extraFile += QString("\n").arg(format); - } - - if (g_config->getEnableGraphviz()) { - extraFile += "\n"; - - // If we use png, we need to specify proper font in the dot command to render - // non-ASCII chars properly. - // Hence we use svg format in both cases. - QString format = p_isPDF ? "svg" : "svg"; - extraFile += QString("\n").arg(format); - } - - if (g_config->getEnableImageCaption()) { - extraFile += "\n"; - } - - if (g_config->getEnableCodeBlockLineNumber()) { - extraFile += "\n" + - "\n"; - } - - if (g_config->getEnableFlashAnchor()) { - extraFile += "\n"; - } - - if (g_config->getEnableCodeBlockCopyButton()) { - extraFile += "\n"; - } - - if (p_addToc) { - extraFile += "\n"; - extraFile += ""; - } - - extraFile += "\n"; - -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - extraFile += "\n"; -#elif defined(Q_OS_WIN) - extraFile += "\n"; -#else - extraFile += "\n"; -#endif - - QString htmlTemplate(p_template); - htmlTemplate.replace(HtmlHolder::c_JSHolder, jsFile); - if (!extraFile.isEmpty()) { - htmlTemplate.replace(HtmlHolder::c_extraHolder, extraFile); - } - - return htmlTemplate; -} - -QString VUtils::generateExportHtmlTemplate(const QString &p_renderBg, - bool p_includeMathJax, - bool p_outlinePanel) -{ - QString templ = VNote::generateExportHtmlTemplate(g_config->getRenderBackgroundColor(p_renderBg)); - QString extra; - if (p_includeMathJax) { - extra += "\n"; - QString mj = g_config->getMathjaxJavascript(); - // Chante MathJax to be rendered as SVG. - QRegExp reg("tex-mml-chtml\\.js\\S+", Qt::CaseInsensitive); - mj.replace(reg, QString("tex-mml-svg.js")); - - extra += "\n"; - } - - if (p_outlinePanel) { - const QString outlineCss(":/resources/export/outline.css"); - QString css = VUtils::readFileFromDisk(outlineCss); - if (!css.isEmpty()) { - templ.replace(HtmlHolder::c_outlineStyleHolder, css); - } - - const QString outlineJs(":/resources/export/outline.js"); - QString js = VUtils::readFileFromDisk(outlineJs); - extra += QString("\n").arg(js); - } - - // Clipboard.js. - if (g_config->getEnableCodeBlockCopyButton()) { - const QString clipboardjs(":/utils/clipboard.js/clipboard.min.js"); - QString js = VUtils::readFileFromDisk(clipboardjs); - extra += QString("\n").arg(js); - extra += "\n"; - } - - if (!extra.isEmpty()) { - templ.replace(HtmlHolder::c_extraHolder, extra); - } - - return templ; -} - -QString VUtils::generateMathJaxPreviewTemplate() -{ - QString mj = g_config->getMathjaxJavascript(); - QString templ = VNote::generateMathJaxPreviewTemplate(); - templ.replace(HtmlHolder::c_JSHolder, mj); - - QString extraFile; - - /* - // Mermaid. - extraFile += "getMermaidCssStyleUrl() + "\"/>\n" + - "\n"; - */ - - // Flowchart. - extraFile += "\n" + - "\n"; - - // MathJax. - extraFile += "\n"; - - - extraFile += "\n" + - "\n"; - - // PlantUML. - extraFile += "\n" + - "\n" + - "\n"; - - templ.replace(HtmlHolder::c_extraHolder, extraFile); - - return templ; -} - -QString VUtils::getFileNameWithSequence(const QString &p_directory, - const QString &p_baseFileName, - bool p_completeBaseName) -{ - QDir dir(p_directory); - if (!dir.exists() || !dir.exists(p_baseFileName)) { - return p_baseFileName; - } - - // Append a sequence. - QFileInfo fi(p_baseFileName); - QString baseName = p_completeBaseName ? fi.completeBaseName() : fi.baseName(); - QString suffix = p_completeBaseName ? fi.suffix() : fi.completeSuffix(); - int seq = 1; - QString fileName; - do { - fileName = QString("%1_%2").arg(baseName).arg(QString::number(seq++), 3, '0'); - if (!suffix.isEmpty()) { - fileName = fileName + "." + suffix; - } - } while (fileExists(dir, fileName, true)); - - return fileName; -} - -QString VUtils::getDirNameWithSequence(const QString &p_directory, - const QString &p_baseDirName) -{ - QDir dir(p_directory); - if (!dir.exists() || !dir.exists(p_baseDirName)) { - return p_baseDirName; - } - - // Append a sequence. - int seq = 1; - QString fileName; - do { - fileName = QString("%1_%2").arg(p_baseDirName).arg(QString::number(seq++), 3, '0'); - } while (fileExists(dir, fileName, true)); - - return fileName; -} - -QString VUtils::getRandomFileName(const QString &p_directory) -{ - Q_ASSERT(!p_directory.isEmpty()); - - QString baseName(QDateTime::currentDateTime().toString("yyyyMMddHHmmsszzz")); - - QDir dir(p_directory); - QString name; - do { - name = baseName + '_' + QString::number(qrand()); - } while (fileExists(dir, name, true)); - - return name; -} - -bool VUtils::checkPathLegal(const QString &p_path) -{ - // Ensure every part of the p_path is a valid file name until we come to - // an existing parent directory. - if (p_path.isEmpty()) { - return false; - } - - if (QFileInfo::exists(p_path)) { -#if defined(Q_OS_WIN) - // On Windows, "/" and ":" will also make exists() return true. - if (p_path.startsWith('/') || p_path == ":") { - return false; - } -#endif - - return true; - } - - bool ret = false; - int pos; - QString basePath = basePathFromPath(p_path); - QString fileName = fileNameFromPath(p_path); - QValidator *validator = new QRegExpValidator(QRegExp(c_fileNameRegExp)); - while (!fileName.isEmpty()) { - QValidator::State validFile = validator->validate(fileName, pos); - if (validFile != QValidator::Acceptable) { - break; - } - - if (QFileInfo::exists(basePath)) { - ret = true; - -#if defined(Q_OS_WIN) - // On Windows, "/" and ":" will also make exists() return true. - if (basePath.startsWith('/') || basePath == ":") { - ret = false; - } -#endif - - break; - } - - fileName = fileNameFromPath(basePath); - basePath = basePathFromPath(basePath); - } - - delete validator; - return ret; -} - -bool VUtils::checkFileNameLegal(const QString &p_name) -{ - if (p_name.isEmpty()) { - return false; - } - - QRegExp exp(c_fileNameRegExp); - return exp.exactMatch(p_name); -} - -bool VUtils::equalPath(const QString &p_patha, const QString &p_pathb) -{ - QString a = QDir::cleanPath(p_patha); - QString b = QDir::cleanPath(p_pathb); - -#if defined(Q_OS_WIN) - a = a.toLower(); - b = b.toLower(); -#endif - - return a == b; -} - -bool VUtils::splitPathInBasePath(const QString &p_base, - const QString &p_path, - QStringList &p_parts) -{ - p_parts.clear(); - QString a = QDir::cleanPath(p_base); - QString b = QDir::cleanPath(p_path); - -#if defined(Q_OS_WIN) - if (!b.toLower().startsWith(a.toLower())) { - return false; - } -#else - if (!b.startsWith(a)) { - return false; - } -#endif - - if (a.size() == b.size()) { - return true; - } - - Q_ASSERT(a.size() < b.size()); - - if (b.at(a.size()) != '/') { - return false; - } - - p_parts = b.right(b.size() - a.size() - 1).split("/", QString::SkipEmptyParts); - return true; -} - -void VUtils::decodeUrl(QString &p_url) -{ - QHash maps; - maps.insert("%20", " "); - - for (auto it = maps.begin(); it != maps.end(); ++it) { - p_url.replace(it.key(), it.value()); - } -} - -QString VUtils::getShortcutText(const QString &p_keySeq) -{ - return QKeySequence(p_keySeq).toString(QKeySequence::NativeText); -} - -bool VUtils::deleteDirectory(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin) -{ - if (p_skipRecycleBin) { - QDir dir(p_path); - return dir.removeRecursively(); - } else { - // Move it to the recycle bin folder. - return deleteFile(p_notebook->getRecycleBinFolderPath(), p_path); - } -} - -bool VUtils::deleteDirectory(const QString &p_path) -{ - if (p_path.isEmpty()) { - return true; - } - - QDir dir(p_path); - return dir.removeRecursively(); -} - -bool VUtils::emptyDirectory(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin) -{ - QDir dir(p_path); - if (!dir.exists()) { - return true; - } - - QFileInfoList nodes = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden - | QDir::NoSymLinks | QDir::NoDotAndDotDot); - for (int i = 0; i < nodes.size(); ++i) { - const QFileInfo &fileInfo = nodes.at(i); - if (fileInfo.isDir()) { - if (!deleteDirectory(p_notebook, fileInfo.absoluteFilePath(), p_skipRecycleBin)) { - return false; - } - } else { - Q_ASSERT(fileInfo.isFile()); - if (!deleteFile(p_notebook, fileInfo.absoluteFilePath(), p_skipRecycleBin)) { - return false; - } - } - } - - return true; -} - -bool VUtils::deleteFile(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin) -{ - if (p_skipRecycleBin) { - QFile file(p_path); - return file.remove(); - } else { - // Move it to the recycle bin folder. - return deleteFile(p_notebook->getRecycleBinFolderPath(), p_path); - } -} - -bool VUtils::deleteFile(const QString &p_path) -{ - QFile file(p_path); - bool ret = file.remove(); - if (ret) { - qDebug() << "deleted file" << p_path; - } else { - qWarning() << "fail to delete file" << p_path; - } - - return ret; -} - -bool VUtils::deleteFile(const VOrphanFile *p_file, - const QString &p_path, - bool p_skipRecycleBin) -{ - if (p_skipRecycleBin) { - QFile file(p_path); - return file.remove(); - } else { - // Move it to the recycle bin folder. - return deleteFile(p_file->fetchRecycleBinFolderPath(), p_path); - } -} - -static QString getRecycleBinSubFolderToUse(const QString &p_folderPath) -{ - QDir dir(p_folderPath); - return QDir::cleanPath(dir.absoluteFilePath(QDateTime::currentDateTime().toString("yyyyMMdd"))); -} - -bool VUtils::deleteFile(const QString &p_recycleBinFolderPath, - const QString &p_path) -{ - QString binPath = getRecycleBinSubFolderToUse(p_recycleBinFolderPath); - QDir binDir(binPath); - if (!binDir.exists()) { - binDir.mkpath(binPath); - if (!binDir.exists()) { - return false; - } - } - - QString destName = getFileNameWithSequence(binPath, - fileNameFromPath(p_path), - true); - - qDebug() << "try to move" << p_path << "to" << binPath << "as" << destName; - if (!binDir.rename(p_path, binDir.filePath(destName))) { - qWarning() << "fail to move" << p_path << "to" << binDir.filePath(destName); - return false; - } - - return true; -} - -QVector VUtils::fetchImageRegionsUsingParser(const QString &p_content) -{ - Q_ASSERT(!p_content.isEmpty()); - - const QSharedPointer parserConfig(new PegParseConfig()); - parserConfig->m_data = p_content.toUtf8(); - - return PegParser::parseImageRegions(parserConfig); -} - -QString VUtils::displayDateTime(const QDateTime &p_dateTime, - bool p_uniformNum) -{ - QString res = p_dateTime.date().toString(p_uniformNum ? Qt::ISODate - : Qt::DefaultLocaleLongDate); - res += " " + p_dateTime.time().toString(p_uniformNum ? Qt::ISODate - : Qt::TextDate); - return res; -} - -bool VUtils::fileExists(const QDir &p_dir, const QString &p_name, bool p_forceCaseInsensitive) -{ - if (!p_forceCaseInsensitive) { - return p_dir.exists(p_name); - } - - QString name = p_name.toLower(); - QStringList names = p_dir.entryList(QDir::Dirs | QDir::Files | QDir::Hidden - | QDir::NoSymLinks | QDir::NoDotAndDotDot); - foreach (const QString &str, names) { - if (str.toLower() == name) { - return true; - } - } - - return false; -} - -void VUtils::addErrMsg(QString *p_msg, const QString &p_str) -{ - if (!p_msg) { - return; - } - - if (p_msg->isEmpty()) { - *p_msg = p_str; - } else { - *p_msg = *p_msg + '\n' + p_str; - } -} - -QStringList VUtils::filterFilePathsToOpen(const QStringList &p_files) -{ - QStringList paths; - for (int i = 0; i < p_files.size(); ++i) { - if (p_files[i].startsWith('-')) { - continue; - } - - QString path = validFilePathToOpen(p_files[i]); - if (!path.isEmpty()) { - paths.append(path); - } - } - - return paths; -} - -QString VUtils::validFilePathToOpen(const QString &p_file) -{ - if (QFileInfo::exists(p_file)) { - QFileInfo fi(p_file); - if (fi.isFile()) { - // Need to use absolute path here since VNote may be launched - // in different working directory. - return QDir::cleanPath(fi.absoluteFilePath()); - } - } - - return QString(); -} - -bool VUtils::isControlModifierForVim(int p_modifiers) -{ -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - return p_modifiers == Qt::MetaModifier; -#else - return p_modifiers == Qt::ControlModifier; -#endif -} - -void VUtils::touchFile(const QString &p_file) -{ - if (p_file.isEmpty()) { - return; - } - - QFile file(p_file); - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "fail to touch file" << p_file; - return; - } - - file.close(); -} - -bool VUtils::isMetaKey(int p_key) -{ - return p_key == Qt::Key_Control - || p_key == Qt::Key_Shift - || p_key == Qt::Key_Meta -#if defined(Q_OS_LINUX) - // For mapping Caps as Ctrl in KDE. - || p_key == Qt::Key_CapsLock -#endif - || p_key == Qt::Key_Alt; -} - -QComboBox *VUtils::getComboBox(QWidget *p_parent) -{ - QComboBox *box = new VComboBox(p_parent); - QStyledItemDelegate *itemDelegate = new QStyledItemDelegate(box); - box->setItemDelegate(itemDelegate); - - return box; -} - -void VUtils::setDynamicProperty(QWidget *p_widget, const char *p_prop, bool p_val) -{ - p_widget->setProperty(p_prop, p_val); - p_widget->style()->unpolish(p_widget); - p_widget->style()->polish(p_widget); -} - -QWebEngineView *VUtils::getWebEngineView(const QColor &p_background, QWidget *p_parent) -{ - QWebEngineView *viewer = new QWebEngineView(p_parent); - VPreviewPage *page = new VPreviewPage(viewer); - - // Setting the background to Qt::transparent will force GrayScale antialiasing. - if (p_background.isValid() && p_background != Qt::transparent) { - page->setBackgroundColor(p_background); - } - - viewer->setPage(page); - viewer->setZoomFactor(g_config->getWebZoomFactor()); - - return viewer; -} - -QString VUtils::getDocFile(const QString &p_name) -{ - QDir dir(VNote::c_docFileFolder); - QString fullLocale = getLocale(); - QString shortLocale = fullLocale.split('_')[0]; - // First looks full locale name folder (eg. zh_CN) - QString name = QString("%1/%2").arg(fullLocale).arg(p_name); - if (!dir.exists(name)) { - // If not found, try 2-char locale name folder (eg. ja) - name = QString("%1/%2").arg(shortLocale).arg(p_name); - } - if (!dir.exists(name)) { - // even not found, fall back to default english folder. - name = QString("%1/%2").arg("en").arg(p_name); - } - - return dir.filePath(name); -} - -QString VUtils::getCaptainShortcutSequenceText(const QString &p_operation) -{ - QString capKey = g_config->getShortcutKeySequence("CaptainMode"); - QString sec = g_config->getCaptainShortcutKeySequence(p_operation); - - QKeySequence seq(capKey + "," + sec); - if (!seq.isEmpty()) { - return seq.toString(QKeySequence::NativeText); - } - - return QString(); -} - -QString VUtils::getAvailableFontFamily(const QStringList &p_families) -{ - QStringList availFamilies = QFontDatabase().families(); - - for (int i = 0; i < p_families.size(); ++i) { - QString family = p_families[i].trimmed(); - if (family.isEmpty()) { - continue; - } - - for (int j = 0; j < availFamilies.size(); ++j) { - QString availFamily = availFamilies[j]; - availFamily.remove(QRegExp("\\[.*\\]")); - availFamily = availFamily.trimmed(); - if (family == availFamily - || family.toLower() == availFamily.toLower()) { - qDebug() << "matched font family" << availFamilies[j]; - return availFamilies[j]; - } - } - } - - return QString(); -} - -bool VUtils::fixTextWithShortcut(QAction *p_act, const QString &p_shortcut) -{ - QString keySeq = g_config->getShortcutKeySequence(p_shortcut); - if (!keySeq.isEmpty()) { - p_act->setText(QString("%1\t%2").arg(p_act->text()).arg(VUtils::getShortcutText(keySeq))); - return true; - } - - return false; -} - -bool VUtils::fixTextWithCaptainShortcut(QAction *p_act, const QString &p_shortcut) -{ - QString keyText = VUtils::getCaptainShortcutSequenceText(p_shortcut); - if (!keyText.isEmpty()) { - p_act->setText(QString("%1\t%2").arg(p_act->text()).arg(keyText)); - return true; - } - - return false; -} - -QStringList VUtils::parseCombinedArgString(const QString &p_program) -{ - QStringList args; - QString tmp; - int quoteCount = 0; - bool inQuote = false; - - // handle quoting. tokens can be surrounded by double quotes - // "hello world". three consecutive double quotes represent - // the quote character itself. - for (int i = 0; i < p_program.size(); ++i) { - if (p_program.at(i) == QLatin1Char('"')) { - ++quoteCount; - if (quoteCount == 3) { - // third consecutive quote - quoteCount = 0; - tmp += p_program.at(i); - } - - continue; - } - - if (quoteCount) { - if (quoteCount == 1) { - inQuote = !inQuote; - } - - quoteCount = 0; - } - - if (!inQuote && p_program.at(i).isSpace()) { - if (!tmp.isEmpty()) { - args += tmp; - tmp.clear(); - } - } else { - tmp += p_program.at(i); - } - } - - if (!tmp.isEmpty()) { - args += tmp; - } - - return args; -} - -QImage VUtils::imageFromFile(const QString &p_filePath) -{ - QImage img(p_filePath); - if (!img.isNull()) { - return img; - } - - // @p_filePath may has a wrong suffix which indicates a wrong image format. - QFile file(p_filePath); - if (!file.open(QIODevice::ReadOnly)) { - qWarning() << "fail to open image file" << p_filePath; - return img; - } - - img.loadFromData(file.readAll()); - qDebug() << "imageFromFile" << p_filePath << img.isNull() << img.format(); - return img; -} - -QPixmap VUtils::pixmapFromFile(const QString &p_filePath) -{ - QPixmap pixmap; - QFile file(p_filePath); - if (!file.open(QIODevice::ReadOnly)) { - qWarning() << "fail to open pixmap file" << p_filePath; - return pixmap; - } - - pixmap.loadFromData(file.readAll()); - qDebug() << "pixmapFromFile" << p_filePath << pixmap.isNull(); - return pixmap; -} - -QFormLayout *VUtils::getFormLayout() -{ - QFormLayout *layout = new QFormLayout(); - -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - layout->setFormAlignment(Qt::AlignLeft | Qt::AlignTop); -#endif - - return layout; -} - -bool VUtils::inSameDrive(const QString &p_a, const QString &p_b) -{ -#if defined(Q_OS_WIN) - QChar sep(':'); - int ai = p_a.indexOf(sep); - int bi = p_b.indexOf(sep); - - if (ai == -1 || bi == -1) { - return false; - } - - return p_a.left(ai).toLower() == p_b.left(bi).toLower(); -#else - return true; -#endif -} - -QString VUtils::promptForFileName(const QString &p_title, - const QString &p_label, - const QString &p_default, - const QString &p_dir, - QWidget *p_parent) -{ - QString name = p_default; - QString text = p_label; - QDir paDir(p_dir); - while (true) { - bool ok; - name = QInputDialog::getText(p_parent, - p_title, - text, - QLineEdit::Normal, - name, - &ok); - if (!ok || name.isEmpty()) { - return ""; - } - - if (!VUtils::checkFileNameLegal(name)) { - text = QObject::tr("Illegal name. Please try again:"); - continue; - } - - if (paDir.exists(name)) { - text = QObject::tr("Name already exists. Please try again:"); - continue; - } - - break; - } - - return name; -} - -QString VUtils::promptForFileName(const QString &p_title, - const QString &p_label, - const QString &p_default, - std::function p_checkExistsFunc, - QWidget *p_parent) -{ - QString name = p_default; - QString text = p_label; - while (true) { - bool ok; - name = QInputDialog::getText(p_parent, - p_title, - text, - QLineEdit::Normal, - name, - &ok); - if (!ok || name.isEmpty()) { - return ""; - } - - if (!VUtils::checkFileNameLegal(name)) { - text = QObject::tr("Illegal name. Please try again:"); - continue; - } - - if (p_checkExistsFunc(name)) { - text = QObject::tr("Name already exists. Please try again:"); - continue; - } - - break; - } - - return name; -} - -bool VUtils::onlyHasImgInHtml(const QString &p_html) -{ - // Tricky. - QRegExp reg("<(?:p|span|div) "); - return !p_html.contains(reg); -} - -int VUtils::elapsedTime(bool p_reset) -{ - static QTime tm; - - if (p_reset) { - tm = QTime(); - return 0; - } - - if (tm.isNull()) { - tm.start(); - return 0; - } - - return tm.restart(); -} - -QPixmap VUtils::svgToPixmap(const QByteArray &p_content, - const QString &p_background, - qreal p_factor) -{ - QSvgRenderer renderer(p_content); - QSize deSz = renderer.defaultSize(); - if (p_factor > 0) { - deSz *= p_factor; - } - - QPixmap pm(deSz); - if (p_background.isEmpty()) { - // Fill a transparent background to avoid glitchy preview. - pm.fill(QColor(255, 255, 255, 0)); - } else { - pm.fill(p_background); - } - - QPainter painter(&pm); - renderer.render(&painter); - return pm; -} - -QString VUtils::fetchImageLinkUrlToPreview(const QString &p_text, int &p_width, int &p_height) -{ - QRegExp regExp(VUtils::c_imageLinkRegExp); - - p_width = p_height = -1; - - int index = regExp.indexIn(p_text); - if (index == -1) { - return QString(); - } - - int lastIndex = regExp.lastIndexIn(p_text); - if (lastIndex != index) { - return QString(); - } - - QString tmp(regExp.cap(7)); - if (!tmp.isEmpty()) { - p_width = tmp.toInt(); - if (p_width <= 0) { - p_width = -1; - } - } - - tmp = regExp.cap(8); - if (!tmp.isEmpty()) { - p_height = tmp.toInt(); - if (p_height <= 0) { - p_height = -1; - } - } - - return regExp.cap(2).trimmed(); -} - -QString VUtils::fetchImageLinkUrl(const QString &p_link) -{ - QRegExp regExp(VUtils::c_imageLinkRegExp); - - int index = regExp.indexIn(p_link); - if (index == -1) { - return QString(); - } - - return regExp.cap(2).trimmed(); -} - -QString VUtils::fetchLinkUrl(const QString &p_link) -{ - QRegExp regExp(VUtils::c_linkRegExp); - - int index = regExp.indexIn(p_link); - if (index == -1) { - return QString(); - } - - return regExp.cap(2).trimmed(); -} - -QUrl VUtils::pathToUrl(const QString &p_path) -{ - QUrl url; - if (QFileInfo::exists(p_path)) { - url = QUrl::fromLocalFile(p_path); - } else { - url = QUrl(p_path); - } - - return url; -} - -QString VUtils::parentDirName(const QString &p_path) -{ - if (p_path.isEmpty()) { - return p_path; - } - - return QFileInfo(p_path).dir().dirName(); -} - -QString VUtils::purifyUrl(const QString &p_url) -{ - int idx = p_url.indexOf('?'); - if (idx > -1) { - return p_url.left(idx); - } - - return p_url; -} - -// Suffix size for QTemporaryFile. -#define MAX_SIZE_SUFFIX_FOR_TEMP_FILE 10 - -QTemporaryFile *VUtils::createTemporaryFile(QString p_suffix) -{ - if (p_suffix.size() > MAX_SIZE_SUFFIX_FOR_TEMP_FILE) { - p_suffix.clear(); - } - - QString xx = p_suffix.isEmpty() ? "XXXXXX" : "XXXXXX."; - return new QTemporaryFile(QDir::tempPath() - + QDir::separator() - + xx - + p_suffix); -} - -QString VUtils::purifyImageTitle(QString p_title) -{ - return p_title.remove(QRegExp("[\\r\\n\\[\\]]")); -} - -QString VUtils::escapeHtml(QString p_text) -{ - p_text.replace(">", ">").replace("<", "<").replace("&", "&"); - return p_text; -} - -QString VUtils::encodeSpacesInPath(const QString &p_path) -{ - QString tmp(p_path); - tmp.replace(' ', "%20"); - return tmp; -} - -void VUtils::prependDotIfRelative(QString &p_path) -{ - if (QFileInfo(p_path).isRelative() - && !p_path.startsWith("../") && !p_path.startsWith("./")) { - p_path.prepend("./"); - } -} diff --git a/src/utils/vutils.h b/src/utils/vutils.h deleted file mode 100644 index 6150eb8a..00000000 --- a/src/utils/vutils.h +++ /dev/null @@ -1,475 +0,0 @@ -#ifndef VUTILS_H -#define VUTILS_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vconfigmanager.h" -#include "vconstants.h" - -class QKeyEvent; -class VFile; -class VOrphanFile; -class VNotebook; -class QWidget; -class QComboBox; -class QWebEngineView; -class QAction; -class QTreeWidgetItem; -class QFormLayout; -class QTemporaryFile; - -#if !defined(V_ASSERT) - #define V_ASSERT(cond) ((!(cond)) ? qt_assert(#cond, __FILE__, __LINE__) : qt_noop()) -#endif - -// Thanks to CGAL/cgal. -#ifndef __has_attribute - #define __has_attribute(x) 0 // Compatibility with non-clang compilers. -#endif - -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 // Compatibility with non-supporting compilers. -#endif - -// The fallthrough attribute. -// See for clang: -// http://clang.llvm.org/docs/AttributeReference.html#statement-attributes -// See for gcc: -// https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html -#if __has_cpp_attribute(fallthrough) -# define V_FALLTHROUGH [[fallthrough]] -#elif __has_cpp_attribute(gnu::fallthrough) -# define V_FALLTHROUGH [[gnu::fallthrough]] -#elif __has_cpp_attribute(clang::fallthrough) -# define V_FALLTHROUGH [[clang::fallthrough]] -#elif __has_attribute(fallthrough) && ! __clang__ -# define V_FALLTHROUGH __attribute__ ((fallthrough)) -#else -# define V_FALLTHROUGH while(false){} -#endif - -#define DETIME() qDebug() << "ELAPSED_TIME" << __func__ << __LINE__ << VUtils::elapsedTime() - -#define RESET_TIME() VUtils::elapsedTime(true) - -enum class MessageBoxType -{ - Normal = 0, - Danger = 1 -}; - -struct ImageLink -{ - enum ImageLinkType - { - LocalRelativeInternal = 0x1, - LocalRelativeExternal = 0x2, - LocalAbsolute = 0x4, - Resource = 0x8, - Remote = 0x10, - All = 0xffff - }; - - QString m_path; - - // The url text in the link. - QString m_url; - - ImageLinkType m_type; -}; - -class VUtils -{ -public: - static QString readFileFromDisk(const QString &filePath); - - static bool writeFileToDisk(const QString &p_filePath, const QString &p_text); - - static bool writeFileToDisk(const QString &p_filePath, const QByteArray &p_data); - - static bool writeJsonToDisk(const QString &p_filePath, const QJsonObject &p_json); - - static QJsonObject readJsonFromDisk(const QString &p_filePath); - - static QString generateImageFileName(const QString &path, - const QString &title, - const QString &format = "png"); - - // Given the file name @p_fileName and directory path @p_dirPath, generate - // a file name based on @p_fileName which does not exist in @p_dirPath. - // @p_completeBaseName: use complete base name or complete suffix. For example, - // "abc.tar.gz", if @p_completeBaseName is true, the base name is "abc.tar", - // otherwise, it is "abc". - static QString generateCopiedFileName(const QString &p_dirPath, - const QString &p_fileName, - bool p_completeBaseName = true); - - // Given the directory name @p_dirName and directory path @p_parentDirPath, - // generate a directory name based on @p_dirName which does not exist in - // @p_parentDirPath. - static QString generateCopiedDirName(const QString &p_parentDirPath, - const QString &p_dirName); - - // Return the last directory name of @p_path. - static QString directoryNameFromPath(const QString& p_path); - - // Return the file name of @p_path. - // /home/tamlok/abc, /home/tamlok/abc/ will both return abc. - static QString fileNameFromPath(const QString &p_path); - - // Return the base path of @p_path. - // /home/tamlok/abc, /home/tamlok/abc/ will both return /home/tamlok. - static QString basePathFromPath(const QString &p_path); - - // Fetch all the image links in markdown file p_file. - // @p_type to filter the links returned. - // Need to open p_file and will close it if it is originally closed. - static QVector fetchImagesFromMarkdownFile(VFile *p_file, - ImageLink::ImageLinkType p_type = ImageLink::All); - - // Use PegParser to parse @p_content to get all image link regions. - static QVector fetchImageRegionsUsingParser(const QString &p_content); - - // Return the absolute path of @p_url according to @p_basePath. - static QString linkUrlToPath(const QString &p_basePath, const QString &p_url); - - // Create directories along the @p_path. - // @p_path could be /home/tamlok/abc, /home/tamlok/abc/. - static bool makePath(const QString &p_path); - - // Return QJsonObject if there is valid Json string in clipboard. - // Return empty object if there is no valid Json string. - static QJsonObject clipboardToJson(); - - // Get the operation type in system's clipboard. - static ClipboardOpType operationInClipboard(); - - static ClipboardOpType opTypeInClipboard() { return ClipboardOpType::Invalid; } - - // Copy file @p_srcFilePath to @p_destFilePath. - // Will make necessary parent directory along the destination path. - static bool copyFile(const QString &p_srcFilePath, const QString &p_destFilePath, bool p_isCut); - - // Copy @p_srcDirPath to be @p_destDirPath. - // @p_destDirPath should not exist. - // Will make necessary parent directory along the destination path. - static bool copyDirectory(const QString &p_srcDirPath, const QString &p_destDirPath, bool p_isCut); - - static int showMessage(QMessageBox::Icon p_icon, const QString &p_title, const QString &p_text, - const QString &p_infoText, QMessageBox::StandardButtons p_buttons, - QMessageBox::StandardButton p_defaultBtn, QWidget *p_parent, - MessageBoxType p_type = MessageBoxType::Normal); - - static void promptForReopen(QWidget *p_parent); - - static const QVector > &getAvailableLanguages(); - static bool isValidLanguage(const QString &p_lang); - static bool isImageURL(const QUrl &p_url); - static bool isImageURLText(const QString &p_url); - static qreal calculateScaleFactor(); - static bool realEqual(qreal p_a, qreal p_b); - - static QChar keyToChar(int p_key, bool p_smallCase = true); - - static QString getLocale(); - - static void sleepWait(int p_milliseconds); - - // Return the DocType according to suffix. - static DocType docTypeFromName(const QString &p_name); - - // Generate HTML template. - static QString generateHtmlTemplate(MarkdownConverterType p_conType); - - // @p_renderBg is the background name. - // @p_wkhtmltopdf: whether this template is used for wkhtmltopdf. - static QString generateHtmlTemplate(MarkdownConverterType p_conType, - const QString &p_renderBg, - const QString &p_renderStyle, - const QString &p_renderCodeBlockStyle, - bool p_isPDF, - bool p_wkhtmltopdf = false, - bool p_addToc = false); - - // @p_renderBg is the background name. - static QString generateExportHtmlTemplate(const QString &p_renderBg, - bool p_includeMathJax, - bool p_outlinePanel); - - static QString generateSimpleHtmlTemplate(const QString &p_body); - - // Generate template for MathJax preview. - static QString generateMathJaxPreviewTemplate(); - - // Get an available file name in @p_directory with base @p_baseFileName. - // If there already exists a file named @p_baseFileName, try to add sequence - // suffix to the name, such as _001. - // @p_completeBaseName: use complete base name or complete suffix. For example, - // "abc.tar.gz", if @p_completeBaseName is true, the base name is "abc.tar", - // otherwise, it is "abc". - static QString getFileNameWithSequence(const QString &p_directory, - const QString &p_baseFileName, - bool p_completeBaseName = true); - - // Get an available directory name in @p_directory with base @p_baseDirName. - // If there already exists a file named @p_baseFileName, try to add sequence - // suffix to the name, such as _001. - static QString getDirNameWithSequence(const QString &p_directory, - const QString &p_baseDirName); - - // Get an available random file name in @p_directory. - static QString getRandomFileName(const QString &p_directory); - - // Try to check if @p_path is legal. - static bool checkPathLegal(const QString &p_path); - - // Check if file/folder name is legal. - static bool checkFileNameLegal(const QString &p_name); - - // Returns true if @p_patha and @p_pathb points to the same file/directory. - static bool equalPath(const QString &p_patha, const QString &p_pathb); - - // Try to split @p_path into multiple parts based on @p_base. - // Returns false if @p_path is not under @p_base directory. - // @p_parts will be empty if @p_path is right @p_base. - // Example: "/home/tamlok/study", "/home/tamlok/study/a/b/c/vnote.md" - // returns true and @p_parts is {a, b, c, vnote.md}. - static bool splitPathInBasePath(const QString &p_base, - const QString &p_path, - QStringList &p_parts); - - // Decode URL by simply replacing meta-characters. - static void decodeUrl(QString &p_url); - - // Returns the shortcut text. - static QString getShortcutText(const QString &p_keySeq); - - // Delete directory recursively specified by @p_path. - // Will just move the directory to the recycle bin of @p_notebook if - // @p_skipRecycleBin is false. - static bool deleteDirectory(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin = false); - - static bool deleteDirectory(const QString &p_path); - - // Empty all files in directory recursively specified by @p_path. - // Will just move files to the recycle bin of @p_notebook if - // @p_skipRecycleBin is false. - static bool emptyDirectory(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin = false); - - // Delete file specified by @p_path. - // Will just move the file to the recycle bin of @p_notebook if - // @p_skipRecycleBin is false. - static bool deleteFile(const VNotebook *p_notebook, - const QString &p_path, - bool p_skipRecycleBin = false); - - // Delete file specified by @p_path. - // Will just move the file to the recycle bin of VOrphanFile if - // @p_skipRecycleBin is false. - static bool deleteFile(const VOrphanFile *p_file, - const QString &p_path, - bool p_skipRecycleBin = false); - - // Delete file specified by @p_path. - static bool deleteFile(const QString &p_path); - - // @p_uniformNum: if true, we use YYYY/MM/DD HH:mm:ss form, which is good for - // sorting. - static QString displayDateTime(const QDateTime &p_dateTime, bool p_uniformNum = false); - - // Check if file @p_name exists in @p_dir. - // @p_forceCaseInsensitive: if true, will check the name ignoring the case. - static bool fileExists(const QDir &p_dir, const QString &p_name, bool p_forceCaseInsensitive = false); - - // Assign @p_str to @p_msg if it is not NULL. - static void addErrMsg(QString *p_msg, const QString &p_str); - - // Check each file of @p_files and return valid ones for VNote to open. - static QStringList filterFilePathsToOpen(const QStringList &p_files); - - // Return the normalized file path of @p_file if it is valid to open. - // Return empty if it is not valid. - static QString validFilePathToOpen(const QString &p_file); - - // See if @p_modifiers is Control which is different on macOs and Windows. - static bool isControlModifierForVim(int p_modifiers); - - // If @p_file does not exists, create an empty file. - static void touchFile(const QString &p_file); - - // Ctrl, Meta, Shift, Alt. - static bool isMetaKey(int p_key); - - // Create and return a QComboBox. - static QComboBox *getComboBox(QWidget *p_parent = nullptr); - - static QWebEngineView *getWebEngineView(const QColor &p_background, QWidget *p_parent = nullptr); - - static void setDynamicProperty(QWidget *p_widget, const char *p_prop, bool p_val = true); - - // Return a doc file path. - static QString getDocFile(const QString &p_name); - - static QString getCaptainShortcutSequenceText(const QString &p_operation); - - static QString getAvailableFontFamily(const QStringList &p_families); - - static bool fixTextWithShortcut(QAction *p_act, const QString &p_shortcut); - - static bool fixTextWithCaptainShortcut(QAction *p_act, const QString &p_shortcut); - - // From QProcess code. - static QStringList parseCombinedArgString(const QString &p_program); - - // Read QImage from local file @p_filePath. - // Directly calling QImage(p_filePath) will judge the image format from the suffix, - // resulting a null image in wrong suffix case. - static QImage imageFromFile(const QString &p_filePath); - - static QPixmap pixmapFromFile(const QString &p_filePath); - - // Return QFormLayout. - static QFormLayout *getFormLayout(); - - static bool inSameDrive(const QString &p_a, const QString &p_b); - - static QString promptForFileName(const QString &p_title, - const QString &p_label, - const QString &p_default, - const QString &p_dir, - QWidget *p_parent = nullptr); - - static QString promptForFileName(const QString &p_title, - const QString &p_label, - const QString &p_default, - std::function p_checkExistsFunc, - QWidget *p_parent = nullptr); - - // Whether @p_html has only content. - static bool onlyHasImgInHtml(const QString &p_html); - - static int elapsedTime(bool p_reset = false); - - // Render SVG to Pixmap. - // @p_factor: < 0 indicates no scaling. - static QPixmap svgToPixmap(const QByteArray &p_content, - const QString &p_background, - qreal p_factor); - - // Fetch the image link's URL if there is only one link. - static QString fetchImageLinkUrlToPreview(const QString &p_text, int &p_width, int &p_height); - - static QString fetchImageLinkUrl(const QString &p_link); - - static QString fetchLinkUrl(const QString &p_link); - - static QUrl pathToUrl(const QString &p_path); - - // Return the name of the parent directory of @p_path. - // @p_path: file path of file or dir. - static QString parentDirName(const QString &p_path); - - // Remove query in the url (?xxx). - static QString purifyUrl(const QString &p_url); - - static QTemporaryFile *createTemporaryFile(QString p_suffix); - - static QString purifyImageTitle(QString p_title); - - static QString escapeHtml(QString p_text); - - static QString encodeSpacesInPath(const QString &p_path); - - static void prependDotIfRelative(QString &p_path); - - // Regular expression for image link. - // ![image title]( http://github.com/tamlok/vnote.jpg "alt text" =200x100) - // Captured texts (need to be trimmed): - // 1. Image Alt Text (Title); - // 2. Image URL; - // 3. Image Optional Title with double quotes or quotes; - // 4. Unused; - // 5. Unused; - // 6. Width and height text; - // 7. Width; - // 8. Height; - static const QString c_imageLinkRegExp; - - // Regular expression for image title. - static const QString c_imageTitleRegExp; - - // Regular expression for link. - // [link text]( http://github.com/tamlok "alt text") - // Captured texts (need to be trimmed): - // 1. Link Alt Text (Title); - // 2. Link URL; - // 3. Link Optional Title with double quotes or quotes; - // 4. Unused; - // 5. Unused; - static const QString c_linkRegExp; - - // Regular expression for file/directory name. - // Forbidden char: \/:*?"<>| and whitespaces except space. - static const QString c_fileNameRegExp; - - // Regular expression for fenced code block. - static const QString c_fencedCodeBlockStartRegExp; - static const QString c_fencedCodeBlockEndRegExp; - - // Regular expression for preview image block. - static const QString c_previewImageBlockRegExp; - - // Regular expression for header block. - // Captured texts: - // 1. Header marker (##); - // 2. Header Title (need to be trimmed); - // 3. Header Sequence (1.1., 1.2., optional); - // 4. Unused; - static const QString c_headerRegExp; - - // Regular expression for header block. - // Captured texts: - // 1. prefix till the real header title content; - static const QString c_headerPrefixRegExp; - - static const QString c_listRegExp; - - static const QString c_blockQuoteRegExp; - -private: - VUtils() {} - - static void initAvailableLanguage(); - - // Delete file/directory specified by @p_path by moving it to the recycle bin - // folder @p_recycleBinFolderPath. - static bool deleteFile(const QString &p_recycleBinFolderPath, - const QString &p_path); - - static QString generateHtmlTemplate(const QString &p_template, - MarkdownConverterType p_conType, - bool p_isPDF = false, - bool p_wkhtmltopdf = false, - bool p_addToc = false); - - // - static QVector> s_availableLanguages; -}; - -inline QString VUtils::directoryNameFromPath(const QString &p_path) -{ - return fileNameFromPath(p_path); -} - -#endif // VUTILS_H diff --git a/src/utils/vvim.cpp b/src/utils/vvim.cpp deleted file mode 100644 index 09115194..00000000 --- a/src/utils/vvim.cpp +++ /dev/null @@ -1,6520 +0,0 @@ -#include "vvim.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vconfigmanager.h" -#include "veditor.h" -#include "utils/veditutils.h" -#include "vconstants.h" -#include "vmdeditor.h" -#include "vmainwindow.h" -#include "vdirectory.h" -#include "vdirectorytree.h" - -extern VConfigManager *g_config; -extern VMainWindow *g_mainWin; - -const QChar VVim::c_unnamedRegister = QChar('"'); -const QChar VVim::c_blackHoleRegister = QChar('_'); -const QChar VVim::c_selectionRegister = QChar('+'); -QMap VVim::s_registers; - -const int VVim::SearchHistory::c_capacity = 50; - -#define ADDKEY(x, y) case (x): {ch = (y); break;} - -// Returns NULL QChar if invalid. -static QChar keyToChar(int p_key, int p_modifiers) -{ - if (p_key >= Qt::Key_0 && p_key <= Qt::Key_9) { - return QChar('0' + (p_key - Qt::Key_0)); - } else if (p_key >= Qt::Key_A && p_key <= Qt::Key_Z) { - if (p_modifiers == Qt::ShiftModifier - || VUtils::isControlModifierForVim(p_modifiers)) { - return QChar('A' + (p_key - Qt::Key_A)); - } else { - return QChar('a' + (p_key - Qt::Key_A)); - } - } - - QChar ch; - switch (p_key) { - ADDKEY(Qt::Key_Tab, '\t'); - ADDKEY(Qt::Key_Space, ' '); - ADDKEY(Qt::Key_Exclam, '!'); - ADDKEY(Qt::Key_QuoteDbl, '"'); - ADDKEY(Qt::Key_NumberSign, '#'); - ADDKEY(Qt::Key_Dollar, '$'); - ADDKEY(Qt::Key_Percent, '%'); - ADDKEY(Qt::Key_Ampersand, '&'); - ADDKEY(Qt::Key_Apostrophe, '\''); - ADDKEY(Qt::Key_ParenLeft, '('); - ADDKEY(Qt::Key_ParenRight, ')'); - ADDKEY(Qt::Key_Asterisk, '*'); - ADDKEY(Qt::Key_Plus, '+'); - ADDKEY(Qt::Key_Comma, ','); - ADDKEY(Qt::Key_Minus, '-'); - ADDKEY(Qt::Key_Period, '.'); - ADDKEY(Qt::Key_Slash, '/'); - ADDKEY(Qt::Key_Colon, ':'); - ADDKEY(Qt::Key_Semicolon, ';'); - ADDKEY(Qt::Key_Less, '<'); - ADDKEY(Qt::Key_Equal, '='); - ADDKEY(Qt::Key_Greater, '>'); - ADDKEY(Qt::Key_Question, '?'); - ADDKEY(Qt::Key_At, '@'); - ADDKEY(Qt::Key_BracketLeft, '['); - ADDKEY(Qt::Key_Backslash, '\\'); - ADDKEY(Qt::Key_BracketRight, ']'); - ADDKEY(Qt::Key_AsciiCircum, '^'); - ADDKEY(Qt::Key_Underscore, '_'); - ADDKEY(Qt::Key_QuoteLeft, '`'); - ADDKEY(Qt::Key_BraceLeft, '{'); - ADDKEY(Qt::Key_Bar, '|'); - ADDKEY(Qt::Key_BraceRight, '}'); - ADDKEY(Qt::Key_AsciiTilde, '~'); - - default: - break; - } - - return ch; -} - -#define ADDCHAR(x, y) case (x): {p_key = (y); break;} -#define ADDCHAR_SHIFT(x, y) case (x): {p_key = (y); p_modifiers = Qt::ShiftModifier; break;} - -static void charToKey(const QChar &p_char, int &p_key, int &p_modifiers) -{ - p_modifiers = Qt::NoModifier; - - ushort ucode = p_char.unicode(); - if (ucode >= '0' && ucode <= '9') { - p_key = Qt::Key_0 + ucode - '0'; - return; - } else if (ucode >= 'a' && ucode <= 'z') { - p_key = Qt::Key_A + ucode - 'a'; - return; - } else if (ucode >= 'A' && ucode <= 'Z') { - p_key = Qt::Key_A + ucode - 'A'; - p_modifiers = Qt::ShiftModifier; - return; - } - - switch (p_char.unicode()) { - ADDCHAR('\t', Qt::Key_Tab); - ADDCHAR(' ', Qt::Key_Space); - ADDCHAR_SHIFT('!', Qt::Key_Exclam); - ADDCHAR_SHIFT('"', Qt::Key_QuoteDbl); - ADDCHAR_SHIFT('#', Qt::Key_NumberSign); - ADDCHAR_SHIFT('$', Qt::Key_Dollar); - ADDCHAR_SHIFT('%', Qt::Key_Percent); - ADDCHAR_SHIFT('&', Qt::Key_Ampersand); - ADDCHAR('\'', Qt::Key_Apostrophe); - ADDCHAR_SHIFT('(', Qt::Key_ParenLeft); - ADDCHAR_SHIFT(')', Qt::Key_ParenRight); - ADDCHAR_SHIFT('*', Qt::Key_Asterisk); - ADDCHAR_SHIFT('+', Qt::Key_Plus); - ADDCHAR(',', Qt::Key_Comma); - ADDCHAR('-', Qt::Key_Minus); - ADDCHAR('.', Qt::Key_Period); - ADDCHAR('/', Qt::Key_Slash); - ADDCHAR_SHIFT(':', Qt::Key_Colon); - ADDCHAR(';', Qt::Key_Semicolon); - ADDCHAR_SHIFT('<', Qt::Key_Less); - ADDCHAR('=', Qt::Key_Equal); - ADDCHAR_SHIFT('>', Qt::Key_Greater); - ADDCHAR_SHIFT('?', Qt::Key_Question); - ADDCHAR_SHIFT('@', Qt::Key_At); - ADDCHAR('[', Qt::Key_BracketLeft); - ADDCHAR('\\', Qt::Key_Backslash); - ADDCHAR(']', Qt::Key_BracketRight); - ADDCHAR_SHIFT('^', Qt::Key_AsciiCircum); - ADDCHAR_SHIFT('_', Qt::Key_Underscore); - ADDCHAR('`', Qt::Key_QuoteLeft); - ADDCHAR_SHIFT('{', Qt::Key_BraceLeft); - ADDCHAR_SHIFT('|', Qt::Key_Bar); - ADDCHAR_SHIFT('}', Qt::Key_BraceRight); - ADDCHAR_SHIFT('~', Qt::Key_AsciiTilde); - - default: - p_key = -1; - break; - } -} - -static QString keyToString(int p_key, int p_modifiers) -{ - QChar ch = keyToChar(p_key, p_modifiers); - if (ch.isNull()) { - return QString(); - } - - if (VUtils::isControlModifierForVim(p_modifiers)) { - return QString("^") + ch; - } else { - return ch; - } -} - -VVim::VVim(VEditor *p_editor) - : QObject(p_editor->getEditor()), - m_editor(p_editor), - m_editConfig(&p_editor->getConfig()), - m_mode(VimMode::Invalid), - m_resetPositionInBlock(true), - m_regName(c_unnamedRegister), - m_leaderKey(Key(Qt::Key_Space)), - m_replayLeaderSequence(false), - m_registerPending(false), - m_insertModeAfterCommand(false), - m_positionBeforeVisualMode(0) -{ - Q_ASSERT(m_editConfig->m_enableVimMode); - - setMode(VimMode::Normal); - - initLeaderKey(); - - initRegisters(); - - connect(m_editor->object(), &VEditorObject::mousePressed, - this, &VVim::handleMousePressed); - connect(m_editor->object(), &VEditorObject::mouseMoved, - this, &VVim::handleMouseMoved); - connect(m_editor->object(), &VEditorObject::mouseReleased, - this, &VVim::handleMouseReleased); - connect(m_editor->object(), &VEditorObject::mouseDoubleClicked, - this, &VVim::handleMouseDoubleClicked); -} - -void VVim::initLeaderKey() -{ - QChar ch = g_config->getVimLeaderKey(); - Q_ASSERT(!ch.isNull()); - - int key, modifiers; - charToKey(ch, key, modifiers); - m_leaderKey = Key(key, modifiers); - qDebug() << "Vim leader key" << ch << key << modifiers; -} - -// Set @p_cursor's position specified by @p_positionInBlock. -// If @p_positionInBlock is bigger than the block's length, move to the end of block. -// Need to setTextCursor() after calling this. -static void setCursorPositionInBlock(QTextCursor &p_cursor, int p_positionInBlock, - QTextCursor::MoveMode p_mode) -{ - QTextBlock block = p_cursor.block(); - if (block.length() > p_positionInBlock) { - p_cursor.setPosition(block.position() + p_positionInBlock, p_mode); - } else { - p_cursor.movePosition(QTextCursor::EndOfBlock, p_mode, 1); - } -} - -// Find the start and end of the spaces @p_cursor locates in (within a single block). -// @p_start and @p_end will be the global position of the start and end of the spaces. -// @p_start will equals to @p_end if @p_cursor is not a space. -static void findCurrentSpace(const QTextCursor &p_cursor, int &p_start, int &p_end) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - - if (pib < text.size() && !text[pib].isSpace()) { - p_start = p_end = p_cursor.position(); - return; - } - - p_start = 0; - for (int i = pib - 1; i >= 0; --i) { - if (!text[i].isSpace()) { - p_start = i + 1; - break; - } - } - - p_end = block.length() - 1; - for (int i = pib; i < text.size(); ++i) { - if (!text[i].isSpace()) { - p_end = i; - break; - } - } - - p_start += block.position(); - p_end += block.position(); -} - -// Move @p_cursor to skip spaces if current cursor is placed at a space -// (may move across blocks). It will stop by the empty block on the way. -// Forward: wwwwsssss|wwww -// Backward: wwww|ssssswwww -static void moveCursorAcrossSpaces(QTextCursor &p_cursor, - QTextCursor::MoveMode p_mode, - bool p_forward, - bool p_stopAtBoundary = false) -{ - while (true) { - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int pib = p_cursor.positionInBlock(); - - if (p_forward) { - for (; pib < text.size(); ++pib) { - if (!text[pib].isSpace()) { - break; - } - } - - if (pib == text.size() && !p_stopAtBoundary) { - // Move to next block. - p_cursor.movePosition(QTextCursor::Down, p_mode, 1); - if (block.blockNumber() == p_cursor.block().blockNumber()) { - // Already at the last block. - p_cursor.movePosition(QTextCursor::EndOfBlock, p_mode, 1); - break; - } else { - p_cursor.movePosition(QTextCursor::StartOfBlock, p_mode, 1); - if (p_cursor.block().length() <= 1) { - break; - } - } - } else { - // Found non-space character. - p_cursor.setPosition(block.position() + pib, p_mode); - break; - } - } else { - int idx = pib - 1; - for (; idx >= 0; --idx) { - if (!text[idx].isSpace()) { - break; - } - } - - if (idx == -1 && !p_stopAtBoundary) { - // Move to previous block. - p_cursor.movePosition(QTextCursor::Up, p_mode, 1); - if (block.blockNumber() == p_cursor.block().blockNumber()) { - // Already at the first block. - p_cursor.movePosition(QTextCursor::StartOfBlock, p_mode, 1); - break; - } else { - p_cursor.movePosition(QTextCursor::EndOfBlock, p_mode, 1); - if (p_cursor.block().length() <= 1) { - break; - } - } - } else { - // Found non-space character. - p_cursor.setPosition(block.position() + idx + 1, p_mode); - break; - } - } - } -} - -// Expand the selection of @p_cursor to contain additional spaces at the two ends -// within a block. -static void expandSelectionAcrossSpacesWithinBlock(QTextCursor &p_cursor) -{ - QTextBlock block = p_cursor.block(); - QString text = block.text(); - int start = p_cursor.selectionStart() - block.position(); - int end = p_cursor.selectionEnd() - block.position(); - - for (int i = start - 1; i >= 0; --i) { - if (!text[i].isSpace()) { - start = i + 1; - break; - } - } - - for (int i = end; i < text.size(); ++i) { - if (!text[i].isSpace()) { - end = i; - break; - } - } - - start += block.position(); - end += block.position(); - - if (start == p_cursor.selectionStart() && end == p_cursor.selectionEnd()) { - return; - } - - if (p_cursor.anchor() <= p_cursor.position()) { - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - p_cursor.setPosition(end, QTextCursor::KeepAnchor); - } else { - p_cursor.setPosition(end, QTextCursor::MoveAnchor); - p_cursor.setPosition(start, QTextCursor::KeepAnchor); - } -} - -// In Change action, after deleting selected block text, we need to insert a new -// block for user input. -// @p_deletionStart is the global position of the start of the deletion. -// Should be called immediately after the deletion. -static void insertChangeBlockAfterDeletion(QTextCursor &p_cursor, int p_deletionStart) -{ - if (p_cursor.position() < p_deletionStart) { - // Insert a new block below. - p_cursor.movePosition(QTextCursor::EndOfBlock); - p_cursor.insertBlock(); - } else { - // Insert a new block above. - p_cursor.movePosition(QTextCursor::StartOfBlock); - p_cursor.insertBlock(); - p_cursor.movePosition(QTextCursor::PreviousBlock); - } - - if (g_config->getAutoIndent()) { - VEditUtils::indentBlockAsBlock(p_cursor, false); - } -} - -// Given the percentage of the text, return the corresponding block number. -// Notice that the block number is based on 0. -// Returns -1 if it is not valid. -static int percentageToBlockNumber(const QTextDocument *p_doc, int p_percent) -{ - if (p_percent > 100 || p_percent <= 0) { - return -1; - } - - int nrBlock = p_doc->blockCount(); - int num = nrBlock * (p_percent * 1.0 / 100) - 1; - - return num >= 0 ? num : 0; -} - -// Replace each of the character of selected text with @p_char. -// Returns true if replacement has taken place. -// Need to setTextCursor() after calling this. -static bool replaceSelectedTextWithCharacter(QTextCursor &p_cursor, QChar p_char) -{ - if (!p_cursor.hasSelection()) { - return false; - } - - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - while (p_cursor.position() < end) { - if (p_cursor.atBlockEnd()) { - p_cursor.movePosition(QTextCursor::NextCharacter); - } else { - p_cursor.deleteChar(); - // insertText() will move the cursor right after the inserted text. - p_cursor.insertText(p_char); - } - } - - return true; -} - -// Reverse the case of selected text. -// Returns true if the reverse has taken place. -// Need to setTextCursor() after calling this. -static bool reverseSelectedTextCase(QTextCursor &p_cursor) -{ - if (!p_cursor.hasSelection()) { - return false; - } - - QTextDocument *doc = p_cursor.document(); - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - while (p_cursor.position() < end) { - if (p_cursor.atBlockEnd()) { - p_cursor.movePosition(QTextCursor::NextCharacter); - } else { - QChar ch = doc->characterAt(p_cursor.position()); - bool changed = false; - if (ch.isLower()) { - ch = ch.toUpper(); - changed = true; - } else if (ch.isUpper()) { - ch = ch.toLower(); - changed = true; - } - - if (changed) { - p_cursor.deleteChar(); - // insertText() will move the cursor right after the inserted text. - p_cursor.insertText(ch); - } else { - p_cursor.movePosition(QTextCursor::NextCharacter); - } - } - } - - return true; -} - -// Join current cursor line and the next line. -static void joinTwoLines(QTextCursor &p_cursor, bool p_modifySpaces) -{ - QTextDocument *doc = p_cursor.document(); - QTextBlock firstBlock = p_cursor.block(); - QString textToAppend = firstBlock.next().text(); - p_cursor.movePosition(QTextCursor::EndOfBlock); - - if (p_modifySpaces) { - bool insertSpaces = false; - if (firstBlock.length() > 1) { - QChar lastChar = doc->characterAt(p_cursor.position() - 1); - if (!lastChar.isSpace()) { - insertSpaces = true; - } - } - - if (insertSpaces) { - p_cursor.insertText(" "); - } - - // Remove indentation. - int idx = 0; - for (idx = 0; idx < textToAppend.size(); ++idx) { - if (!textToAppend[idx].isSpace()) { - break; - } - } - - textToAppend = textToAppend.right(textToAppend.size() - idx); - } - - // Now p_cursor is at the end of the first block. - int position = p_cursor.block().position() + p_cursor.positionInBlock(); - p_cursor.insertText(textToAppend); - - // Delete the second block. - p_cursor.movePosition(QTextCursor::NextBlock); - VEditUtils::removeBlock(p_cursor); - - // Position p_cursor right at the front of appended text. - p_cursor.setPosition(position); -} - -// Join lines specified by [@p_firstBlock, @p_firstBlock + p_blockCount). -// Need to check the block range (based on 0). -static bool joinLines(QTextCursor &p_cursor, - int p_firstBlock, - int p_blockCount, - bool p_modifySpaces) -{ - QTextDocument *doc = p_cursor.document(); - int totalBlockCount = doc->blockCount(); - if (p_blockCount <= 0 - || p_firstBlock >= totalBlockCount - 1) { - return false; - } - - p_blockCount = qMin(p_blockCount, totalBlockCount - p_firstBlock); - p_cursor.setPosition(doc->findBlockByNumber(p_firstBlock).position()); - for (int i = 1; i < p_blockCount; ++i) { - joinTwoLines(p_cursor, p_modifySpaces); - } - - return true; -} - -bool VVim::handleKeyPressEvent(QKeyEvent *p_event, int *p_autoIndentPos) -{ - int modifiers = p_event->modifiers(); - QString keyText = p_event->text(); - if (keyText.size() == 1) { - if (keyText[0].isUpper()) { - // Upper case. - modifiers |= Qt::ShiftModifier; - } else if (keyText[0].isLower()) { - // Lower case. - if (modifiers & Qt::ShiftModifier) { - modifiers &= ~Qt::ShiftModifier; - } - } - } - - bool ret = handleKeyPressEvent(p_event->key(), modifiers, p_autoIndentPos); - if (ret) { - p_event->accept(); - } - - return ret; -} - -bool VVim::handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos) -{ - bool ret = false; - bool resetPositionInBlock = true; - Key keyInfo(key, modifiers); - bool unindent = false; - int autoIndentPos = p_autoIndentPos ? *p_autoIndentPos : -1; - - // Handle Insert mode key press. - if (VimMode::Insert == m_mode) { - if (checkEnterNormalMode(key, modifiers)) { - // See if we need to cancel auto indent. - bool cancelAutoIndent = false; - if (p_autoIndentPos && *p_autoIndentPos > -1) { - QTextCursor cursor = m_editor->textCursorW(); - cancelAutoIndent = VEditUtils::needToCancelAutoIndent(*p_autoIndentPos, cursor); - - if (cancelAutoIndent) { - autoIndentPos = -1; - VEditUtils::deleteIndentAndListMark(cursor); - m_editor->setTextCursorW(cursor); - } - } - - // Clear selection and enter Normal mode. - if (!cancelAutoIndent) { - clearSelection(); - } - - setMode(VimMode::Normal); - goto clear_accept; - } - - if (m_registerPending) { - // Ctrl and Shift may be sent out first. - if (VUtils::isMetaKey(key)) { - goto accept; - } - - // Expecting a register name. - QChar reg = keyToRegisterName(keyInfo); - if (!reg.isNull()) { - // Insert register content. - m_editor->insertPlainTextW(getRegister(reg).read()); - } - - goto clear_accept; - } else if (key == Qt::Key_R && VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+R, insert the content of a register. - m_pendingKeys.append(keyInfo); - m_registerPending = true; - goto accept; - } - - if (key == Qt::Key_O && VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+O, enter normal mode, execute one command, then return to insert mode. - m_insertModeAfterCommand = true; - clearSelection(); - setMode(VimMode::Normal); - goto accept; - } - - // Let it be handled outside VVim. - goto exit; - } - - // Ctrl and Shift may be sent out first. - if (isKeyShouldBeIgnored(key)) { - goto accept; - } - - if (m_replayLeaderSequence) { - qDebug() << "replaying sequence" << keyToChar(key, modifiers); - } - - m_pendingKeys.append(keyInfo); - - if (expectingLeaderSequence()) { - if (processLeaderSequence(keyInfo)) { - goto accept; - } else { - goto clear_accept; - } - } - - if (expectingRegisterName()) { - // Expecting a register name. - QChar reg = keyToRegisterName(keyInfo); - if (!reg.isNull()) { - m_keys.clear(); - setCurrentRegisterName(reg); - Register &r = getRegister(reg); - if (r.isNamedRegister()) { - r.m_append = (modifiers == Qt::ShiftModifier); - } else { - Q_ASSERT(!r.m_append); - } - - goto accept; - } - - goto clear_accept; - } - - if (expectingMarkName()) { - // Expecting a mark name to create a mark. - if (keyInfo.isAlphabet() && modifiers == Qt::NoModifier) { - m_keys.clear(); - m_marks.setMark(keyToChar(key, modifiers), m_editor->textCursorW()); - } - - goto clear_accept; - } - - if (expectingMarkTarget()) { - // Expecting a mark name as the target. - Movement mm = Movement::Invalid; - const Key &aKey = m_keys.first(); - if (aKey == Key(Qt::Key_Apostrophe)) { - mm = Movement::MarkJumpLine; - } else { - Q_ASSERT(aKey == Key(Qt::Key_QuoteLeft)); - mm = Movement::MarkJump; - } - - tryAddMoveAction(); - addMovementToken(mm, keyInfo); - processCommand(m_tokens); - goto clear_accept; - } - - if (expectingCharacterTarget()) { - // Expecting a target character for f/F/t/T. - Movement mm = Movement::Invalid; - const Key &aKey = m_keys.first(); - if (aKey.m_key == Qt::Key_F) { - if (aKey.m_modifiers == Qt::NoModifier) { - mm = Movement::FindForward; - } else { - mm = Movement::FindBackward; - } - } else { - if (aKey.m_modifiers == Qt::NoModifier) { - mm = Movement::TillForward; - } else { - mm = Movement::TillBackward; - } - } - - tryAddMoveAction(); - addMovementToken(mm, keyInfo); - m_lastFindToken = m_tokens.last(); - processCommand(m_tokens); - - goto clear_accept; - } - - if (expectingReplaceCharacter()) { - // Expecting a character to replace with for r. - addActionToken(Action::Replace); - addKeyToken(keyInfo); - processCommand(m_tokens); - - goto clear_accept; - } - - // Check leader key here. If leader key conflicts with other keys, it will - // overwrite it. - // Leader sequence is just like an action. - if (keyInfo == m_leaderKey - && !hasActionToken() - && !hasNonDigitPendingKeys() - && !m_replayLeaderSequence) { - tryGetRepeatToken(m_keys, m_tokens); - - Q_ASSERT(m_keys.isEmpty()); - - m_pendingKeys.pop_back(); - m_pendingKeys.append(Key(Qt::Key_Backslash)); - m_keys.append(Key(Qt::Key_Backslash)); - goto accept; - } - - // We will add key to m_keys. If all m_keys can combined to a token, add - // a new token to m_tokens, clear m_keys and try to process m_tokens. - switch (key) { - case Qt::Key_0: - { - if (modifiers == Qt::NoModifier - || modifiers == Qt::KeypadModifier) { - if (checkPendingKey(Key(Qt::Key_G))) { - // StartOfVisualLine. - tryAddMoveAction(); - m_tokens.append(Token(Movement::StartOfVisualLine)); - processCommand(m_tokens); - } else if (m_keys.isEmpty()) { - // StartOfLine. - tryAddMoveAction(); - m_tokens.append(Token(Movement::StartOfLine)); - processCommand(m_tokens); - } else if (m_keys.last().isDigit()) { - // Repeat. - m_keys.append(keyInfo); - resetPositionInBlock = false; - goto accept; - } - } - - break; - } - - case Qt::Key_1: - case Qt::Key_2: - case Qt::Key_3: - case Qt::Key_4: - case Qt::Key_5: - case Qt::Key_6: - case Qt::Key_7: - case Qt::Key_8: - case Qt::Key_9: - { - if (modifiers == Qt::NoModifier - || modifiers == Qt::KeypadModifier) { - if (!m_keys.isEmpty() && numberFromKeySequence(m_keys) == -1) { - // Invalid sequence. - break; - } - - m_keys.append(keyInfo); - resetPositionInBlock = false; - goto accept; - } - - break; - } - - case Qt::Key_Left: - case Qt::Key_Down: - case Qt::Key_Up: - case Qt::Key_Right: - case Qt::Key_H: - case Qt::Key_J: - case Qt::Key_K: - case Qt::Key_L: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier) { - // Check if we could generate a Repeat token. - tryGetRepeatToken(m_keys, m_tokens); - - // Generate a Movement token. - Movement mm = Movement::Invalid; - - if (!m_keys.isEmpty()) { - // gj, gk. - Key gKey(Qt::Key_G); - if (m_keys.size() == 1 && m_keys.at(0) == gKey) { - if (key == Qt::Key_J) { - mm = Movement::VisualDown; - } else if (key == Qt::Key_K) { - mm = Movement::VisualUp; - } else { - break; - } - } else { - // Not a valid sequence. - break; - } - } else { - // h, j, k, l. - switch (key) { - case Qt::Key_H: - case Qt::Key_Left: - mm = Movement::Left; - break; - - case Qt::Key_L: - case Qt::Key_Right: - mm = Movement::Right; - break; - - case Qt::Key_J: - case Qt::Key_Down: - mm = Movement::Down; - break; - - case Qt::Key_K: - case Qt::Key_Up: - mm = Movement::Up; - break; - - default: - V_ASSERT(false); - } - } - - V_ASSERT(mm != Movement::Invalid); - tryAddMoveAction(); - addMovementToken(mm); - processCommand(m_tokens); - resetPositionInBlock = false; - } else if (modifiers == Qt::ShiftModifier) { - if (key == Qt::Key_J) { - tryGetRepeatToken(m_keys, m_tokens); - - if (hasActionToken()) { - break; - } - - if (checkPendingKey(Key(Qt::Key_G))) { - // gJ, JoinNoModification. - addActionToken(Action::JoinNoModification); - } else if (m_keys.isEmpty()) { - // J, Join. - addActionToken(Action::Join); - } - - processCommand(m_tokens); - } - } else if (VUtils::isControlModifierForVim(modifiers)) { - if (key == Qt::Key_J || key == Qt::Key_K) { - // Let it be handled outside. - resetState(); - goto exit; - } - } - - break; - } - - case Qt::Key_I: - { - if (modifiers == Qt::NoModifier) { - if (hasActionTokenValidForTextObject()) { - // Inner text object. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Invalid sequence; - break; - } - - m_keys.append(keyInfo); - goto accept; - } - - // Enter Insert mode. - // Different from Vim: - // We enter Insert mode even in Visual and VisualLine mode. We - // also keep the selection after the mode change. - if (checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine)) { - setMode(VimMode::Insert, false); - } - } else if (modifiers == Qt::ShiftModifier) { - QTextCursor cursor = m_editor->textCursorW(); - if (m_mode == VimMode::Normal) { - // Insert at the first non-space character. - VEditUtils::moveCursorFirstNonSpaceCharacter(cursor, QTextCursor::MoveAnchor); - } else if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - // Insert at the start of line. - cursor.movePosition(QTextCursor::StartOfBlock, - QTextCursor::MoveAnchor, - 1); - } - - m_editor->setTextCursorW(cursor); - setMode(VimMode::Insert); - } else if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+I, jump to next location. - if (!m_tokens.isEmpty() - || !checkMode(VimMode::Normal)) { - break; - } - - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - addActionToken(Action::JumpNextLocation); - processCommand(m_tokens); - break; - } - - break; - } - - case Qt::Key_A: - { - if (modifiers == Qt::NoModifier) { - if (hasActionTokenValidForTextObject()) { - // Around text object. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Invalid sequence; - break; - } - - m_keys.append(keyInfo); - goto accept; - } - - // Enter Insert mode. - // Move cursor back one character. - if (m_mode == VimMode::Normal) { - QTextCursor cursor = m_editor->textCursorW(); - V_ASSERT(!cursor.hasSelection()); - - if (!cursor.atBlockEnd()) { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - m_editor->setTextCursorW(cursor); - } - - setMode(VimMode::Insert); - } - } else if (modifiers == Qt::ShiftModifier) { - // Insert at the end of line. - QTextCursor cursor = m_editor->textCursorW(); - if (m_mode == VimMode::Normal) { - cursor.movePosition(QTextCursor::EndOfBlock, - QTextCursor::MoveAnchor, - 1); - m_editor->setTextCursorW(cursor); - } else if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - if (!cursor.atBlockEnd()) { - cursor.clearSelection(); - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - m_editor->setTextCursorW(cursor); - } - } - - setMode(VimMode::Insert); - } - - break; - } - - case Qt::Key_O: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // Insert a new block under/above current block and enter insert mode. - bool insertAbove = modifiers == Qt::ShiftModifier; - if (m_mode == VimMode::Normal) { - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - cursor.movePosition(insertAbove ? QTextCursor::StartOfBlock - : QTextCursor::EndOfBlock, - QTextCursor::MoveAnchor, - 1); - - cursor.insertBlock(); - - if (insertAbove) { - cursor.movePosition(QTextCursor::PreviousBlock, - QTextCursor::MoveAnchor, - 1); - } - - bool textInserted = false; - if (g_config->getAutoIndent()) { - textInserted = VEditUtils::indentBlockAsBlock(cursor, false); - bool listInserted = false; - if (g_config->getAutoList()) { - listInserted = VEditUtils::insertListMarkAsPreviousBlock(cursor); - textInserted = listInserted || textInserted; - } - - if (!listInserted && g_config->getAutoQuote()) { - textInserted = VEditUtils::insertQuoteMarkAsPreviousBlock(cursor) - || textInserted; - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - - if (textInserted) { - autoIndentPos = cursor.position(); - } - - setMode(VimMode::Insert); - } - - break; - } else if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+O, jump to previous location. - if (!m_tokens.isEmpty() - || !checkMode(VimMode::Normal)) { - break; - } - - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - addActionToken(Action::JumpPreviousLocation); - processCommand(m_tokens); - break; - } - - break; - } - - case Qt::Key_S: - { - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty() || hasActionToken()) { - break; - } - - if (modifiers == Qt::NoModifier) { - addActionToken(Action::Change); - // Movement will be ignored in Visual mode. - addMovementToken(Movement::Right); - processCommand(m_tokens); - } else if (modifiers == Qt::ShiftModifier) { - // S, change current line. - addActionToken(Action::Change); - addRangeToken(Range::Line); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_Dollar: - { - if (modifiers == Qt::ShiftModifier) { - // $, move to end of line. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - tryAddMoveAction(); - - m_tokens.append(Token(Movement::EndOfLine)); - processCommand(m_tokens); - } - } - - break; - } - - case Qt::Key_G: - { - Movement mm = Movement::Invalid; - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty()) { - // First g, pend it. - m_keys.append(keyInfo); - goto accept; - } else if (m_keys.size() == 1 && m_keys.at(0) == keyInfo) { - // gg, go to a certain line or first line. - if (!m_tokens.isEmpty() && m_tokens.last().isRepeat()) { - mm = Movement::LineJump; - } else { - mm = Movement::StartOfDocument; - } - } - } else if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty()) { - // G, go to a certain line or the last line. - if (!m_tokens.isEmpty() && m_tokens.last().isRepeat()) { - mm = Movement::LineJump; - } else { - mm = Movement::EndOfDocument; - } - } - } - - if (mm != Movement::Invalid) { - tryAddMoveAction(); - - m_tokens.append(Token(mm)); - processCommand(m_tokens); - } - - break; - } - - // Should be kept together with Qt::Key_PageUp. - case Qt::Key_B: - { - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+B, page up, fall through. - modifiers = Qt::NoModifier; - } else if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - if (modifiers == Qt::NoModifier && checkPendingKey(Key(Qt::Key_Z))) { - // zb, redraw to make a certain line the bottom of window. - addActionToken(Action::RedrawAtBottom); - processCommand(m_tokens); - break; - } - - break; - } - - // b, go to the start of previous or current word. - Movement mm = Movement::WordBackward; - if (modifiers == Qt::ShiftModifier) { - // B, go to the start of previous or current WORD. - mm = Movement::WORDBackward; - } - - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - break; - } else { - break; - } - - V_FALLTHROUGH; - } - - case Qt::Key_PageUp: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::PageUp; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - resetPositionInBlock = false; - } - - break; - } - - case Qt::Key_U: - { - tryGetRepeatToken(m_keys, m_tokens); - bool toLower = modifiers == Qt::NoModifier; - - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+U, HalfPageUp. - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::HalfPageUp; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - resetPositionInBlock = false; - } else if (m_keys.isEmpty() && !hasActionToken()) { - if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - // u/U for tolower and toupper selected text. - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - // Different from Vim: - // If there is no selection in Visual mode, we do nothing. - if (m_mode == VimMode::VisualLine) { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 changed").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - - convertCaseOfSelectedText(cursor, toLower); - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - - setMode(VimMode::Normal); - break; - } - - // u, Undo. - if (modifiers == Qt::NoModifier) { - addActionToken(Action::Undo); - processCommand(m_tokens); - } - break; - } else { - if (hasActionToken()) { - // guu/gUU. - if ((toLower && checkActionToken(Action::ToLower)) - || (!toLower && checkActionToken(Action::ToUpper))) { - addRangeToken(Range::Line); - processCommand(m_tokens); - break; - } else { - // An invalid sequence. - break; - } - } else if (checkPendingKey(Key(Qt::Key_G))) { - // gu/gU, ToLower/ToUpper action. - if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - // Different from Vim: - // If there is no selection in Visual mode, we do nothing. - if (m_mode == VimMode::VisualLine) { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 changed").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - - convertCaseOfSelectedText(cursor, toLower); - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - setMode(VimMode::Normal); - break; - } - - addActionToken(toLower ? Action::ToLower : Action::ToUpper); - m_keys.clear(); - goto accept; - } else { - // An invalid sequence. - break; - } - } - - break; - } - - // Ctrl+F is used for Find dialog, not used here. - case Qt::Key_PageDown: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::PageDown; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - resetPositionInBlock = false; - } - - break; - } - - case Qt::Key_D: - { - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+D, HalfPageDown. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::HalfPageDown; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - resetPositionInBlock = false; - } else if (modifiers == Qt::NoModifier) { - // d, delete action. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // This is another d, something like dd. - if (checkActionToken(Action::Delete)) { - addRangeToken(Range::Line); - processCommand(m_tokens); - break; - } else { - // An invalid sequence. - break; - } - } else { - // The first d, an Action. - addActionToken(Action::Delete); - if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - // Movement will be ignored. - addMovementToken(Movement::Left); - processCommand(m_tokens); - setMode(VimMode::Normal); - break; - } - - goto accept; - } - } else if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!hasActionToken()) { - if (checkMode(VimMode::Normal)) { - // D, same as d$. - addActionToken(Action::Delete); - addMovementToken(Movement::EndOfLine); - processCommand(m_tokens); - } else if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - // D, same as dd. - addActionToken(Action::Delete); - addRangeToken(Range::Line); - processCommand(m_tokens); - setMode(VimMode::Normal); - } - } - - break; - } - - break; - } - - case Qt::Key_BracketRight: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BracketInner/BracketAround. - Range range = Range::BracketInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BracketAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (hasActionToken() || !checkMode(VimMode::Normal)) { - // Invalid sequence. - break; - } else if (m_keys.isEmpty()) { - // First ], pend it. - m_keys.append(keyInfo); - goto accept; - } else if (checkPendingKey(keyInfo)) { - // ]], goto next title, regardless of level. - processTitleJump(m_tokens, true, 1); - } else if (checkPendingKey(Key(Qt::Key_BracketLeft))) { - // [], goto previous title at the same level. - processTitleJump(m_tokens, false, 0); - } - - break; - } - - break; - } - - // Should be kept together with Qt::Key_Escape. - case Qt::Key_BracketLeft: - { - if (VUtils::isControlModifierForVim(modifiers)) { - clearSelectionAndEnterNormalMode(); - } else if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BracketInner/BracketAround. - Range range = Range::BracketInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BracketAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (hasActionToken() || !checkMode(VimMode::Normal)) { - // Invalid sequence. - break; - } else if (m_keys.isEmpty()) { - // First [, pend it. - m_keys.append(keyInfo); - goto accept; - } else if (checkPendingKey(keyInfo)) { - // [[, goto previous title, regardless of level. - processTitleJump(m_tokens, false, 1); - } else if (checkPendingKey(Key(Qt::Key_BracketRight))) { - // ][, goto next title at the same level. - processTitleJump(m_tokens, true, 0); - } - } - - break; - } - - case Qt::Key_Escape: - { - clearSelectionAndEnterNormalMode(); - break; - } - - case Qt::Key_V: - { - if (modifiers == Qt::NoModifier) { - if (checkMode(VimMode::Visual)) { - setMode(VimMode::Normal, true); - } else { - // Toggle Visual Mode. - setMode(VimMode::Visual); - maintainSelectionInVisualMode(); - } - } else if (modifiers == Qt::ShiftModifier) { - // Visual Line Mode. - clearSelection(); - VimMode mode = VimMode::VisualLine; - if (m_mode == VimMode::VisualLine) { - mode = VimMode::Normal; - } - - setMode(mode); - - if (m_mode == VimMode::VisualLine) { - QTextCursor cursor = m_editor->textCursorW(); - expandSelectionToWholeLines(cursor); - m_editor->setTextCursorW(cursor); - } - } else if (VUtils::isControlModifierForVim(modifiers)) { - if (g_config->getVimExemptionKeys().contains('v')) { - // Let it be handled outside. - resetState(); - goto exit; - } - } - - break; - } - - case Qt::Key_AsciiCircum: - { - if (modifiers == Qt::ShiftModifier) { - // ^, go to first non-space character of current line (block). - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - Movement mm = Movement::FirstCharacter; - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_W: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - bool shift = modifiers == Qt::ShiftModifier; - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // WordInner/WORDInner/WordAournd/WORDAround. - bool around = checkPendingKey(Key(Qt::Key_A)); - Range range = Range::Invalid; - if (shift) { - if (around) { - range = Range::WORDAround; - } else { - range = Range::WORDInner; - } - } else { - if (around) { - range = Range::WordAround; - } else { - range = Range::WordInner; - } - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (!m_keys.isEmpty()) { - // Not a valid sequence. - break; - } - - // w, go to the start of next word. - Movement mm = Movement::WordForward; - if (shift) { - // W, go to the start of next WORD. - mm = Movement::WORDForward; - } - - if (checkActionToken(Action::Change)) { - // In Change action, cw equals to ce. - if (shift) { - mm = Movement::ForwardEndOfWORD; - } else { - mm = Movement::ForwardEndOfWord; - } - } else { - tryAddMoveAction(); - } - - addMovementToken(mm); - processCommand(m_tokens); - break; - } - - break; - } - - case Qt::Key_E: - { - // e, E, ge, gE. - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - Movement mm = Movement::Invalid; - if (!m_keys.isEmpty()) { - if (m_keys.size() == 1 && m_keys.at(0) == Key(Qt::Key_G)) { - // ge, gE. - if (modifiers == Qt::NoModifier) { - mm = Movement::BackwardEndOfWord; - } else { - mm = Movement::BackwardEndOfWORD; - } - } else { - // Not a valid sequence. - break; - } - } else { - // e, E. - if (modifiers == Qt::NoModifier) { - mm = Movement::ForwardEndOfWord; - } else { - mm = Movement::ForwardEndOfWORD; - } - } - - tryAddMoveAction(); - m_tokens.append(Token(mm)); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_QuoteDbl: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // DoubleQuoteInner/DoubleQuoteAround. - Range range = Range::DoubleQuoteInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::DoubleQuoteAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (!m_keys.isEmpty() || hasActionToken()) { - // Invalid sequence. - break; - } - - // ", specify a register. - m_keys.append(keyInfo); - goto accept; - } - - break; - } - - case Qt::Key_X: - { - if (modifiers == Qt::ShiftModifier || modifiers == Qt::NoModifier) { - // x, or X to delete one char. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty() || hasActionToken()) { - break; - } - - addActionToken(Action::Delete); - if (modifiers == Qt::ShiftModifier) { - if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - // X, same as dd. - addRangeToken(Range::Line); - } else { - // X, delete one char. - addMovementToken(Movement::Left); - } - } else { - // x. - // Movement will be ignored in Visual mode. - addMovementToken(Movement::Right); - } - - processCommand(m_tokens); - setMode(VimMode::Normal); - break; - } else if (VUtils::isControlModifierForVim(modifiers)) { - if (g_config->getVimExemptionKeys().contains('x')) { - // Let it be handled outside. - resetState(); - goto exit; - } - } - - break; - } - - case Qt::Key_Y: - { - if (modifiers == Qt::NoModifier) { - // y, copy action. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // This is another y, something like yy. - if (checkActionToken(Action::Copy) && checkMode(VimMode::Normal)) { - addRangeToken(Range::Line); - processCommand(m_tokens); - } else { - // An invalid sequence. - break; - } - } else { - // The first y, an Action. - if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) { - copySelectedText(m_mode == VimMode::VisualLine); - setMode(VimMode::Normal); - break; - } - - addActionToken(Action::Copy); - goto accept; - } - } else if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!hasActionToken()) { - // Y, same as yy. - addActionToken(Action::Copy); - addRangeToken(Range::Line); - processCommand(m_tokens); - setMode(VimMode::Normal); - } - - break; - } - - break; - } - - case Qt::Key_P: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // p/P, paste/pastebefore action. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken() || !m_keys.isEmpty()) { - // An invalid sequence. - break; - } - - addActionToken(modifiers == Qt::NoModifier ? Action::Paste - : Action::PasteBefore); - processCommand(m_tokens); - break; - } - - break; - } - - case Qt::Key_C: - { - if (modifiers == Qt::NoModifier) { - // c, change action. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // This is another c, something like cc. - if (checkActionToken(Action::Change)) { - addRangeToken(Range::Line); - processCommand(m_tokens); - } - } else { - // The first c, an action. - addActionToken(Action::Change); - - if (checkMode(VimMode::VisualLine) || checkMode(VimMode::Visual)) { - // Movement will be ignored. - addMovementToken(Movement::Left); - processCommand(m_tokens); - break; - } - - goto accept; - } - } else if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (!hasActionToken() && m_mode == VimMode::Normal) { - // C, same as c$. - addActionToken(Action::Change); - addMovementToken(Movement::EndOfLine); - processCommand(m_tokens); - } - } else if (VUtils::isControlModifierForVim(modifiers)) { - if (g_config->getVimExemptionKeys().contains('c')) { - // Let it be handled outside. - resetState(); - goto exit; - } else { - clearSelectionAndEnterNormalMode(); - } - } - - break; - } - - case Qt::Key_Less: - unindent = true; - // Fall through. - case Qt::Key_Greater: - { - if (modifiers == Qt::ShiftModifier) { - // >/<, Indent/Unindent. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // This is another >/<, something like >>/<<. - if ((!unindent && checkActionToken(Action::Indent)) - || (unindent && checkActionToken(Action::UnIndent))) { - addRangeToken(Range::Line); - processCommand(m_tokens); - break; - } else if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // AngleBracketInner/AngleBracketAround. - Range range = Range::AngleBracketInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::AngleBracketAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } - } else { - // The first >/<, an Action. - addActionToken(unindent ? Action::UnIndent : Action::Indent); - - if (checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine)) { - // Movement will be ignored. - addMovementToken(Movement::Left); - processCommand(m_tokens); - break; - } - - goto accept; - } - } - - break; - } - - case Qt::Key_Equal: - { - if (modifiers == Qt::NoModifier) { - // =, AutoIndent. - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken()) { - // ==. - if (checkActionToken(Action::AutoIndent)) { - addRangeToken(Range::Line); - processCommand(m_tokens); - break; - } - } else { - // The first =, an Action. - addActionToken(Action::AutoIndent); - - if (checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine)) { - // Movement will be ignored. - addMovementToken(Movement::Left); - processCommand(m_tokens); - break; - } - - goto accept; - } - } - - break; - } - - case Qt::Key_F: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // f/F, find forward/backward within a block. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - m_keys.append(keyInfo); - goto accept; - } - - break; - } - - break; - } - - case Qt::Key_T: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // t/T, find till forward/backward within a block. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - m_keys.append(keyInfo); - goto accept; - } else if (modifiers == Qt::NoModifier && checkPendingKey(Key(Qt::Key_Z))) { - // zt, redraw to make a certain line the top of window. - addActionToken(Action::RedrawAtTop); - processCommand(m_tokens); - break; - } - - break; - } - - break; - } - - case Qt::Key_Comma: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - // ,, repeat last find target movement, but reversely. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - repeatLastFindMovement(true); - break; - } - - break; - } - - case Qt::Key_Semicolon: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - // ;, repeat last find target movement. - tryGetRepeatToken(m_keys, m_tokens); - - if (m_keys.isEmpty()) { - repeatLastFindMovement(false); - break; - } - - break; - } - - case Qt::Key_R: - { - if (m_mode == VimMode::VisualLine) { - break; - } - - if (VUtils::isControlModifierForVim(modifiers)) { - // Redo. - tryGetRepeatToken(m_keys, m_tokens); - if (!m_keys.isEmpty() || hasActionToken()) { - break; - } - - addActionToken(Action::Redo); - processCommand(m_tokens); - break; - } else if (modifiers == Qt::NoModifier) { - // r, replace. - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty() && !hasActionToken()) { - m_keys.append(keyInfo); - goto accept; - } - } - - break; - } - - case Qt::Key_Z: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty() && !hasActionToken()) { - // First z, pend it. - m_keys.append(keyInfo); - goto accept; - } else if (checkPendingKey(keyInfo)) { - // zz, redraw to make a certain line the center of the window. - addActionToken(Action::RedrawAtCenter); - processCommand(m_tokens); - break; - } - - break; - } - - break; - } - - case Qt::Key_Colon: - { - if (modifiers == Qt::ShiftModifier) { - if (m_keys.isEmpty() - && m_tokens.isEmpty() - && checkMode(VimMode::Normal)) { - emit commandLineTriggered(CommandLineType::Command); - } - } - - break; - } - - case Qt::Key_Percent: - { - if (modifiers == Qt::ShiftModifier) { - if (m_keys.isEmpty()) { - // %, FindPair movement. - tryAddMoveAction(); - addMovementToken(Movement::FindPair); - processCommand(m_tokens); - break; - } else { - tryGetRepeatToken(m_keys, m_tokens); - if (m_keys.isEmpty() && hasRepeatToken()) { - // xx%, jump to a certain line (percentage of the documents). - // Change the repeat from percentage to line number. - Token *token = getRepeatToken(); - int bn = percentageToBlockNumber(m_editor->documentW(), token->m_repeat); - if (bn == -1) { - break; - } else { - // Repeat of LineJump is based on 1. - token->m_repeat = bn + 1; - } - - tryAddMoveAction(); - addMovementToken(Movement::LineJump); - processCommand(m_tokens); - break; - } - } - - break; - } - - break; - } - - case Qt::Key_M: - { - if (modifiers == Qt::NoModifier) { - if (m_keys.isEmpty() && m_tokens.isEmpty()) { - // m, creating a mark. - // We can create marks in Visual mode, too. - m_keys.append(keyInfo); - goto accept; - } - } - - break; - } - - case Qt::Key_Apostrophe: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // QuoteInner/QuoteAround. - Range range = Range::QuoteInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::QuoteAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } - - // ', jump to the start of line of a mark. - // Repeat is useless in this case. - if (m_keys.isEmpty()) { - m_keys.append(keyInfo); - goto accept; - } - } - - break; - } - - case Qt::Key_QuoteLeft: - { - if (modifiers == Qt::NoModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BackQuoteInner/BackQuoteAround. - Range range = Range::BackQuoteInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BackQuoteAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } - - // `, jump to a mark. - // Repeat is useless in this case. - if (m_keys.isEmpty()) { - m_keys.append(keyInfo); - goto accept; - } - } - - break; - } - - case Qt::Key_ParenLeft: - // Fall through. - case Qt::Key_ParenRight: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // ParenthesisInner/ParenthesisAround. - Range range = Range::ParenthesisInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::ParenthesisAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } - } - - break; - } - - case Qt::Key_BraceLeft: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BraceInner/BraceAround. - Range range = Range::BraceInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BraceAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (m_keys.isEmpty()) { - // {, ParagraphUp movement. - tryAddMoveAction(); - addMovementToken(Movement::ParagraphUp); - processCommand(m_tokens); - } else if (!hasActionToken() - && checkPendingKey(Key(Qt::Key_BracketLeft))) { - // [{, goto previous title at one higher level. - if (checkMode(VimMode::Normal)) { - processTitleJump(m_tokens, false, -1); - } - } - - break; - } - - break; - } - - case Qt::Key_BraceRight: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (checkPendingKey(Key(Qt::Key_I)) - || checkPendingKey(Key(Qt::Key_A))) { - // BraceInner/BraceAround. - Range range = Range::BraceInner; - if (checkPendingKey(Key(Qt::Key_A))) { - range = Range::BraceAround; - } - - addRangeToken(range); - processCommand(m_tokens); - break; - } else if (m_keys.isEmpty()) { - // }, ParagraphDown movement. - tryAddMoveAction(); - addMovementToken(Movement::ParagraphDown); - processCommand(m_tokens); - } else if (!hasActionToken() - && checkPendingKey(Key(Qt::Key_BracketRight))) { - // ]}, goto next title at one higher level. - if (checkMode(VimMode::Normal)) { - processTitleJump(m_tokens, true, -1); - } - } - - break; - } - - break; - } - - case Qt::Key_AsciiTilde: - { - if (modifiers == Qt::ShiftModifier) { - tryGetRepeatToken(m_keys, m_tokens); - if (hasActionToken() || !m_keys.isEmpty()) { - break; - } - - // Reverse the case. - addActionToken(Action::ReverseCase); - processCommand(m_tokens); - - break; - } - - break; - } - - case Qt::Key_Slash: - { - if (modifiers == Qt::NoModifier) { - if (m_tokens.isEmpty() - && m_keys.isEmpty() - && checkMode(VimMode::Normal)) { - emit commandLineTriggered(CommandLineType::SearchForward); - } - } - - break; - } - - case Qt::Key_Question: - { - if (modifiers == Qt::ShiftModifier) { - if (m_tokens.isEmpty() - && m_keys.isEmpty() - && checkMode(VimMode::Normal)) { - emit commandLineTriggered(CommandLineType::SearchBackward); - } - } - - break; - } - - case Qt::Key_N: - { - if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier) { - // n, FindNext/FindPrevious movement. - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - Movement mm = Movement::FindNext; - if (modifiers == Qt::ShiftModifier) { - mm = Movement::FindPrevious; - } - - tryAddMoveAction(); - addMovementToken(mm); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_Asterisk: - { - if (modifiers == Qt::ShiftModifier) { - // *, FindNextWordUnderCursor movement. - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - tryAddMoveAction(); - addMovementToken(Movement::FindNextWordUnderCursor); - processCommand(m_tokens); - } - - break; - } - - case Qt::Key_NumberSign: - { - if (modifiers == Qt::ShiftModifier) { - // #, FindPreviousWordUnderCursor movement. - tryGetRepeatToken(m_keys, m_tokens); - - if (!m_keys.isEmpty()) { - break; - } - - tryAddMoveAction(); - addMovementToken(Movement::FindPreviousWordUnderCursor); - processCommand(m_tokens); - } - - break; - } - - default: - break; - } - -clear_accept: - resetState(); - - amendCursorPosition(); - - if (m_insertModeAfterCommand - && !checkMode(VimMode::Visual) - && !checkMode(VimMode::VisualLine)) { - m_insertModeAfterCommand = false; - setMode(VimMode::Insert); - } - - m_editor->makeBlockVisible(m_editor->textCursorW().block()); - -accept: - ret = true; - - // Only alter the autoIndentPos when the key is handled by Vim. - if (p_autoIndentPos) { - *p_autoIndentPos = autoIndentPos; - } - -exit: - m_resetPositionInBlock = resetPositionInBlock; - emit vimStatusUpdated(this); - return ret; -} - -void VVim::resetState() -{ - m_keys.clear(); - m_tokens.clear(); - m_pendingKeys.clear(); - setCurrentRegisterName(c_unnamedRegister); - m_resetPositionInBlock = true; - m_registerPending = false; -} - -VimMode VVim::getMode() const -{ - return m_mode; -} - -void VVim::setMode(VimMode p_mode, bool p_clearSelection, int p_position) -{ - if (m_mode != p_mode) { - QTextCursor cursor = m_editor->textCursorW(); - int position = p_position; - if (position == -1) { - if (m_mode == VimMode::Visual - && p_mode == VimMode::Normal - && cursor.position() > cursor.anchor()) { - position = cursor.position() - 1; - } else if (m_mode == VimMode::Insert - && p_mode == VimMode::Normal - && !cursor.atBlockStart()) { - position = cursor.position() - 1; - if (position < 0) { - position = 0; - } - } - } - - if (p_clearSelection) { - clearSelection(); - } - - if (p_mode == VimMode::Insert) { - m_editor->setInputMethodEnabled(true); - } else if (g_config->getEnableSmartImInVimMode()) { - m_editor->setInputMethodEnabled(false); - } - - m_mode = p_mode; - resetState(); - - VMdEditor *mdEditor = dynamic_cast(m_editor); - switch (m_mode) { - case VimMode::Insert: - setCursorBlockMode(m_editor, CursorBlock::None); - if (mdEditor) { - mdEditor->setHighlightCursorLineBlockEnabled(false); - } - - break; - - case VimMode::Visual: - m_positionBeforeVisualMode = cursor.anchor(); - V_FALLTHROUGH; - - default: - setCursorBlockMode(m_editor, CursorBlock::RightSide); - if (mdEditor && g_config->getHighlightCursorLine()) { - QString color; - if (m_mode == VimMode::Normal) { - color = g_config->getEditorVimNormalBg(); - } else { - color = g_config->getEditorVimVisualBg(); - } - - mdEditor->setCursorLineBlockBg(color); - mdEditor->setHighlightCursorLineBlockEnabled(true); - } - - break; - } - - if (position != -1) { - cursor.setPosition(position); - m_editor->setTextCursorW(cursor); - } - - amendCursorPosition(); - - emit modeChanged(m_mode); - emit vimStatusUpdated(this); - } -} - -void VVim::processCommand(QList &p_tokens) -{ - if (p_tokens.isEmpty()) { - return; - } - - V_ASSERT(p_tokens.at(0).isAction()); - - Token act = p_tokens.takeFirst(); - switch (act.m_action) { - case Action::Move: - processMoveAction(p_tokens); - break; - - case Action::Delete: - processDeleteAction(p_tokens); - break; - - case Action::Copy: - processCopyAction(p_tokens); - break; - - case Action::Paste: - processPasteAction(p_tokens, false); - break; - - case Action::PasteBefore: - processPasteAction(p_tokens, true); - break; - - case Action::Change: - processChangeAction(p_tokens); - break; - - case Action::Indent: - processIndentAction(p_tokens, IndentType::Indent); - break; - - case Action::UnIndent: - processIndentAction(p_tokens, IndentType::UnIndent); - break; - - case Action::AutoIndent: - processIndentAction(p_tokens, IndentType::AutoIndent); - break; - - case Action::ToLower: - processToLowerAction(p_tokens, true); - break; - - case Action::ToUpper: - processToLowerAction(p_tokens, false); - break; - - case Action::Undo: - processUndoAction(p_tokens); - break; - - case Action::Redo: - processRedoAction(p_tokens); - break; - - case Action::RedrawAtTop: - processRedrawLineAction(p_tokens, 0); - break; - - case Action::RedrawAtCenter: - processRedrawLineAction(p_tokens, 1); - break; - - case Action::RedrawAtBottom: - processRedrawLineAction(p_tokens, 2); - break; - - case Action::JumpPreviousLocation: - processJumpLocationAction(p_tokens, false); - break; - - case Action::JumpNextLocation: - processJumpLocationAction(p_tokens, true); - break; - - case Action::Replace: - processReplaceAction(p_tokens); - break; - - case Action::ReverseCase: - processReverseCaseAction(p_tokens); - break; - - case Action::Join: - processJoinAction(p_tokens, true); - break; - - case Action::JoinNoModification: - processJoinAction(p_tokens, false); - break; - - default: - p_tokens.clear(); - break; - } - - Q_ASSERT(p_tokens.isEmpty()); -} - -int VVim::numberFromKeySequence(const QList &p_keys) -{ - int num = 0; - - for (auto const & key : p_keys) { - if (key.isDigit()) { - num = num * 10 + key.toDigit(); - } else { - return -1; - } - } - - return num == 0 ? -1 : num; -} - -bool VVim::tryGetRepeatToken(QList &p_keys, QList &p_tokens) -{ - if (!p_keys.isEmpty()) { - int repeat = numberFromKeySequence(p_keys); - if (repeat != -1) { - p_tokens.append(Token(repeat)); - p_keys.clear(); - - return true; - } - } - - return false; -} - -void VVim::processMoveAction(QList &p_tokens) -{ - // Only moving left/right could change this. - static int positionInBlock = 0; - - Token to = p_tokens.takeFirst(); - V_ASSERT(to.isRepeat() || to.isMovement()); - Token mvToken; - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - mvToken = p_tokens.takeFirst(); - } else { - mvToken = to; - } - - if (!mvToken.isMovement() || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - if (m_resetPositionInBlock) { - positionInBlock = cursor.positionInBlock(); - } - - QTextCursor::MoveMode moveMode = (m_mode == VimMode::Visual - || m_mode == VimMode::VisualLine) - ? QTextCursor::KeepAnchor - : QTextCursor::MoveAnchor; - bool hasMoved = processMovement(cursor, moveMode, mvToken, repeat); - - if (hasMoved) { - // Maintain positionInBlock. - switch (mvToken.m_movement) { - case Movement::Left: - case Movement::Right: - positionInBlock = cursor.positionInBlock(); - break; - - case Movement::Up: - case Movement::Down: - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - setCursorPositionInBlock(cursor, positionInBlock, moveMode); - break; - - default: - break; - } - - if (checkMode(VimMode::VisualLine)) { - expandSelectionToWholeLines(cursor); - } else if (checkMode(VimMode::Visual)) { - maintainSelectionInVisualMode(&cursor); - } - - m_editor->setTextCursorW(cursor); - } -} - -bool VVim::processMovement(QTextCursor &p_cursor, - QTextCursor::MoveMode p_moveMode, - const Token &p_token, - int p_repeat) -{ - V_ASSERT(p_token.isMovement()); - - bool hasMoved = false; - bool inclusive = true; - bool forward = true; - QTextDocument *doc = p_cursor.document(); - - switch (p_token.m_movement) { - case Movement::Left: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int pib = p_cursor.positionInBlock(); - p_repeat = qMin(pib, p_repeat); - - if (p_repeat > 0) { - p_cursor.movePosition(QTextCursor::Left, p_moveMode, p_repeat); - hasMoved = true; - } - - break; - } - - case Movement::Right: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - if (checkMode(VimMode::Visual)) { - int pos = p_cursor.position(); - if (pos == p_cursor.anchor() - 1 && pos == m_positionBeforeVisualMode) { - ++p_repeat; - } - } - - int pib = p_cursor.positionInBlock(); - int length = p_cursor.block().length(); - if (length - pib <= p_repeat) { - p_repeat = length - pib - 1; - } - - if (p_repeat > 0) { - p_cursor.movePosition(QTextCursor::Right, p_moveMode, p_repeat); - hasMoved = true; - } - - break; - } - - case Movement::Up: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - p_repeat = qMin(p_cursor.block().blockNumber(), p_repeat); - - if (p_repeat > 0) { - p_cursor.movePosition(QTextCursor::PreviousBlock, p_moveMode, p_repeat); - hasMoved = true; - } - - break; - } - - case Movement::Down: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockCount = doc->blockCount(); - p_repeat = qMin(blockCount - 1 - p_cursor.block().blockNumber(), p_repeat); - - if (p_repeat > 0) { - p_cursor.movePosition(QTextCursor::NextBlock, p_moveMode, p_repeat); - hasMoved = true; - } - - break; - } - - case Movement::VisualUp: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - p_cursor.movePosition(QTextCursor::Up, p_moveMode, p_repeat); - hasMoved = true; - break; - } - - case Movement::VisualDown: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - p_cursor.movePosition(QTextCursor::Down, p_moveMode, p_repeat); - hasMoved = true; - break; - } - - case Movement::PageUp: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockStep = blockCountOfPageStep() * p_repeat; - int block = p_cursor.block().blockNumber(); - block = qMax(0, block - blockStep); - p_cursor.setPosition(doc->findBlockByNumber(block).position(), p_moveMode); - hasMoved = true; - - break; - } - - case Movement::PageDown: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockStep = blockCountOfPageStep() * p_repeat; - int block = p_cursor.block().blockNumber(); - block = qMin(block + blockStep, doc->blockCount() - 1); - p_cursor.setPosition(doc->findBlockByNumber(block).position(), p_moveMode); - hasMoved = true; - - break; - } - - case Movement::HalfPageUp: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockStep = blockCountOfPageStep(); - int halfBlockStep = qMax(blockStep / 2, 1); - blockStep = p_repeat * halfBlockStep; - int block = p_cursor.block().blockNumber(); - block = qMax(0, block - blockStep); - p_cursor.setPosition(doc->findBlockByNumber(block).position(), p_moveMode); - hasMoved = true; - - break; - } - - case Movement::HalfPageDown: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - int blockStep = blockCountOfPageStep(); - int halfBlockStep = qMax(blockStep / 2, 1); - blockStep = p_repeat * halfBlockStep; - int block = p_cursor.block().blockNumber(); - block = qMin(block + blockStep, doc->blockCount() - 1); - p_cursor.setPosition(doc->findBlockByNumber(block).position(), p_moveMode); - hasMoved = true; - - break; - } - - case Movement::StartOfLine: - { - Q_ASSERT(p_repeat == -1); - - // Start of the Line (block). - if (!p_cursor.atBlockStart()) { - p_cursor.movePosition(QTextCursor::StartOfBlock, p_moveMode, 1); - hasMoved = true; - } - - break; - } - - case Movement::StartOfVisualLine: - { - // Start of the visual line. - if (!p_cursor.atBlockStart()) { - p_cursor.movePosition(QTextCursor::StartOfLine, p_moveMode, 1); - hasMoved = true; - } - - break; - } - - case Movement::EndOfLine: - { - // End of line (block). - if (p_repeat == -1) { - p_repeat = 1; - } else if (p_repeat > 1) { - // Move down (p_repeat-1) blocks. - p_cursor.movePosition(QTextCursor::NextBlock, p_moveMode, p_repeat - 1); - } - - // Move to the end of block. - p_cursor.movePosition(QTextCursor::EndOfBlock, p_moveMode, 1); - hasMoved = true; - break; - } - - case Movement::FirstCharacter: - { - // p_repeat is not considered in this command. - // If all the block is space, just move to the end of block; otherwise, - // move to the first non-space character. - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::LineJump: - { - // Jump to the first non-space character of @p_repeat line (block). - V_ASSERT(p_repeat > 0); - - // Record current location. - m_locations.addLocation(p_cursor); - - // @p_repeat starts from 1 while block number starts from 0. - QTextBlock block = doc->findBlockByNumber(p_repeat - 1); - if (block.isValid()) { - p_cursor.setPosition(block.position(), p_moveMode); - } else { - // Go beyond the document. - p_cursor.movePosition(QTextCursor::End, p_moveMode, 1); - } - - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::StartOfDocument: - { - // Jump to the first non-space character of the start of the document. - V_ASSERT(p_repeat == -1); - - // Record current location. - m_locations.addLocation(p_cursor); - - p_cursor.movePosition(QTextCursor::Start, p_moveMode, 1); - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::EndOfDocument: - { - // Jump to the first non-space character of the end of the document. - V_ASSERT(p_repeat == -1); - - // Record current location. - m_locations.addLocation(p_cursor); - - p_cursor.movePosition(QTextCursor::End, p_moveMode, 1); - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::WordForward: - { - // Go to the start of next word. - if (p_repeat == -1) { - p_repeat = 1; - } - - while (p_repeat) { - if (p_cursor.atEnd()) { - break; - } - - p_cursor.movePosition(QTextCursor::NextWord, p_moveMode); - if (p_cursor.atBlockEnd()) { - // dw/yw/cw will stop at the end of the line. - if (p_repeat == 1 - && checkMode(VimMode::Normal) - && p_moveMode == QTextCursor::KeepAnchor) { - --p_repeat; - } - - continue; - } else if (doc->characterAt(p_cursor.position()).isSpace() - || VEditUtils::isSpaceBlock(p_cursor.block())) { - continue; - } - - --p_repeat; - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::WORDForward: - { - // Go to the start of next WORD. - if (p_repeat == -1) { - p_repeat = 1; - } - - while (p_repeat) { - if (p_cursor.atEnd()) { - break; - } - - int start, end; - // [start, end] is current WORD. - VEditUtils::findCurrentWORD(p_cursor, start, end); - // Move cursor to end of current WORD. - p_cursor.setPosition(end, p_moveMode); - - if (p_repeat == 1 - && checkMode(VimMode::Normal) - && p_moveMode == QTextCursor::KeepAnchor) { - // dW/yW/cW will stop at the end of the line. - moveCursorAcrossSpaces(p_cursor, p_moveMode, true, true); - if (p_cursor.atBlockEnd()) { - --p_repeat; - continue; - } - } - - // Skip spaces. - moveCursorAcrossSpaces(p_cursor, p_moveMode, true); - if (p_cursor.atBlockEnd()) { - continue; - } - - --p_repeat; - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::ForwardEndOfWord: - { - // Go to the end of current word or next word. - if (p_repeat == -1) { - p_repeat = 1; - } - - int pos = p_cursor.position(); - bool leftSideBefore = useLeftSideOfCursor(p_cursor); - // First move to the end of current word. - p_cursor.movePosition(QTextCursor::EndOfWord, p_moveMode, 1); - if (p_cursor.position() > pos) { - if (p_cursor.position() > pos + 1 || (leftSideBefore && useLeftSideOfCursor(p_cursor))) { - // We did move. - p_repeat -= 1; - } - } - - while (p_repeat) { - if (p_cursor.atEnd()) { - break; - } - - pos = p_cursor.position(); - p_cursor.movePosition(QTextCursor::EndOfWord, p_moveMode); - if (p_cursor.position() == pos) { - // Need to move to the start of next word. - p_cursor.movePosition(QTextCursor::NextWord, p_moveMode); - if (p_cursor.atBlockEnd()) { - continue; - } - - p_cursor.movePosition(QTextCursor::EndOfWord, p_moveMode); - if (p_cursor.atBlockStart()) { - continue; - } - } - - --p_repeat; - } - - // Move one character back. - if (!p_cursor.atBlockStart()) { - if (p_moveMode == QTextCursor::MoveAnchor - || (checkMode(VimMode::Visual) && !useLeftSideOfCursor(p_cursor))) { - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - } - - hasMoved = true; - break; - } - - case Movement::ForwardEndOfWORD: - { - // Go to the end of current WORD or next WORD. - if (p_repeat == -1) { - p_repeat = 1; - } - - int pos = p_cursor.position(); - bool leftSideBefore = useLeftSideOfCursor(p_cursor); - while (p_repeat) { - if (p_cursor.atEnd()) { - break; - } - - // Skip spaces. - moveCursorAcrossSpaces(p_cursor, p_moveMode, true); - if (p_cursor.atBlockEnd()) { - continue; - } - - int start, end; - // [start, end] is current WORD. - VEditUtils::findCurrentWORD(p_cursor, start, end); - - // Move cursor to the end of current WORD. - p_cursor.setPosition(end, p_moveMode); - - if (p_cursor.position() > pos + 1 - || (leftSideBefore && useLeftSideOfCursor(p_cursor))) { - --p_repeat; - } - } - - // Move one character back. - if (!p_cursor.atBlockStart()) { - if (p_moveMode == QTextCursor::MoveAnchor - || (checkMode(VimMode::Visual) && !useLeftSideOfCursor(p_cursor))) { - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - } - - hasMoved = true; - break; - } - - case Movement::WordBackward: - { - // Go to the start of previous word or current word. - if (p_repeat == -1) { - p_repeat = 1; - } - - int pos = p_cursor.position(); - // first move to the start of current word. - p_cursor.movePosition(QTextCursor::StartOfWord, p_moveMode); - if (p_cursor.position() == pos && useLeftSideOfCursor(p_cursor)) { - // Cursor did not move and now is at the start of a word. - // Actually we are using the left side character so we need to move - // to previous word. - p_cursor.movePosition(QTextCursor::PreviousWord, p_moveMode); - } - - if (p_cursor.position() < pos) { - if (p_cursor.position() < pos - 1 || !useLeftSideOfCursor(p_cursor)) { - // We did move. - p_repeat -= 1; - } - } - - while (p_repeat) { - if (p_cursor.atStart()) { - break; - } - - pos = p_cursor.position(); - p_cursor.movePosition(QTextCursor::StartOfWord, p_moveMode); - if (p_cursor.position() == pos) { - // Need to move to the start of previous word. - p_cursor.movePosition(QTextCursor::PreviousWord, p_moveMode); - if (p_cursor.atBlockEnd()) { - continue; - } - - if (p_cursor.atBlockStart() && doc->characterAt(p_cursor.position()).isSpace()) { - continue; - } - } - - --p_repeat; - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::WORDBackward: - { - // Go to the start of previous WORD or current WORD. - if (p_repeat == -1) { - p_repeat = 1; - } - - int pos = p_cursor.position(); - while (p_repeat) { - if (p_cursor.atStart()) { - break; - } - - // Skip Spaces. - moveCursorAcrossSpaces(p_cursor, p_moveMode, false); - if (p_cursor.atBlockStart()) { - continue; - } - - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - - int start, end; - // [start, end] is current WORD. - VEditUtils::findCurrentWORD(p_cursor, start, end); - - // Move cursor to the start of current WORD. - p_cursor.setPosition(start, p_moveMode); - - if (p_cursor.position() < pos - 1 || !useLeftSideOfCursor(p_cursor)) { - --p_repeat; - } - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } - - case Movement::BackwardEndOfWord: - { - // Go to the end of previous word. - if (p_repeat == -1) { - p_repeat = 1; - } - - if (useLeftSideOfCursor(p_cursor)) { - // Move one previous char. - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - - int pos = p_cursor.position(); - // Move across spaces backward. - moveCursorAcrossSpaces(p_cursor, p_moveMode, false); - int start, end; - VEditUtils::findCurrentWord(p_cursor, start, end); - if (pos != p_cursor.position() || start == end || start == pos) { - // We are alreay at the end of previous word. - --p_repeat; - - // Move it to the start of current word. - p_cursor.movePosition(QTextCursor::PreviousWord, p_moveMode); - } else { - p_cursor.movePosition(QTextCursor::StartOfWord, p_moveMode); - } - - while (p_repeat) { - if (p_cursor.atStart()) { - break; - } - - p_cursor.movePosition(QTextCursor::PreviousWord, p_moveMode); - if (p_cursor.atBlockEnd()) { - continue; - } - - if (p_cursor.atBlockStart() && doc->characterAt(p_cursor.position()).isSpace()) { - continue; - } - - --p_repeat; - } - - // Move it to the end. - p_cursor.movePosition(QTextCursor::EndOfWord, p_moveMode); - - // Move one character back. - if (!p_cursor.atBlockStart()) { - if (p_moveMode == QTextCursor::MoveAnchor - || (checkMode(VimMode::Visual) && !useLeftSideOfCursor(p_cursor)) - || p_cursor.position() <= p_cursor.anchor()) { - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - } - - hasMoved = true; - break; - } - - case Movement::BackwardEndOfWORD: - { - // Go to the end of previous WORD. - if (p_repeat == -1) { - p_repeat = 1; - } - - if (useLeftSideOfCursor(p_cursor)) { - // Move one previous char. - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - - int pos = p_cursor.position(); - // Move across spaces backward. - moveCursorAcrossSpaces(p_cursor, p_moveMode, false); - int start, end; - VEditUtils::findCurrentWORD(p_cursor, start, end); - if (pos != p_cursor.position() || start == end) { - // We are alreay at the end of previous WORD. - --p_repeat; - - // Move it to the start of current WORD. - p_cursor.setPosition(start, p_moveMode); - } else { - // Move it to the start of current WORD. - p_cursor.setPosition(start, p_moveMode); - } - - while (p_repeat) { - if (p_cursor.atStart()) { - break; - } - - moveCursorAcrossSpaces(p_cursor, p_moveMode, false); - if (p_cursor.atBlockStart()) { - continue; - } - - if (p_cursor.atBlockStart() && doc->characterAt(p_cursor.position()).isSpace()) { - continue; - } - - VEditUtils::findCurrentWORD(p_cursor, start, end); - p_cursor.setPosition(start, p_moveMode); - - --p_repeat; - } - - // Move it to the end. - VEditUtils::findCurrentWORD(p_cursor, start, end); - p_cursor.setPosition(end, p_moveMode); - - // Move one character back. - if (!p_cursor.atBlockStart()) { - if (p_moveMode == QTextCursor::MoveAnchor - || (checkMode(VimMode::Visual) && !useLeftSideOfCursor(p_cursor)) - || p_cursor.position() <= p_cursor.anchor()) { - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - } - - hasMoved = true; - break; - } - - case Movement::TillBackward: - forward = false; - // Fall through. - case Movement::TillForward: - inclusive = false; - goto handle_target; - - case Movement::FindBackward: - forward = false; - // Fall through. - case Movement::FindForward: - { -handle_target: - if (p_repeat == -1) { - p_repeat = 1; - } - - const Key &key = p_token.m_key; - QChar target = keyToChar(key.m_key, key.m_modifiers); - if (!target.isNull()) { - hasMoved = VEditUtils::findTargetWithinBlock(p_cursor, - p_moveMode, - target, - forward, - inclusive, - useLeftSideOfCursor(p_cursor), - p_repeat); - } - - break; - } - - case Movement::MarkJump: - // Fall through. - case Movement::MarkJumpLine: - { - // repeat is useless here. - const Key &key = p_token.m_key; - QChar target = keyToChar(key.m_key, key.m_modifiers); - Location loc = m_marks.getMarkLocation(target); - if (loc.isValid()) { - if (loc.m_blockNumber >= doc->blockCount()) { - // Invalid block number. - message(tr("Mark not set")); - m_marks.clearMark(target); - break; - } - - // Different from Vim: - // We just use the block number for mark, so if we delete the line - // where the mark locates, we could not detect if it is set or not. - QTextBlock block = doc->findBlockByNumber(loc.m_blockNumber); - p_cursor.setPosition(block.position(), p_moveMode); - if (p_token.m_movement == Movement::MarkJump) { - setCursorPositionInBlock(p_cursor, loc.m_positionInBlock, p_moveMode); - } else { - // Jump to the first non-space character. - VEditUtils::moveCursorFirstNonSpaceCharacter(p_cursor, p_moveMode); - } - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - } - - break; - } - - case Movement::FindPair: - { - Q_ASSERT(p_repeat == -1); - int anchor = p_cursor.anchor(); - int position = p_cursor.position(); - QList> pairs; - pairs.append(QPair('(', ')')); - pairs.append(QPair('[', ']')); - pairs.append(QPair('{', '}')); - - // Find forward for a pair (), [], and {}. - QList targets; - for (auto const & pair : pairs) { - targets.append(pair.first); - targets.append(pair.second); - } - - // First check if current char hits the targets. - bool useLeftSideBefore = useLeftSideOfCursor(p_cursor); - QChar ch = doc->characterAt(useLeftSideBefore ? position - 1 - : position); - int idx = targets.indexOf(ch); - if (idx == -1) { - idx = VEditUtils::findTargetsWithinBlock(p_cursor, - targets, - true, - useLeftSideOfCursor(p_cursor), - true); - } else if (useLeftSideBefore) { - // Move one character back to let p_cursor position at the pair. - p_cursor.movePosition(QTextCursor::PreviousCharacter, p_moveMode); - } - - if (idx == -1) { - break; - } - - idx /= 2; - int pairPosition = p_cursor.position(); - bool ret = VEditUtils::selectPairTargetAround(p_cursor, - pairs.at(idx).first, - pairs.at(idx).second, - true, - true, - 1); - - if (ret) { - // Found matched pair. - int first = p_cursor.position(); - int second = p_cursor.anchor(); - if (first > second) { - int tmp = first; - first = second; - second = tmp; - } - - if (!(checkMode(VimMode::Normal) && p_moveMode == QTextCursor::KeepAnchor)) { - --second; - } - - int target = first; - if (first == pairPosition) { - target = second; - } - - if (anchor > target - && !p_cursor.atEnd() - && !useLeftSideOfCursor(p_cursor)) { - ++anchor; - } - - p_cursor.setPosition(anchor); - p_cursor.setPosition(target, p_moveMode); - - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - // Move one character forward. - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - hasMoved = true; - break; - } else { - // Restore the cursor position. - p_cursor.setPosition(anchor); - if (anchor != position) { - p_cursor.setPosition(position, QTextCursor::KeepAnchor); - } - } - - break; - } - - case Movement::FindPrevious: - forward = false; - // Fall through. - case Movement::FindNext: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - if (m_searchHistory.isEmpty()) { - break; - } - - // Record current location. - m_locations.addLocation(p_cursor); - - bool useLeftSideBefore = useLeftSideOfCursor(p_cursor); - const SearchItem &item = m_searchHistory.lastItem(); - while (--p_repeat >= 0) { - bool found = m_editor->findText(item.m_text, - item.m_options, - forward ? item.m_forward : !item.m_forward, - &p_cursor, - p_moveMode, - useLeftSideBefore); - if (found) { - hasMoved = true; - useLeftSideBefore = false; - } else { - break; - } - } - - if (hasMoved) { - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - } - - break; - } - - case Movement::FindPreviousWordUnderCursor: - forward = false; - // Fall through. - case Movement::FindNextWordUnderCursor: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - // Get current word under cursor. - // Different from Vim: - // We do not recognize a word as strict as Vim. - int start, end; - VEditUtils::findCurrentWord(p_cursor, start, end); - if (start == end) { - // Spaces, find next word. - QTextCursor cursor = p_cursor; - while (true) { - moveCursorAcrossSpaces(cursor, p_moveMode, true); - if (cursor.atEnd()) { - break; - } - - if (!doc->characterAt(cursor.position()).isSpace()) { - VEditUtils::findCurrentWord(cursor, start, end); - Q_ASSERT(start != end); - break; - } - } - - if (start == end) { - break; - } - } - - QTextCursor cursor = p_cursor; - cursor.setPosition(start); - cursor.setPosition(end, QTextCursor::KeepAnchor); - QString text = cursor.selectedText(); - if (text.isEmpty()) { - break; - } - - // Record current location. - m_locations.addLocation(p_cursor); - - p_cursor.setPosition(start, p_moveMode); - - // Case-insensitive, non-regularexpression. - SearchItem item; - item.m_rawStr = text; - item.m_text = text; - item.m_forward = forward; - - m_searchHistory.addItem(item); - m_searchHistory.resetIndex(); - while (--p_repeat >= 0) { - hasMoved = m_editor->findText(item.m_text, item.m_options, - item.m_forward, - &p_cursor, p_moveMode); - } - - Q_ASSERT(hasMoved); - if (!p_cursor.atEnd() && useLeftSideOfCursor(p_cursor)) { - p_cursor.movePosition(QTextCursor::NextCharacter, p_moveMode); - } - - break; - } - - case Movement::ParagraphUp: - forward = false; - // Fall through. - case Movement::ParagraphDown: - { - if (p_repeat == -1) { - p_repeat = 1; - } - - // Record current location. - m_locations.addLocation(p_cursor); - - int oriPos = p_cursor.position(); - - int position = VEditUtils::findNextEmptyBlock(p_cursor, - forward, - p_repeat); - if (position == -1) { - // No empty block. Move to the first/last character. - p_cursor.movePosition(forward ? QTextCursor::End : QTextCursor::Start, - p_moveMode); - hasMoved = p_cursor.position() != oriPos; - } else { - p_cursor.setPosition(position, p_moveMode); - hasMoved = true; - } - - break; - } - - default: - break; - } - - return hasMoved; -} - -bool VVim::selectRange(QTextCursor &p_cursor, const QTextDocument *p_doc, - Range p_range, int p_repeat) -{ - bool hasMoved = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - bool around = false; - QChar opening; - QChar closing; - bool crossBlock = false; - bool multipleTargets = false; - - Q_UNUSED(p_doc); - - switch (p_range) { - case Range::Line: - { - // Visual mode, just select selected lines. - if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - expandSelectionToWholeLines(p_cursor); - hasMoved = true; - break; - } - - // Current line and next (p_repeat - 1) lines. - if (p_repeat == -1) { - p_repeat = 1; - } - - if (p_repeat > 1) { - p_cursor.movePosition(QTextCursor::NextBlock, moveMode, p_repeat - 1); - } - - expandSelectionToWholeLines(p_cursor); - hasMoved = true; - break; - } - - case Range::WordAround: - around = true; - // Fall through. - case Range::WordInner: - { - Q_ASSERT(p_repeat == -1); - bool spaces = false; - int start, end; - VEditUtils::findCurrentWord(p_cursor, start, end); - - if (start == end) { - // Select the space between previous word and next word. - findCurrentSpace(p_cursor, start, end); - spaces = true; - } - - if (start != end) { - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - p_cursor.setPosition(end, moveMode); - hasMoved = true; - - if (around) { - if (spaces) { - // Select the word by the end of spaces. - if (!p_cursor.atBlockEnd()) { - p_cursor.movePosition(QTextCursor::EndOfWord, moveMode); - } - } else { - // Select additional spaces at two ends. - expandSelectionAcrossSpacesWithinBlock(p_cursor); - } - } - } - - break; - } - - case Range::WORDAround: - around = true; - // Fall through. - case Range::WORDInner: - { - Q_ASSERT(p_repeat == -1); - bool spaces = false; - int start, end; - findCurrentSpace(p_cursor, start, end); - - if (start == end) { - VEditUtils::findCurrentWORD(p_cursor, start, end); - } else { - // Select the space between previous WORD and next WORD. - spaces = true; - } - - if (start != end) { - p_cursor.setPosition(start, QTextCursor::MoveAnchor); - p_cursor.setPosition(end, moveMode); - hasMoved = true; - - if (around) { - if (spaces) { - // Select the WORD by the end of spaces. - if (!p_cursor.atBlockEnd()) { - // Skip spaces (mainly across block). - moveCursorAcrossSpaces(p_cursor, moveMode, true); - - // [start, end] is current WORD. - VEditUtils::findCurrentWORD(p_cursor, start, end); - - // Move cursor to the end of current WORD. - p_cursor.setPosition(end, moveMode); - } - } else { - // Select additional spaces at two ends. - expandSelectionAcrossSpacesWithinBlock(p_cursor); - } - } - } - - break; - } - - case Range::ParenthesisAround: - { - around = true; - opening = '('; - closing = ')'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::ParenthesisInner: - { - around = false; - opening = '('; - closing = ')'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::BracketAround: - { - around = true; - opening = '['; - closing = ']'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::BracketInner: - { - around = false; - opening = '['; - closing = ']'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::AngleBracketAround: - { - around = true; - opening = '<'; - closing = '>'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::AngleBracketInner: - { - around = false; - opening = '<'; - closing = '>'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::BraceAround: - { - around = true; - opening = '{'; - closing = '}'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::BraceInner: - { - around = false; - opening = '{'; - closing = '}'; - crossBlock = true; - multipleTargets = true; - goto handlePairTarget; - } - - case Range::DoubleQuoteAround: - { - around = true; - opening = '"'; - closing = '"'; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::DoubleQuoteInner: - { - around = false; - opening = '"'; - closing = '"'; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::BackQuoteAround: - { - around = true; - opening = '`'; - closing = '`'; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::BackQuoteInner: - { - around = false; - opening = '`'; - closing = '`'; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::QuoteAround: - { - around = true; - opening = '\''; - closing = '\''; - crossBlock = false; - multipleTargets = false; - goto handlePairTarget; - } - - case Range::QuoteInner: - { - around = false; - opening = '\''; - closing = '\''; - crossBlock = false; - multipleTargets = false; - -handlePairTarget: - - if (p_repeat == -1) { - p_repeat = 1; - } else if (p_repeat > 1 && !multipleTargets) { - // According to the behavior of Vim. - p_repeat = 1; - around = true; - } - - hasMoved = VEditUtils::selectPairTargetAround(p_cursor, - opening, - closing, - around, - crossBlock, - p_repeat); - break; - } - - default: - break; - } - - return hasMoved; -} - -void VVim::processDeleteAction(QList &p_tokens) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextDocument *doc = m_editor->documentW(); - bool hasMoved = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - - if (to.isRange()) { - cursor.beginEditBlock(); - hasMoved = selectRange(cursor, doc, to.m_range, repeat); - if (hasMoved) { - // Whether the range may cross blocks. - bool mayCrossBlock = false; - - switch (to.m_range) { - case Range::Line: - { - // dd, delete current line. - if (cursor.hasSelection()) { - repeat = VEditUtils::selectedBlockCount(cursor); - deleteSelectedText(cursor, true); - } else { - VEditUtils::removeBlock(cursor); - saveToRegister("\n"); - repeat = 1; - } - - message(tr("%1 fewer %2").arg(repeat).arg(repeat > 1 ? tr("lines") - : tr("line"))); - break; - } - - case Range::ParenthesisInner: - // Fall through. - case Range::ParenthesisAround: - // Fall through. - case Range::BracketInner: - // Fall through. - case Range::BracketAround: - // Fall through. - case Range::AngleBracketInner: - // Fall through. - case Range::AngleBracketAround: - // Fall through. - case Range::BraceInner: - // Fall through. - case Range::BraceAround: - // Fall through. - mayCrossBlock = true; - - V_FALLTHROUGH; - - case Range::WordAround: - // Fall through. - case Range::WordInner: - // Fall through. - case Range::WORDAround: - // Fall through. - case Range::WORDInner: - // Fall through. - case Range::QuoteInner: - // Fall through. - case Range::QuoteAround: - // Fall through. - case Range::DoubleQuoteInner: - // Fall through. - case Range::DoubleQuoteAround: - // Fall through. - case Range::BackQuoteInner: - // Fall through. - case Range::BackQuoteAround: - { - if (cursor.hasSelection()) { - bool clearEmptyBlock = false; - if (mayCrossBlock - && VEditUtils::selectedBlockCount(cursor) > 1) { - clearEmptyBlock = true; - } - - int blockCount = 0; - if (clearEmptyBlock) { - blockCount = doc->blockCount(); - } - - deleteSelectedText(cursor, clearEmptyBlock); - - if (clearEmptyBlock) { - int nrBlock = blockCount - doc->blockCount(); - Q_ASSERT(nrBlock > 0); - message(tr("%1 fewer %2").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - } - - break; - } - - default: - return; - } - } - - cursor.endEditBlock(); - goto exit; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for DELETE action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - cursor.beginEditBlock(); - if (checkMode(VimMode::VisualLine) || checkMode(VimMode::Visual)) { - // Visual mode, omitting repeat and movement. - // Different from Vim: - // If there is no selection in Visual mode, we do nothing. - if (cursor.hasSelection()) { - hasMoved = true; - deleteSelectedText(cursor, m_mode == VimMode::VisualLine); - } else if (checkMode(VimMode::Visual)) { - hasMoved = true; - VEditUtils::removeBlock(cursor); - saveToRegister("\n"); - } - - cursor.endEditBlock(); - goto exit; - } - - hasMoved = processMovement(cursor, moveMode, to, repeat); - if (repeat == -1) { - repeat = 1; - } - - if (hasMoved) { - bool clearEmptyBlock = false; - switch (to.m_movement) { - case Movement::Up: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete up" << repeat << "lines"; - break; - } - - case Movement::Down: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete down" << repeat << "lines"; - break; - } - - case Movement::EndOfLine: - { - // End of line (block). - if (repeat > 1) { - clearEmptyBlock = true; - } - - qDebug() << "delete till end of" << repeat << "line"; - break; - } - - case Movement::LineJump: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete till line" << repeat; - break; - } - - case Movement::StartOfDocument: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete till start of document"; - break; - } - - case Movement::EndOfDocument: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "delete till end of document"; - break; - } - - // ParagraphUp and ParagraphDown are a little different from Vim in - // block deletion. - - default: - break; - } - - if (clearEmptyBlock) { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 fewer %2").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - - deleteSelectedText(cursor, clearEmptyBlock); - } - - cursor.endEditBlock(); - -exit: - if (hasMoved) { - m_editor->setTextCursorW(cursor); - } -} - -void VVim::processCopyAction(QList &p_tokens) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextDocument *doc = m_editor->documentW(); - int oriPos = cursor.position(); - bool changed = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - - if (to.isRange()) { - cursor.beginEditBlock(); - changed = selectRange(cursor, doc, to.m_range, repeat); - if (changed) { - // Whether the range may cross blocks. - bool mayCrossBlock = false; - - switch (to.m_range) { - case Range::Line: - { - // yy, copy current line. - if (cursor.hasSelection()) { - repeat = VEditUtils::selectedBlockCount(cursor); - copySelectedText(cursor, true); - } else { - saveToRegister("\n"); - repeat = 1; - } - - message(tr("%1 %2 yanked").arg(repeat).arg(repeat > 1 ? tr("lines") - : tr("line"))); - break; - } - - case Range::ParenthesisInner: - // Fall through. - case Range::ParenthesisAround: - // Fall through. - case Range::BracketInner: - // Fall through. - case Range::BracketAround: - // Fall through. - case Range::AngleBracketInner: - // Fall through. - case Range::AngleBracketAround: - // Fall through. - case Range::BraceInner: - // Fall through. - case Range::BraceAround: - // Fall through. - mayCrossBlock = true; - - V_FALLTHROUGH; - - case Range::WordAround: - // Fall through. - case Range::WordInner: - // Fall through. - case Range::WORDAround: - // Fall through. - case Range::WORDInner: - // Fall through. - case Range::QuoteInner: - // Fall through. - case Range::QuoteAround: - // Fall through. - case Range::DoubleQuoteInner: - // Fall through. - case Range::DoubleQuoteAround: - // Fall through. - case Range::BackQuoteInner: - // Fall through. - case Range::BackQuoteAround: - { - if (cursor.hasSelection()) { - bool multipleBlocks = false; - int nrBlock = VEditUtils::selectedBlockCount(cursor); - if (mayCrossBlock && nrBlock > 1) { - multipleBlocks = true; - } - - // No need to add new line even crossing multiple blocks. - copySelectedText(cursor, false); - - if (multipleBlocks) { - message(tr("%1 %2 yanked").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - } - - break; - } - - default: - return; - } - } - - if (cursor.position() != oriPos) { - cursor.setPosition(oriPos); - changed = true; - } - - cursor.endEditBlock(); - goto exit; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for Copy action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - cursor.beginEditBlock(); - changed = processMovement(cursor, moveMode, to, repeat); - if (repeat == -1) { - repeat = 1; - } - - if (changed) { - bool addNewLine = false; - switch (to.m_movement) { - case Movement::Up: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy up" << repeat << "lines"; - break; - } - - case Movement::Down: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy down" << repeat << "lines"; - break; - } - - case Movement::EndOfLine: - { - // End of line (block). - // Do not need to add new line even if repeat > 1. - qDebug() << "copy till end of" << repeat << "line"; - break; - } - - case Movement::LineJump: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy till line" << repeat; - break; - } - - case Movement::StartOfDocument: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy till start of document"; - break; - } - - case Movement::EndOfDocument: - { - expandSelectionToWholeLines(cursor); - addNewLine = true; - qDebug() << "copy till end of document"; - break; - } - - default: - break; - } - - if (addNewLine) { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 yanked").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - - copySelectedText(cursor, addNewLine); - if (cursor.position() != oriPos) { - cursor.setPosition(oriPos); - } - } - - cursor.endEditBlock(); - -exit: - if (changed) { - m_editor->setTextCursorW(cursor); - } -} - -void VVim::processPasteAction(QList &p_tokens, bool p_pasteBefore) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat; - } - - Register ® = getRegister(m_regName); - QString value = reg.read(); - bool isBlock = reg.isBlock(); - if (value.isEmpty()) { - if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) { - setMode(VimMode::Normal); - } - - return; - } - - if (!(checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine))) { - return; - } - - QString text; - text.reserve(repeat * value.size() + 1); - for (int i = 0; i < repeat; ++i) { - text.append(value); - } - - bool changed = false; - int nrBlock = 0; - int restorePos = -1; - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - - // Different from Vim: - // In visual mode, by default vim select the current char, so paste operation will replace - // current char, but here it is strange to follow this specification. - bool isVisualLine = checkMode(VimMode::VisualLine); - if (!checkMode(VimMode::Normal)) { - // Visual or VisualLine mode. - if (cursor.hasSelection()) { - int pos = cursor.selectionStart(); - deleteSelectedText(cursor, isVisualLine); - if (isVisualLine) { - // Insert a new block for insertion. - insertChangeBlockAfterDeletion(cursor, pos); - - restorePos = cursor.position(); - - if (isBlock) { - nrBlock = text.count('\n'); - // insertChangeBlockAfterDeletion() already insert a new line, so eliminate one here. - text = text.left(text.size() - 1); - } - } else if (isBlock) { - // Insert new block right at current cursor. - nrBlock = text.count('\n'); - cursor.insertBlock(); - restorePos = cursor.position(); - } else if (text.count('\n') > 0) { - restorePos = cursor.position(); - } - - changed = true; - } - } else { - // Normal mode. - if (isBlock) { - if (p_pasteBefore) { - cursor.movePosition(QTextCursor::StartOfBlock); - cursor.insertBlock(); - cursor.movePosition(QTextCursor::PreviousBlock); - } else { - cursor.movePosition(QTextCursor::EndOfBlock); - cursor.insertBlock(); - } - - restorePos = cursor.position(); - - nrBlock = text.count('\n'); - - // inserBlock() already insert a new line, so eliminate one here. - text = text.left(text.size() - 1); - } else { - // Not a block. - if (!p_pasteBefore && !cursor.atBlockEnd()) { - // Insert behind current cursor. - cursor.movePosition(QTextCursor::Right); - } - - if (text.count('\n') > 0) { - restorePos = cursor.position(); - } - } - - changed = true; - } - - if (changed) { - cursor.insertText(text); - - if (restorePos == -1) { - // Move cursor one character left. - cursor.movePosition(QTextCursor::Left); - } else { - // Move cursor at the right position. - cursor.setPosition(restorePos); - } - - if (nrBlock > 0) { - message(tr("%1 more %2").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - } - } - - cursor.endEditBlock(); - - if (!checkMode(VimMode::Normal)) { - setMode(VimMode::Normal); - } - - if (changed) { - m_editor->setTextCursorW(cursor); - } - - qDebug() << "text pasted" << text; -} - -void VVim::processChangeAction(QList &p_tokens) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextDocument *doc = m_editor->documentW(); - bool hasMoved = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - - if (to.isRange()) { - cursor.beginEditBlock(); - hasMoved = selectRange(cursor, doc, to.m_range, repeat); - if (hasMoved) { - int pos = cursor.selectionStart(); - - switch (to.m_range) { - case Range::Line: - { - // cc, change current line. - if (cursor.hasSelection()) { - deleteSelectedText(cursor, true); - insertChangeBlockAfterDeletion(cursor, pos); - } else { - saveToRegister("\n"); - } - - break; - } - - case Range::ParenthesisInner: - // Fall through. - case Range::ParenthesisAround: - // Fall through. - case Range::BracketInner: - // Fall through. - case Range::BracketAround: - // Fall through. - case Range::AngleBracketInner: - // Fall through. - case Range::AngleBracketAround: - // Fall through. - case Range::BraceInner: - // Fall through. - case Range::BraceAround: - // Fall through. - case Range::WordAround: - // Fall through. - case Range::WordInner: - // Fall through. - case Range::WORDAround: - // Fall through. - case Range::WORDInner: - // Fall through. - case Range::QuoteInner: - // Fall through. - case Range::QuoteAround: - // Fall through. - case Range::DoubleQuoteInner: - // Fall through. - case Range::DoubleQuoteAround: - // Fall through. - case Range::BackQuoteInner: - // Fall through. - case Range::BackQuoteAround: - { - if (cursor.hasSelection()) { - deleteSelectedText(cursor, false); - } - - break; - } - - default: - return; - } - } - - cursor.endEditBlock(); - goto exit; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for Change action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - cursor.beginEditBlock(); - if (checkMode(VimMode::VisualLine) || checkMode(VimMode::Visual)) { - // Visual mode, omitting repeat and movement. - // Different from Vim: - // If there is no selection in Visual mode, we do nothing. - bool visualLine = checkMode(VimMode::VisualLine); - if (cursor.hasSelection()) { - hasMoved = true; - int pos = cursor.selectionStart(); - deleteSelectedText(cursor, visualLine); - if (visualLine) { - insertChangeBlockAfterDeletion(cursor, pos); - } - } else if (visualLine) { - hasMoved = true; - saveToRegister("\n"); - } - - cursor.endEditBlock(); - goto exit; - } - - hasMoved = processMovement(cursor, moveMode, to, repeat); - if (repeat == -1) { - repeat = 1; - } - - if (hasMoved) { - bool clearEmptyBlock = false; - switch (to.m_movement) { - case Movement::Left: - { - qDebug() << "change backward" << repeat << "chars"; - break; - } - - case Movement::Right: - { - qDebug() << "change forward" << repeat << "chars"; - break; - } - - case Movement::Up: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change up" << repeat << "lines"; - break; - } - - case Movement::Down: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change down" << repeat << "lines"; - break; - } - - case Movement::VisualUp: - { - qDebug() << "change visual up" << repeat << "lines"; - break; - } - - case Movement::VisualDown: - { - qDebug() << "change visual down" << repeat << "lines"; - break; - } - - case Movement::StartOfLine: - { - qDebug() << "change till start of line"; - break; - } - - case Movement::EndOfLine: - { - // End of line (block). - if (repeat > 1) { - clearEmptyBlock = true; - } - - qDebug() << "change till end of" << repeat << "line"; - break; - } - - case Movement::FirstCharacter: - { - qDebug() << "change till first non-space character"; - break; - } - - case Movement::LineJump: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change till line" << repeat; - break; - } - - case Movement::StartOfDocument: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change till start of document"; - break; - } - - case Movement::EndOfDocument: - { - expandSelectionToWholeLines(cursor); - clearEmptyBlock = true; - qDebug() << "change till end of document"; - break; - } - - case Movement::WordForward: - { - qDebug() << "change" << repeat << "words forward"; - break; - } - - case Movement::WORDForward: - { - qDebug() << "change" << repeat << "WORDs forward"; - break; - } - - case Movement::ForwardEndOfWord: - { - qDebug() << "change" << repeat << "end of words forward"; - break; - } - - case Movement::ForwardEndOfWORD: - { - qDebug() << "change" << repeat << "end of WORDs forward"; - break; - } - - case Movement::WordBackward: - { - qDebug() << "change" << repeat << "words backward"; - break; - } - - case Movement::WORDBackward: - { - qDebug() << "change" << repeat << "WORDs backward"; - break; - } - - case Movement::BackwardEndOfWord: - { - qDebug() << "change" << repeat << "end of words backward"; - break; - } - - case Movement::BackwardEndOfWORD: - { - qDebug() << "change" << repeat << "end of WORDs backward"; - break; - } - - default: - break; - } - - if (cursor.hasSelection()) { - int pos = cursor.selectionStart(); - bool allDeleted = false; - if (pos == 0) { - QTextBlock block = m_editor->documentW()->lastBlock(); - if (block.position() + block.length() - 1 == cursor.selectionEnd()) { - allDeleted = true; - } - } - - deleteSelectedText(cursor, clearEmptyBlock); - if (clearEmptyBlock && !allDeleted) { - insertChangeBlockAfterDeletion(cursor, pos); - } - } - } - - cursor.endEditBlock(); - -exit: - if (hasMoved) { - m_editor->setTextCursorW(cursor); - } - - setMode(VimMode::Insert); -} - -void VVim::processIndentAction(QList &p_tokens, IndentType p_type) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - - QString op; - switch (p_type) { - case IndentType::Indent: - op = ">"; - break; - - case IndentType::UnIndent: - op = "<"; - break; - - case IndentType::AutoIndent: - op = "="; - break; - - default: - Q_ASSERT(false); - } - - if (to.isRange()) { - bool changed = selectRange(cursor, m_editor->documentW(), to.m_range, repeat); - if (changed) { - switch (to.m_range) { - case Range::Line: - { - // >>/<<, indent/unindent current line. - if (repeat == -1) { - repeat = 1; - } - - if (p_type == IndentType::AutoIndent) { - VEditUtils::indentSelectedBlocksAsBlock(cursor, false); - } else { - VEditUtils::indentSelectedBlocks(cursor, - m_editConfig->m_tabSpaces, - p_type == IndentType::Indent); - } - - message(tr("%1 %2 %3ed 1 time").arg(repeat) - .arg(repeat > 1 ? tr("lines") - : tr("line")) - .arg(op)); - break; - } - - case Range::ParenthesisInner: - // Fall through. - case Range::ParenthesisAround: - // Fall through. - case Range::BracketInner: - // Fall through. - case Range::BracketAround: - // Fall through. - case Range::AngleBracketInner: - // Fall through. - case Range::AngleBracketAround: - // Fall through. - case Range::BraceInner: - // Fall through. - case Range::BraceAround: - // Fall through. - case Range::WordAround: - // Fall through. - case Range::WordInner: - // Fall through. - case Range::WORDAround: - // Fall through. - case Range::WORDInner: - // Fall through. - case Range::QuoteInner: - // Fall through. - case Range::QuoteAround: - // Fall through. - case Range::DoubleQuoteInner: - // Fall through. - case Range::DoubleQuoteAround: - // Fall through. - case Range::BackQuoteInner: - // Fall through. - case Range::BackQuoteAround: - { - int nrBlock = VEditUtils::selectedBlockCount(cursor); - if (p_type == IndentType::AutoIndent) { - VEditUtils::indentSelectedBlocksAsBlock(cursor, false); - } else { - VEditUtils::indentSelectedBlocks(cursor, - m_editConfig->m_tabSpaces, - p_type == IndentType::Indent); - } - - message(tr("%1 %2 %3ed 1 time").arg(nrBlock) - .arg(nrBlock > 1 ? tr("lines") - : tr("line")) - .arg(op)); - break; - } - - default: - return; - } - } - - return; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for Indent/UnIndent action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - if (checkMode(VimMode::VisualLine) || checkMode(VimMode::Visual)) { - // Visual mode, omitting repeat and movement. - // Different from Vim: - // Do not exit Visual mode after indentation/unindentation. - if (p_type == IndentType::AutoIndent) { - VEditUtils::indentSelectedBlocksAsBlock(cursor, false); - } else { - VEditUtils::indentSelectedBlocks(cursor, - m_editConfig->m_tabSpaces, - p_type == IndentType::Indent); - } - - return; - } - - processMovement(cursor, - QTextCursor::KeepAnchor, - to, - repeat); - - int nrBlock = VEditUtils::selectedBlockCount(cursor); - if (p_type == IndentType::AutoIndent) { - VEditUtils::indentSelectedBlocksAsBlock(cursor, false); - } else { - VEditUtils::indentSelectedBlocks(cursor, - m_editConfig->m_tabSpaces, - p_type == IndentType::Indent); - } - - message(tr("%1 %2 %3ed 1 time").arg(nrBlock) - .arg(nrBlock > 1 ? tr("lines") - : tr("line")) - .arg(op)); -} - -void VVim::processToLowerAction(QList &p_tokens, bool p_toLower) -{ - Token to = p_tokens.takeFirst(); - int repeat = -1; - if (to.isRepeat()) { - repeat = to.m_repeat; - to = p_tokens.takeFirst(); - } - - if ((!to.isMovement() && !to.isRange()) || !p_tokens.isEmpty()) { - p_tokens.clear(); - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextDocument *doc = m_editor->documentW(); - bool changed = false; - QTextCursor::MoveMode moveMode = QTextCursor::KeepAnchor; - int oriPos = cursor.position(); - - if (to.isRange()) { - cursor.beginEditBlock(); - changed = selectRange(cursor, doc, to.m_range, repeat); - if (changed) { - oriPos = cursor.selectionStart(); - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 changed").arg(nrBlock) - .arg(nrBlock > 1 ? tr("lines") : tr("line"))); - - convertCaseOfSelectedText(cursor, p_toLower); - - cursor.setPosition(oriPos); - } - - cursor.endEditBlock(); - goto exit; - } - - V_ASSERT(to.isMovement()); - - // Filter out not supported movement for ToLower/ToUpper action. - switch (to.m_movement) { - case Movement::PageUp: - case Movement::PageDown: - case Movement::HalfPageUp: - case Movement::HalfPageDown: - return; - - default: - break; - } - - cursor.beginEditBlock(); - changed = processMovement(cursor, - moveMode, - to, - repeat); - if (repeat == -1) { - repeat = 1; - } - - if (changed) { - oriPos = cursor.selectionStart(); - - switch (to.m_movement) { - case Movement::Up: - { - expandSelectionToWholeLines(cursor); - break; - } - - case Movement::Down: - { - expandSelectionToWholeLines(cursor); - break; - } - - case Movement::LineJump: - { - expandSelectionToWholeLines(cursor); - break; - } - - case Movement::StartOfDocument: - { - expandSelectionToWholeLines(cursor); - break; - } - - case Movement::EndOfDocument: - { - expandSelectionToWholeLines(cursor); - break; - } - - default: - break; - } - - int nrBlock = VEditUtils::selectedBlockCount(cursor); - message(tr("%1 %2 changed").arg(nrBlock).arg(nrBlock > 1 ? tr("lines") - : tr("line"))); - - convertCaseOfSelectedText(cursor, p_toLower); - - cursor.setPosition(oriPos); - } - - cursor.endEditBlock(); - -exit: - if (changed) { - m_editor->setTextCursorW(cursor); - } -} - -void VVim::processUndoAction(QList &p_tokens) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat; - } - - QTextDocument *doc = m_editor->documentW(); - int i = 0; - for (i = 0; i < repeat && doc->isUndoAvailable(); ++i) { - m_editor->undoW(); - } - - message(tr("Undo %1 %2").arg(i).arg(i > 1 ? tr("changes") : tr("change"))); -} - -void VVim::processRedoAction(QList &p_tokens) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat; - } - - QTextDocument *doc = m_editor->documentW(); - int i = 0; - for (i = 0; i < repeat && doc->isRedoAvailable(); ++i) { - m_editor->redoW(); - } - - message(tr("Redo %1 %2").arg(i).arg(i > 1 ? tr("changes") : tr("change"))); -} - -void VVim::processRedrawLineAction(QList &p_tokens, int p_dest) -{ - QTextCursor cursor = m_editor->textCursorW(); - int repeat = cursor.block().blockNumber(); - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat - 1; - } - - m_editor->scrollBlockInPage(repeat, p_dest); -} - -void VVim::processJumpLocationAction(QList &p_tokens, bool p_next) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - if (!p_tokens.isEmpty() || !to.isRepeat()) { - p_tokens.clear(); - return; - } - - repeat = to.m_repeat; - } - - QTextCursor cursor = m_editor->textCursorW(); - Location loc; - if (p_next) { - while (m_locations.hasNext() && repeat > 0) { - --repeat; - loc = m_locations.nextLocation(); - } - } else { - while (m_locations.hasPrevious() && repeat > 0) { - --repeat; - loc = m_locations.previousLocation(cursor); - } - } - - if (loc.isValid()) { - QTextDocument *doc = m_editor->documentW(); - if (loc.m_blockNumber >= doc->blockCount()) { - message(tr("Mark has invalid line number")); - return; - } - - QTextBlock block = doc->findBlockByNumber(loc.m_blockNumber); - int pib = loc.m_positionInBlock; - if (pib >= block.length()) { - pib = block.length() - 1; - } - - if (!m_editor->isBlockVisible(block)) { - // Scroll the block to the center of screen. - m_editor->scrollBlockInPage(block.blockNumber(), 1); - } - - cursor.setPosition(block.position() + pib); - m_editor->setTextCursorW(cursor); - } -} - -void VVim::processReplaceAction(QList &p_tokens) -{ - int repeat = 1; - QChar replaceChar; - Q_ASSERT(!p_tokens.isEmpty()); - Token to = p_tokens.takeFirst(); - if (to.isRepeat()) { - repeat = to.m_repeat; - Q_ASSERT(!p_tokens.isEmpty()); - to = p_tokens.takeFirst(); - } - - Q_ASSERT(to.isKey() && p_tokens.isEmpty()); - replaceChar = keyToChar(to.m_key.m_key, to.m_key.m_modifiers); - if (replaceChar.isNull()) { - return; - } - - if (!(checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine))) { - return; - } - - // Replace the next repeat characters with replaceChar until the end of line. - // If repeat is greater than the number of left characters in current line, - // do nothing. - // In visual mode, repeat is ignored. - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (checkMode(VimMode::Normal)) { - // Select the characters to be replaced. - cursor.clearSelection(); - int pib = cursor.positionInBlock(); - int nrChar = cursor.block().length() - 1 - pib; - if (repeat <= nrChar) { - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, repeat); - } - } - - bool changed = replaceSelectedTextWithCharacter(cursor, replaceChar); - cursor.endEditBlock(); - - if (changed) { - m_editor->setTextCursorW(cursor); - setMode(VimMode::Normal); - } -} - -void VVim::processReverseCaseAction(QList &p_tokens) -{ - int repeat = 1; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - Q_ASSERT(to.isRepeat() && p_tokens.isEmpty()); - repeat = to.m_repeat; - } - - if (!(checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine))) { - return; - } - - // Reverse the next repeat characters' case until the end of line. - // If repeat is greater than the number of left characters in current line, - // just change the actual number of left characters. - // In visual mode, repeat is ignored and reverse the selected text. - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (checkMode(VimMode::Normal)) { - // Select the characters to be replaced. - cursor.clearSelection(); - int pib = cursor.positionInBlock(); - int nrChar = cursor.block().length() - 1 - pib; - cursor.movePosition(QTextCursor::Right, - QTextCursor::KeepAnchor, - repeat > nrChar ? nrChar : repeat); - } - - bool changed = reverseSelectedTextCase(cursor); - cursor.endEditBlock(); - - if (changed) { - m_editor->setTextCursorW(cursor); - setMode(VimMode::Normal); - } -} - -void VVim::processJoinAction(QList &p_tokens, bool p_modifySpaces) -{ - int repeat = 2; - if (!p_tokens.isEmpty()) { - Token to = p_tokens.takeFirst(); - Q_ASSERT(to.isRepeat() && p_tokens.isEmpty()); - repeat = qMax(to.m_repeat, repeat); - } - - if (!(checkMode(VimMode::Normal) - || checkMode(VimMode::Visual) - || checkMode(VimMode::VisualLine))) { - return; - } - - // Join repeat lines, with the minimum of two lines. Do nothing when on the - // last line. - // If @p_modifySpaces is true, remove the indent and insert up to two spaces. - // If repeat is too big, it is reduced to the number of lines available. - // In visual mode, repeat is ignored and join the highlighted lines. - int firstBlock = -1; - int blockCount = repeat; - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (checkMode(VimMode::Normal)) { - firstBlock = cursor.block().blockNumber(); - } else { - QTextDocument *doc = m_editor->documentW(); - firstBlock = doc->findBlock(cursor.selectionStart()).blockNumber(); - int lastBlock = doc->findBlock(cursor.selectionEnd()).blockNumber(); - blockCount = lastBlock - firstBlock + 1; - } - - bool changed = joinLines(cursor, firstBlock, blockCount, p_modifySpaces); - cursor.endEditBlock(); - - if (changed) { - m_editor->setTextCursorW(cursor); - setMode(VimMode::Normal); - } -} - -bool VVim::clearSelection() -{ - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.clearSelection(); - m_editor->setTextCursorW(cursor); - return true; - } - - return false; -} - -int VVim::blockCountOfPageStep() const -{ - int lineCount = m_editor->documentW()->blockCount(); - QScrollBar *bar = m_editor->verticalScrollBarW(); - int steps = (bar->maximum() - bar->minimum() + bar->pageStep()); - int pageLineCount = lineCount * (bar->pageStep() * 1.0 / steps); - return pageLineCount; -} - -void VVim::maintainSelectionInVisualMode(QTextCursor *p_cursor) -{ - // We need to always select the character on current position. - QTextCursor *cursor = p_cursor; - QTextCursor tmpCursor = m_editor->textCursorW(); - if (!cursor) { - cursor = &tmpCursor; - } - - bool hasChanged = false; - int pos = cursor->position(); - int anchor = cursor->anchor(); - - if (pos > anchor) { - Q_ASSERT(pos > m_positionBeforeVisualMode); - if (anchor > m_positionBeforeVisualMode) { - // Re-select. - cursor->setPosition(m_positionBeforeVisualMode); - cursor->setPosition(pos, QTextCursor::KeepAnchor); - hasChanged = true; - } - - setCursorBlockMode(m_editor, CursorBlock::LeftSide); - } else if (pos == anchor) { - Q_ASSERT(anchor >= m_positionBeforeVisualMode); - // Re-select. - if (anchor == m_positionBeforeVisualMode) { - cursor->setPosition(m_positionBeforeVisualMode + 1); - cursor->setPosition(pos, QTextCursor::KeepAnchor); - hasChanged = true; - - setCursorBlockMode(m_editor, CursorBlock::RightSide); - } else { - cursor->setPosition(m_positionBeforeVisualMode); - cursor->setPosition(pos, QTextCursor::KeepAnchor); - hasChanged = true; - - setCursorBlockMode(m_editor, CursorBlock::LeftSide); - } - } else { - // Re-select. - if (anchor <= m_positionBeforeVisualMode) { - cursor->setPosition(m_positionBeforeVisualMode + 1); - cursor->setPosition(pos, QTextCursor::KeepAnchor); - hasChanged = true; - } - - setCursorBlockMode(m_editor, CursorBlock::RightSide); - } - - if (hasChanged && !p_cursor) { - m_editor->setTextCursorW(*cursor); - } -} - -void VVim::expandSelectionToWholeLines(QTextCursor &p_cursor) -{ - QTextDocument *doc = m_editor->documentW(); - int curPos = p_cursor.position(); - int anchorPos = p_cursor.anchor(); - QTextBlock curBlock = doc->findBlock(curPos); - QTextBlock anchorBlock = doc->findBlock(anchorPos); - - if (curPos >= anchorPos) { - p_cursor.setPosition(anchorBlock.position(), QTextCursor::MoveAnchor); - p_cursor.setPosition(curBlock.position() + curBlock.length() - 1, - QTextCursor::KeepAnchor); - } else { - p_cursor.setPosition(anchorBlock.position() + anchorBlock.length() - 1, - QTextCursor::MoveAnchor); - p_cursor.setPosition(curBlock.position(), - QTextCursor::KeepAnchor); - } -} - -void VVim::initRegisters() -{ - if (!s_registers.isEmpty()) { - return; - } - - for (char ch = 'a'; ch <= 'z'; ++ch) { - s_registers[QChar(ch)] = Register(QChar(ch)); - } - - s_registers[c_unnamedRegister] = Register(c_unnamedRegister); - s_registers[c_blackHoleRegister] = Register(c_blackHoleRegister); - s_registers[c_selectionRegister] = Register(c_selectionRegister); -} - -bool VVim::expectingRegisterName() const -{ - return m_keys.size() == 1 - && m_keys.at(0) == Key(Qt::Key_QuoteDbl, Qt::ShiftModifier); -} - -bool VVim::expectingCharacterTarget() const -{ - if (m_keys.size() != 1) { - return false; - } - - const Key &key = m_keys.first(); - return (key == Key(Qt::Key_F, Qt::NoModifier) - || key == Key(Qt::Key_F, Qt::ShiftModifier) - || key == Key(Qt::Key_T, Qt::NoModifier) - || key == Key(Qt::Key_T, Qt::ShiftModifier)); -} - -bool VVim::expectingReplaceCharacter() const -{ - return m_keys.size() == 1 - && m_keys.first() == Key(Qt::Key_R, Qt::NoModifier); -} - -bool VVim::expectingLeaderSequence() const -{ - if (m_replayLeaderSequence || m_keys.isEmpty()) { - return false; - } - - return m_keys.first() == Key(Qt::Key_Backslash); -} - -bool VVim::expectingMarkName() const -{ - return checkPendingKey(Key(Qt::Key_M)) && m_tokens.isEmpty(); -} - -bool VVim::expectingMarkTarget() const -{ - return checkPendingKey(Key(Qt::Key_Apostrophe)) - || checkPendingKey(Key(Qt::Key_QuoteLeft)); -} - -QChar VVim::keyToRegisterName(const Key &p_key) const -{ - if (p_key.isAlphabet()) { - return p_key.toAlphabet().toLower(); - } - - switch (p_key.m_key) { - case Qt::Key_QuoteDbl: - if (p_key.m_modifiers == Qt::ShiftModifier) { - return c_unnamedRegister; - } - - break; - - case Qt::Key_Plus: - if (p_key.m_modifiers == Qt::ShiftModifier) { - return c_selectionRegister; - } - - break; - - case Qt::Key_Underscore: - if (p_key.m_modifiers == Qt::ShiftModifier) { - return c_blackHoleRegister; - } - - break; - - default: - break; - } - - return QChar(); -} - -bool VVim::hasActionToken() const -{ - // There will be only one action token and it is placed at the front. - bool has = false; - if (m_tokens.isEmpty()) { - return false; - } - - if (m_tokens.at(0).isAction()) { - has = true; - } - - for (int i = 1; i < m_tokens.size(); ++i) { - V_ASSERT(!m_tokens.at(i).isAction()); - } - - return has; -} - -bool VVim::hasRepeatToken() const -{ - // There will be only one repeat token. - bool has = false; - if (m_tokens.isEmpty()) { - return false; - } - - for (int i = 0; i < m_tokens.size(); ++i) { - if (m_tokens.at(i).isRepeat()) { - V_ASSERT(!has); - has = true; - } - } - - return has; -} - -bool VVim::hasActionTokenValidForTextObject() const -{ - if (hasActionToken()) { - Action act = m_tokens.first().m_action; - if (act == Action::Delete - || act == Action::Copy - || act == Action::Change - || act == Action::ToLower - || act == Action::ToUpper - || act == Action::Indent - || act == Action::UnIndent) { - return true; - } - } - - return false; -} - -bool VVim::checkActionToken(Action p_action) const -{ - if (hasActionToken()) { - return m_tokens.first().m_action == p_action; - } - - return false; -} - -bool VVim::checkPendingKey(const Key &p_key) const -{ - return (m_keys.size() == 1 && m_keys.first() == p_key); -} - -void VVim::tryAddMoveAction() -{ - if (!hasActionToken()) { - addActionToken(Action::Move); - } -} - -void VVim::addActionToken(Action p_action) -{ - V_ASSERT(!hasActionToken()); - m_tokens.prepend(Token(p_action)); -} - -const VVim::Token *VVim::getActionToken() const -{ - V_ASSERT(hasActionToken()); - return &m_tokens.first(); -} - -VVim::Token *VVim::getRepeatToken() -{ - V_ASSERT(hasRepeatToken()); - - for (auto & token : m_tokens) { - if (token.isRepeat()) { - return &token; - } - } - - return NULL; -} - -void VVim::addRangeToken(Range p_range) -{ - m_tokens.append(Token(p_range)); -} - -void VVim::addMovementToken(Movement p_movement) -{ - m_tokens.append(Token(p_movement)); -} - -void VVim::addMovementToken(Movement p_movement, Key p_key) -{ - m_tokens.append(Token(p_movement, p_key)); -} - -void VVim::addKeyToken(Key p_key) -{ - m_tokens.append(Token(p_key)); -} - -void VVim::deleteSelectedText(QTextCursor &p_cursor, bool p_clearEmptyBlock) -{ - if (p_cursor.hasSelection()) { - QString deletedText = VEditUtils::selectedText(p_cursor); - p_cursor.removeSelectedText(); - if (p_clearEmptyBlock && p_cursor.block().length() == 1) { - deletedText += "\n"; - VEditUtils::removeBlock(p_cursor); - } - - saveToRegister(deletedText); - } -} - -void VVim::copySelectedText(bool p_addNewLine) -{ - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.beginEditBlock(); - copySelectedText(cursor, p_addNewLine); - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - } -} - -void VVim::copySelectedText(QTextCursor &p_cursor, bool p_addNewLine) -{ - if (p_cursor.hasSelection()) { - QString text = VEditUtils::selectedText(p_cursor); - p_cursor.clearSelection(); - if (p_addNewLine) { - text += "\n"; - } - - saveToRegister(text); - } -} - -void VVim::convertCaseOfSelectedText(QTextCursor &p_cursor, bool p_toLower) -{ - if (p_cursor.hasSelection()) { - QTextDocument *doc = p_cursor.document(); - int start = p_cursor.selectionStart(); - int end = p_cursor.selectionEnd(); - p_cursor.clearSelection(); - p_cursor.setPosition(start); - int pos = p_cursor.position(); - while (pos < end) { - QChar ch = doc->characterAt(pos); - bool modified = false; - if (p_toLower) { - if (ch.isUpper()) { - ch = ch.toLower(); - modified = true; - } - } else if (ch.isLower()) { - ch = ch.toUpper(); - modified = true; - } - - if (modified) { - p_cursor.deleteChar(); - p_cursor.insertText(ch); - } else { - p_cursor.movePosition(QTextCursor::NextCharacter); - } - - pos = p_cursor.position(); - } - } -} - -void VVim::saveToRegister(const QString &p_text) -{ - QString text(p_text); - VEditUtils::removeObjectReplacementCharacter(text); - - qDebug() << QString("save text(%1) to register(%2)").arg(text).arg(m_regName); - - Register ® = getRegister(m_regName); - reg.update(text); - - if (!reg.isBlackHoleRegister() && !reg.isUnnamedRegister()) { - // Save it to unnamed register. - setRegister(c_unnamedRegister, reg.m_value); - } -} - -void VVim::Register::update(const QString &p_value) -{ - QChar newLine('\n'); - bool newIsBlock = false; - if (p_value.endsWith(newLine)) { - newIsBlock = true; - } - - bool oriIsBlock = isBlock(); - if (isNamedRegister() && m_append) { - // Append @p_value to m_value. - if (newIsBlock) { - if (oriIsBlock) { - m_value += p_value; - } else { - m_value.append(newLine); - m_value += p_value; - } - } else if (oriIsBlock) { - m_value += p_value; - m_value.append(newLine); - } else { - m_value += p_value; - } - } else { - // Set m_value to @p_value. - m_value = p_value; - } - - if (isSelectionRegister()) { - // Change system clipboard. - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(m_value); - } -} - -const QString &VVim::Register::read() -{ - if (isSelectionRegister()) { - // Update from system clipboard. - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - if (mimeData->hasText()) { - m_value = mimeData->text(); - } else { - m_value.clear(); - } - } - - return m_value; -} - -void VVim::repeatLastFindMovement(bool p_reverse) -{ - if (!m_lastFindToken.isValid()) { - return; - } - - V_ASSERT(m_lastFindToken.isMovement()); - - Movement mm = m_lastFindToken.m_movement; - Key key = m_lastFindToken.m_key; - - V_ASSERT(key.isValid()); - - if (p_reverse) { - switch (mm) { - case Movement::FindForward: - mm = Movement::FindBackward; - break; - - case Movement::FindBackward: - mm = Movement::FindForward; - break; - - case Movement::TillForward: - mm = Movement::TillBackward; - break; - - case Movement::TillBackward: - mm = Movement::TillForward; - break; - - default: - break; - } - } - - tryAddMoveAction(); - addMovementToken(mm, key); - processCommand(m_tokens); -} - -void VVim::message(const QString &p_msg) -{ - if (!p_msg.isEmpty()) { - qDebug() << "vim msg:" << p_msg; - emit vimMessage(p_msg); - } -} - -const QMap &VVim::getRegisters() const -{ - return s_registers; -} - -const VVim::Marks &VVim::getMarks() const -{ - return m_marks; -} - -QChar VVim::getCurrentRegisterName() const -{ - return m_regName; -} - -QString VVim::getPendingKeys() const -{ - QString str; - for (auto const & key : m_pendingKeys) { - str.append(keyToString(key.m_key, key.m_modifiers)); - } - - return str; -} - -void VVim::setCurrentRegisterName(QChar p_reg) -{ - m_regName = p_reg; -} - -bool VVim::checkMode(VimMode p_mode) -{ - return m_mode == p_mode; -} - -bool VVim::processCommandLine(VVim::CommandLineType p_type, const QString &p_cmd) -{ - setMode(VimMode::Normal); - - bool ret = false; - switch (p_type) { - case CommandLineType::Command: - ret = executeCommand(p_cmd); - break; - - case CommandLineType::SearchForward: - // Fall through. - case CommandLineType::SearchBackward: - { - SearchItem item = fetchSearchItem(p_type, p_cmd); - m_editor->findText(item.m_text, item.m_options, item.m_forward); - m_searchHistory.addItem(item); - m_searchHistory.resetIndex(); - break; - } - - default: - break; - } - - return ret; -} - -void VVim::processCommandLineChanged(VVim::CommandLineType p_type, - const QString &p_cmd) -{ - setMode(VimMode::Normal); - - if (p_type == CommandLineType::SearchForward - || p_type == CommandLineType::SearchBackward) { - // Peek text. - SearchItem item = fetchSearchItem(p_type, p_cmd); - m_editor->peekText(item.m_text, item.m_options, item.m_forward); - } -} - -void VVim::processCommandLineCancelled() -{ - m_searchHistory.resetIndex(); - m_editor->clearIncrementalSearchedWordHighlight(); -} - -VVim::SearchItem VVim::fetchSearchItem(VVim::CommandLineType p_type, - const QString &p_cmd) -{ - Q_ASSERT(p_type == CommandLineType::SearchForward - || p_type == CommandLineType::SearchBackward); - - SearchItem item; - item.m_rawStr = p_cmd; - item.m_text = p_cmd; - item.m_forward = p_type == CommandLineType::SearchForward; - - if (p_cmd.indexOf("\\C") > -1) { - item.m_options |= FindOption::CaseSensitive; - item.m_text.remove("\\C"); - } - - item.m_options |= FindOption::RegularExpression; - - return item; -} - -bool VVim::executeCommand(const QString &p_cmd) -{ - bool validCommand = true; - QString msg; - - Q_ASSERT(m_tokens.isEmpty() && m_keys.isEmpty()); - if (p_cmd.isEmpty()) { - return true; - } else if (p_cmd.size() == 1) { - if (p_cmd == "w") { - // :w, save current file. - emit m_editor->object()->saveNote(); - msg = tr("Note has been saved"); - } else if (p_cmd == "q") { - // :q, quit edit mode. - emit m_editor->object()->discardAndRead(); - msg = tr("Quit"); - } else if (p_cmd == "x") { - // :x, save if there is any change and quit edit mode. - emit m_editor->object()->saveAndRead(); - msg = tr("Quit with note having been saved"); - } else { - validCommand = false; - } - } else if (p_cmd.size() == 2) { - if (p_cmd == "wq") { - // :wq, save change and quit edit mode. - // We treat it same as :x. - emit m_editor->object()->saveAndRead(); - msg = tr("Quit with note having been saved"); - } else if (p_cmd == "q!") { - // :q!, discard change and quit edit mode. - emit m_editor->object()->discardAndRead(); - msg = tr("Quit"); - } else { - validCommand = false; - } - } else if (p_cmd == "nohlsearch" || p_cmd == "noh") { - // :nohlsearch, clear highlight search. - clearSearchHighlight(); - } else if (p_cmd.size() > 3 && p_cmd.left(2) == "e ") { - // :e , open a note in edit mode. - auto filePath = p_cmd.mid(2).trimmed(); - - if(filePath.left(2) == "~/") { - filePath.remove(0, 1).insert(0, QDir::homePath()); - } else if(filePath.left(2) == "./" || filePath[0] != '/') { - VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory(); - if(filePath.left(2) == "./") { - filePath.remove(0, 1); - } else { - filePath.insert(0, '/'); - } - filePath.insert(0, dir->fetchPath()); - } - - if(g_mainWin->openFiles(QStringList(filePath), false, OpenFileMode::Edit).size()) { - msg = tr("Open %1 in edit mode.").arg(filePath); - } else { - msg = tr("Unable to open %1").arg(filePath); - } - } else { - validCommand = false; - } - - if (!validCommand) { - bool allDigits = true; - for (int i = 0; i < p_cmd.size(); ++i) { - if (!p_cmd[i].isDigit()) { - allDigits = false; - break; - } - } - - // All digits. - // Jump to a specific line. - if (allDigits) { - bool ok; - int num = p_cmd.toInt(&ok, 10); - if (num == 0) { - num = 1; - } - - if (ok && num > 0) { - m_tokens.append(Token(num)); - tryAddMoveAction(); - addMovementToken(Movement::LineJump); - processCommand(m_tokens); - validCommand = true; - } - } - } - - if (!validCommand) { - message(tr("Not an editor command: %1").arg(p_cmd)); - } else { - message(msg); - } - - return validCommand; -} - -bool VVim::hasNonDigitPendingKeys(const QList &p_keys) -{ - for (auto const &key : p_keys) { - if (!key.isDigit()) { - return true; - } - } - - return false; -} - -bool VVim::hasNonDigitPendingKeys() -{ - return hasNonDigitPendingKeys(m_keys); -} - -bool VVim::processLeaderSequence(const Key &p_key) -{ - // Different from Vim: - // If it is not a valid sequence, we just do nothing here. - V_ASSERT(checkPendingKey(Key(Qt::Key_Backslash))); - bool validSequence = true; - QList replaySeq; - - if (p_key == Key(Qt::Key_Y)) { - // y, "+y - replaySeq.append(Key(Qt::Key_QuoteDbl, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Plus, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Y)); - } else if (p_key == Key(Qt::Key_D)) { - // d, "+d - replaySeq.append(Key(Qt::Key_QuoteDbl, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Plus, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_D)); - } else if (p_key == Key(Qt::Key_P)) { - // p, "+p - replaySeq.append(Key(Qt::Key_QuoteDbl, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Plus, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_P)); - } else if (p_key == Key(Qt::Key_P, Qt::ShiftModifier)) { - // P, "+P - replaySeq.append(Key(Qt::Key_QuoteDbl, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_Plus, Qt::ShiftModifier)); - replaySeq.append(Key(Qt::Key_P, Qt::ShiftModifier)); - } else if (p_key == Key(Qt::Key_Space)) { - // , clear search highlight - clearSearchHighlight(); - } else if (p_key == Key(Qt::Key_W)) { - // w, save note - emit m_editor->object()->saveNote(); - message(tr("Note has been saved")); - } else { - validSequence = false; - } - - if (!replaySeq.isEmpty()) { - // Replay the sequence. - m_replayLeaderSequence = true; - m_keys.clear(); - for (int i = 0; i < 2; ++i) { - m_pendingKeys.pop_back(); - } - - for (auto const &key : replaySeq) { - bool ret = handleKeyPressEvent(key.m_key, key.m_modifiers); - if (!ret) { - break; - } - } - - m_replayLeaderSequence = false; - } else { - resetState(); - } - - return validSequence; -} - -VVim::LocationStack::LocationStack(int p_maximum) - : m_pointer(0), c_maximumLocations(p_maximum < 10 ? 10 : p_maximum) -{ -} - -bool VVim::LocationStack::hasPrevious() const -{ - return m_pointer > 0; -} - -bool VVim::LocationStack::hasNext() const -{ - return m_pointer < m_locations.size() - 1; -} - -void VVim::LocationStack::addLocation(const QTextCursor &p_cursor) -{ - int blockNumber = p_cursor.block().blockNumber(); - int pib = p_cursor.positionInBlock(); - - // Remove older location with the same block number. - for (auto it = m_locations.begin(); it != m_locations.end();) { - if (it->m_blockNumber == blockNumber) { - it = m_locations.erase(it); - break; - } else { - ++it; - } - } - - if (m_locations.size() >= c_maximumLocations) { - m_locations.removeFirst(); - } - - m_locations.append(Location(blockNumber, pib)); - - m_pointer = m_locations.size(); - - qDebug() << QString("add location (%1,%2), pointer=%3") - .arg(blockNumber).arg(pib).arg(m_pointer); -} - -const VVim::Location &VVim::LocationStack::previousLocation(const QTextCursor &p_cursor) -{ - V_ASSERT(hasPrevious()); - if (m_pointer == m_locations.size()) { - // Add current location to the stack. - addLocation(p_cursor); - - m_pointer = m_locations.size() - 1; - } - - // Jump to previous location. - if (m_pointer > 0) { - --m_pointer; - } - - qDebug() << QString("previous location (%1,%2), pointer=%3, size=%4") - .arg(m_locations.at(m_pointer).m_blockNumber) - .arg(m_locations.at(m_pointer).m_positionInBlock) - .arg(m_pointer).arg(m_locations.size()); - - return m_locations.at(m_pointer); -} - -const VVim::Location &VVim::LocationStack::nextLocation() -{ - V_ASSERT(hasNext()); - ++m_pointer; - - qDebug() << QString("next location (%1,%2), pointer=%3, size=%4") - .arg(m_locations.at(m_pointer).m_blockNumber) - .arg(m_locations.at(m_pointer).m_positionInBlock) - .arg(m_pointer).arg(m_locations.size()); - - return m_locations.at(m_pointer); -} - -VVim::Marks::Marks() -{ - for (char ch = 'a'; ch <= 'z'; ++ch) { - m_marks[QChar(ch)] = Mark(); - } -} - -void VVim::Marks::setMark(QChar p_name, const QTextCursor &p_cursor) -{ - auto it = m_marks.find(p_name); - if (it == m_marks.end()) { - return; - } - - it->m_location.m_blockNumber = p_cursor.block().blockNumber(); - it->m_location.m_positionInBlock = p_cursor.positionInBlock(); - it->m_text = p_cursor.block().text().trimmed(); - it->m_name = p_name; - - m_lastUsedMark = p_name; - - qDebug() << QString("set mark %1 to (%2,%3)") - .arg(p_name) - .arg(it->m_location.m_blockNumber) - .arg(it->m_location.m_positionInBlock); -} - -void VVim::Marks::clearMark(QChar p_name) -{ - auto it = m_marks.find(p_name); - if (it == m_marks.end()) { - return; - } - - it->m_location = Location(); - it->m_text.clear(); - - if (m_lastUsedMark == p_name) { - m_lastUsedMark = QChar(); - } -} - -VVim::Location VVim::Marks::getMarkLocation(QChar p_name) -{ - auto it = m_marks.find(p_name); - if (it == m_marks.end()) { - return Location(); - } - - if (it->m_location.isValid()) { - m_lastUsedMark = p_name; - } - - return it->m_location; -} - -const QMap &VVim::Marks::getMarks() const -{ - return m_marks; -} - -QChar VVim::Marks::getLastUsedMark() const -{ - return m_lastUsedMark; -} - -void VVim::processTitleJump(const QList &p_tokens, bool p_forward, int p_relativeLevel) -{ - int repeat = 1; - if (p_tokens.size() == 1) { - Token to = p_tokens.first(); - if (to.isRepeat()) { - repeat = to.m_repeat; - } else { - return; - } - } else if (!p_tokens.isEmpty()) { - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - if (m_editor->jumpTitle(p_forward, p_relativeLevel, repeat)) { - // Record current location. - m_locations.addLocation(cursor); - } -} - -void VVim::SearchHistory::addItem(const SearchItem &p_item) -{ - m_isLastItemForward = p_item.m_forward; - if (m_isLastItemForward) { - m_forwardItems.push_back(p_item); - m_forwardIdx = m_forwardItems.size(); - } else { - m_backwardItems.push_back(p_item); - m_backwardIdx = m_forwardItems.size(); - } - - qDebug() << "search history add item" << m_isLastItemForward - << m_forwardIdx << m_forwardItems.size() - << m_backwardIdx << m_backwardItems.size(); -} - -const VVim::SearchItem &VVim::SearchHistory::lastItem() const -{ - if (m_isLastItemForward) { - Q_ASSERT(!m_forwardItems.isEmpty()); - return m_forwardItems.back(); - } else { - Q_ASSERT(!m_backwardItems.isEmpty()); - return m_backwardItems.back(); - } -} - -const VVim::SearchItem &VVim::SearchHistory::nextItem(bool p_forward) -{ - Q_ASSERT(hasNext(p_forward)); - return p_forward ? m_forwardItems.at(++m_forwardIdx) - : m_backwardItems.at(++m_backwardIdx); -} - -// Return previous item in the @p_forward stack. -const VVim::SearchItem &VVim::SearchHistory::previousItem(bool p_forward) -{ - Q_ASSERT(hasPrevious(p_forward)); - qDebug() << "previousItem" << p_forward << m_forwardItems.size() << m_backwardItems.size() - << m_forwardIdx << m_backwardIdx; - return p_forward ? m_forwardItems.at(--m_forwardIdx) - : m_backwardItems.at(--m_backwardIdx); -} - -void VVim::SearchHistory::resetIndex() -{ - m_forwardIdx = m_forwardItems.size(); - m_backwardIdx = m_backwardItems.size(); -} - -QString VVim::getNextCommandHistory(VVim::CommandLineType p_type, - const QString &p_cmd) -{ - Q_UNUSED(p_cmd); - bool forward = false; - QString cmd; - switch (p_type) { - case CommandLineType::SearchForward: - forward = true; - // Fall through. - case CommandLineType::SearchBackward: - if (m_searchHistory.hasNext(forward)) { - return m_searchHistory.nextItem(forward).m_rawStr; - } else { - m_searchHistory.resetIndex(); - } - - break; - - default: - break; - } - - return cmd; -} - -// Get the previous command in history of @p_type. @p_cmd is the current input. -QString VVim::getPreviousCommandHistory(VVim::CommandLineType p_type, - const QString &p_cmd) -{ - Q_UNUSED(p_cmd); - bool forward = false; - QString cmd; - switch (p_type) { - case CommandLineType::SearchForward: - forward = true; - // Fall through. - case CommandLineType::SearchBackward: - if (m_searchHistory.hasPrevious(forward)) { - return m_searchHistory.previousItem(forward).m_rawStr; - } - - break; - - default: - break; - } - - return cmd; -} - -void VVim::clearSearchHighlight() -{ - m_editor->clearSearchedWordHighlight(); -} - -QString VVim::readRegister(int p_key, int p_modifiers) -{ - Key keyInfo(p_key, p_modifiers); - QChar reg = keyToRegisterName(keyInfo); - if (!reg.isNull()) { - return getRegister(reg).read(); - } - - return ""; -} - -void VVim::amendCursorPosition() -{ - if (checkMode(VimMode::Normal)) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.atBlockEnd() && !cursor.atBlockStart()) { - // Normal mode and cursor at the end of a non-empty block. - cursor.movePosition(QTextCursor::PreviousCharacter); - m_editor->setTextCursorW(cursor); - } - } -} - -void VVim::handleMousePressed(QMouseEvent *p_event) -{ - Q_UNUSED(p_event); - if ((checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) - && p_event->buttons() != Qt::RightButton) { - setMode(VimMode::Normal); - } -} - -void VVim::handleMouseDoubleClicked(QMouseEvent *p_event) -{ - Q_UNUSED(p_event); - if (checkMode(VimMode::Normal)) { - if (m_editor->textCursorW().hasSelection()) { - setMode(VimMode::Visual, false); - maintainSelectionInVisualMode(); - } - } -} - -void VVim::handleMouseMoved(QMouseEvent *p_event) -{ - if (p_event->buttons() != Qt::LeftButton) { - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - if (checkMode(VimMode::Normal)) { - int pos = cursor.position(); - int anchor = cursor.anchor(); - QTextBlock block = cursor.document()->findBlock(anchor); - if (anchor > 0 && anchor == block.position() + block.length() - 1) { - // Move anchor left. - cursor.setPosition(anchor - 1); - cursor.setPosition(pos, QTextCursor::KeepAnchor); - m_editor->setTextCursorW(cursor); - } - - setMode(VimMode::Visual, false); - maintainSelectionInVisualMode(); - } else if (checkMode(VimMode::Visual)) { - // We need to assure we always select the character on m_positionBeforeVisualMode. - maintainSelectionInVisualMode(); - } - } else if (checkMode(VimMode::Visual)) { - // User move cursor in Visual mode. Now the cursor and anchor - // are at the same position. - maintainSelectionInVisualMode(); - } -} - -void VVim::handleMouseReleased(QMouseEvent *p_event) -{ - if (checkMode(VimMode::Normal) && p_event->button() == Qt::LeftButton) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - return; - } - - amendCursorPosition(); - } -} - -void VVim::setCursorBlockMode(VEditor *p_cursor, CursorBlock p_mode) -{ - p_cursor->setCursorBlockModeW(p_mode); -} - -bool VVim::useLeftSideOfCursor(const QTextCursor &p_cursor) -{ - if (!checkMode(VimMode::Visual)) { - return false; - } - - Q_ASSERT(m_positionBeforeVisualMode >= 0); - return p_cursor.position() > m_positionBeforeVisualMode; -} - -bool VVim::checkEnterNormalMode(int p_key, int p_modifiers) -{ - if (p_key == Qt::Key_Escape) { - return true; - } - - if (!VUtils::isControlModifierForVim(p_modifiers)) { - return false; - } - - if (p_key == Qt::Key_BracketLeft) { - return true; - } - - if (p_key == Qt::Key_C && !g_config->getVimExemptionKeys().contains('c')) { - return true; - } - - return false; -} - -void VVim::clearSelectionAndEnterNormalMode() -{ - int position = -1; - if (checkMode(VimMode::Visual)) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.position() > cursor.anchor()) { - position = cursor.position() - 1; - } - } - - bool ret = clearSelection(); - if (!ret && checkMode(VimMode::Normal)) { - emit m_editor->object()->requestCloseFindReplaceDialog(); - } - - setMode(VimMode::Normal, true, position); -} - -bool VVim::isKeyShouldBeIgnored(int p_key) const -{ - if (VUtils::isMetaKey(p_key)) { - return true; - } - - return false; -} diff --git a/src/utils/vvim.h b/src/utils/vvim.h deleted file mode 100644 index e503bd4c..00000000 --- a/src/utils/vvim.h +++ /dev/null @@ -1,908 +0,0 @@ -#ifndef VVIM_H -#define VVIM_H - -#include -#include -#include -#include -#include -#include "vutils.h" - -class VEditor; -class QKeyEvent; -class VEditConfig; -class QKeyEvent; -class QMouseEvent; - -enum class VimMode { - Normal = 0, - Insert, - Visual, - VisualLine, - Replace, - Invalid -}; - -class VVim : public QObject -{ - Q_OBJECT -public: - explicit VVim(VEditor *p_editor); - - // Struct for a location. - struct Location - { - Location() : m_blockNumber(-1), m_positionInBlock(0) - { - } - - Location(int p_blockNumber, int p_positionInBlock) - : m_blockNumber(p_blockNumber), m_positionInBlock(p_positionInBlock) - { - } - - bool isValid() const - { - return m_blockNumber > -1; - } - - // Block number of the location, based on 0. - int m_blockNumber; - - // Position in block, based on 0. - int m_positionInBlock; - }; - - struct Register - { - Register(QChar p_name, const QString &p_value) - : m_name(p_name), m_value(p_value), m_append(false) - { - } - - Register(QChar p_name) - : m_name(p_name), m_append(false) - { - } - - Register() - : m_append(false) - { - } - - // Register a-z. - bool isNamedRegister() const - { - char ch = m_name.toLatin1(); - return ch >= 'a' && ch <= 'z'; - } - - bool isUnnamedRegister() const - { - return m_name == c_unnamedRegister; - } - - bool isBlackHoleRegister() const - { - return m_name == c_blackHoleRegister; - } - - bool isSelectionRegister() const - { - return m_name == c_selectionRegister; - } - - bool isBlock() const - { - return m_value.endsWith('\n'); - } - - // @p_value is the content to update. - // If @p_value ends with \n, then it is a block. - // When @p_value is a block, we need to add \n at the end if necessary. - // If @m_append is true and @p_value is a block, we need to add \n between - // them if necessary. - void update(const QString &p_value); - - // Read the value of this register. - const QString &read(); - - QChar m_name; - QString m_value; - - // This is not info of Register itself, but a hint to the handling logics - // whether we need to append the content to this register. - // Only valid for a-z registers. - bool m_append; - }; - - struct Mark - { - QChar m_name; - Location m_location; - QString m_text; - }; - - // We only support simple local marks a-z. - class Marks - { - public: - Marks(); - - // Set mark @p_name to point to @p_cursor. - void setMark(QChar p_name, const QTextCursor &p_cursor); - - void clearMark(QChar p_name); - - // Return the location of mark @p_name. - Location getMarkLocation(QChar p_name); - - const QMap &getMarks() const; - - QChar getLastUsedMark() const; - - private: - QMap m_marks; - - QChar m_lastUsedMark; - }; - - enum class CommandLineType - { - Command, - SearchForward, - SearchBackward, - Invalid - }; - - // Search item including the searched text and options. - struct SearchItem - { - SearchItem() : m_options(0), m_forward(true) {} - - bool isEmpty() const - { - return m_text.isEmpty(); - } - - // The user raw input. - QString m_rawStr; - - // The string used to search. - QString m_text; - - uint m_options; - bool m_forward; - }; - - // Handle key press event. - // @p_autoIndentPos: the cursor position of last auto indent. - // Returns true if the event is consumed and need no more handling. - bool handleKeyPressEvent(QKeyEvent *p_event, int *p_autoIndentPos = NULL); - - // Return current mode. - VimMode getMode() const; - - // Set current mode. - void setMode(VimMode p_mode, bool p_clearSelection = true, int p_position = -1); - - // Set current register. - void setCurrentRegisterName(QChar p_reg); - - // Get m_registers. - const QMap &getRegisters() const; - - QChar getCurrentRegisterName() const; - - // Get pending keys. - // Turn m_pendingKeys to a string. - QString getPendingKeys() const; - - // Get m_marks. - const VVim::Marks &getMarks() const; - - // Process command line of type @p_type and command @p_cmd. - // Returns true if it is a valid command. - bool processCommandLine(VVim::CommandLineType p_type, const QString &p_cmd); - - // Process the command line text change. - void processCommandLineChanged(VVim::CommandLineType p_type, - const QString &p_cmd); - - void processCommandLineCancelled(); - - // Get the next command in history of @p_type. @p_cmd is the current input. - // Return NULL QString if history is not applicable. - QString getNextCommandHistory(VVim::CommandLineType p_type, - const QString &p_cmd); - - // Get the previous command in history of @p_type. @p_cmd is the current input. - // Return NULL QString if history is not applicable. - QString getPreviousCommandHistory(VVim::CommandLineType p_type, - const QString &p_cmd); - - // Read the register content. - // Returns empty string if it is not a valid register. - QString readRegister(int p_key, int p_modifiers); - - // Fetch the searched string and options from @p_type and @p_cmd. - // \C for case-sensitive; - // Case-insensitive by default. - // Regular-expression by default. - static VVim::SearchItem fetchSearchItem(VVim::CommandLineType p_type, const QString &p_cmd); - -signals: - // Emit when current mode has been changed. - void modeChanged(VimMode p_mode); - - // Emit when VVim want to display some messages. - void vimMessage(const QString &p_msg); - - // Emit when current status updated. - void vimStatusUpdated(const VVim *p_vim); - - // Emit when user pressed : to trigger command line. - void commandLineTriggered(VVim::CommandLineType p_type); - -private slots: - void handleMousePressed(QMouseEvent *p_event); - - void handleMouseMoved(QMouseEvent *p_event); - - void handleMouseReleased(QMouseEvent *p_event); - - void handleMouseDoubleClicked(QMouseEvent *p_event); - - // When we display cursor as block, it makes no sense to put cursor at the - // end of line. - void amendCursorPosition(); - -private: - // Struct for a key press. - struct Key - { - Key(int p_key, int p_modifiers = Qt::NoModifier) - : m_key(p_key), m_modifiers(p_modifiers) - { - } - - Key() : m_key(-1), m_modifiers(Qt::NoModifier) {} - - int m_key; - int m_modifiers; - - bool isDigit() const - { - return m_key >= Qt::Key_0 - && m_key <= Qt::Key_9 - && (m_modifiers == Qt::NoModifier || m_modifiers == Qt::KeypadModifier); - } - - int toDigit() const - { - V_ASSERT(isDigit()); - return m_key - Qt::Key_0; - } - - bool isAlphabet() const - { - return m_key >= Qt::Key_A - && m_key <= Qt::Key_Z - && (m_modifiers == Qt::NoModifier || m_modifiers == Qt::ShiftModifier); - } - - QChar toAlphabet() const - { - V_ASSERT(isAlphabet()); - if (m_modifiers == Qt::NoModifier) { - return QChar('a' + (m_key - Qt::Key_A)); - } else { - return QChar('A' + (m_key - Qt::Key_A)); - } - } - - bool isValid() const - { - return m_key > -1 && m_modifiers > -1; - } - - bool operator==(const Key &p_key) const - { - return p_key.m_key == m_key && p_key.m_modifiers == m_modifiers; - } - }; - - class SearchHistory - { - public: - SearchHistory() - : m_forwardIdx(0), m_backwardIdx(0), m_isLastItemForward(true) {} - - // Add @p_item to history. - void addItem(const SearchItem &p_item); - - // Whether the history is empty. - bool isEmpty() const - { - return m_forwardItems.isEmpty() && m_backwardItems.isEmpty(); - } - - bool hasNext(bool p_forward) const - { - return p_forward ? m_forwardIdx < m_forwardItems.size() - 1 - : m_backwardIdx < m_backwardItems.size() - 1; - } - - bool hasPrevious(bool p_forward) const - { - return p_forward ? m_forwardIdx > 0 - : m_backwardIdx > 0; - } - - // Return the last search item according to m_isLastItemForward. - // Make sure the history is not empty before calling this. - const SearchItem &lastItem() const; - - // Return next item in the @p_forward stack. - // Make sure before by calling hasNext(). - const SearchItem &nextItem(bool p_forward); - - // Return previous item in the @p_forward stack. - // Make sure before by calling hasPrevious(). - const SearchItem &previousItem(bool p_forward); - - void resetIndex(); - - private: - // Maintain two stacks for the search history. Use the back as the top - // of the stack. - // The idx points to the next item to push. - // Just simply add new search item to the stack, without duplication. - QList m_forwardItems; - int m_forwardIdx; - - QList m_backwardItems; - int m_backwardIdx; - - // Whether last search item is forward or not. - bool m_isLastItemForward; - - static const int c_capacity; - }; - - // Supported actions. - enum class Action - { - Move = 0, - Delete, - Copy, - Paste, - PasteBefore, - Change, - Indent, - UnIndent, - AutoIndent, - ToUpper, - ToLower, - ReverseCase, - Undo, - Redo, - RedrawAtTop, - RedrawAtCenter, - RedrawAtBottom, - JumpPreviousLocation, - JumpNextLocation, - Replace, - Join, - JoinNoModification, - Invalid - }; - - // Supported movements. - enum class Movement - { - Left = 0, - Right, - Up, - Down, - VisualUp, - VisualDown, - PageUp, - PageDown, - HalfPageUp, - HalfPageDown, - StartOfVisualLine, - StartOfLine, - EndOfLine, - FirstCharacter, - LineJump, - StartOfDocument, - EndOfDocument, - WordForward, - WORDForward, - ForwardEndOfWord, - ForwardEndOfWORD, - WordBackward, - WORDBackward, - BackwardEndOfWord, - BackwardEndOfWORD, - FindForward, - FindBackward, - TillForward, - TillBackward, - MarkJump, - MarkJumpLine, - FindPair, - FindNext, - FindPrevious, - FindNextWordUnderCursor, - FindPreviousWordUnderCursor, - ParagraphUp, - ParagraphDown, - Invalid - }; - - // Supported ranges. - enum class Range - { - Line = 0, - WordInner, - WordAround, - WORDInner, - WORDAround, - QuoteInner, - QuoteAround, - DoubleQuoteInner, - DoubleQuoteAround, - BackQuoteInner, - BackQuoteAround, - ParenthesisInner, - ParenthesisAround, - BracketInner, - BracketAround, - AngleBracketInner, - AngleBracketAround, - BraceInner, - BraceAround, - Invalid - }; - - enum class TokenType { Action = 0, Repeat, Movement, Range, Key, Invalid }; - - struct Token - { - Token(Action p_action) - : m_type(TokenType::Action), m_action(p_action) {} - - Token(int p_repeat) - : m_type(TokenType::Repeat), m_repeat(p_repeat) {} - - Token(Movement p_movement) - : m_type(TokenType::Movement), m_movement(p_movement) {} - - Token(Movement p_movement, Key p_key) - : m_type(TokenType::Movement), m_movement(p_movement), m_key(p_key) {} - - Token(Range p_range) - : m_type(TokenType::Range), m_range(p_range) {} - - Token(Key p_key) - : m_type(TokenType::Key), m_key(p_key) {} - - Token() : m_type(TokenType::Invalid) {} - - bool isRepeat() const - { - return m_type == TokenType::Repeat; - } - - bool isAction() const - { - return m_type == TokenType::Action; - } - - bool isMovement() const - { - return m_type == TokenType::Movement; - } - - bool isRange() const - { - return m_type == TokenType::Range; - } - - bool isKey() const - { - return m_type == TokenType::Key; - } - - bool isValid() const - { - return m_type != TokenType::Invalid; - } - - QString toString() const - { - QString str; - switch (m_type) { - case TokenType::Action: - str = QString("action %1").arg((int)m_action); - break; - - case TokenType::Repeat: - str = QString("repeat %1").arg(m_repeat); - break; - - case TokenType::Movement: - str = QString("movement %1").arg((int)m_movement); - break; - - case TokenType::Range: - str = QString("range %1").arg((int)m_range); - break; - - case TokenType::Key: - str = QString("key %1 %2").arg(m_key.m_key).arg(m_key.m_modifiers); - break; - - default: - str = "invalid"; - } - - return str; - } - - TokenType m_type; - - union - { - Action m_action; - int m_repeat; - Range m_range; - Movement m_movement; - }; - - // Used in some Movement and Key Token. - Key m_key; - }; - - // Stack for all the jump locations. - // When we execute a jump action, we push current location to the stack and - // remove older location with the same block number. - // Ctrl+O is also a jum action. If m_pointer points to the top of the stack, - // Ctrl+O will insert a location to the stack. - class LocationStack - { - public: - LocationStack(int p_maximum = 100); - - // Add @p_cursor's location to stack. - // Need to delete all older locations with the same block number. - void addLocation(const QTextCursor &p_cursor); - - // Go up through the stack. Need to add current location if we are at - // the top of the stack currently. - const Location &previousLocation(const QTextCursor &p_cursor); - - // Go down through the stack. - const Location &nextLocation(); - - bool hasPrevious() const; - - bool hasNext() const; - - private: - // A stack containing locations. - QList m_locations; - - // Pointer to current element in the stack. - // If we are not in the history of the locations, it points to the next - // element to the top element. - int m_pointer; - - // Maximum number of locations in stack. - const int c_maximumLocations; - }; - - enum IndentType { Indent = 0, UnIndent, AutoIndent }; - - // Returns true if the event is consumed and need no more handling. - bool handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos = NULL); - - // Reset all key state info. - void resetState(); - - // Now m_tokens constitute a command. Execute it. - // Will clear @p_tokens. - void processCommand(QList &p_tokens); - - // Return the number represented by @p_keys. - // Return -1 if @p_keys is not a valid digit sequence. - int numberFromKeySequence(const QList &p_keys); - - // Try to generate a Repeat token from @p_keys and insert it to @p_tokens. - // If succeed, clear @p_keys and return true. - bool tryGetRepeatToken(QList &p_keys, QList &p_tokens); - - // @p_tokens is the arguments of the Action::Move action. - void processMoveAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Delete action. - void processDeleteAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Copy action. - void processCopyAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Paste and Action::PasteBefore action. - void processPasteAction(QList &p_tokens, bool p_pasteBefore); - - // @p_tokens is the arguments of the Action::Change action. - void processChangeAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Indent, Action::UnIndent, - // and Action::AutoIndent action. - void processIndentAction(QList &p_tokens, IndentType p_type); - - // @p_tokens is the arguments of the Action::ToLower and Action::ToUpper action. - void processToLowerAction(QList &p_tokens, bool p_toLower); - - // @p_tokens is the arguments of the Action::Undo action. - void processUndoAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::Redo action. - void processRedoAction(QList &p_tokens); - - // @p_tokens is the arguments of the Action::RedrawAtBottom/RedrawAtCenter/RedrawAtTop action. - // @p_dest: 0 for top, 1 for center, 2 for bottom. - void processRedrawLineAction(QList &p_tokens, int p_dest); - - // Action::JumpPreviousLocation and Action::JumpNextLocation action. - void processJumpLocationAction(QList &p_tokens, bool p_next); - - // Action::Replace. - void processReplaceAction(QList &p_tokens); - - // Action::ReverseCase. - void processReverseCaseAction(QList &p_tokens); - - // Action::Join and Action::JoinNoModification action. - // @p_modifySpaces: whether remove the indent and insert up to two spaces. - void processJoinAction(QList &p_tokens, bool p_modifySpaces); - - // Clear selection if there is any. - // Returns true if there is selection. - bool clearSelection(); - - // Get the block count of one page step in vertical scroll bar. - int blockCountOfPageStep() const; - - // Expand selection to whole lines which will change the position - // of @p_cursor. - void expandSelectionToWholeLines(QTextCursor &p_cursor); - - // Init leader key from config. - void initLeaderKey(); - - // Init m_registers. - // Currently supported registers: - // a-z, A-Z (append to a-z), ", +, _ - void initRegisters(); - - // Check m_keys to see if we are expecting a register name. - bool expectingRegisterName() const; - - // Check m_keys to see if we are expecting a target for f/t/F/T command. - bool expectingCharacterTarget() const; - - // Check m_keys to see if we are expecting a character to replace with. - bool expectingReplaceCharacter() const; - - // Check if we are in a leader sequence. - bool expectingLeaderSequence() const; - - // Check m_keys to see if we are expecting a mark name to create a mark. - bool expectingMarkName() const; - - // Check m_keys to see if we are expecting a mark name as the target. - bool expectingMarkTarget() const; - - // Return the corresponding register name of @p_key. - // If @p_key is not a valid register name, return a NULL QChar. - QChar keyToRegisterName(const Key &p_key) const; - - // Check if @m_tokens contains an action token. - bool hasActionToken() const; - - // Check if @m_tokens contains a repeat token. - bool hasRepeatToken() const; - - // Try to add an Action::Move action at the front if there is no any action - // token. - void tryAddMoveAction(); - - // Add an Action token in front of m_tokens. - void addActionToken(Action p_action); - - // Get the action token from m_tokens. - const Token *getActionToken() const; - - // Get the repeat token from m_tokens. - Token *getRepeatToken(); - - // Add a Range token at the end of m_tokens. - void addRangeToken(Range p_range); - - // Add a Movement token at the end of m_tokens. - void addMovementToken(Movement p_movement); - - // Add a Movement token at the end of m_tokens. - void addMovementToken(Movement p_movement, Key p_key); - - // Add a Key token at the end of m_tokens. - void addKeyToken(Key p_key); - - // Delete selected text if there is any. - // @p_clearEmptyBlock: whether to remove the empty block after deletion. - void deleteSelectedText(QTextCursor &p_cursor, bool p_clearEmptyBlock); - - // Copy selected text if there is any. - // Will clear selection. - // @p_addNewLine: whether to add a new line \n to the selection. - void copySelectedText(bool p_addNewLine); - - void copySelectedText(QTextCursor &p_cursor, bool p_addNewLine); - - // Convert the case of selected text if there is any. - // Will clear selection. - // @p_toLower: to lower or upper. - void convertCaseOfSelectedText(QTextCursor &p_cursor, bool p_toLower); - - // Save @p_text to the Register pointed by m_regName. - // Remove QChar::ObjectReplacementCharacter before saving. - void saveToRegister(const QString &p_text); - - // Move @p_cursor according to @p_moveMode and @p_token. - // Return true if it has moved @p_cursor. - bool processMovement(QTextCursor &p_cursor, - QTextCursor::MoveMode p_moveMode, - const Token &p_token, - int p_repeat); - - // Move @p_cursor according to @p_moveMode and @p_range. - // Return true if it has moved @p_cursor. - bool selectRange(QTextCursor &p_cursor, const QTextDocument *p_doc, - Range p_range, int p_repeat); - - // Check if there is an Action token with Delete/Copy/Change action. - bool hasActionTokenValidForTextObject() const; - - // Check if m_keys only contains @p_key. - bool checkPendingKey(const Key &p_key) const; - - // Check if m_tokens only contains action token @p_action. - bool checkActionToken(Action p_action) const; - - // Repeat m_lastFindToken. - void repeatLastFindMovement(bool p_reverse); - - void message(const QString &p_str); - - // Check if m_mode equals to p_mode. - bool checkMode(VimMode p_mode); - - // Execute command specified by @p_cmd. - // @p_cmd does not contain the leading colon. - // Returns true if it is a valid command. - // Following commands are supported: - // w, wq, q, q!, x, - bool executeCommand(const QString &p_cmd); - - // Check if m_keys has non-digit key. - bool hasNonDigitPendingKeys(); - - bool hasNonDigitPendingKeys(const QList &p_keys); - - // Reading a leader sequence, read input @p_key and process it. - // Returns true if a sequence has been replayed or it is being read, - // otherwise returns false. - // Following sequences are supported: - // y: "+y - // d: "+d - // p: "+p - // P: "+P - bool processLeaderSequence(const Key &p_key); - - // Jump across titles. - // [[, ]], [], ][, [{, ]}. - void processTitleJump(const QList &p_tokens, bool p_forward, int p_relativeLevel); - - // Clear search highlight. - void clearSearchHighlight(); - - // Function utils for register. - Register &getRegister(QChar p_regName) const; - void setRegister(QChar p_regName, const QString &p_val); - - // May need to do these things: - // 1. Change the CursorBlock mode; - // 2. Alter the selection to assure the character in m_positionBeforeVisualMode - // is always selected. - void maintainSelectionInVisualMode(QTextCursor *p_cursor = NULL); - - void setCursorBlockMode(VEditor *p_cursor, CursorBlock p_mode); - - // Whether we should consider the left or right side of the cursor. - bool useLeftSideOfCursor(const QTextCursor &p_cursor); - - bool checkEnterNormalMode(int p_key, int p_modifiers); - - void clearSelectionAndEnterNormalMode(); - - bool isKeyShouldBeIgnored(int p_key) const; - - VEditor *m_editor; - const VEditConfig *m_editConfig; - VimMode m_mode; - - // A valid command token should follow the rule: - // Action, Repeat, Movement. - // Action, Repeat, Range. - // Action, Repeat. - QList m_keys; - QList m_tokens; - - // Keys for status indication. - QList m_pendingKeys; - - // Whether reset the position in block when moving cursor. - bool m_resetPositionInBlock; - - // Currently used register. - QChar m_regName; - - // Last f/F/t/T Token. - Token m_lastFindToken; - - // The leader key, which is Key_Space by default. - Key m_leaderKey; - - // Whether we are parsing a leader sequence. - // We will map a leader sequence to another actual sequence. When replaying - // this actual sequence, m_leaderSequence will be true. - bool m_replayLeaderSequence; - - LocationStack m_locations; - - Marks m_marks; - - // Search history. - SearchHistory m_searchHistory; - - // Whether we are expecting to read a register to insert. - bool m_registerPending; - - // Whether enter insert mode after a command. - bool m_insertModeAfterCommand; - - // Cursor position when entering Visual mode. - // After displaying cursor as block, we need to always select current character - // when entering Visual mode. - int m_positionBeforeVisualMode; - - static const QChar c_unnamedRegister; - static const QChar c_blackHoleRegister; - static const QChar c_selectionRegister; - - static QMap s_registers; -}; - -inline VVim::Register &VVim::getRegister(QChar p_regName) const -{ - return s_registers[p_regName]; -} - -inline void VVim::setRegister(QChar p_regName, const QString &p_val) -{ - s_registers[p_regName].update(p_val); -} -#endif // VVIM_H diff --git a/src/utils/vwebutils.cpp b/src/utils/vwebutils.cpp deleted file mode 100644 index 5c559654..00000000 --- a/src/utils/vwebutils.cpp +++ /dev/null @@ -1,978 +0,0 @@ -#include "vwebutils.h" - -#include -#include -#include -#include -#include -#include - -#include "vpalette.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vdownloader.h" - -extern VPalette *g_palette; - -extern VConfigManager *g_config; - -VWebUtils::VWebUtils() -{ -} - -void VWebUtils::init() -{ - m_stylesToRemoveWhenCopied = g_config->getStylesToRemoveWhenCopied(); - - m_styleOfSpanForMark = g_config->getStyleOfSpanForMark(); - - m_tagReg = QRegExp("<([^>/\\s]+)([^>]*)>"); - - m_styleTagReg = QRegExp("<([^>\\s]+)([^>]*\\s)style=\"([^\">]+)\"([^>]*)>"); - - m_imgTagReg = QRegExp("]*>"); - - initCopyTargets(g_config->getCopyTargets()); -} - -void VWebUtils::initCopyTargets(const QStringList &p_str) -{ - Q_ASSERT(m_copyTargets.isEmpty()); - // cap(1): action; - // cap(3): arguments; - QRegExp actReg("([0-9a-zA-Z])(\\(([^\\)]*)\\))?"); - - for (auto const & str : p_str) { - auto vals = str.split('$'); - if (vals.size() != 2) { - continue; - } - - CopyTarget tar; - tar.m_name = vals[0]; - if (tar.m_name.isEmpty()) { - continue; - } - - auto acts = vals[1].split(':'); - for (auto const & it : acts) { - if (it.isEmpty()) { - continue; - } - - if (!actReg.exactMatch(it)) { - continue; - } - - if (actReg.cap(1).size() != 1) { - continue; - } - - CopyTargetAction act; - act.m_act = actReg.cap(1)[0]; - - if (!actReg.cap(3).isEmpty()) { - act.m_args = actReg.cap(3).toLower().split('|'); - } - - tar.m_actions.append(act); - } - - m_copyTargets.append(tar); - } - - qDebug() << "init" << m_copyTargets.size() << "copy targets"; -} - -bool VWebUtils::fixImageSrc(const QUrl &p_baseUrl, QString &p_html) -{ - bool changed = false; - -#if defined(Q_OS_WIN) - QUrl::ComponentFormattingOption strOpt = QUrl::EncodeSpaces; -#else - QUrl::ComponentFormattingOption strOpt = QUrl::FullyEncoded; -#endif - - QRegExp reg("(this)->alterHtmlByTargetAction(p_baseUrl, p_html, act)) { - altered = true; - } - } - - return altered; -} - -int VWebUtils::targetIndex(const QString &p_target) const -{ - if (p_target.isEmpty()) { - return -1; - } - - for (int i = 0; i < m_copyTargets.size(); ++i) { - if (m_copyTargets[i].m_name == p_target) { - return i; - } - } - - return -1; -} - -bool VWebUtils::alterHtmlByTargetAction(const QUrl &p_baseUrl, QString &p_html, const CopyTargetAction &p_action) -{ - bool altered = false; - switch (p_action.m_act.toLatin1()) { - case 's': - if (!p_html.startsWith("")) { - p_html = "" + p_html + ""; - altered = true; - } - - break; - - case 'e': - if (!p_html.startsWith("")) { - p_html = "" + p_html + ""; - altered = true; - } - - break; - - case 'b': - altered = removeBackgroundColor(p_html, p_action.m_args); - break; - - case 'c': - altered = translateColors(p_html, p_action.m_args); - break; - - case 'i': - altered = fixImageSrc(p_baseUrl, p_html); - break; - - case 'm': - altered = removeMarginPadding(p_html, p_action.m_args); - break; - - case 'x': - altered = removeStylesToRemoveWhenCopied(p_html, p_action.m_args); - break; - - case 'r': - altered = removeAllStyles(p_html, p_action.m_args); - break; - - case 'a': - altered = transformMarkToSpan(p_html); - break; - - case 'p': - altered = replacePreBackgroundColorWithCode(p_html); - break; - - case 'n': - altered = replaceNewLineWithBR(p_html); - break; - - case 'g': - altered = replaceLocalImgWithWarningLabel(p_html); - break; - - case 'd': - altered = addSpanInsideCode(p_html); - break; - - case 'f': - altered = replaceQuoteInFontFamily(p_html); - break; - - case 'h': - altered = replaceHeadingWithSpan(p_html); - break; - - case 'j': - altered = fixXHtmlTags(p_html); - break; - - default: - break; - } - - return altered; -} - -static int skipToTagEnd(const QString &p_html, - int p_pos, - const QString &p_tag, - int *p_endTagIdx = NULL) -{ - QRegExp beginReg(QString("<%1 ").arg(p_tag)); - QRegExp endReg(QString("").arg(p_tag)); - - int pos = p_pos; - int nBegin = p_html.indexOf(beginReg, pos); - int nEnd = p_html.indexOf(endReg, pos); - if (nBegin > -1 && nBegin < nEnd) { - // Nested tag. - pos = skipToTagEnd(p_html, nBegin + beginReg.matchedLength(), p_tag); - nEnd = p_html.indexOf(endReg, pos); - } - - if (nEnd > -1) { - if (p_endTagIdx) { - *p_endTagIdx = nEnd; - } - - pos = nEnd + endReg.matchedLength(); - } else if (p_endTagIdx) { - *p_endTagIdx = -1; - } - - return pos; -} - -// @p_html is the style string. -static bool removeStylesInStyleString(QString &p_html, const QStringList &p_styles) -{ - if (p_styles.isEmpty()) { - return false; - } - - int size = p_html.size(); - QRegExp reg(QString("(\\s|^)(%1):[^:]+;").arg(p_styles.join('|'))); - p_html.remove(reg); - - return size != p_html.size(); -} - -bool VWebUtils::removeBackgroundColor(QString &p_html, const QStringList &p_skipTags) -{ - QStringList styles({"background", "background-color"}); - - return removeStyles(p_html, p_skipTags, styles); -} - -bool VWebUtils::translateColors(QString &p_html, const QStringList &p_skipTags) -{ - bool changed = false; - - const QHash &mapping = g_palette->getColorMapping(); - if (mapping.isEmpty()) { - return changed; - } - - // Won't mixed up with background-color. - QRegExp colorReg("(\\s|^)color:([^;]+);"); - - int pos = 0; - while (pos < p_html.size()) { - int tagIdx = p_html.indexOf(m_tagReg, pos); - if (tagIdx == -1) { - break; - } - - QString tagName = m_tagReg.cap(1); - if (p_skipTags.contains(tagName.toLower())) { - // Skip this tag. - pos = skipToTagEnd(p_html, tagIdx + m_tagReg.matchedLength(), tagName); - continue; - } - - pos = tagIdx; - int idx = p_html.indexOf(m_styleTagReg, pos); - if (idx == -1) { - break; - } else if (idx != tagIdx) { - pos = tagIdx + m_tagReg.matchedLength(); - continue; - } - - QString styleStr = m_styleTagReg.cap(3); - QString alteredStyleStr = styleStr; - int posb = 0; - while (posb < alteredStyleStr.size()) { - int idxb = alteredStyleStr.indexOf(colorReg, posb); - if (idxb == -1) { - break; - } - - QString col = colorReg.cap(2).trimmed().toLower(); - auto it = mapping.find(col); - if (it == mapping.end()) { - posb = idxb + colorReg.matchedLength(); - continue; - } - - // Replace the color. - QString newCol = it.value(); - // Should not add extra space before :. - QString newStr = QString("%1color: %2;").arg(colorReg.cap(1)).arg(newCol); - alteredStyleStr.replace(idxb, colorReg.matchedLength(), newStr); - posb = idxb + newStr.size(); - changed = true; - } - - if (changed) { - QString newTag = QString("<%1%2style=\"%3\"%4>").arg(m_styleTagReg.cap(1)) - .arg(m_styleTagReg.cap(2)) - .arg(alteredStyleStr) - .arg(m_styleTagReg.cap(4)); - - p_html.replace(idx, m_styleTagReg.matchedLength(), newTag); - - pos = idx + newTag.size(); - } else { - pos = idx + m_styleTagReg.matchedLength(); - } - } - - return changed; -} - -bool VWebUtils::removeMarginPadding(QString &p_html, const QStringList &p_skipTags) -{ - QStringList styles({"margin", "margin-left", "margin-right", - "padding", "padding-left", "padding-right"}); - - return removeStyles(p_html, p_skipTags, styles); -} - -bool VWebUtils::removeStyles(QString &p_html, const QStringList &p_skipTags, const QStringList &p_styles) -{ - if (p_styles.isEmpty()) { - return false; - } - - bool altered = false; - int pos = 0; - - while (pos < p_html.size()) { - int tagIdx = p_html.indexOf(m_tagReg, pos); - if (tagIdx == -1) { - break; - } - - QString tagName = m_tagReg.cap(1); - if (p_skipTags.contains(tagName.toLower())) { - // Skip this tag. - pos = skipToTagEnd(p_html, tagIdx + m_tagReg.matchedLength(), tagName); - continue; - } - - pos = tagIdx; - int idx = p_html.indexOf(m_styleTagReg, pos); - if (idx == -1) { - break; - } else if (idx != tagIdx) { - pos = tagIdx + m_tagReg.matchedLength(); - continue; - } - - QString styleStr = m_styleTagReg.cap(3); - if (removeStylesInStyleString(styleStr, p_styles)) { - QString newTag = QString("<%1%2style=\"%3\"%4>").arg(m_styleTagReg.cap(1)) - .arg(m_styleTagReg.cap(2)) - .arg(styleStr) - .arg(m_styleTagReg.cap(4)); - p_html.replace(idx, m_styleTagReg.matchedLength(), newTag); - - pos = idx + newTag.size(); - - altered = true; - } else { - pos = idx + m_styleTagReg.matchedLength(); - } - } - - return altered; -} - -bool VWebUtils::removeStylesToRemoveWhenCopied(QString &p_html, const QStringList &p_skipTags) -{ - return removeStyles(p_html, p_skipTags, m_stylesToRemoveWhenCopied); -} - -bool VWebUtils::removeAllStyles(QString &p_html, const QStringList &p_skipTags) -{ - bool altered = false; - int pos = 0; - - while (pos < p_html.size()) { - int tagIdx = p_html.indexOf(m_tagReg, pos); - if (tagIdx == -1) { - break; - } - - QString tagName = m_tagReg.cap(1); - if (p_skipTags.contains(tagName.toLower())) { - // Skip this tag. - pos = skipToTagEnd(p_html, tagIdx + m_tagReg.matchedLength(), tagName); - continue; - } - - pos = tagIdx; - int idx = p_html.indexOf(m_styleTagReg, pos); - if (idx == -1) { - break; - } else if (idx != tagIdx) { - pos = tagIdx + m_tagReg.matchedLength(); - continue; - } - - QString newTag = QString("<%1%2%3>").arg(m_styleTagReg.cap(1)) - .arg(m_styleTagReg.cap(2)) - .arg(m_styleTagReg.cap(4)); - p_html.replace(idx, m_styleTagReg.matchedLength(), newTag); - - pos = idx + newTag.size(); - - altered = true; - } - - return altered; -} - -bool VWebUtils::transformMarkToSpan(QString &p_html) -{ - bool altered = false; - int pos = 0; - - while (pos < p_html.size()) { - int tagIdx = p_html.indexOf(m_tagReg, pos); - if (tagIdx == -1) { - break; - } - - QString tagName = m_tagReg.cap(1); - if (tagName.toLower() != "mark") { - pos = tagIdx + m_tagReg.matchedLength(); - continue; - } - - pos = tagIdx; - int idx = p_html.indexOf(m_styleTagReg, pos); - if (idx == -1 || idx != tagIdx) { - // without "style". - QString newTag = QString("").arg(m_styleOfSpanForMark) - .arg(m_tagReg.cap(2)); - p_html.replace(tagIdx, m_tagReg.matchedLength(), newTag); - - pos = tagIdx + newTag.size(); - - altered = true; - continue; - } - - QString newTag = QString("").arg(m_styleTagReg.cap(2)) - .arg(m_styleTagReg.cap(3) + m_styleOfSpanForMark) - .arg(m_styleTagReg.cap(4)); - p_html.replace(idx, m_styleTagReg.matchedLength(), newTag); - - pos = idx + newTag.size(); - - altered = true; - } - - if (altered) { - // Replace all with . - p_html.replace("", ""); - } - - return altered; -} - -bool VWebUtils::replacePreBackgroundColorWithCode(QString &p_html) -{ - if (p_html.isEmpty()) { - return false; - } - - bool altered = false; - int pos = 0; - - QRegExp bgReg("(\\s|^)(background(-color)?:[^;]+;)"); - - while (pos < p_html.size()) { - int tagIdx = p_html.indexOf(m_tagReg, pos); - if (tagIdx == -1) { - break; - } - - QString tagName = m_tagReg.cap(1); - pos = tagIdx + m_tagReg.matchedLength(); - if (tagName.toLower() != "pre") { - continue; - } - - int preEnd = skipToTagEnd(p_html, pos, tagName); - - HtmlTag nextTag = readNextTag(p_html, pos); - if (nextTag.m_name != "code" - || nextTag.m_start >= preEnd - || nextTag.m_style.isEmpty()) { - continue; - } - - // Get the background style of . - int idx = nextTag.m_style.indexOf(bgReg); - if (idx == -1) { - continue; - } - - QString bgStyle = bgReg.cap(2); - - pos = tagIdx; - idx = p_html.indexOf(m_styleTagReg, pos); - if (idx == -1 || idx != tagIdx) { - //
     without "style".
    -            QString newTag = QString("<%1 style=\"%2\" %3>").arg(m_tagReg.cap(1))
    -                                                            .arg(bgStyle)
    -                                                            .arg(m_tagReg.cap(2));
    -            p_html.replace(tagIdx, m_tagReg.matchedLength(), newTag);
    -
    -            pos = tagIdx + newTag.size();
    -
    -            altered = true;
    -            continue;
    -        }
    -
    -        QString newTag;
    -        if (m_styleTagReg.cap(3).indexOf(bgReg) == -1) {
    -            // No background style specified.
    -            newTag = QString("<%1%2style=\"%3\"%4>").arg(m_styleTagReg.cap(1))
    -                                                    .arg(m_styleTagReg.cap(2))
    -                                                    .arg(m_styleTagReg.cap(3) + bgStyle)
    -                                                    .arg(m_styleTagReg.cap(4));
    -        } else {
    -            // Replace background style.
    -            newTag = QString("<%1%2style=\"%3\"%4>").arg(m_styleTagReg.cap(1))
    -                                                    .arg(m_styleTagReg.cap(2))
    -                                                    .arg(m_styleTagReg.cap(3).replace(bgReg, " " + bgStyle))
    -                                                    .arg(m_styleTagReg.cap(4));
    -        }
    -
    -        p_html.replace(idx, m_styleTagReg.matchedLength(), newTag);
    -
    -        pos = idx + newTag.size();
    -
    -        altered = true;
    -    }
    -
    -    return altered;
    -}
    -
    -VWebUtils::HtmlTag VWebUtils::readNextTag(const QString &p_html, int p_pos)
    -{
    -    HtmlTag tag;
    -
    -    int tagIdx = p_html.indexOf(m_tagReg, p_pos);
    -    if (tagIdx == -1) {
    -        return tag;
    -    }
    -
    -    tag.m_name = m_tagReg.cap(1);
    -    tag.m_start = tagIdx;
    -    tag.m_end = skipToTagEnd(p_html, tagIdx + m_tagReg.matchedLength(), tag.m_name);
    -
    -    int idx = p_html.indexOf(m_styleTagReg, tagIdx);
    -    if (idx == -1 || idx != tagIdx) {
    -        return tag;
    -    }
    -
    -    tag.m_style = m_styleTagReg.cap(3);
    -    return tag;
    -}
    -
    -bool VWebUtils::replaceNewLineWithBR(QString &p_html)
    -{
    -    if (p_html.isEmpty()) {
    -        return false;
    -    }
    -
    -    bool altered = false;
    -    int pos = 0;
    -    const QString brTag("
    "); - - while (pos < p_html.size()) { - int tagIdx = p_html.indexOf(m_tagReg, pos); - if (tagIdx == -1) { - break; - } - - QString tagName = m_tagReg.cap(1); - pos = tagIdx + m_tagReg.matchedLength(); - if (tagName.toLower() != "pre") { - continue; - } - - int preEnd = skipToTagEnd(p_html, pos, tagName); - - // Replace '\n' in [pos, preEnd). - while (pos < preEnd) { - int idx = p_html.indexOf('\n', pos); - if (idx == -1 || idx >= preEnd) { - break; - } - - p_html.replace(idx, 1, brTag); - pos = idx + brTag.size() - 1; - preEnd = preEnd + brTag.size() - 1; - - altered = true; - } - - pos = preEnd; - } - - return altered; -} - -bool VWebUtils::replaceLocalImgWithWarningLabel(QString &p_html) -{ - bool altered = false; - - QString label = QString("%1") - .arg(QObject::tr("Insert_Image_HERE")); - - int pos = 0; - while (pos < p_html.size()) { - int idx = p_html.indexOf(m_imgTagReg, pos); - if (idx == -1) { - break; - } - - QString urlStr = m_imgTagReg.cap(1); - QUrl imgUrl(urlStr); - - if (imgUrl.scheme() == "https" || imgUrl.scheme() == "http") { - pos = idx + m_imgTagReg.matchedLength(); - continue; - } - - p_html.replace(idx, m_imgTagReg.matchedLength(), label); - pos = idx + label.size(); - - altered = true; - } - - return altered; -} - -bool VWebUtils::addSpanInsideCode(QString &p_html) -{ - bool altered = false; - int pos = 0; - - while (pos < p_html.size()) { - int tagIdx = p_html.indexOf(m_tagReg, pos); - if (tagIdx == -1) { - break; - } - - QString tagName = m_tagReg.cap(1); - QString lowerName = tagName.toLower(); - if (lowerName == "pre") { - // Skip
    .
    -            pos = skipToTagEnd(p_html, tagIdx + m_tagReg.matchedLength(), tagName);
    -            continue;
    -        }
    -
    -        if (lowerName != "code") {
    -            pos = tagIdx + m_tagReg.matchedLength();
    -            continue;
    -        }
    -
    -        int idx = tagIdx + m_tagReg.matchedLength() - 1;
    -        Q_ASSERT(p_html[idx] == '>');
    -        QString span = QString(">").arg(m_tagReg.cap(2));
    -        p_html.replace(idx, 1, span);
    -
    -        int codeEnd = skipToTagEnd(p_html, idx + span.size(), tagName, &idx);
    -        Q_ASSERT(idx > -1);
    -        Q_ASSERT(codeEnd - idx == 7);
    -        Q_ASSERT(p_html[idx] == '<');
    -        p_html.replace(idx, 1, "<");
    -
    -        pos = codeEnd;
    -
    -        altered = true;
    -    }
    -
    -    return altered;
    -}
    -
    -// @p_html is the style string.
    -static bool replaceQuoteInFontFamilyInStyleString(QString &p_html)
    -{
    -    QRegExp reg("font-family:((")|[^;])+;");
    -    int idx = p_html.indexOf(reg);
    -    if (idx == -1) {
    -        return false;
    -    }
    -
    -    QString quote(""");
    -    QString family = reg.cap(0);
    -    if (family.indexOf(quote) == -1) {
    -        return false;
    -    }
    -
    -    QString newFamily = family.replace(quote, "'");
    -    p_html.replace(idx, reg.matchedLength(), newFamily);
    -    return true;
    -}
    -
    -bool VWebUtils::replaceQuoteInFontFamily(QString &p_html)
    -{
    -    bool altered = false;
    -    int pos = 0;
    -
    -    while (pos < p_html.size()) {
    -        int idx = p_html.indexOf(m_styleTagReg, pos);
    -        if (idx == -1) {
    -            break;
    -        }
    -
    -        QString styleStr = m_styleTagReg.cap(3);
    -        if (replaceQuoteInFontFamilyInStyleString(styleStr)) {
    -            QString newTag = QString("<%1%2style=\"%3\"%4>").arg(m_styleTagReg.cap(1))
    -                                                            .arg(m_styleTagReg.cap(2))
    -                                                            .arg(styleStr)
    -                                                            .arg(m_styleTagReg.cap(4));
    -            p_html.replace(idx, m_styleTagReg.matchedLength(), newTag);
    -
    -            pos = idx + newTag.size();
    -
    -            altered = true;
    -        } else {
    -            pos = idx + m_styleTagReg.matchedLength();
    -        }
    -    }
    -
    -    return altered;
    -}
    -
    -static bool isHeadingTag(const QString &p_tagName)
    -{
    -    QString tag = p_tagName.toLower();
    -    if (!tag.startsWith('h') || tag.size() != 2) {
    -        return false;
    -    }
    -
    -    return tag == "h1"
    -           || tag == "h2"
    -           || tag == "h3"
    -           || tag == "h4"
    -           || tag == "h5"
    -           || tag == "h6";
    -}
    -
    -bool VWebUtils::replaceHeadingWithSpan(QString &p_html)
    -{
    -    bool altered = false;
    -    int pos = 0;
    -    QString spanTag("span");
    -
    -    while (pos < p_html.size()) {
    -        int tagIdx = p_html.indexOf(m_tagReg, pos);
    -        if (tagIdx == -1) {
    -            break;
    -        }
    -
    -        QString tagName = m_tagReg.cap(1);
    -        if (!isHeadingTag(tagName)) {
    -            pos = tagIdx + m_tagReg.matchedLength();
    -            continue;
    -        }
    -
    -        p_html.replace(tagIdx + 1, 2, spanTag);
    -
    -        pos = tagIdx + m_tagReg.matchedLength() + spanTag.size() - 2;
    -
    -        pos = skipToTagEnd(p_html, pos, tagName);
    -
    -        Q_ASSERT(pos != -1);
    -
    -        Q_ASSERT(p_html.mid(pos - 3, 2) == tagName);
    -
    -        p_html.replace(pos - 3, 2, spanTag);
    -
    -        pos = pos + spanTag.size() - 2;
    -
    -        altered = true;
    -    }
    -
    -    return altered;
    -}
    -
    -bool VWebUtils::fixXHtmlTags(QString &p_html)
    -{
    -    bool altered = false;
    -
    -    // .
    -    int pos = 0;
    -    const QString legalTag("/>");
    -    while (pos < p_html.size()) {
    -        int idx = p_html.indexOf(m_imgTagReg, pos);
    -        if (idx == -1) {
    -            break;
    -        }
    -
    -        pos = idx + m_imgTagReg.matchedLength();
    -
    -        Q_ASSERT(p_html[pos - 1] == '>');
    -
    -        if (p_html.mid(pos - 2, 2) == legalTag) {
    -            continue;
    -        }
    -
    -        p_html.replace(pos - 1, 1, legalTag);
    -        pos = pos + legalTag.size() - 1;
    -
    -        altered = true;
    -    }
    -
    -    // 
    . - int size = p_html.size(); - p_html.replace("
    ", "
    "); - if (!altered && size != p_html.size()) { - altered = true; - } - - return altered; -} - -QString VWebUtils::copyResource(const QUrl &p_url, const QString &p_folder) const -{ - Q_ASSERT(!p_url.isRelative()); - - QDir dir(p_folder); - if (!dir.exists()) { - VUtils::makePath(p_folder); - } - - QString file = p_url.isLocalFile() ? p_url.toLocalFile() : p_url.toString(); - QString fileName = VUtils::fileNameFromPath(file); - fileName = VUtils::getFileNameWithSequence(p_folder, fileName, true); - QString targetFile = dir.absoluteFilePath(fileName); - - bool succ = false; - if (p_url.scheme() == "https" || p_url.scheme() == "http") { - // Download it. - QByteArray data = VDownloader::downloadSync(p_url); - if (!data.isEmpty()) { - succ = VUtils::writeFileToDisk(targetFile, data); - } - } else if (QFileInfo::exists(file)) { - // Do a copy. - succ = VUtils::copyFile(file, targetFile, false); - } - - return succ ? targetFile : QString(); -} - -// Please use single quote to quote the URI. -QString VWebUtils::dataURI(const QUrl &p_url, bool p_keepTitle) const -{ - QString uri; - Q_ASSERT(!p_url.isRelative()); - QString file = p_url.isLocalFile() ? p_url.toLocalFile() : p_url.toString(); - QString suffix(QFileInfo(VUtils::purifyUrl(file)).suffix().toLower()); - - if (!QImageReader::supportedImageFormats().contains(suffix.toLatin1())) { - return uri; - } - - QByteArray data; - if (p_url.scheme() == "https" || p_url.scheme() == "http") { - // Download it. - data = VDownloader::downloadSync(p_url); - } else if (QFileInfo::exists(file)) { - QFile fi(file); - if (fi.open(QIODevice::ReadOnly)) { - data = fi.readAll(); - fi.close(); - } - } - - if (data.isEmpty()) { - return uri; - } - - if (suffix == "svg") { - uri = QString("data:image/svg+xml;utf8,%1").arg(QString::fromUtf8(data)); - uri.replace('\r', "").replace('\n', ""); - - // Using unescaped '#' characters in a data URI body is deprecated and - // will be removed in M68, around July 2018. Please use '%23' instead. - uri.replace("#", "%23"); - - // Escape "'" to avoid conflict with src='...' attribute. - uri.replace("'", "%27"); - - if (!p_keepTitle) { - // Remove .... - QRegExp reg(".*", Qt::CaseInsensitive); - uri.remove(reg); - } - } else { - uri = QString("data:image/%1;base64,%2").arg(suffix).arg(QString::fromUtf8(data.toBase64())); - } - - return uri; -} diff --git a/src/utils/vwebutils.h b/src/utils/vwebutils.h deleted file mode 100644 index 4ee9465a..00000000 --- a/src/utils/vwebutils.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef VWEBUTILS_H -#define VWEBUTILS_H - -#include -#include -#include -#include -#include - - -class VWebUtils -{ -public: - VWebUtils(); - - void init(); - - QStringList getCopyTargetsName() const; - - // Alter @p_html using @p_target. - // Returns true if @p_html is modified. - bool alterHtmlAsTarget(const QUrl &p_baseUrl, QString &p_html, const QString &p_target) const; - - // Download or copy @p_url to @p_folder. - // Return the target file path on success or empty string on failure. - QString copyResource(const QUrl &p_url, const QString &p_folder) const; - - // Return a dataURI of @p_url if it is an image. - // Please use single quote to quote the URI. - QString dataURI(const QUrl &p_url, bool p_keepTitle = true) const; - -private: - struct CopyTargetAction - { - QChar m_act; - - QStringList m_args; - }; - - struct CopyTarget - { - QString m_name; - - QVector m_actions; - }; - - struct HtmlTag - { - HtmlTag() - : m_start(-1), m_end(-1) - { - - } - - bool isNull() - { - return m_name.isEmpty(); - } - - QString m_name; - QString m_style; - - int m_start; - int m_end; - }; - - void initCopyTargets(const QStringList &p_str); - - // Return the index in m_copyTargets of @p_target. - int targetIndex(const QString &p_target) const; - - bool alterHtmlByTargetAction(const QUrl &p_baseUrl, QString &p_html, const CopyTargetAction &p_action); - - // Remove background color style in @p_html of all tags except @p_skipTags. - bool removeBackgroundColor(QString &p_html, const QStringList &p_skipTags); - - // Translate color styles in @p_html using mappings from VPalette. - bool translateColors(QString &p_html, const QStringList &p_skipTags); - - // Fix in @p_html. - bool fixImageSrc(const QUrl &p_baseUrl, QString &p_html); - - // Remove margin/padding/margin-left/right/padding-left/right. - bool removeMarginPadding(QString &p_html, const QStringList &p_skipTags); - - bool removeStyles(QString &p_html, const QStringList &p_skipTags, const QStringList &p_styles); - - // Remove styles specified in [web]/styles_to_remove_when_copied. - bool removeStylesToRemoveWhenCopied(QString &p_html, const QStringList &p_skipTags); - - // Remove all styles. - bool removeAllStyles(QString &p_html, const QStringList &p_skipTags); - - // Transform to . - bool transformMarkToSpan(QString &p_html); - - // Replace the background color of
     with that of its child .
    -    bool replacePreBackgroundColorWithCode(QString &p_html);
    -
    -    VWebUtils::HtmlTag readNextTag(const QString &p_html, int p_pos);
    -
    -    // Replace \n with 
    in
    .
    -    bool replaceNewLineWithBR(QString &p_html);
    -
    -    // Replace local absolute/relative  tag with a warning label.
    -    bool replaceLocalImgWithWarningLabel(QString &p_html);
    -
    -    // Add  inside  not in 
    .
    -    bool addSpanInsideCode(QString &p_html);
    -
    -    // Replace " in font-family with '.
    -    bool replaceQuoteInFontFamily(QString &p_html);
    -
    -    // Replace headings with span.
    -    bool replaceHeadingWithSpan(QString &p_html);
    -
    -    // Fix tags as XHTML like  and 
    . - bool fixXHtmlTags(QString &p_html); - - QVector m_copyTargets; - - // Custom styles to remove when copied. - QStringList m_stylesToRemoveWhenCopied; - - // Style of which is transformed from . - QString m_styleOfSpanForMark; - - // Html start tag. - // Captured texts: - // 1. The tag name like 'code'; - // 2. Text after tag name and before the end '>'; - QRegExp m_tagReg; - - // Html start tag with "style" defined. - // Captured texts: - // 1. The tag name like 'code'; - // 2. Text before 'style=""'; - // 3. Text inside 'style=""'; - // 4. Text after 'style=""' and before '>'; - QRegExp m_styleTagReg; - - // tag. - // Captured texts: - // 1. Src string without "; - QRegExp m_imgTagReg; -}; -#endif // VWEBUTILS_H diff --git a/src/utils/wavedrom/README.md b/src/utils/wavedrom/README.md deleted file mode 100644 index 03838eb2..00000000 --- a/src/utils/wavedrom/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# [WaveDrom](https://github.com/wavedrom/wavedrom) -v1.6.2 \ No newline at end of file diff --git a/src/utils/wavedrom/wavedrom-theme.js b/src/utils/wavedrom/wavedrom-theme.js deleted file mode 100644 index c6a2ca07..00000000 --- a/src/utils/wavedrom/wavedrom-theme.js +++ /dev/null @@ -1 +0,0 @@ -var WaveSkin=WaveSkin||{};WaveSkin.default=["svg",{"id":"svg","xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","height":"0"},["style",{"type":"text/css"},"text{font-size:11pt;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;fill-opacity:1;font-family:Helvetica}.muted{fill:#aaa}.warning{fill:#f6b900}.error{fill:#f60000}.info{fill:#0041c4}.success{fill:#00ab00}.h1{font-size:33pt;font-weight:bold}.h2{font-size:27pt;font-weight:bold}.h3{font-size:20pt;font-weight:bold}.h4{font-size:14pt;font-weight:bold}.h5{font-size:11pt;font-weight:bold}.h6{font-size:8pt;font-weight:bold}.s1{fill:none;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none}.s2{fill:none;stroke:#000;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none}.s3{color:#000;fill:none;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 3;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s4{color:#000;fill:none;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible}.s5{fill:#fff;stroke:none}.s6{color:#000;fill:#ffffb4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s7{color:#000;fill:#ffe0b9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s8{color:#000;fill:#b9e0ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s9{fill:#000;fill-opacity:1;stroke:none}.s10{color:#000;fill:#fff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}.s11{fill:#0041c4;fill-opacity:1;stroke:none}.s12{fill:none;stroke:#0041c4;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none}"],["defs",["g",{"id":"socket"},["rect",{"y":"15","x":"6","height":"20","width":"20"}]],["g",{"id":"pclk"},["path",{"d":"M0,20 0,0 20,0","class":"s1"}]],["g",{"id":"nclk"},["path",{"d":"m0,0 0,20 20,0","class":"s1"}]],["g",{"id":"000"},["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"0m0"},["path",{"d":"m0,20 3,0 3,-10 3,10 11,0","class":"s1"}]],["g",{"id":"0m1"},["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"0mx"},["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m20,15 -5,5","class":"s2"}],["path",{"d":"M20,10 10,20","class":"s2"}],["path",{"d":"M20,5 5,20","class":"s2"}],["path",{"d":"M20,0 4,16","class":"s2"}],["path",{"d":"M15,0 6,9","class":"s2"}],["path",{"d":"M10,0 9,1","class":"s2"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"0md"},["path",{"d":"m8,20 10,0","class":"s3"}],["path",{"d":"m0,20 5,0","class":"s1"}]],["g",{"id":"0mu"},["path",{"d":"m0,20 3,0 C 7,10 10.107603,0 20,0","class":"s1"}]],["g",{"id":"0mz"},["path",{"d":"m0,20 3,0 C 10,10 15,10 20,10","class":"s1"}]],["g",{"id":"111"},["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"1m0"},["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}]],["g",{"id":"1m1"},["path",{"d":"M0,0 3,0 6,10 9,0 20,0","class":"s1"}]],["g",{"id":"1mx"},["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"m20,15 -5,5","class":"s2"}],["path",{"d":"M20,10 10,20","class":"s2"}],["path",{"d":"M20,5 8,17","class":"s2"}],["path",{"d":"M20,0 7,13","class":"s2"}],["path",{"d":"M15,0 6,9","class":"s2"}],["path",{"d":"M10,0 5,5","class":"s2"}],["path",{"d":"M3.5,1.5 5,0","class":"s2"}]],["g",{"id":"1md"},["path",{"d":"m0,0 3,0 c 4,10 7,20 17,20","class":"s1"}]],["g",{"id":"1mu"},["path",{"d":"M0,0 5,0","class":"s1"}],["path",{"d":"M8,0 18,0","class":"s3"}]],["g",{"id":"1mz"},["path",{"d":"m0,0 3,0 c 7,10 12,10 17,10","class":"s1"}]],["g",{"id":"xxx"},["path",{"d":"m0,20 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"M0,5 5,0","class":"s2"}],["path",{"d":"M0,10 10,0","class":"s2"}],["path",{"d":"M0,15 15,0","class":"s2"}],["path",{"d":"M0,20 20,0","class":"s2"}],["path",{"d":"M5,20 20,5","class":"s2"}],["path",{"d":"M10,20 20,10","class":"s2"}],["path",{"d":"m15,20 5,-5","class":"s2"}]],["g",{"id":"xm0"},["path",{"d":"M0,0 4,0 9,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}],["path",{"d":"M0,5 4,1","class":"s2"}],["path",{"d":"M0,10 5,5","class":"s2"}],["path",{"d":"M0,15 6,9","class":"s2"}],["path",{"d":"M0,20 7,13","class":"s2"}],["path",{"d":"M5,20 8,17","class":"s2"}]],["g",{"id":"xm1"},["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"M0,20 4,20 9,0","class":"s1"}],["path",{"d":"M0,5 5,0","class":"s2"}],["path",{"d":"M0,10 9,1","class":"s2"}],["path",{"d":"M0,15 7,8","class":"s2"}],["path",{"d":"M0,20 5,15","class":"s2"}]],["g",{"id":"xmx"},["path",{"d":"m0,20 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"M0,5 5,0","class":"s2"}],["path",{"d":"M0,10 10,0","class":"s2"}],["path",{"d":"M0,15 15,0","class":"s2"}],["path",{"d":"M0,20 20,0","class":"s2"}],["path",{"d":"M5,20 20,5","class":"s2"}],["path",{"d":"M10,20 20,10","class":"s2"}],["path",{"d":"m15,20 5,-5","class":"s2"}]],["g",{"id":"xmd"},["path",{"d":"m0,0 4,0 c 3,10 6,20 16,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}],["path",{"d":"M0,5 4,1","class":"s2"}],["path",{"d":"M0,10 5.5,4.5","class":"s2"}],["path",{"d":"M0,15 6.5,8.5","class":"s2"}],["path",{"d":"M0,20 8,12","class":"s2"}],["path",{"d":"m5,20 5,-5","class":"s2"}],["path",{"d":"m10,20 2.5,-2.5","class":"s2"}]],["g",{"id":"xmu"},["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"m0,20 4,0 C 7,10 10,0 20,0","class":"s1"}],["path",{"d":"M0,5 5,0","class":"s2"}],["path",{"d":"M0,10 10,0","class":"s2"}],["path",{"d":"M0,15 10,5","class":"s2"}],["path",{"d":"M0,20 6,14","class":"s2"}]],["g",{"id":"xmz"},["path",{"d":"m0,0 4,0 c 6,10 11,10 16,10","class":"s1"}],["path",{"d":"m0,20 4,0 C 10,10 15,10 20,10","class":"s1"}],["path",{"d":"M0,5 4.5,0.5","class":"s2"}],["path",{"d":"M0,10 6.5,3.5","class":"s2"}],["path",{"d":"M0,15 8.5,6.5","class":"s2"}],["path",{"d":"M0,20 11.5,8.5","class":"s2"}]],["g",{"id":"ddd"},["path",{"d":"m0,20 20,0","class":"s3"}]],["g",{"id":"dm0"},["path",{"d":"m0,20 10,0","class":"s3"}],["path",{"d":"m12,20 8,0","class":"s1"}]],["g",{"id":"dm1"},["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"dmx"},["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m20,15 -5,5","class":"s2"}],["path",{"d":"M20,10 10,20","class":"s2"}],["path",{"d":"M20,5 5,20","class":"s2"}],["path",{"d":"M20,0 4,16","class":"s2"}],["path",{"d":"M15,0 6,9","class":"s2"}],["path",{"d":"M10,0 9,1","class":"s2"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"dmd"},["path",{"d":"m0,20 20,0","class":"s3"}]],["g",{"id":"dmu"},["path",{"d":"m0,20 3,0 C 7,10 10.107603,0 20,0","class":"s1"}]],["g",{"id":"dmz"},["path",{"d":"m0,20 3,0 C 10,10 15,10 20,10","class":"s1"}]],["g",{"id":"uuu"},["path",{"d":"M0,0 20,0","class":"s3"}]],["g",{"id":"um0"},["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}]],["g",{"id":"um1"},["path",{"d":"M0,0 10,0","class":"s3"}],["path",{"d":"m12,0 8,0","class":"s1"}]],["g",{"id":"umx"},["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"m20,15 -5,5","class":"s2"}],["path",{"d":"M20,10 10,20","class":"s2"}],["path",{"d":"M20,5 8,17","class":"s2"}],["path",{"d":"M20,0 7,13","class":"s2"}],["path",{"d":"M15,0 6,9","class":"s2"}],["path",{"d":"M10,0 5,5","class":"s2"}],["path",{"d":"M3.5,1.5 5,0","class":"s2"}]],["g",{"id":"umd"},["path",{"d":"m0,0 3,0 c 4,10 7,20 17,20","class":"s1"}]],["g",{"id":"umu"},["path",{"d":"M0,0 20,0","class":"s3"}]],["g",{"id":"umz"},["path",{"d":"m0,0 3,0 c 7,10 12,10 17,10","class":"s4"}]],["g",{"id":"zzz"},["path",{"d":"m0,10 20,0","class":"s1"}]],["g",{"id":"zm0"},["path",{"d":"m0,10 6,0 3,10 11,0","class":"s1"}]],["g",{"id":"zm1"},["path",{"d":"M0,10 6,10 9,0 20,0","class":"s1"}]],["g",{"id":"zmx"},["path",{"d":"m6,10 3,10 11,0","class":"s1"}],["path",{"d":"M0,10 6,10 9,0 20,0","class":"s1"}],["path",{"d":"m20,15 -5,5","class":"s2"}],["path",{"d":"M20,10 10,20","class":"s2"}],["path",{"d":"M20,5 8,17","class":"s2"}],["path",{"d":"M20,0 7,13","class":"s2"}],["path",{"d":"M15,0 6.5,8.5","class":"s2"}],["path",{"d":"M10,0 9,1","class":"s2"}]],["g",{"id":"zmd"},["path",{"d":"m0,10 7,0 c 3,5 8,10 13,10","class":"s1"}]],["g",{"id":"zmu"},["path",{"d":"m0,10 7,0 C 10,5 15,0 20,0","class":"s1"}]],["g",{"id":"zmz"},["path",{"d":"m0,10 20,0","class":"s1"}]],["g",{"id":"gap"},["path",{"d":"m7,-2 -4,0 c -5,0 -5,24 -10,24 l 4,0 C 2,22 2,-2 7,-2 z","class":"s5"}],["path",{"d":"M-7,22 C -2,22 -2,-2 3,-2","class":"s1"}],["path",{"d":"M-3,22 C 2,22 2,-2 7,-2","class":"s1"}]],["g",{"id":"0mv-3"},["path",{"d":"M9,0 20,0 20,20 3,20 z","class":"s6"}],["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"1mv-3"},["path",{"d":"M2.875,0 20,0 20,20 9,20 z","class":"s6"}],["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"xmv-3"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s6"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,5 3.5,1.5","class":"s2"}],["path",{"d":"M0,10 4.5,5.5","class":"s2"}],["path",{"d":"M0,15 6,9","class":"s2"}],["path",{"d":"M0,20 4,16","class":"s2"}]],["g",{"id":"dmv-3"},["path",{"d":"M9,0 20,0 20,20 3,20 z","class":"s6"}],["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"umv-3"},["path",{"d":"M3,0 20,0 20,20 9,20 z","class":"s6"}],["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"zmv-3"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s6"}],["path",{"d":"m6,10 3,10 11,0","class":"s1"}],["path",{"d":"M0,10 6,10 9,0 20,0","class":"s1"}]],["g",{"id":"vvv-3"},["path",{"d":"M20,20 0,20 0,0 20,0","class":"s6"}],["path",{"d":"m0,20 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"vm0-3"},["path",{"d":"M0,20 0,0 3,0 9,20","class":"s6"}],["path",{"d":"M0,0 3,0 9,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"vm1-3"},["path",{"d":"M0,0 0,20 3,20 9,0","class":"s6"}],["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0","class":"s1"}]],["g",{"id":"vmx-3"},["path",{"d":"M0,0 0,20 3,20 6,10 3,0","class":"s6"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}],["path",{"d":"m20,15 -5,5","class":"s2"}],["path",{"d":"M20,10 10,20","class":"s2"}],["path",{"d":"M20,5 8,17","class":"s2"}],["path",{"d":"M20,0 7,13","class":"s2"}],["path",{"d":"M15,0 7,8","class":"s2"}],["path",{"d":"M10,0 9,1","class":"s2"}]],["g",{"id":"vmd-3"},["path",{"d":"m0,0 0,20 20,0 C 10,20 7,10 3,0","class":"s6"}],["path",{"d":"m0,0 3,0 c 4,10 7,20 17,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"vmu-3"},["path",{"d":"m0,0 0,20 3,0 C 7,10 10,0 20,0","class":"s6"}],["path",{"d":"m0,20 3,0 C 7,10 10,0 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"vmz-3"},["path",{"d":"M0,0 3,0 C 10,10 15,10 20,10 15,10 10,10 3,20 L 0,20","class":"s6"}],["path",{"d":"m0,0 3,0 c 7,10 12,10 17,10","class":"s1"}],["path",{"d":"m0,20 3,0 C 10,10 15,10 20,10","class":"s1"}]],["g",{"id":"vmv-3-3"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s6"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s6"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-3-4"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s7"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s6"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-3-5"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s8"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s6"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-4-3"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s6"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s7"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-4-4"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s7"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s7"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-4-5"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s8"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s7"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-5-3"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s6"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s8"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-5-4"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s7"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s8"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-5-5"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s8"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s8"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"0mv-4"},["path",{"d":"M9,0 20,0 20,20 3,20 z","class":"s7"}],["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"1mv-4"},["path",{"d":"M2.875,0 20,0 20,20 9,20 z","class":"s7"}],["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"xmv-4"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s7"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,5 3.5,1.5","class":"s2"}],["path",{"d":"M0,10 4.5,5.5","class":"s2"}],["path",{"d":"M0,15 6,9","class":"s2"}],["path",{"d":"M0,20 4,16","class":"s2"}]],["g",{"id":"dmv-4"},["path",{"d":"M9,0 20,0 20,20 3,20 z","class":"s7"}],["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"umv-4"},["path",{"d":"M3,0 20,0 20,20 9,20 z","class":"s7"}],["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"zmv-4"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s7"}],["path",{"d":"m6,10 3,10 11,0","class":"s1"}],["path",{"d":"M0,10 6,10 9,0 20,0","class":"s1"}]],["g",{"id":"0mv-5"},["path",{"d":"M9,0 20,0 20,20 3,20 z","class":"s8"}],["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"1mv-5"},["path",{"d":"M2.875,0 20,0 20,20 9,20 z","class":"s8"}],["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"xmv-5"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s8"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,5 3.5,1.5","class":"s2"}],["path",{"d":"M0,10 4.5,5.5","class":"s2"}],["path",{"d":"M0,15 6,9","class":"s2"}],["path",{"d":"M0,20 4,16","class":"s2"}]],["g",{"id":"dmv-5"},["path",{"d":"M9,0 20,0 20,20 3,20 z","class":"s8"}],["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"umv-5"},["path",{"d":"M3,0 20,0 20,20 9,20 z","class":"s8"}],["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"zmv-5"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s8"}],["path",{"d":"m6,10 3,10 11,0","class":"s1"}],["path",{"d":"M0,10 6,10 9,0 20,0","class":"s1"}]],["g",{"id":"vvv-4"},["path",{"d":"M20,20 0,20 0,0 20,0","class":"s7"}],["path",{"d":"m0,20 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"vm0-4"},["path",{"d":"M0,20 0,0 3,0 9,20","class":"s7"}],["path",{"d":"M0,0 3,0 9,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"vm1-4"},["path",{"d":"M0,0 0,20 3,20 9,0","class":"s7"}],["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0","class":"s1"}]],["g",{"id":"vmx-4"},["path",{"d":"M0,0 0,20 3,20 6,10 3,0","class":"s7"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}],["path",{"d":"m20,15 -5,5","class":"s2"}],["path",{"d":"M20,10 10,20","class":"s2"}],["path",{"d":"M20,5 8,17","class":"s2"}],["path",{"d":"M20,0 7,13","class":"s2"}],["path",{"d":"M15,0 7,8","class":"s2"}],["path",{"d":"M10,0 9,1","class":"s2"}]],["g",{"id":"vmd-4"},["path",{"d":"m0,0 0,20 20,0 C 10,20 7,10 3,0","class":"s7"}],["path",{"d":"m0,0 3,0 c 4,10 7,20 17,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"vmu-4"},["path",{"d":"m0,0 0,20 3,0 C 7,10 10,0 20,0","class":"s7"}],["path",{"d":"m0,20 3,0 C 7,10 10,0 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"vmz-4"},["path",{"d":"M0,0 3,0 C 10,10 15,10 20,10 15,10 10,10 3,20 L 0,20","class":"s7"}],["path",{"d":"m0,0 3,0 c 7,10 12,10 17,10","class":"s1"}],["path",{"d":"m0,20 3,0 C 10,10 15,10 20,10","class":"s1"}]],["g",{"id":"vvv-5"},["path",{"d":"M20,20 0,20 0,0 20,0","class":"s8"}],["path",{"d":"m0,20 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"vm0-5"},["path",{"d":"M0,20 0,0 3,0 9,20","class":"s8"}],["path",{"d":"M0,0 3,0 9,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"vm1-5"},["path",{"d":"M0,0 0,20 3,20 9,0","class":"s8"}],["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0","class":"s1"}]],["g",{"id":"vmx-5"},["path",{"d":"M0,0 0,20 3,20 6,10 3,0","class":"s8"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}],["path",{"d":"m20,15 -5,5","class":"s2"}],["path",{"d":"M20,10 10,20","class":"s2"}],["path",{"d":"M20,5 8,17","class":"s2"}],["path",{"d":"M20,0 7,13","class":"s2"}],["path",{"d":"M15,0 7,8","class":"s2"}],["path",{"d":"M10,0 9,1","class":"s2"}]],["g",{"id":"vmd-5"},["path",{"d":"m0,0 0,20 20,0 C 10,20 7,10 3,0","class":"s8"}],["path",{"d":"m0,0 3,0 c 4,10 7,20 17,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"vmu-5"},["path",{"d":"m0,0 0,20 3,0 C 7,10 10,0 20,0","class":"s8"}],["path",{"d":"m0,20 3,0 C 7,10 10,0 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"vmz-5"},["path",{"d":"M0,0 3,0 C 10,10 15,10 20,10 15,10 10,10 3,20 L 0,20","class":"s8"}],["path",{"d":"m0,0 3,0 c 7,10 12,10 17,10","class":"s1"}],["path",{"d":"m0,20 3,0 C 10,10 15,10 20,10","class":"s1"}]],["g",{"id":"Pclk"},["path",{"d":"M-3,12 0,3 3,12 C 1,11 -1,11 -3,12 z","class":"s9"}],["path",{"d":"M0,20 0,0 20,0","class":"s1"}]],["g",{"id":"Nclk"},["path",{"d":"M-3,8 0,17 3,8 C 1,9 -1,9 -3,8 z","class":"s9"}],["path",{"d":"m0,0 0,20 20,0","class":"s1"}]],["g",{"id":"vvv-2"},["path",{"d":"M20,20 0,20 0,0 20,0","class":"s10"}],["path",{"d":"m0,20 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"vm0-2"},["path",{"d":"M0,20 0,0 3,0 9,20","class":"s10"}],["path",{"d":"M0,0 3,0 9,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"vm1-2"},["path",{"d":"M0,0 0,20 3,20 9,0","class":"s10"}],["path",{"d":"M0,0 20,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0","class":"s1"}]],["g",{"id":"vmx-2"},["path",{"d":"M0,0 0,20 3,20 6,10 3,0","class":"s10"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}],["path",{"d":"m20,15 -5,5","class":"s2"}],["path",{"d":"M20,10 10,20","class":"s2"}],["path",{"d":"M20,5 8,17","class":"s2"}],["path",{"d":"M20,0 7,13","class":"s2"}],["path",{"d":"M15,0 7,8","class":"s2"}],["path",{"d":"M10,0 9,1","class":"s2"}]],["g",{"id":"vmd-2"},["path",{"d":"m0,0 0,20 20,0 C 10,20 7,10 3,0","class":"s10"}],["path",{"d":"m0,0 3,0 c 4,10 7,20 17,20","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"vmu-2"},["path",{"d":"m0,0 0,20 3,0 C 7,10 10,0 20,0","class":"s10"}],["path",{"d":"m0,20 3,0 C 7,10 10,0 20,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"vmz-2"},["path",{"d":"M0,0 3,0 C 10,10 15,10 20,10 15,10 10,10 3,20 L 0,20","class":"s10"}],["path",{"d":"m0,0 3,0 c 7,10 12,10 17,10","class":"s1"}],["path",{"d":"m0,20 3,0 C 10,10 15,10 20,10","class":"s1"}]],["g",{"id":"0mv-2"},["path",{"d":"M9,0 20,0 20,20 3,20 z","class":"s10"}],["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"1mv-2"},["path",{"d":"M2.875,0 20,0 20,20 9,20 z","class":"s10"}],["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"xmv-2"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s10"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,5 3.5,1.5","class":"s2"}],["path",{"d":"M0,10 4.5,5.5","class":"s2"}],["path",{"d":"M0,15 6,9","class":"s2"}],["path",{"d":"M0,20 4,16","class":"s2"}]],["g",{"id":"dmv-2"},["path",{"d":"M9,0 20,0 20,20 3,20 z","class":"s10"}],["path",{"d":"M3,20 9,0 20,0","class":"s1"}],["path",{"d":"m0,20 20,0","class":"s1"}]],["g",{"id":"umv-2"},["path",{"d":"M3,0 20,0 20,20 9,20 z","class":"s10"}],["path",{"d":"m3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,0 20,0","class":"s1"}]],["g",{"id":"zmv-2"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s10"}],["path",{"d":"m6,10 3,10 11,0","class":"s1"}],["path",{"d":"M0,10 6,10 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-3-2"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s10"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s6"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-4-2"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s10"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s7"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-5-2"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s10"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s8"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-2-3"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s6"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s10"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-2-4"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s7"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s10"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-2-5"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s8"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s10"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"vmv-2-2"},["path",{"d":"M9,0 20,0 20,20 9,20 6,10 z","class":"s10"}],["path",{"d":"M3,0 0,0 0,20 3,20 6,10 z","class":"s10"}],["path",{"d":"m0,0 3,0 6,20 11,0","class":"s1"}],["path",{"d":"M0,20 3,20 9,0 20,0","class":"s1"}]],["g",{"id":"arrow0"},["path",{"d":"m-12,-3 9,3 -9,3 c 1,-2 1,-4 0,-6 z","class":"s11"}],["path",{"d":"M0,0 -15,0","class":"s12"}]],["marker",{"id":"arrowhead","style":"fill:#0041c4","markerHeight":"7","markerWidth":"10","markerUnits":"strokeWidth","viewBox":"0 -4 11 8","refX":"15","refY":"0","orient":"auto"},["path",{"d":"M0 -4 11 0 0 4z"}]],["marker",{"id":"arrowtail","style":"fill:#0041c4","markerHeight":"7","markerWidth":"10","markerUnits":"strokeWidth","viewBox":"-11 -4 11 8","refX":"-15","refY":"0","orient":"auto"},["path",{"d":"M0 -4 -11 0 0 4z"}]]],["g",{"id":"waves"},["g",{"id":"lanes"}],["g",{"id":"groups"}]]]; diff --git a/src/utils/wavedrom/wavedrom.min.js b/src/utils/wavedrom/wavedrom.min.js deleted file mode 100644 index 8d1b960f..00000000 --- a/src/utils/wavedrom/wavedrom.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! wavedrom 2017-11-08 */ - -!function e(t,r,n){function s(a,i){if(!r[a]){if(!t[a]){var l="function"==typeof require&&require;if(!i&&l)return l(a,!0);if(o)return o(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var u=r[a]={exports:{}};t[a][0].call(u.exports,function(e){var r=t[a][1][e];return s(r||e)},u,u.exports,e,t,r,n)}return r[a].exports}for(var o="function"==typeof require&&require,a=0;at+s.offsetWidth||e.yn+s.offsetHeight)&&(s.parentNode.removeChild(s),document.body.removeEventListener("mousedown",r,!1))}var n,s;(n=document.getElementById(t+e)).childNodes[0].addEventListener("contextmenu",function(o){var a,i,l;(s=document.createElement("div")).className="wavedromMenu",s.style.top=o.y+"px",s.style.left=o.x+"px",a=document.createElement("ul"),(i=document.createElement("li")).innerHTML="Save as PNG",a.appendChild(i),(l=document.createElement("li")).innerHTML="Save as SVG",a.appendChild(l),s.appendChild(a),document.body.appendChild(s),i.addEventListener("click",function(){var o,a,i,l,c,u,d;o="",0!==e&&(o+=(a=document.getElementById(t+0)).innerHTML.substring(166,a.innerHTML.indexOf(''))),o=[n.innerHTML.slice(0,166),o,n.innerHTML.slice(166)].join(""),i="data:image/svg+xml;base64,"+btoa(o),(l=new Image).src=i,(c=document.createElement("canvas")).width=l.width,c.height=l.height,c.getContext("2d").drawImage(l,0,0),u=c.toDataURL("image/png"),(d=document.createElement("a")).href=u,d.download="wavedrom.png",d.click(),s.parentNode.removeChild(s),document.body.removeEventListener("mousedown",r,!1)},!1),l.addEventListener("click",function(){var o,a,i,l;o="",0!==e&&(o+=(a=document.getElementById(t+0)).innerHTML.substring(166,a.innerHTML.indexOf(''))),o=[n.innerHTML.slice(0,166),o,n.innerHTML.slice(166)].join(""),i="data:image/svg+xml;base64,"+btoa(o),(l=document.createElement("a")).href=i,l.download="wavedrom.svg",l.click(),s.parentNode.removeChild(s),document.body.removeEventListener("mousedown",r,!1)},!1),s.addEventListener("contextmenu",function(e){e.preventDefault()},!1),document.body.addEventListener("mousedown",r,!1),o.preventDefault()},!1)}},{}],2:[function(e,t,r){"use strict";var n=e("./jsonml-parse");t.exports=n},{"./jsonml-parse":15}],3:[function(e,t,r){"use strict";var n=e("./eva"),s=e("./render-wave-form");t.exports=function(){s(0,n("InputJSON_0"),"WaveDrom_Display_")}},{"./eva":4,"./render-wave-form":29}],4:[function(require,module,exports){"use strict";function eva(id){function erra(e){return{signal:[{name:["tspan",["tspan",{class:"error h5"},"Error: "],e.message]}]}}var TheTextBox,source;if((TheTextBox=document.getElementById(id)).type&&"textarea"===TheTextBox.type)try{source=eval("("+TheTextBox.value+")")}catch(e){return erra(e)}else try{source=eval("("+TheTextBox.innerHTML+")")}catch(e){return erra(e)}if("[object Object]"!==Object.prototype.toString.call(source))return erra({message:'[Semantic]: The root has to be an Object: "{signal:[...]}"'});if(source.signal){if("[object Array]"!==Object.prototype.toString.call(source.signal))return erra({message:'[Semantic]: "signal" object has to be an Array "signal:[]"'})}else if(source.assign){if("[object Array]"!==Object.prototype.toString.call(source.assign))return erra({message:'[Semantic]: "assign" object hasto be an Array "assign:[]"'})}else if(!source.reg)return erra({message:'[Semantic]: "signal:[...]" or "assign:[...]" property is missing inside the root Object'});return source}module.exports=eva},{}],5:[function(e,t,r){"use strict";t.exports=function(e){var t=0,r=0,n=[];return e.forEach(function(e){"vvv-2"===e||"vvv-3"===e||"vvv-4"===e||"vvv-5"===e?r+=1:0!==r&&(n.push(t-(r+1)/2),r=0),t+=1}),0!==r&&n.push(t-(r+1)/2),n}},{}],6:[function(e,t,r){"use strict";t.exports=function(e,t,r){var n,s,o=[];if(4===e.length){for(s=0;s");e.tagName===r.tagName&&(e=r)}catch(e){console.log(e)}for(var i in t)if(t.hasOwnProperty(i)){var l=t[i];i&&null!==l&&void 0!==l&&("style"===(i=s[i.toLowerCase()]||i)?void 0!==e.style.cssText?e.style.cssText=l:e.style=l:a[i]?(n(e,i,l),o[i]&&n(e,o[i],l)):"string"==typeof l||"number"==typeof l||"boolean"==typeof l?(e.setAttribute(i,l),o[i]&&e.setAttribute(o[i],l)):(e[i]=l,o[i]&&(e[o[i]]=l)))}return e}},{}],13:[function(e,t,r){"use strict";t.exports=function(e,t){t&&(e.tagName&&"style"===e.tagName.toLowerCase()&&document.createStyleSheet?e.cssText=t:!1!==e.canHaveChildren&&e.appendChild(t))}},{}],14:[function(e,t,r){"use strict";var n=e("./jsonml-trim-whitespace");t.exports=function(e){var t=document.createElement("div");if(t.innerHTML=e,n(t),1===t.childNodes.length)return t.firstChild;for(var r=document.createDocumentFragment?document.createDocumentFragment():document.createElement("");t.firstChild;)r.appendChild(t.firstChild);return r}},{"./jsonml-trim-whitespace":16}],15:[function(e,t,r){"use strict";function n(e){return e instanceof Array&&"string"==typeof e[0]}function s(e,t,r){return document.createTextNode("["+e+"-"+r+"]")}var o,a,i=e("./jsonml-hydrate"),l=e("./w3"),c=e("./jsonml-append-child"),u=e("./jsonml-add-attributes"),d=e("./jsonml-trim-whitespace");o=function(e,t,r){for(var n=1;n0?Math.round(e):1}(e.config.hscale)))>0&&(r>100&&(r=100),t.hscale=r),t.yh0=0,t.yh1=0,t.head=e.head,t.xmin_cfg=0,t.xmax_cfg=1e12,e&&e.config&&e.config.hbounds&&2==e.config.hbounds.length&&(e.config.hbounds[0]=Math.floor(e.config.hbounds[0]),e.config.hbounds[1]=Math.ceil(e.config.hbounds[1]),e.config.hbounds[0]"===l&&(u=!1,l=f.shift()),a=1;"."===f[0]||"|"===f[0];)f.shift(),a+=1;h=u?h.concat(s(i+l,0,a-r.period)):h.concat(s(i+l,t,a))}for(c=0;c0?(d=o(m).length,1==o([m[m.length-1]]).length&&1==o([h[0]]).length&&(d-=1)):d=0,[h,d]}},{"./find-lane-markers":5,"./gen-first-wave-brick":7,"./gen-wave-brick":8}],20:[function(e,t,r){"use strict";function n(e,t){var r;return void 0===(r=e.data)?null:("string"==typeof r&&(r=r.split(" ")),r=r.slice(t))}var s=e("./parse-wave-lane");t.exports=function(e,t){var r,o,a,i,l,c=[],u=[];for(r in e)o=e[r],t.period=o.period?o.period:1,t.phase=(o.phase?2*o.phase:0)+t.xmin_cfg,c.push([]),u[0]=o.name||" ",u[1]=(o.phase||0)+t.xmin_cfg/2,o.wave?(a=(i=s(o.wave,t.period*t.hscale-1,t))[0],l=i[1]):a=null,c[c.length-1][0]=u.slice(0),c[c.length-1][1]=a,c[c.length-1][2]=n(o,l);return c}},{"./parse-wave-lane":19}],21:[function(e,t,r){"use strict";var n=e("./eva"),s=e("./append-save-as-dialog"),o=e("./render-wave-form");t.exports=function(){var e,t,r,a;for(r=0,e=document.querySelectorAll("*"),t=0;tdiv.wavedromMenu{position:fixed;border:solid 1pt#CCCCCC;background-color:white;box-shadow:0px 10px 20px #808080;cursor:default;margin:0px;padding:0px;}div.wavedromMenu>ul{margin:0px;padding:0px;}div.wavedromMenu>ul>li{padding:2px 10px;list-style:none;}div.wavedromMenu>ul>li:hover{background-color:#b5d5ff;}'}},{"./append-save-as-dialog":1,"./eva":4,"./render-wave-form":29}],22:[function(e,t,r){"use strict";function n(e,t){var r,s,o={},a={x:10};for("string"!=typeof e[0]&&"number"!=typeof e[0]||(s=e[0],a.x=25),t.x+=a.x,r=0;r":k.setAttribute("style","marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none");break;case"~>":k.setAttribute("style","marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","M "+x.x+","+x.y+" c "+.7*v+", 0 "+.3*v+", "+y+" "+v+", "+y);break;case"-~>":k.setAttribute("style","marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","M "+x.x+","+x.y+" c "+.7*v+", 0 "+v+", "+y+" "+v+", "+y),_.label&&(b=x.x+.75*(g.x-x.x));break;case"~->":k.setAttribute("style","marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","M "+x.x+","+x.y+" c 0, 0 "+.3*v+", "+y+" "+v+", "+y),_.label&&(b=x.x+.25*(g.x-x.x));break;case"-|>":k.setAttribute("style","marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","m "+x.x+","+x.y+" "+v+",0 0,"+y),_.label&&(b=g.x);break;case"|->":k.setAttribute("style","marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","m "+x.x+","+x.y+" 0,"+y+" "+v+",0"),_.label&&(b=x.x);break;case"-|->":k.setAttribute("style","marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","m "+x.x+","+x.y+" "+v/2+",0 0,"+y+" "+v/2+",0");break;case"<->":k.setAttribute("style","marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none");break;case"<~>":k.setAttribute("style","marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","M "+x.x+","+x.y+" c "+.7*v+", 0 "+.3*v+", "+y+" "+v+", "+y);break;case"<-~>":k.setAttribute("style","marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","M "+x.x+","+x.y+" c "+.7*v+", 0 "+v+", "+y+" "+v+", "+y),_.label&&(b=x.x+.75*(g.x-x.x));break;case"<-|>":k.setAttribute("style","marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","m "+x.x+","+x.y+" "+v+",0 0,"+y),_.label&&(b=g.x);break;case"<-|->":k.setAttribute("style","marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none"),k.setAttribute("d","m "+x.x+","+x.y+" "+v/2+",0 0,"+y+" "+v/2+",0");break;default:k.setAttribute("style","fill:none;stroke:#F00;stroke-width:1")}_.label&&(m.setAttribute("x",b),m.setAttribute("y",w+3),p.setAttribute("x",b-N/2),p.setAttribute("y",w-5))}for(u in E)u===u.toLowerCase()&&E[u].x>0&&(p=s(["rect",{y:E[u].y-4,height:8,style:"fill:#FFF;"}]),m=s(["text",{style:"font-size:8px;",x:E[u].x,y:E[u].y+2,"text-anchor":"middle"},u+""]),l.insertBefore(p,null),l.insertBefore(m,null),N=m.getBBox().width+2,p.setAttribute("x",E[u].x-N/2),p.setAttribute("width",N))}}},{"./create-element":2,"./w3":31,tspan:35}],24:[function(e,t,r){"use strict";function n(e,t){var r,s,o;for(t.xmax=Math.max(t.xmax,t.x),r=t.y,o=e.length,s=1;s"===f&&(d=!1,f=h.shift()),c+=d?1:2*s.period,"|"===f&&((l=document.createElementNS(n.svg,"use")).setAttributeNS(n.xlink,"xlink:href","#gap"),l.setAttribute("transform","translate("+s.xs*((c-(d?0:s.period))*s.hscale-s.phase)+")"),i.insertBefore(l,null))}}},{"./w3":31}],26:[function(e,t,r){"use strict";var n=e("tspan");t.exports=function(e,t,r){var s,o,a,i=["g"];return e.forEach(function(e,l){i.push(["path",{id:"group_"+l+"_"+t,d:"m "+(e.x+.5)+","+(e.y*r.yo+3.5+r.yh0+r.yh1)+" c -3,0 -5,2 -5,5 l 0,"+(e.height*r.yo-16)+" c 0,3 2,5 5,5",style:"stroke:#0041c4;stroke-width:1;fill:none"}]),void 0!==e.name&&(s=e.x-10,o=r.yo*(e.y+e.height/2)+r.yh0+r.yh1,(a=n.parse(e.name)).unshift("text",{"text-anchor":"middle",class:"info","xml:space":"preserve"}),i.push(["g",{transform:"translate("+s+","+o+")"},["g",{transform:"rotate(270)"},a]]))}),i}},{tspan:35}],27:[function(e,t,r){"use strict";var n=e("tspan"),s=e("./create-element");t.exports=function(e,t,r,o){function a(e,t,r){var o;e[t]&&e[t].text&&((o=n.parse(e[t].text)).unshift("text",{x:e.xmax*e.xs/2,y:r,"text-anchor":"middle",fill:"#000","xml:space":"preserve"}),o=s(o),c.insertBefore(o,null))}function i(e,t,r,o,a,i,u){var d,f,h,m,p=1,x=0,g=[];if(void 0!==e[t]&&void 0!==e[t][r]){if("string"==typeof(h=e[t][r]))h=h.split(" ");else if("number"==typeof h||"boolean"==typeof h)for(f=Number(h),h=[],l=0;l0?Math.ceil(2*x)-2*x:-2*x,f=s(["g",{id:"wavelane_draw_"+c+"_"+r,transform:"translate("+x*i.xs+", 0)"}]),d.insertBefore(f,null),t[c][1])){for(l=0;lv&&(v=t[c][1].length)}return i.xmax=Math.min(v,i.xmax_cfg-i.xmin_cfg),i.xg=20,y}},{"./create-element":2,"./find-lane-markers":5,"./w3":31,tspan:35}],31:[function(e,t,r){"use strict";t.exports={svg:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",xmlns:"http://www.w3.org/XML/1998/namespace"}},{}],32:[function(e,t,r){"use strict";window.WaveDrom=window.WaveDrom||{};var n=e("./");window.WaveDrom.ProcessAll=n.processAll,window.WaveDrom.RenderWaveForm=n.renderWaveForm,window.WaveDrom.EditorRefresh=n.editorRefresh,window.WaveDrom.eva=n.eva},{"./":9}],33:[function(e,t,r){"use strict";t.exports=window.WaveSkin},{}],34:[function(e,t,r){"use strict";function n(e,t){return"translate("+e+","+t+")"}function s(e,t,r){var n=["line"],s={};return t?(s.x1=t,s.x2=t+e):s.x2=e,r&&(s.y1=r,s.y2=r),n.push(s),n}function o(e,t,r){var n=["line"],s={};return t&&(s.x1=t,s.x2=t),r?(s.y1=r,s.y2=r+e):s.y2=e,n.push(s),n}function a(e,t){var r=t.hspace/t.mod,s=["g",{transform:n(r/2,t.vspace/5)}],o=["g",{transform:n(r/2,t.vspace/2+4)}],a=["g",{transform:n(r/2,t.vspace)}],i=["g",{transform:n(0,t.vspace/4)}],l=t.fontsize,c=t.fontfamily,d=t.fontweight;return e.forEach(function(e){var n,f,h,m,p,x;if(h=0,m=t.mod-1,p=t.index*t.mod,x=(t.index+1)*t.mod-1,e.lsb/t.mod>>0===t.index)h=e.lsbm,p=e.lsb,e.msb/t.mod>>0===t.index&&(x=e.msb,m=e.msbm);else{if(e.msb/t.mod>>0!==t.index)return;x=e.msb,m=e.msbm}s.push(["text",{x:r*(t.mod-h-1),"font-size":l,"font-family":c,"font-weight":d},p.toString()]),h!==m&&s.push(["text",{x:r*(t.mod-m-1),"font-size":l,"font-family":c,"font-weight":d},x.toString()]),e.name?((n=u.parse(e.name)).unshift({x:r*(t.mod-(m+h)/2-1),"font-size":l,"font-family":c,"font-weight":d}),n.unshift("text"),o.push(n)):i.push(["rect",{style:"fill-opacity:0.1",x:r*(t.mod-m-1),y:0,width:r*(m-h+1),height:t.vspace/2}]),e.attr&&((f=u.parse(e.attr)).unshift({x:r*(t.mod-(m+h)/2-1),"font-size":l,"font-family":c,"font-weight":d}),f.unshift("text"),a.push(f))}),["g",i,s,o,a]}function i(e,t){return["g",{"text-anchor":"middle"},a(e,t)]}function l(e,t){var r=t.hspace,a=t.vspace,i=t.mod,l=["g",{stroke:"black","stroke-width":1,"stroke-linecap":"round",transform:n(0,a/4)}];l.push(s(r)),l.push(o(a/2)),l.push(s(r,0,a/2));var c=t.index*t.mod,u=t.mod;do{u===t.mod||e.some(function(e){return e.lsb===c})?l.push(o(a/2,u*(r/i))):(l.push(o(a/16,u*(r/i))),l.push(o(a/16,u*(r/i),7*a/16))),c++,u--}while(u);return l}function c(e,t){var r=["g",{transform:n(4.5,(t.lanes-t.index-1)*t.vspace+.5)}];return r.push(l(e,t)),r.push(i(e,t)),r}var u=e("tspan");t.exports=function(e,t){(t=t||{}).vspace=t.vspace||80,t.hspace=t.hspace||640,t.lanes=t.lanes||2,t.bits=t.bits||32,t.bigendian=t.bigendian||!1,t.fontfamily=t.fontfamily||"sans-serif",t.fontweight=t.fontweight||"normal",t.fontsize=t.fontsize||14;var r=["svg",{xmlns:"http://www.w3.org/2000/svg",width:t.hspace+9,height:t.vspace*t.lanes+5,viewBox:[0,0,t.hspace+9,t.vspace*t.lanes+5].join(" ")}],n=0,s=t.bits/t.lanes;t.mod=s,e.forEach(function(e){e.lsb=n,e.lsbm=n%s,n+=e.bits,e.msb=n-1,e.msbm=e.msb%s});var o;for(o=0;o0&&(t[r]=n.join(" ")),t},{})}var o=/||||||||<\/o>|<\/ins>|<\/s>|<\/sub>|<\/sup>|<\/b>|<\/i>|<\/tt>/,a={"":{add:"text-decoration overline"},"":{del:"text-decoration overline"},"":{add:"text-decoration underline"},"":{del:"text-decoration underline"},"":{add:"text-decoration line-through"},"":{del:"text-decoration line-through"},"":{add:"font-weight bold"},"":{del:"font-weight bold"},"":{add:"font-style italic"},"":{del:"font-style italic"},"":{add:"baseline-shift sub;font-size .7em"},"":{del:"baseline-shift sub;font-size .7em"},"":{add:"baseline-shift super;font-size .7em"},"":{del:"baseline-shift super;font-size .7em"},"":{add:"font-family monospace"},"":{del:"font-family monospace"}};t.exports=function(e){var t,r,i,l,c;if(void 0===e)return[];if("number"==typeof e)return[e+""];if("string"!=typeof e)return[e];for(r=[],t={"text-decoration":{},"font-weight":{},"font-style":{},"baseline-shift":{},"font-size":{},"font-family":{}};;){if(-1===(i=e.search(o)))return r.push(["tspan",s(t),e]),r;if(i>0&&(c=e.slice(0,i),r.push(["tspan",s(t),c])),l=e.match(o)[0],n(t,a[l]),0===(e=e.slice(i+l.length)).length)return r}}},{}],37:[function(e,t,r){"use strict";function n(e){var t=e.match(/(\w+)-(\w)(\w+)/);return null===t?e:t[1]+t[2].toUpperCase()+t[3]}var s=e("./parse");t.exports=function(e){function t(e,t){var s=e[0],o=e[1],a=Object.keys(o).reduce(function(e,t){return e[n(t)]=o[t],e},{}),i=e[2];return o.key=t,r(s,a,i)}var r=e.createElement;return function(e){return s(e).map(t)}}},{"./parse":36}]},{},[32]); \ No newline at end of file diff --git a/src/valltagspanel.cpp b/src/valltagspanel.cpp deleted file mode 100644 index 5cb9da3b..00000000 --- a/src/valltagspanel.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "valltagspanel.h" - -#include - -#include "vtaglabel.h" -#include "utils/vimnavigationforwidget.h" - -VAllTagsPanel::VAllTagsPanel(QWidget *p_parent) - : QWidget(p_parent) -{ - m_list = new QListWidget(this); - - QVBoxLayout *layout = new QVBoxLayout(); - layout->addWidget(m_list); - - setLayout(layout); -} - -void VAllTagsPanel::clear() -{ - while (m_list->count() > 0) { - removeItem(m_list->item(0)); - } -} - -void VAllTagsPanel::removeItem(QListWidgetItem *p_item) -{ - QWidget *wid = m_list->itemWidget(p_item); - m_list->removeItemWidget(p_item); - wid->deleteLater(); - - int row = m_list->row(p_item); - Q_ASSERT(row >= 0); - m_list->takeItem(row); - delete p_item; -} - -VTagLabel *VAllTagsPanel::addTag(const QString &p_text) -{ - VTagLabel *label = new VTagLabel(p_text, true, this); - QSize sz = label->sizeHint(); - sz.setHeight(sz.height() * 2 + 10); - - QListWidgetItem *item = new QListWidgetItem(); - item->setSizeHint(sz); - - connect(label, &VTagLabel::removalRequested, - this, [this, item](const QString &p_text) { - removeItem(item); - emit tagRemoved(p_text); - }); - - m_list->addItem(item); - m_list->setItemWidget(item, label); - return label; -} - -void VAllTagsPanel::showEvent(QShowEvent *p_event) -{ - QWidget::showEvent(p_event); - - m_list->setFocus(); -} - -void VAllTagsPanel::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(m_list, p_event)) { - return; - } - - QWidget::keyPressEvent(p_event); -} diff --git a/src/valltagspanel.h b/src/valltagspanel.h deleted file mode 100644 index 31558461..00000000 --- a/src/valltagspanel.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef VALLTAGSPANEL_H -#define VALLTAGSPANEL_H - -#include - -class QListWidget; -class QListWidgetItem; -class VTagLabel; - -class VAllTagsPanel : public QWidget -{ - Q_OBJECT -public: - explicit VAllTagsPanel(QWidget *p_parent = nullptr); - - void clear(); - - VTagLabel *addTag(const QString &p_text); - -signals: - void tagRemoved(const QString &p_text); - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - -private: - void removeItem(QListWidgetItem *p_item); - - QListWidget *m_list; -}; - -#endif // VALLTAGSPANEL_H diff --git a/src/vapplication.cpp b/src/vapplication.cpp deleted file mode 100644 index 2680d427..00000000 --- a/src/vapplication.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "vapplication.h" - -VApplication::VApplication(int &argc, char **argv) - : QApplication(argc, argv) -{ - connect(this, &QApplication::applicationStateChanged, - this, &VApplication::onApplicationStateChanged); -} - -void VApplication::onApplicationStateChanged(Qt::ApplicationState state) -{ - Q_UNUSED(state); -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - if(state == Qt::ApplicationActive && this->window) { - this->window->show(); - // Need to call raise() in macOS. - this->window->raise(); - } -#endif -} diff --git a/src/vapplication.h b/src/vapplication.h deleted file mode 100644 index 31bdfffe..00000000 --- a/src/vapplication.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef VAPPLICATION_H -#define VAPPLICATION_H - -#include -#include -#include "vmainwindow.h" - -class VApplication : public QApplication -{ - Q_OBJECT -public: - explicit VApplication(int &argc, char **argv); - - void setWindow(VMainWindow * window) - { - this->window = window; - } - - -public slots: - void onApplicationStateChanged(Qt::ApplicationState state); - -private: - VMainWindow *window = nullptr; -}; - -#endif // VAPPLICATION_H diff --git a/src/vattachmentlist.cpp b/src/vattachmentlist.cpp deleted file mode 100644 index 1d3c82fd..00000000 --- a/src/vattachmentlist.cpp +++ /dev/null @@ -1,719 +0,0 @@ -#include "vattachmentlist.h" - -#include - -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vbuttonwithwidget.h" -#include "vmainwindow.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "dialog/vsortdialog.h" -#include "utils/vimnavigationforwidget.h" -#include "utils/viconutils.h" -#include "vlineedit.h" - -extern VConfigManager *g_config; - -extern VMainWindow *g_mainWin; - -const QString VAttachmentList::c_infoShortcutSequence = "F2"; - -VAttachmentList::VAttachmentList(QWidget *p_parent) - : QWidget(p_parent), - VButtonPopupWidget(this), - m_initialized(false), - m_file(NULL) -{ -} - -void VAttachmentList::setupUI() -{ - m_addBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/add_attachment.svg"), ""); - m_addBtn->setToolTip(tr("Add")); - m_addBtn->setProperty("FlatBtn", true); - m_addBtn->setDefault(true); - connect(m_addBtn, &QPushButton::clicked, - this, &VAttachmentList::addAttachment); - - m_clearBtn = new QPushButton(VIconUtils::buttonDangerIcon(":/resources/icons/clear_attachment.svg"), ""); - m_clearBtn->setToolTip(tr("Clear")); - m_clearBtn->setProperty("FlatBtn", true); - connect(m_clearBtn, &QPushButton::clicked, - this, [this]() { - if (m_file && m_attachmentList->count() > 0) { - int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Are you sure to clear attachments of note " - "%2?") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - tr("WARNING: " - "VNote will delete all the files in directory " - "%3." - "Deleted files could be found in the recycle bin " - "of this note.
    The operation is IRREVERSIBLE!") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(m_file->fetchAttachmentFolderPath()), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - g_mainWin, - MessageBoxType::Danger); - if (ret == QMessageBox::Ok) { - if (!m_file->deleteAttachments()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to clear attachments of note %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - tr("Please check the attachments folder and " - "maintain the configuration file manually."), - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } - - m_attachmentList->clear(); - - updateButtonState(); - } - } - }); - - m_locateBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/locate_attachment.svg"), ""); - m_locateBtn->setToolTip(tr("Open Folder")); - m_locateBtn->setProperty("FlatBtn", true); - connect(m_locateBtn, &QPushButton::clicked, - this, [this]() { - if (m_file && !m_file->getAttachmentFolder().isEmpty()) { - QUrl url = QUrl::fromLocalFile(m_file->fetchAttachmentFolderPath()); - QDesktopServices::openUrl(url); - } - }); - - m_numLabel = new QLabel(); - - QHBoxLayout *btnLayout = new QHBoxLayout; - btnLayout->addWidget(m_addBtn); - btnLayout->addWidget(m_clearBtn); - btnLayout->addWidget(m_locateBtn); - btnLayout->addStretch(); - btnLayout->addWidget(m_numLabel); - - m_attachmentList = new QListWidget; - m_attachmentList->setContextMenuPolicy(Qt::CustomContextMenu); - m_attachmentList->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_attachmentList->setEditTriggers(QAbstractItemView::SelectedClicked); - m_attachmentList->setAttribute(Qt::WA_MacShowFocusRect, false); - m_attachmentList->setItemDelegate(&m_listDelegate); - connect(m_attachmentList, &QListWidget::customContextMenuRequested, - this, &VAttachmentList::handleContextMenuRequested); - connect(m_attachmentList, &QListWidget::itemActivated, - this, &VAttachmentList::handleItemActivated); - connect(m_attachmentList->itemDelegate(), &QAbstractItemDelegate::commitData, - this, &VAttachmentList::handleListItemCommitData); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(btnLayout); - mainLayout->addWidget(m_attachmentList); - - setLayout(mainLayout); -} - -void VAttachmentList::setFile(VNoteFile *p_file) -{ - init(); - - m_file = p_file; - - updateButtonState(); -} - -void VAttachmentList::updateContent() -{ - bool enableAdd = true, enableDelete = true, enableClear = true, enableLocate = true; - m_attachmentList->clear(); - - if (!m_file) { - enableAdd = enableDelete = enableClear = enableLocate = false; - } else { - QString folder = m_file->getAttachmentFolder(); - const QVector &attas = m_file->getAttachments(); - - if (folder.isEmpty()) { - Q_ASSERT(attas.isEmpty()); - enableDelete = enableClear = enableLocate = false; - } else if (attas.isEmpty()) { - enableDelete = enableClear = false; - } else { - fillAttachmentList(attas); - } - } - - m_addBtn->setEnabled(enableAdd); - m_clearBtn->setEnabled(enableClear); - m_locateBtn->setEnabled(enableLocate); - - int cnt = m_attachmentList->count(); - if (cnt > 0) { - m_numLabel->setText(tr("%1 %2").arg(cnt).arg(cnt > 1 ? tr("Files") : tr("File"))); - m_attachmentList->setFocus(); - } else { - m_numLabel->setText(""); - - if (m_file) { - m_addBtn->setFocus(); - } - } -} - -void VAttachmentList::fillAttachmentList(const QVector &p_attachments) -{ - Q_ASSERT(m_attachmentList->count() == 0); - for (int i = 0; i < p_attachments.size(); ++i) { - const VAttachment &atta = p_attachments[i]; - QListWidgetItem *item = new QListWidgetItem(atta.m_name); - item->setFlags(item->flags() | Qt::ItemIsEditable); - item->setData(Qt::UserRole, atta.m_name); - - m_attachmentList->addItem(item); - } -} - -void VAttachmentList::addAttachment() -{ - if (!m_file) { - return; - } - - static QString lastPath = QDir::homePath(); - QStringList files = QFileDialog::getOpenFileNames(g_mainWin, - tr("Select Files As Attachments"), - lastPath); - if (files.isEmpty()) { - return; - } - - // Update lastPath - lastPath = QFileInfo(files[0]).path(); - - addAttachments(files); - - updateButtonState(); - - updateContent(); -} - -void VAttachmentList::addAttachments(const QStringList &p_files) -{ - Q_ASSERT(m_file); - int addedFiles = 0; - for (int i = 0; i < p_files.size(); ++i) { - if (!m_file->addAttachment(p_files[i])) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to add attachment %1 for note %3.") - .arg(p_files[i]) - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } else { - ++addedFiles; - } - } - - if (addedFiles > 0) { - g_mainWin->showStatusMessage(tr("%1 %2 added as attachments") - .arg(addedFiles) - .arg(addedFiles > 1 ? tr("files") : tr("file"))); - } -} - -void VAttachmentList::handleContextMenuRequested(QPoint p_pos) -{ - // @p_pos is the position in the coordinate of VAttachmentList, no m_attachmentList. - QListWidgetItem *item = m_attachmentList->itemAt(m_attachmentList->mapFromParent(p_pos)); - QMenu menu(this); - menu.setToolTipsVisible(true); - - if (!m_file) { - return; - } - - int selectedSize = m_attachmentList->selectedItems().size(); - if (item) { - if (!item->isSelected()) { - m_attachmentList->setCurrentItem(item, QItemSelectionModel::ClearAndSelect); - } - - if (selectedSize == 1) { - QAction *openAct = new QAction(tr("&Open"), &menu); - openAct->setToolTip(tr("Open current attachment file")); - connect(openAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = m_attachmentList->currentItem(); - handleItemActivated(item); - }); - menu.addAction(openAct); - } - - QAction *deleteAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_attachment.svg"), - tr("&Delete"), - &menu); - deleteAct->setToolTip(tr("Delete selected attachments")); - connect(deleteAct, &QAction::triggered, - this, &VAttachmentList::deleteSelectedItems); - menu.addAction(deleteAct); - } - - m_attachmentList->update(); - - if (m_file->getAttachments().size() > 1) { - if (!menu.actions().isEmpty()) { - menu.addSeparator(); - } - - QAction *sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - &menu); - sortAct->setToolTip(tr("Sort attachments manually")); - connect(sortAct, &QAction::triggered, - this, &VAttachmentList::sortItems); - menu.addAction(sortAct); - } - - if (selectedSize == 1) { - menu.addSeparator(); - - QAction *copyPathAct = new QAction(tr("Copy File Path"), &menu); - connect(copyPathAct, &QAction::triggered, - this, &VAttachmentList::copyAttachmentFilePath); - menu.addAction(copyPathAct); - - QAction *fileInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), - tr("&Info (Rename)\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)), - &menu); - fileInfoAct->setToolTip(tr("View and edit current attachment's information")); - connect(fileInfoAct, &QAction::triggered, - this, &VAttachmentList::attachmentInfo); - menu.addAction(fileInfoAct); - } - - if (!menu.actions().isEmpty()) { - menu.exec(mapToGlobal(p_pos)); - } -} - -void VAttachmentList::handleItemActivated(QListWidgetItem *p_item) -{ - if (p_item) { - Q_ASSERT(m_file); - - QString name = p_item->data(Qt::UserRole).toString(); - QString folderPath = m_file->fetchAttachmentFolderPath(); - QUrl url = QUrl::fromLocalFile(QDir(folderPath).filePath(name)); - QDesktopServices::openUrl(url); - } -} - -void VAttachmentList::deleteSelectedItems() -{ - QVector items; - const QList selectedItems = m_attachmentList->selectedItems(); - - if (selectedItems.isEmpty()) { - return; - } - - for (auto const & item : selectedItems) { - items.push_back(ConfirmItemInfo(item->text(), - item->text(), - "", - NULL)); - } - - QString text = tr("Are you sure to delete these attachments of note " - "%2?") - .arg(g_config->c_dataTextStyle).arg(m_file->getName()); - - QString info = tr("Deleted files could be found in the recycle " - "bin of this note.
    " - "Click \"Cancel\" to leave them untouched."); - - VConfirmDeletionDialog dialog(tr("Confirm Deleting Attachments"), - text, - info, - items, - false, - false, - false, - g_mainWin); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - - QVector names; - for (auto const & item : items) { - names.push_back(item.m_name); - } - - if (!m_file->deleteAttachments(names)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete attachments of note %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - tr("Please check the attachments folder and " - "maintain the configuration file manually."), - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } - - updateButtonState(); - - updateContent(); - } -} - -void VAttachmentList::sortItems() -{ - const QVector &attas = m_file->getAttachments(); - if (attas.size() < 2) { - return; - } - - VSortDialog dialog(tr("Sort Attachments"), - tr("Sort attachments of note %2 " - "in the configuration file.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - g_mainWin); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(1); - QStringList headers(tr("Name")); - tree->setHeaderLabels(headers); - - for (int i = 0; i < attas.size(); ++i) { - QTreeWidgetItem *item = new QTreeWidgetItem(tree, QStringList(attas[i].m_name)); - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == attas.size()); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - if (!m_file->sortAttachments(sortedIdx)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to sort attachments of note %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - } -} - -void VAttachmentList::handleListItemCommitData(QWidget *p_itemEdit) -{ - QString text = reinterpret_cast(p_itemEdit)->text(); - QListWidgetItem *item = m_attachmentList->currentItem(); - Q_ASSERT(item && item->text() == text); - - QString oldText = item->data(Qt::UserRole).toString(); - - if (oldText == text) { - return; - } - - bool legalName = true; - if (text.isEmpty()) { - legalName = false; - } else { - QRegExp reg(VUtils::c_fileNameRegExp); - if (!reg.exactMatch(text)) { - legalName = false; - } - } - - if (!legalName) { - // Recover to old name. - item->setText(oldText); - return; - } - - if (!(oldText.toLower() == text.toLower()) - && m_file->findAttachment(text, false) > -1) { - // Name conflict. - // Recover to old name. - item->setText(oldText); - } else { - if (!m_file->renameAttachment(oldText, text)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Rename Attachment"), - tr("Fail to rename attachment %2.") - .arg(g_config->c_dataTextStyle) - .arg(oldText), - "", - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - // Recover to old name. - item->setText(oldText); - } else { - // Change the data. - item->setData(Qt::UserRole, text); - } - } -} - -void VAttachmentList::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(m_attachmentList, - p_event, - this)) { - return; - } - - QWidget::keyPressEvent(p_event); -} - -bool VAttachmentList::isAcceptDrops() const -{ - return true; -} - -bool VAttachmentList::handleDragEnterEvent(QDragEnterEvent *p_event) -{ - if (!m_file) { - return false; - } - - if (p_event->mimeData()->hasFormat("text/uri-list")) { - p_event->acceptProposedAction(); - return true; - } - - return false; -} - -bool VAttachmentList::handleDropEvent(QDropEvent *p_event) -{ - if (!m_file) { - return false; - } - - init(); - - const QMimeData *mime = p_event->mimeData(); - if (mime->hasFormat("text/uri-list") && mime->hasUrls()) { - // Add attachments. - QStringList files; - QList urls = mime->urls(); - for (int i = 0; i < urls.size(); ++i) { - QString file; - if (urls[i].isLocalFile()) { - file = urls[i].toLocalFile(); - QFileInfo fi(file); - if (fi.exists() && fi.isFile()) { - file = QDir::cleanPath(fi.absoluteFilePath()); - files.append(file); - } - } - } - - if (!files.isEmpty()) { - addAttachments(files); - - updateButtonState(); - } - - p_event->acceptProposedAction(); - return true; - } - - return false; -} - -void VAttachmentList::handleAboutToShow() -{ - init(); - - updateContent(); - - checkAttachments(); -} - -void VAttachmentList::updateButtonState() const -{ - VButtonWithWidget *btn = getButton(); - Q_ASSERT(btn); - if (!btn) { - return; - } - - int numOfAttachments = -1; - if (m_file) { - numOfAttachments = m_file->getAttachments().size(); - if (numOfAttachments == 0) { - numOfAttachments = -1; - } - } - - btn->setBubbleNumber(numOfAttachments); -} - -void VAttachmentList::checkAttachments() -{ - if (!m_file) { - return; - } - - QVector missingAttas = m_file->checkAttachments(); - if (missingAttas.isEmpty()) { - return; - } - - QVector items; - for (auto const & atta : missingAttas) { - items.push_back(ConfirmItemInfo(atta, - atta, - "", - NULL)); - } - - QString text = tr("VNote detects that these attachments of note " - "%2 are missing in disk. " - "Would you like to remove them from the note?") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()); - - QString info = tr("Click \"Cancel\" to leave them untouched."); - - VConfirmDeletionDialog dialog(tr("Confirm Deleting Attachments"), - text, - info, - items, - false, - false, - false, - g_mainWin); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - - QVector names; - for (auto const & item : items) { - names.push_back(item.m_name); - } - - if (!m_file->deleteAttachments(names, true)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete attachments of note %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_file->getName()), - tr("Please check the attachments folder and " - "maintain the configuration file manually."), - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } - - updateButtonState(); - - updateContent(); - } -} - -void VAttachmentList::showEvent(QShowEvent *p_event) -{ - init(); - - QWidget::showEvent(p_event); - - processShowEvent(p_event); -} - -void VAttachmentList::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - setupUI(); - - QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this); - infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(infoShortcut, &QShortcut::activated, - this, &VAttachmentList::attachmentInfo); - - updateContent(); -} - -void VAttachmentList::attachmentInfo() -{ - QListWidgetItem *item = m_attachmentList->currentItem(); - if (!item) { - return; - } - - QString oldName = item->data(Qt::UserRole).toString(); - QString name = VUtils::promptForFileName(tr("Attachment Information"), - tr("Rename attachment (%1):").arg(oldName), - oldName, - [this](const QString &p_name) { - if (m_file->findAttachment(p_name, false) > -1) { - return true; - } - - return false; - }, - g_mainWin); - - if (name.isEmpty()) { - return; - } - - if (!m_file->renameAttachment(oldName, name)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Attachment Information"), - tr("Fail to rename attachment %2.") - .arg(g_config->c_dataTextStyle) - .arg(oldName), - "", - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } else { - // Change the data. - item->setData(Qt::UserRole, name); - item->setText(name); - } -} - -void VAttachmentList::copyAttachmentFilePath() -{ - QListWidgetItem *item = m_attachmentList->currentItem(); - if (!item) { - return; - } - - QString name = item->data(Qt::UserRole).toString(); - QString filePath = QDir(m_file->fetchAttachmentFolderPath()).filePath(name); - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(filePath); - g_mainWin->showStatusMessage(tr("Attachment file path copied %1").arg(filePath)); -} diff --git a/src/vattachmentlist.h b/src/vattachmentlist.h deleted file mode 100644 index 21a46385..00000000 --- a/src/vattachmentlist.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef VATTACHMENTLIST_H -#define VATTACHMENTLIST_H - -#include -#include -#include -#include "vnotefile.h" -#include "vbuttonwithwidget.h" -#include "lineeditdelegate.h" - -class QPushButton; -class QListWidget; -class QListWidgetItem; -class QLabel; -class VNoteFile; - - -class VAttachmentList : public QWidget, public VButtonPopupWidget -{ - Q_OBJECT -public: - explicit VAttachmentList(QWidget *p_parent = 0); - - // Need to call updateContent() to update the list. - void setFile(VNoteFile *p_file); - - bool isAcceptDrops() const Q_DECL_OVERRIDE; - - bool handleDragEnterEvent(QDragEnterEvent *p_event) Q_DECL_OVERRIDE; - - bool handleDropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE; - - void handleAboutToShow() Q_DECL_OVERRIDE; - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void addAttachment(); - - void handleContextMenuRequested(QPoint p_pos); - - void handleItemActivated(QListWidgetItem *p_item); - - void deleteSelectedItems(); - - void sortItems(); - - void handleListItemCommitData(QWidget *p_itemEdit); - - void attachmentInfo(); - - void copyAttachmentFilePath(); - -private: - void setupUI(); - - void init(); - - void fillAttachmentList(const QVector &p_attachments); - - void addAttachments(const QStringList &p_files); - - // Update the state of VButtonWithWidget. - void updateButtonState() const; - - // Check if there are attachments that do not exist in disk. - void checkAttachments(); - - // Update attachment info of m_file. - void updateContent(); - - bool m_initialized; - - QPushButton *m_addBtn; - QPushButton *m_clearBtn; - QPushButton *m_locateBtn; - QLabel *m_numLabel; - - LineEditDelegate m_listDelegate; - QListWidget *m_attachmentList; - - VNoteFile *m_file; - - static const QString c_infoShortcutSequence; -}; - -#endif // VATTACHMENTLIST_H diff --git a/src/vbuttonmenuitem.cpp b/src/vbuttonmenuitem.cpp deleted file mode 100644 index c3268277..00000000 --- a/src/vbuttonmenuitem.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "vbuttonmenuitem.h" - -#include -#include -#include -#include -#include - -VButtonMenuItem::VButtonMenuItem(QAction *p_action, QWidget *p_parent) - : QPushButton(p_parent), - m_action(p_action), - m_decorationWidth(0), - m_decorationFM(font()) -{ - init(); -} - -VButtonMenuItem::VButtonMenuItem(QAction *p_action, const QString &p_text, QWidget *p_parent) - : QPushButton(p_text, p_parent), - m_action(p_action), - m_decorationWidth(0), - m_decorationFM(font()) -{ - init(); -} - -VButtonMenuItem::VButtonMenuItem(QAction *p_action, - const QIcon &p_icon, - const QString &p_text, - const QString &p_decorationText, - const QString &p_decorationTextFg, - QWidget *p_parent) - : QPushButton(p_icon, p_text, p_parent), - m_action(p_action), - m_decorationText(p_decorationText), - m_decorationTextFg(p_decorationTextFg), - m_decorationWidth(0), - m_decorationFM(font()) -{ - init(); -} - -void VButtonMenuItem::init() -{ - QFont ft = font(); - ft.setItalic(true); - ft.setBold(true); - m_decorationFM = QFontMetrics(ft); - - connect(this, &QPushButton::clicked, - m_action, &QAction::triggered); -} - -void VButtonMenuItem::paintEvent(QPaintEvent *p_event) -{ - QPushButton::paintEvent(p_event); - - if (m_decorationWidth > 0) { - Q_ASSERT(!m_decorationText.isEmpty()); - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - QFont font = painter.font(); - font.setItalic(true); - font.setBold(true); - painter.setFont(font); - - QPen pen = painter.pen(); - pen.setColor(m_decorationTextFg); - painter.setPen(pen); - - QRect re = rect(); - re.adjust(re.width() - m_decorationWidth, 0, 0, 0); - painter.drawText(re, Qt::AlignCenter, m_decorationText); - } -} - -QSize VButtonMenuItem::sizeHint() const -{ - QSize size = QPushButton::sizeHint(); - if (!m_decorationText.isEmpty()) { - const_cast(this)->m_decorationWidth = 10 + m_decorationFM.width(m_decorationText); - size.rwidth() += m_decorationWidth; - } - - return size; -} diff --git a/src/vbuttonmenuitem.h b/src/vbuttonmenuitem.h deleted file mode 100644 index 5909f18d..00000000 --- a/src/vbuttonmenuitem.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef VBUTTONMENUITEM_H -#define VBUTTONMENUITEM_H - -#include -#include -#include - -class QAction; -class QPaintEvent; - - -class VButtonMenuItem : public QPushButton -{ - Q_OBJECT -public: - explicit VButtonMenuItem(QAction *p_action, QWidget *p_parent = nullptr); - - VButtonMenuItem(QAction *p_action, const QString &p_text, QWidget *p_parent = nullptr); - - VButtonMenuItem(QAction *p_action, - const QIcon &p_icon, - const QString &p_text, - const QString &p_decorationText = QString(), - const QString &p_decorationTextFg = QString(), - QWidget *p_parent = nullptr); - - QSize sizeHint() const Q_DECL_OVERRIDE; - -protected: - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE; - -private: - void init(); - - QAction *m_action; - - // Decoration text drawn at the right end. - QString m_decorationText; - - // Decoration text foreground. - QColor m_decorationTextFg; - - // Width in pixels of the decoration text. - int m_decorationWidth; - - QFontMetrics m_decorationFM; -}; - -#endif // VBUTTONMENUITEM_H diff --git a/src/vbuttonwithwidget.cpp b/src/vbuttonwithwidget.cpp deleted file mode 100644 index 722dfc73..00000000 --- a/src/vbuttonwithwidget.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include "vbuttonwithwidget.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -VButtonWithWidget::VButtonWithWidget(QWidget *p_widget, - QWidget *p_parent) - : QPushButton(p_parent), m_popupWidget(p_widget) -{ - init(); -} - -VButtonWithWidget::VButtonWithWidget(const QString &p_text, - QWidget *p_widget, - QWidget *p_parent) - : QPushButton(p_text, p_parent), m_popupWidget(p_widget) -{ - init(); -} - -VButtonWithWidget::VButtonWithWidget(const QIcon &p_icon, - const QString &p_text, - QWidget *p_widget, - QWidget *p_parent) - : QPushButton(p_icon, p_text, p_parent), m_popupWidget(p_widget) -{ - init(); -} - -void VButtonWithWidget::init() -{ - m_popupWidget->setParent(this); - - m_bubbleFg = QColor(Qt::white); - m_bubbleBg = QColor("#15AE67"); - - QMenu *menu = new QMenu(this); - QWidgetAction *act = new QWidgetAction(menu); - act->setDefaultWidget(m_popupWidget); - menu->addAction(act); - connect(menu, &QMenu::aboutToShow, - this, [this]() { - emit popupWidgetAboutToShow(m_popupWidget); - }); - - setMenu(menu); - - VButtonPopupWidget *popup = getButtonPopupWidget(); - if (popup) { - popup->setButton(this); - setAcceptDrops(popup->isAcceptDrops()); - connect(this, &VButtonWithWidget::popupWidgetAboutToShow, - this, [this]() { - getButtonPopupWidget()->handleAboutToShow(); - }); - } -} - -QWidget *VButtonWithWidget::getPopupWidget() const -{ - return m_popupWidget; -} - -void VButtonWithWidget::showPopupWidget() -{ - showMenu(); -} - -void VButtonWithWidget::hidePopupWidget() -{ - menu()->hide(); -} - -void VButtonWithWidget::dragEnterEvent(QDragEnterEvent *p_event) -{ - VButtonPopupWidget *popup = getButtonPopupWidget(); - Q_ASSERT(popup); - - if (popup->handleDragEnterEvent(p_event)) { - return; - } - - QPushButton::dragEnterEvent(p_event); -} - -void VButtonWithWidget::dropEvent(QDropEvent *p_event) -{ - VButtonPopupWidget *popup = getButtonPopupWidget(); - Q_ASSERT(popup); - - if (popup->handleDropEvent(p_event)) { - return; - } - - QPushButton::dropEvent(p_event); -} - -void VButtonWithWidget::paintEvent(QPaintEvent *p_event) -{ - QPushButton::paintEvent(p_event); - - if (!isEnabled() || m_bubbleStr.isEmpty()) { - return; - } - - QRect re = rect(); - int bubbleWidth = re.width() * 3.0 / 7; - int x = re.width() - bubbleWidth; - int y = 0; - QRect bubbleRect(x, y, bubbleWidth, bubbleWidth); - - QPainter painter(this); - QPainterPath bgPath; - bgPath.addEllipse(bubbleRect); - painter.fillPath(bgPath, m_bubbleBg); - - QFont font = painter.font(); - font.setPixelSize(bubbleWidth / 1.3); - painter.setFont(font); - painter.setPen(m_bubbleFg); - painter.drawText(bubbleRect, Qt::AlignCenter, m_bubbleStr); -} - -void VButtonWithWidget::setBubbleNumber(int p_num) -{ - if (p_num < 0) { - m_bubbleStr.clear(); - } else { - m_bubbleStr = QString::number(p_num); - } - - update(); -} diff --git a/src/vbuttonwithwidget.h b/src/vbuttonwithwidget.h deleted file mode 100644 index bdd3134c..00000000 --- a/src/vbuttonwithwidget.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef VBUTTONWITHWIDGET_H -#define VBUTTONWITHWIDGET_H - -#include -#include -#include -#include - -class QDragEnterEvent; -class QDropEvent; -class QPaintEvent; -class QShowEvent; -class VButtonWithWidget; - -// Abstract class for the widget used by VButtonWithWidget. -// Widget need to inherit this class if drag/drop is needed. -class VButtonPopupWidget -{ -public: - VButtonPopupWidget(QWidget *p_widget) - : m_widget(p_widget), m_btn(NULL) - { - } - - virtual bool isAcceptDrops() const = 0; - virtual bool handleDragEnterEvent(QDragEnterEvent *p_event) = 0; - virtual bool handleDropEvent(QDropEvent *p_event) = 0; - virtual void handleAboutToShow() = 0; - - void setButton(VButtonWithWidget *p_btn) - { - m_btn = p_btn; - } - - VButtonWithWidget *getButton() const - { - return m_btn; - } - -protected: - // **MUST** be called in subclass at the end of showEvent(). - void processShowEvent(QShowEvent *p_event) - { - Q_UNUSED(p_event); - m_widget->activateWindow(); - } - -private: - QWidget *m_widget; - - VButtonWithWidget *m_btn; -}; - -// A QPushButton with popup widget. -class VButtonWithWidget : public QPushButton -{ - Q_OBJECT -public: - VButtonWithWidget(QWidget *p_widget, - QWidget *p_parent = Q_NULLPTR); - - VButtonWithWidget(const QString &p_text, - QWidget *p_widget, - QWidget *p_parent = Q_NULLPTR); - - VButtonWithWidget(const QIcon &p_icon, - const QString &p_text, - QWidget *p_widget, - QWidget *p_parent = Q_NULLPTR); - - QWidget *getPopupWidget() const; - - // Set the bubble to display a number @p_num. - // @p_num: -1 to hide the bubble. - void setBubbleNumber(int p_num); - - // Set the foreground and background of the bubble. - void setBubbleColor(const QColor &p_fg, const QColor &p_bg); - -public slots: - // Show the popup widget. - void showPopupWidget(); - - void hidePopupWidget(); - -signals: - // Emit when popup widget is about to show. - void popupWidgetAboutToShow(QWidget *p_widget); - -protected: - // To accept specific drop. - void dragEnterEvent(QDragEnterEvent *p_event) Q_DECL_OVERRIDE; - - // Drop the data. - void dropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE; - - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE; - -private: - void init(); - - // Get VButtonWithWidget from m_popupWidget. - VButtonPopupWidget *getButtonPopupWidget() const; - - QWidget *m_popupWidget; - - QColor m_bubbleBg; - QColor m_bubbleFg; - - // String to display in the bubble. - // Empty to hide bubble. - QString m_bubbleStr; -}; - -inline VButtonPopupWidget *VButtonWithWidget::getButtonPopupWidget() const -{ - return dynamic_cast(m_popupWidget); -} - -inline void VButtonWithWidget::setBubbleColor(const QColor &p_fg, const QColor &p_bg) -{ - m_bubbleFg = p_fg; - m_bubbleBg = p_bg; -} -#endif // VBUTTONWITHWIDGET_H diff --git a/src/vcaptain.cpp b/src/vcaptain.cpp deleted file mode 100644 index 9b8f3694..00000000 --- a/src/vcaptain.cpp +++ /dev/null @@ -1,292 +0,0 @@ -#include -#include -#include -#include -#include "vcaptain.h" -#include "veditarea.h" -#include "vedittab.h" -#include "vfilelist.h" -#include "vnavigationmode.h" -#include "vconfigmanager.h" -#include "utils/vkeyboardlayoutmanager.h" - -extern VConfigManager *g_config; - -VCaptain::VCaptain(QWidget *p_parent) - : QWidget(p_parent), - m_mode(CaptainMode::Normal), - m_widgetBeforeCaptain(NULL), - m_nextMajorKey('a'), - m_ignoreFocusChange(false) -{ - connect(qApp, &QApplication::focusChanged, - this, &VCaptain::handleFocusChanged); - - setWindowFlags(Qt::FramelessWindowHint); - - // Make it as small as possible. This widget will stay at the top-left corner - // of VMainWindow. - resize(1, 1); - - // Register Captain mode leader key. - // This can fix the Input Method blocking issue. - m_captainModeShortcut = new QShortcut(QKeySequence(g_config->getShortcutKeySequence("CaptainMode")), - this); - m_captainModeShortcut->setContext(Qt::ApplicationShortcut); - connect(m_captainModeShortcut, &QShortcut::activated, - this, &VCaptain::trigger); - - // Register Navigation mode as Captain mode target. - registerCaptainTarget(tr("NavigationMode"), - g_config->getCaptainShortcutKeySequence("NavigationMode"), - this, - navigationModeByCaptain); -} - -QChar VCaptain::getNextMajorKey() -{ - QChar ret = m_nextMajorKey; - if (m_nextMajorKey == 'z') { - m_nextMajorKey = QChar(); - } else if (!m_nextMajorKey.isNull()) { - m_nextMajorKey = QChar(m_nextMajorKey.toLatin1() + 1); - } - return ret; -} - -void VCaptain::registerNavigationTarget(VNavigationMode *p_target) -{ - QChar key = getNextMajorKey(); - if (!key.isNull()) { - p_target->registerNavigation(key); - m_naviTargets.push_back(NaviModeTarget(p_target, true)); - } -} - -void VCaptain::handleFocusChanged(QWidget *p_old, QWidget * p_now) -{ - Q_UNUSED(p_now); - - if (p_old == this - && !m_ignoreFocusChange - && !checkMode(CaptainMode::Normal)) { - exitCaptainMode(); - } -} - -void VCaptain::trigger() -{ - if (!checkMode(CaptainMode::Normal)) { - exitCaptainMode(); - return; - } - - triggerCaptainMode(); -} - -void VCaptain::keyPressEvent(QKeyEvent *p_event) -{ - int key = p_event->key(); - Qt::KeyboardModifiers modifiers = p_event->modifiers(); - - Q_ASSERT(!checkMode(CaptainMode::Normal)); - - if (VUtils::isMetaKey(key)) { - QWidget::keyPressEvent(p_event); - return; - } - - key = VKeyboardLayoutManager::mapKey(key); - - if (handleKeyPress(key, modifiers)) { - p_event->accept(); - } else { - QWidget::keyPressEvent(p_event); - } -} - -bool VCaptain::handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers) -{ - bool ret = true; - - m_ignoreFocusChange = true; - - if (checkMode(CaptainMode::Navigation)) { - ret = handleKeyPressNavigationMode(p_key, p_modifiers); - m_ignoreFocusChange = false; - return ret; - } - - ret = handleKeyPressCaptainMode(p_key, p_modifiers); - m_ignoreFocusChange = false; - return ret; -} - -bool VCaptain::handleKeyPressNavigationMode(int p_key, - Qt::KeyboardModifiers /* p_modifiers */) -{ - Q_ASSERT(m_mode == CaptainMode::Navigation); - bool hasConsumed = false; - bool pending = false; - for (auto &target : m_naviTargets) { - if (hasConsumed) { - target.m_available = false; - target.m_target->hideNavigation(); - continue; - } - if (target.m_available) { - bool succeed = false; - // May change focus, so we need to ignore focus change here. - bool consumed = target.m_target->handleKeyNavigation(p_key, succeed); - if (consumed) { - hasConsumed = true; - if (succeed) { - // Exit. - m_widgetBeforeCaptain = NULL; - } else { - // Consumed but not succeed. Need more keys. - pending = true; - } - } else { - // Do not ask this target any more. - target.m_available = false; - target.m_target->hideNavigation(); - } - } - } - - if (pending) { - return true; - } - - exitCaptainMode(); - return true; -} - -void VCaptain::triggerNavigationMode() -{ - setMode(CaptainMode::Navigation); - - for (auto &target : m_naviTargets) { - target.m_available = true; - target.m_target->showNavigation(); - } -} - -void VCaptain::exitNavigationMode() -{ - setMode(CaptainMode::Normal); - - for (auto &target : m_naviTargets) { - target.m_available = true; - target.m_target->hideNavigation(); - } -} - -void VCaptain::restoreFocus() -{ - if (m_widgetBeforeCaptain) { - m_widgetBeforeCaptain->setFocus(); - m_widgetBeforeCaptain = NULL; - } -} - -void VCaptain::exitCaptainMode() -{ - if (checkMode(CaptainMode::Normal)) { - return; - } else if (checkMode(CaptainMode::Navigation)) { - exitNavigationMode(); - } - - setMode(CaptainMode::Normal); - m_ignoreFocusChange = false; - - restoreFocus(); - - emit captainModeChanged(false); -} - -bool VCaptain::registerCaptainTarget(const QString &p_name, - const QString &p_key, - void *p_target, - CaptainFunc p_func) -{ - if (p_key.isEmpty()) { - return false; - } - - QString normKey = QKeySequence(p_key).toString(); - - if (m_captainTargets.contains(normKey)) { - return false; - } - - CaptainModeTarget target(p_name, - normKey, - p_target, - p_func); - m_captainTargets.insert(normKey, target); - - qDebug() << "registered:" << target.toString() << normKey; - - return true; -} - -void VCaptain::triggerCaptainTarget(const QString &p_key) -{ - auto it = m_captainTargets.find(p_key); - if (it == m_captainTargets.end()) { - return; - } - - const CaptainModeTarget &target = it.value(); - - qDebug() << "triggered:" << target.toString(); - - CaptainData data(m_widgetBeforeCaptain); - if (!target.m_function(target.m_target, (void *)&data)) { - m_widgetBeforeCaptain = NULL; - } -} - -bool VCaptain::navigationModeByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VCaptain *obj = static_cast(p_target); - obj->triggerNavigationMode(); - return true; -} - -void VCaptain::triggerCaptainMode() -{ - m_widgetBeforeCaptain = QApplication::focusWidget(); - - m_ignoreFocusChange = false; - - setMode(CaptainMode::Pending); - - emit captainModeChanged(true); - - // Focus to listen pending key press. - setFocus(); -} - -bool VCaptain::handleKeyPressCaptainMode(int p_key, - Qt::KeyboardModifiers p_modifiers) -{ - Q_ASSERT(checkMode(CaptainMode::Pending)); - QString normKey = QKeySequence(p_key | p_modifiers).toString(); - triggerCaptainTarget(normKey); - - if (!checkMode(CaptainMode::Navigation)) { - exitCaptainMode(); - } - - return true; -} - -void VCaptain::setCaptainModeEnabled(bool p_enabled) -{ - m_captainModeShortcut->setEnabled(p_enabled); -} diff --git a/src/vcaptain.h b/src/vcaptain.h deleted file mode 100644 index c92b1658..00000000 --- a/src/vcaptain.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef VCAPTAIN_H -#define VCAPTAIN_H - -#include - -#include -#include -#include - -class QKeyEvent; -class VNavigationMode; -class QShortcut; - -// bool func(void *p_target, void *p_data); -// Return true if the target needs to restore focus by the Captain. -typedef std::function CaptainFunc; - - -// Will be passed to CaptainFunc as the data. -struct CaptainData -{ - CaptainData(QWidget *p_focusWidgetBeforeCaptain) - : m_focusWidgetBeforeCaptain(p_focusWidgetBeforeCaptain) - { - } - - QWidget *m_focusWidgetBeforeCaptain; -}; - - -class VCaptain : public QWidget -{ - Q_OBJECT -public: - explicit VCaptain(QWidget *p_parent); - - // Register a target for Navigation mode. - void registerNavigationTarget(VNavigationMode *p_target); - - // Register a target for Captain mode. - bool registerCaptainTarget(const QString &p_name, - const QString &p_key, - void *p_target, - CaptainFunc p_func); - - void setCaptainModeEnabled(bool p_enabled); - - void exitCaptainMode(); - -signals: - // Emit when mode changed. - void captainModeChanged(bool p_captainMode); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - // Exit Navigation mode if focus lost. - void handleFocusChanged(QWidget *p_old, QWidget *p_new); - -private: - // A widget target for Navigation mode. - struct NaviModeTarget { - NaviModeTarget() - : m_target(nullptr), m_available(false) - { - } - - NaviModeTarget(VNavigationMode *p_target, bool p_available) - : m_target(p_target), m_available(p_available) - { - } - - VNavigationMode *m_target; - bool m_available; - }; - - // Modes. - enum class CaptainMode { - Normal = 0, - Pending, - Navigation - }; - - struct CaptainModeTarget { - CaptainModeTarget() - : m_target(nullptr), m_function(nullptr) - { - } - - CaptainModeTarget(const QString &p_name, - const QString &p_key, - void *p_target, - CaptainFunc p_func) - : m_name(p_name), - m_key(p_key), - m_target(p_target), - m_function(p_func) - { - } - - QString toString() const - { - return QString("Captain mode target %1 key[%2]").arg(m_name).arg(m_key); - } - - // Name to display. - QString m_name; - - // Key sequence to trigger this target. - // This is the sub-sequence after leader key. - QString m_key; - - // Target. - void *m_target; - - // Function to call when this target is trigger. - CaptainFunc m_function; - }; - - // Restore the focus to m_widgetBeforeCaptain. - void restoreFocus(); - - // Return true if finish handling the event; otherwise, let the base widget - // to handle it. - bool handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers); - - // Handle key press event in Navigation mode. - bool handleKeyPressNavigationMode(int p_key, - Qt::KeyboardModifiers p_modifiers); - - // Handle key press event in Captain mode. - bool handleKeyPressCaptainMode(int p_key, - Qt::KeyboardModifiers p_modifiers); - - // Get next major key to use for Navigation mode. - QChar getNextMajorKey(); - - // Trigger navigation mode to ask all targets show themselves. - void triggerNavigationMode(); - - // Exit navigation mode to ask all targets hide themselves. - void exitNavigationMode(); - - // Called to trigger the action of a Captain target which has - // registered @p_key. - void triggerCaptainTarget(const QString &p_key); - - void setMode(CaptainMode p_mode); - - bool checkMode(CaptainMode p_mode) const; - - void trigger(); - - void triggerCaptainMode(); - - static bool navigationModeByCaptain(void *p_target, void *p_data); - - // Used to indicate current mode. - CaptainMode m_mode; - - // The widget which has the focus before entering Captain mode. - QWidget *m_widgetBeforeCaptain; - - // Targets for Navigation mode. - QVector m_naviTargets; - - QChar m_nextMajorKey; - - // Targets for Captain mode. - // Key(lower) -> CaptainModeTarget. - QHash m_captainTargets; - - // Ignore focus change during handling Captain and Navigation target actions. - bool m_ignoreFocusChange; - - QShortcut *m_captainModeShortcut; -}; - -inline void VCaptain::setMode(CaptainMode p_mode) -{ - m_mode = p_mode; -} - -inline bool VCaptain::checkMode(CaptainMode p_mode) const -{ - return m_mode == p_mode; -} -#endif // VCAPTAIN_H diff --git a/src/vcart.cpp b/src/vcart.cpp deleted file mode 100644 index 2067ee74..00000000 --- a/src/vcart.cpp +++ /dev/null @@ -1,321 +0,0 @@ -#include "vcart.h" - -#include - -#include "utils/viconutils.h" -#include "utils/vutils.h" -#include "vmainwindow.h" -#include "vnote.h" -#include "vnotefile.h" -#include "vlistwidget.h" -#include "dialog/vsortdialog.h" - -extern VMainWindow *g_mainWin; - -extern VNote *g_vnote; - -VCart::VCart(QWidget *p_parent) - : QWidget(p_parent), - m_initialized(false), - m_uiInitialized(false) -{ -} - -void VCart::setupUI() -{ - if (m_uiInitialized) { - return; - } - - m_uiInitialized = true; - - m_clearBtn = new QPushButton(VIconUtils::buttonDangerIcon(":/resources/icons/clear_cart.svg"), ""); - m_clearBtn->setToolTip(tr("Clear")); - m_clearBtn->setProperty("FlatBtn", true); - connect(m_clearBtn, &QPushButton::clicked, - this, [this]() { - if (m_itemList->count() > 0) { - int ret = VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Are you sure to clear Cart?"), - "", - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - g_mainWin, - MessageBoxType::Danger); - if (ret == QMessageBox::Ok) { - m_itemList->clearAll(); - updateNumberLabel(); - } - } - }); - - m_numLabel = new QLabel(); - - QHBoxLayout *btnLayout = new QHBoxLayout; - btnLayout->addWidget(m_clearBtn); - btnLayout->addStretch(); - btnLayout->addWidget(m_numLabel); - btnLayout->setContentsMargins(0, 0, 0, 0); - - m_itemList = new VListWidget(); - m_itemList->setAttribute(Qt::WA_MacShowFocusRect, false); - m_itemList->setContextMenuPolicy(Qt::CustomContextMenu); - m_itemList->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_itemList->setDragDropMode(QAbstractItemView::InternalMove); - connect(m_itemList, &QListWidget::customContextMenuRequested, - this, &VCart::handleContextMenuRequested); - connect(m_itemList, &QListWidget::itemActivated, - this, &VCart::openItem); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(btnLayout); - mainLayout->addWidget(m_itemList); - mainLayout->setContentsMargins(3, 0, 3, 0); - - setLayout(mainLayout); -} - -void VCart::handleContextMenuRequested(QPoint p_pos) -{ - QListWidgetItem *item = m_itemList->itemAt(p_pos); - QMenu menu(this); - menu.setToolTipsVisible(true); - - if (item) { - QAction *openAct = new QAction(tr("&Open"), &menu); - openAct->setToolTip(tr("Open selected notes")); - connect(openAct, &QAction::triggered, - this, &VCart::openSelectedItems); - menu.addAction(openAct); - - if (m_itemList->selectedItems().size() == 1) { - QAction *locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"), - tr("&Locate To Folder"), - &menu); - locateAct->setToolTip(tr("Locate the folder of current note")); - connect(locateAct, &QAction::triggered, - this, &VCart::locateCurrentItem); - menu.addAction(locateAct); - } - - QAction *deleteAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_cart_item.svg"), - tr("&Delete"), - &menu); - deleteAct->setToolTip(tr("Delete selected items from Cart")); - connect(deleteAct, &QAction::triggered, - this, &VCart::deleteSelectedItems); - menu.addAction(deleteAct); - } - - if (m_itemList->count() == 0) { - return; - } - - if (!menu.actions().isEmpty()) { - menu.addSeparator(); - } - - QAction *sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - &menu); - sortAct->setToolTip(tr("Sort items in Cart")); - connect(sortAct, &QAction::triggered, - this, &VCart::sortItems); - menu.addAction(sortAct); - - menu.exec(m_itemList->mapToGlobal(p_pos)); -} - -void VCart::addFile(const QString &p_filePath) -{ - init(); - - if (p_filePath.isEmpty() - || findFileInCart(p_filePath) != -1) { - return; - } - - addItem(p_filePath); -} - -int VCart::findFileInCart(const QString &p_file) const -{ - int cnt = m_itemList->count(); - for (int i = 0; i < cnt; ++i) { - if (VUtils::equalPath(m_itemList->item(i)->data(Qt::UserRole).toString(), - p_file)) { - return i; - } - } - - return -1; -} - -void VCart::addItem(const QString &p_path) -{ - QListWidgetItem *item = new QListWidgetItem(VUtils::fileNameFromPath(p_path)); - item->setToolTip(p_path); - item->setData(Qt::UserRole, p_path); - - m_itemList->addItem(item); - updateNumberLabel(); -} - -void VCart::deleteSelectedItems() -{ - QList selectedItems = m_itemList->selectedItems(); - for (auto it : selectedItems) { - delete it; - } -} - -void VCart::openSelectedItems() const -{ - QStringList files; - QList selectedItems = m_itemList->selectedItems(); - for (auto it : selectedItems) { - files << getFilePath(it); - } - - if (!files.isEmpty()) { - g_mainWin->openFiles(files); - } -} - -void VCart::locateCurrentItem() -{ - auto item = m_itemList->currentItem(); - if (!item) { - return; - } - - VFile *file = g_vnote->getInternalFile(getFilePath(item)); - if (file) { - g_mainWin->locateFile(file); - } -} - -void VCart::openItem(const QListWidgetItem *p_item) const -{ - if (!p_item) { - return; - } - - QStringList files; - files << getFilePath(p_item); - g_mainWin->openFiles(files); -} - -QString VCart::getFilePath(const QListWidgetItem *p_item) const -{ - return p_item->data(Qt::UserRole).toString(); -} - -int VCart::count() const -{ - const_cast(this)->init(); - - return m_itemList->count(); -} - -QVector VCart::getFiles() const -{ - const_cast(this)->init(); - - QVector files; - int cnt = m_itemList->count(); - for (int i = 0; i < cnt; ++i) { - files.append(getFilePath(m_itemList->item(i))); - } - - return files; -} - -void VCart::sortItems() -{ - if (m_itemList->count() < 2) { - return; - } - - VSortDialog dialog(tr("Sort Cart"), - tr("Sort items in Cart."), - this); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(1); - QStringList headers(tr("Name")); - tree->setHeaderLabels(headers); - - int cnt = m_itemList->count(); - for (int i = 0; i < cnt; ++i) { - QListWidgetItem *it = m_itemList->item(i); - QTreeWidgetItem *item = new QTreeWidgetItem(tree, - QStringList(it->text())); - item->setToolTip(0, getFilePath(it)); - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == cnt); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - VListWidget::sortListWidget(m_itemList, sortedIdx); - } -} - -void VCart::updateNumberLabel() const -{ - int cnt = m_itemList->count(); - m_numLabel->setText(tr("%1 %2").arg(cnt) - .arg(cnt > 1 ? tr("Items") : tr("Item"))); -} - -void VCart::showNavigation() -{ - setupUI(); - - VNavigationMode::showNavigation(m_itemList); -} - -bool VCart::handleKeyNavigation(int p_key, bool &p_succeed) -{ - setupUI(); - - return VNavigationMode::handleKeyNavigation(m_itemList, - p_key, - p_succeed); -} - -void VCart::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - setupUI(); - updateNumberLabel(); -} - -void VCart::showEvent(QShowEvent *p_event) -{ - init(); - - QWidget::showEvent(p_event); -} - -void VCart::focusInEvent(QFocusEvent *p_event) -{ - init(); - - QWidget::focusInEvent(p_event); - m_itemList->setFocus(); -} diff --git a/src/vcart.h b/src/vcart.h deleted file mode 100644 index d9c4ad91..00000000 --- a/src/vcart.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef VCART_H -#define VCART_H - -#include -#include - -#include "vnavigationmode.h" - -class QPushButton; -class VListWidget; -class QListWidgetItem; -class QLabel; - -class VCart : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VCart(QWidget *p_parent = nullptr); - - void addFile(const QString &p_filePath); - - int count() const; - - QVector getFiles() const; - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void handleContextMenuRequested(QPoint p_pos); - - void deleteSelectedItems(); - - void openSelectedItems() const; - - void openItem(const QListWidgetItem *p_item) const; - - void locateCurrentItem(); - - void sortItems(); - -private: - void setupUI(); - - void init(); - - bool m_initialized; - - bool m_uiInitialized; - - // Return index of item. - int findFileInCart(const QString &p_file) const; - - void addItem(const QString &p_path); - - QString getFilePath(const QListWidgetItem *p_item) const; - - void updateNumberLabel() const; - - QPushButton *m_clearBtn; - QLabel *m_numLabel; - VListWidget *m_itemList; -}; - -#endif // VCART_H diff --git a/src/vcodeblockhighlighthelper.cpp b/src/vcodeblockhighlighthelper.cpp deleted file mode 100644 index c161a3ec..00000000 --- a/src/vcodeblockhighlighthelper.cpp +++ /dev/null @@ -1,307 +0,0 @@ -#include "vcodeblockhighlighthelper.h" - -#include -#include - -#include "vdocument.h" -#include "utils/vutils.h" -#include "pegmarkdownhighlighter.h" - -VCodeBlockHighlightHelper::VCodeBlockHighlightHelper(PegMarkdownHighlighter *p_highlighter, - VDocument *p_vdoc, - MarkdownConverterType p_type) - : QObject(p_highlighter), - m_highlighter(p_highlighter), - m_vdocument(p_vdoc), - m_type(p_type), - m_timeStamp(0) -{ - connect(m_highlighter, &PegMarkdownHighlighter::codeBlocksUpdated, - this, &VCodeBlockHighlightHelper::handleCodeBlocksUpdated); - connect(m_vdocument, &VDocument::textHighlighted, - this, &VCodeBlockHighlightHelper::handleTextHighlightResult); - - // Web side is ready for code block highlight. - connect(m_vdocument, &VDocument::readyToHighlightText, - m_highlighter, &PegMarkdownHighlighter::updateHighlight); -} - -QString VCodeBlockHighlightHelper::unindentCodeBlock(const QString &p_text) -{ - if (p_text.isEmpty()) { - return p_text; - } - - QStringList lines = p_text.split('\n'); - Q_ASSERT(lines[0].trimmed().startsWith("```") || lines[0].trimmed().startsWith("~~~")); - Q_ASSERT(lines.size() > 1); - - QRegExp regExp("(^\\s*)"); - regExp.indexIn(lines[0]); - V_ASSERT(regExp.captureCount() == 1); - int nrSpaces = regExp.capturedTexts()[1].size(); - - if (nrSpaces == 0) { - return p_text; - } - - QString res = lines[0].right(lines[0].size() - nrSpaces); - for (int i = 1; i < lines.size(); ++i) { - const QString &line = lines[i]; - - int idx = 0; - while (idx < nrSpaces && idx < line.size() && line[idx].isSpace()) { - ++idx; - } - res = res + "\n" + line.right(line.size() - idx); - } - - return res; -} - -void VCodeBlockHighlightHelper::handleCodeBlocksUpdated(TimeStamp p_timeStamp, - const QVector &p_codeBlocks) -{ - if (!m_vdocument->isReadyToHighlight()) { - // Immediately return empty results. - QVector emptyRes; - for (int i = 0; i < p_codeBlocks.size(); ++i) { - updateHighlightResults(p_timeStamp, 0, emptyRes); - } - - return; - } - - m_timeStamp = p_timeStamp; - m_codeBlocks = p_codeBlocks; - for (int i = 0; i < m_codeBlocks.size(); ++i) { - const VCodeBlock &block = m_codeBlocks[i]; - auto it = m_cache.find(block.m_text); - if (it != m_cache.end()) { - // Hit cache. - qDebug() << "code block highlight hit cache" << p_timeStamp << i; - it.value().m_timeStamp = p_timeStamp; - updateHighlightResults(p_timeStamp, block.m_startPos, it.value().m_units); - } else { - QString unindentedText = unindentCodeBlock(block.m_text); - m_vdocument->highlightTextAsync(unindentedText, i, p_timeStamp); - } - } -} - -void VCodeBlockHighlightHelper::handleTextHighlightResult(const QString &p_html, - int p_id, - unsigned long long p_timeStamp) -{ - // Abandon obsolete result. - if (m_timeStamp != p_timeStamp) { - return; - } - - parseHighlightResult(p_timeStamp, p_id, p_html); -} - -static void revertEscapedHtml(QString &p_html) -{ - p_html.replace(">", ">").replace("<", "<").replace("&", "&"); -} - -// Search @p_tokenStr in @p_text from p_index. Spaces after `\n` will not make -// a difference in the match. The matched range will be returned as -// [@p_start, @p_end]. Update @p_index to @p_end + 1. -// Set @p_start and @p_end to -1 to indicate mismatch. -static void matchTokenRelaxed(const QString &p_text, const QString &p_tokenStr, - int &p_index, int &p_start, int &p_end) -{ - QString regStr = QRegExp::escape(p_tokenStr); - - // Remove the leading spaces. - int nonSpaceIdx = 0; - while (nonSpaceIdx < regStr.size() && regStr[nonSpaceIdx].isSpace()) { - ++nonSpaceIdx; - } - - if (nonSpaceIdx > 0 && nonSpaceIdx < regStr.size()) { - regStr.remove(0, nonSpaceIdx); - } - - // Do not replace the ending '\n'. - regStr.replace(QRegExp("\n(?!$)"), "\\s+"); - - QRegExp regExp(regStr); - p_start = p_text.indexOf(regExp, p_index); - if (p_start == -1) { - p_end = -1; - return; - } - - p_end = p_start + regExp.matchedLength() - 1; - p_index = p_end + 1; -} - -// For now, we could only handle code blocks outside the list. -void VCodeBlockHighlightHelper::parseHighlightResult(TimeStamp p_timeStamp, - int p_idx, - const QString &p_html) -{ - const VCodeBlock &block = m_codeBlocks.at(p_idx); - int startPos = block.m_startPos; - QString text = block.m_text; - - QVector hlUnits; - - bool failed = true; - - QXmlStreamReader xml(p_html); - - // Must have a fenced line at the front. - // textIndex is the start index in the code block text to search for. - int textIndex = text.indexOf('\n'); - if (textIndex == -1) { - goto exit; - } - ++textIndex; - - if (xml.readNextStartElement()) { - if (xml.name() != "pre") { - goto exit; - } - - if (!xml.readNextStartElement()) { - goto exit; - } - - if (xml.name() != "code") { - goto exit; - } - - while (xml.readNext()) { - if (xml.isCharacters()) { - // Revert the HTML escape to match. - QString tokenStr = xml.text().toString(); - revertEscapedHtml(tokenStr); - - int start, end; - matchTokenRelaxed(text, tokenStr, textIndex, start, end); - if (start == -1) { - failed = true; - goto exit; - } - } else if (xml.isStartElement()) { - if (xml.name() != "span") { - failed = true; - goto exit; - } - if (!parseSpanElement(xml, text, textIndex, hlUnits)) { - failed = true; - goto exit; - } - } else if (xml.isEndElement()) { - if (xml.name() != "code" && xml.name() != "pre") { - failed = true; - } else { - failed = false; - } - goto exit; - } else { - failed = true; - goto exit; - } - } - } - -exit: - // Pass result back to highlighter. - // Abandon obsolete result. - if (m_timeStamp != p_timeStamp) { - return; - } - - if (xml.hasError() || failed) { - qWarning() << "fail to parse highlighted result" - << "stamp:" << p_timeStamp << "index:" << p_idx << p_html; - hlUnits.clear(); - } - - // Add it to cache. - addToHighlightCache(text, p_timeStamp, hlUnits); - - updateHighlightResults(p_timeStamp, startPos, hlUnits); -} - -void VCodeBlockHighlightHelper::updateHighlightResults(TimeStamp p_timeStamp, - int p_startPos, - QVector p_units) -{ - for (int i = 0; i < p_units.size(); ++i) { - p_units[i].m_position += p_startPos; - } - - // We need to call this function anyway to trigger the rehighlight. - m_highlighter->setCodeBlockHighlights(p_timeStamp, p_units); -} - -bool VCodeBlockHighlightHelper::parseSpanElement(QXmlStreamReader &p_xml, - const QString &p_text, - int &p_index, - QVector &p_units) -{ - int unitStart = p_index; - QString style = p_xml.attributes().value("class").toString(); - - while (p_xml.readNext()) { - if (p_xml.isCharacters()) { - // Revert the HTML escape to match. - QString tokenStr = p_xml.text().toString(); - revertEscapedHtml(tokenStr); - - int start, end; - matchTokenRelaxed(p_text, tokenStr, p_index, start, end); - if (start == -1) { - return false; - } - } else if (p_xml.isStartElement()) { - if (p_xml.name() != "span") { - return false; - } - - // Sub-span. - if (!parseSpanElement(p_xml, p_text, p_index, p_units)) { - return false; - } - } else if (p_xml.isEndElement()) { - if (p_xml.name() != "span") { - return false; - } - - // Got a complete span. Use relative position here. - HLUnitPos unit(unitStart, p_index - unitStart, style); - p_units.append(unit); - return true; - } else { - return false; - } - } - return false; -} - -void VCodeBlockHighlightHelper::addToHighlightCache(const QString &p_text, - TimeStamp p_timeStamp, - const QVector &p_units) -{ - const int c_maxEntries = 100; - const TimeStamp c_maxTimeStampSpan = 3; - if (m_cache.size() >= c_maxEntries) { - // Remove the oldest one. - TimeStamp ts = p_timeStamp - c_maxTimeStampSpan; - for (auto it = m_cache.begin(); it != m_cache.end();) { - if (it.value().m_timeStamp < ts) { - it = m_cache.erase(it); - } else { - ++it; - } - } - } - - m_cache.insert(p_text, HLResult(p_timeStamp, p_units)); -} diff --git a/src/vcodeblockhighlighthelper.h b/src/vcodeblockhighlighthelper.h deleted file mode 100644 index cba7c72c..00000000 --- a/src/vcodeblockhighlighthelper.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef VCODEBLOCKHIGHLIGHTHELPER_H -#define VCODEBLOCKHIGHLIGHTHELPER_H - -#include -#include -#include -#include -#include - -#include "vconfigmanager.h" - -class VDocument; -class PegMarkdownHighlighter; - -class VCodeBlockHighlightHelper : public QObject -{ - Q_OBJECT -public: - VCodeBlockHighlightHelper(PegMarkdownHighlighter *p_highlighter, - VDocument *p_vdoc, MarkdownConverterType p_type); - - // @p_text: text of fenced code block. - // Get the indent level of the first line (fence) and unindent the whole block - // to make the fence at the highest indent level. - // This operation is to make sure JS could handle the code block correctly - // without any context. - static QString unindentCodeBlock(const QString &p_text); - -private slots: - void handleCodeBlocksUpdated(TimeStamp p_timeStamp, const QVector &p_codeBlocks); - - void handleTextHighlightResult(const QString &p_html, int p_id, unsigned long long p_timeStamp); - -private: - struct HLResult - { - HLResult() - : m_timeStamp(0) - { - } - - HLResult(TimeStamp p_timeStamp, const QVector &p_units) - : m_timeStamp(p_timeStamp), - m_units(p_units) - { - } - - TimeStamp m_timeStamp; - - QVector m_units; - }; - - void parseHighlightResult(TimeStamp p_timeStamp, int p_idx, const QString &p_html); - - // @p_text: the raw text of the code block; - // @p_index: the start index of the span element within @p_text; - // @p_units: all the highlight units of this code block; - bool parseSpanElement(QXmlStreamReader &p_xml, - const QString &p_text, int &p_index, - QVector &p_units); - - void updateHighlightResults(TimeStamp p_timeStamp, int p_startPos, QVector p_units); - - void addToHighlightCache(const QString &p_text, - TimeStamp p_timeStamp, - const QVector &p_units); - - PegMarkdownHighlighter *m_highlighter; - VDocument *m_vdocument; - MarkdownConverterType m_type; - - TimeStamp m_timeStamp; - - QVector m_codeBlocks; - - // Cache for highlight result, using the code block text as key. - // The HLResult has relative position only. - QHash m_cache; -}; - -#endif // VCODEBLOCKHIGHLIGHTHELPER_H diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp deleted file mode 100644 index 785d5b39..00000000 --- a/src/vconfigmanager.cpp +++ /dev/null @@ -1,1801 +0,0 @@ -#include "vconfigmanager.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils/vutils.h" -#include "vstyleparser.h" -#include "vpalette.h" - -const QString VConfigManager::orgName = QString("vnote"); - -const QString VConfigManager::appName = QString("vnote"); - -const QString VConfigManager::c_version = QString("2.10"); - -const QString VConfigManager::c_dirConfigFile = QString("_vnote.json"); - -const QString VConfigManager::c_defaultConfigFilePath = QString(":/resources/vnote.ini"); - -const QString VConfigManager::c_defaultConfigFile = QString("vnote.ini"); - -const QString VConfigManager::c_sessionConfigFile = QString("session.ini"); - -const QString VConfigManager::c_snippetConfigFile = QString("snippet.json"); - -const QString VConfigManager::c_keyboardLayoutConfigFile = QString("keyboard_layouts.ini"); - -const QString VConfigManager::c_styleConfigFolder = QString("styles"); - -const QString VConfigManager::c_themeConfigFolder = QString("themes"); - -const QString VConfigManager::c_codeBlockStyleConfigFolder = QString("codeblock_styles"); - -const QString VConfigManager::c_templateConfigFolder = QString("templates"); - -const QString VConfigManager::c_snippetConfigFolder = QString("snippets"); - -const QString VConfigManager::c_resourceConfigFolder = QString("resources"); - -const QString VConfigManager::c_warningTextStyle = QString("color: #C9302C; font: bold"); - -const QString VConfigManager::c_dataTextStyle = QString("font: bold"); - -const QString VConfigManager::c_vnoteNotebookFolderName = QString("vnote_notebooks"); - -const QString VConfigManager::c_exportFolderName = QString("vnote_exports"); - -VConfigManager::VConfigManager(QObject *p_parent) - : QObject(p_parent), - m_noteListViewOrder(-1), - m_explorerCurrentIndex(-1), - m_hasReset(false), - userSettings(NULL), - defaultSettings(NULL), - m_sessionSettings(NULL) -{ -} - -void VConfigManager::initialize() -{ - initSettings(); - - checkVersion(); - - initThemes(); - - initEditorStyles(); - - initCssStyles(); - - initCodeBlockCssStyles(); - - m_githubPersonalAccessToken = getConfigFromSettings("global", "github_personal_access_token").toString(); - m_githubReposName = getConfigFromSettings("global", "github_repos_name").toString(); - m_githubUserName = getConfigFromSettings("global", "github_user_name").toString(); - m_githubKeepImgScale = getConfigFromSettings("global", "github_keep_img_scale").toBool(); - m_githubDoNotReplaceLink = getConfigFromSettings("global", "github_do_not_replace_link").toBool(); - - m_giteePersonalAccessToken = getConfigFromSettings("global", "gitee_personal_access_token").toString(); - m_giteeReposName = getConfigFromSettings("global", "gitee_repos_name").toString(); - m_giteeUserName = getConfigFromSettings("global", "gitee_user_name").toString(); - m_giteeKeepImgScale = getConfigFromSettings("global", "gitee_keep_img_scale").toBool(); - m_giteeDoNotReplaceLink = getConfigFromSettings("global", "gitee_do_not_replace_link").toBool(); - - m_wechatAppid = getConfigFromSettings("global", "wechat_appid").toString(); - m_wechatSecret = getConfigFromSettings("global", "wechat_secret").toString(); - m_markdown2WechatToolUrl = getConfigFromSettings("global", "wechat_markdown_to_wechat_tool_url").toString(); - m_wechatKeepImgScale = getConfigFromSettings("global", "wechat_keep_img_scale").toBool(); - m_wechatDoNotReplaceLink = getConfigFromSettings("global", "wechat_do_not_replace_link").toBool(); - - m_tencentAccessDomainName = getConfigFromSettings("global", "tencent_access_domain_name").toString(); - m_tencentSecretId = getConfigFromSettings("global", "tencent_secret_id").toString(); - m_tencentSecretKey = getConfigFromSettings("global", "tencent_secret_key").toString(); - m_tencentKeepImgScale = getConfigFromSettings("global", "tencent_keep_img_scale").toBool(); - m_tencentDoNotReplaceLink = getConfigFromSettings("global", "tencent_do_not_replace_link").toBool(); - - m_theme = getConfigFromSettings("global", "theme").toString(); - - m_editorStyle = getConfigFromSettings("global", "editor_style").toString(); - - m_cssStyle = getConfigFromSettings("global", "css_style").toString(); - - m_codeBlockCssStyle = getConfigFromSettings("global", "code_block_css_style").toString(); - - m_defaultEditPalette = QTextEdit().palette(); - - markdownExtensions = hoedown_extensions(HOEDOWN_EXT_TABLES | HOEDOWN_EXT_FENCED_CODE | - HOEDOWN_EXT_HIGHLIGHT | HOEDOWN_EXT_AUTOLINK | - HOEDOWN_EXT_QUOTE | HOEDOWN_EXT_MATH | HOEDOWN_EXT_MATH_EXPLICIT); - mdConverterType = (MarkdownConverterType)getConfigFromSettings("global", "markdown_converter").toInt(); - - tabStopWidth = getConfigFromSettings("global", "tab_stop_width").toInt(); - isExpandTab = getConfigFromSettings("global", "is_expand_tab").toBool(); - m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool(); - m_highlightSelectedWord = getConfigFromSettings("global", "highlight_selected_word").toBool(); - m_highlightSearchedWord = getConfigFromSettings("global", "highlight_searched_word").toBool(); - - readCustomColors(); - - curBackgroundColor = getConfigFromSettings("global", "current_background_color").toString(); - - updateEditStyle(); - - curRenderBackgroundColor = getConfigFromSettings("global", - "current_render_background_color").toString(); - - m_findCaseSensitive = getConfigFromSettings("global", - "find_case_sensitive").toBool(); - m_findWholeWordOnly = getConfigFromSettings("global", - "find_whole_word_only").toBool(); - m_findRegularExpression = getConfigFromSettings("global", - "find_regular_expression").toBool(); - m_findIncrementalSearch = getConfigFromSettings("global", - "find_incremental_search").toBool(); - - m_language = getConfigFromSettings("global", "language").toString(); - - m_enableMermaid = getConfigFromSettings("global", "enable_mermaid").toBool(); - - m_enableFlowchart = getConfigFromSettings("global", "enable_flowchart").toBool(); - - m_enableMathjax = getConfigFromSettings("global", "enable_mathjax").toBool(); - - m_webZoomFactor = getConfigFromSettings("global", "web_zoom_factor").toReal(); - if (!isCustomWebZoomFactor()) { - // Calculate the zoom factor based on DPI. - m_webZoomFactor = VUtils::calculateScaleFactor(); - qDebug() << "set WebZoomFactor to" << m_webZoomFactor; - } - - m_editorZoomDelta = getConfigFromSettings("global", "editor_zoom_delta").toInt(); - - m_enableCodeBlockHighlight = getConfigFromSettings("global", - "enable_code_block_highlight").toBool(); - - m_enablePreviewImages = getConfigFromSettings("global", - "enable_preview_images").toBool(); - - m_enablePreviewImageConstraint = getConfigFromSettings("global", - "enable_preview_image_constraint").toBool(); - - m_enableImageConstraint = getConfigFromSettings("global", - "enable_image_constraint").toBool(); - - m_enableImageCaption = getConfigFromSettings("global", - "enable_image_caption").toBool(); - - m_imageFolder = getConfigFromSettings("global", - "image_folder").toString(); - - m_imageFolderExt = getConfigFromSettings("global", - "external_image_folder").toString(); - - m_attachmentFolder = getConfigFromSettings("global", - "attachment_folder").toString(); - if (m_attachmentFolder.isEmpty()) { - // Reset the default folder. - m_attachmentFolder = resetDefaultConfig("global", "attachment_folder").toString(); - } - - m_enableTrailingSpaceHighlight = getConfigFromSettings("global", - "enable_trailing_space_highlight").toBool(); - - m_editorLineNumber = getConfigFromSettings("global", - "editor_line_number").toInt(); - - m_minimizeToSystemTray = getConfigFromSettings("global", - "minimize_to_system_tray").toInt(); - if (m_minimizeToSystemTray > 1 || m_minimizeToSystemTray < -1) { - setMinimizeToSystemTray(0); - } - - readShortcutsFromSettings(); - - readCaptainShortcutsFromSettings(); - - initDocSuffixes(); - - m_markdownHighlightInterval = getConfigFromSettings("global", - "markdown_highlight_interval").toInt(); - - m_lineDistanceHeight = getConfigFromSettings("global", - "line_distance_height").toInt(); - - m_insertTitleFromNoteName = getConfigFromSettings("global", - "insert_title_from_note_name").toBool(); - - int openMode = getConfigFromSettings("global", - "note_open_mode").toInt(); - if (openMode == 1) { - m_noteOpenMode = OpenFileMode::Edit; - } else { - m_noteOpenMode = OpenFileMode::Read; - } - - int tmpHeadingSequenceType = getConfigFromSettings("global", - "heading_sequence_type").toInt(); - if (tmpHeadingSequenceType < (int)HeadingSequenceType::Invalid - && tmpHeadingSequenceType >= (int)HeadingSequenceType::Disabled) { - m_headingSequenceType = (HeadingSequenceType)tmpHeadingSequenceType; - } else { - m_headingSequenceType = HeadingSequenceType::Disabled; - } - - m_headingSequenceBaseLevel = getConfigFromSettings("global", - "heading_sequence_base_level").toInt(); - - m_colorColumn = getConfigFromSettings("global", "color_column").toInt(); - - m_enableCodeBlockLineNumber = getConfigFromSettings("global", - "enable_code_block_line_number").toBool(); - - m_toolBarIconSize = getConfigFromSettings("global", - "tool_bar_icon_size").toInt(); - - m_markdownItOpt = MarkdownitOption::fromConfig(getConfigFromSettings("web", - "markdownit_opt").toStringList()); - - m_recycleBinFolder = getConfigFromSettings("global", - "recycle_bin_folder").toString(); - - m_recycleBinFolderExt = getConfigFromSettings("global", - "external_recycle_bin_folder").toString(); - - m_confirmImagesCleanUp = getConfigFromSettings("global", - "confirm_images_clean_up").toBool(); - - m_confirmReloadFolder = getConfigFromSettings("global", - "confirm_reload_folder").toBool(); - - m_mathjaxJavascript = getConfigFromSettings("web", - "mathjax_javascript").toString(); - - m_doubleClickCloseTab = getConfigFromSettings("global", - "double_click_close_tab").toBool(); - - m_middleClickCloseTab = getConfigFromSettings("global", - "middle_click_close_tab").toBool(); - - int tmpStartupPageMode = getConfigFromSettings("global", - "startup_page_type").toInt(); - if (tmpStartupPageMode < (int)StartupPageType::Invalid - && tmpStartupPageMode >= (int)StartupPageType::None) { - m_startupPageType = (StartupPageType)tmpStartupPageMode; - } else { - m_startupPageType = StartupPageType::None; - } - - m_startupPages = getConfigFromSettings("global", - "startup_pages").toStringList(); - - initFromSessionSettings(); - - m_fileTimerInterval = getConfigFromSettings("global", - "file_timer_interval").toInt(); - if (m_fileTimerInterval < 100) { - m_fileTimerInterval = 100; - } - - m_backupDirectory = getConfigFromSettings("global", - "backup_directory").toString(); - - m_backupExtension = getConfigFromSettings("global", - "backup_extension").toString(); - if (m_backupExtension.isEmpty()) { - m_backupExtension = "."; - } - - m_vimExemptionKeys = getConfigFromSettings("global", - "vim_exemption_keys").toString(); - - m_closeBeforeExternalEditor = getConfigFromSettings("global", - "close_before_external_editor").toBool(); - - m_stylesToInlineWhenCopied = getConfigFromSettings("web", - "styles_to_inline_when_copied").toStringList().join(","); - - m_singleClickClosePreviousTab = getConfigFromSettings("global", - "single_click_close_previous_tab").toBool(); - - m_enableFlashAnchor = getConfigFromSettings("web", - "enable_flash_anchor").toBool(); - - m_plantUMLMode = getConfigFromSettings("global", "plantuml_mode").toInt(); - m_plantUMLServer = getConfigFromSettings("web", "plantuml_server").toString(); - m_plantUMLJar = getConfigFromSettings("web", "plantuml_jar").toString(); - - QString plantUMLArgs = getConfigFromSettings("web", "plantuml_args").toString(); - m_plantUMLArgs = VUtils::parseCombinedArgString(plantUMLArgs); - - m_plantUMLCmd = getConfigFromSettings("web", "plantuml_cmd").toString(); - - m_enableGraphviz = getConfigFromSettings("global", "enable_graphviz").toBool(); - m_graphvizDot = getConfigFromSettings("web", "graphviz_dot").toString(); - - m_historySize = getConfigFromSettings("global", "history_size").toInt(); - if (m_historySize < 0) { - m_historySize = 0; - } - - m_outlineExpandedLevel = getConfigFromSettings("global", - "outline_expanded_level").toInt(); - - m_imageNamePrefix = getConfigFromSettings("global", - "image_name_prefix").toString(); - - m_panelViewState = getConfigFromSettings("global", - "panel_view_state").toInt(); - - m_maxTagLabelLength = getConfigFromSettings("global", - "max_tag_label_length").toInt(); - - m_maxNumOfTagLabels = getConfigFromSettings("global", - "max_num_of_tag_labels").toInt(); - - m_smartLivePreview = getConfigFromSettings("global", - "smart_live_preview").toInt(); - - m_insertNewNoteInFront = getConfigFromSettings("global", - "insert_new_note_in_front").toBool(); - - m_highlightMatchesInPage = getConfigFromSettings("global", - "highlight_matches_in_page").toBool(); - - m_syncNoteListToCurrentTab = getConfigFromSettings("global", - "sync_note_list_to_current_tab").toBool(); - - initEditorConfigs(); - - initMarkdownConfigs(); - - m_enableCodeBlockCopyButton = getConfigFromSettings("web", - "enable_code_block_copy_button").toBool(); -} - -void VConfigManager::initEditorConfigs() -{ - const QString section("editor"); - - m_autoIndent = getConfigFromSettings(section, "auto_indent").toBool(); - - m_autoList = getConfigFromSettings(section, "auto_list").toBool(); - - m_autoQuote = getConfigFromSettings(section, "auto_quote").toBool(); - - int keyMode = getConfigFromSettings(section, "key_mode").toInt(); - if (keyMode < 0 || keyMode >= (int)KeyMode::Invalid) { - keyMode = 0; - } - m_keyMode = (KeyMode)keyMode; - - m_enableSmartImInVimMode = getConfigFromSettings(section, - "enable_smart_im_in_vim_mode").toBool(); - - QString tmpLeader = getConfigFromSettings(section, - "vim_leader_key").toString(); - if (tmpLeader.isEmpty()) { - m_vimLeaderKey = QChar(' '); - } else { - m_vimLeaderKey = tmpLeader[0]; - if (m_vimLeaderKey.isNull()) { - m_vimLeaderKey = QChar(' '); - } - } - - m_enableTabHighlight = getConfigFromSettings(section, - "enable_tab_highlight").toBool(); - - m_parsePasteLocalImage = getConfigFromSettings(section, "parse_paste_local_image").toBool(); - - m_enableExtraBuffer = getConfigFromSettings(section, "enable_extra_buffer").toBool(); - - m_autoScrollCursorLine = getConfigFromSettings(section, "auto_scroll_cursor_line").toInt(); - - m_editorFontFamily = getConfigFromSettings(section, "editor_font_family").toString(); - - m_enableSmartTable = getConfigFromSettings(section, "enable_smart_table").toBool(); - - m_tableFormatIntervalMS = getConfigFromSettings(section, "table_format_interval").toInt(); -} - -void VConfigManager::initMarkdownConfigs() -{ - const QString section("markdown"); - m_enableWavedrom = getConfigFromSettings(section, "enable_wavedrom").toBool(); - - m_prependDotInRelativePath = getConfigFromSettings(section, "prepend_dot_in_relative_path").toBool(); -} - -void VConfigManager::initSettings() -{ - Q_ASSERT(!userSettings && !defaultSettings && !m_sessionSettings); - - const char *codecForIni = "UTF-8"; - - // vnote.ini. - // First try to read vnote.ini from the directory of the executable. - QString userIniPath = QDir(QCoreApplication::applicationDirPath()).filePath(c_defaultConfigFile); - if (QFileInfo::exists(userIniPath)) { - userSettings = new QSettings(userIniPath, - QSettings::IniFormat, - this); - } else { - userSettings = new QSettings(QSettings::IniFormat, - QSettings::UserScope, - orgName, - appName, - this); - } - - userSettings->setIniCodec(codecForIni); - - qDebug() << "use user config" << userSettings->fileName(); - - // Default vnote.ini from resource file. - defaultSettings = new QSettings(c_defaultConfigFilePath, QSettings::IniFormat, this); - defaultSettings->setIniCodec(codecForIni); - - // session.ini. - m_sessionSettings = new QSettings(QDir(getConfigFolder()).filePath(c_sessionConfigFile), - QSettings::IniFormat, - this); - m_sessionSettings->setIniCodec(codecForIni); -} - -void VConfigManager::initFromSessionSettings() -{ - curNotebookIndex = getConfigFromSessionSettings("global", "current_notebook").toInt(); -} - -void VConfigManager::readCustomColors() -{ - m_customColors.clear(); - QStringList str = getConfigFromSettings("global", "custom_colors").toStringList(); - - for (auto const & item : str) { - QStringList parts = item.split(':', QString::SkipEmptyParts); - if (parts.size() != 2) { - continue; - } - - if (!QColor(parts[1]).isValid()) { - continue; - } - - VColor color; - color.m_name = parts[0]; - color.m_color = parts[1]; - m_customColors.append(color); - } -} - -void VConfigManager::readNotebookFromSettings(QSettings *p_settings, - QVector &p_notebooks, - QObject *parent) -{ - Q_ASSERT(p_notebooks.isEmpty()); - int size = p_settings->beginReadArray("notebooks"); - for (int i = 0; i < size; ++i) { - p_settings->setArrayIndex(i); - QString name = p_settings->value("name").toString(); - QString path = p_settings->value("path").toString(); - VNotebook *notebook = new VNotebook(name, path, parent); - notebook->readConfigNotebook(); - p_notebooks.append(notebook); - } - - p_settings->endArray(); - qDebug() << "read" << p_notebooks.size() - << "notebook items from [notebooks] section"; -} - -void VConfigManager::writeNotebookToSettings(QSettings *p_settings, - const QVector &p_notebooks) -{ - // Clear it first - p_settings->beginGroup("notebooks"); - p_settings->remove(""); - p_settings->endGroup(); - - p_settings->beginWriteArray("notebooks"); - for (int i = 0; i < p_notebooks.size(); ++i) { - p_settings->setArrayIndex(i); - const VNotebook ¬ebook = *p_notebooks[i]; - p_settings->setValue("name", notebook.getName()); - p_settings->setValue("path", notebook.getPathInConfig()); - } - - p_settings->endArray(); - qDebug() << "write" << p_notebooks.size() - << "notebook items in [notebooks] section"; -} - -static QVariant getConfigFromSettingsBySectionKey(const QSettings *p_settings, - const QString &p_section, - const QString &p_key) -{ - QString fullKey = p_section + "/" + p_key; - return p_settings->value(fullKey); -} - -static void setConfigToSettingsBySectionKey(QSettings *p_settings, - const QString &p_section, - const QString &p_key, - const QVariant &p_value) -{ - QString fullKey = p_section + "/" + p_key; - return p_settings->setValue(fullKey, p_value); -} - -QVariant VConfigManager::getConfigFromSettings(const QString §ion, const QString &key) const -{ - // First, look up the user-scoped config file - QVariant value = getConfigFromSettingsBySectionKey(userSettings, section, key); - if (!value.isNull()) { - qDebug() << "user config:" << (section + "/" + key) << value; - return value; - } - - // Second, look up the default config file - return getDefaultConfig(section, key); -} - -void VConfigManager::setConfigToSettings(const QString §ion, const QString &key, const QVariant &value) -{ - if (m_hasReset) { - return; - } - - // Set the user-scoped config file - setConfigToSettingsBySectionKey(userSettings, section, key, value); - qDebug() << "set user config:" << (section + "/" + key) << value; -} - -QVariant VConfigManager::getDefaultConfig(const QString &p_section, const QString &p_key) const -{ - QVariant value = getConfigFromSettingsBySectionKey(defaultSettings, p_section, p_key); - qDebug() << "default config:" << (p_section + "/" + p_key) << value; - return value; -} - -QVariant VConfigManager::resetDefaultConfig(const QString &p_section, const QString &p_key) -{ - QVariant defaultValue = getDefaultConfig(p_section, p_key); - setConfigToSettings(p_section, p_key, defaultValue); - - return defaultValue; -} - -QVariant VConfigManager::getConfigFromSessionSettings(const QString &p_section, - const QString &p_key) const -{ - return getConfigFromSettingsBySectionKey(m_sessionSettings, - p_section, - p_key); -} - -void VConfigManager::setConfigToSessionSettings(const QString &p_section, - const QString &p_key, - const QVariant &p_value) -{ - if (m_hasReset) { - return; - } - - setConfigToSettingsBySectionKey(m_sessionSettings, - p_section, - p_key, - p_value); -} - -QJsonObject VConfigManager::readDirectoryConfig(const QString &path) -{ - QString configFile = fetchDirConfigFilePath(path); - - QFile config(configFile); - if (!config.open(QIODevice::ReadOnly)) { - qWarning() << "fail to read directory configuration file:" - << configFile; - return QJsonObject(); - } - - QByteArray configData = config.readAll(); - return QJsonDocument::fromJson(configData).object(); -} - -bool VConfigManager::directoryConfigExist(const QString &path) -{ - return QFileInfo::exists(fetchDirConfigFilePath(path)); -} - -bool VConfigManager::writeDirectoryConfig(const QString &path, const QJsonObject &configJson) -{ - QString configFile = fetchDirConfigFilePath(path); - - QFile config(configFile); - // We use Unix LF for config file. - if (!config.open(QIODevice::WriteOnly)) { - qWarning() << "fail to open directory configuration file for write:" - << configFile; - return false; - } - - QJsonDocument configDoc(configJson); - config.write(configDoc.toJson()); - return true; -} - -bool VConfigManager::deleteDirectoryConfig(const QString &path) -{ - QString configFile = fetchDirConfigFilePath(path); - - QFile config(configFile); - if (!config.remove()) { - qWarning() << "fail to delete directory configuration file:" - << configFile; - return false; - } - - qDebug() << "delete config file:" << configFile; - return true; -} - -QString VConfigManager::getLogFilePath() const -{ - return QDir(getConfigFolder()).filePath("vnote.log"); -} - -void VConfigManager::updateMarkdownEditStyle() -{ - static const QString defaultColor = "#00897B"; - - // Read style file .mdhl - QString file(getEditorStyleFile()); - - qDebug() << "use editor style file" << file; - - QString styleStr = VUtils::readFileFromDisk(file); - if (styleStr.isEmpty()) { - return; - } - - mdEditPalette = baseEditPalette; - mdEditFont = baseEditFont; - - VStyleParser parser; - parser.parseMarkdownStyle(styleStr); - - QMap> styles; - parser.fetchMarkdownEditorStyles(mdEditPalette, mdEditFont, styles); - - mdHighlightingStyles = parser.fetchMarkdownStyles(mdEditFont); - m_codeBlockStyles = parser.fetchCodeBlockStyles(mdEditFont); - - m_editorCurrentLineBg = defaultColor; - m_editorVimInsertBg = defaultColor; - m_editorVimNormalBg = defaultColor; - m_editorVimVisualBg = defaultColor; - m_editorVimReplaceBg = defaultColor; - - auto editorCurrentLineIt = styles.find("editor-current-line"); - if (editorCurrentLineIt != styles.end()) { - auto backgroundIt = editorCurrentLineIt->find("background"); - if (backgroundIt != editorCurrentLineIt->end()) { - // Do not need to add "#" here, since this is a built-in attribute. - m_editorCurrentLineBg = *backgroundIt; - } - - auto vimBgIt = editorCurrentLineIt->find("vim-insert-background"); - if (vimBgIt != editorCurrentLineIt->end()) { - m_editorVimInsertBg = "#" + *vimBgIt; - } - - vimBgIt = editorCurrentLineIt->find("vim-normal-background"); - if (vimBgIt != editorCurrentLineIt->end()) { - m_editorVimNormalBg = "#" + *vimBgIt; - } - - vimBgIt = editorCurrentLineIt->find("vim-visual-background"); - if (vimBgIt != editorCurrentLineIt->end()) { - m_editorVimVisualBg = "#" + *vimBgIt; - } - - vimBgIt = editorCurrentLineIt->find("vim-replace-background"); - if (vimBgIt != editorCurrentLineIt->end()) { - m_editorVimReplaceBg = "#" + *vimBgIt; - } - } - - m_editorTrailingSpaceBg = defaultColor; - m_editorSelectedWordFg = defaultColor; - m_editorSelectedWordBg = defaultColor; - m_editorSearchedWordFg = defaultColor; - m_editorSearchedWordBg = defaultColor; - m_editorSearchedWordCursorFg = defaultColor; - m_editorSearchedWordCursorBg = defaultColor; - m_editorIncrementalSearchedWordFg = defaultColor; - m_editorIncrementalSearchedWordBg = defaultColor; - m_editorLineNumberBg = defaultColor; - m_editorLineNumberFg = defaultColor; - m_editorColorColumnBg = defaultColor; - m_editorColorColumnFg = defaultColor; - m_editorPreviewImageLineFg = defaultColor; - m_editorPreviewImageBg.clear(); - - auto editorIt = styles.find("editor"); - if (editorIt != styles.end()) { - auto it = editorIt->find("trailing-space"); - if (it != editorIt->end()) { - m_editorTrailingSpaceBg = "#" + *it; - } - - it = editorIt->find("line-number-background"); - if (it != editorIt->end()) { - m_editorLineNumberBg = "#" + *it; - } - - it = editorIt->find("line-number-foreground"); - if (it != editorIt->end()) { - m_editorLineNumberFg = "#" + *it; - } - - it = editorIt->find("selected-word-foreground"); - if (it != editorIt->end()) { - m_editorSelectedWordFg = "#" + *it; - } - - it = editorIt->find("selected-word-background"); - if (it != editorIt->end()) { - m_editorSelectedWordBg = "#" + *it; - } - - it = editorIt->find("searched-word-foreground"); - if (it != editorIt->end()) { - m_editorSearchedWordFg = "#" + *it; - } - - it = editorIt->find("searched-word-background"); - if (it != editorIt->end()) { - m_editorSearchedWordBg = "#" + *it; - } - - it = editorIt->find("searched-word-cursor-foreground"); - if (it != editorIt->end()) { - m_editorSearchedWordCursorFg = "#" + *it; - } - - it = editorIt->find("searched-word-cursor-background"); - if (it != editorIt->end()) { - m_editorSearchedWordCursorBg = "#" + *it; - } - - it = editorIt->find("incremental-searched-word-foreground"); - if (it != editorIt->end()) { - m_editorIncrementalSearchedWordFg = "#" + *it; - } - - it = editorIt->find("incremental-searched-word-background"); - if (it != editorIt->end()) { - m_editorIncrementalSearchedWordBg = "#" + *it; - } - - it = editorIt->find("color-column-background"); - if (it != editorIt->end()) { - m_editorColorColumnBg = "#" + *it; - } - - it = editorIt->find("color-column-foreground"); - if (it != editorIt->end()) { - m_editorColorColumnFg = "#" + *it; - } - - it = editorIt->find("preview-image-line-foreground"); - if (it != editorIt->end()) { - m_editorPreviewImageLineFg = "#" + *it; - } - - it = editorIt->find("preview-image-background"); - if (it != editorIt->end()) { - m_editorPreviewImageBg = "#" + *it; - } - } -} - -void VConfigManager::updateEditStyle() -{ - // Reset font and palette. - baseEditFont = mdEditFont = m_defaultEditFont; - baseEditPalette = mdEditPalette = m_defaultEditPalette; - - static const QColor defaultColor = m_defaultEditPalette.color(QPalette::Base); - QColor newColor = defaultColor; - bool force = false; - if (curBackgroundColor != "System") { - for (int i = 0; i < m_customColors.size(); ++i) { - if (m_customColors[i].m_name == curBackgroundColor) { - newColor = QColor(m_customColors[i].m_color); - force = true; - break; - } - } - } - - baseEditPalette.setColor(QPalette::Base, newColor); - - // Update markdown editor palette - updateMarkdownEditStyle(); - - // Base editor will use the same font size as the markdown editor by now. - if (mdEditFont.pointSize() > -1) { - baseEditFont.setPointSize(mdEditFont.pointSize()); - } - - if (force) { - mdEditPalette.setColor(QPalette::Base, newColor); - } -} - -void VConfigManager::setWebZoomFactor(qreal p_factor) -{ - if (isCustomWebZoomFactor()) { - if (VUtils::realEqual(m_webZoomFactor, p_factor)) { - return; - } else if (VUtils::realEqual(p_factor, -1)) { - m_webZoomFactor = VUtils::calculateScaleFactor(); - setConfigToSettings("global", "web_zoom_factor", -1); - return; - } - } else { - if (VUtils::realEqual(p_factor, -1)) { - return; - } - } - m_webZoomFactor = p_factor; - setConfigToSettings("global", "web_zoom_factor", m_webZoomFactor); -} - -QString VConfigManager::getConfigFolder() const -{ - V_ASSERT(userSettings); - - QString iniPath = userSettings->fileName(); - return VUtils::basePathFromPath(iniPath); -} - -QString VConfigManager::getConfigFilePath() const -{ - V_ASSERT(userSettings); - - return userSettings->fileName(); -} - -const QString &VConfigManager::getStyleConfigFolder() const -{ - static QString path = QDir(getConfigFolder()).filePath(c_styleConfigFolder); - return path; -} - -const QString &VConfigManager::getThemeConfigFolder() const -{ - static QString path = QDir(getConfigFolder()).filePath(c_themeConfigFolder); - return path; -} - -const QString &VConfigManager::getCodeBlockStyleConfigFolder() const -{ - static QString path = QDir(getStyleConfigFolder()).filePath(c_codeBlockStyleConfigFolder); - return path; -} - -const QString &VConfigManager::getTemplateConfigFolder() const -{ - static QString path = QDir(getConfigFolder()).filePath(c_templateConfigFolder); - return path; -} - -const QString &VConfigManager::getSnippetConfigFolder() const -{ - static QString path = QDir(getConfigFolder()).filePath(c_snippetConfigFolder); - return path; -} - -const QString &VConfigManager::getSnippetConfigFilePath() const -{ - static QString path = QDir(getSnippetConfigFolder()).filePath(c_snippetConfigFile); - return path; -} - -QString VConfigManager::getResourceConfigFolder() const -{ - return QDir(getConfigFolder()).filePath(c_resourceConfigFolder); -} - -const QString &VConfigManager::getCommonCssUrl() const -{ - static QString cssPath; - if (cssPath.isEmpty()) { - cssPath = QDir(getResourceConfigFolder()).filePath("common.css"); - if (m_versionChanged || !QFileInfo::exists(cssPath)) { - VUtils::deleteFile(cssPath); - // Output the default one. - if (!VUtils::copyFile(":/resources/common.css", cssPath, false)) { - cssPath = "qrc:/resources/common.css"; - return cssPath; - } - } - - cssPath = QUrl::fromLocalFile(cssPath).toString(); - } - - return cssPath; -} - -const QString VConfigManager::getKeyboardLayoutConfigFilePath() const -{ - return QDir(getConfigFolder()).filePath(c_keyboardLayoutConfigFile); -} - -QString VConfigManager::getThemeFile() const -{ - auto it = m_themes.find(m_theme); - if (it != m_themes.end()) { - return it.value(); - } else { - qWarning() << "use default theme due to missing specified theme" << m_theme; - const_cast(this)->m_theme = getDefaultConfig("global", "theme").toString(); - return m_themes[m_theme]; - } -} - -QVector VConfigManager::getNoteTemplates(DocType p_type) const -{ - QVector res; - QDir dir(getTemplateConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getTemplateConfigFolder()); - return res; - } - - dir.setFilter(QDir::Files | QDir::NoSymLinks); - QStringList files = dir.entryList(); - res.reserve(files.size()); - for (auto const &item : files) { - if (p_type == DocType::Unknown - || p_type == VUtils::docTypeFromName(item)) { - res.push_back(item); - } - } - - return res; -} - -// The URL will be used in the Web page. -QString VConfigManager::getCssStyleUrl() const -{ - Q_ASSERT(!m_themes.isEmpty()); - Q_ASSERT(!m_cssStyles.isEmpty()); - - if (m_cssStyle.isEmpty()) { - // Use theme's style. - const_cast(this)->m_cssStyle = VPalette::themeCssStyle(getThemeFile()); - } - - QString cssPath = getCssStyleUrl(m_cssStyle); - qDebug() << "use css style file" << cssPath; - return cssPath; -} - -QString VConfigManager::getCssStyleUrl(const QString &p_style) const -{ - Q_ASSERT(!m_themes.isEmpty()); - Q_ASSERT(!m_cssStyles.isEmpty()); - - if (p_style.isEmpty()) { - return QString(); - } - - QString cssPath; - auto it = m_cssStyles.find(p_style); - if (it != m_cssStyles.end()) { - cssPath = it.value(); - } - - if (cssPath.startsWith(":")) { - cssPath = "qrc" + cssPath; - } else { - QUrl cssUrl = QUrl::fromLocalFile(cssPath); - cssPath = cssUrl.toString(); - } - - return cssPath; -} - -QString VConfigManager::getCodeBlockCssStyleUrl() const -{ - Q_ASSERT(!m_themes.isEmpty()); - Q_ASSERT(!m_codeBlockCssStyles.isEmpty()); - - if (m_codeBlockCssStyle.isEmpty()) { - // Use theme's style. - const_cast(this)->m_codeBlockCssStyle = - VPalette::themeCodeBlockCssStyle(getThemeFile()); - } - - QString cssPath = getCodeBlockCssStyleUrl(m_codeBlockCssStyle); - qDebug() << "use code block css style file" << cssPath; - return cssPath; -} - -QString VConfigManager::getCodeBlockCssStyleUrl(const QString &p_style) const -{ - Q_ASSERT(!m_themes.isEmpty()); - Q_ASSERT(!m_codeBlockCssStyles.isEmpty()); - - if (p_style.isEmpty()) { - return QString(); - } - - QString cssPath; - auto it = m_codeBlockCssStyles.find(p_style); - if (it != m_codeBlockCssStyles.end()) { - cssPath = it.value(); - } - - if (cssPath.startsWith(":")) { - cssPath = "qrc" + cssPath; - } else { - QUrl cssUrl = QUrl::fromLocalFile(cssPath); - cssPath = cssUrl.toString(); - } - - return cssPath; -} - -QString VConfigManager::getMermaidCssStyleUrl() const -{ - Q_ASSERT(!m_themes.isEmpty()); - Q_ASSERT(!m_theme.isEmpty()); - - static QString mermaidCssPath; - - if (mermaidCssPath.isEmpty()) { - VPaletteMetaData data = VPalette::getPaletteMetaData(getThemeFile()); - mermaidCssPath = data.m_mermaidCssFile; - if (mermaidCssPath.startsWith(":")) { - mermaidCssPath = "qrc" + mermaidCssPath; - } else { - QUrl cssUrl = QUrl::fromLocalFile(mermaidCssPath); - mermaidCssPath = cssUrl.toString(); - } - - qDebug() << "use mermaid css style file" << mermaidCssPath; - } - - return mermaidCssPath; -} - -QString VConfigManager::getEditorStyleFile() const -{ - Q_ASSERT(!m_themes.isEmpty()); - Q_ASSERT(!m_editorStyles.isEmpty()); - - if (m_editorStyle.isEmpty()) { - // Use theme's style. - const_cast(this)->m_editorStyle = VPalette::themeEditorStyle(getThemeFile()); - } - - auto it = m_editorStyles.find(m_editorStyle); - if (it != m_editorStyles.end()) { - return it.value(); - } - - return QString(); -} - -QString VConfigManager::getVnoteNotebookFolderPath() -{ - QStringList folders = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); - if (folders.isEmpty()) { - return QDir::home().filePath(c_vnoteNotebookFolderName); - } else { - return QDir(folders[0]).filePath(c_vnoteNotebookFolderName); - } -} - -QString VConfigManager::getExportFolderPath() -{ - QStringList folders = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); - if (folders.isEmpty()) { - return QDir::home().filePath(c_exportFolderName); - } else { - return QDir(folders[0]).filePath(c_exportFolderName); - } -} - -QString VConfigManager::getDocumentPathOrHomePath() -{ - QStringList folders = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); - if (folders.isEmpty()) { - return QDir::homePath(); - } else { - return folders[0]; - } -} - -QHash VConfigManager::readShortcutsFromSettings(QSettings *p_settings, - const QString &p_group) -{ - QHash ret; - p_settings->beginGroup(p_group); - QStringList keys = p_settings->childKeys(); - for (auto const & key : keys) { - if (key.isEmpty()) { - continue; - } - - QVariant varVal = p_settings->value(key); - QString sequence = varVal.toString(); - if (varVal.type() == QVariant::StringList) { - sequence = varVal.toStringList().join(","); - } - - sequence = sequence.trimmed(); - if (isValidKeySequence(sequence)) { - ret.insert(key, sequence); - } - } - - p_settings->endGroup(); - - return ret; -} - -bool VConfigManager::isValidKeySequence(const QString &p_seq) -{ - return p_seq.isEmpty() - || (p_seq.toLower() != "ctrl+q" && !QKeySequence(p_seq).isEmpty()); -} - -void VConfigManager::readShortcutsFromSettings() -{ - const QString group("shortcuts"); - - m_shortcuts.clear(); - m_shortcuts = readShortcutsFromSettings(defaultSettings, group); - - // Update default settings according to user settings. - QHash userShortcuts = readShortcutsFromSettings(userSettings, - group); - QSet matched; - matched.reserve(m_shortcuts.size()); - for (auto it = userShortcuts.begin(); it != userShortcuts.end(); ++it) { - auto defaultIt = m_shortcuts.find(it.key()); - if (defaultIt != m_shortcuts.end()) { - QString sequence = it.value().trimmed(); - if (sequence != defaultIt.value()) { - if (isValidKeySequence(sequence)) { - matched.insert(it.key()); - *defaultIt = sequence; - } - } else { - matched.insert(it.key()); - } - } - } - - if (matched.size() < m_shortcuts.size()) { - qDebug() << "override user shortcuts settings using default settings"; - writeShortcutsToSettings(userSettings, group, m_shortcuts); - } -} - -void VConfigManager::readCaptainShortcutsFromSettings() -{ - const QString group("captain_mode_shortcuts"); - - m_captainShortcuts.clear(); - m_captainShortcuts = readShortcutsFromSettings(defaultSettings, group); - - // Update default settings according to user settings. - QHash userShortcuts = readShortcutsFromSettings(userSettings, - group); - QSet matched; - matched.reserve(m_captainShortcuts.size()); - for (auto it = userShortcuts.begin(); it != userShortcuts.end(); ++it) { - auto defaultIt = m_captainShortcuts.find(it.key()); - if (defaultIt != m_captainShortcuts.end()) { - QString sequence = it.value().trimmed(); - if (sequence != defaultIt.value()) { - if (isValidKeySequence(sequence)) { - matched.insert(it.key()); - *defaultIt = sequence; - } - } else { - matched.insert(it.key()); - } - } - } - - if (matched.size() < m_captainShortcuts.size()) { - writeShortcutsToSettings(userSettings, group, m_captainShortcuts); - } - - qDebug() << "captain mode shortcuts:" << m_captainShortcuts; -} - -void VConfigManager::writeShortcutsToSettings(QSettings *p_settings, - const QString &p_group, - const QHash &p_shortcuts) -{ - p_settings->beginGroup(p_group); - p_settings->remove(""); - - for (auto it = p_shortcuts.begin(); it != p_shortcuts.end(); ++it) { - p_settings->setValue(it.key(), it.value()); - } - - p_settings->endGroup(); -} - -QString VConfigManager::getShortcutKeySequence(const QString &p_operation) const -{ - auto it = m_shortcuts.find(p_operation); - if (it == m_shortcuts.end()) { - return QString(); - } - - return *it; -} - -QString VConfigManager::getCaptainShortcutKeySequence(const QString &p_operation) const -{ - auto it = m_captainShortcuts.find(p_operation); - if (it == m_captainShortcuts.end()) { - return QString(); - } - - return *it; -} - -void VConfigManager::initDocSuffixes() -{ - m_docSuffixes.clear(); - - QStringList mdSuffix = getConfigFromSettings("global", - "markdown_suffix").toStringList(); - if (mdSuffix.isEmpty()) { - mdSuffix = getDefaultConfig("global", - "markdown_suffix").toStringList(); - } - - for (auto it = mdSuffix.begin(); it != mdSuffix.end();) { - if (it->isEmpty()) { - it = mdSuffix.erase(it); - } else { - *it = it->toLower(); - ++it; - } - } - - Q_ASSERT(!mdSuffix.isEmpty()); - - mdSuffix.removeDuplicates(); - - m_docSuffixes[(int)DocType::Markdown] = mdSuffix; - - QList list; - list << "ls" << "list"; - m_docSuffixes[(int)DocType::List] = list; - - QList container; - container << "co" << "container" << "con"; - m_docSuffixes[(int)DocType::Container] = container; - - QList html; - html << "html"; - m_docSuffixes[(int)DocType::Html] = html; - - qDebug() << "doc suffixes" << m_docSuffixes; -} - -QVector VConfigManager::getLastOpenedFiles() -{ - QVector files; - int size = m_sessionSettings->beginReadArray("last_opened_files"); - for (int i = 0; i < size; ++i) { - m_sessionSettings->setArrayIndex(i); - files.push_back(VFileSessionInfo::fromSettings(m_sessionSettings)); - } - - m_sessionSettings->endArray(); - qDebug() << "read" << files.size() - << "items from [last_opened_files] section"; - - return files; -} - -void VConfigManager::setLastOpenedFiles(const QVector &p_files) -{ - if (m_hasReset) { - return; - } - - const QString section("last_opened_files"); - - // Clear it first - m_sessionSettings->beginGroup(section); - m_sessionSettings->remove(""); - m_sessionSettings->endGroup(); - - m_sessionSettings->beginWriteArray(section); - for (int i = 0; i < p_files.size(); ++i) { - m_sessionSettings->setArrayIndex(i); - const VFileSessionInfo &info = p_files[i]; - info.toSettings(m_sessionSettings); - } - - m_sessionSettings->endArray(); -} - -void VConfigManager::getHistory(QLinkedList &p_history) const -{ - p_history.clear(); - - int size = m_sessionSettings->beginReadArray("history"); - for (int i = 0; i < size; ++i) { - m_sessionSettings->setArrayIndex(i); - p_history.append(VHistoryEntry::fromSettings(m_sessionSettings)); - } - - m_sessionSettings->endArray(); -} - -void VConfigManager::setHistory(const QLinkedList &p_history) -{ - if (m_hasReset) { - return; - } - - const QString section("history"); - - // Clear it first - m_sessionSettings->beginGroup(section); - m_sessionSettings->remove(""); - m_sessionSettings->endGroup(); - - m_sessionSettings->beginWriteArray(section); - int i = 0; - for (auto it = p_history.begin(); it != p_history.end(); ++it, ++i) { - m_sessionSettings->setArrayIndex(i); - it->toSettings(m_sessionSettings); - } - - m_sessionSettings->endArray(); -} - -void VConfigManager::getExplorerEntries(QVector &p_entries) const -{ - p_entries.clear(); - - int size = m_sessionSettings->beginReadArray("explorer_starred"); - for (int i = 0; i < size; ++i) { - m_sessionSettings->setArrayIndex(i); - p_entries.append(VExplorerEntry::fromSettings(m_sessionSettings)); - } - - m_sessionSettings->endArray(); -} - -void VConfigManager::setExplorerEntries(const QVector &p_entries) -{ - if (m_hasReset) { - return; - } - - const QString section("explorer_starred"); - - // Clear it first - m_sessionSettings->beginGroup(section); - m_sessionSettings->remove(""); - m_sessionSettings->endGroup(); - - m_sessionSettings->beginWriteArray(section); - int idx = 0; - for (auto const & entry : p_entries) { - if (entry.m_isStarred) { - m_sessionSettings->setArrayIndex(idx); - entry.toSettings(m_sessionSettings); - ++idx; - } - } - - m_sessionSettings->endArray(); -} - -QVector VConfigManager::getCustomMagicWords() -{ - QVector words; - int size = userSettings->beginReadArray("magic_words"); - for (int i = 0; i < size; ++i) { - userSettings->setArrayIndex(i); - - VMagicWord word; - word.m_name = userSettings->value("name").toString(); - word.m_definition = userSettings->value("definition").toString(); - words.push_back(word); - } - - userSettings->endArray(); - - return words; -} - -QVector VConfigManager::getExternalEditors() const -{ - QVector ret; - userSettings->beginGroup("external_editors"); - QStringList keys = userSettings->childKeys(); - for (auto const & key : keys) { - if (key.isEmpty()) { - continue; - } - - QStringList val = userSettings->value(key).toStringList(); - if (val.size() > 2 - || val.isEmpty()) { - continue; - } - - VExternalEditor editor; - editor.m_name = key; - editor.m_cmd = val[0].trimmed(); - if (editor.m_cmd.isEmpty()) { - continue; - } - - if (val.size() == 2) { - editor.m_shortcut = val[1].trimmed(); - } - - ret.push_back(editor); - } - - userSettings->endGroup(); - - return ret; -} - -const QString &VConfigManager::getFlashPage() const -{ - if (m_flashPage.isEmpty()) { - VConfigManager *var = const_cast(this); - - var->m_flashPage = var->getConfigFromSettings("global", - "flash_page").toString(); - if (var->m_flashPage.isEmpty()) { - var->m_flashPage = var->resetDefaultConfig("global", "flash_page").toString(); - } - - if (VUtils::checkFileNameLegal(m_flashPage)) { - var->m_flashPage = QDir(getConfigFolder()).filePath(m_flashPage); - } - } - - if (!QFileInfo::exists(m_flashPage)) { - VUtils::touchFile(m_flashPage); - } - - return m_flashPage; -} - -const QString &VConfigManager::getQuickAccess() const -{ - if (m_quickAccess.isEmpty()) { - VConfigManager *var = const_cast(this); - - var->m_quickAccess = var->getConfigFromSettings("global", - "quick_access").toString(); - if (VUtils::checkFileNameLegal(m_quickAccess)) { - var->m_quickAccess = QDir(getConfigFolder()).filePath(m_quickAccess); - } - } - - if (!m_quickAccess.isEmpty() && !QFileInfo::exists(m_quickAccess)) { - VUtils::touchFile(m_quickAccess); - } - - return m_quickAccess; -} - -void VConfigManager::initThemes() -{ - m_themes.clear(); - - // Built-in. - QString file(":/resources/themes/v_native/v_native.palette"); - m_themes.insert(VPalette::themeName(file), file); - file = ":/resources/themes/v_pure/v_pure.palette"; - m_themes.insert(VPalette::themeName(file), file); - file = ":/resources/themes/v_moonlight/v_moonlight.palette"; - m_themes.insert(VPalette::themeName(file), file); - file = ":/resources/themes/v_detorte/v_detorte.palette"; - m_themes.insert(VPalette::themeName(file), file); - file = ":/resources/themes/v_simple/v_simple.palette"; - m_themes.insert(VPalette::themeName(file), file); - file = ":/resources/themes/v_next/v_next.palette"; - m_themes.insert(VPalette::themeName(file), file); - - outputBuiltInThemes(); - - // User theme folder. - QDir dir(getThemeConfigFolder()); - Q_ASSERT(dir.exists()); - if (!dir.exists()) { - dir.mkpath(getThemeConfigFolder()); - return; - } - - dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); - QStringList dirs = dir.entryList(); - for (auto const &item : dirs) { - QDir themeDir(dir.filePath(item)); - QStringList files = themeDir.entryList(QStringList() << "*.palette"); - if (files.size() != 1) { - continue; - } - - QFileInfo fi(files[0]); - m_themes.insert(VPalette::themeName(files[0]), themeDir.filePath(files[0])); - } -} - -void VConfigManager::outputBuiltInThemes() -{ - QDir dir(getThemeConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getThemeConfigFolder()); - } - - QStringList suffix({"*.palette"}); - - for (auto it = m_themes.begin(); it != m_themes.end(); ++it) { - QString file = it.value(); - QString srcDir = VUtils::basePathFromPath(file); - QString folder = VUtils::directoryNameFromPath(srcDir); - - bool needOutput = false; - if (dir.exists(folder)) { - QString folderPath = dir.filePath(folder); - QDir tmpDir(folderPath); - QStringList files = tmpDir.entryList(suffix); - if (files.size() == 1) { - int newVer = VPalette::getPaletteVersion(file); - int curVer = VPalette::getPaletteVersion(tmpDir.filePath(files[0])); - if (newVer != curVer) { - needOutput = true; - } - } else { - needOutput = true; - } - - if (needOutput) { - // Delete the folder. - bool ret = VUtils::deleteDirectory(folderPath); - VUtils::sleepWait(100); - Q_UNUSED(ret); - qDebug() << "delete obsolete theme" << folderPath << ret; - } - } else { - needOutput = true; - } - - if (needOutput) { - qDebug() << "output built-in theme" << file << folder; - VUtils::copyDirectory(srcDir, dir.filePath(folder), false); - } - } -} - -void VConfigManager::initEditorStyles() -{ - Q_ASSERT(!m_themes.isEmpty()); - - // Styles from themes. - m_editorStyles = VPalette::editorStylesFromThemes(m_themes.values()); - - // User style folder. - // Get all the .mdhl files in the folder. - QDir dir(getStyleConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getStyleConfigFolder()); - return; - } - - dir.setFilter(QDir::Files | QDir::NoSymLinks); - dir.setNameFilters(QStringList("*.mdhl")); - QStringList files = dir.entryList(); - for (auto const &item : files) { - QFileInfo fi(item); - m_editorStyles.insert(fi.completeBaseName(), dir.filePath(item)); - } -} - -void VConfigManager::initCssStyles() -{ - Q_ASSERT(!m_themes.isEmpty()); - - // Styles from themes. - m_cssStyles = VPalette::cssStylesFromThemes(m_themes.values()); - - // User style folder. - // Get all the .css files in the folder. - QDir dir(getStyleConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getStyleConfigFolder()); - return; - } - - dir.setFilter(QDir::Files | QDir::NoSymLinks); - dir.setNameFilters(QStringList("*.css")); - QStringList files = dir.entryList(); - for (auto const &item : files) { - QFileInfo fi(item); - m_cssStyles.insert(fi.completeBaseName(), dir.filePath(item)); - } -} - -void VConfigManager::initCodeBlockCssStyles() -{ - Q_ASSERT(!m_themes.isEmpty()); - - // Styles from themes. - m_codeBlockCssStyles = VPalette::codeBlockCssStylesFromThemes(m_themes.values()); - - // User style folder. - // Get all the .css files in the folder. - QDir dir(getCodeBlockStyleConfigFolder()); - if (!dir.exists()) { - dir.mkpath(getCodeBlockStyleConfigFolder()); - return; - } - - dir.setFilter(QDir::Files | QDir::NoSymLinks); - dir.setNameFilters(QStringList("*.css")); - QStringList files = dir.entryList(); - for (auto const &item : files) { - QFileInfo fi(item); - m_codeBlockCssStyles.insert(fi.completeBaseName(), dir.filePath(item)); - } -} - -void VConfigManager::resetConfigurations() -{ - // Clear userSettings. - userSettings->clear(); - - // Clear m_sessionSettings except the notebooks information. - clearGroupOfSettings(m_sessionSettings, "last_opened_files"); - clearGroupOfSettings(m_sessionSettings, "geometry"); - - m_hasReset = true; -} - -void VConfigManager::resetLayoutConfigurations() -{ - resetDefaultConfig("global", "tools_dock_checked"); - resetDefaultConfig("global", "search_dock_checked"); - resetDefaultConfig("global", "menu_bar_checked"); - - clearGroupOfSettings(m_sessionSettings, "geometry"); - - m_hasReset = true; -} - -void VConfigManager::clearGroupOfSettings(QSettings *p_settings, const QString &p_group) -{ - p_settings->beginGroup(p_group); - p_settings->remove(""); - p_settings->endGroup(); -} - -QString VConfigManager::getRenderBackgroundColor(const QString &p_bgName) const -{ - if (p_bgName == "Transparent") { - return "transparent"; - } else if (p_bgName != "System") { - for (int i = 0; i < m_customColors.size(); ++i) { - if (m_customColors[i].m_name == p_bgName) { - return m_customColors[i].m_color; - } - } - } - - return QString(); -} - -void VConfigManager::checkVersion() -{ - const QString key("version"); - QString ver = getConfigFromSettings("global", key).toString(); - m_versionChanged = ver != c_version; - m_freshInstall = ver.isEmpty(); - if (m_versionChanged) { - setConfigToSettings("global", key, c_version); - } -} - -int VConfigManager::getWindowsOpenGL() -{ - const char *codecForIni = "UTF-8"; - - QScopedPointer userSet(new QSettings(QSettings::IniFormat, - QSettings::UserScope, - orgName, - appName)); - userSet->setIniCodec(codecForIni); - - QString fullKey("global/windows_opengl"); - QVariant val = userSet->value(fullKey); - if (!val.isNull()) { - return val.toInt(); - } - - // Default vnote.ini from resource file. - QScopedPointer defaultSet(new QSettings(c_defaultConfigFilePath, - QSettings::IniFormat)); - defaultSet->setIniCodec(codecForIni); - return defaultSet->value(fullKey).toInt(); -} - -void VConfigManager::setWindowsOpenGL(int p_openGL) -{ - const char *codecForIni = "UTF-8"; - - QScopedPointer userSet(new QSettings(QSettings::IniFormat, - QSettings::UserScope, - orgName, - appName)); - userSet->setIniCodec(codecForIni); - - QString fullKey("global/windows_opengl"); - userSet->setValue(fullKey, p_openGL); -} - -QDate VConfigManager::getLastUserTrackDate() const -{ - - auto dateStr = getConfigFromSessionSettings("global", - "last_user_track_date").toString(); - return QDate::fromString(dateStr, Qt::ISODate); -} - -void VConfigManager::updateLastUserTrackDate() -{ - auto date = QDate::currentDate(); - setConfigToSessionSettings("global", - "last_user_track_date", - date.toString(Qt::ISODate)); -} - -QDateTime VConfigManager::getLastStartDateTime() const -{ - auto dateStr = getConfigFromSessionSettings("global", - "last_start_time").toString(); - return QDateTime::fromString(dateStr, Qt::ISODate); -} - -void VConfigManager::updateLastStartDateTime() -{ - auto dateTime = QDateTime::currentDateTime(); - setConfigToSessionSettings("global", "last_start_time", dateTime.toString(Qt::ISODate)); -} diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h deleted file mode 100644 index 9bb92178..00000000 --- a/src/vconfigmanager.h +++ /dev/null @@ -1,3392 +0,0 @@ -#ifndef VCONFIGMANAGER_H -#define VCONFIGMANAGER_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vnotebook.h" -#include "markdownhighlighterdata.h" -#include "vmarkdownconverter.h" -#include "vconstants.h" -#include "vfilesessioninfo.h" -#include "utils/vmetawordmanager.h" -#include "markdownitoption.h" -#include "vhistoryentry.h" -#include "vexplorerentry.h" - -class QJsonObject; -class QString; - -struct VColor -{ - QString m_name; - QString m_color; // #RGB or color name. -}; - - -struct VExternalEditor -{ - QString m_name; - - QString m_cmd; - - QString m_shortcut; -}; - - -// Type of heading sequence. -enum class HeadingSequenceType -{ - Disabled = 0, - Enabled, - - // Enabled only for internal notes. - EnabledNoteOnly, - - Invalid -}; - -// Editor key mode. -enum class KeyMode -{ - Normal = 0, - Vim, - Invalid -}; - -enum SmartLivePreview -{ - Disabled = 0, - EditorToWeb = 0x1, - WebToEditor = 0x2 -}; - -enum -{ - AutoScrollDisabled = 0, - AutoScrollEndOfDoc = 1, - AutoScrollAlways = 2 -}; - -enum -{ - OpenGLDefault = 0, - OpenGLDesktop = 1, - OpenGLAngle = 2, - OpenGLSoftware = 3 -}; - -class VConfigManager : public QObject -{ -public: - explicit VConfigManager(QObject *p_parent = NULL); - - void initialize(); - - // Read config from the directory config json file into a QJsonObject. - // @path is the directory containing the config json file. - static QJsonObject readDirectoryConfig(const QString &path); - - static bool writeDirectoryConfig(const QString &path, const QJsonObject &configJson); - - static bool directoryConfigExist(const QString &path); - - static bool deleteDirectoryConfig(const QString &path); - - // Get the path of the folder used to store default notebook. - static QString getVnoteNotebookFolderPath(); - - // Get the path of the default export folder. - static QString getExportFolderPath(); - - static QString getDocumentPathOrHomePath(); - - // Get windows_opengl config. - // Because we may call this before QApplication initialization, we only - // read/write the config to the user folder. - static int getWindowsOpenGL(); - static void setWindowsOpenGL(int p_openGL); - - // Constants - static const QString orgName; - static const QString appName; - static const QString c_version; - - // CSS style for Warning texts. - static const QString c_warningTextStyle; - - // CSS style for data in label. - static const QString c_dataTextStyle; - - // Reset the configuratio files. - void resetConfigurations(); - - // Reset the layout. - void resetLayoutConfigurations(); - - QFont getMdEditFont() const; - - const QPalette &getMdEditPalette() const; - - QVector getMdHighlightingStyles() const; - - QHash getCodeBlockStyles() const; - - QString getLogFilePath() const; - - // Get the css style URL for web view. - QString getCssStyleUrl() const; - - QString getCssStyleUrl(const QString &p_style) const; - - QString getCodeBlockCssStyleUrl() const; - - QString getCodeBlockCssStyleUrl(const QString &p_style) const; - - QString getMermaidCssStyleUrl() const; - - const QString &getEditorStyle() const; - void setEditorStyle(const QString &p_style); - - const QString &getCssStyle() const; - void setCssStyle(const QString &p_style); - - const QString &getCodeBlockCssStyle() const; - void setCodeBlockCssStyle(const QString &p_style); - - QFont getBaseEditFont() const; - QPalette getBaseEditPalette() const; - - int getCurNotebookIndex() const; - void setCurNotebookIndex(int index); - - int getNaviBoxCurrentIndex() const; - void setNaviBoxCurrentIndex(int p_index); - - // Read [notebooks] section from settings into @p_notebooks. - void getNotebooks(QVector &p_notebooks, QObject *p_parent); - - // Write @p_notebooks to [notebooks] section into settings. - void setNotebooks(const QVector &p_notebooks); - - hoedown_extensions getMarkdownExtensions() const; - MarkdownConverterType getMdConverterType() const; - void setMarkdownConverterType(MarkdownConverterType type); - - int getTabStopWidth() const; - void setTabStopWidth(int tabStopWidth); - bool getIsExpandTab() const; - void setIsExpandTab(bool isExpandTab); - - bool getHighlightCursorLine() const; - void setHighlightCursorLine(bool p_cursorLine); - - bool getHighlightSelectedWord() const; - void setHighlightSelectedWord(bool p_selectedWord); - - bool getHighlightSearchedWord() const; - void setHighlightSearchedWord(bool p_searchedWord); - - bool getAutoIndent() const; - void setAutoIndent(bool p_autoIndent); - - bool getAutoList() const; - void setAutoList(bool p_autoList); - - bool getAutoQuote() const; - - const QVector &getCustomColors() const; - - const QString &getCurBackgroundColor() const; - void setCurBackgroundColor(const QString &colorName); - - const QString &getCurRenderBackgroundColor() const; - void setCurRenderBackgroundColor(const QString &colorName); - - // Return the color string of background @p_bgName. - QString getRenderBackgroundColor(const QString &p_bgName) const; - - bool getToolsDockChecked() const; - void setToolsDockChecked(bool p_checked); - - bool getSearchDockChecked() const; - void setSearchDockChecked(bool p_checked); - - const QByteArray getMainWindowGeometry() const; - void setMainWindowGeometry(const QByteArray &p_geometry); - - const QByteArray getMainWindowState() const; - void setMainWindowState(const QByteArray &p_state); - - const QByteArray getMainSplitterState() const; - void setMainSplitterState(const QByteArray &p_state); - - const QByteArray getNotebookSplitterState() const; - void setNotebookSplitterState(const QByteArray &p_state); - - const QByteArray getTagExplorerSplitterState() const; - void setTagExplorerSplitterState(const QByteArray &p_state); - - int getPanelViewState() const; - void setPanelViewState(int p_state); - - int getMaxTagLabelLength() const; - - int getMaxNumOfTagLabels() const; - - bool getFindCaseSensitive() const; - void setFindCaseSensitive(bool p_enabled); - - bool getFindWholeWordOnly() const; - void setFindWholeWordOnly(bool p_enabled); - - bool getFindRegularExpression() const; - void setFindRegularExpression(bool p_enabled); - - bool getFindIncrementalSearch() const; - void setFindIncrementalSearch(bool p_enabled); - - QString getLanguage() const; - void setLanguage(const QString &p_language); - - bool getEnableMermaid() const; - void setEnableMermaid(bool p_enabled); - - bool getEnableFlowchart() const; - void setEnableFlowchart(bool p_enabled); - - bool getEnableMathjax() const; - void setEnableMathjax(bool p_enabled); - - bool getEnableWavedrom() const; - void setEnableWavedrom(bool p_enabled); - - bool getEnableGraphviz() const; - void setEnableGraphviz(bool p_enabled); - - int getPlantUMLMode() const; - void setPlantUMLMode(int p_mode); - - qreal getWebZoomFactor() const; - void setWebZoomFactor(qreal p_factor); - bool isCustomWebZoomFactor(); - - int getEditorZoomDelta() const; - void setEditorZoomDelta(int p_delta); - - const QString &getEditorCurrentLineBg() const; - - const QString &getEditorTrailingSpaceBg() const; - - const QString &getEditorSelectedWordFg() const; - const QString &getEditorSelectedWordBg() const; - - const QString &getEditorSearchedWordFg() const; - const QString &getEditorSearchedWordBg() const; - - const QString &getEditorSearchedWordCursorFg() const; - const QString &getEditorSearchedWordCursorBg() const; - - const QString &getEditorIncrementalSearchedWordFg() const; - const QString &getEditorIncrementalSearchedWordBg() const; - - const QString &getEditorVimNormalBg() const; - const QString &getEditorVimInsertBg() const; - const QString &getEditorVimVisualBg() const; - const QString &getEditorVimReplaceBg() const; - - bool getEnableCodeBlockHighlight() const; - void setEnableCodeBlockHighlight(bool p_enabled); - - bool getEnablePreviewImages() const; - void setEnablePreviewImages(bool p_enabled); - - bool getEnablePreviewImageConstraint() const; - void setEnablePreviewImageConstraint(bool p_enabled); - - bool getEnableImageConstraint() const; - void setEnableImageConstraint(bool p_enabled); - - bool getEnableImageCaption() const; - void setEnableImageCaption(bool p_enabled); - - const QString &getImageFolder() const; - // Empty string to reset the default folder. - void setImageFolder(const QString &p_folder); - bool isCustomImageFolder() const; - - const QString &getImageFolderExt() const; - // Empty string to reset the default folder. - void setImageFolderExt(const QString &p_folder); - bool isCustomImageFolderExt() const; - - const QString &getAttachmentFolder() const; - // Empty string to reset the default folder. - void setAttachmentFolder(const QString &p_folder); - bool isCustomAttachmentFolder() const; - - bool getEnableTrailingSpaceHighlight() const; - void setEnableTrailingSapceHighlight(bool p_enabled); - - bool getEnableTabHighlight() const; - void setEnableTabHighlight(bool p_enabled); - - KeyMode getKeyMode() const; - void setKeyMode(KeyMode p_mode); - - bool getEnableVimMode() const; - - bool getEnableSmartImInVimMode() const; - void setEnableSmartImInVimMode(bool p_enabled); - - int getEditorLineNumber() const; - void setEditorLineNumber(int p_mode); - - const QString &getEditorLineNumberBg() const; - const QString &getEditorLineNumberFg() const; - - int getMinimizeToStystemTray() const; - void setMinimizeToSystemTray(int p_val); - - void initDocSuffixes(); - const QHash> &getDocSuffixes() const; - - int getMarkdownHighlightInterval() const; - - int getLineDistanceHeight() const; - - bool getInsertTitleFromNoteName() const; - void setInsertTitleFromNoteName(bool p_enabled); - - OpenFileMode getNoteOpenMode() const; - void setNoteOpenMode(OpenFileMode p_mode); - - HeadingSequenceType getHeadingSequenceType() const; - void setHeadingSequenceType(HeadingSequenceType p_type); - - int getHeadingSequenceBaseLevel() const; - void setHeadingSequenceBaseLevel(int p_level); - - int getColorColumn() const; - void setColorColumn(int p_column); - - const QString &getEditorColorColumnBg() const; - const QString &getEditorColorColumnFg() const; - - const QString &getEditorPreviewImageLineFg() const; - - const QString &getEditorPreviewImageBg() const; - - bool getEnableCodeBlockLineNumber() const; - void setEnableCodeBlockLineNumber(bool p_enabled); - - int getToolBarIconSize() const; - void setToolBarIconSize(int p_size); - - const MarkdownitOption &getMarkdownitOption() const; - void setMarkdownitOption(const MarkdownitOption &p_opt); - - const QString &getRecycleBinFolder() const; - - const QString &getRecycleBinFolderExt() const; - - bool getConfirmImagesCleanUp() const; - void setConfirmImagesCleanUp(bool p_enabled); - - bool getConfirmReloadFolder() const; - void setConfirmReloadFolder(bool p_enabled); - - const QString &getMathjaxJavascript() const; - void setMathjaxJavascript(const QString &p_js); - - bool getDoubleClickCloseTab() const; - - bool getMiddleClickClostTab() const; - - StartupPageType getStartupPageType() const; - void setStartupPageType(StartupPageType p_type); - - const QStringList &getStartupPages() const; - void setStartupPages(const QStringList &p_pages); - - // Read last opened files from [last_opened_files] of session.ini. - QVector getLastOpenedFiles(); - - // Write last opened files to [last_opened_files] of session.ini. - void setLastOpenedFiles(const QVector &p_files); - - // Read history from [history] of session.ini. - void getHistory(QLinkedList &p_history) const; - - void setHistory(const QLinkedList &p_history); - - int getHistorySize() const; - - // Read explorer's starred entries from [explorer_starred] of session.ini. - void getExplorerEntries(QVector &p_entries) const; - - // Output starred entries to [explorer_starred] of session.ini. - void setExplorerEntries(const QVector &p_entries); - - int getExplorerCurrentIndex() const; - - void setExplorerCurrentIndex(int p_idx); - - // Read custom magic words from [magic_words] section. - QVector getCustomMagicWords(); - - // Return the configured key sequence of @p_operation. - // Return empty if there is no corresponding config. - QString getShortcutKeySequence(const QString &p_operation) const; - - // Return the configured key sequence in Captain mode. - // Return empty if there is no corresponding config. - QString getCaptainShortcutKeySequence(const QString &p_operation) const; - - // Get the folder the ini file exists. - QString getConfigFolder() const; - - // Get the ini config file path. - QString getConfigFilePath() const; - - // Get the folder c_styleConfigFolder in the config folder. - const QString &getStyleConfigFolder() const; - - // Get the folder c_templateConfigFolder in the config folder. - const QString &getTemplateConfigFolder() const; - - // Get the folder c_themeConfigFolder in the config folder. - const QString &getThemeConfigFolder() const; - - // Get the folder c_snippetConfigFolder in the config folder. - const QString &getSnippetConfigFolder() const; - - const QString &getSnippetConfigFilePath() const; - - const QString getKeyboardLayoutConfigFilePath() const; - - // Read all available templates files in c_templateConfigFolder. - QVector getNoteTemplates(DocType p_type = DocType::Unknown) const; - - // Get the folder c_codeBlockStyleConfigFolder in the config folder. - const QString &getCodeBlockStyleConfigFolder() const; - - // Get the folder c_resourceConfigFolder in the config folder. - QString getResourceConfigFolder() const; - - const QString &getCommonCssUrl() const; - - // All the editor styles. - QList getEditorStyles() const; - - // All the css styles. - QList getCssStyles() const; - - // All the css styles. - QList getCodeBlockCssStyles() const; - - // Return the timer interval for checking file. - int getFileTimerInterval() const; - - // Get the backup directory. - const QString &getBackupDirectory() const; - - // Get the backup file extension. - const QString &getBackupExtension() const; - - // Whether backup file is enabled. - bool getEnableBackupFile() const; - void setEnableBackupFile(bool p_enabled); - - // Get defined external editors. - QVector getExternalEditors() const; - - const QString &getVimExemptionKeys() const; - - const QString &getFlashPage() const; - - const QString &getQuickAccess() const; - void setQuickAccess(const QString &p_path); - - bool getHighlightMatchesInPage() const; - void setHighlightMatchesInPage(bool p_enabled); - - // All the themes. - QList getThemes() const; - - // Return current theme name. - const QString &getTheme() const; - - void setTheme(const QString &p_theme); - - QString getThemeFile() const; - - bool getCloseBeforeExternalEditor() const; - - QStringList getStylesToRemoveWhenCopied() const; - - const QString &getStylesToInlineWhenCopied() const; - - QString getStyleOfSpanForMark() const; - - // Return [web]/copy_targets. - QStringList getCopyTargets() const; - - bool getMenuBarChecked() const; - void setMenuBarChecked(bool p_checked); - - bool getToolBarChecked() const; - void setToolBarChecked(bool p_checked); - - bool getSingleClickClosePreviousTab() const; - void setSingleClickClosePreviousTab(bool p_enabled); - - bool getEnableWildCardInSimpleSearch() const; - - bool getEnableAutoSave() const; - void setEnableAutoSave(bool p_enabled); - - QString getWkhtmltopdfPath() const; - void setWkhtmltopdfPath(const QString &p_path); - - QString getWkhtmltopdfArgs() const; - void setWkhtmltopdfArgs(const QString &p_args); - - bool getEnableFlashAnchor() const; - void setEnableFlashAnchor(bool p_enabled); - - QStringList getCustomExport() const; - void setCustomExport(const QStringList &p_exp); - - QStringList getSearchOptions() const; - void setSearchOptions(const QStringList &p_opts); - - const QString &getPlantUMLServer() const; - void setPlantUMLServer(const QString &p_server); - - const QString &getPlantUMLJar() const; - void setPlantUMLJar(const QString &p_jarPath); - - const QStringList &getPlantUMLArgs() const; - const QString &getPlantUMLCmd() const; - - const QString &getGraphvizDot() const; - void setGraphvizDot(const QString &p_dotPath); - - int getNoteListViewOrder() const; - void setNoteListViewOrder(int p_order); - - int getOutlineExpandedLevel() const; - void setOutlineExpandedLevel(int p_level); - - const QString &getImageNamePrefix() const; - - QChar getVimLeaderKey() const; - - int getSmartLivePreview() const; - void setSmartLivePreview(int p_preview); - - bool getInsertNewNoteInFront() const; - void setInsertNewNoteInFront(bool p_enabled); - - QString getKeyboardLayout() const; - void setKeyboardLayout(const QString &p_name); - - QList getKeyboardLayoutMappingKeys() const; - - bool getParsePasteLocalImage() const; - - bool versionChanged() const; - bool isFreshInstall() const; - - const QColor &getBaseBackground() const; - void setBaseBackground(const QColor &p_bg); - - bool getEnableExtraBuffer() const; - - int getAutoScrollCursorLine() const; - void setAutoScrollCursorLine(int p_mode); - - const QString &getEditorFontFamily() const; - void setEditorFontFamily(const QString &p_font); - - bool getEnableSplitFileList() const; - void setEnableSplitFileList(bool p_enable); - - bool getEnableSplitTagFileList() const; - void setEnableSplitTagFileList(bool p_enable); - - // Get the path to browse when inserting image. - QString getImageBrowsePath() const; - void setImageBrowsePath(const QString &p_path); - - bool getPrependDotInRelativePath() const; - void setPrependDotInRelativePath(bool p_enabled); - - bool getEnableSmartTable() const; - void setEnableSmartTable(bool p_enabled); - - bool getAllowUserTrack() const; - void setAllowUserTrack(bool p_enabled); - - bool getSyncNoteListToTab() const; - void setSyncNoteListToTab(bool p_enabled); - - QDate getLastUserTrackDate() const; - void updateLastUserTrackDate(); - - QDateTime getLastStartDateTime() const; - void updateLastStartDateTime(); - - int getTableFormatInterval() const; - - bool getEnableCodeBlockCopyButton() const; - void setEnableCodeBlockCopyButton(bool p_enabled); - - // Github image hosting setting. - const QString &getGithubPersonalAccessToken() const; - void setGithubPersonalAccessToken(const QString &p_token); - - const QString &getGithubReposName() const; - void setGithubReposName(const QString &p_reposName); - - const QString &getGithubUserName() const; - void setGithubUserName(const QString &p_userName); - - const bool &getGithubKeepImgScale() const; - void setGithubKeepImgScale(const bool &p_githubKeepImgScale); - - const bool &getGithubDoNotReplaceLink() const; - void setGithubDoNotReplaceLink(const bool &p_githubDoNotReplaceLink); - - // Gitee image hosting setting. - const QString &getGiteePersonalAccessToken() const; - void setGiteePersonalAccessToken(const QString &p_token); - - const QString &getGiteeReposName() const; - void setGiteeReposName(const QString &p_reposName); - - const QString &getGiteeUserName() const; - void setGiteeUserName(const QString &p_userName); - - const bool &getGiteeKeepImgScale() const; - void setGiteeKeepImgScale(const bool &p_giteeKeepImgScale); - - const bool &getGiteeDoNotReplaceLink() const; - void setGiteeDoNotReplaceLink(const bool &p_giteeDoNotReplaceLink); - - // Wechat image hosting setting. - const QString &getWechatAppid() const; - void setWechatAppid(const QString &p_appid); - - const QString &getWechatSecret() const; - void setWechatSecret(const QString &p_secret); - - const QString &getMarkdown2WechatToolUrl() const; - void setMarkdown2WechatToolUrl(const QString &p_markdown2WechatToolUrl); - - const bool &getWechatKeepImgScale() const; - void setWechatKeepImgScale(const bool &p_wechatKeepImgScale); - - const bool &getWechatDoNotReplaceLink() const; - void setWechatDoNotReplaceLink(const bool &p_wechatDoNotReplaceLink); - - // Tencent image hosting setting. - const QString &getTencentAccessDomainName() const; - void setTencentAccessDomainName(const QString &p_accessDomainName); - - const QString &getTencentSecretId() const; - void setTencentSecretId(const QString &p_secretId); - - const QString &getTencentSecretKey() const; - void setTencentSecretKey(const QString &p_secretKey); - - const bool &getTencentKeepImgScale() const; - void setTencentKeepImgScale(const bool &p_tencentKeepImgScale); - - const bool &getTencentDoNotReplaceLink() const; - void setTencentDoNotReplaceLink(const bool &p_tencentDoNotReplaceLink); - -private: - void initEditorConfigs(); - - void initMarkdownConfigs(); - - // Look up a config from user and default settings. - QVariant getConfigFromSettings(const QString §ion, const QString &key) const; - - // Set a config to user settings. - void setConfigToSettings(const QString §ion, const QString &key, const QVariant &value); - - // Get default config from vnote.ini. - QVariant getDefaultConfig(const QString &p_section, const QString &p_key) const; - - // Reset user config to default config and return the default config value. - QVariant resetDefaultConfig(const QString &p_section, const QString &p_key); - - // Look up a config from session settings. - QVariant getConfigFromSessionSettings(const QString &p_section, const QString &p_key) const; - - // Set a config to session settings. - void setConfigToSessionSettings(const QString &p_section, - const QString &p_key, - const QVariant &p_value); - - void clearGroupOfSettings(QSettings *p_settings, const QString &p_group); - - // Init defaultSettings, userSettings, and m_sessionSettings. - void initSettings(); - - // Init from m_sessionSettings. - void initFromSessionSettings(); - - // Read [notebooks] section from @p_settings. - void readNotebookFromSettings(QSettings *p_settings, - QVector &p_notebooks, - QObject *parent); - - // Write to [notebooks] section to @p_settings. - void writeNotebookToSettings(QSettings *p_settings, - const QVector &p_notebooks); - - void readCustomColors(); - - // 1. Update styles common in HTML and Markdown; - // 2. Update styles for Markdown. - void updateEditStyle(); - - void updateMarkdownEditStyle(); - - static QString fetchDirConfigFilePath(const QString &p_path); - - // Read the [shortcuts] section in settings to init m_shortcuts. - // Will remove invalid config items. - // First read the config in default settings; - // Second read the config in user settings and overwrite the default ones; - // If there is any config in deafult settings that is absent in user settings, - // write the combined configs to user settings. - void readShortcutsFromSettings(); - - // Read the [captain_mode_shortcuts] section in the settings to init - // m_captainShortcuts. - void readCaptainShortcutsFromSettings(); - - QHash readShortcutsFromSettings(QSettings *p_settings, - const QString &p_group); - - void writeShortcutsToSettings(QSettings *p_settings, - const QString &p_group, - const QHash &p_shortcuts); - - // Whether @p_seq is a valid key sequence for shortcuts. - bool isValidKeySequence(const QString &p_seq); - - // Init the themes name-file mappings. - void initThemes(); - - // Output built-in themes to user theme folder if there does not exists folders - // with the same name. - void outputBuiltInThemes(); - - // Init the editor styles name-file mappings. - void initEditorStyles(); - - void initCssStyles(); - - void initCodeBlockCssStyles(); - - QString getEditorStyleFile() const; - - void checkVersion(); - - // Default font and palette. - QFont m_defaultEditFont; - QPalette m_defaultEditPalette; - - // Font and palette used for non-markdown editor. - QFont baseEditFont; - QPalette baseEditPalette; - - // Font and palette used for markdown editor. - QFont mdEditFont; - QPalette mdEditPalette; - - QVector mdHighlightingStyles; - QHash m_codeBlockStyles; - - // Index of current notebook. - int curNotebookIndex; - - // Markdown Converter - hoedown_extensions markdownExtensions; - MarkdownConverterType mdConverterType; - - // Num of spaces - int tabStopWidth; - // Expand tab to @tabStopWidth spaces - bool isExpandTab; - - // Highlight current cursor line. - bool m_highlightCursorLine; - - // Highlight selected word. - bool m_highlightSelectedWord; - - // Highlight searched word. - bool m_highlightSearchedWord; - - // Auto Indent. - bool m_autoIndent; - - // Auto List. - bool m_autoList; - - // Auto quote. - bool m_autoQuote; - - // App defined color - QVector m_customColors; - - QString curBackgroundColor; - - QString curRenderBackgroundColor; - - // Find/Replace dialog options - bool m_findCaseSensitive; - bool m_findWholeWordOnly; - bool m_findRegularExpression; - bool m_findIncrementalSearch; - - // Language - QString m_language; - - // Enable Mermaid. - bool m_enableMermaid; - - // Enable flowchart.js. - bool m_enableFlowchart; - - // Enable Mathjax. - bool m_enableMathjax; - - // Enable WaveDrom. - bool m_enableWavedrom; - - // Enable Graphviz. - bool m_enableGraphviz; - - QString m_graphvizDot; - - // Zoom factor of the QWebEngineView. - qreal m_webZoomFactor; - - // Editor zoom delta. - int m_editorZoomDelta; - - // Current line background color in editor. - QString m_editorCurrentLineBg; - - // Current line background color in editor in Vim normal mode. - QString m_editorVimNormalBg; - - // Current line background color in editor in Vim insert mode. - QString m_editorVimInsertBg; - - // Current line background color in editor in Vim visual mode. - QString m_editorVimVisualBg; - - // Current line background color in editor in Vim replace mode. - QString m_editorVimReplaceBg; - - // Trailing space background color in editor. - QString m_editorTrailingSpaceBg; - - // Foreground and background color of selected word in editor. - QString m_editorSelectedWordFg; - - QString m_editorSelectedWordBg; - - // Foreground and background color of searched word in editor. - QString m_editorSearchedWordFg; - - QString m_editorSearchedWordBg; - - // Foreground and background color of searched word under cursor in editor. - QString m_editorSearchedWordCursorFg; - - QString m_editorSearchedWordCursorBg; - - // Foreground and background color of incremental searched word in editor. - QString m_editorIncrementalSearchedWordFg; - - QString m_editorIncrementalSearchedWordBg; - - // Enable colde block syntax highlight. - bool m_enableCodeBlockHighlight; - - // Preview images in edit mode. - bool m_enablePreviewImages; - - // Constrain the width of image preview in edit mode. - bool m_enablePreviewImageConstraint; - - // Constrain the width of image in read mode. - bool m_enableImageConstraint; - - // Center image and add the alt text as caption. - bool m_enableImageCaption; - - // Global default folder name to store images of all the notes. - // Each notebook can specify its custom folder. - QString m_imageFolder; - - // Global default folder name to store images of all external files. - // Each file can specify its custom folder. - QString m_imageFolderExt; - - // Global default folder name to store attachments of all the notes. - // Each notebook can specify its custom folder. - QString m_attachmentFolder; - - // Enable trailing-space highlight. - bool m_enableTrailingSpaceHighlight; - - // Enable tab highlight. - bool m_enableTabHighlight; - - // Editor key mode. - KeyMode m_keyMode; - - // Enable smart input method in Vim mode. - bool m_enableSmartImInVimMode; - - // Editor line number mode. - int m_editorLineNumber; - - // The background color of the line number area. - QString m_editorLineNumberBg; - - // The foreground color of the line number area. - QString m_editorLineNumberFg; - - // Shortcuts config. - // Operation -> KeySequence. - QHash m_shortcuts; - - // Shortcuts config in Captain mode. - // Operation -> KeySequence. - QHash m_captainShortcuts; - - // Whether minimize to system tray icon when closing the app. - // -1: uninitialized; - // 0: do not minimize to the tay; - // 1: minimize to the tray. - int m_minimizeToSystemTray; - - // Suffixes of different doc type. - // [DocType] -> { Suffixes }. - QHash> m_docSuffixes; - - // Interval for PegMarkdownHighlighter highlight timer (milliseconds). - int m_markdownHighlightInterval; - - // Line distance height in pixel. - int m_lineDistanceHeight; - - // Whether insert the note name as a title when creating a new note. - bool m_insertTitleFromNoteName; - - // Default mode when opening a note. - OpenFileMode m_noteOpenMode; - - // Whether auto genearte heading sequence. - HeadingSequenceType m_headingSequenceType; - - // Heading sequence base level. - int m_headingSequenceBaseLevel; - - // The column to style in code block. - int m_colorColumn; - - // Whether display line number of code block in read mode. - bool m_enableCodeBlockLineNumber; - - // The background color of the color column. - QString m_editorColorColumnBg; - - // The foreground color of the color column. - QString m_editorColorColumnFg; - - // The foreground color of the preview image line. - QString m_editorPreviewImageLineFg; - - // The forced background color of the preview image. Can be empty. - QString m_editorPreviewImageBg; - - // Icon size of tool bar in pixels. - int m_toolBarIconSize; - - // Markdown-it option. - MarkdownitOption m_markdownItOpt; - - // Default name of the recycle bin folder of notebook. - QString m_recycleBinFolder; - - // Default name of the recycle bin folder of external files. - QString m_recycleBinFolderExt; - - // Confirm before deleting unused images. - bool m_confirmImagesCleanUp; - - // Confirm before reloading folder from disk. - bool m_confirmReloadFolder; - - // Location and configuration for Mathjax. - QString m_mathjaxJavascript; - - // Whether double click on a tab to close it. - bool m_doubleClickCloseTab; - - // Whether middle click on a tab to close it. - bool m_middleClickCloseTab; - - // Type of the pages to open on startup. - StartupPageType m_startupPageType; - - // File paths to open on startup. - QStringList m_startupPages; - - // Timer interval to check file in milliseconds. - int m_fileTimerInterval; - - // Directory for the backup file (relative or absolute path). - QString m_backupDirectory; - - // Extension of the backup file. - QString m_backupExtension; - - // Skipped keys in Vim mode. - // c: Ctrl+C - // v: Ctrl+V - QString m_vimExemptionKeys; - - // Absolute path of flash page. - QString m_flashPage; - - // Absolute path of quick access note. - QString m_quickAccess; - - // Whether highlight matches in page when activating a search item. - bool m_highlightMatchesInPage; - - // The theme name. - QString m_theme; - - // All the themes. - // [name] -> [file path]. - QMap m_themes; - - // The editor style name. - QString m_editorStyle; - - // All the editor styles. - // [name] -> [file path]. - QMap m_editorStyles; - - // The web view css style name. - QString m_cssStyle; - - // All the css styles. - // [name] -> [file path]. - QMap m_cssStyles; - - // The web view code block css style name. - QString m_codeBlockCssStyle; - - // All the css styles. - // [name] -> [file path]. - QMap m_codeBlockCssStyles; - - // Whether close note before open it via external editor. - bool m_closeBeforeExternalEditor; - - // The string containing styles to inline when copied in edit mode. - QString m_stylesToInlineWhenCopied; - - // Single click to open file and then close previous tab. - bool m_singleClickClosePreviousTab; - - // Whether flash anchor in read mode. - bool m_enableFlashAnchor; - - // PlantUML mode. - int m_plantUMLMode; - - QString m_plantUMLServer; - - QString m_plantUMLJar; - - QStringList m_plantUMLArgs; - - QString m_plantUMLCmd; - - // Github image hosting. - QString m_githubPersonalAccessToken; - QString m_githubReposName; - QString m_githubUserName; - bool m_githubKeepImgScale; - bool m_githubDoNotReplaceLink; - - // Gitee image hosting. - QString m_giteePersonalAccessToken; - QString m_giteeReposName; - QString m_giteeUserName; - bool m_giteeKeepImgScale; - bool m_giteeDoNotReplaceLink; - - // Wechat image hosting. - QString m_wechatAppid; - QString m_wechatSecret; - QString m_markdown2WechatToolUrl; - bool m_wechatKeepImgScale; - bool m_wechatDoNotReplaceLink; - - // Tencent image hosting. - QString m_tencentAccessDomainName; - QString m_tencentSecretId; - QString m_tencentSecretKey; - bool m_tencentKeepImgScale; - bool m_tencentDoNotReplaceLink; - - // Size of history. - int m_historySize; - - // View order of note list. - int m_noteListViewOrder; - - // Current entry index of explorer entries. - int m_explorerCurrentIndex; - - // Whether user has reset the configurations. - bool m_hasReset; - - // Expanded level of outline. - int m_outlineExpandedLevel; - - // Prefix of the name of inserted images. - QString m_imageNamePrefix; - - // State of MainWindow panel view. - int m_panelViewState; - - // Max length of the tag label text. - int m_maxTagLabelLength; - - // Max number of tag labels to display. - int m_maxNumOfTagLabels; - - // Vim leader key. - QChar m_vimLeaderKey; - - // Smart live preview. - int m_smartLivePreview; - - // Whether insert new note in front. - bool m_insertNewNoteInFront; - - // Whether download image from parse and paste. - bool m_parsePasteLocalImage; - - // Whether the VNote instance has different version of vnote.ini. - bool m_versionChanged; - - // Whether VNote is first installed on this machine. - bool m_freshInstall; - - // Base background of MainWindow. - QColor m_baseBackground; - - // Whether enable extra buffer at the bottom of editor. - bool m_enableExtraBuffer; - - // Whether auto scroll cursor line to the middle of the window when - // cursor is at the bottom part of the content. - // 0 - disalbed - // 1 - end of doc - // 2 - always - int m_autoScrollCursorLine; - - // Editor font family to override the value set by the style. - QString m_editorFontFamily; - - // Whether prepend a dot in the relative path of images and attachments. - bool m_prependDotInRelativePath; - - // Whether enable smart table. - bool m_enableSmartTable; - - // Whether auto locate to current tab in note list. - bool m_syncNoteListToCurrentTab; - - // Interval (milliseconds) to format table. - int m_tableFormatIntervalMS; - - // Whether enable copy button in code block in read mode. - bool m_enableCodeBlockCopyButton; - - // The name of the config file in each directory. - static const QString c_dirConfigFile; - - // The path of the default configuration file - static const QString c_defaultConfigFilePath; - - // The name of the config file. - static const QString c_defaultConfigFile; - - // The name of the config file for session information. - static const QString c_sessionConfigFile; - - // The name of the config file for snippets folder. - static const QString c_snippetConfigFile; - - // The name of the config file for keyboard layouts. - static const QString c_keyboardLayoutConfigFile; - - // QSettings for the user configuration - QSettings *userSettings; - - // Qsettings for @c_defaultConfigFilePath. - QSettings *defaultSettings; - - // QSettings for the session configuration, such as notebooks, - // geometry, last opened files. - QSettings *m_sessionSettings; - - // The folder name of style files. - static const QString c_styleConfigFolder; - - // The folder name of theme files. - static const QString c_themeConfigFolder; - - // The folder name of code block style files. - static const QString c_codeBlockStyleConfigFolder; - - // The folder name of template files. - static const QString c_templateConfigFolder; - - // The folder name of snippet files. - static const QString c_snippetConfigFolder; - - // The folder name to store all notebooks if user does not specify one. - static const QString c_vnoteNotebookFolderName; - - // The default export output folder name. - static const QString c_exportFolderName; - - // The folder name of resource files. - static const QString c_resourceConfigFolder; -}; - - -inline QFont VConfigManager::getMdEditFont() const -{ - if (m_editorFontFamily.isEmpty()) { - return mdEditFont; - } else { - QFont font(mdEditFont); - font.setFamily(m_editorFontFamily); - return font; - } -} - -inline const QPalette &VConfigManager::getMdEditPalette() const -{ - return mdEditPalette; -} - -inline QVector VConfigManager::getMdHighlightingStyles() const -{ - return mdHighlightingStyles; -} - -inline QHash VConfigManager::getCodeBlockStyles() const -{ - return m_codeBlockStyles; -} - -inline QFont VConfigManager::getBaseEditFont() const -{ - return baseEditFont; -} - -inline QPalette VConfigManager::getBaseEditPalette() const -{ - return baseEditPalette; -} - -inline int VConfigManager::getCurNotebookIndex() const -{ - return curNotebookIndex; -} - -inline void VConfigManager::setCurNotebookIndex(int index) -{ - if (index == curNotebookIndex) { - return; - } - - curNotebookIndex = index; - setConfigToSessionSettings("global", "current_notebook", index); -} - -inline int VConfigManager::getNaviBoxCurrentIndex() const -{ - return getConfigFromSessionSettings("global", "navibox_current_index").toInt(); -} - -inline void VConfigManager::setNaviBoxCurrentIndex(int p_index) -{ - setConfigToSessionSettings("global", "navibox_current_index", p_index); -} - -inline void VConfigManager::getNotebooks(QVector &p_notebooks, - QObject *p_parent) -{ - // We used to store it in vnote.ini. For now, we store it in session.ini. - readNotebookFromSettings(m_sessionSettings, p_notebooks, p_parent); - - // Migration. - if (p_notebooks.isEmpty()) { - readNotebookFromSettings(userSettings, p_notebooks, p_parent); - - if (!p_notebooks.isEmpty()) { - // Clear and save it in another place. - userSettings->beginGroup("notebooks"); - userSettings->remove(""); - userSettings->endGroup(); - - writeNotebookToSettings(m_sessionSettings, p_notebooks); - } - } -} - -inline void VConfigManager::setNotebooks(const QVector &p_notebooks) -{ - writeNotebookToSettings(m_sessionSettings, p_notebooks); -} - -inline hoedown_extensions VConfigManager::getMarkdownExtensions() const -{ - return markdownExtensions; -} - -inline MarkdownConverterType VConfigManager::getMdConverterType() const -{ - return mdConverterType; -} - -inline void VConfigManager::setMarkdownConverterType(MarkdownConverterType type) -{ - if (mdConverterType == type) { - return; - } - mdConverterType = type; - setConfigToSettings("global", "markdown_converter", type); -} - -inline int VConfigManager::getTabStopWidth() const -{ - return tabStopWidth; -} - -inline bool VConfigManager::getIsExpandTab() const -{ - return isExpandTab; -} - -inline void VConfigManager::setTabStopWidth(int tabStopWidth) -{ - if (tabStopWidth == this->tabStopWidth) { - return; - } - this->tabStopWidth = tabStopWidth; - setConfigToSettings("global", "tab_stop_width", tabStopWidth); -} - -inline void VConfigManager::setIsExpandTab(bool isExpandTab) -{ - if (isExpandTab == this->isExpandTab) { - return; - } - this->isExpandTab = isExpandTab; - setConfigToSettings("global", "is_expand_tab", this->isExpandTab); -} - -inline bool VConfigManager::getHighlightCursorLine() const -{ - return m_highlightCursorLine; -} - -inline void VConfigManager::setHighlightCursorLine(bool p_cursorLine) -{ - if (p_cursorLine == m_highlightCursorLine) { - return; - } - m_highlightCursorLine = p_cursorLine; - setConfigToSettings("global", "highlight_cursor_line", m_highlightCursorLine); -} - -inline bool VConfigManager::getHighlightSelectedWord() const -{ - return m_highlightSelectedWord; -} - -inline void VConfigManager::setHighlightSelectedWord(bool p_selectedWord) -{ - if (p_selectedWord == m_highlightSelectedWord) { - return; - } - m_highlightSelectedWord = p_selectedWord; - setConfigToSettings("global", "highlight_selected_word", - m_highlightSelectedWord); -} - -inline bool VConfigManager::getHighlightSearchedWord() const -{ - return m_highlightSearchedWord; -} - -inline void VConfigManager::setHighlightSearchedWord(bool p_searchedWord) -{ - if (p_searchedWord == m_highlightSearchedWord) { - return; - } - m_highlightSearchedWord = p_searchedWord; - setConfigToSettings("global", "highlight_searched_word", - m_highlightSearchedWord); -} - -inline bool VConfigManager::getAutoIndent() const -{ - return m_autoIndent; -} - -inline void VConfigManager::setAutoIndent(bool p_autoIndent) -{ - if (m_autoIndent == p_autoIndent) { - return; - } - m_autoIndent = p_autoIndent; - setConfigToSettings("editor", "auto_indent", m_autoIndent); -} - -inline bool VConfigManager::getAutoList() const -{ - return m_autoList; -} - -inline void VConfigManager::setAutoList(bool p_autoList) -{ - if (m_autoList == p_autoList) { - return; - } - m_autoList = p_autoList; - setConfigToSettings("editor", "auto_list", m_autoList); -} - -inline bool VConfigManager::getAutoQuote() const -{ - return m_autoQuote; -} - -inline const QVector& VConfigManager::getCustomColors() const -{ - return m_customColors; -} - -inline const QString& VConfigManager::getCurBackgroundColor() const -{ - return curBackgroundColor; -} - -inline void VConfigManager::setCurBackgroundColor(const QString &colorName) -{ - if (curBackgroundColor == colorName) { - return; - } - curBackgroundColor = colorName; - setConfigToSettings("global", "current_background_color", - curBackgroundColor); - updateEditStyle(); -} - -inline const QString& VConfigManager::getCurRenderBackgroundColor() const -{ - return curRenderBackgroundColor; -} - -inline void VConfigManager::setCurRenderBackgroundColor(const QString &colorName) -{ - if (curRenderBackgroundColor == colorName) { - return; - } - curRenderBackgroundColor = colorName; - setConfigToSettings("global", "current_render_background_color", - curRenderBackgroundColor); -} - -inline bool VConfigManager::getToolsDockChecked() const -{ - return getConfigFromSettings("global", "tools_dock_checked").toBool(); -} - -inline void VConfigManager::setToolsDockChecked(bool p_checked) -{ - setConfigToSettings("global", - "tools_dock_checked", - p_checked); -} - -inline bool VConfigManager::getSearchDockChecked() const -{ - return getConfigFromSettings("global", "search_dock_checked").toBool(); -} - -inline void VConfigManager::setSearchDockChecked(bool p_checked) -{ - setConfigToSettings("global", - "search_dock_checked", - p_checked); -} - -inline const QByteArray VConfigManager::getMainWindowGeometry() const -{ - return getConfigFromSessionSettings("geometry", - "main_window_geometry").toByteArray(); -} - -inline void VConfigManager::setMainWindowGeometry(const QByteArray &p_geometry) -{ - setConfigToSessionSettings("geometry", - "main_window_geometry", - p_geometry); -} - -inline const QByteArray VConfigManager::getMainWindowState() const -{ - return getConfigFromSessionSettings("geometry", - "main_window_state").toByteArray(); -} - -inline void VConfigManager::setMainWindowState(const QByteArray &p_state) -{ - setConfigToSessionSettings("geometry", - "main_window_state", - p_state); -} - -inline const QByteArray VConfigManager::getMainSplitterState() const -{ - return getConfigFromSessionSettings("geometry", - "main_splitter_state").toByteArray(); -} - -inline void VConfigManager::setMainSplitterState(const QByteArray &p_state) -{ - setConfigToSessionSettings("geometry", - "main_splitter_state", - p_state); -} - -inline const QByteArray VConfigManager::getNotebookSplitterState() const -{ - return getConfigFromSessionSettings("geometry", - "notebook_splitter_state").toByteArray(); -} - -inline void VConfigManager::setNotebookSplitterState(const QByteArray &p_state) -{ - setConfigToSessionSettings("geometry", - "notebook_splitter_state", - p_state); -} - -inline const QByteArray VConfigManager::getTagExplorerSplitterState() const -{ - return getConfigFromSessionSettings("geometry", - "tag_explorer_splitter_state").toByteArray(); -} - -inline void VConfigManager::setTagExplorerSplitterState(const QByteArray &p_state) -{ - setConfigToSessionSettings("geometry", - "tag_explorer_splitter_state", - p_state); -} - -inline bool VConfigManager::getFindCaseSensitive() const -{ - return m_findCaseSensitive; -} - -inline void VConfigManager::setFindCaseSensitive(bool p_enabled) -{ - if (m_findCaseSensitive == p_enabled) { - return; - } - m_findCaseSensitive = p_enabled; - setConfigToSettings("global", "find_case_sensitive", m_findCaseSensitive); -} - -inline bool VConfigManager::getFindWholeWordOnly() const -{ - return m_findWholeWordOnly; -} - -inline void VConfigManager::setFindWholeWordOnly(bool p_enabled) -{ - if (m_findWholeWordOnly == p_enabled) { - return; - } - m_findWholeWordOnly = p_enabled; - setConfigToSettings("global", "find_whole_word_only", m_findWholeWordOnly); -} - -inline bool VConfigManager::getFindRegularExpression() const -{ - return m_findRegularExpression; -} - -inline void VConfigManager::setFindRegularExpression(bool p_enabled) -{ - if (m_findRegularExpression == p_enabled) { - return; - } - m_findRegularExpression = p_enabled; - setConfigToSettings("global", "find_regular_expression", - m_findRegularExpression); -} - -inline bool VConfigManager::getFindIncrementalSearch() const -{ - return m_findIncrementalSearch; -} - -inline void VConfigManager::setFindIncrementalSearch(bool p_enabled) -{ - if (m_findIncrementalSearch == p_enabled) { - return; - } - m_findIncrementalSearch = p_enabled; - setConfigToSettings("global", "find_incremental_search", - m_findIncrementalSearch); -} - -inline QString VConfigManager::getLanguage() const -{ - return m_language; -} - -inline void VConfigManager::setLanguage(const QString &p_language) -{ - if (m_language == p_language) { - return; - } - m_language = p_language; - setConfigToSettings("global", "language", - m_language); -} - -inline bool VConfigManager::getEnableMermaid() const -{ - return m_enableMermaid; -} - -inline void VConfigManager::setEnableMermaid(bool p_enabled) -{ - if (m_enableMermaid == p_enabled) { - return; - } - m_enableMermaid = p_enabled; - setConfigToSettings("global", "enable_mermaid", m_enableMermaid); -} - -inline bool VConfigManager::getEnableFlowchart() const -{ - return m_enableFlowchart; -} - -inline void VConfigManager::setEnableFlowchart(bool p_enabled) -{ - if (m_enableFlowchart == p_enabled) { - return; - } - - m_enableFlowchart = p_enabled; - setConfigToSettings("global", "enable_flowchart", m_enableFlowchart); -} - -inline bool VConfigManager::getEnableMathjax() const -{ - return m_enableMathjax; -} - -inline void VConfigManager::setEnableMathjax(bool p_enabled) -{ - if (m_enableMathjax == p_enabled) { - return; - } - - m_enableMathjax = p_enabled; - setConfigToSettings("global", "enable_mathjax", m_enableMathjax); -} - -inline bool VConfigManager::getEnableWavedrom() const -{ - return m_enableWavedrom; -} - -inline void VConfigManager::setEnableWavedrom(bool p_enabled) -{ - if (m_enableWavedrom == p_enabled) { - return; - } - - m_enableWavedrom = p_enabled; - setConfigToSettings("markdown", "enable_wavedrom", m_enableWavedrom); -} - -inline bool VConfigManager::getEnableGraphviz() const -{ - return m_enableGraphviz; -} - -inline void VConfigManager::setEnableGraphviz(bool p_enabled) -{ - if (m_enableGraphviz == p_enabled) { - return; - } - - m_enableGraphviz = p_enabled; - setConfigToSettings("global", "enable_graphviz", m_enableGraphviz); -} - -inline int VConfigManager::getPlantUMLMode() const -{ - return m_plantUMLMode; -} - -inline void VConfigManager::setPlantUMLMode(int p_mode) -{ - if (m_plantUMLMode == p_mode) { - return; - } - - m_plantUMLMode = p_mode; - setConfigToSettings("global", "plantuml_mode", p_mode); -} - -inline qreal VConfigManager::getWebZoomFactor() const -{ - return m_webZoomFactor; -} - -inline bool VConfigManager::isCustomWebZoomFactor() -{ - qreal factorFromIni = getConfigFromSettings("global", "web_zoom_factor").toReal(); - // -1 indicates let system automatically calculate the factor. - return factorFromIni > 0; -} - -inline int VConfigManager::getEditorZoomDelta() const -{ - return m_editorZoomDelta; -} - -inline void VConfigManager::setEditorZoomDelta(int p_delta) -{ - if (m_editorZoomDelta == p_delta) { - return; - } - - m_editorZoomDelta = p_delta; - setConfigToSettings("global", "editor_zoom_delta", m_editorZoomDelta); -} - -inline const QString &VConfigManager::getEditorCurrentLineBg() const -{ - return m_editorCurrentLineBg; -} - -inline const QString &VConfigManager::getEditorTrailingSpaceBg() const -{ - return m_editorTrailingSpaceBg; -} - -inline const QString &VConfigManager::getEditorSelectedWordFg() const -{ - return m_editorSelectedWordFg; -} - -inline const QString &VConfigManager::getEditorSelectedWordBg() const -{ - return m_editorSelectedWordBg; -} - -inline const QString &VConfigManager::getEditorSearchedWordFg() const -{ - return m_editorSearchedWordFg; -} - -inline const QString &VConfigManager::getEditorSearchedWordBg() const -{ - return m_editorSearchedWordBg; -} - -inline const QString &VConfigManager::getEditorSearchedWordCursorFg() const -{ - return m_editorSearchedWordCursorFg; -} - -inline const QString &VConfigManager::getEditorSearchedWordCursorBg() const -{ - return m_editorSearchedWordCursorBg; -} - -inline const QString &VConfigManager::getEditorIncrementalSearchedWordFg() const -{ - return m_editorIncrementalSearchedWordFg; -} - -inline const QString &VConfigManager::getEditorIncrementalSearchedWordBg() const -{ - return m_editorIncrementalSearchedWordBg; -} - -inline const QString &VConfigManager::getEditorVimNormalBg() const -{ - return m_editorVimNormalBg; -} - -inline const QString &VConfigManager::getEditorVimInsertBg() const -{ - return m_editorVimInsertBg; -} - -inline const QString &VConfigManager::getEditorVimVisualBg() const -{ - return m_editorVimVisualBg; -} - -inline const QString &VConfigManager::getEditorVimReplaceBg() const -{ - return m_editorVimReplaceBg; -} - -inline bool VConfigManager::getEnableCodeBlockHighlight() const -{ - return m_enableCodeBlockHighlight; -} - -inline void VConfigManager::setEnableCodeBlockHighlight(bool p_enabled) -{ - if (m_enableCodeBlockHighlight == p_enabled) { - return; - } - m_enableCodeBlockHighlight = p_enabled; - setConfigToSettings("global", "enable_code_block_highlight", - m_enableCodeBlockHighlight); -} - -inline bool VConfigManager::getEnablePreviewImages() const -{ - return m_enablePreviewImages; -} - -inline void VConfigManager::setEnablePreviewImages(bool p_enabled) -{ - if (m_enablePreviewImages == p_enabled) { - return; - } - - m_enablePreviewImages = p_enabled; - setConfigToSettings("global", "enable_preview_images", - m_enablePreviewImages); -} - -inline bool VConfigManager::getEnablePreviewImageConstraint() const -{ - return m_enablePreviewImageConstraint; -} - -inline void VConfigManager::setEnablePreviewImageConstraint(bool p_enabled) -{ - if (m_enablePreviewImageConstraint == p_enabled) { - return; - } - - m_enablePreviewImageConstraint = p_enabled; - setConfigToSettings("global", "enable_preview_image_constraint", - m_enablePreviewImageConstraint); -} - -inline bool VConfigManager::getEnableImageConstraint() const -{ - return m_enableImageConstraint; -} - -inline void VConfigManager::setEnableImageConstraint(bool p_enabled) -{ - if (m_enableImageConstraint == p_enabled) { - return; - } - - m_enableImageConstraint = p_enabled; - setConfigToSettings("global", "enable_image_constraint", - m_enableImageConstraint); -} - -inline bool VConfigManager::getEnableImageCaption() const -{ - return m_enableImageCaption; -} - -inline void VConfigManager::setEnableImageCaption(bool p_enabled) -{ - if (m_enableImageCaption == p_enabled) { - return; - } - m_enableImageCaption = p_enabled; - setConfigToSettings("global", "enable_image_caption", - m_enableImageCaption); -} - -inline const QString &VConfigManager::getImageFolder() const -{ - return m_imageFolder; -} - -inline void VConfigManager::setImageFolder(const QString &p_folder) -{ - if (p_folder.isEmpty()) { - // Reset the default folder. - m_imageFolder = resetDefaultConfig("global", "image_folder").toString(); - return; - } - - if (m_imageFolder == p_folder) { - return; - } - - m_imageFolder = p_folder; - setConfigToSettings("global", "image_folder", m_imageFolder); -} - -inline bool VConfigManager::isCustomImageFolder() const -{ - return m_imageFolder != getDefaultConfig("global", "image_folder").toString(); -} - -inline const QString &VConfigManager::getImageFolderExt() const -{ - return m_imageFolderExt; -} - -inline void VConfigManager::setImageFolderExt(const QString &p_folder) -{ - if (p_folder.isEmpty()) { - // Reset the default folder. - m_imageFolderExt = resetDefaultConfig("global", "external_image_folder").toString(); - return; - } - - if (m_imageFolderExt == p_folder) { - return; - } - - m_imageFolderExt = p_folder; - setConfigToSettings("global", "external_image_folder", m_imageFolderExt); -} - -inline bool VConfigManager::isCustomImageFolderExt() const -{ - return m_imageFolderExt != getDefaultConfig("global", "external_image_folder").toString(); -} - -inline const QString &VConfigManager::getAttachmentFolder() const -{ - return m_attachmentFolder; -} - -inline void VConfigManager::setAttachmentFolder(const QString &p_folder) -{ - if (p_folder.isEmpty()) { - // Reset the default folder. - m_attachmentFolder = resetDefaultConfig("global", "attachment_folder").toString(); - return; - } - - if (m_attachmentFolder == p_folder) { - return; - } - - m_attachmentFolder = p_folder; - setConfigToSettings("global", "attachment_folder", m_attachmentFolder); -} - -inline bool VConfigManager::isCustomAttachmentFolder() const -{ - return m_attachmentFolder != getDefaultConfig("global", "attachment_folder").toString(); -} - -inline bool VConfigManager::getEnableTrailingSpaceHighlight() const -{ - return m_enableTrailingSpaceHighlight; -} - -inline void VConfigManager::setEnableTrailingSapceHighlight(bool p_enabled) -{ - if (m_enableTrailingSpaceHighlight == p_enabled) { - return; - } - - m_enableTrailingSpaceHighlight = p_enabled; - setConfigToSettings("global", "enable_trailing_space_highlight", - m_enableTrailingSpaceHighlight); -} - -inline bool VConfigManager::getEnableTabHighlight() const -{ - return m_enableTabHighlight; -} - -inline void VConfigManager::setEnableTabHighlight(bool p_enabled) -{ - if (m_enableTabHighlight == p_enabled) { - return; - } - - m_enableTabHighlight = p_enabled; - setConfigToSettings("editor", - "enable_tab_highlight", - m_enableTabHighlight); -} - -inline KeyMode VConfigManager::getKeyMode() const -{ - return m_keyMode; -} - -inline void VConfigManager::setKeyMode(KeyMode p_mode) -{ - if (m_keyMode == p_mode) { - return; - } - - m_keyMode = p_mode; - setConfigToSettings("editor", "key_mode", (int)m_keyMode); -} - -inline bool VConfigManager::getEnableVimMode() const -{ - return m_keyMode == KeyMode::Vim; -} - -inline bool VConfigManager::getEnableSmartImInVimMode() const -{ - return m_enableSmartImInVimMode; -} - -inline void VConfigManager::setEnableSmartImInVimMode(bool p_enabled) -{ - if (m_enableSmartImInVimMode == p_enabled) { - return; - } - - m_enableSmartImInVimMode = p_enabled; - setConfigToSettings("editor", "enable_smart_im_in_vim_mode", - m_enableSmartImInVimMode); -} - -inline int VConfigManager::getEditorLineNumber() const -{ - return m_editorLineNumber; -} - -inline void VConfigManager::setEditorLineNumber(int p_mode) -{ - if (m_editorLineNumber == p_mode) { - return; - } - - m_editorLineNumber = p_mode; - setConfigToSettings("global", "editor_line_number", - m_editorLineNumber); -} - -inline const QString &VConfigManager::getEditorLineNumberBg() const -{ - return m_editorLineNumberBg; -} - -inline const QString &VConfigManager::getEditorLineNumberFg() const -{ - return m_editorLineNumberFg; -} - -inline int VConfigManager::getMinimizeToStystemTray() const -{ - return m_minimizeToSystemTray; -} - -inline void VConfigManager::setMinimizeToSystemTray(int p_val) -{ - if (m_minimizeToSystemTray == p_val) { - return; - } - - m_minimizeToSystemTray = p_val; - setConfigToSettings("global", "minimize_to_system_tray", - m_minimizeToSystemTray); -} - -inline const QHash> &VConfigManager::getDocSuffixes() const -{ - return m_docSuffixes; -} - -inline int VConfigManager::getMarkdownHighlightInterval() const -{ - return m_markdownHighlightInterval; -} - -inline int VConfigManager::getLineDistanceHeight() const -{ - return m_lineDistanceHeight; -} - -inline bool VConfigManager::getInsertTitleFromNoteName() const -{ - return m_insertTitleFromNoteName; -} - -inline void VConfigManager::setInsertTitleFromNoteName(bool p_enabled) -{ - if (p_enabled == m_insertTitleFromNoteName) { - return; - } - - m_insertTitleFromNoteName = p_enabled; - setConfigToSettings("global", "insert_title_from_note_name", - m_insertTitleFromNoteName); -} - -inline OpenFileMode VConfigManager::getNoteOpenMode() const -{ - return m_noteOpenMode; -} - -inline void VConfigManager::setNoteOpenMode(OpenFileMode p_mode) -{ - if (m_noteOpenMode == p_mode) { - return; - } - - m_noteOpenMode = p_mode; - setConfigToSettings("global", "note_open_mode", - m_noteOpenMode == OpenFileMode::Read ? 0 : 1); -} - -inline HeadingSequenceType VConfigManager::getHeadingSequenceType() const -{ - return m_headingSequenceType; -} - -inline void VConfigManager::setHeadingSequenceType(HeadingSequenceType p_type) -{ - if (m_headingSequenceType == p_type) { - return; - } - - m_headingSequenceType = p_type; - setConfigToSettings("global", - "heading_sequence_type", - (int)m_headingSequenceType); -} - -inline int VConfigManager::getHeadingSequenceBaseLevel() const -{ - return m_headingSequenceBaseLevel; -} - -inline void VConfigManager::setHeadingSequenceBaseLevel(int p_level) -{ - if (m_headingSequenceBaseLevel == p_level) { - return; - } - - m_headingSequenceBaseLevel = p_level; - setConfigToSettings("global", - "heading_sequence_base_level", - m_headingSequenceBaseLevel); -} - -inline int VConfigManager::getColorColumn() const -{ - return m_colorColumn; -} - -inline void VConfigManager::setColorColumn(int p_column) -{ - if (m_colorColumn == p_column) { - return; - } - - m_colorColumn = p_column; - setConfigToSettings("global", "color_column", m_colorColumn); -} - -inline const QString &VConfigManager::getEditorColorColumnBg() const -{ - return m_editorColorColumnBg; -} - -inline const QString &VConfigManager::getEditorColorColumnFg() const -{ - return m_editorColorColumnFg; -} - -inline const QString &VConfigManager::getEditorPreviewImageLineFg() const -{ - return m_editorPreviewImageLineFg; -} - -inline const QString &VConfigManager::getEditorPreviewImageBg() const -{ - return m_editorPreviewImageBg; -} - -inline bool VConfigManager::getEnableCodeBlockLineNumber() const -{ - return m_enableCodeBlockLineNumber; -} - -inline void VConfigManager::setEnableCodeBlockLineNumber(bool p_enabled) -{ - if (m_enableCodeBlockLineNumber == p_enabled) { - return; - } - - m_enableCodeBlockLineNumber = p_enabled; - setConfigToSettings("global", - "enable_code_block_line_number", - m_enableCodeBlockLineNumber); -} - -inline int VConfigManager::getToolBarIconSize() const -{ - return m_toolBarIconSize; -} - -inline void VConfigManager::setToolBarIconSize(int p_size) -{ - if (m_toolBarIconSize == p_size) { - return; - } - - m_toolBarIconSize = p_size; - setConfigToSettings("global", - "tool_bar_icon_size", - m_toolBarIconSize); -} -inline const MarkdownitOption &VConfigManager::getMarkdownitOption() const -{ - return m_markdownItOpt; -} - -inline void VConfigManager::setMarkdownitOption(const MarkdownitOption &p_opt) -{ - if (m_markdownItOpt == p_opt) { - return; - } - - m_markdownItOpt = p_opt; - setConfigToSettings("web", "markdownit_opt", m_markdownItOpt.toConfig()); -} - -inline const QString &VConfigManager::getRecycleBinFolder() const -{ - return m_recycleBinFolder; -} - -inline const QString &VConfigManager::getRecycleBinFolderExt() const -{ - return m_recycleBinFolderExt; -} - -inline bool VConfigManager::getConfirmImagesCleanUp() const -{ - return m_confirmImagesCleanUp; -} - -inline void VConfigManager::setConfirmImagesCleanUp(bool p_enabled) -{ - if (m_confirmImagesCleanUp == p_enabled) { - return; - } - - m_confirmImagesCleanUp = p_enabled; - setConfigToSettings("global", - "confirm_images_clean_up", - m_confirmImagesCleanUp); -} - -inline bool VConfigManager::getConfirmReloadFolder() const -{ - return m_confirmReloadFolder; -} - -inline void VConfigManager::setConfirmReloadFolder(bool p_enabled) -{ - if (m_confirmReloadFolder == p_enabled) { - return; - } - - m_confirmReloadFolder = p_enabled; - setConfigToSettings("global", - "confirm_reload_folder", - m_confirmReloadFolder); -} - -inline const QString &VConfigManager::getMathjaxJavascript() const -{ - return m_mathjaxJavascript; -} - -inline void VConfigManager::setMathjaxJavascript(const QString &p_js) -{ - if (m_mathjaxJavascript == p_js) { - return; - } - - if (p_js.isEmpty()) { - m_mathjaxJavascript = resetDefaultConfig("web", "mathjax_javascript").toString(); - } else { - m_mathjaxJavascript = p_js; - setConfigToSettings("web", - "mathjax_javascript", - m_mathjaxJavascript); - } -} - -inline bool VConfigManager::getDoubleClickCloseTab() const -{ - return m_doubleClickCloseTab; -} - -inline bool VConfigManager::getMiddleClickClostTab() const -{ - return m_middleClickCloseTab; -} - -inline StartupPageType VConfigManager::getStartupPageType() const -{ - return m_startupPageType; -} - -inline void VConfigManager::setStartupPageType(StartupPageType p_type) -{ - if (m_startupPageType == p_type) { - return; - } - - m_startupPageType = p_type; - setConfigToSettings("global", "startup_page_type", (int)m_startupPageType); -} - -inline const QStringList &VConfigManager::getStartupPages() const -{ - return m_startupPages; -} - -inline void VConfigManager::setStartupPages(const QStringList &p_pages) -{ - if (m_startupPages == p_pages) { - return; - } - - m_startupPages = p_pages; - setConfigToSettings("global", "startup_pages", m_startupPages); -} - -inline int VConfigManager::getFileTimerInterval() const -{ - return m_fileTimerInterval; -} - -inline const QString &VConfigManager::getBackupDirectory() const -{ - return m_backupDirectory; -} - -inline const QString &VConfigManager::getBackupExtension() const -{ - return m_backupExtension; -} - -inline bool VConfigManager::getEnableBackupFile() const -{ - return getConfigFromSettings("global", - "enable_backup_file").toBool(); -} - -inline void VConfigManager::setEnableBackupFile(bool p_enabled) -{ - setConfigToSettings("global", "enable_backup_file", p_enabled); -} - -inline const QString &VConfigManager::getVimExemptionKeys() const -{ - return m_vimExemptionKeys; -} - -inline QList VConfigManager::getThemes() const -{ - return m_themes.keys(); -} - -inline const QString &VConfigManager::getTheme() const -{ - return m_theme; -} - -inline void VConfigManager::setTheme(const QString &p_theme) -{ - if (p_theme == m_theme) { - return; - } - - m_theme = p_theme; - setConfigToSettings("global", "theme", m_theme); - setConfigToSettings("global", "editor_style", ""); - setConfigToSettings("global", "css_style", ""); - setConfigToSettings("global", "code_block_css_style", ""); -} - -inline QList VConfigManager::getEditorStyles() const -{ - return m_editorStyles.keys(); -} - -inline const QString &VConfigManager::getEditorStyle() const -{ - return m_editorStyle; -} - -inline void VConfigManager::setEditorStyle(const QString &p_style) -{ - if (m_editorStyle == p_style) { - return; - } - - m_editorStyle = p_style; - setConfigToSettings("global", "editor_style", m_editorStyle); - updateEditStyle(); -} - -inline QList VConfigManager::getCssStyles() const -{ - return m_cssStyles.keys(); -} - -inline const QString &VConfigManager::getCssStyle() const -{ - return m_cssStyle; -} - -inline void VConfigManager::setCssStyle(const QString &p_style) -{ - if (m_cssStyle == p_style) { - return; - } - - m_cssStyle = p_style; - setConfigToSettings("global", "css_style", m_cssStyle); -} - -inline QList VConfigManager::getCodeBlockCssStyles() const -{ - return m_codeBlockCssStyles.keys(); -} - -inline const QString &VConfigManager::getCodeBlockCssStyle() const -{ - return m_codeBlockCssStyle; -} - -inline void VConfigManager::setCodeBlockCssStyle(const QString &p_style) -{ - if (m_codeBlockCssStyle == p_style) { - return; - } - - m_codeBlockCssStyle = p_style; - setConfigToSettings("global", "code_block_css_style", m_codeBlockCssStyle); -} - -inline bool VConfigManager::getCloseBeforeExternalEditor() const -{ - return m_closeBeforeExternalEditor; -} - -inline QStringList VConfigManager::getStylesToRemoveWhenCopied() const -{ - return getConfigFromSettings("web", - "styles_to_remove_when_copied").toStringList(); - -} - -inline const QString &VConfigManager::getStylesToInlineWhenCopied() const -{ - return m_stylesToInlineWhenCopied; -} - -inline QStringList VConfigManager::getCopyTargets() const -{ - return getConfigFromSettings("web", - "copy_targets").toStringList(); -} - -inline QString VConfigManager::getStyleOfSpanForMark() const -{ - return getConfigFromSettings("web", - "style_of_span_for_mark").toString(); -} - -inline bool VConfigManager::getMenuBarChecked() const -{ - return getConfigFromSettings("global", - "menu_bar_checked").toBool(); -} - -inline void VConfigManager::setMenuBarChecked(bool p_checked) -{ - setConfigToSettings("global", "menu_bar_checked", p_checked); -} - -inline bool VConfigManager::getToolBarChecked() const -{ - return getConfigFromSettings("global", - "tool_bar_checked").toBool(); -} - -inline void VConfigManager::setToolBarChecked(bool p_checked) -{ - setConfigToSettings("global", "tool_bar_checked", p_checked); -} - -inline bool VConfigManager::getSingleClickClosePreviousTab() const -{ - return m_singleClickClosePreviousTab; -} - -inline void VConfigManager::setSingleClickClosePreviousTab(bool p_enabled) -{ - if (m_singleClickClosePreviousTab == p_enabled) { - return; - } - - m_singleClickClosePreviousTab = p_enabled; - setConfigToSettings("global", "single_click_close_previous_tab", m_singleClickClosePreviousTab); -} - -inline bool VConfigManager::getEnableWildCardInSimpleSearch() const -{ - return getConfigFromSettings("global", - "enable_wildcard_in_simple_search").toBool(); -} - -inline bool VConfigManager::getEnableAutoSave() const -{ - return getConfigFromSettings("global", - "enable_auto_save").toBool(); -} - -inline void VConfigManager::setEnableAutoSave(bool p_enabled) -{ - setConfigToSettings("global", "enable_auto_save", p_enabled); -} - -inline QString VConfigManager::getWkhtmltopdfPath() const -{ - return getConfigFromSettings("export", - "wkhtmltopdf").toString(); -} - -inline void VConfigManager::setWkhtmltopdfPath(const QString &p_file) -{ - setConfigToSettings("export", "wkhtmltopdf", p_file); -} - -inline QString VConfigManager::getWkhtmltopdfArgs() const -{ - return getConfigFromSettings("export", - "wkhtmltopdfArgs").toString(); -} - -inline void VConfigManager::setWkhtmltopdfArgs(const QString &p_file) -{ - setConfigToSettings("export", "wkhtmltopdfArgs", p_file); -} - -inline bool VConfigManager::getEnableFlashAnchor() const -{ - return m_enableFlashAnchor; -} - -inline void VConfigManager::setEnableFlashAnchor(bool p_enabled) -{ - if (p_enabled == m_enableFlashAnchor) { - return; - } - - m_enableFlashAnchor = p_enabled; - setConfigToSettings("web", "enable_flash_anchor", m_enableFlashAnchor); -} - -inline QStringList VConfigManager::getCustomExport() const -{ - return getConfigFromSettings("export", - "custom_export").toStringList(); -} - -inline void VConfigManager::setCustomExport(const QStringList &p_exp) -{ - setConfigToSettings("export", "custom_export", p_exp); -} - -inline QStringList VConfigManager::getSearchOptions() const -{ - return getConfigFromSettings("global", - "search_options").toStringList(); -} - -inline void VConfigManager::setSearchOptions(const QStringList &p_opts) -{ - setConfigToSettings("global", "search_options", p_opts); -} - -inline const QString &VConfigManager::getPlantUMLServer() const -{ - return m_plantUMLServer; -} - -inline void VConfigManager::setPlantUMLServer(const QString &p_server) -{ - if (m_plantUMLServer == p_server) { - return; - } - - m_plantUMLServer = p_server; - setConfigToSettings("web", "plantuml_server", p_server); -} - -inline const QString &VConfigManager::getPlantUMLJar() const -{ - return m_plantUMLJar; -} - -inline void VConfigManager::setPlantUMLJar(const QString &p_jarPath) -{ - if (m_plantUMLJar == p_jarPath) { - return; - } - - m_plantUMLJar = p_jarPath; - setConfigToSettings("web", "plantuml_jar", p_jarPath); -} - -inline const QStringList &VConfigManager::getPlantUMLArgs() const -{ - return m_plantUMLArgs; -} - -inline const QString &VConfigManager::getPlantUMLCmd() const -{ - return m_plantUMLCmd; -} - -inline const QString &VConfigManager::getGraphvizDot() const -{ - return m_graphvizDot; -} - -inline void VConfigManager::setGraphvizDot(const QString &p_dotPath) -{ - if (m_graphvizDot == p_dotPath) { - return; - } - - m_graphvizDot = p_dotPath; - setConfigToSettings("web", "graphviz_dot", p_dotPath); -} - -inline int VConfigManager::getHistorySize() const -{ - return m_historySize; -} - -inline int VConfigManager::getNoteListViewOrder() const -{ - if (m_noteListViewOrder == -1) { - const_cast(this)->m_noteListViewOrder = getConfigFromSettings("global", "note_list_view_order").toInt(); - } - - return m_noteListViewOrder; -} - -inline void VConfigManager::setNoteListViewOrder(int p_order) -{ - if (m_noteListViewOrder == p_order) { - return; - } - - m_noteListViewOrder = p_order; - setConfigToSettings("global", "note_list_view_order", m_noteListViewOrder); -} - -inline int VConfigManager::getExplorerCurrentIndex() const -{ - if (m_explorerCurrentIndex == -1) { - const_cast(this)->m_explorerCurrentIndex = getConfigFromSessionSettings("global", "explorer_current_entry").toInt(); - } - - return m_explorerCurrentIndex; -} - -inline void VConfigManager::setExplorerCurrentIndex(int p_idx) -{ - if (p_idx == m_explorerCurrentIndex) { - return; - } - - m_explorerCurrentIndex = p_idx; - setConfigToSessionSettings("global", "explorer_current_entry", m_explorerCurrentIndex); -} - -inline QString VConfigManager::fetchDirConfigFilePath(const QString &p_path) -{ - return QDir(p_path).filePath(c_dirConfigFile); -} - -inline int VConfigManager::getOutlineExpandedLevel() const -{ - return m_outlineExpandedLevel; -} - -inline void VConfigManager::setOutlineExpandedLevel(int p_level) -{ - if (m_outlineExpandedLevel == p_level) { - return; - } - - m_outlineExpandedLevel = p_level; - setConfigToSettings("global", "outline_expanded_level", m_outlineExpandedLevel); -} - -inline const QString &VConfigManager::getImageNamePrefix() const -{ - return m_imageNamePrefix; -} - -inline int VConfigManager::getPanelViewState() const -{ - return m_panelViewState; -} - -inline void VConfigManager::setPanelViewState(int p_state) -{ - if (m_panelViewState == p_state) { - return; - } - - m_panelViewState = p_state; - setConfigToSettings("global", "panel_view_state", m_panelViewState); -} - -inline int VConfigManager::getMaxTagLabelLength() const -{ - return m_maxTagLabelLength; -} - -inline int VConfigManager::getMaxNumOfTagLabels() const -{ - return m_maxNumOfTagLabels; -} - -inline QChar VConfigManager::getVimLeaderKey() const -{ - return m_vimLeaderKey; -} - -inline int VConfigManager::getSmartLivePreview() const -{ - return m_smartLivePreview; -} - -inline void VConfigManager::setSmartLivePreview(int p_preview) -{ - if (m_smartLivePreview == p_preview) { - return; - } - - m_smartLivePreview = p_preview; - setConfigToSettings("global", "smart_live_preview", m_smartLivePreview); -} - -inline bool VConfigManager::getInsertNewNoteInFront() const -{ - return m_insertNewNoteInFront; -} - -inline void VConfigManager::setInsertNewNoteInFront(bool p_enabled) -{ - if (m_insertNewNoteInFront == p_enabled) { - return; - } - - m_insertNewNoteInFront = p_enabled; - setConfigToSettings("global", "insert_new_note_in_front", m_insertNewNoteInFront); -} - -inline void VConfigManager::setQuickAccess(const QString &p_path) -{ - if (m_quickAccess == p_path) { - return; - } - - m_quickAccess = p_path; - setConfigToSettings("global", "quick_access", m_quickAccess); -} - -inline bool VConfigManager::getHighlightMatchesInPage() const -{ - return m_highlightMatchesInPage; -} - -inline void VConfigManager::setHighlightMatchesInPage(bool p_enabled) -{ - if (m_highlightMatchesInPage == p_enabled) { - return; - } - - m_highlightMatchesInPage = p_enabled; - setConfigToSettings("global", "highlight_matches_in_page", m_highlightMatchesInPage); -} - -inline QString VConfigManager::getKeyboardLayout() const -{ - return getConfigFromSettings("global", "keyboard_layout").toString(); -} - -inline void VConfigManager::setKeyboardLayout(const QString &p_name) -{ - setConfigToSettings("global", "keyboard_layout", p_name); -} - -inline QList VConfigManager::getKeyboardLayoutMappingKeys() const -{ - QStringList keyStrs = getConfigFromSettings("global", - "keyboard_layout_mapping_keys").toStringList(); - - QList keys; - for (auto & str : keyStrs) { - bool ok; - int tmp = str.toInt(&ok); - if (ok) { - keys.append(tmp); - } - } - - return keys; -} - -inline bool VConfigManager::getParsePasteLocalImage() const -{ - return m_parsePasteLocalImage; -} - -inline bool VConfigManager::versionChanged() const -{ - return m_versionChanged; -} - -inline bool VConfigManager::isFreshInstall() const -{ - return m_freshInstall; -} - -inline const QColor &VConfigManager::getBaseBackground() const -{ - return m_baseBackground; -} - -inline void VConfigManager::setBaseBackground(const QColor &p_bg) -{ - m_baseBackground = p_bg; -} - -inline bool VConfigManager::getEnableExtraBuffer() const -{ - return m_enableExtraBuffer; -} - -inline int VConfigManager::getAutoScrollCursorLine() const -{ - if (m_enableExtraBuffer) { - return m_autoScrollCursorLine; - } else { - return AutoScrollDisabled; - } -} - -inline void VConfigManager::setAutoScrollCursorLine(int p_mode) -{ - m_autoScrollCursorLine = p_mode; - if (p_mode == AutoScrollDisabled) { - setConfigToSettings("editor", "auto_scroll_cursor_line", m_autoScrollCursorLine); - } else { - if (!m_enableExtraBuffer) { - m_enableExtraBuffer = true; - setConfigToSettings("editor", "enable_extra_buffer", m_enableExtraBuffer); - } - - setConfigToSettings("editor", "auto_scroll_cursor_line", m_autoScrollCursorLine); - } -} - -inline const QString &VConfigManager::getEditorFontFamily() const -{ - return m_editorFontFamily; -} - -inline void VConfigManager::setEditorFontFamily(const QString &p_font) -{ - if (m_editorFontFamily == p_font) { - return; - } - - m_editorFontFamily = p_font; - - setConfigToSettings("editor", "editor_font_family", m_editorFontFamily); -} - -inline bool VConfigManager::getEnableSplitFileList() const -{ - return getConfigFromSettings("global", "split_file_list").toBool(); -} - -inline void VConfigManager::setEnableSplitFileList(bool p_enable) -{ - setConfigToSettings("global", "split_file_list", p_enable); -} - -inline bool VConfigManager::getEnableSplitTagFileList() const -{ - return getConfigFromSettings("global", "split_tag_file_list").toBool(); -} - -inline void VConfigManager::setEnableSplitTagFileList(bool p_enable) -{ - setConfigToSettings("global", "split_tag_file_list", p_enable); -} - -inline QString VConfigManager::getImageBrowsePath() const -{ - return getConfigFromSessionSettings("global", "image_browse_path").toString(); -} - -inline void VConfigManager::setImageBrowsePath(const QString &p_path) -{ - setConfigToSessionSettings("global", "image_browse_path", p_path); -} - -inline bool VConfigManager::getPrependDotInRelativePath() const -{ - return m_prependDotInRelativePath; -} - -inline void VConfigManager::setPrependDotInRelativePath(bool p_enabled) -{ - if (m_prependDotInRelativePath == p_enabled) { - return; - } - - m_prependDotInRelativePath = p_enabled; - setConfigToSettings("markdown", "prepend_dot_in_relative_path", m_prependDotInRelativePath); -} - -inline bool VConfigManager::getEnableSmartTable() const -{ - return m_enableSmartTable; -} - -inline void VConfigManager::setEnableSmartTable(bool p_enabled) -{ - if (m_enableSmartTable == p_enabled) { - return; - } - - m_enableSmartTable = p_enabled; - setConfigToSettings("editor", "enable_smart_table", m_enableSmartTable); -} - -inline bool VConfigManager::getAllowUserTrack() const -{ - return getConfigFromSettings("global", "allow_user_track").toBool(); -} - -inline void VConfigManager::setAllowUserTrack(bool p_enabled) -{ - setConfigToSettings("global", "allow_user_track", p_enabled); -} - -inline bool VConfigManager::getSyncNoteListToTab() const -{ - return m_syncNoteListToCurrentTab; -} - -inline void VConfigManager::setSyncNoteListToTab(bool p_enabled) -{ - if (m_syncNoteListToCurrentTab == p_enabled) { - return; - } - - m_syncNoteListToCurrentTab = p_enabled; - setConfigToSettings("global", "sync_note_list_to_current_tab", m_syncNoteListToCurrentTab); -} - -inline int VConfigManager::getTableFormatInterval() const -{ - return m_tableFormatIntervalMS; -} - -inline bool VConfigManager::getEnableCodeBlockCopyButton() const -{ - return m_enableCodeBlockCopyButton; -} - -inline void VConfigManager::setEnableCodeBlockCopyButton(bool p_enabled) -{ - if (m_enableCodeBlockCopyButton == p_enabled) { - return; - } - - m_enableCodeBlockCopyButton = p_enabled; - setConfigToSettings("web", "enable_code_block_copy_button", p_enabled); -} - -inline const QString &VConfigManager::getGithubPersonalAccessToken() const -{ - return m_githubPersonalAccessToken; -} - -inline void VConfigManager::setGithubPersonalAccessToken(const QString &p_token) -{ - if (m_githubPersonalAccessToken == p_token) { - return; - } - - m_githubPersonalAccessToken = p_token; - setConfigToSettings("global", "github_personal_access_token", p_token); -} - -inline const QString &VConfigManager::getGithubReposName() const -{ - return m_githubReposName; -} - -inline void VConfigManager::setGithubReposName(const QString &p_reposName) -{ - if (m_githubReposName == p_reposName) { - return; - } - - m_githubReposName = p_reposName; - setConfigToSettings("global", "github_repos_name", p_reposName); -} - -inline const QString &VConfigManager::getGithubUserName() const -{ - return m_githubUserName; -} - -inline void VConfigManager::setGithubUserName(const QString &p_userName) -{ - if (m_githubUserName == p_userName) { - return; - } - - m_githubUserName = p_userName; - setConfigToSettings("global", "github_user_name", p_userName); -} - -inline const bool &VConfigManager::getGithubKeepImgScale() const -{ - return m_githubKeepImgScale; -} - -inline void VConfigManager::setGithubKeepImgScale(const bool &p_githubKeepImgScale) -{ - if (m_githubKeepImgScale == p_githubKeepImgScale) { - return; - } - - m_githubKeepImgScale = p_githubKeepImgScale; - setConfigToSettings("global", "github_keep_img_scale", p_githubKeepImgScale); -} - -inline const bool &VConfigManager::getGithubDoNotReplaceLink() const -{ - return m_githubDoNotReplaceLink; -} - -inline void VConfigManager::setGithubDoNotReplaceLink(const bool &p_githubDoNotReplaceLink) -{ - if (m_githubDoNotReplaceLink == p_githubDoNotReplaceLink) { - return; - } - - m_githubDoNotReplaceLink = p_githubDoNotReplaceLink; - setConfigToSettings("global", "github_do_not_replace_link", p_githubDoNotReplaceLink); -} - -inline const QString &VConfigManager::getGiteePersonalAccessToken() const -{ - return m_giteePersonalAccessToken; -} - -inline void VConfigManager::setGiteePersonalAccessToken(const QString &p_giteePersonalAccessToken) -{ - if (m_giteePersonalAccessToken == p_giteePersonalAccessToken) { - return; - } - - m_giteePersonalAccessToken = p_giteePersonalAccessToken; - setConfigToSettings("global", "gitee_personal_access_token", p_giteePersonalAccessToken); -} - -inline const QString &VConfigManager::getGiteeReposName() const -{ - return m_giteeReposName; -} - -inline void VConfigManager::setGiteeReposName(const QString &p_giteeReposName) -{ - if (m_giteeReposName == p_giteeReposName) { - return; - } - - m_giteeReposName = p_giteeReposName; - setConfigToSettings("global", "gitee_repos_name", p_giteeReposName); -} - -inline const QString &VConfigManager::getGiteeUserName() const -{ - return m_giteeUserName; -} - -inline void VConfigManager::setGiteeUserName(const QString &p_giteeUserName) -{ - if (m_giteeUserName == p_giteeUserName) { - return; - } - - m_giteeUserName = p_giteeUserName; - setConfigToSettings("global", "gitee_user_name", p_giteeUserName); -} - -inline const bool &VConfigManager::getGiteeKeepImgScale() const -{ - return m_giteeKeepImgScale; -} - -inline void VConfigManager::setGiteeKeepImgScale(const bool &p_giteeKeepImgScale) -{ - if (m_giteeKeepImgScale == p_giteeKeepImgScale) { - return; - } - - m_giteeKeepImgScale = p_giteeKeepImgScale; - setConfigToSettings("global", "gitee_keep_img_scale", p_giteeKeepImgScale); -} - -inline const bool &VConfigManager::getGiteeDoNotReplaceLink() const -{ - return m_giteeDoNotReplaceLink; -} - -inline void VConfigManager::setGiteeDoNotReplaceLink(const bool &p_giteeDoNotReplaceLink) -{ - if (m_giteeDoNotReplaceLink == p_giteeDoNotReplaceLink) { - return; - } - - m_giteeDoNotReplaceLink = p_giteeDoNotReplaceLink; - setConfigToSettings("global", "gitee_do_not_replace_link", p_giteeDoNotReplaceLink); -} - -inline const QString &VConfigManager::getWechatAppid() const -{ - return m_wechatAppid; -} - -inline void VConfigManager::setWechatAppid(const QString &p_appid) -{ - if(m_wechatAppid == p_appid){ - return; - } - m_wechatAppid = p_appid; - setConfigToSettings("global", "wechat_appid", p_appid); -} - -inline const QString &VConfigManager::getWechatSecret() const -{ - return m_wechatSecret; -} - -inline void VConfigManager::setWechatSecret(const QString &p_secret) -{ - if(m_wechatSecret == p_secret){ - return; - } - m_wechatSecret = p_secret; - setConfigToSettings("global", "wechat_secret", p_secret); -} - -inline const QString &VConfigManager::getMarkdown2WechatToolUrl() const -{ - return m_markdown2WechatToolUrl; -} - -inline void VConfigManager::setMarkdown2WechatToolUrl(const QString &p_markdown2WechatToolUrl) -{ - if(m_markdown2WechatToolUrl == p_markdown2WechatToolUrl){ - return; - } - m_markdown2WechatToolUrl = p_markdown2WechatToolUrl; - setConfigToSettings("global", "wechat_markdown_to_wechat_tool_url", p_markdown2WechatToolUrl); -} - -inline const bool &VConfigManager::getWechatKeepImgScale() const -{ - return m_wechatKeepImgScale; -} - -inline void VConfigManager::setWechatKeepImgScale(const bool &p_wechatKeepImgScale) -{ - if (m_wechatKeepImgScale == p_wechatKeepImgScale) { - return; - } - - m_wechatKeepImgScale = p_wechatKeepImgScale; - setConfigToSettings("global", "wechat_keep_img_scale", p_wechatKeepImgScale); -} - -inline const bool &VConfigManager::getWechatDoNotReplaceLink() const -{ - return m_wechatDoNotReplaceLink; -} - -inline void VConfigManager::setWechatDoNotReplaceLink(const bool &p_wechatDoNotReplaceLink) -{ - if (m_wechatDoNotReplaceLink == p_wechatDoNotReplaceLink) { - return; - } - - m_wechatDoNotReplaceLink = p_wechatDoNotReplaceLink; - setConfigToSettings("global", "wechat_do_not_replace_link", p_wechatDoNotReplaceLink); -} - -inline const QString &VConfigManager::getTencentAccessDomainName() const -{ - return m_tencentAccessDomainName; -} - -inline void VConfigManager::setTencentAccessDomainName(const QString &p_accessDomainName) -{ - if (m_tencentAccessDomainName == p_accessDomainName) { - return; - } - - m_tencentAccessDomainName = p_accessDomainName; - setConfigToSettings("global", "tencent_access_domain_name", p_accessDomainName); -} - -inline const QString &VConfigManager::getTencentSecretId() const -{ - return m_tencentSecretId; -} - -inline void VConfigManager::setTencentSecretId(const QString &p_secretId) -{ - if (m_tencentSecretId == p_secretId) { - return; - } - - m_tencentSecretId = p_secretId; - setConfigToSettings("global", "tencent_secret_id", p_secretId); -} - -inline const QString &VConfigManager::getTencentSecretKey() const -{ - return m_tencentSecretKey; -} - -inline void VConfigManager::setTencentSecretKey(const QString &p_secretKey) -{ - if (m_tencentSecretKey == p_secretKey) { - return; - } - - m_tencentSecretKey = p_secretKey; - setConfigToSettings("global", "tencent_secret_key", p_secretKey); -} - -inline const bool &VConfigManager::getTencentKeepImgScale() const -{ - return m_tencentKeepImgScale; -} - -inline void VConfigManager::setTencentKeepImgScale(const bool &p_tencentKeepImgScale) -{ - if (m_tencentKeepImgScale == p_tencentKeepImgScale) { - return; - } - - m_tencentKeepImgScale = p_tencentKeepImgScale; - setConfigToSettings("global", "tencent_keep_img_scale", p_tencentKeepImgScale); -} - -inline const bool &VConfigManager::getTencentDoNotReplaceLink() const -{ - return m_tencentDoNotReplaceLink; -} - -inline void VConfigManager::setTencentDoNotReplaceLink(const bool &p_tencentDoNotReplaceLink) -{ - if (m_tencentDoNotReplaceLink == p_tencentDoNotReplaceLink) { - return; - } - - m_tencentDoNotReplaceLink = p_tencentDoNotReplaceLink; - setConfigToSettings("global", "tencent_do_not_replace_link", p_tencentDoNotReplaceLink); -} - -#endif // VCONFIGMANAGER_H diff --git a/src/vconstants.h b/src/vconstants.h deleted file mode 100644 index b166021a..00000000 --- a/src/vconstants.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef VCONSTANTS_H -#define VCONSTANTS_H - -#include -#include - -typedef unsigned long long TimeStamp; - -// Html: rich text file; -// Markdown: Markdown text file; -// List: Infinite list file like WorkFlowy; -// Container: a composite file containing multiple files; -enum class DocType { Html = 0, Markdown, List, Container, Unknown }; - -// Note: note file managed by VNote; -// Orphan: external file; -enum class FileType { Note, Orphan }; - -enum class ClipboardOpType { CopyFile, CopyDir, Invalid }; - -namespace ClipboardConfig -{ - static const QString c_type = "type"; - static const QString c_magic = "magic"; - static const QString c_isCut = "is_cut"; - static const QString c_files = "files"; - static const QString c_dirs = "dirs"; - static const QString c_format = "text/json"; -} - -enum class OpenFileMode {Read = 0, Edit, Invalid }; - -static const qreal c_webZoomFactorMax = 5; -static const qreal c_webZoomFactorMin = 0.25; - -static const int c_editorZoomDeltaMax = 10; -static const int c_editorZoomDeltaMin = -10; - -static const int c_tabSequenceBase = 1; - -// HTML and JS. -namespace HtmlHolder -{ - static const QString c_JSHolder = "JS_PLACE_HOLDER"; - static const QString c_cssHolder = "CSS_PLACE_HOLDER"; - static const QString c_codeBlockCssHolder = "HIGHLIGHTJS_CSS_PLACE_HOLDER"; - static const QString c_commonCssHolder = "COMMON_CSS_PLACE_HOLDER"; - static const QString c_scaleFactorHolder = "SCALE_FACTOR_PLACE_HOLDER"; - static const QString c_globalStyleHolder = "/* STYLE_GLOBAL_PLACE_HOLDER */"; - static const QString c_extraHolder = ""; - static const QString c_bodyHolder = ""; - static const QString c_headHolder = ""; - static const QString c_styleHolder = "/* STYLE_PLACE_HOLDER */"; - static const QString c_outlineStyleHolder = "/* STYLE_OUTLINE_PLACE_HOLDER */"; - static const QString c_headTitleHolder = ""; -} - -// Directory Config file items. -namespace DirConfig -{ - static const QString c_version = "version"; - static const QString c_subDirectories = "sub_directories"; - static const QString c_files = "files"; - static const QString c_attachments = "attachments"; - static const QString c_imageFolder = "image_folder"; - static const QString c_attachmentFolder = "attachment_folder"; - static const QString c_recycleBinFolder = "recycle_bin_folder"; - static const QString c_tags = "tags"; - static const QString c_name = "name"; - static const QString c_createdTime = "created_time"; - static const QString c_modifiedTime = "modified_time"; -} - -// Snippet Cofnig file items. -namespace SnippetConfig -{ - static const QString c_version = "version"; - static const QString c_snippets = "snippets"; - static const QString c_name = "name"; - static const QString c_type = "type"; - static const QString c_cursorMark = "cursor_mark"; - static const QString c_selectionMark = "selection_mark"; - static const QString c_shortcut = "shortcut"; - static const QString c_autoIndent = "auto_indent"; -} - -namespace Shortcut -{ - static const QString c_expand = "Ctrl+B"; - static const QString c_info = "F2"; - static const QString c_copy = "Ctrl+C"; - static const QString c_cut = "Ctrl+X"; - static const QString c_paste = "Ctrl+V"; -} - -static const QString c_emptyHeaderName = "[EMPTY]"; - -enum class TextDecoration -{ - None, - Bold, - Italic, - Underline, - Strikethrough, - InlineCode, - CodeBlock, - Heading -}; - -enum FindOption -{ - CaseSensitive = 0x1U, - WholeWordOnly = 0x2U, - RegularExpression = 0x4U, - IncrementalSearch = 0x8U -}; - -enum class ImageProperty {/* ID of the image preview (long long). Unique for each source. */ - ImageID = 1, - /* Source type of the preview, such as image, codeblock. */ - ImageSource, - /* Type of the preview, block or inline. */ - ImageType }; - -enum class PreviewImageType { Block, Inline, Invalid }; - -enum class PreviewImageSource { Image, CodeBlock, Invalid }; - -enum HighlightBlockState -{ - Normal = -1, - - // A fenced code block. - CodeBlockStart, - CodeBlock, - CodeBlockEnd, - - HRule -}; - -// Pages to open on start up. -enum class StartupPageType -{ - None = 0, - ContinueLeftOff = 1, - SpecificPages = 2, - Invalid -}; - -// Cursor block mode. -enum class CursorBlock -{ - None = 0, - // Display a cursor block on the character on the right side of the cursor. - RightSide, - // Display a cursor block on the character on the left side of the cursor. - LeftSide -}; - -enum class UpdateAction -{ - // The info of a file/directory has been changed. - InfoChanged = 0, - - // The file/directory has been moved. - Moved -}; - -enum MarkdownConverterType -{ - Hoedown = 0, - Marked, - MarkdownIt, - Showdown -}; - -enum PlantUMLMode -{ - DisablePlantUML = 0, - OnlinePlantUML = 1, - LocalPlantUML = 2 -}; -#endif diff --git a/src/vdirectory.cpp b/src/vdirectory.cpp deleted file mode 100644 index b5104fc4..00000000 --- a/src/vdirectory.cpp +++ /dev/null @@ -1,845 +0,0 @@ -#include "vdirectory.h" -#include -#include -#include -#include -#include "vconfigmanager.h" -#include "vnotefile.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VDirectory::VDirectory(VNotebook *p_notebook, - VDirectory *p_parent, - const QString &p_name, - QDateTime p_createdTimeUtc) - : QObject(p_parent), - m_notebook(p_notebook), - m_name(p_name), - m_opened(false), - m_expanded(false), - m_createdTimeUtc(p_createdTimeUtc) -{ -} - -bool VDirectory::open() -{ - if (m_opened) { - return true; - } - - V_ASSERT(m_subDirs.isEmpty() && m_files.isEmpty()); - - QString path = fetchPath(); - QJsonObject configJson = VConfigManager::readDirectoryConfig(path); - if (configJson.isEmpty()) { - qWarning() << "invalid directory configuration in path" << path; - return false; - } - - // created_time - m_createdTimeUtc = QDateTime::fromString(configJson[DirConfig::c_createdTime].toString(), - Qt::ISODate); - - // [sub_directories] section - QJsonArray dirJson = configJson[DirConfig::c_subDirectories].toArray(); - for (int i = 0; i < dirJson.size(); ++i) { - QJsonObject dirItem = dirJson[i].toObject(); - VDirectory *dir = new VDirectory(m_notebook, this, dirItem[DirConfig::c_name].toString()); - m_subDirs.append(dir); - } - - // [files] section - QJsonArray fileJson = configJson[DirConfig::c_files].toArray(); - for (int i = 0; i < fileJson.size(); ++i) { - QJsonObject fileItem = fileJson[i].toObject(); - VNoteFile *file = VNoteFile::fromJson(this, - fileItem, - FileType::Note, - true); - m_files.append(file); - } - - m_opened = true; - return true; -} - -void VDirectory::close() -{ - if (!m_opened) { - return; - } - - for (int i = 0; i < m_subDirs.size(); ++i) { - VDirectory *dir = m_subDirs[i]; - dir->close(); - delete dir; - } - m_subDirs.clear(); - - for (int i = 0; i < m_files.size(); ++i) { - VNoteFile *file = m_files[i]; - file->close(); - delete file; - } - m_files.clear(); - - m_opened = false; -} - -QString VDirectory::fetchBasePath() const -{ - return VUtils::basePathFromPath(fetchPath()); -} - -QString VDirectory::fetchPath(const VDirectory *p_dir) const -{ - if (!p_dir) { - return ""; - } - VDirectory *parentDir = (VDirectory *)p_dir->parent(); - if (parentDir) { - // Not the root directory - return QDir(parentDir->fetchPath()).filePath(p_dir->getName()); - } else { - return p_dir->getNotebook()->getPath(); - } -} - -QString VDirectory::fetchRelativePath(const VDirectory *p_dir) const -{ - if (!p_dir) { - return ""; - } - VDirectory *parentDir = (VDirectory *)p_dir->parent(); - if (parentDir) { - // Not the root directory - return QDir(fetchRelativePath(parentDir)).filePath(p_dir->getName()); - } else { - return ""; - } -} - -QJsonObject VDirectory::toConfigJson() const -{ - QJsonObject dirJson; - dirJson[DirConfig::c_version] = "1"; - dirJson[DirConfig::c_createdTime] = m_createdTimeUtc.toString(Qt::ISODate); - - QJsonArray subDirs; - for (int i = 0; i < m_subDirs.size(); ++i) { - QJsonObject item; - item[DirConfig::c_name] = m_subDirs[i]->getName(); - - subDirs.append(item); - } - dirJson[DirConfig::c_subDirectories] = subDirs; - - QJsonArray files; - for (int i = 0; i < m_files.size(); ++i) { - files.append(m_files[i]->toConfigJson()); - } - - dirJson[DirConfig::c_files] = files; - - return dirJson; -} - -bool VDirectory::readConfig() -{ - return true; -} - -bool VDirectory::writeToConfig() const -{ - QJsonObject json = toConfigJson(); - - if (!getParentDirectory()) { - // Root directory. - addNotebookConfig(json); - } - - qDebug() << "folder" << m_name << "write to config" << json; - return writeToConfig(json); -} - -bool VDirectory::updateFileConfig(const VNoteFile *p_file) -{ - Q_ASSERT(m_opened); - Q_UNUSED(p_file); - return writeToConfig(); -} - -bool VDirectory::writeToConfig(const QJsonObject &p_json) const -{ - return VConfigManager::writeDirectoryConfig(fetchPath(), p_json); -} - -void VDirectory::addNotebookConfig(QJsonObject &p_json) const -{ - V_ASSERT(!getParentDirectory()); - - QJsonObject nbJson = m_notebook->toConfigJsonNotebook(); - - // Merge it to p_json. - for (auto it = nbJson.begin(); it != nbJson.end(); ++it) { - V_ASSERT(!p_json.contains(it.key())); - p_json[it.key()] = it.value(); - } -} - -VDirectory *VDirectory::createSubDirectory(const QString &p_name, - QString *p_errMsg) -{ - Q_ASSERT(!p_name.isEmpty()); - - if (!open()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to open folder %1.").arg(m_name)); - return NULL; - } - - QDir dir(fetchPath()); - if (dir.exists(p_name)) { - VUtils::addErrMsg(p_errMsg, tr("%1 already exists in directory %2.") - .arg(p_name) - .arg(fetchPath())); - return NULL; - } - - if (!dir.mkdir(p_name)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to create folder in %1.") - .arg(m_name)); - return NULL; - } - - VDirectory *ret = new VDirectory(m_notebook, - this, - p_name, - QDateTime::currentDateTimeUtc()); - if (!ret->writeToConfig()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to write configuration of folder %1.") - .arg(p_name)); - dir.rmdir(p_name); - delete ret; - return NULL; - } - - m_subDirs.append(ret); - if (!writeToConfig()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to write configuration of folder %1.") - .arg(p_name)); - - QDir subdir(dir.filePath(p_name)); - subdir.removeRecursively(); - delete ret; - m_subDirs.removeLast(); - return NULL; - } - - return ret; -} - -VDirectory *VDirectory::findSubDirectory(const QString &p_name, bool p_caseSensitive) -{ - if (!open()) { - return NULL; - } - - QString name = p_caseSensitive ? p_name : p_name.toLower(); - for (int i = 0; i < m_subDirs.size(); ++i) { - if (name == (p_caseSensitive ? m_subDirs[i]->getName() : m_subDirs[i]->getName().toLower())) { - return m_subDirs[i]; - } - } - - return NULL; -} - -VNoteFile *VDirectory::findFile(const QString &p_name, bool p_caseSensitive) -{ - if (!open()) { - return NULL; - } - - QString name = p_caseSensitive ? p_name : p_name.toLower(); - for (int i = 0; i < m_files.size(); ++i) { - if (name == (p_caseSensitive ? m_files[i]->getName() : m_files[i]->getName().toLower())) { - return m_files[i]; - } - } - - return NULL; -} - -bool VDirectory::containsFile(const VFile *p_file) const -{ - if (!p_file) { - return false; - } - - QObject *paDir = p_file->parent(); - while (paDir) { - if (paDir == this) { - return true; - } else { - paDir = paDir->parent(); - } - } - - return false; -} - -VNoteFile *VDirectory::createFile(const QString &p_name, bool p_front) -{ - Q_ASSERT(!p_name.isEmpty()); - if (!open()) { - return NULL; - } - - QString path = fetchPath(); - QFile file(QDir(path).filePath(p_name)); - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "fail to create file" << p_name; - return NULL; - } - - file.close(); - - QDateTime dateTime = QDateTime::currentDateTimeUtc(); - VNoteFile *ret = new VNoteFile(this, - p_name, - FileType::Note, - true, - dateTime, - dateTime); - int idx = -1; - if (p_front) { - m_files.prepend(ret); - idx = 0; - } else { - m_files.append(ret); - idx = m_files.size() - 1; - } - - if (!writeToConfig()) { - file.remove(); - delete ret; - m_files.remove(idx); - return NULL; - } - - qDebug() << "note" << p_name << "created in folder" << m_name; - - return ret; -} - -bool VDirectory::addFile(VNoteFile *p_file, int p_index) -{ - if (!open()) { - return false; - } - - if (p_index == -1) { - m_files.append(p_file); - } else { - m_files.insert(p_index, p_file); - } - - if (!writeToConfig()) { - if (p_index == -1) { - m_files.removeLast(); - } else { - m_files.remove(p_index); - } - - return false; - } - - p_file->setParent(this); - - // Add tags from this file to the notebook. - const QStringList &tags = p_file->getTags(); - for (auto const & tag : tags) { - m_notebook->addTag(tag); - } - - qDebug() << "note" << p_file->getName() << "added to folder" << m_name; - - return true; -} - -VNoteFile *VDirectory::addFile(const QString &p_name, int p_index) -{ - if (!open() || p_name.isEmpty()) { - return NULL; - } - - QDateTime dateTime = QDateTime::currentDateTimeUtc(); - VNoteFile *file = new VNoteFile(this, - p_name, - FileType::Note, - true, - dateTime, - dateTime); - if (!file) { - return NULL; - } - - if (!addFile(file, p_index)) { - delete file; - return NULL; - } - - return file; -} - -bool VDirectory::addSubDirectory(VDirectory *p_dir, int p_index) -{ - if (!open()) { - return false; - } - - if (p_index == -1) { - m_subDirs.append(p_dir); - } else { - m_subDirs.insert(p_index, p_dir); - } - - if (!writeToConfig()) { - if (p_index == -1) { - m_subDirs.removeLast(); - } else { - m_subDirs.remove(p_index); - } - - return false; - } - - p_dir->setParent(this); - p_dir->m_notebook = m_notebook; - - m_notebook->addTags(p_dir); - - qDebug() << "folder" << p_dir->getName() << "added to folder" << m_name; - - return true; -} - -VDirectory *VDirectory::addSubDirectory(const QString &p_name, int p_index) -{ - if (!open() || p_name.isEmpty()) { - return NULL; - } - - VDirectory *dir = new VDirectory(m_notebook, - this, - p_name, - QDateTime::currentDateTimeUtc()); - if (!dir) { - return NULL; - } - - if (!addSubDirectory(dir, p_index)) { - delete dir; - return NULL; - } - - return dir; -} - -bool VDirectory::deleteDirectory(bool p_skipRecycleBin, QString *p_errMsg) -{ - Q_ASSERT(!m_opened); - Q_ASSERT(parent()); - - // Delete the entire directory. - bool ret = true; - QString dirPath = fetchPath(); - if (!VUtils::deleteDirectory(m_notebook, dirPath, p_skipRecycleBin)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to delete the directory %1.").arg(dirPath)); - ret = false; - } - - return ret; -} - -bool VDirectory::deleteDirectory(VDirectory *p_dir, bool p_skipRecycleBin, QString *p_errMsg) -{ - p_dir->close(); - - bool ret = true; - - QString name = p_dir->getName(); - QString path = p_dir->fetchPath(); - - if (!p_dir->deleteDirectory(p_skipRecycleBin, p_errMsg)) { - ret = false; - } - - VDirectory *paDir = p_dir->getParentDirectory(); - Q_ASSERT(paDir); - if (!paDir->removeSubDirectory(p_dir)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to remove the folder from the folder configuration.")); - ret = false; - } - - delete p_dir; - - return ret; -} - -bool VDirectory::removeSubDirectory(VDirectory *p_dir) -{ - V_ASSERT(m_opened); - V_ASSERT(p_dir); - - int index = m_subDirs.indexOf(p_dir); - V_ASSERT(index != -1); - m_subDirs.remove(index); - - if (!writeToConfig()) { - return false; - } - - return true; -} - -bool VDirectory::removeFile(VNoteFile *p_file) -{ - V_ASSERT(m_opened); - V_ASSERT(p_file); - - int index = m_files.indexOf(p_file); - V_ASSERT(index != -1); - m_files.remove(index); - - if (!writeToConfig()) { - return false; - } - - return true; -} - -bool VDirectory::rename(const QString &p_name) -{ - if (m_name == p_name) { - return true; - } - - QString oldName = m_name; - - VDirectory *parentDir = getParentDirectory(); - V_ASSERT(parentDir); - // Rename it in disk. - QDir dir(parentDir->fetchPath()); - if (!dir.rename(m_name, p_name)) { - qWarning() << "fail to rename folder" << m_name << "to" << p_name << "in disk"; - return false; - } - - m_name = p_name; - - // Update parent's config file - if (!parentDir->writeToConfig()) { - m_name = oldName; - dir.rename(p_name, m_name); - return false; - } - - qDebug() << "folder renamed from" << oldName << "to" << m_name; - - return true; -} - -bool VDirectory::copyDirectory(VDirectory *p_destDir, - const QString &p_destName, - VDirectory *p_dir, - bool p_isCut, - VDirectory **p_targetDir, - QString *p_errMsg) -{ - bool ret = true; - *p_targetDir = NULL; - - QString srcPath = QDir::cleanPath(p_dir->fetchPath()); - QString destPath = QDir::cleanPath(QDir(p_destDir->fetchPath()).filePath(p_destName)); - if (VUtils::equalPath(srcPath, destPath)) { - *p_targetDir = p_dir; - return false; - } - - if (!p_destDir->isOpened()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to open target folder.")); - return false; - } - - QString opStr = p_isCut ? tr("cut") : tr("copy"); - VDirectory *paDir = p_dir->getParentDirectory(); - - Q_ASSERT(paDir->isOpened()); - - // Copy the directory. - if (!VUtils::copyDirectory(srcPath, destPath, p_isCut)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to %1 the folder.").arg(opStr)); - qWarning() << "fail to" << opStr << "the folder directory" << srcPath << "to" << destPath; - return false; - } - - // Add directory to VDirectory. - VDirectory *destDir = NULL; - if (p_isCut) { - paDir->removeSubDirectory(p_dir); - p_dir->setName(p_destName); - // Add the directory to new dir's config - if (p_destDir->addSubDirectory(p_dir, -1)) { - destDir = p_dir; - } else { - destDir = NULL; - } - } else { - destDir = p_destDir->addSubDirectory(p_destName, -1); - } - - if (!destDir) { - VUtils::addErrMsg(p_errMsg, tr("Fail to add the folder to target folder's configuration.")); - return false; - } - - *p_targetDir = destDir; - return ret; -} - -void VDirectory::setExpanded(bool p_expanded) -{ - if (p_expanded) { - V_ASSERT(m_opened); - } - - m_expanded = p_expanded; -} - -VNoteFile *VDirectory::tryLoadFile(QStringList &p_filePath) -{ - if (p_filePath.isEmpty()) { - return NULL; - } - - bool opened = isOpened(); - if (!open()) { - return NULL; - } - - VNoteFile *file = NULL; - -#if defined(Q_OS_WIN) - bool caseSensitive = false; -#else - bool caseSensitive = true; -#endif - - if (p_filePath.size() == 1) { - // File. - file = findFile(p_filePath.at(0), caseSensitive); - } else { - // Directory. - VDirectory *dir = findSubDirectory(p_filePath.at(0), caseSensitive); - if (dir) { - p_filePath.removeFirst(); - file = dir->tryLoadFile(p_filePath); - } - } - - if (!file && !opened) { - close(); - } - - return file; -} - -VDirectory *VDirectory::tryLoadDirectory(QStringList &p_filePath) -{ - if (p_filePath.isEmpty()) { - return NULL; - } - - bool opened = isOpened(); - if (!open()) { - return NULL; - } - -#if defined(Q_OS_WIN) - bool caseSensitive = false; -#else - bool caseSensitive = true; -#endif - - VDirectory *dir = findSubDirectory(p_filePath.at(0), caseSensitive); - if (dir) { - if (p_filePath.size() > 1) { - p_filePath.removeFirst(); - dir = dir->tryLoadDirectory(p_filePath); - } - } - - if (!dir && !opened) { - close(); - } - - return dir; -} - -bool VDirectory::sortFiles(const QVector &p_sortedIdx) -{ - V_ASSERT(m_opened); - V_ASSERT(p_sortedIdx.size() == m_files.size()); - - auto ori = m_files; - - for (int i = 0; i < p_sortedIdx.size(); ++i) { - m_files[i] = ori[p_sortedIdx[i]]; - } - - bool ret = true; - if (!writeToConfig()) { - qWarning() << "fail to reorder files in config" << p_sortedIdx; - m_files = ori; - ret = false; - } - - return ret; -} - -bool VDirectory::sortSubDirectories(const QVector &p_sortedIdx) -{ - V_ASSERT(m_opened); - V_ASSERT(p_sortedIdx.size() == m_subDirs.size()); - - auto ori = m_subDirs; - - for (int i = 0; i < p_sortedIdx.size(); ++i) { - m_subDirs[i] = ori[p_sortedIdx[i]]; - } - - bool ret = true; - if (!writeToConfig()) { - qWarning() << "fail to reorder sub-directories in config" << p_sortedIdx; - m_subDirs = ori; - ret = false; - } - - return ret; -} - -QList VDirectory::collectFiles() -{ - QList files; - bool opened = isOpened(); - if (!opened && !open()) { - qWarning() << "fail to open directory" << fetchPath(); - return files; - } - - // Files. - for (auto const & file : m_files) { - files.append(file->fetchPath()); - } - - // Subfolders. - for (auto const & dir : m_subDirs) { - files.append(dir->collectFiles()); - } - - if (!opened) { - close(); - } - - return files; -} - -QStringList VDirectory::collectTags() -{ - QStringList tags; - bool opened = isOpened(); - if (!opened && !open()) { - qWarning() << "fail to open directory" << fetchPath(); - return tags; - } - - // Files. - for (auto const & file : m_files) { - tags.append(file->getTags()); - } - - // Subfolders. - for (auto const & dir : m_subDirs) { - tags.append(dir->collectTags()); - } - - if (!opened) { - close(); - } - - return tags; -} - -VDirectory *VDirectory::buildDirectory(const QString &p_path, - VDirectory *p_parent, - QString *p_errMsg) -{ - VDirectory *ret = new VDirectory(p_parent->getNotebook(), - p_parent, - VUtils::directoryNameFromPath(p_path), - QDateTime::currentDateTimeUtc()); - - QDir rootDir(p_path); - - // Process all the folders. - QVector &subdirs = ret->getSubDirs(); - QFileInfoList dirList = rootDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot); - for (auto const & sub : dirList) { - VDirectory *dir = VDirectory::buildDirectory(sub.absoluteFilePath(), - ret, - p_errMsg); - if (dir) { - subdirs.append(dir); - } - } - - // Process all the files. - QVector &files = ret->getFiles(); - QDateTime dateTime = QDateTime::currentDateTimeUtc(); - QList suffixes = g_config->getDocSuffixes()[(int)DocType::Markdown]; - QStringList filters; - for (auto const & suf : suffixes) { - filters << ("*." + suf); - } - - QStringList fileList = rootDir.entryList(filters, QDir::Files); - for (auto const & fileName : fileList) { - VNoteFile *file = new VNoteFile(ret, - fileName, - FileType::Note, - true, - dateTime, - dateTime); - if (!file) { - VUtils::addErrMsg(p_errMsg, tr("Skip file %1.").arg(rootDir.absoluteFilePath(fileName))); - } else { - files.append(file); - } - } - - if (subdirs.isEmpty() && files.isEmpty()) { - delete ret; - VUtils::addErrMsg(p_errMsg, tr("Skip folder %1.").arg(p_path)); - return NULL; - } - - if (!ret->writeToConfig()) { - delete ret; - VUtils::addErrMsg(p_errMsg, tr("Fail to write configuration of folder %1.").arg(p_path)); - return NULL; - } - - return ret; -} diff --git a/src/vdirectory.h b/src/vdirectory.h deleted file mode 100644 index 13f72a85..00000000 --- a/src/vdirectory.h +++ /dev/null @@ -1,263 +0,0 @@ -#ifndef VDIRECTORY_H -#define VDIRECTORY_H - -#include -#include -#include -#include -#include -#include -#include "vnotebook.h" - -class VFile; -class VNoteFile; - -class VDirectory : public QObject -{ - Q_OBJECT -public: - VDirectory(VNotebook *p_notebook, - VDirectory *p_parent, - const QString &p_name, - QDateTime p_createdTimeUtc = QDateTime()); - - bool open(); - void close(); - - // Create a sub-directory with name @p_name. - VDirectory *createSubDirectory(const QString &p_name, - QString *p_errMsg = NULL); - - // Returns the VDirectory with the name @p_name directly in this directory. - VDirectory *findSubDirectory(const QString &p_name, bool p_caseSensitive); - - // Returns the VNoteFile with the name @p_name directly in this directory. - VNoteFile *findFile(const QString &p_name, bool p_caseSensitive); - - // If current dir or its sub-dir contains @p_file. - bool containsFile(const VFile *p_file) const; - - VNoteFile *createFile(const QString &p_name, bool p_front); - - // Remove the file in the config and m_files without deleting it in the disk. - // It won't change the parent of @p_file to enable it find its path. - bool removeFile(VNoteFile *p_file); - - // Remove the directory in the config and m_subDirs without deleting it in the disk. - // It won't change the parent of @p_dir to enable it find its path. - bool removeSubDirectory(VDirectory *p_dir); - - // Add the file in the config and m_files. If @p_index is -1, add it at the end. - // @p_name: the file name of the file to add. - // Return the VNoteFile if succeed. - VNoteFile *addFile(const QString &p_name, int p_index); - - // Add the file in the config and m_files. If @p_index is -1, add it at the end. - bool addFile(VNoteFile *p_file, int p_index); - - // Rename current directory to @p_name. - bool rename(const QString &p_name); - - // Copy @p_dir as a sub-directory of @p_destDir with the new name @p_destName. - // Return a directory representing the destination directory after copy/cut. - static bool copyDirectory(VDirectory *p_destDir, - const QString &p_destName, - VDirectory *p_dir, - bool p_isCut, - VDirectory **p_targetDir, - QString *p_errMsg = NULL); - - const QVector &getSubDirs() const; - QVector &getSubDirs(); - - const QString &getName() const; - void setName(const QString &p_name); - bool isOpened() const; - VDirectory *getParentDirectory(); - const VDirectory *getParentDirectory() const; - VNotebook *getNotebook(); - const VNotebook *getNotebook() const; - - const QVector &getFiles() const; - - QVector &getFiles(); - - QString fetchPath() const; - QString fetchBasePath() const; - QString fetchRelativePath() const; - QString getNotebookName() const; - bool isExpanded() const; - void setExpanded(bool p_expanded); - - // Serialize current instance to json. - // Not including sections belonging to notebook. - QJsonObject toConfigJson() const; - - // Read configurations (excluding "sub_directories" and "files" section) - // from config file. - bool readConfig(); - - // Write current instance to config file. - // If it is root directory, this will include sections belonging to - // notebook. - bool writeToConfig() const; - - // Write the config of @p_file to config file. - bool updateFileConfig(const VNoteFile *p_file); - - // Try to load file given relative path @p_filePath. - VNoteFile *tryLoadFile(QStringList &p_filePath); - - // Try to load directory given relative path @p_filePath. - VDirectory *tryLoadDirectory(QStringList &p_filePath); - - QDateTime getCreatedTimeUtc() const; - - // Reorder files in m_files by index. - bool sortFiles(const QVector &p_sortedIdx); - - // Reorder sub-directories in m_subDirs by index. - bool sortSubDirectories(const QVector &p_sortedIdx); - - // Return path of files in this directory recursively. - QList collectFiles(); - - // Return tags of files in this directory recursively. - QStringList collectTags(); - - // Delete directory @p_dir. - static bool deleteDirectory(VDirectory *p_dir, - bool p_skipRecycleBin = false, - QString *p_errMsg = NULL); - - static VDirectory *buildDirectory(const QString &p_path, - VDirectory *p_parent, - QString *p_errMsg); - -private: - // Get the path of @p_dir recursively - QString fetchPath(const VDirectory *p_dir) const; - // Get teh relative path of @p_dir recursively related to the notebook path - QString fetchRelativePath(const VDirectory *p_dir) const; - - // Write @p_json to config. - bool writeToConfig(const QJsonObject &p_json) const; - - // Add notebook part config to @p_json. - // Should only be called with root directory. - void addNotebookConfig(QJsonObject &p_json) const; - - // Add the directory in the config and m_subDirs. If @p_index is -1, add it at the end. - // Return the VDirectory if succeed. - VDirectory *addSubDirectory(const QString &p_name, int p_index); - - // Add the directory in the config and m_subDirs. If @p_index is -1, add it at the end. - bool addSubDirectory(VDirectory *p_dir, int p_index); - - // Delete this directory in disk. - bool deleteDirectory(bool p_skipRecycleBin = false, QString *p_errMsg = NULL); - - // Notebook containing this folder. - QPointer m_notebook; - - // Name of this folder. - QString m_name; - - // Owner of the sub-directories - QVector m_subDirs; - - // Owner of the files - QVector m_files; - - // Whether the directory has been opened. - bool m_opened; - - // Whether expanded in the directory tree. - bool m_expanded; - - // UTC time when creating this directory. - // Loaded after open(). - QDateTime m_createdTimeUtc; -}; - -inline const QVector &VDirectory::getSubDirs() const -{ - return m_subDirs; -} - -inline QVector &VDirectory::getSubDirs() -{ - return m_subDirs; -} - -inline const QString &VDirectory::getName() const -{ - return m_name; -} - -inline void VDirectory::setName(const QString &p_name) -{ - m_name = p_name; -} - -inline bool VDirectory::isOpened() const -{ - return m_opened; -} - -inline VDirectory *VDirectory::getParentDirectory() -{ - return (VDirectory *)this->parent(); -} - -inline const VDirectory *VDirectory::getParentDirectory() const -{ - return (const VDirectory *)this->parent(); -} - -inline const QVector &VDirectory::getFiles() const -{ - return m_files; -} - -inline QVector &VDirectory::getFiles() -{ - return m_files; -} - -inline QString VDirectory::getNotebookName() const -{ - return m_notebook->getName(); -} - -inline VNotebook *VDirectory::getNotebook() -{ - return m_notebook; -} - -inline const VNotebook *VDirectory::getNotebook() const -{ - return m_notebook; -} - -inline QString VDirectory::fetchPath() const -{ - return fetchPath(this); -} - -inline QString VDirectory::fetchRelativePath() const -{ - return fetchRelativePath(this); -} - -inline bool VDirectory::isExpanded() const -{ - return m_expanded; -} - -inline QDateTime VDirectory::getCreatedTimeUtc() const -{ - return m_createdTimeUtc; -} - -#endif // VDIRECTORY_H diff --git a/src/vdirectorytree.cpp b/src/vdirectorytree.cpp deleted file mode 100644 index 4dda57ac..00000000 --- a/src/vdirectorytree.cpp +++ /dev/null @@ -1,1393 +0,0 @@ -#include -#include "vdirectorytree.h" -#include "dialog/vnewdirdialog.h" -#include "vconfigmanager.h" -#include "dialog/vdirinfodialog.h" -#include "vnote.h" -#include "vdirectory.h" -#include "utils/vutils.h" -#include "veditarea.h" -#include "vconfigmanager.h" -#include "vmainwindow.h" -#include "dialog/vsortdialog.h" -#include "utils/vimnavigationforwidget.h" -#include "utils/viconutils.h" -#include "vfilelist.h" -#include "vhistorylist.h" - -extern VMainWindow *g_mainWin; - -extern VConfigManager *g_config; -extern VNote *g_vnote; - -VDirectoryTree::VDirectoryTree(QWidget *parent) - : VTreeWidget(parent), - VNavigationMode(), - m_editArea(NULL) -{ - setColumnCount(1); - setHeaderHidden(true); - setContextMenuPolicy(Qt::CustomContextMenu); - setFitContent(true); - - viewport()->setAcceptDrops(true); - setDropIndicatorShown(true); - - initShortcuts(); - - connect(this, SIGNAL(itemExpanded(QTreeWidgetItem*)), - this, SLOT(handleItemExpanded(QTreeWidgetItem*))); - connect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), - this, SLOT(handleItemCollapsed(QTreeWidgetItem*))); - connect(this, SIGNAL(customContextMenuRequested(QPoint)), - this, SLOT(contextMenuRequested(QPoint))); - connect(this, &VDirectoryTree::currentItemChanged, - this, &VDirectoryTree::currentDirectoryItemChanged); -} - -void VDirectoryTree::initShortcuts() -{ - QShortcut *infoShortcut = new QShortcut(QKeySequence(Shortcut::c_info), this); - infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(infoShortcut, &QShortcut::activated, - this, [this](){ - editDirectoryInfo(); - }); - - QShortcut *copyShortcut = new QShortcut(QKeySequence(Shortcut::c_copy), this); - copyShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(copyShortcut, &QShortcut::activated, - this, [this](){ - copySelectedDirectories(); - }); - - QShortcut *cutShortcut = new QShortcut(QKeySequence(Shortcut::c_cut), this); - cutShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(cutShortcut, &QShortcut::activated, - this, [this](){ - cutSelectedDirectories(); - }); - - QShortcut *pasteShortcut = new QShortcut(QKeySequence(Shortcut::c_paste), this); - pasteShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(pasteShortcut, &QShortcut::activated, - this, [this](){ - pasteDirectoriesFromClipboard(); - }); - - QKeySequence seq = QKeySequence(g_config->getShortcutKeySequence("NewSubfolder")); - if (!seq.isEmpty()) { - QShortcut *newSubDirShortcut = new QShortcut(seq, this); - newSubDirShortcut->setContext(Qt::ApplicationShortcut); - connect(newSubDirShortcut, &QShortcut::activated, - this, [this](){ - newSubDirectory(); - }); - } -} - -void VDirectoryTree::setNotebook(VNotebook *p_notebook) -{ - if (m_notebook == p_notebook) { - return; - } - - clear(); - m_notebook = p_notebook; - if (!m_notebook) { - return; - } - - if (!m_notebook->open()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to open notebook %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getName()), - tr("Please check if the notebook's root folder %2 exists.") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getPath()), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - updateDirectoryTree(); -} - -void VDirectoryTree::fillTreeItem(QTreeWidgetItem *p_item, VDirectory *p_directory) -{ - static QIcon itemIcon = VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg"); - - int col = 0; - QString name = p_directory->getName(); - p_item->setText(col, name); - p_item->setToolTip(col, name); - p_item->setData(col, Qt::UserRole, QVariant::fromValue(p_directory)); - p_item->setIcon(col, itemIcon); -} - -void VDirectoryTree::updateDirectoryTree() -{ - clear(); - - VDirectory *rootDir = m_notebook->getRootDir(); - const QVector &subDirs = rootDir->getSubDirs(); - for (int i = 0; i < subDirs.size(); ++i) { - VDirectory *dir = subDirs[i]; - QTreeWidgetItem *item = new QTreeWidgetItem(this); - - fillTreeItem(item, dir); - - buildSubTree(item, 1); - } - - if (!restoreCurrentItem() && topLevelItemCount() > 0) { - setCurrentItem(topLevelItem(0)); - } - - resizeColumnToContents(0); -} - -bool VDirectoryTree::restoreCurrentItem() -{ - auto it = m_notebookCurrentDirMap.find(m_notebook); - if (it != m_notebookCurrentDirMap.end()) { - QTreeWidgetItem *item = findVDirectory(it.value()); - if (item) { - setCurrentItem(item); - return true; - } - } - - return false; -} - -void VDirectoryTree::buildSubTree(QTreeWidgetItem *p_parent, int p_depth) -{ - if (p_depth == 0) { - return; - } - - Q_ASSERT(p_parent); - - VDirectory *dir = getVDirectory(p_parent); - if (!dir->open()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to open folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(dir->getName()), - tr("Please check if directory %2 exists.") - .arg(g_config->c_dataTextStyle) - .arg(dir->fetchPath()), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - if (p_parent->childCount() > 0) { - // This directory has been built before. Try its children directly. - int cnt = p_parent->childCount(); - for (int i = 0; i < cnt; ++i) { - buildSubTree(p_parent->child(i), p_depth -1); - } - } else { - const QVector &subDirs = dir->getSubDirs(); - for (int i = 0; i < subDirs.size(); ++i) { - VDirectory *subDir = subDirs[i]; - QTreeWidgetItem *item = new QTreeWidgetItem(p_parent); - fillTreeItem(item, subDir); - buildSubTree(item, p_depth - 1); - } - } - - if (dir->isExpanded()) { - expandItem(p_parent); - } -} - -void VDirectoryTree::handleItemCollapsed(QTreeWidgetItem *p_item) -{ - if (p_item) { - VDirectory *dir = getVDirectory(p_item); - dir->setExpanded(false); - } -} - -void VDirectoryTree::handleItemExpanded(QTreeWidgetItem *p_item) -{ - if (p_item) { - buildChildren(p_item); - - VDirectory *dir = getVDirectory(p_item); - dir->setExpanded(true); - } -} - -void VDirectoryTree::buildChildren(QTreeWidgetItem *p_item) -{ - Q_ASSERT(p_item); - int nrChild = p_item->childCount(); - if (nrChild == 0) { - return; - } - - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *childItem = p_item->child(i); - if (childItem->childCount() > 0) { - continue; - } - - buildSubTree(childItem, 1); - } -} - -void VDirectoryTree::updateItemDirectChildren(QTreeWidgetItem *p_item) -{ - QPointer parentDir; - if (p_item) { - parentDir = getVDirectory(p_item); - } else { - parentDir = m_notebook->getRootDir(); - } - - const QVector &dirs = parentDir->getSubDirs(); - - QHash itemDirMap; - int nrChild = p_item ? p_item->childCount() : topLevelItemCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = p_item ? p_item->child(i) : topLevelItem(i); - itemDirMap.insert(getVDirectory(item), item); - } - - for (int i = 0; i < dirs.size(); ++i) { - VDirectory *dir = dirs[i]; - QTreeWidgetItem *item = itemDirMap.value(dir, NULL); - if (item) { - if (p_item) { - p_item->removeChild(item); - p_item->insertChild(i, item); - } else { - int topIdx = indexOfTopLevelItem(item); - takeTopLevelItem(topIdx); - insertTopLevelItem(i, item); - } - - itemDirMap.remove(dir); - } else { - // Insert a new item - if (p_item) { - item = new QTreeWidgetItem(p_item); - } else { - item = new QTreeWidgetItem(this); - } - - fillTreeItem(item, dir); - buildSubTree(item, 1); - } - - expandSubTree(item); - } - - // Delete items without corresponding VDirectory - for (auto iter = itemDirMap.begin(); iter != itemDirMap.end(); ++iter) { - QTreeWidgetItem *item = iter.value(); - if (p_item) { - p_item->removeChild(item); - } else { - int topIdx = indexOfTopLevelItem(item); - takeTopLevelItem(topIdx); - } - - delete item; - } -} - -void VDirectoryTree::contextMenuRequested(QPoint pos) -{ - QTreeWidgetItem *item = itemAt(pos); - - if (!m_notebook) { - return; - } - - QMenu menu(this); - menu.setToolTipsVisible(true); - - QAction *newRootDirAct = new QAction(VIconUtils::menuIcon(":/resources/icons/create_rootdir.svg"), - tr("New &Root Folder"), - &menu); - newRootDirAct->setToolTip(tr("Create a root folder in current notebook")); - connect(newRootDirAct, &QAction::triggered, - this, &VDirectoryTree::newRootDirectory); - - QAction *sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - &menu); - sortAct->setToolTip(tr("Sort folders in this folder/notebook manually")); - connect(sortAct, SIGNAL(triggered(bool)), - this, SLOT(sortItems())); - - if (!item) { - // Context menu on the free space of the QTreeWidget - menu.addAction(newRootDirAct); - - if (topLevelItemCount() > 1) { - menu.addAction(sortAct); - } - } else { - // Context menu on a QTreeWidgetItem - QAction *newNoteAct = new QAction(VIconUtils::menuIcon(":/resources/icons/create_note_tb.svg"), - tr("New &Note"), - &menu); - VUtils::fixTextWithShortcut(newNoteAct, "NewNote"); - newNoteAct->setToolTip(tr("Create a note in selected folder")); - connect(newNoteAct, &QAction::triggered, - this, []() { - g_mainWin->getFileList()->newFile(); - }); - - menu.addAction(newNoteAct); - - QAction *newSiblingFolder = new QAction(tr("New Si&bling Folder"), &menu); - newSiblingFolder->setToolTip(tr("Create a folder in the same parent folder")); - connect(newSiblingFolder, &QAction::triggered, - this, [this]() { - auto item = currentItem(); - if (item) { - newDirectory(item->parent()); - } - }); - - QAction *newSubDirAct = new QAction(VIconUtils::menuIcon(":/resources/icons/create_subdir.svg"), - tr("New Sub&folder"), - &menu); - newSubDirAct->setToolTip(tr("Create a subfolder")); - VUtils::fixTextWithShortcut(newSubDirAct, "NewSubfolder"); - connect(newSubDirAct, &QAction::triggered, - this, &VDirectoryTree::newSubDirectory); - - if (item->parent()) { - // Low-level item - menu.addAction(newSiblingFolder); - menu.addAction(newSubDirAct); - - if (item->parent()->childCount() > 1) { - menu.addAction(sortAct); - } - } else { - // Top-level item - menu.addAction(newRootDirAct); - menu.addAction(newSubDirAct); - - if (topLevelItemCount() > 1) { - menu.addAction(sortAct); - } - } - - menu.addSeparator(); - - QAction *deleteDirAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_dir.svg"), - tr("&Delete"), - &menu); - deleteDirAct->setToolTip(tr("Delete selected folder")); - connect(deleteDirAct, &QAction::triggered, - this, &VDirectoryTree::deleteSelectedDirectory); - menu.addAction(deleteDirAct); - - QAction *copyAct = new QAction(VIconUtils::menuIcon(":/resources/icons/copy.svg"), - tr("&Copy\t%1").arg(VUtils::getShortcutText(Shortcut::c_copy)), - &menu); - copyAct->setToolTip(tr("Copy selected folders")); - connect(copyAct, &QAction::triggered, - this, &VDirectoryTree::copySelectedDirectories); - menu.addAction(copyAct); - - QAction *cutAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cut.svg"), - tr("C&ut\t%1").arg(VUtils::getShortcutText(Shortcut::c_cut)), - &menu); - cutAct->setToolTip(tr("Cut selected folders")); - connect(cutAct, &QAction::triggered, - this, &VDirectoryTree::cutSelectedDirectories); - menu.addAction(cutAct); - } - - if (pasteAvailable()) { - if (!item) { - menu.addSeparator(); - } - - QAction *pasteAct = new QAction(VIconUtils::menuIcon(":/resources/icons/paste.svg"), - tr("&Paste\t%1").arg(VUtils::getShortcutText(Shortcut::c_paste)), - &menu); - pasteAct->setToolTip(tr("Paste folders in this folder")); - connect(pasteAct, &QAction::triggered, - this, &VDirectoryTree::pasteDirectoriesFromClipboard); - menu.addAction(pasteAct); - } - - menu.addSeparator(); - - QAction *reloadAct = new QAction(tr("Reload From Disk"), &menu); - reloadAct->setToolTip(tr("Reload the content of this folder (or notebook) from disk")); - connect(reloadAct, &QAction::triggered, - this, &VDirectoryTree::reloadFromDisk); - menu.addAction(reloadAct); - - if (item) { - QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"), - tr("Open Folder &Location"), - &menu); - openLocationAct->setToolTip(tr("Explore this folder in operating system")); - connect(openLocationAct, &QAction::triggered, - this, &VDirectoryTree::openDirectoryLocation); - menu.addAction(openLocationAct); - - QAction *pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"), - tr("Pin To History"), - &menu); - pinToHistoryAct->setToolTip(tr("Pin selected folder to History")); - connect(pinToHistoryAct, &QAction::triggered, - this, &VDirectoryTree::pinDirectoryToHistory); - menu.addAction(pinToHistoryAct); - - QAction *dirInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/dir_info.svg"), - tr("&Info (Rename)\t%1").arg(VUtils::getShortcutText(Shortcut::c_info)), - &menu); - dirInfoAct->setToolTip(tr("View and edit current folder's information")); - connect(dirInfoAct, &QAction::triggered, - this, &VDirectoryTree::editDirectoryInfo); - menu.addAction(dirInfoAct); - } - - menu.exec(mapToGlobal(pos)); -} - -void VDirectoryTree::newSubDirectory() -{ - if (!m_notebook) { - return; - } - - newDirectory(currentItem()); -} - -void VDirectoryTree::newDirectory(QTreeWidgetItem *p_parentItem) -{ - if (!p_parentItem) { - return; - } - - VDirectory *curDir = getVDirectory(p_parentItem); - - QString info = tr("Create a subfolder in %2.") - .arg(g_config->c_dataTextStyle) - .arg(curDir->getName()); - QString defaultName("new_folder"); - defaultName = VUtils::getDirNameWithSequence(curDir->fetchPath(), defaultName); - VNewDirDialog dialog(tr("Create Folder"), info, defaultName, curDir, this); - if (dialog.exec() == QDialog::Accepted) { - QString name = dialog.getNameInput(); - QString msg; - VDirectory *subDir = curDir->createSubDirectory(name, &msg); - if (!subDir) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to create subfolder %2.") - .arg(g_config->c_dataTextStyle) - .arg(name), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - updateItemDirectChildren(p_parentItem); - - locateDirectory(subDir); - } -} - -void VDirectoryTree::newRootDirectory() -{ - if (!m_notebook) { - return; - } - - VDirectory *rootDir = m_notebook->getRootDir(); - - QString info = tr("Create a root folder in notebook %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getName()); - QString defaultName("new_folder"); - defaultName = VUtils::getDirNameWithSequence(rootDir->fetchPath(), defaultName); - VNewDirDialog dialog(tr("Create Root Folder"), info, defaultName, rootDir, this); - if (dialog.exec() == QDialog::Accepted) { - QString name = dialog.getNameInput(); - QString msg; - VDirectory *dir = rootDir->createSubDirectory(name, &msg); - if (!dir) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to create root folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(name), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - updateItemDirectChildren(NULL); - - locateDirectory(dir); - } -} - -void VDirectoryTree::deleteSelectedDirectory() -{ - Q_ASSERT(selectedItems().size() <= 1); - - QTreeWidgetItem *curItem = currentItem(); - if (!curItem) { - return; - } - - VDirectory *curDir = getVDirectory(curItem); - int ret = VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Are you sure to delete folder %2?") - .arg(g_config->c_dataTextStyle) - .arg(curDir->getName()), - tr("WARNING: " - "VNote will delete the whole directory " - "%3." - "Deleted files could be found in the recycle bin " - "of this folder.
    " - "The operation is IRREVERSIBLE!") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(curDir->fetchPath()), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - this, - MessageBoxType::Danger); - - if (ret == QMessageBox::Ok) { - int nrDeleted = 1; - m_editArea->closeFile(curDir, true); - - // Remove the item from the tree. - delete curItem; - - QString msg; - QString dirName = curDir->getName(); - QString dirPath = curDir->fetchPath(); - if (!VDirectory::deleteDirectory(curDir, false, &msg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete folder %2.
    " - "Please check %3 and manually delete it.") - .arg(g_config->c_dataTextStyle) - .arg(dirName) - .arg(dirPath), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } else { - g_mainWin->showStatusMessage(tr("%1 %2 deleted") - .arg(nrDeleted) - .arg(nrDeleted > 1 ? tr("folders") : tr("folder"))); - } - } -} - -void VDirectoryTree::currentDirectoryItemChanged(QTreeWidgetItem *currentItem) -{ - if (!currentItem) { - emit currentDirectoryChanged(NULL); - return; - } - - QPointer dir = getVDirectory(currentItem); - m_notebookCurrentDirMap[m_notebook] = dir; - emit currentDirectoryChanged(dir); -} - -void VDirectoryTree::editDirectoryInfo() -{ - QTreeWidgetItem *curItem = currentItem(); - if (!curItem) { - return; - } - - VDirectory *curDir = getVDirectory(curItem); - QString curName = curDir->getName(); - - VDirInfoDialog dialog(tr("Folder Information"), - "", - curDir, - curDir->getParentDirectory(), - this); - if (dialog.exec() == QDialog::Accepted) { - QString name = dialog.getNameInput(); - if (name == curName) { - return; - } - - if (!curDir->rename(name)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to rename folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(curName), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - fillTreeItem(curItem, curDir); - - emit directoryUpdated(curDir, UpdateAction::InfoChanged); - } -} - -void VDirectoryTree::openDirectoryLocation() const -{ - QTreeWidgetItem *curItem = currentItem(); - V_ASSERT(curItem); - QUrl url = QUrl::fromLocalFile(getVDirectory(curItem)->fetchPath()); - QDesktopServices::openUrl(url); -} - -void VDirectoryTree::reloadAllFromDisk() -{ - if (!m_notebook) - { - return; - } - - QString info = tr("Are you sure to reload notebook %2?") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getName()); - QString msg = tr("Notebook %1 reloaded from disk").arg(m_notebook->getName()); - - if (g_config->getConfirmReloadFolder()) - { - int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"), - info, - tr("VNote will close all the related notes before reload."), - QMessageBox::Ok | QMessageBox::YesToAll | QMessageBox::Cancel, - QMessageBox::Ok, - this); - switch (ret) - { - case QMessageBox::YesToAll: - g_config->setConfirmReloadFolder(false); - // Fall through. - - case QMessageBox::Ok: - break; - - case QMessageBox::Cancel: - return; - - default: - return; - } - } - - m_notebookCurrentDirMap.remove(m_notebook); - - if (!m_editArea->closeFile(m_notebook, false)) - { - return; - } - - m_notebook->close(); - - if (!m_notebook->open()) - { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to open notebook %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getName()), - tr("Please check if path %2 exists.") - .arg(g_config->c_dataTextStyle) - .arg(m_notebook->getPath()), - QMessageBox::Ok, QMessageBox::Ok, this); - clear(); - return; - } - - updateDirectoryTree(); - - if (!msg.isEmpty()) - { - g_mainWin->showStatusMessage(msg); - } -} - -void VDirectoryTree::reloadFromDisk() -{ - if (!m_notebook) { - return; - } - - QString msg; - QString info; - VDirectory *curDir = NULL; - QTreeWidgetItem *curItem = currentItem(); - if (curItem) { - // Reload current directory. - curDir = getVDirectory(curItem); - info = tr("Are you sure to reload folder %2?") - .arg(g_config->c_dataTextStyle).arg(curDir->getName()); - msg = tr("Folder %1 reloaded from disk").arg(curDir->getName()); - } else { - // Reload notebook. - info = tr("Are you sure to reload notebook %2?") - .arg(g_config->c_dataTextStyle).arg(m_notebook->getName()); - msg = tr("Notebook %1 reloaded from disk").arg(m_notebook->getName()); - } - - if (g_config->getConfirmReloadFolder()) { - int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"), - info, - tr("VNote will close all the related notes before reload."), - QMessageBox::Ok | QMessageBox::YesToAll | QMessageBox::Cancel, - QMessageBox::Ok, - this); - switch (ret) { - case QMessageBox::YesToAll: - g_config->setConfirmReloadFolder(false); - // Fall through. - - case QMessageBox::Ok: - break; - - case QMessageBox::Cancel: - return; - - default: - return; - } - } - - m_notebookCurrentDirMap.remove(m_notebook); - - if (curItem) { - if (!m_editArea->closeFile(curDir, false)) { - return; - } - - setCurrentItem(NULL); - - curItem->setExpanded(false); - curDir->setExpanded(false); - - curDir->close(); - - // Remove all its children. - QList children = curItem->takeChildren(); - for (int i = 0; i < children.size(); ++i) { - delete children[i]; - } - - buildSubTree(curItem, 1); - - setCurrentItem(curItem); - } else { - if (!m_editArea->closeFile(m_notebook, false)) { - return; - } - - m_notebook->close(); - - if (!m_notebook->open()) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to open notebook %2.") - .arg(g_config->c_dataTextStyle).arg(m_notebook->getName()), - tr("Please check if path %2 exists.") - .arg(g_config->c_dataTextStyle).arg(m_notebook->getPath()), - QMessageBox::Ok, QMessageBox::Ok, this); - clear(); - return; - } - - updateDirectoryTree(); - } - - if (!msg.isEmpty()) { - g_mainWin->showStatusMessage(msg); - } -} - -void VDirectoryTree::copySelectedDirectories(bool p_isCut) -{ - QList items = selectedItems(); - if (items.isEmpty()) { - return; - } - - QJsonArray dirs; - for (int i = 0; i < items.size(); ++i) { - VDirectory *dir = getVDirectory(items[i]); - dirs.append(dir->fetchPath()); - } - - QJsonObject clip; - clip[ClipboardConfig::c_magic] = getNewMagic(); - clip[ClipboardConfig::c_type] = (int)ClipboardOpType::CopyDir; - clip[ClipboardConfig::c_isCut] = p_isCut; - clip[ClipboardConfig::c_dirs] = dirs; - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(QJsonDocument(clip).toJson(QJsonDocument::Compact)); - - qDebug() << "copied directories info" << clipboard->text(); - - int cnt = dirs.size(); - g_mainWin->showStatusMessage(tr("%1 %2 %3") - .arg(cnt) - .arg(cnt > 1 ? tr("folders") : tr("folder")) - .arg(p_isCut ? tr("cut") : tr("copied"))); -} - -void VDirectoryTree::cutSelectedDirectories() -{ - copySelectedDirectories(true); -} - -void VDirectoryTree::pasteDirectoriesFromClipboard() -{ - if (!pasteAvailable()) { - return; - } - - QJsonObject obj = VUtils::clipboardToJson(); - QJsonArray dirs = obj[ClipboardConfig::c_dirs].toArray(); - bool isCut = obj[ClipboardConfig::c_isCut].toBool(); - QVector dirsToPaste(dirs.size()); - for (int i = 0; i < dirs.size(); ++i) { - dirsToPaste[i] = dirs[i].toString(); - } - - VDirectory *destDir; - QTreeWidgetItem *item = currentItem(); - if (item) { - destDir = getVDirectory(item); - } else { - destDir = m_notebook->getRootDir(); - } - - pasteDirectories(destDir, dirsToPaste, isCut); - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); -} - -void VDirectoryTree::pasteDirectories(VDirectory *p_destDir, - const QVector &p_dirs, - bool p_isCut) -{ - if (!p_destDir || p_dirs.isEmpty()) { - return; - } - - int nrPasted = 0; - for (int i = 0; i < p_dirs.size(); ++i) { - VDirectory *dir = g_vnote->getInternalDirectory(p_dirs[i]); - if (!dir) { - qWarning() << "Copied dir is not an internal folder" << p_dirs[i]; - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to paste folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_dirs[i]), - tr("VNote could not find this folder in any notebook."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - - continue; - } - - if (dir == p_destDir) { - continue; - } - - QString dirName = dir->getName(); - VDirectory *paDir = dir->getParentDirectory(); - if (paDir == p_destDir) { - if (p_isCut) { - continue; - } - - // Copy and paste in the same folder. - // Rename it to xxx_copy. - dirName = VUtils::generateCopiedDirName(paDir->fetchPath(), dirName); - } else { - // Rename it to xxx_copy if needed. - dirName = VUtils::generateCopiedDirName(p_destDir->fetchPath(), dirName); - } - - QString msg; - VDirectory *destDir = NULL; - bool ret = VDirectory::copyDirectory(p_destDir, - dirName, - dir, - p_isCut, - &destDir, - &msg); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to copy folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_dirs[i]), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - if (destDir) { - ++nrPasted; - - // Update QTreeWidget. - bool isWidget; - QTreeWidgetItem *destItem = findVDirectory(p_destDir, &isWidget); - if (destItem || isWidget) { - updateItemDirectChildren(destItem); - } - - if (p_isCut) { - QTreeWidgetItem *srcItem = findVDirectory(paDir, &isWidget); - if (srcItem || isWidget) { - updateItemDirectChildren(srcItem); - } - } - - // Broadcast this update - emit directoryUpdated(destDir, p_isCut ? UpdateAction::Moved : UpdateAction::InfoChanged); - } - } - - qDebug() << "pasted" << nrPasted << "directories"; - if (nrPasted > 0) { - g_mainWin->showStatusMessage(tr("%1 %2 pasted") - .arg(nrPasted) - .arg(nrPasted > 1 ? tr("folders") : tr("folder"))); - } - - getNewMagic(); -} - -bool VDirectoryTree::pasteAvailable() const -{ - QJsonObject obj = VUtils::clipboardToJson(); - if (obj.isEmpty()) { - return false; - } - - if (!obj.contains(ClipboardConfig::c_type)) { - return false; - } - - ClipboardOpType type = (ClipboardOpType)obj[ClipboardConfig::c_type].toInt(); - if (type != ClipboardOpType::CopyDir) { - return false; - } - - if (!obj.contains(ClipboardConfig::c_magic) - || !obj.contains(ClipboardConfig::c_isCut) - || !obj.contains(ClipboardConfig::c_dirs)) { - return false; - } - - int magic = obj[ClipboardConfig::c_magic].toInt(); - if (!checkMagic(magic)) { - return false; - } - - QJsonArray dirs = obj[ClipboardConfig::c_dirs].toArray(); - return !dirs.isEmpty(); -} - -void VDirectoryTree::mousePressEvent(QMouseEvent *event) -{ - QTreeWidgetItem *item = itemAt(event->pos()); - if (!item) { - setCurrentItem(NULL); - } - - VTreeWidget::mousePressEvent(event); -} - -void VDirectoryTree::keyPressEvent(QKeyEvent *event) -{ - int key = event->key(); - int modifiers = event->modifiers(); - - switch (key) { - case Qt::Key_Return: - { - QTreeWidgetItem *item = currentItem(); - if (item) { - item->setExpanded(!item->isExpanded()); - } - - break; - } - - case Qt::Key_Asterisk: - { - if (modifiers == Qt::ShiftModifier) { - // *, by default will expand current item recursively. - // We build the tree recursively before the expanding. - QTreeWidgetItem *item = currentItem(); - if (item) { - buildSubTree(item, -1); - } - } - - break; - } - - default: - break; - } - - VTreeWidget::keyPressEvent(event); -} - -QTreeWidgetItem *VDirectoryTree::findVDirectory(const VDirectory *p_dir, bool *p_widget) -{ - if (p_widget) { - *p_widget = false; - } - - if (!p_dir) { - return NULL; - } else if (p_dir->getNotebookName() != m_notebook->getName()) { - return NULL; - } else if (p_dir == m_notebook->getRootDir()) { - if (p_widget) { - *p_widget = true; - } - return NULL; - } - - bool isWidget; - QTreeWidgetItem *pItem = findVDirectory(p_dir->getParentDirectory(), &isWidget); - if (pItem) { - // Iterate all its children to find the match. - int nrChild = pItem->childCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = pItem->child(i); - if (getVDirectory(item) == p_dir) { - return item; - } - } - } else if (isWidget) { - // Iterate all the top-level items. - int nrChild = topLevelItemCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = topLevelItem(i); - if (getVDirectory(item) == p_dir) { - return item; - } - } - } - - return NULL; -} - -bool VDirectoryTree::locateDirectory(const VDirectory *p_directory) -{ - if (p_directory) { - if (p_directory->getNotebook() != m_notebook) { - return false; - } - - QTreeWidgetItem *item = expandToVDirectory(p_directory); - if (item) { - setCurrentItem(item); - } - - return item; - } - - return false; -} - -QTreeWidgetItem *VDirectoryTree::expandToVDirectory(const VDirectory *p_directory) -{ - if (!p_directory - || p_directory->getNotebook() != m_notebook - || p_directory == m_notebook->getRootDir()) { - return NULL; - } - - if (p_directory->getParentDirectory() == m_notebook->getRootDir()) { - // Top-level items. - int nrChild = topLevelItemCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = topLevelItem(i); - if (getVDirectory(item) == p_directory) { - return item; - } - } - } else { - QTreeWidgetItem *pItem = expandToVDirectory(p_directory->getParentDirectory()); - if (!pItem) { - return NULL; - } - - int nrChild = pItem->childCount(); - if (nrChild == 0) { - buildSubTree(pItem, 1); - } - - nrChild = pItem->childCount(); - for (int i = 0; i < nrChild; ++i) { - QTreeWidgetItem *item = pItem->child(i); - if (getVDirectory(item) == p_directory) { - return item; - } - } - } - - return NULL; -} - -void VDirectoryTree::expandSubTree(QTreeWidgetItem *p_item) -{ - if (!p_item) { - return; - } - - VDirectory *dir = getVDirectory(p_item); - int nrChild = p_item->childCount(); - for (int i = 0; i < nrChild; ++i) { - expandSubTree(p_item->child(i)); - } - - if (dir->isExpanded()) { - Q_ASSERT(nrChild > 0); - expandItem(p_item); - } -} - -void VDirectoryTree::showNavigation() -{ - VNavigationMode::showNavigation(this); -} - -bool VDirectoryTree::handleKeyNavigation(int p_key, bool &p_succeed) -{ - return VNavigationMode::handleKeyNavigation(this, - p_key, - p_succeed); -} - -int VDirectoryTree::getNewMagic() -{ - m_magicForClipboard = (int)QDateTime::currentDateTime().toTime_t(); - m_magicForClipboard |= qrand(); - - return m_magicForClipboard; -} - -bool VDirectoryTree::checkMagic(int p_magic) const -{ - return m_magicForClipboard == p_magic; -} - -void VDirectoryTree::sortItems() -{ - if (!m_notebook) { - return; - } - - QTreeWidgetItem *item = currentItem(); - if (item && item->parent()) { - sortItems(getVDirectory(item->parent())); - } else { - sortItems(m_notebook->getRootDir()); - } - - if (item) { - setCurrentItem(item); - } -} - -void VDirectoryTree::sortItems(VDirectory *p_dir) -{ - if (!p_dir) { - return; - } - - const QVector &dirs = p_dir->getSubDirs(); - if (dirs.size() < 2) { - return; - } - - bool isNotebook = p_dir->parent() == NULL; - - VSortDialog dialog(tr("Sort Folders"), - tr("Sort folders in %1 %3 " - "in the configuration file.") - .arg(isNotebook ? tr("notebook") : tr("folder")) - .arg(g_config->c_dataTextStyle) - .arg(isNotebook ? p_dir->getNotebook()->getName() : p_dir->getName()), - this); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(2); - QStringList headers; - headers << tr("Name") << tr("Created Time"); - tree->setHeaderLabels(headers); - - for (int i = 0; i < dirs.size(); ++i) { - const VDirectory *dir = dirs[i]; - Q_ASSERT(dir->isOpened()); - QString createdTime = VUtils::displayDateTime(dir->getCreatedTimeUtc().toLocalTime(), true); - QStringList cols; - cols << dir->getName() << createdTime; - QTreeWidgetItem *item = new QTreeWidgetItem(tree, cols); - - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == dirs.size()); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - qDebug() << "sort dirs" << sortedIdx; - if (!p_dir->sortSubDirectories(sortedIdx)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to sort folders in %1 %3.") - .arg(isNotebook ? tr("notebook") : tr("folder")) - .arg(g_config->c_dataTextStyle) - .arg(isNotebook ? p_dir->getNotebook()->getName() : p_dir->getName()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateItemDirectChildren(findVDirectory(p_dir)); - } -} - -VDirectory *VDirectoryTree::currentDirectory() const -{ - QTreeWidgetItem *item = currentItem(); - if (item) { - return getVDirectory(item); - } - - return NULL; -} - -void VDirectoryTree::pinDirectoryToHistory() -{ - QTreeWidgetItem *curItem = currentItem(); - V_ASSERT(curItem); - g_mainWin->getHistoryList()->pinFolder(getVDirectory(curItem)->fetchPath()); - g_mainWin->showStatusMessage(tr("1 folder pinned to History")); -} - -Qt::DropActions VDirectoryTree::supportedDropActions() const -{ - return Qt::CopyAction | Qt::MoveAction; -} - -bool VDirectoryTree::dropMimeData(QTreeWidgetItem *p_parent, - int p_index, - const QMimeData *p_data, - Qt::DropAction p_action) -{ - Q_UNUSED(p_index); - - if (!p_parent) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Please drop it on a folder item."), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - return false; - } - - if (p_data->hasFormat(ClipboardConfig::c_format)) { - VDirectory *dir = getVDirectory(p_parent); - if (!dir) { - return false; - } - - QByteArray ba = p_data->data(ClipboardConfig::c_format); - QJsonObject obj = QJsonDocument::fromJson(ba).object(); - if (obj.isEmpty()) { - return false; - } - - if (obj[ClipboardConfig::c_type] != (int)ClipboardOpType::CopyFile) { - return false; - } - - QJsonArray files = obj[ClipboardConfig::c_files].toArray(); - if (files.isEmpty()) { - return false; - } - - QVector filesToPaste; - for (auto const & file : files) { - filesToPaste.append(file.toString()); - } - - qDebug() << "paste files from dropped mime data" << dir->getName() << filesToPaste; - g_mainWin->getFileList()->pasteFiles(dir, filesToPaste, p_action == Qt::MoveAction); - return true; - } - - return false; -} - -void VDirectoryTree::dropEvent(QDropEvent *p_event) -{ - // Distinguish copy and cut. - int modifiers = p_event->keyboardModifiers(); - if (modifiers & Qt::ControlModifier) { - p_event->setDropAction(Qt::CopyAction); - } else { - // Cut. - // Will pass to dropMimeData(). - p_event->setDropAction(Qt::MoveAction); - } - - QTreeWidget::dropEvent(p_event); -} - -QStringList VDirectoryTree::mimeTypes() const -{ - return QStringList(ClipboardConfig::c_format); -} diff --git a/src/vdirectorytree.h b/src/vdirectorytree.h deleted file mode 100644 index 911cb492..00000000 --- a/src/vdirectorytree.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef VDIRECTORYTREE_H -#define VDIRECTORYTREE_H - -#include -#include -#include -#include -#include -#include - -#include "vtreewidget.h" -#include "vdirectory.h" -#include "vnotebook.h" -#include "vnavigationmode.h" -#include "vconstants.h" - -class VEditArea; -class QLabel; - -class VDirectoryTree : public VTreeWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VDirectoryTree(QWidget *parent = 0); - - void setEditArea(VEditArea *p_editArea); - - // Locate to the item representing @p_directory. - bool locateDirectory(const VDirectory *p_directory); - - const VNotebook *currentNotebook() const; - - VDirectory *currentDirectory() const; - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - void reloadAllFromDisk(); - -signals: - void currentDirectoryChanged(VDirectory *p_directory); - - void directoryUpdated(const VDirectory *p_directory, UpdateAction p_act); - -public slots: - // Set directory tree to display a given notebook @p_notebook. - void setNotebook(VNotebook *p_notebook); - - // Create a root folder. - void newRootDirectory(); - - // View and edit info about directory. - void editDirectoryInfo(); - - // Clear and re-build the whole directory tree. - // Do not load all the sub-directories at once. - void updateDirectoryTree(); - -private slots: - // Set the state of expansion of the directory. - void handleItemExpanded(QTreeWidgetItem *p_item); - - // Set the state of expansion of the directory. - void handleItemCollapsed(QTreeWidgetItem *p_item); - - void contextMenuRequested(QPoint pos); - - // Directory selected folder. - // Currently only support single selected item. - void deleteSelectedDirectory(); - - // Create sub-directory of current item's directory. - void newSubDirectory(); - - void newDirectory(QTreeWidgetItem *p_parentItem); - - // Current tree item changed. - void currentDirectoryItemChanged(QTreeWidgetItem *currentItem); - - // Copy selected directories. - // Will put a Json string into the clipboard which contains the information - // about copied directories. - void copySelectedDirectories(bool p_isCut = false); - - void cutSelectedDirectories(); - - // Paste directories from clipboard as sub-directories of current item. - void pasteDirectoriesFromClipboard(); - - // Open the folder's parent directory in system's file browser. - void openDirectoryLocation() const; - - // Reload the content of current directory. - void reloadFromDisk(); - - // Sort sub-folders of current item's folder. - void sortItems(); - - // Pin selected directory to History. - void pinDirectoryToHistory(); - -protected: - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - - QStringList mimeTypes() const Q_DECL_OVERRIDE; - - Qt::DropActions supportedDropActions() const Q_DECL_OVERRIDE; - - // Will be called inside dropEvent(). - bool dropMimeData(QTreeWidgetItem *p_parent, - int p_index, - const QMimeData *p_data, - Qt::DropAction p_action) Q_DECL_OVERRIDE; - - // Drop the data. - void dropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE; - -private: - // Build the subtree of @p_parent recursively to the depth @p_depth. - // @p_depth: negative - infinite levels. - // Will expand the item if the corresponding directory was expanded before. - // Will treat items with children as items having been built before. - void buildSubTree(QTreeWidgetItem *p_parent, int p_depth); - - // Fill the content of a tree item according to @p_directory. - void fillTreeItem(QTreeWidgetItem *p_item, VDirectory *p_directory); - - void initShortcuts(); - - // Update @p_item's direct children only: deleted, added, renamed. - void updateItemDirectChildren(QTreeWidgetItem *p_item); - - // Find the corresponding item of @p_dir; - // Return's NULL if no item is found and it is the root directory if @p_widget is true. - QTreeWidgetItem *findVDirectory(const VDirectory *p_dir, bool *p_widget = NULL); - - QPointer getVDirectory(QTreeWidgetItem *p_item) const; - - // Paste @p_dirs as sub-directory of @p_destDir. - void pasteDirectories(VDirectory *p_destDir, - const QVector &p_dirs, - bool p_isCut); - - // Build the subtree of @p_item's children if it has not been built yet. - // We need to fill the children before showing a item to get a correct render. - void buildChildren(QTreeWidgetItem *p_item); - - // Expand/create the directory tree nodes to @p_directory. - QTreeWidgetItem *expandToVDirectory(const VDirectory *p_directory); - - // Expand the currently-built subtree of @p_item according to VDirectory.isExpanded(). - void expandSubTree(QTreeWidgetItem *p_item); - - // We use a map to save and restore current directory of each notebook. - // Try to restore current directory after changing notebook. - // Return false if no cache item found for current notebook. - bool restoreCurrentItem(); - - // Generate new magic to m_magicForClipboard. - int getNewMagic(); - - // Check if @p_magic equals to m_magicForClipboard. - bool checkMagic(int p_magic) const; - - // Check if clipboard contains valid info to paste as directories. - bool pasteAvailable() const; - - // Sort sub-directories of @p_dir. - void sortItems(VDirectory *p_dir); - - QPointer m_notebook; - - VEditArea *m_editArea; - - // Each notebook's current item's VDirectory. - QHash m_notebookCurrentDirMap; - - // Magic number for clipboard operations. - int m_magicForClipboard; -}; - -inline QPointer VDirectoryTree::getVDirectory(QTreeWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - return p_item->data(0, Qt::UserRole).value(); -} - -inline void VDirectoryTree::setEditArea(VEditArea *p_editArea) -{ - m_editArea = p_editArea; -} - -inline const VNotebook *VDirectoryTree::currentNotebook() const -{ - return m_notebook; -} - -#endif // VDIRECTORYTREE_H diff --git a/src/vdocument.cpp b/src/vdocument.cpp deleted file mode 100644 index c967a1d5..00000000 --- a/src/vdocument.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#include "vdocument.h" - -#include - -#include "vfile.h" -#include "vplantumlhelper.h" -#include "vgraphvizhelper.h" - -VDocument::VDocument(const VFile *v_file, QObject *p_parent) - : QObject(p_parent), - m_file(v_file), - m_readyToHighlight(false), - m_plantUMLHelper(NULL), - m_graphvizHelper(NULL), - m_nextID(0), - m_webViewMuted(false) -{ -} - -void VDocument::updateText() -{ - if (m_file) { - emit textChanged(m_file->getContent()); - } -} - -void VDocument::setToc(const QString &toc, int /* baseLevel */) -{ - if (toc == m_toc) { - return; - } - m_toc = toc; - emit tocChanged(m_toc); -} - -QString VDocument::getToc() -{ - return m_toc; -} - -void VDocument::scrollToAnchor(const QString &anchor) -{ - m_header = anchor; - - emit requestScrollToAnchor(anchor); -} - -void VDocument::setHeader(const QString &anchor) -{ - if (m_webViewMuted || anchor == m_header) { - return; - } - - m_header = anchor; - emit headerChanged(m_header); -} - -void VDocument::setHtml(const QString &html) -{ - if (html == m_html) { - return; - } - m_html = html; - emit htmlChanged(m_html); -} - -void VDocument::setLog(const QString &p_log) -{ - qDebug() << "JS:" << p_log; -} - -void VDocument::keyPressEvent(int p_key, bool p_ctrl, bool p_shift, bool p_meta) -{ - emit keyPressed(p_key, p_ctrl, p_shift, p_meta); -} - -void VDocument::highlightTextAsync(const QString &p_text, int p_id, unsigned long long p_timeStamp) -{ - emit requestHighlightText(p_text, p_id, p_timeStamp); -} - -void VDocument::highlightTextCB(const QString &p_html, int p_id, unsigned long long p_timeStamp) -{ - emit textHighlighted(p_html, p_id, p_timeStamp); -} - -void VDocument::textToHtmlAsync(int p_identitifer, - int p_id, - int p_timeStamp, - const QString &p_text, - bool p_inlineStyle) -{ - emit requestTextToHtml(p_identitifer, p_id, p_timeStamp, p_text, p_inlineStyle); -} - -void VDocument::htmlToTextAsync(int p_identitifer, - int p_id, - int p_timeStamp, - const QString &p_html) -{ - emit requestHtmlToText(p_identitifer, p_id, p_timeStamp, p_html); -} - -void VDocument::getHtmlContentAsync() -{ - emit requestHtmlContent(); -} - -void VDocument::textToHtmlCB(int p_identitifer, int p_id, int p_timeStamp, const QString &p_html) -{ - emit textToHtmlFinished(p_identitifer, p_id, p_timeStamp, p_html); -} - -void VDocument::htmlToTextCB(int p_identitifer, int p_id, int p_timeStamp, const QString &p_text) -{ - emit htmlToTextFinished(p_identitifer, p_id, p_timeStamp, p_text); -} - -void VDocument::noticeReadyToHighlightText() -{ - m_readyToHighlight = true; - emit readyToHighlightText(); -} - -void VDocument::noticeReadyToTextToHtml() -{ - m_readyToTextToHtml = true; -} - -void VDocument::setFile(const VFile *p_file) -{ - m_file = p_file; -} - -const VFile *VDocument::getFile() const -{ - return m_file; -} - -void VDocument::finishLogics() -{ - qDebug() << "Web side finished logics" << this; - emit logicsFinished(); -} - -void VDocument::htmlContentCB(const QString &p_head, - const QString &p_style, - const QString &p_body) -{ - emit htmlContentFinished(p_head, p_style, p_body); -} - -void VDocument::updateWordCountInfo(int p_wordCount, - int p_charWithoutSpacesCount, - int p_charWithSpacesCount) -{ - m_wordCountInfo.m_mode = VWordCountInfo::Read; - m_wordCountInfo.m_wordCount = p_wordCount; - m_wordCountInfo.m_charWithoutSpacesCount = p_charWithoutSpacesCount; - m_wordCountInfo.m_charWithSpacesCount = p_charWithSpacesCount; - - emit wordCountInfoUpdated(); -} - -void VDocument::processPlantUML(int p_id, const QString &p_format, const QString &p_text) -{ - if (!m_plantUMLHelper) { - m_plantUMLHelper = new VPlantUMLHelper(this); - connect(m_plantUMLHelper, &VPlantUMLHelper::resultReady, - this, &VDocument::plantUMLResultReady); - } - - m_plantUMLHelper->processAsync(p_id, 0, p_format, p_text); -} - -void VDocument::processGraphviz(int p_id, const QString &p_format, const QString &p_text) -{ - if (!m_graphvizHelper) { - m_graphvizHelper = new VGraphvizHelper(this); - connect(m_graphvizHelper, &VGraphvizHelper::resultReady, - this, &VDocument::graphvizResultReady); - } - - m_graphvizHelper->processAsync(p_id, 0, p_format, p_text); -} - -void VDocument::setPreviewEnabled(bool p_enabled) -{ - emit requestPreviewEnabled(p_enabled); -} - -void VDocument::previewCodeBlock(int p_id, - const QString &p_lang, - const QString &p_text, - bool p_livePreview) -{ - emit requestPreviewCodeBlock(p_id, p_lang, p_text, p_livePreview); -} - -void VDocument::setPreviewContent(const QString &p_lang, const QString &p_html) -{ - emit requestSetPreviewContent(p_lang, p_html); -} - -void VDocument::previewCodeBlockCB(int p_id, const QString &p_lang, const QString &p_html) -{ - emit codeBlockPreviewReady(p_id, p_lang, p_html); -} - -void VDocument::performSmartLivePreview(const QString &p_lang, - const QString &p_text, - const QString &p_hints, - bool p_isRegex) -{ - if (!p_text.isEmpty()) { - qDebug() << "performSmartLivePreview" << p_lang << p_text << p_hints << p_isRegex; - emit requestPerformSmartLivePreview(p_lang, p_text, p_hints, p_isRegex); - } -} diff --git a/src/vdocument.h b/src/vdocument.h deleted file mode 100644 index f60c598a..00000000 --- a/src/vdocument.h +++ /dev/null @@ -1,260 +0,0 @@ -#ifndef VDOCUMENT_H -#define VDOCUMENT_H - -#include -#include - -#include "vwordcountinfo.h" - -class VFile; -class VPlantUMLHelper; -class VGraphvizHelper; - -class VDocument : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged) - Q_PROPERTY(QString toc MEMBER m_toc NOTIFY tocChanged) - Q_PROPERTY(QString html MEMBER m_html NOTIFY htmlChanged) - -public: - // @p_file could be NULL. - VDocument(const VFile *p_file, QObject *p_parent = 0); - - QString getToc(); - - // Scroll to @anchor in the web. - // @anchor is the id without '#', like "toc_1". If empty, will scroll to top. - void scrollToAnchor(const QString &anchor); - - void setHtml(const QString &html); - - // Request to highlight a segment text. - // Use p_id to identify the result. - void highlightTextAsync(const QString &p_text, int p_id, unsigned long long p_timeStamp); - - // Request to convert @p_text to HTML. - void textToHtmlAsync(int p_identitifer, - int p_id, - int p_timeStamp, - const QString &p_text, - bool p_inlineStyle); - - // Request to convert @p_html to Markdown text. - void htmlToTextAsync(int p_identitifer, - int p_id, - int p_timeStamp, - const QString &p_html); - - void setFile(const VFile *p_file); - - const VFile *getFile() const; - - bool isReadyToHighlight() const; - - bool isReadyToTextToHtml() const; - - // Request to get the HTML content. - void getHtmlContentAsync(); - - const VWordCountInfo &getWordCountInfo() const; - - // Whether change to preview mode. - void setPreviewEnabled(bool p_enabled); - - // @p_livePreview: if true, display the result in the preview-div; otherwise, - // call previewCodeBlockCB() to pass back the result. - // Only for online parser. - void previewCodeBlock(int p_id, - const QString &p_lang, - const QString &p_text, - bool p_livePreview); - - // Set the content of the preview. - void setPreviewContent(const QString &p_lang, const QString &p_html); - - int registerIdentifier(); - - void muteWebView(bool p_muted); - - void performSmartLivePreview(const QString &p_lang, - const QString &p_text, - const QString &p_hints, - bool p_isRegex); - -public slots: - // Will be called in the HTML side - - // @toc: the HTML of the TOC. - // @baseLevel: the base level of @toc, starting from 1. It is the top level - // in the @toc. - void setToc(const QString &toc, int baseLevel); - - // When the Web view has been scrolled, it will signal current header anchor. - // Empty @anchor to indicate an invalid header. - // The header does not begins with '#'. - void setHeader(const QString &anchor); - - void setLog(const QString &p_log); - void keyPressEvent(int p_key, bool p_ctrl, bool p_shift, bool p_meta); - void updateText(); - - void highlightTextCB(const QString &p_html, int p_id, unsigned long long p_timeStamp); - - void noticeReadyToHighlightText(); - - void textToHtmlCB(int p_identitifer, int p_id, int p_timeStamp, const QString &p_html); - - void htmlToTextCB(int p_identitifer, int p_id, int p_timeStamp, const QString &p_text); - - void noticeReadyToTextToHtml(); - - // Web-side handle logics (MathJax etc.) is finished. - // But the page may not finish loading, such as images. - void finishLogics(); - - void htmlContentCB(const QString &p_head, - const QString &p_style, - const QString &p_body); - - void updateWordCountInfo(int p_wordCount, - int p_charWithoutSpacesCount, - int p_charWithSpacesCount); - - // Web-side call this to process PlantUML locally. - void processPlantUML(int p_id, const QString &p_format, const QString &p_text); - - // Web-side call this to process Graphviz locally. - void processGraphviz(int p_id, const QString &p_format, const QString &p_text); - - void previewCodeBlockCB(int p_id, const QString &p_lang, const QString &p_html); - -signals: - void textChanged(const QString &text); - - void tocChanged(const QString &toc); - - void requestScrollToAnchor(const QString &anchor); - - // @anchor is the id of that anchor, without '#'. - void headerChanged(const QString &anchor); - - void htmlChanged(const QString &html); - - void keyPressed(int p_key, bool p_ctrl, bool p_shift, bool p_meta); - - void requestHighlightText(const QString &p_text, int p_id, unsigned long long p_timeStamp); - - void textHighlighted(const QString &p_html, int p_id, unsigned long long p_timeStamp); - - void readyToHighlightText(); - - void logicsFinished(); - - void requestTextToHtml(int p_identitifer, - int p_id, - int p_timeStamp, - const QString &p_text, - bool p_inlineStyle); - - void requestHtmlToText(int p_identitifer, - int p_id, - int p_timeStamp, - const QString &p_html); - - void textToHtmlFinished(int p_identitifer, int p_id, int p_timeStamp, const QString &p_html); - - void htmlToTextFinished(int p_identitifer, int p_id, int p_timeStamp, const QString &p_text); - - void requestHtmlContent(); - - void htmlContentFinished(const QString &p_headContent, - const QString &p_styleContent, - const QString &p_bodyContent); - - void wordCountInfoUpdated(); - - void plantUMLResultReady(int p_id, - unsigned long long p_timeStamp, - const QString &p_format, - const QString &p_result); - - void graphvizResultReady(int p_id, - unsigned long long p_timeStamp, - const QString &p_format, - const QString &p_result); - - void requestPreviewEnabled(bool p_enabled); - - void requestPreviewCodeBlock(int p_id, - const QString &p_lang, - const QString &p_text, - bool p_livePreview); - - void requestSetPreviewContent(const QString &p_lang, const QString &p_html); - - void codeBlockPreviewReady(int p_id, const QString &p_lang, const QString &p_html); - - void requestMuted(bool p_muted); - - void requestPerformSmartLivePreview(const QString &p_lang, - const QString &p_text, - const QString &p_hints, - bool p_isRegex); - -private: - QString m_toc; - QString m_header; - - // m_text does NOT contain actual content. - QString m_text; - - // When using Hoedown, m_html will contain the html content. - QString m_html; - - const VFile *m_file; - - // Whether the web side is ready to handle highlight text request. - bool m_readyToHighlight; - - // Whether the web side is ready to convert text to html. - bool m_readyToTextToHtml; - - VWordCountInfo m_wordCountInfo; - - VPlantUMLHelper *m_plantUMLHelper; - - VGraphvizHelper *m_graphvizHelper; - - int m_nextID; - - // Whether propogate signals from web view. - bool m_webViewMuted; -}; - -inline bool VDocument::isReadyToHighlight() const -{ - return m_readyToHighlight; -} - -inline bool VDocument::isReadyToTextToHtml() const -{ - return m_readyToTextToHtml; -} - -inline const VWordCountInfo &VDocument::getWordCountInfo() const -{ - return m_wordCountInfo; -} - -inline int VDocument::registerIdentifier() -{ - return ++m_nextID; -} - -inline void VDocument::muteWebView(bool p_muted) -{ - m_webViewMuted = p_muted; - emit requestMuted(m_webViewMuted); -} -#endif // VDOCUMENT_H diff --git a/src/vdoublerowitemwidget.cpp b/src/vdoublerowitemwidget.cpp deleted file mode 100644 index 465c3301..00000000 --- a/src/vdoublerowitemwidget.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "vdoublerowitemwidget.h" - -#include -#include -#include - -VDoubleRowItemWidget::VDoubleRowItemWidget(QWidget *p_parent) - : QWidget(p_parent) -{ - m_firstLabel = new QLabel(this); - m_firstLabel->setProperty("FirstRowLabel", true); - - m_secondLabel = new QLabel(this); - m_secondLabel->setProperty("SecondRowLabel", true); - - QVBoxLayout *layout = new QVBoxLayout(); - layout->addWidget(m_firstLabel); - layout->addWidget(m_secondLabel); - layout->addStretch(); - layout->setContentsMargins(3, 0, 0, 0); - - setLayout(layout); -} - -void VDoubleRowItemWidget::setText(const QString &p_firstText, - const QString &p_secondText) -{ - m_firstLabel->setText(p_firstText); - - if (!p_secondText.isEmpty()) { - m_secondLabel->setText(p_secondText); - m_secondLabel->show(); - } else { - m_secondLabel->hide(); - } -} - -VDoubleRowItemWidget *VDoubleRowItemWidget::cloneWidget(VDoubleRowItemWidget *p_widget, - QWidget *p_parent) -{ - VDoubleRowItemWidget *widget = new VDoubleRowItemWidget(p_parent); - widget->setText(p_widget->m_firstLabel->text(), p_widget->m_secondLabel->text()); - - return widget; -} diff --git a/src/vdoublerowitemwidget.h b/src/vdoublerowitemwidget.h deleted file mode 100644 index 7136cd19..00000000 --- a/src/vdoublerowitemwidget.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef VDOUBLEROWITEMWIDGET_H -#define VDOUBLEROWITEMWIDGET_H - -#include - -class QLabel; - -class VDoubleRowItemWidget : public QWidget -{ - Q_OBJECT -public: - explicit VDoubleRowItemWidget(QWidget *p_parent = nullptr); - - void setText(const QString &p_firstText, const QString &p_secondText); - - static VDoubleRowItemWidget *cloneWidget(VDoubleRowItemWidget *p_widget, - QWidget *p_parent = nullptr); - -private: - QLabel *m_firstLabel; - QLabel *m_secondLabel; -}; - -#endif // VDOUBLEROWITEMWIDGET_H diff --git a/src/vdownloader.cpp b/src/vdownloader.cpp deleted file mode 100644 index e413af22..00000000 --- a/src/vdownloader.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "vdownloader.h" - -#include "utils/vutils.h" - -VDownloader::VDownloader(QObject *parent) - : QObject(parent) -{ - connect(&webCtrl, &QNetworkAccessManager::finished, - this, &VDownloader::handleDownloadFinished); -} - -void VDownloader::handleDownloadFinished(QNetworkReply *reply) -{ - if (reply->error() != QNetworkReply::NoError) { - qWarning() << "download reply error" << reply->error(); - } - - data = reply->readAll(); - reply->deleteLater(); - // The url() of the reply may be redirected and different from that of the request. - emit downloadFinished(data, reply->request().url().toString()); -} - -static QNetworkRequest networkRequest(const QUrl &p_url) -{ - QNetworkRequest request(p_url); - /* - QSslConfiguration config = QSslConfiguration::defaultConfiguration(); - config.setProtocol(QSsl::SslV3); - config.setPeerVerifyMode(QSslSocket::VerifyNone); - request.setSslConfiguration(config); - */ - - request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); - - return request; -} - -void VDownloader::download(const QUrl &p_url) -{ - if (!p_url.isValid()) { - return; - } - - webCtrl.get(networkRequest(p_url)); -} - -QByteArray VDownloader::downloadSync(const QUrl &p_url) -{ - QByteArray data; - if (!p_url.isValid()) { - return data; - } - - bool finished = false; - QNetworkAccessManager nam; - connect(&nam, &QNetworkAccessManager::finished, - [&data, &finished](QNetworkReply *p_reply) { - if (p_reply->error() != QNetworkReply::NoError) { - qWarning() << "download reply error" << p_reply->error(); - } - - data = p_reply->readAll(); - p_reply->deleteLater(); - finished = true; - }); - - nam.get(networkRequest(p_url)); - - while (!finished) { - VUtils::sleepWait(100); - } - - return data; -} diff --git a/src/vdownloader.h b/src/vdownloader.h deleted file mode 100644 index fb0cfce7..00000000 --- a/src/vdownloader.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef VDOWNLOADER_H -#define VDOWNLOADER_H - -#include -#include -#include -#include -#include -#include - -class VDownloader : public QObject -{ - Q_OBJECT -public: - explicit VDownloader(QObject *parent = 0); - void download(const QUrl &p_url); - - static QByteArray downloadSync(const QUrl &p_url); - -signals: - // Url is the original url of the request. - void downloadFinished(const QByteArray &data, const QString &url); - -private slots: - void handleDownloadFinished(QNetworkReply *reply); - -private: - QNetworkAccessManager webCtrl; - QByteArray data; -}; - -#endif // VDOWNLOADER_H diff --git a/src/vedit.cpp b/src/vedit.cpp deleted file mode 100644 index f4f2a720..00000000 --- a/src/vedit.cpp +++ /dev/null @@ -1,1428 +0,0 @@ -#include -#include -#include -#include "vedit.h" -#include "vnote.h" -#include "vconfigmanager.h" -#include "vtableofcontent.h" -#include "utils/vutils.h" -#include "utils/veditutils.h" -#include "utils/vmetawordmanager.h" -#include "veditoperations.h" -#include "vedittab.h" -#include "dialog/vinsertlinkdialog.h" -#include "utils/viconutils.h" - -extern VConfigManager *g_config; - -extern VNote *g_vnote; - -extern VMetaWordManager *g_mwMgr; - -VEdit::VEdit(VFile *p_file, QWidget *p_parent) - : QTextEdit(p_parent), m_file(p_file), - m_editOps(NULL), m_enableInputMethod(true) -{ - const int labelTimerInterval = 500; - const int extraSelectionHighlightTimer = 500; - const int labelSize = 64; - - m_selectedWordColor = QColor(g_config->getEditorSelectedWordBg()); - m_searchedWordColor = QColor(g_config->getEditorSearchedWordBg()); - m_searchedWordCursorColor = QColor(g_config->getEditorSearchedWordCursorBg()); - m_incrementalSearchedWordColor = QColor(g_config->getEditorIncrementalSearchedWordBg()); - m_trailingSpaceColor = QColor(g_config->getEditorTrailingSpaceBg()); - - QPixmap wrapPixmap(":/resources/icons/search_wrap.svg"); - m_wrapLabel = new QLabel(this); - m_wrapLabel->setPixmap(wrapPixmap.scaled(labelSize, labelSize)); - m_wrapLabel->hide(); - m_labelTimer = new QTimer(this); - m_labelTimer->setSingleShot(true); - m_labelTimer->setInterval(labelTimerInterval); - connect(m_labelTimer, &QTimer::timeout, - this, &VEdit::labelTimerTimeout); - - m_highlightTimer = new QTimer(this); - m_highlightTimer->setSingleShot(true); - m_highlightTimer->setInterval(extraSelectionHighlightTimer); - connect(m_highlightTimer, &QTimer::timeout, - this, &VEdit::doHighlightExtraSelections); - - m_extraSelections.resize((int)SelectionId::MaxSelection); - - updateFontAndPalette(); - - m_config.init(QFontMetrics(font()), false); - updateConfig(); - - connect(this, &VEdit::cursorPositionChanged, - this, &VEdit::handleCursorPositionChanged); - - connect(this, &VEdit::selectionChanged, - this, &VEdit::highlightSelectedWord); - - m_lineNumberArea = new LineNumberArea(this); - connect(document(), &QTextDocument::blockCountChanged, - this, &VEdit::updateLineNumberAreaMargin); - connect(this, &QTextEdit::textChanged, - this, &VEdit::updateLineNumberArea); - connect(verticalScrollBar(), &QScrollBar::valueChanged, - this, &VEdit::updateLineNumberArea); - - updateLineNumberAreaMargin(); - - connect(document(), &QTextDocument::contentsChange, - this, &VEdit::updateBlockLineDistanceHeight); -} - -VEdit::~VEdit() -{ -} - -void VEdit::updateConfig() -{ - m_config.update(QFontMetrics(font())); - - if (m_config.m_tabStopWidth > 0) { - setTabStopWidth(m_config.m_tabStopWidth); - } - - emit configUpdated(); -} - -void VEdit::beginEdit() -{ - updateFontAndPalette(); - - updateConfig(); - - setReadOnlyAndHighlight(false); - - setModified(false); -} - -void VEdit::endEdit() -{ - setReadOnlyAndHighlight(true); -} - -void VEdit::saveFile() -{ - Q_ASSERT(m_file->isModifiable()); - - if (!document()->isModified()) { - return; - } - - m_file->setContent(toHtml()); - setModified(false); -} - -void VEdit::reloadFile() -{ - setHtml(m_file->getContent()); - - setModified(false); -} - -bool VEdit::scrollToBlock(int p_blockNumber) -{ - QTextBlock block = document()->findBlockByNumber(p_blockNumber); - if (block.isValid()) { - VEditUtils::scrollBlockInPage(this, block.blockNumber(), 0); - moveCursor(QTextCursor::EndOfBlock); - return true; - } - - return false; -} - -bool VEdit::isModified() const -{ - return document()->isModified(); -} - -void VEdit::setModified(bool p_modified) -{ - document()->setModified(p_modified); -} - -void VEdit::insertImage() -{ - if (m_editOps) { - m_editOps->insertImage(); - } -} - -void VEdit::insertLink() -{ - if (!m_editOps) { - return; - } - - QString text; - QString linkText, linkUrl; - QTextCursor cursor = textCursor(); - if (cursor.hasSelection()) { - text = VEditUtils::selectedText(cursor).trimmed(); - // Only pure space is accepted. - QRegExp reg("[\\S ]*"); - if (reg.exactMatch(text)) { - QUrl url = QUrl::fromUserInput(text, - m_file->fetchBasePath()); - QRegExp urlReg("[\\.\\\\/]"); - if (url.isValid() - && text.contains(urlReg)) { - // Url. - linkUrl = text; - } else { - // Text. - linkText = text; - } - } - } - - VInsertLinkDialog dialog(tr("Insert Link"), - "", - "", - linkText, - linkUrl, - false, - this); - if (dialog.exec() == QDialog::Accepted) { - linkText = dialog.getLinkText(); - linkUrl = dialog.getLinkUrl(); - Q_ASSERT(!linkText.isEmpty() && !linkUrl.isEmpty()); - - m_editOps->insertLink(linkText, linkUrl); - } -} - -bool VEdit::peekText(const QString &p_text, uint p_options, bool p_forward) -{ - if (p_text.isEmpty()) { - makeBlockVisible(document()->findBlock(textCursor().selectionStart())); - highlightIncrementalSearchedWord(QTextCursor()); - return false; - } - - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, p_options, p_forward, - p_forward ? textCursor().position() + 1 - : textCursor().position(), - wrapped, retCursor); - if (found) { - makeBlockVisible(document()->findBlock(retCursor.selectionStart())); - highlightIncrementalSearchedWord(retCursor); - } - - return found; -} - -// Use QTextEdit::find() instead of QTextDocument::find() because the later has -// bugs in searching backward. -bool VEdit::findTextHelper(const QString &p_text, uint p_options, - bool p_forward, int p_start, - bool &p_wrapped, QTextCursor &p_cursor) -{ - p_wrapped = false; - bool found = false; - - // Options - QTextDocument::FindFlags findFlags; - bool caseSensitive = false; - if (p_options & FindOption::CaseSensitive) { - findFlags |= QTextDocument::FindCaseSensitively; - caseSensitive = true; - } - - if (p_options & FindOption::WholeWordOnly) { - findFlags |= QTextDocument::FindWholeWords; - } - - if (!p_forward) { - findFlags |= QTextDocument::FindBackward; - } - - // Use regular expression - bool useRegExp = false; - QRegExp exp; - if (p_options & FindOption::RegularExpression) { - useRegExp = true; - exp = QRegExp(p_text, - caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - } - - // Store current state of the cursor. - QTextCursor cursor = textCursor(); - if (cursor.position() != p_start) { - if (p_start < 0) { - p_start = 0; - } else if (p_start > document()->characterCount()) { - p_start = document()->characterCount(); - } - - QTextCursor startCursor = cursor; - startCursor.setPosition(p_start); - setTextCursor(startCursor); - } - - while (!found) { - if (useRegExp) { - found = find(exp, findFlags); - } else { - found = find(p_text, findFlags); - } - - if (p_wrapped) { - break; - } - - if (!found) { - // Wrap to the other end of the document to search again. - p_wrapped = true; - QTextCursor wrapCursor = textCursor(); - if (p_forward) { - wrapCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - } else { - wrapCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); - } - - setTextCursor(wrapCursor); - } - } - - if (found) { - p_cursor = textCursor(); - } - - // Restore the original cursor. - setTextCursor(cursor); - - return found; -} - -QList VEdit::findTextAll(const QString &p_text, uint p_options) -{ - QList results; - if (p_text.isEmpty()) { - return results; - } - // Options - QTextDocument::FindFlags findFlags; - bool caseSensitive = false; - if (p_options & FindOption::CaseSensitive) { - findFlags |= QTextDocument::FindCaseSensitively; - caseSensitive = true; - } - if (p_options & FindOption::WholeWordOnly) { - findFlags |= QTextDocument::FindWholeWords; - } - // Use regular expression - bool useRegExp = false; - QRegExp exp; - if (p_options & FindOption::RegularExpression) { - useRegExp = true; - exp = QRegExp(p_text, - caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - } - int startPos = 0; - QTextCursor cursor; - QTextDocument *doc = document(); - while (true) { - if (useRegExp) { - cursor = doc->find(exp, startPos, findFlags); - } else { - cursor = doc->find(p_text, startPos, findFlags); - } - if (cursor.isNull()) { - break; - } else { - results.append(cursor); - startPos = cursor.selectionEnd(); - } - } - return results; -} - -bool VEdit::findText(const QString &p_text, uint p_options, bool p_forward, - QTextCursor *p_cursor, QTextCursor::MoveMode p_moveMode) -{ - clearIncrementalSearchedWordHighlight(); - - if (p_text.isEmpty()) { - clearSearchedWordHighlight(); - return false; - } - - QTextCursor cursor = textCursor(); - bool wrapped = false; - QTextCursor retCursor; - int matches = 0; - int start = p_forward ? cursor.position() + 1 : cursor.position(); - if (p_cursor) { - start = p_forward ? p_cursor->position() + 1 : p_cursor->position(); - } - - bool found = findTextHelper(p_text, p_options, p_forward, start, - wrapped, retCursor); - if (found) { - Q_ASSERT(!retCursor.isNull()); - if (wrapped) { - showWrapLabel(); - } - - if (p_cursor) { - p_cursor->setPosition(retCursor.selectionStart(), p_moveMode); - } else { - cursor.setPosition(retCursor.selectionStart(), p_moveMode); - setTextCursor(cursor); - } - - highlightSearchedWord(p_text, p_options); - highlightSearchedWordUnderCursor(retCursor); - matches = m_extraSelections[(int)SelectionId::SearchedKeyword].size(); - } else { - clearSearchedWordHighlight(); - } - - if (matches == 0) { - statusMessage(tr("Found no match")); - } else { - statusMessage(tr("Found %1 %2").arg(matches) - .arg(matches > 1 ? tr("matches") : tr("match"))); - } - - return found; -} - -void VEdit::replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) -{ - QTextCursor cursor = textCursor(); - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, p_options, true, - cursor.position(), wrapped, retCursor); - if (found) { - if (retCursor.selectionStart() == cursor.position()) { - // Matched. - retCursor.beginEditBlock(); - retCursor.insertText(p_replaceText); - retCursor.endEditBlock(); - setTextCursor(retCursor); - } - - if (p_findNext) { - findText(p_text, p_options, true); - } - } -} - -void VEdit::replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) -{ - // Replace from the start to the end and restore the cursor. - QTextCursor cursor = textCursor(); - int nrReplaces = 0; - QTextCursor tmpCursor = cursor; - tmpCursor.setPosition(0); - setTextCursor(tmpCursor); - int start = tmpCursor.position(); - while (true) { - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, p_options, true, - start, wrapped, retCursor); - if (!found) { - break; - } else { - if (wrapped) { - // Wrap back. - break; - } - - nrReplaces++; - retCursor.beginEditBlock(); - retCursor.insertText(p_replaceText); - retCursor.endEditBlock(); - setTextCursor(retCursor); - start = retCursor.position(); - } - } - - // Restore cursor position. - cursor.clearSelection(); - setTextCursor(cursor); - qDebug() << "replace all" << nrReplaces << "occurences"; - - emit statusMessage(tr("Replace %1 %2").arg(nrReplaces) - .arg(nrReplaces > 1 ? tr("occurences") - : tr("occurence"))); -} - -void VEdit::showWrapLabel() -{ - int labelW = m_wrapLabel->width(); - int labelH = m_wrapLabel->height(); - int x = (width() - labelW) / 2; - int y = (height() - labelH) / 2; - if (x < 0) { - x = 0; - } - if (y < 0) { - y = 0; - } - m_wrapLabel->move(x, y); - m_wrapLabel->show(); - m_labelTimer->stop(); - m_labelTimer->start(); -} - -void VEdit::labelTimerTimeout() -{ - m_wrapLabel->hide(); -} - -void VEdit::updateFontAndPalette() -{ - setFont(g_config->getBaseEditFont()); - setPalette(g_config->getBaseEditPalette()); -} - -void VEdit::highlightExtraSelections(bool p_now) -{ - m_highlightTimer->stop(); - if (p_now) { - doHighlightExtraSelections(); - } else { - m_highlightTimer->start(); - } -} - -void VEdit::doHighlightExtraSelections() -{ - int nrExtra = m_extraSelections.size(); - Q_ASSERT(nrExtra == (int)SelectionId::MaxSelection); - QList extraSelects; - for (int i = 0; i < nrExtra; ++i) { - extraSelects.append(m_extraSelections[i]); - } - - setExtraSelections(extraSelects); -} - -void VEdit::highlightCurrentLine() -{ - QList &selects = m_extraSelections[(int)SelectionId::CurrentLine]; - if (g_config->getHighlightCursorLine() && !isReadOnly()) { - // Need to highlight current line. - selects.clear(); - - // A long block maybe splited into multiple visual lines. - QTextEdit::ExtraSelection select; - select.format.setBackground(m_config.m_cursorLineBg); - select.format.setProperty(QTextFormat::FullWidthSelection, true); - - QTextCursor cursor = textCursor(); - if (m_config.m_highlightWholeBlock) { - cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor, 1); - QTextBlock block = cursor.block(); - int blockEnd = block.position() + block.length(); - int pos = -1; - while (cursor.position() < blockEnd && pos != cursor.position()) { - QTextEdit::ExtraSelection newSelect = select; - newSelect.cursor = cursor; - selects.append(newSelect); - - pos = cursor.position(); - cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 1); - } - } else { - cursor.clearSelection(); - select.cursor = cursor; - selects.append(select); - } - } else { - // Need to clear current line highlight. - if (selects.isEmpty()) { - return; - } - - selects.clear(); - } - - highlightExtraSelections(true); -} - -void VEdit::highlightSelectedWord() -{ - QList &selects = m_extraSelections[(int)SelectionId::SelectedWord]; - if (!g_config->getHighlightSelectedWord()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - QString text = textCursor().selectedText().trimmed(); - if (text.isEmpty() || wordInSearchedSelection(text)) { - selects.clear(); - highlightExtraSelections(true); - return; - } - - QTextCharFormat format; - format.setBackground(m_selectedWordColor); - highlightTextAll(text, FindOption::CaseSensitive, SelectionId::SelectedWord, - format); -} - -// Do not highlight trailing spaces with current cursor right behind. -static void trailingSpaceFilter(VEdit *p_editor, QList &p_result) -{ - QTextCursor cursor = p_editor->textCursor(); - if (!cursor.atBlockEnd()) { - return; - } - - int cursorPos = cursor.position(); - for (auto it = p_result.begin(); it != p_result.end(); ++it) { - if (it->cursor.selectionEnd() == cursorPos) { - p_result.erase(it); - - // There will be only one. - return; - } - } -} - -void VEdit::highlightTrailingSpace() -{ - if (!g_config->getEnableTrailingSpaceHighlight()) { - QList &selects = m_extraSelections[(int)SelectionId::TrailingSpace]; - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - return; - } - - QTextCharFormat format; - format.setBackground(m_trailingSpaceColor); - QString text("\\s+$"); - highlightTextAll(text, FindOption::RegularExpression, - SelectionId::TrailingSpace, format, - trailingSpaceFilter); -} - -bool VEdit::wordInSearchedSelection(const QString &p_text) -{ - QString text = p_text.trimmed(); - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - for (int i = 0; i < selects.size(); ++i) { - QString searchedWord = selects[i].cursor.selectedText(); - if (text == searchedWord.trimmed()) { - return true; - } - } - return false; -} - -void VEdit::highlightTextAll(const QString &p_text, uint p_options, - SelectionId p_id, QTextCharFormat p_format, - void (*p_filter)(VEdit *, QList &)) -{ - QList &selects = m_extraSelections[(int)p_id]; - if (!p_text.isEmpty()) { - selects.clear(); - - QList occurs = findTextAll(p_text, p_options); - for (int i = 0; i < occurs.size(); ++i) { - QTextEdit::ExtraSelection select; - select.format = p_format; - select.cursor = occurs[i]; - selects.append(select); - } - } else { - if (selects.isEmpty()) { - return; - } - selects.clear(); - } - - if (p_filter) { - p_filter(this, selects); - } - - highlightExtraSelections(); -} - -void VEdit::highlightSearchedWord(const QString &p_text, uint p_options) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - if (!g_config->getHighlightSearchedWord() || p_text.isEmpty()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - QTextCharFormat format; - format.setBackground(m_searchedWordColor); - highlightTextAll(p_text, p_options, SelectionId::SearchedKeyword, format); -} - -void VEdit::highlightSearchedWordUnderCursor(const QTextCursor &p_cursor) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeywordUnderCursor]; - if (!p_cursor.hasSelection()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - selects.clear(); - QTextEdit::ExtraSelection select; - select.format.setBackground(m_searchedWordCursorColor); - select.cursor = p_cursor; - selects.append(select); - - highlightExtraSelections(true); -} - -void VEdit::highlightIncrementalSearchedWord(const QTextCursor &p_cursor) -{ - QList &selects = m_extraSelections[(int)SelectionId::IncrementalSearchedKeyword]; - if (!g_config->getHighlightSearchedWord() || !p_cursor.hasSelection()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - selects.clear(); - QTextEdit::ExtraSelection select; - select.format.setBackground(m_incrementalSearchedWordColor); - select.cursor = p_cursor; - selects.append(select); - - highlightExtraSelections(true); -} - -void VEdit::clearSearchedWordHighlight() -{ - clearIncrementalSearchedWordHighlight(false); - clearSearchedWordUnderCursorHighlight(false); - - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(true); -} - -void VEdit::clearSearchedWordUnderCursorHighlight(bool p_now) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeywordUnderCursor]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(p_now); -} - -void VEdit::clearIncrementalSearchedWordHighlight(bool p_now) -{ - QList &selects = m_extraSelections[(int)SelectionId::IncrementalSearchedKeyword]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(p_now); -} - -void VEdit::contextMenuEvent(QContextMenuEvent *p_event) -{ - QMenu *menu = createStandardContextMenu(); - menu->setToolTipsVisible(true); - - const QList actions = menu->actions(); - - if (!textCursor().hasSelection()) { - VEditTab *editTab = dynamic_cast(parent()); - V_ASSERT(editTab); - if (editTab->isEditMode()) { - QAction *saveExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/save_exit.svg"), - tr("&Save Changes And Read"), this); - saveExitAct->setToolTip(tr("Save changes and exit edit mode")); - connect(saveExitAct, &QAction::triggered, - this, &VEdit::handleSaveExitAct); - - QAction *discardExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/discard_exit.svg"), - tr("&Discard Changes And Read"), this); - discardExitAct->setToolTip(tr("Discard changes and exit edit mode")); - connect(discardExitAct, &QAction::triggered, - this, &VEdit::handleDiscardExitAct); - - menu->insertAction(actions.isEmpty() ? NULL : actions[0], discardExitAct); - menu->insertAction(discardExitAct, saveExitAct); - if (!actions.isEmpty()) { - menu->insertSeparator(actions[0]); - } - } else if (m_file->isModifiable()) { - // HTML. - QAction *editAct= new QAction(VIconUtils::menuIcon(":/resources/icons/edit_note.svg"), - tr("&Edit"), this); - editAct->setToolTip(tr("Edit current note")); - connect(editAct, &QAction::triggered, - this, &VEdit::handleEditAct); - menu->insertAction(actions.isEmpty() ? NULL : actions[0], editAct); - // actions does not contain editAction. - if (!actions.isEmpty()) { - menu->insertSeparator(actions[0]); - } - } - } - - alterContextMenu(menu, actions); - - menu->exec(p_event->globalPos()); - delete menu; -} - -void VEdit::handleSaveExitAct() -{ - emit saveAndRead(); -} - -void VEdit::handleDiscardExitAct() -{ - emit discardAndRead(); -} - -void VEdit::handleEditAct() -{ - emit editNote(); -} - -VFile *VEdit::getFile() const -{ - return m_file; -} - -void VEdit::handleCursorPositionChanged() -{ - static QTextCursor lastCursor; - - QTextCursor cursor = textCursor(); - if (lastCursor.isNull() || cursor.blockNumber() != lastCursor.blockNumber()) { - highlightCurrentLine(); - highlightTrailingSpace(); - } else { - // Judge whether we have trailing space at current line. - QString text = cursor.block().text(); - if (text.rbegin()->isSpace()) { - highlightTrailingSpace(); - } - - // Handle word-wrap in one block. - // Highlight current line if in different visual line. - if ((lastCursor.positionInBlock() - lastCursor.columnNumber()) != - (cursor.positionInBlock() - cursor.columnNumber())) { - highlightCurrentLine(); - } - } - - lastCursor = cursor; -} - -VEditConfig &VEdit::getConfig() -{ - return m_config; -} - -void VEdit::mousePressEvent(QMouseEvent *p_event) -{ - if (p_event->button() == Qt::LeftButton - && p_event->modifiers() == Qt::ControlModifier - && !textCursor().hasSelection()) { - m_oriMouseX = p_event->x(); - m_oriMouseY = p_event->y(); - m_readyToScroll = true; - m_mouseMoveScrolled = false; - p_event->accept(); - return; - } - - m_readyToScroll = false; - m_mouseMoveScrolled = false; - - QTextEdit::mousePressEvent(p_event); - - emit selectionChangedByMouse(textCursor().hasSelection()); -} - -void VEdit::mouseReleaseEvent(QMouseEvent *p_event) -{ - if (m_mouseMoveScrolled || m_readyToScroll) { - viewport()->setCursor(Qt::IBeamCursor); - m_readyToScroll = false; - m_mouseMoveScrolled = false; - p_event->accept(); - return; - } - - m_readyToScroll = false; - m_mouseMoveScrolled = false; - - QTextEdit::mouseReleaseEvent(p_event); -} - -void VEdit::mouseMoveEvent(QMouseEvent *p_event) -{ - const int threshold = 5; - - if (m_readyToScroll) { - int deltaX = p_event->x() - m_oriMouseX; - int deltaY = p_event->y() - m_oriMouseY; - - if (qAbs(deltaX) >= threshold || qAbs(deltaY) >= threshold) { - m_oriMouseX = p_event->x(); - m_oriMouseY = p_event->y(); - - if (!m_mouseMoveScrolled) { - m_mouseMoveScrolled = true; - viewport()->setCursor(Qt::SizeAllCursor); - } - - QScrollBar *verBar = verticalScrollBar(); - QScrollBar *horBar = horizontalScrollBar(); - if (verBar->isVisible()) { - verBar->setValue(verBar->value() - deltaY); - } - - if (horBar->isVisible()) { - horBar->setValue(horBar->value() - deltaX); - } - } - - p_event->accept(); - return; - } - - QTextEdit::mouseMoveEvent(p_event); - - emit selectionChangedByMouse(textCursor().hasSelection()); -} - -void VEdit::requestUpdateVimStatus() -{ - if (m_editOps) { - m_editOps->requestUpdateVimStatus(); - } else { - emit vimStatusUpdated(NULL); - } -} - -bool VEdit::jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) -{ - Q_UNUSED(p_forward); - Q_UNUSED(p_relativeLevel); - Q_UNUSED(p_repeat); - return false; -} - -QVariant VEdit::inputMethodQuery(Qt::InputMethodQuery p_query) const -{ - if (p_query == Qt::ImEnabled) { - return m_enableInputMethod; - } - - return QTextEdit::inputMethodQuery(p_query); -} - -void VEdit::setInputMethodEnabled(bool p_enabled) -{ - if (m_enableInputMethod != p_enabled) { - m_enableInputMethod = p_enabled; - - QInputMethod *im = QGuiApplication::inputMethod(); - im->reset(); - // Ask input method to query current state, which will call inputMethodQuery(). - im->update(Qt::ImEnabled); - } -} - -void VEdit::decorateText(TextDecoration p_decoration) -{ - if (m_editOps) { - m_editOps->decorateText(p_decoration); - } -} - -void VEdit::updateLineNumberAreaMargin() -{ - int width = 0; - if (g_config->getEditorLineNumber()) { - width = m_lineNumberArea->calculateWidth(); - } - - setViewportMargins(width, 0, 0, 0); -} - -void VEdit::updateLineNumberArea() -{ - if (g_config->getEditorLineNumber()) { - if (!m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->show(); - } - - m_lineNumberArea->update(); - } else if (m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - } -} - -void VEdit::resizeEvent(QResizeEvent *p_event) -{ - QTextEdit::resizeEvent(p_event); - - if (g_config->getEditorLineNumber()) { - QRect rect = contentsRect(); - m_lineNumberArea->setGeometry(QRect(rect.left(), - rect.top(), - m_lineNumberArea->calculateWidth(), - rect.height())); - } -} - -void VEdit::lineNumberAreaPaintEvent(QPaintEvent *p_event) -{ - int lineNumberType = g_config->getEditorLineNumber(); - if (!lineNumberType) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - return; - } - - QPainter painter(m_lineNumberArea); - painter.fillRect(p_event->rect(), g_config->getEditorLineNumberBg()); - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - - QTextBlock block = firstVisibleBlock(); - if (!block.isValid()) { - return; - } - - int blockNumber = block.blockNumber(); - int offsetY = contentOffsetY(); - QRectF rect = layout->blockBoundingRect(block); - int top = offsetY + (int)rect.y(); - int bottom = top + (int)rect.height(); - int eventTop = p_event->rect().top(); - int eventBtm = p_event->rect().bottom(); - const int digitHeight = m_lineNumberArea->getDigitHeight(); - const int curBlockNumber = textCursor().block().blockNumber(); - const QString &fg = g_config->getEditorLineNumberFg(); - const int lineDistanceHeight = m_config.m_lineDistanceHeight; - painter.setPen(fg); - - // Display line number only in code block. - if (lineNumberType == 3) { - if (m_file->getDocType() != DocType::Markdown) { - return; - } - - int number = 0; - while (block.isValid() && top <= eventBtm) { - int blockState = block.userState(); - switch (blockState) { - case HighlightBlockState::CodeBlockStart: - Q_ASSERT(number == 0); - number = 1; - break; - - case HighlightBlockState::CodeBlockEnd: - number = 0; - break; - - case HighlightBlockState::CodeBlock: - if (number == 0) { - // Need to find current line number in code block. - QTextBlock startBlock = block.previous(); - while (startBlock.isValid()) { - if (startBlock.userState() == HighlightBlockState::CodeBlockStart) { - number = block.blockNumber() - startBlock.blockNumber(); - break; - } - - startBlock = startBlock.previous(); - } - } - - break; - - default: - break; - } - - if (blockState == HighlightBlockState::CodeBlock) { - if (block.isVisible() && bottom >= eventTop) { - QString numberStr = QString::number(number); - painter.drawText(0, - top + 2, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - } - - ++number; - } - - block = block.next(); - top = bottom; - bottom = top + (int)layout->blockBoundingRect(block).height() + lineDistanceHeight; - } - - return; - } - - // Handle lineNumberType 1 and 2. - Q_ASSERT(lineNumberType == 1 || lineNumberType == 2); - while (block.isValid() && top <= eventBtm) { - if (block.isVisible() && bottom >= eventTop) { - bool currentLine = false; - int number = blockNumber + 1; - if (lineNumberType == 2) { - number = blockNumber - curBlockNumber; - if (number == 0) { - currentLine = true; - number = blockNumber + 1; - } else if (number < 0) { - number = -number; - } - } else if (blockNumber == curBlockNumber) { - currentLine = true; - } - - QString numberStr = QString::number(number); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(true); - painter.setFont(font); - } - - painter.drawText(0, - top + 2, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(false); - painter.setFont(font); - } - } - - block = block.next(); - top = bottom; - bottom = top + (int)layout->blockBoundingRect(block).height() + lineDistanceHeight; - ++blockNumber; - } -} - -int VEdit::contentOffsetY() -{ - int offsety = 0; - QScrollBar *sb = verticalScrollBar(); - offsety = sb->value(); - return -offsety; -} - -QTextBlock VEdit::firstVisibleBlock() -{ - QTextDocument *doc = document(); - QAbstractTextDocumentLayout *layout = doc->documentLayout(); - int offsetY = contentOffsetY(); - - // Binary search. - int idx = -1; - int start = 0, end = doc->blockCount() - 1; - while (start <= end) { - int mid = start + (end - start) / 2; - QTextBlock block = doc->findBlockByNumber(mid); - if (!block.isValid()) { - break; - } - - int y = offsetY + (int)layout->blockBoundingRect(block).y(); - if (y == 0) { - return block; - } else if (y < 0) { - start = mid + 1; - } else { - if (idx == -1 || mid < idx) { - idx = mid; - } - - end = mid - 1; - } - } - - if (idx != -1) { - return doc->findBlockByNumber(idx); - } - - // Linear search. - qDebug() << "fall back to linear search for first visible block"; - QTextBlock block = doc->begin(); - while (block.isValid()) { - int y = offsetY + (int)layout->blockBoundingRect(block).y(); - if (y >= 0) { - return block; - } - - block = block.next(); - } - - return QTextBlock(); -} - -int LineNumberArea::calculateWidth() const -{ - int bc = m_document->blockCount(); - if (m_blockCount == bc) { - return m_width; - } - - const_cast(this)->m_blockCount = bc; - int digits = 1; - int max = qMax(1, m_blockCount); - while (max >= 10) { - max /= 10; - ++digits; - } - - int width = m_digitWidth * digits; - const_cast(this)->m_width = width; - - return m_width; -} - -void VEdit::makeBlockVisible(const QTextBlock &p_block) -{ - if (!p_block.isValid() || !p_block.isVisible()) { - return; - } - - QScrollBar *vbar = verticalScrollBar(); - if (!vbar || !vbar->isVisible()) { - // No vertical scrollbar. No need to scroll. - return; - } - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - int height = rect().height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && hbar->isVisible()) { - height -= hbar->height(); - } - - bool moved = false; - - QRectF rect = layout->blockBoundingRect(p_block); - int y = contentOffsetY() + (int)rect.y(); - int rectHeight = (int)rect.height(); - - // Handle the case rectHeight >= height. - if (rectHeight >= height) { - if (y <= 0) { - if (y + rectHeight < height) { - // Need to scroll up. - while (y + rectHeight < height && vbar->value() > vbar->minimum()) { - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = contentOffsetY() + (int)rect.y(); - } - } - } else { - // Need to scroll down. - while (y > 0 && vbar->value() < vbar->maximum()) { - moved = true; - vbar->setValue(vbar->value() + vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = contentOffsetY() + (int)rect.y(); - } - } - - if (moved) { - qDebug() << "scroll to make huge block visible"; - } - - return; - } - - while (y < 0 && vbar->value() > vbar->minimum()) { - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = contentOffsetY() + (int)rect.y(); - } - - if (moved) { - qDebug() << "scroll page down to make block visible"; - return; - } - - while (y + rectHeight > height && vbar->value() < vbar->maximum()) { - moved = true; - vbar->setValue(vbar->value() + vbar->singleStep()); - rect = layout->blockBoundingRect(p_block); - rectHeight = (int)rect.height(); - y = contentOffsetY() + (int)rect.y(); - } - - if (moved) { - qDebug() << "scroll page up to make block visible"; - } -} - -bool VEdit::isBlockVisible(const QTextBlock &p_block) -{ - if (!p_block.isValid() || !p_block.isVisible()) { - return false; - } - - QScrollBar *vbar = verticalScrollBar(); - if (!vbar || !vbar->isVisible()) { - // No vertical scrollbar. - return true; - } - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - int height = rect().height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && hbar->isVisible()) { - height -= hbar->height(); - } - - QRectF rect = layout->blockBoundingRect(p_block); - int y = contentOffsetY() + (int)rect.y(); - int rectHeight = (int)rect.height(); - - return (y >= 0 && y < height) || (y < 0 && y + rectHeight > 0); -} - -void VEdit::alterContextMenu(QMenu *p_menu, const QList &p_actions) -{ - Q_UNUSED(p_menu); - Q_UNUSED(p_actions); -} - -void VEdit::updateBlockLineDistanceHeight(int p_pos, - int p_charsRemoved, - int p_charsAdded) -{ - if ((p_charsRemoved == 0 && p_charsAdded == 0) - || m_config.m_lineDistanceHeight <= 0) { - return; - } - - QTextDocument *doc = document(); - QTextBlock block = doc->findBlock(p_pos); - QTextBlock lastBlock = doc->findBlock(p_pos + p_charsRemoved + p_charsAdded); - QTextCursor cursor(block); - bool changed = false; - while (block.isValid()) { - cursor.setPosition(block.position()); - QTextBlockFormat fmt = cursor.blockFormat(); - if (fmt.lineHeightType() != QTextBlockFormat::LineDistanceHeight - || fmt.lineHeight() != m_config.m_lineDistanceHeight) { - fmt.setLineHeight(m_config.m_lineDistanceHeight, - QTextBlockFormat::LineDistanceHeight); - if (!changed) { - changed = true; - cursor.joinPreviousEditBlock(); - } - - cursor.mergeBlockFormat(fmt); - qDebug() << "merge block format line distance" << block.blockNumber(); - } - - if (block == lastBlock) { - break; - } - - block = block.next(); - } - - if (changed) { - cursor.endEditBlock(); - } -} - -void VEdit::evaluateMagicWords() -{ - QString text; - QTextCursor cursor = textCursor(); - if (!cursor.hasSelection()) { - // Get the WORD in current cursor. - int start, end; - VEditUtils::findCurrentWORD(cursor, start, end); - - if (start == end) { - return; - } else { - cursor.setPosition(start); - cursor.setPosition(end, QTextCursor::KeepAnchor); - } - } - - text = VEditUtils::selectedText(cursor); - Q_ASSERT(!text.isEmpty()); - QString evaText = g_mwMgr->evaluate(text); - if (text != evaText) { - qDebug() << "evaluateMagicWords" << text << evaText; - - cursor.insertText(evaText); - - if (m_editOps) { - m_editOps->setVimMode(VimMode::Insert); - } - - setTextCursor(cursor); - } -} - -void VEdit::setReadOnlyAndHighlight(bool p_readonly) -{ - setReadOnly(p_readonly); - highlightCurrentLine(); -} diff --git a/src/vedit.h b/src/vedit.h deleted file mode 100644 index 10d52c78..00000000 --- a/src/vedit.h +++ /dev/null @@ -1,295 +0,0 @@ -#ifndef VEDIT_H -#define VEDIT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "vconstants.h" -#include "vnotefile.h" -#include "veditconfig.h" -#include "veditor.h" - -class VEditOperations; -class QLabel; -class QTimer; -class VVim; -class QPaintEvent; -class QResizeEvent; -class QSize; -class QWidget; - -class LineNumberArea; - -class VEdit : public QTextEdit -{ - Q_OBJECT -public: - VEdit(VFile *p_file, QWidget *p_parent = 0); - virtual ~VEdit(); - virtual void beginEdit(); - virtual void endEdit(); - // Save buffer content to VFile. - virtual void saveFile(); - virtual void setModified(bool p_modified); - bool isModified() const; - virtual void reloadFile(); - - virtual bool scrollToBlock(int p_blockNumber); - - // User requests to insert an image. - virtual void insertImage(); - - // User requests to insert a link. - virtual void insertLink(); - - // Used for incremental search. - // User has enter the content to search, but does not enter the "find" button yet. - bool peekText(const QString &p_text, uint p_options, bool p_forward = true); - - // If @p_cursor is not null, set the position of @p_cursor instead of current - // cursor. - bool findText(const QString &p_text, uint p_options, bool p_forward, - QTextCursor *p_cursor = NULL, - QTextCursor::MoveMode p_moveMode = QTextCursor::MoveAnchor); - - void replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext); - void replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText); - - // Clear SearchedKeyword highlight. - void clearSearchedWordHighlight(); - - // Clear SearchedKeywordUnderCursor Highlight. - void clearSearchedWordUnderCursorHighlight(bool p_now = true); - - // Clear IncrementalSearchedKeyword highlight. - void clearIncrementalSearchedWordHighlight(bool p_now = true); - - VFile *getFile() const; - - VEditConfig &getConfig(); - - // Request to update Vim status. - void requestUpdateVimStatus(); - - QVariant inputMethodQuery(Qt::InputMethodQuery p_query) const Q_DECL_OVERRIDE; - - void setInputMethodEnabled(bool p_enabled); - - // Insert decoration markers or decorate selected text. - void decorateText(TextDecoration p_decoration); - - // LineNumberArea will call this to request paint itself. - void lineNumberAreaPaintEvent(QPaintEvent *p_event); - - // Scroll the content to make @p_block visible. - // If the @p_block is too long to hold in one page, just let it occupy the - // whole page. - // Will not change current cursor. - void makeBlockVisible(const QTextBlock &p_block); - - bool isBlockVisible(const QTextBlock &p_block); - - // Evaluate selected text or cursor word as magic words. - void evaluateMagicWords(); - -signals: - // Request VEditTab to save and exit edit mode. - void saveAndRead(); - - // Request VEditTab to discard and exit edit mode. - void discardAndRead(); - - // Request VEditTab to edit current note. - void editNote(); - - // Request VEditTab to save this file. - void saveNote(); - - // Emit when m_config has been updated. - void configUpdated(); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - // Emit when Vim status updated. - void vimStatusUpdated(const VVim *p_vim); - - // Selection changed by mouse. - void selectionChangedByMouse(bool p_hasSelection); - - // Request the edit tab to close find and replace dialog. - void requestCloseFindReplaceDialog(); - - // Emit when all initialization is ready. - void ready(); - -public slots: - virtual void highlightCurrentLine(); - - // Jump to a title. - // @p_forward: jump forward or backward. - // @p_relativeLevel: 0 for the same level as current header; - // negative value for upper level; - // positive value is ignored. - // Returns true if the jump succeeded. - virtual bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat); - -private slots: - void labelTimerTimeout(); - void highlightSelectedWord(); - void handleSaveExitAct(); - void handleDiscardExitAct(); - void handleEditAct(); - void highlightTrailingSpace(); - void handleCursorPositionChanged(); - - // Update viewport margin to hold the line number area. - void updateLineNumberAreaMargin(); - - void updateLineNumberArea(); - - // According to the document change, try to set the block line distance height - // if affected blocks are not set. - void updateBlockLineDistanceHeight(int p_pos, int p_charsRemoved, int p_charsAdded); - -protected: - QPointer m_file; - VEditOperations *m_editOps; - - VEditConfig m_config; - - virtual void updateFontAndPalette(); - virtual void contextMenuEvent(QContextMenuEvent *p_event) Q_DECL_OVERRIDE; - - // Used to implement dragging mouse with Ctrl and left button pressed to scroll. - virtual void mousePressEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - virtual void mouseReleaseEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - virtual void mouseMoveEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - virtual void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - - // Update m_config according to VConfigManager. - void updateConfig(); - - // Called in contextMenuEvent() to modify the context menu. - virtual void alterContextMenu(QMenu *p_menu, const QList &p_actions); - - // Set read-only property and highlight current line. - void setReadOnlyAndHighlight(bool p_readonly); - -private: - QLabel *m_wrapLabel; - QTimer *m_labelTimer; - - // doHighlightExtraSelections() will highlight these selections. - // Selections are indexed by SelectionId. - QVector > m_extraSelections; - - QColor m_selectedWordColor; - QColor m_searchedWordColor; - QColor m_searchedWordCursorColor; - QColor m_incrementalSearchedWordColor; - QColor m_trailingSpaceColor; - - // Timer for extra selections highlight. - QTimer *m_highlightTimer; - - bool m_readyToScroll; - bool m_mouseMoveScrolled; - int m_oriMouseX; - int m_oriMouseY; - - // Whether enable input method. - bool m_enableInputMethod; - - LineNumberArea *m_lineNumberArea; - - void showWrapLabel(); - - // Trigger the timer to request highlight. - // If @p_now is true, stop the timer and highlight immediately. - void highlightExtraSelections(bool p_now = false); - - // Do the real work to highlight extra selections. - void doHighlightExtraSelections(); - - // Find all the occurences of @p_text. - QList findTextAll(const QString &p_text, uint p_options); - - // @p_fileter: a function to filter out highlight results. - void highlightTextAll(const QString &p_text, uint p_options, - SelectionId p_id, QTextCharFormat p_format, - void (*p_filter)(VEdit *, QList &) = NULL); - - void highlightSearchedWord(const QString &p_text, uint p_options); - - // Highlight @p_cursor as the searched keyword under cursor. - void highlightSearchedWordUnderCursor(const QTextCursor &p_cursor); - - // Highlight @p_cursor as the incremental searched keyword. - void highlightIncrementalSearchedWord(const QTextCursor &p_cursor); - - bool wordInSearchedSelection(const QString &p_text); - - // Return the first visible block. - QTextBlock firstVisibleBlock(); - - // Return the y offset of the content. - int contentOffsetY(); - - // Find @p_text in the document starting from @p_start. - // Returns true if @p_text is found and set @p_cursor to indicate - // the position. - // Will NOT change current cursor. - bool findTextHelper(const QString &p_text, uint p_options, - bool p_forward, int p_start, - bool &p_wrapped, QTextCursor &p_cursor); -}; - -class LineNumberArea : public QWidget -{ -public: - LineNumberArea(VEdit *p_editor) - : QWidget(p_editor), m_editor(p_editor), - m_document(p_editor->document()), - m_width(0), m_blockCount(-1) - { - m_digitWidth = m_editor->fontMetrics().width(QLatin1Char('1')); - m_digitHeight = m_editor->fontMetrics().height(); - } - - QSize sizeHint() const Q_DECL_OVERRIDE - { - return QSize(calculateWidth(), 0); - } - - int calculateWidth() const; - - int getDigitHeight() const - { - return m_digitHeight; - } - -protected: - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE - { - m_editor->lineNumberAreaPaintEvent(p_event); - } - -private: - VEdit *m_editor; - const QTextDocument *m_document; - int m_width; - int m_blockCount; - int m_digitWidth; - int m_digitHeight; -}; - -#endif // VEDIT_H diff --git a/src/veditarea.cpp b/src/veditarea.cpp deleted file mode 100644 index 9ad1864e..00000000 --- a/src/veditarea.cpp +++ /dev/null @@ -1,1324 +0,0 @@ -#include "veditarea.h" - -#include - -#include "veditwindow.h" -#include "vedittab.h" -#include "vnote.h" -#include "vconfigmanager.h" -#include "vfile.h" -#include "dialog/vfindreplacedialog.h" -#include "utils/vutils.h" -#include "vfilesessioninfo.h" -#include "vmainwindow.h" -#include "vcaptain.h" -#include "vfilelist.h" -#include "vmathjaxpreviewhelper.h" -#include "vmdtab.h" -#include "vmdeditor.h" - -extern VConfigManager *g_config; - -extern VNote *g_vnote; - -extern VMainWindow *g_mainWin; - -VEditArea::VEditArea(QWidget *parent) - : QWidget(parent), - VNavigationMode(), - curWindowIndex(-1) -{ - setupUI(); - - insertSplitWindow(0); - setCurrentWindow(0, false); - - registerCaptainTargets(); - - initShortcuts(); - - QTimer *timer = new QTimer(this); - timer->setSingleShot(false); - timer->setInterval(g_config->getFileTimerInterval()); - connect(timer, &QTimer::timeout, - this, &VEditArea::handleFileTimerTimeout); - - timer->start(); - - m_autoSave = g_config->getEnableAutoSave(); - - m_mathPreviewHelper = new VMathJaxPreviewHelper(this, this); -} - -void VEditArea::setupUI() -{ - splitter = new QSplitter(this); - m_findReplace = new VFindReplaceDialog(this); - m_findReplace->setOption(FindOption::CaseSensitive, - g_config->getFindCaseSensitive()); - m_findReplace->setOption(FindOption::WholeWordOnly, - g_config->getFindWholeWordOnly()); - m_findReplace->setOption(FindOption::RegularExpression, - g_config->getFindRegularExpression()); - m_findReplace->setOption(FindOption::IncrementalSearch, - g_config->getFindIncrementalSearch()); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(splitter); - mainLayout->addWidget(m_findReplace); - mainLayout->setContentsMargins(0, 0, 0, 0); - mainLayout->setSpacing(0); - mainLayout->setStretch(0, 1); - mainLayout->setStretch(1, 0); - - setLayout(mainLayout); - - connect(m_findReplace, &VFindReplaceDialog::findTextChanged, - this, &VEditArea::handleFindTextChanged); - connect(m_findReplace, &VFindReplaceDialog::findOptionChanged, - this, &VEditArea::handleFindOptionChanged); - connect(m_findReplace, SIGNAL(findNext(const QString &, uint, bool)), - this, SLOT(handleFindNext(const QString &, uint, bool))); - connect(m_findReplace, - SIGNAL(replace(const QString &, uint, const QString &, bool)), - this, - SLOT(handleReplace(const QString &, uint, const QString &, bool))); - connect(m_findReplace, - SIGNAL(replaceAll(const QString &, uint, const QString &)), - this, - SLOT(handleReplaceAll(const QString &, uint, const QString &))); - connect(m_findReplace, &VFindReplaceDialog::dialogClosed, - this, &VEditArea::handleFindDialogClosed); - m_findReplace->hide(); - - // Shortcut Ctrl+Shift+T to open last closed file. - QString keySeq = g_config->getShortcutKeySequence("LastClosedFile"); - qDebug() << "set LastClosedFile shortcut to" << keySeq; - QShortcut *lastClosedFileShortcut = new QShortcut(QKeySequence(keySeq), this); - lastClosedFileShortcut->setContext(Qt::ApplicationShortcut); - connect(lastClosedFileShortcut, &QShortcut::activated, - this, [this]() { - if (!m_lastClosedFiles.isEmpty()) { - const VFileSessionInfo &file = m_lastClosedFiles.top(); - QVector files(1, file); - m_lastClosedFiles.pop(); - - openFiles(files); - } - }); -} - -void VEditArea::initShortcuts() -{ - QString keySeq = g_config->getShortcutKeySequence("ActivateNextTab"); - qDebug() << "set ActivateNextTab shortcut to" << keySeq; - QShortcut *activateNextTab = new QShortcut(QKeySequence(keySeq), this); - activateNextTab->setContext(Qt::ApplicationShortcut); - connect(activateNextTab, &QShortcut::activated, - this, [this]() { - VEditWindow *win = getCurrentWindow(); - if (win) { - win->focusNextTab(true); - } - }); - - keySeq = g_config->getShortcutKeySequence("ActivatePreviousTab"); - qDebug() << "set ActivatePreviousTab shortcut to" << keySeq; - QShortcut *activatePreviousTab = new QShortcut(QKeySequence(keySeq), this); - activatePreviousTab->setContext(Qt::ApplicationShortcut); - connect(activatePreviousTab, &QShortcut::activated, - this, [this]() { - VEditWindow *win = getCurrentWindow(); - if (win) { - win->focusNextTab(false); - } - }); - - keySeq = g_config->getShortcutKeySequence("NextMatch"); - qDebug() << "set NextMatch shortcut to" << keySeq; - QShortcut *nextMatchSC = new QShortcut(QKeySequence(keySeq), this); - connect(nextMatchSC, &QShortcut::activated, - this, [this]() { - nextMatch(true); - }); - - keySeq = g_config->getShortcutKeySequence("PreviousMatch"); - qDebug() << "set PreviousMatch shortcut to" << keySeq; - QShortcut *previousMatchSC = new QShortcut(QKeySequence(keySeq), this); - connect(previousMatchSC, &QShortcut::activated, - this, [this]() { - nextMatch(false); - }); -} - -void VEditArea::insertSplitWindow(int idx) -{ - VEditWindow *win = new VEditWindow(this); - splitter->insertWidget(idx, win); - connect(win, &VEditWindow::tabStatusUpdated, - this, &VEditArea::handleWindowTabStatusUpdated); - connect(win, &VEditWindow::requestSplitWindow, - this, &VEditArea::splitWindow); - connect(win, &VEditWindow::requestRemoveSplit, - this, &VEditArea::handleRemoveSplitRequest); - connect(win, &VEditWindow::getFocused, - this, &VEditArea::handleWindowFocused); - connect(win, &VEditWindow::outlineChanged, - this, &VEditArea::handleWindowOutlineChanged); - connect(win, &VEditWindow::currentHeaderChanged, - this, &VEditArea::handleWindowCurrentHeaderChanged); - connect(win, &VEditWindow::statusMessage, - this, &VEditArea::handleWindowStatusMessage); - connect(win, &VEditWindow::vimStatusUpdated, - this, &VEditArea::handleWindowVimStatusUpdated); -} - -void VEditArea::handleWindowTabStatusUpdated(const VEditTabInfo &p_info) -{ - if (splitter->widget(curWindowIndex) == sender()) { - emit tabStatusUpdated(p_info); - } -} - -void VEditArea::handleWindowStatusMessage(const QString &p_msg) -{ - if (splitter->widget(curWindowIndex) == sender()) { - emit statusMessage(p_msg); - } -} - -void VEditArea::handleWindowVimStatusUpdated(const VVim *p_vim) -{ - if (splitter->widget(curWindowIndex) == sender()) { - emit vimStatusUpdated(p_vim); - } -} - -void VEditArea::removeSplitWindow(VEditWindow *win) -{ - if (!win) { - return; - } - - win->hide(); - win->setParent(this); - disconnect(win, 0, this, 0); - // Should be deleted later - win->deleteLater(); -} - -VEditTab *VEditArea::openFile(VFile *p_file, OpenFileMode p_mode, bool p_forceMode) -{ - if (!p_file) { - return NULL; - } - - // Update auto save settings. - m_autoSave = g_config->getEnableAutoSave(); - - // If it is DocType::Unknown, open it using system default method. - if (p_file->getDocType() == DocType::Unknown) { - QUrl url = QUrl::fromLocalFile(p_file->fetchPath()); - QDesktopServices::openUrl(url); - return NULL; - } - - // Find if it has been opened already - int winIdx, tabIdx; - bool existFile = false; - bool setFocus = false; - auto tabs = findTabsByFile(p_file); - if (!tabs.empty()) { - // Current window first - winIdx = tabs[0].first; - tabIdx = tabs[0].second; - for (int i = 0; i < tabs.size(); ++i) { - if (tabs[i].first == curWindowIndex) { - winIdx = tabs[i].first; - tabIdx = tabs[i].second; - break; - } - } - - setFocus = true; - existFile = true; - goto out; - } - - // Open it in current window - if (curWindowIndex == -1) { - // insert a new split - insertSplitWindow(0); - curWindowIndex = 0; - } - - winIdx = curWindowIndex; - tabIdx = openFileInWindow(winIdx, p_file, p_mode); - -out: - VEditTab *tab = getTab(winIdx, tabIdx); - - setCurrentTab(winIdx, tabIdx, setFocus); - - if (existFile && p_forceMode) { - if (p_mode == OpenFileMode::Read) { - readFile(); - } else if (p_mode == OpenFileMode::Edit) { - editFile(); - } - } - - return tab; -} - -QVector > VEditArea::findTabsByFile(const VFile *p_file) -{ - QVector > tabs; - int nrWin = splitter->count(); - for (int winIdx = 0; winIdx < nrWin; ++winIdx) { - VEditWindow *win = getWindow(winIdx); - int tabIdx = win->findTabByFile(p_file); - if (tabIdx != -1) { - QPair match; - match.first = winIdx; - match.second = tabIdx; - tabs.append(match); - } - } - return tabs; -} - -int VEditArea::openFileInWindow(int windowIndex, VFile *p_file, OpenFileMode p_mode) -{ - Q_ASSERT(windowIndex < splitter->count()); - VEditWindow *win = getWindow(windowIndex); - return win->openFile(p_file, p_mode); -} - -void VEditArea::setCurrentTab(int windowIndex, int tabIndex, bool setFocus) -{ - VEditWindow *win = getWindow(windowIndex); - win->setCurrentIndex(tabIndex); - - setCurrentWindow(windowIndex, setFocus); -} - -void VEditArea::setCurrentWindow(int windowIndex, bool setFocus) -{ - int nrWin = splitter->count(); - curWindowIndex = windowIndex; - - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->setCurrentWindow(false); - } - if (curWindowIndex > -1) { - getWindow(curWindowIndex)->setCurrentWindow(true); - if (setFocus) { - getWindow(curWindowIndex)->focusWindow(); - } - } - // Update status - updateWindowStatus(); -} - -void VEditArea::updateWindowStatus() -{ - if (curWindowIndex == -1) { - Q_ASSERT(splitter->count() == 0); - - emit tabStatusUpdated(VEditTabInfo()); - emit outlineChanged(VTableOfContent()); - emit currentHeaderChanged(VHeaderPointer()); - return; - } - - VEditWindow *win = getWindow(curWindowIndex); - win->updateTabStatus(); -} - -bool VEditArea::closeFile(const VFile *p_file, bool p_forced) -{ - if (!p_file) { - return true; - } - bool ret = false; - int i = 0; - while (i < splitter->count()) { - VEditWindow *win = getWindow(i); - int nrWin = splitter->count(); - ret = ret || win->closeFile(p_file, p_forced); - if (nrWin == splitter->count()) { - ++i; - } - } - updateWindowStatus(); - return ret; -} - -bool VEditArea::closeFile(const VDirectory *p_dir, bool p_forced) -{ - if (!p_dir) { - return true; - } - int i = 0; - while (i < splitter->count()) { - VEditWindow *win = getWindow(i); - if (!p_forced) { - setCurrentWindow(i, false); - } - int nrWin = splitter->count(); - if (!win->closeFile(p_dir, p_forced)) { - return false; - } - // win may be removed after closeFile() - if (nrWin == splitter->count()) { - ++i; - } - } - updateWindowStatus(); - return true; -} - -bool VEditArea::closeFile(const VNotebook *p_notebook, bool p_forced) -{ - if (!p_notebook) { - return true; - } - int i = 0; - while (i < splitter->count()) { - VEditWindow *win = getWindow(i); - if (!p_forced) { - setCurrentWindow(i, false); - } - int nrWin = splitter->count(); - if (!win->closeFile(p_notebook, p_forced)) { - return false; - } - // win may be removed after closeFile() - if (nrWin == splitter->count()) { - ++i; - } - } - updateWindowStatus(); - return true; -} - -bool VEditArea::closeAllFiles(bool p_forced) -{ - int i = 0; - while (i < splitter->count()) { - VEditWindow *win = getWindow(i); - if (!p_forced) { - setCurrentWindow(i, false); - } - int nrWin = splitter->count(); - if (!win->closeAllFiles(p_forced)) { - return false; - } - if (nrWin == splitter->count()) { - ++i; - } - } - updateWindowStatus(); - return true; -} - -void VEditArea::editFile() -{ - VEditWindow *win = getWindow(curWindowIndex); - win->editFile(); -} - -void VEditArea::saveFile() -{ - VEditWindow *win = getWindow(curWindowIndex); - win->saveFile(); -} - -void VEditArea::readFile(bool p_discard) -{ - VEditWindow *win = getWindow(curWindowIndex); - win->readFile(p_discard); -} - -void VEditArea::saveAndReadFile() -{ - VEditWindow *win = getWindow(curWindowIndex); - win->saveAndReadFile(); -} - -void VEditArea::splitWindow(VEditWindow *p_window, bool p_right) -{ - if (!p_window) { - return; - } - - int idx = splitter->indexOf(p_window); - Q_ASSERT(idx > -1); - if (p_right) { - ++idx; - } else { - --idx; - if (idx < 0) { - idx = 0; - } - } - - insertSplitWindow(idx); - setCurrentWindow(idx, true); - - distributeSplits(); -} - -void VEditArea::splitCurrentWindow() -{ - if (curWindowIndex > -1) { - splitWindow(getWindow(curWindowIndex)); - } -} - -void VEditArea::handleRemoveSplitRequest(VEditWindow *curWindow) -{ - if (!curWindow || splitter->count() <= 1) { - return; - } - int idx = splitter->indexOf(curWindow); - - // curWindow will be deleted later - removeSplitWindow(curWindow); - - if (idx >= splitter->count()) { - idx = splitter->count() - 1; - } - setCurrentWindow(idx, true); -} - -void VEditArea::removeCurrentWindow() -{ - if (curWindowIndex > -1) { - handleRemoveSplitRequest(getWindow(curWindowIndex)); - } -} - -void VEditArea::mousePressEvent(QMouseEvent *event) -{ - QPoint pos = event->pos(); - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - VEditWindow *win = getWindow(i); - if (win->geometry().contains(pos, true)) { - setCurrentWindow(i, true); - break; - } - } - QWidget::mousePressEvent(event); -} - -void VEditArea::handleWindowFocused() -{ - QObject *winObject = sender(); - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - if (splitter->widget(i) == winObject) { - setCurrentWindow(i, false); - break; - } - } -} - -void VEditArea::handleWindowOutlineChanged(const VTableOfContent &p_outline) -{ - QObject *winObject = sender(); - if (splitter->widget(curWindowIndex) == winObject) { - emit outlineChanged(p_outline); - } -} - -void VEditArea::handleWindowCurrentHeaderChanged(const VHeaderPointer &p_header) -{ - QObject *winObject = sender(); - if (splitter->widget(curWindowIndex) == winObject) { - emit currentHeaderChanged(p_header); - } -} - -void VEditArea::scrollToHeader(const VHeaderPointer &p_header) -{ - VEditWindow *win = getCurrentWindow(); - if (win) { - win->scrollToHeader(p_header); - } -} - -bool VEditArea::isFileOpened(const VFile *p_file) -{ - return !findTabsByFile(p_file).isEmpty(); -} - -void VEditArea::handleFileUpdated(const VFile *p_file, UpdateAction p_act) -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->updateFileInfo(p_file, p_act); - } -} - -void VEditArea::handleDirectoryUpdated(const VDirectory *p_dir, UpdateAction p_act) -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->updateDirectoryInfo(p_dir, p_act); - } -} - -void VEditArea::handleNotebookUpdated(const VNotebook *p_notebook) -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->updateNotebookInfo(p_notebook); - } -} - -VEditTab *VEditArea::getCurrentTab() const -{ - if (curWindowIndex == -1) { - return NULL; - } - - VEditWindow *win = getWindow(curWindowIndex); - return win->getCurrentTab(); -} - -VEditTab *VEditArea::getTab(int p_winIdx, int p_tabIdx) const -{ - VEditWindow *win = getWindow(p_winIdx); - if (!win) { - return NULL; - } - - return win->getTab(p_tabIdx); -} - -VEditTab *VEditArea::getTab(const VFile *p_file) const -{ - int nrWin = splitter->count(); - for (int winIdx = 0; winIdx < nrWin; ++winIdx) { - VEditWindow *win = getWindow(winIdx); - int tabIdx = win->findTabByFile(p_file); - if (tabIdx != -1) { - return win->getTab(tabIdx); - } - } - - return NULL; -} - -QVector VEditArea::getAllTabsInfo() const -{ - QVector tabs; - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - tabs.append(getWindow(i)->getAllTabsInfo()); - } - - return tabs; -} - -QVector VEditArea::getAllTabs() const -{ - QVector tabs; - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - tabs.append(getWindow(i)->getAllTabs()); - } - - return tabs; -} - -int VEditArea::windowIndex(const VEditWindow *p_window) const -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - if (p_window == getWindow(i)) { - return i; - } - } - return -1; -} - -void VEditArea::moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx) -{ - int nrWin = splitter->count(); - if (!p_widget || p_fromIdx < 0 || p_fromIdx >= nrWin - || p_toIdx < 0 || p_toIdx >= nrWin) { - return; - } - qDebug() << "move widget" << p_widget << "from" << p_fromIdx << "to" << p_toIdx; - if (!getWindow(p_toIdx)->addEditTab(p_widget)) { - delete p_widget; - } -} - -// Only propogate the search in the IncrementalSearch case. -void VEditArea::handleFindTextChanged(const QString &p_text, uint p_options) -{ - VEditTab *tab = getCurrentTab(); - if (tab) { - if (p_options & FindOption::IncrementalSearch) { - tab->findText(p_text, p_options, true); - } - } -} - -void VEditArea::handleFindOptionChanged(uint p_options) -{ - qDebug() << "find option changed" << p_options; - g_config->setFindCaseSensitive(p_options & FindOption::CaseSensitive); - g_config->setFindWholeWordOnly(p_options & FindOption::WholeWordOnly); - g_config->setFindRegularExpression(p_options & FindOption::RegularExpression); - g_config->setFindIncrementalSearch(p_options & FindOption::IncrementalSearch); -} - -void VEditArea::handleFindNext(const QString &p_text, uint p_options, - bool p_forward) -{ - qDebug() << "find next" << p_text << p_options << p_forward; - VEditTab *tab = getCurrentTab(); - if (tab) { - tab->findText(p_text, p_options, false, p_forward); - } -} - -void VEditArea::handleReplace(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) -{ - qDebug() << "replace" << p_text << p_options << "with" << p_replaceText - << p_findNext; - VEditTab *tab = getCurrentTab(); - if (tab) { - tab->replaceText(p_text, p_options, p_replaceText, p_findNext); - } -} - -void VEditArea::handleReplaceAll(const QString &p_text, uint p_options, - const QString &p_replaceText) -{ - qDebug() << "replace all" << p_text << p_options << "with" << p_replaceText; - VEditTab *tab = getCurrentTab(); - if (tab) { - tab->replaceTextAll(p_text, p_options, p_replaceText); - } -} - -// Let VEditArea get focus after VFindReplaceDialog is closed. -void VEditArea::handleFindDialogClosed() -{ - if (curWindowIndex == -1) { - setFocus(); - } else { - getWindow(curWindowIndex)->focusWindow(); - } - - // Clear all the search highlight. - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - getWindow(i)->clearSearchedWordHighlight(); - } -} - -QString VEditArea::getSelectedText() -{ - VEditTab *tab = getCurrentTab(); - if (tab) { - return tab->getSelectedText(); - } else { - return QString(); - } -} - -int VEditArea::focusNextWindow(int p_biaIdx) -{ - if (p_biaIdx == 0) { - return curWindowIndex; - } - int newIdx = curWindowIndex + p_biaIdx; - if (newIdx < 0) { - newIdx = 0; - } else if (newIdx >= splitter->count()) { - newIdx = splitter->count() - 1; - } - if (newIdx >= 0 && newIdx < splitter->count()) { - setCurrentWindow(newIdx, true); - } else { - newIdx = -1; - } - return newIdx; -} - -void VEditArea::moveCurrentTabOneSplit(bool p_right) -{ - getWindow(curWindowIndex)->moveCurrentTabOneSplit(p_right); -} - -VEditWindow *VEditArea::getCurrentWindow() const -{ - if (curWindowIndex < 0) { - return NULL; - } - - return getWindow(curWindowIndex); -} - -void VEditArea::registerNavigation(QChar p_majorKey) -{ - m_majorKey = p_majorKey; - V_ASSERT(m_keyMap.empty()); - V_ASSERT(m_naviLabels.empty()); -} - -void VEditArea::showNavigation() -{ - // Clean up. - m_keyMap.clear(); - for (auto label : m_naviLabels) { - delete label; - } - - m_naviLabels.clear(); - - if (!isVisible()) { - return; - } - - // Generate labels for VEDitTab. - int charIdx = 0; - for (int i = 0; charIdx < 26 && i < splitter->count(); ++i) { - VEditWindow *win = getWindow(i); - QVector tabInfos = win->getTabsNavigationInfo(); - for (int j = 0; charIdx < 26 && j < tabInfos.size(); ++j, ++charIdx) { - QChar key('a' + charIdx); - m_keyMap[key] = tabInfos[j].m_tab; - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, win); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str)); - label->show(); - label->move(tabInfos[j].m_topLeft); - m_naviLabels.append(label); - } - } -} - -void VEditArea::hideNavigation() -{ - m_keyMap.clear(); - for (auto label : m_naviLabels) { - delete label; - } - - m_naviLabels.clear(); -} - -bool VEditArea::handleKeyNavigation(int p_key, bool &p_succeed) -{ - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (m_isSecondKey && !keyChar.isNull()) { - m_isSecondKey = false; - p_succeed = true; - auto it = m_keyMap.find(keyChar); - if (it != m_keyMap.end()) { - ret = true; - static_cast(it.value())->focusTab(); - } - } else if (keyChar == m_majorKey) { - // Major key pressed. - // Need second key if m_keyMap is not empty. - if (m_keyMap.isEmpty()) { - p_succeed = true; - } else { - m_isSecondKey = true; - } - ret = true; - } - - return ret; -} - -int VEditArea::openFiles(const QVector &p_files, bool p_oneByOne) -{ - VFile *curFile = NULL; - int nrOpened = 0; - for (auto const & info : p_files) { - QString filePath = VUtils::validFilePathToOpen(info.m_file); - if (filePath.isEmpty()) { - continue; - } - - VFile *file = g_vnote->getFile(filePath); - if (!file) { - continue; - } - - VEditTab *tab = openFile(file, info.m_mode, true); - ++nrOpened; - - if (info.m_active) { - curFile = file; - } - - VEditTabInfo tabInfo; - tabInfo.m_editTab = tab; - info.toEditTabInfo(&tabInfo); - - tab->tryRestoreFromTabInfo(tabInfo); - - if (p_oneByOne) { - QCoreApplication::sendPostedEvents(); - } - } - - if (curFile) { - openFile(curFile, OpenFileMode::Read, false); - } - - return nrOpened; -} - -void VEditArea::registerCaptainTargets() -{ - using namespace std::placeholders; - - VCaptain *captain = g_mainWin->getCaptain(); - - captain->registerCaptainTarget(tr("ActivateTab1"), - g_config->getCaptainShortcutKeySequence("ActivateTab1"), - this, - std::bind(activateTabByCaptain, _1, _2, 1)); - captain->registerCaptainTarget(tr("ActivateTab2"), - g_config->getCaptainShortcutKeySequence("ActivateTab2"), - this, - std::bind(activateTabByCaptain, _1, _2, 2)); - captain->registerCaptainTarget(tr("ActivateTab3"), - g_config->getCaptainShortcutKeySequence("ActivateTab3"), - this, - std::bind(activateTabByCaptain, _1, _2, 3)); - captain->registerCaptainTarget(tr("ActivateTab4"), - g_config->getCaptainShortcutKeySequence("ActivateTab4"), - this, - std::bind(activateTabByCaptain, _1, _2, 4)); - captain->registerCaptainTarget(tr("ActivateTab5"), - g_config->getCaptainShortcutKeySequence("ActivateTab5"), - this, - std::bind(activateTabByCaptain, _1, _2, 5)); - captain->registerCaptainTarget(tr("ActivateTab6"), - g_config->getCaptainShortcutKeySequence("ActivateTab6"), - this, - std::bind(activateTabByCaptain, _1, _2, 6)); - captain->registerCaptainTarget(tr("ActivateTab7"), - g_config->getCaptainShortcutKeySequence("ActivateTab7"), - this, - std::bind(activateTabByCaptain, _1, _2, 7)); - captain->registerCaptainTarget(tr("ActivateTab8"), - g_config->getCaptainShortcutKeySequence("ActivateTab8"), - this, - std::bind(activateTabByCaptain, _1, _2, 8)); - captain->registerCaptainTarget(tr("ActivateTab9"), - g_config->getCaptainShortcutKeySequence("ActivateTab9"), - this, - std::bind(activateTabByCaptain, _1, _2, 9)); - captain->registerCaptainTarget(tr("AlternateTab"), - g_config->getCaptainShortcutKeySequence("AlternateTab"), - this, - alternateTabByCaptain); - captain->registerCaptainTarget(tr("OpenedFileList"), - g_config->getCaptainShortcutKeySequence("OpenedFileList"), - this, - showOpenedFileListByCaptain); - captain->registerCaptainTarget(tr("ActivateSplitLeft"), - g_config->getCaptainShortcutKeySequence("ActivateSplitLeft"), - this, - activateSplitLeftByCaptain); - captain->registerCaptainTarget(tr("ActivateSplitRight"), - g_config->getCaptainShortcutKeySequence("ActivateSplitRight"), - this, - activateSplitRightByCaptain); - captain->registerCaptainTarget(tr("MoveTabSplitLeft"), - g_config->getCaptainShortcutKeySequence("MoveTabSplitLeft"), - this, - moveTabSplitLeftByCaptain); - captain->registerCaptainTarget(tr("MoveTabSplitRight"), - g_config->getCaptainShortcutKeySequence("MoveTabSplitRight"), - this, - moveTabSplitRightByCaptain); - captain->registerCaptainTarget(tr("ActivateNextTab"), - g_config->getCaptainShortcutKeySequence("ActivateNextTab"), - this, - activateNextTabByCaptain); - captain->registerCaptainTarget(tr("ActivatePreviousTab"), - g_config->getCaptainShortcutKeySequence("ActivatePreviousTab"), - this, - activatePreviousTabByCaptain); - captain->registerCaptainTarget(tr("VerticalSplit"), - g_config->getCaptainShortcutKeySequence("VerticalSplit"), - this, - verticalSplitByCaptain); - captain->registerCaptainTarget(tr("RemoveSplit"), - g_config->getCaptainShortcutKeySequence("RemoveSplit"), - this, - removeSplitByCaptain); - captain->registerCaptainTarget(tr("MaximizeSplit"), - g_config->getCaptainShortcutKeySequence("MaximizeSplit"), - this, - maximizeSplitByCaptain); - captain->registerCaptainTarget(tr("DistributeSplits"), - g_config->getCaptainShortcutKeySequence("DistributeSplits"), - this, - distributeSplitsByCaptain); - captain->registerCaptainTarget(tr("MagicWord"), - g_config->getCaptainShortcutKeySequence("MagicWord"), - this, - evaluateMagicWordsByCaptain); - captain->registerCaptainTarget(tr("ApplySnippet"), - g_config->getCaptainShortcutKeySequence("ApplySnippet"), - this, - applySnippetByCaptain); - captain->registerCaptainTarget(tr("LivePreview"), - g_config->getCaptainShortcutKeySequence("LivePreview"), - this, - toggleLivePreviewByCaptain); - captain->registerCaptainTarget(tr("ExpandLivePreview"), - g_config->getCaptainShortcutKeySequence("ExpandLivePreview"), - this, - expandLivePreviewByCaptain); - captain->registerCaptainTarget(tr("ParseAndPaste"), - g_config->getCaptainShortcutKeySequence("ParseAndPaste"), - this, - parseAndPasteByCaptain); -} - -bool VEditArea::activateTabByCaptain(void *p_target, void *p_data, int p_idx) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - if (win->activateTab(p_idx)) { - return false; - } - } - - return true; -} - -bool VEditArea::alternateTabByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - if (win->alternateTab()) { - return false; - } - } - - return true; -} - -bool VEditArea::showOpenedFileListByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - if (win->showOpenedFileList()) { - return false; - } - } - - return true; -} - -bool VEditArea::activateSplitLeftByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - if (obj->focusNextWindow(-1) > -1) { - return false; - } - - return true; -} - -bool VEditArea::activateSplitRightByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - if (obj->focusNextWindow(1) > -1) { - return false; - } - - return true; -} - -bool VEditArea::moveTabSplitLeftByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - obj->moveCurrentTabOneSplit(false); - return true; -} - -bool VEditArea::moveTabSplitRightByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - obj->moveCurrentTabOneSplit(true); - return true; -} - -bool VEditArea::activateNextTabByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - win->focusNextTab(true); - return false; - } - - return true; -} - -bool VEditArea::activatePreviousTabByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - VEditWindow *win = obj->getCurrentWindow(); - if (win) { - win->focusNextTab(false); - return false; - } - - return true; -} - -bool VEditArea::verticalSplitByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - obj->splitCurrentWindow(); - return false; -} - -bool VEditArea::removeSplitByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - obj->removeCurrentWindow(); - - QWidget *nextFocus = obj->getCurrentTab(); - if (nextFocus) { - nextFocus->setFocus(); - } else { - g_mainWin->getFileList()->setFocus(); - } - - return false; -} - -bool VEditArea::maximizeSplitByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - - obj->maximizeCurrentSplit(); - return true; -} - -bool VEditArea::distributeSplitsByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - - obj->distributeSplits(); - return true; -} - -bool VEditArea::evaluateMagicWordsByCaptain(void *p_target, void *p_data) -{ - VEditArea *obj = static_cast(p_target); - CaptainData *data = static_cast(p_data); - - VEditTab *tab = obj->getCurrentTab(); - if (tab - && (data->m_focusWidgetBeforeCaptain == tab - || tab->isAncestorOf(data->m_focusWidgetBeforeCaptain))) { - tab->evaluateMagicWords(); - } - - return true; -} - -bool VEditArea::applySnippetByCaptain(void *p_target, void *p_data) -{ - VEditArea *obj = static_cast(p_target); - CaptainData *data = static_cast(p_data); - - VEditTab *tab = obj->getCurrentTab(); - if (tab - && (data->m_focusWidgetBeforeCaptain == tab - || tab->isAncestorOf(data->m_focusWidgetBeforeCaptain))) { - tab->applySnippet(); - } - - return true; -} - -bool VEditArea::toggleLivePreviewByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - - VMdTab *tab = dynamic_cast(obj->getCurrentTab()); - if (tab) { - if (tab->toggleLivePreview()) { - return false; - } - } - - return true; -} - -bool VEditArea::expandLivePreviewByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - - VMdTab *tab = dynamic_cast(obj->getCurrentTab()); - if (tab) { - if (tab->expandRestorePreviewArea()) { - return false; - } - } - - return true; -} - -bool VEditArea::parseAndPasteByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VEditArea *obj = static_cast(p_target); - - const VMdTab *tab = dynamic_cast(obj->getCurrentTab()); - if (tab && tab->isEditMode()) { - VMdEditor *editor = tab->getEditor(); - editor->parseAndPaste(); - } - - return true; -} - -void VEditArea::recordClosedFile(const VFileSessionInfo &p_file) -{ - for (auto it = m_lastClosedFiles.begin(); it != m_lastClosedFiles.end(); ++it) { - if (it->m_file == p_file.m_file) { - // Remove it. - m_lastClosedFiles.erase(it); - break; - } - } - - m_lastClosedFiles.push(p_file); - - emit fileClosed(p_file.m_file); -} - -void VEditArea::handleFileTimerTimeout() -{ - int nrWin = splitter->count(); - for (int i = 0; i < nrWin; ++i) { - // Check whether opened files have been changed outside. - VEditWindow *win = getWindow(i); - win->checkFileChangeOutside(); - - if (m_autoSave) { - win->saveAll(); - } - } -} - -QRect VEditArea::editAreaRect() const -{ - QRect rt = rect(); - int nrWin = splitter->count(); - if (nrWin > 0) { - rt.setTopLeft(QPoint(0, getWindow(0)->tabBarHeight())); - } - - return rt; -} - -void VEditArea::maximizeCurrentSplit() -{ - if (splitter->count() <= 1 || curWindowIndex == -1) { - return; - } - - const int MinSplitWidth = 20 * VUtils::calculateScaleFactor(); - - auto sizes = splitter->sizes(); - int totalWidth = 0; - for (auto sz : sizes) { - totalWidth += sz; - } - - int newWidth = totalWidth - MinSplitWidth * (sizes.size() - 1); - if (newWidth <= 0) { - return; - } - - for (int i = 0; i < sizes.size(); ++i) { - sizes[i] = (i == curWindowIndex) ? newWidth : MinSplitWidth; - } - - splitter->setSizes(sizes); -} - -void VEditArea::distributeSplits() -{ - if (splitter->count() <= 1) { - return; - } - - auto sizes = splitter->sizes(); - int totalWidth = 0; - for (auto sz : sizes) { - totalWidth += sz; - } - - int newWidth = totalWidth / sizes.size(); - if (newWidth <= 0) { - return; - } - - for (int i = 0; i < sizes.size(); ++i) { - sizes[i] = newWidth; - } - - splitter->setSizes(sizes); -} - -void VEditArea::nextMatch(bool p_forward) -{ - VEditTab *tab = getCurrentTab(); - if (!tab) { - return; - } - - Q_ASSERT(m_findReplace); - - tab->nextMatch(m_findReplace->textToFind(), - m_findReplace->options(), - p_forward); -} diff --git a/src/veditarea.h b/src/veditarea.h deleted file mode 100644 index 5424797e..00000000 --- a/src/veditarea.h +++ /dev/null @@ -1,301 +0,0 @@ -#ifndef VEDITAREA_H -#define VEDITAREA_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vnotebook.h" -#include "veditwindow.h" -#include "vnavigationmode.h" -#include "vfilesessioninfo.h" -#include "vtexteditcompleter.h" - -class VFile; -class VDirectory; -class VFindReplaceDialog; -class QLabel; -class VVim; -class VMathJaxPreviewHelper; - -class VEditArea : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VEditArea(QWidget *parent = 0); - - // Whether @p_file has been opened in edit area. - bool isFileOpened(const VFile *p_file); - - bool closeAllFiles(bool p_forced); - bool closeFile(const VFile *p_file, bool p_forced); - bool closeFile(const VDirectory *p_dir, bool p_forced); - bool closeFile(const VNotebook *p_notebook, bool p_forced); - - // Return current edit window. - VEditWindow *getCurrentWindow() const; - - // Return current edit tab. - VEditTab *getCurrentTab() const; - - // Return the @p_tabIdx tab in the @p_winIdx window. - VEditTab *getTab(int p_winIdx, int p_tabIdx) const; - - // Return the tab for @p_file file. - VEditTab *getTab(const VFile *p_file) const; - - // Return VEditTabInfo of all edit tabs. - QVector getAllTabsInfo() const; - - QVector getAllTabs() const; - - // Return the count of VEditWindow. - int windowCount() const; - - // Returns the index of @p_window. - int windowIndex(const VEditWindow *p_window) const; - // Move tab widget @p_widget from window @p_fromIdx to @p_toIdx. - // @p_widget has been removed from the original window. - // If fail, just delete the p_widget. - void moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx); - - VFindReplaceDialog *getFindReplaceDialog() const; - - // Return selected text of current edit tab. - QString getSelectedText(); - void splitCurrentWindow(); - void removeCurrentWindow(); - // Focus next window (curWindowIndex + p_biaIdx). - // Return the new current window index, otherwise, return -1. - int focusNextWindow(int p_biaIdx); - void moveCurrentTabOneSplit(bool p_right); - - // Implementations for VNavigationMode. - void registerNavigation(QChar p_majorKey) Q_DECL_OVERRIDE; - void showNavigation() Q_DECL_OVERRIDE; - void hideNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - - // Open files @p_files. - int openFiles(const QVector &p_files, bool p_oneByOne = false); - - // Record a closed file in the stack. - void recordClosedFile(const VFileSessionInfo &p_file); - - // Return the rect not containing the tab bar. - QRect editAreaRect() const; - - VMathJaxPreviewHelper *getMathJaxPreviewHelper() const; - - // Maximize the width of current vertical split. - void maximizeCurrentSplit(); - - // Distribute all the splits evenly. - void distributeSplits(); - - QSharedPointer getCompleter() const; - -signals: - // Emit when current window's tab status updated. - void tabStatusUpdated(const VEditTabInfo &p_info); - - // Emit when current window's tab's outline changed. - void outlineChanged(const VTableOfContent &p_outline); - - // Emit when current window's tab's current header changed. - void currentHeaderChanged(const VHeaderPointer &p_header); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - // Emit when Vim status updated. - void vimStatusUpdated(const VVim *p_vim); - - // Emit when @p_file is closed. - void fileClosed(const QString &p_file); - -protected: - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - -public slots: - // Open @p_file in mode @p_mode. - // If @p_file has already been opened, change its mode to @p_mode only if - // @p_forceMode is true. - // A given file can be opened in multiple split windows. A given file could be - // opened at most in one tab inside a window. - VEditTab *openFile(VFile *p_file, OpenFileMode p_mode, bool p_forceMode = false); - - void editFile(); - void saveFile(); - - void readFile(bool p_discard = false); - - void saveAndReadFile(); - - // Scroll current tab to @p_header. - void scrollToHeader(const VHeaderPointer &p_header); - - void handleFileUpdated(const VFile *p_file, UpdateAction p_act); - - void handleDirectoryUpdated(const VDirectory *p_dir, UpdateAction p_act); - - void handleNotebookUpdated(const VNotebook *p_notebook); - -private slots: - // Split @curWindow via inserting a new window around it. - // @p_right: insert the new window on the right side. - void splitWindow(VEditWindow *p_window, bool p_right = true); - - void handleRemoveSplitRequest(VEditWindow *curWindow); - void handleWindowFocused(); - - void handleWindowOutlineChanged(const VTableOfContent &p_outline); - - void handleWindowCurrentHeaderChanged(const VHeaderPointer &p_header); - - void handleFindTextChanged(const QString &p_text, uint p_options); - void handleFindOptionChanged(uint p_options); - void handleFindNext(const QString &p_text, uint p_options, bool p_forward); - void handleReplace(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext); - void handleReplaceAll(const QString &p_text, uint p_options, - const QString &p_replaceText); - void handleFindDialogClosed(); - - // Hanle the status update of current tab within a VEditWindow. - void handleWindowTabStatusUpdated(const VEditTabInfo &p_info); - - // Handle the statusMessage signal of VEditWindow. - void handleWindowStatusMessage(const QString &p_msg); - - // Handle the vimStatusUpdated signal of VEditWindow. - void handleWindowVimStatusUpdated(const VVim *p_vim); - - // Handle the timeout signal of file timer. - void handleFileTimerTimeout(); - - // Jump to next match of last find. - void nextMatch(bool p_forward); - -private: - void setupUI(); - - void initShortcuts(); - - QVector > findTabsByFile(const VFile *p_file); - - int openFileInWindow(int windowIndex, VFile *p_file, OpenFileMode p_mode); - void setCurrentTab(int windowIndex, int tabIndex, bool setFocus); - void setCurrentWindow(int windowIndex, bool setFocus); - - VEditWindow *getWindow(int windowIndex) const; - - void insertSplitWindow(int idx); - void removeSplitWindow(VEditWindow *win); - - // Update status of current window. - void updateWindowStatus(); - - // Init targets for Captain mode. - void registerCaptainTargets(); - - // Captain mode functions. - // Activate tab @p_idx. - static bool activateTabByCaptain(void *p_target, void *p_data, int p_idx); - - static bool alternateTabByCaptain(void *p_target, void *p_data); - - static bool showOpenedFileListByCaptain(void *p_target, void *p_data); - - static bool activateSplitLeftByCaptain(void *p_target, void *p_data); - - static bool activateSplitRightByCaptain(void *p_target, void *p_data); - - static bool moveTabSplitLeftByCaptain(void *p_target, void *p_data); - - static bool moveTabSplitRightByCaptain(void *p_target, void *p_data); - - static bool activateNextTabByCaptain(void *p_target, void *p_data); - - static bool activatePreviousTabByCaptain(void *p_target, void *p_data); - - static bool verticalSplitByCaptain(void *p_target, void *p_data); - - static bool removeSplitByCaptain(void *p_target, void *p_data); - - static bool maximizeSplitByCaptain(void *p_target, void *p_data); - - static bool distributeSplitsByCaptain(void *p_target, void *p_data); - - // Evaluate selected text or the word on cursor as magic words. - static bool evaluateMagicWordsByCaptain(void *p_target, void *p_data); - - // Prompt for user to apply a snippet. - static bool applySnippetByCaptain(void *p_target, void *p_data); - - // Toggle live preview. - static bool toggleLivePreviewByCaptain(void *p_target, void *p_data); - - // Expand live preview. - static bool expandLivePreviewByCaptain(void *p_target, void *p_data); - - // Parse and paste. - static bool parseAndPasteByCaptain(void *p_target, void *p_data); - - // End Captain mode functions. - - int curWindowIndex; - - // Splitter holding multiple split windows - QSplitter *splitter; - VFindReplaceDialog *m_findReplace; - - // Last closed files stack. - QStack m_lastClosedFiles; - - // Whether auto save files. - bool m_autoSave; - - VMathJaxPreviewHelper *m_mathPreviewHelper; - - QSharedPointer m_completer; -}; - -inline VEditWindow* VEditArea::getWindow(int windowIndex) const -{ - Q_ASSERT(windowIndex < splitter->count()); - return dynamic_cast(splitter->widget(windowIndex)); -} - -inline int VEditArea::windowCount() const -{ - return splitter->count(); -} - -inline VFindReplaceDialog *VEditArea::getFindReplaceDialog() const -{ - return m_findReplace; -} - -inline VMathJaxPreviewHelper *VEditArea::getMathJaxPreviewHelper() const -{ - return m_mathPreviewHelper; -} - -inline QSharedPointer VEditArea::getCompleter() const -{ - if (m_completer.isNull()) { - VEditArea *ea = const_cast(this); - ea->m_completer.reset(new VTextEditCompleter(ea)); - } - - return m_completer; -} -#endif // VEDITAREA_H diff --git a/src/veditconfig.cpp b/src/veditconfig.cpp deleted file mode 100644 index 9866d7fa..00000000 --- a/src/veditconfig.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "veditconfig.h" - -#include "vconfigmanager.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -void VEditConfig::init(const QFontMetrics &p_metric, - bool p_enableHeadingSequence) -{ - update(p_metric); - - // Init configs that do not support update later. - m_enableVimMode = g_config->getEnableVimMode(); - - if (g_config->getLineDistanceHeight() <= 0) { - m_lineDistanceHeight = 0; - } else { - m_lineDistanceHeight = g_config->getLineDistanceHeight() * VUtils::calculateScaleFactor(); - } - - m_highlightWholeBlock = m_enableVimMode; - - m_enableHeadingSequence = p_enableHeadingSequence; -} - -void VEditConfig::update(const QFontMetrics &p_metric) -{ - if (g_config->getTabStopWidth() > 0) { - m_tabStopWidth = g_config->getTabStopWidth() * p_metric.width(' '); - } else { - m_tabStopWidth = 0; - } - - m_expandTab = g_config->getIsExpandTab(); - - if (m_expandTab && (g_config->getTabStopWidth() > 0)) { - m_tabSpaces = QString(g_config->getTabStopWidth(), ' '); - } else { - m_tabSpaces = "\t"; - } - - m_cursorLineBg = QColor(g_config->getEditorCurrentLineBg()); -} diff --git a/src/veditconfig.h b/src/veditconfig.h deleted file mode 100644 index af1803b0..00000000 --- a/src/veditconfig.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef VEDITCONFIG_H -#define VEDITCONFIG_H - -#include -#include -#include - - -class VEditConfig { -public: - VEditConfig() : m_tabStopWidth(0), - m_tabSpaces("\t"), - m_enableVimMode(false), - m_highlightWholeBlock(false), - m_lineDistanceHeight(0), - m_enableHeadingSequence(false) - {} - - void init(const QFontMetrics &p_metric, - bool p_enableHeadingSequence); - - // Only update those configs which could be updated online. - void update(const QFontMetrics &p_metric); - - // Width in pixels. - int m_tabStopWidth; - - bool m_expandTab; - - // The literal string for Tab. It is spaces if Tab is expanded. - QString m_tabSpaces; - - bool m_enableVimMode; - - // The background color of cursor line. - QColor m_cursorLineBg; - - // Whether highlight a visual line or a whole block. - bool m_highlightWholeBlock; - - // Line distance height in pixels. - int m_lineDistanceHeight; - - // Whether enable auto heading sequence. - bool m_enableHeadingSequence; -}; - -#endif // VEDITCONFIG_H diff --git a/src/veditoperations.cpp b/src/veditoperations.cpp deleted file mode 100644 index 27ec5cdf..00000000 --- a/src/veditoperations.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include -#include -#include -#include "veditor.h" -#include "veditoperations.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -VEditOperations::VEditOperations(VEditor *p_editor, VFile *p_file) - : QObject(p_editor->getEditor()), - m_editor(p_editor), - m_file(p_file), - m_editConfig(&p_editor->getConfig()), - m_vim(NULL) -{ - connect(m_editor->object(), &VEditorObject::configUpdated, - this, &VEditOperations::handleEditConfigUpdated); - - if (m_editConfig->m_enableVimMode) { - m_vim = new VVim(m_editor); - - connect(m_vim, &VVim::modeChanged, - this, &VEditOperations::handleVimModeChanged); - connect(m_vim, &VVim::vimMessage, - this, &VEditOperations::statusMessage); - connect(m_vim, &VVim::vimStatusUpdated, - this, &VEditOperations::vimStatusUpdated); - } -} - -void VEditOperations::insertText(const QString &p_text) -{ - m_editor->insertPlainTextW(p_text); -} - -VEditOperations::~VEditOperations() -{ -} - -void VEditOperations::updateCursorLineBg() -{ - if (m_editConfig->m_enableVimMode) { - switch (m_vim->getMode()) { - case VimMode::Normal: - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorVimNormalBg()); - break; - - case VimMode::Insert: - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorVimInsertBg()); - break; - - case VimMode::Visual: - case VimMode::VisualLine: - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorVimVisualBg()); - break; - - case VimMode::Replace: - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorVimReplaceBg()); - break; - - default: - V_ASSERT(false); - break; - } - } else { - m_editConfig->m_cursorLineBg = QColor(g_config->getEditorCurrentLineBg()); - } - - m_editor->highlightCurrentLine(); -} - -void VEditOperations::handleEditConfigUpdated() -{ - // Reset to Normal mode. - if (m_vim) { - m_vim->setMode(VimMode::Normal); - } - - updateCursorLineBg(); -} - -void VEditOperations::handleVimModeChanged(VimMode p_mode) -{ - // Only highlight current visual line in Insert mode. - m_editConfig->m_highlightWholeBlock = (p_mode != VimMode::Insert); - - updateCursorLineBg(); -} - -void VEditOperations::requestUpdateVimStatus() -{ - emit vimStatusUpdated(m_vim); -} - -void VEditOperations::setVimMode(VimMode p_mode) -{ - if (m_vim && m_editConfig->m_enableVimMode) { - m_vim->setMode(p_mode); - } -} - -VVim *VEditOperations::getVim() const -{ - return m_vim; -} diff --git a/src/veditoperations.h b/src/veditoperations.h deleted file mode 100644 index e8b32d62..00000000 --- a/src/veditoperations.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef VEDITOPERATIONS_H -#define VEDITOPERATIONS_H - -#include -#include -#include -#include -#include "vfile.h" -#include "utils/vvim.h" - -class VEditor; -class VEditConfig; -class QMimeData; -class QKeyEvent; - -class VEditOperations: public QObject -{ - Q_OBJECT -public: - VEditOperations(VEditor *p_editor, VFile *p_file); - - virtual ~VEditOperations(); - - virtual bool insertImageFromMimeData(const QMimeData *source) = 0; - - virtual bool insertImage() = 0; - - virtual bool insertImageFromURL(const QUrl &p_imageUrl) = 0; - - virtual bool insertLink(const QString &p_linkText, - const QString &p_linkUrl) = 0; - - virtual void insertText(const QString &p_text); - - // Return true if @p_event has been handled and no need to be further - // processed. - virtual bool handleKeyPressEvent(QKeyEvent *p_event) = 0; - - // Request to propogate Vim status. - void requestUpdateVimStatus(); - - // Insert decoration markers or decorate selected text. - virtual void decorateText(TextDecoration p_decoration, int p_level = -1) - { - Q_UNUSED(p_decoration); - Q_UNUSED(p_level); - } - - // Set Vim mode if not NULL. - void setVimMode(VimMode p_mode); - - VVim *getVim() const; - -signals: - // Want to display a template message in status bar. - void statusMessage(const QString &p_msg); - - // Propogate Vim status. - void vimStatusUpdated(const VVim *p_vim); - -protected slots: - // Handle the update of VEditConfig of the editor. - virtual void handleEditConfigUpdated(); - - // Vim mode changed. - void handleVimModeChanged(VimMode p_mode); - -private: - // Update m_editConfig->m_cursorLineBg. - void updateCursorLineBg(); - -protected: - VEditor *m_editor; - QPointer m_file; - VEditConfig *m_editConfig; - VVim *m_vim; -}; - -#endif // VEDITOPERATIONS_H diff --git a/src/veditor.cpp b/src/veditor.cpp deleted file mode 100644 index afdc1854..00000000 --- a/src/veditor.cpp +++ /dev/null @@ -1,1752 +0,0 @@ -#include "veditor.h" - -#include -#include - -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "utils/veditutils.h" -#include "veditoperations.h" -#include "dialog/vinsertlinkdialog.h" -#include "utils/vmetawordmanager.h" -#include "utils/vvim.h" -#include "vnote.h" - -extern VConfigManager *g_config; - -extern VMetaWordManager *g_mwMgr; - -VEditor::VEditor(VFile *p_file, - QWidget *p_editor, - const QSharedPointer &p_completer) - : m_editor(p_editor), - m_object(new VEditorObject(this, p_editor)), - m_file(p_file), - m_editOps(nullptr), - m_document(nullptr), - m_enableInputMethod(true), - m_timeStamp(0), - m_trailingSpaceSelectionTS(0), - m_completer(p_completer), - m_trailingSpaceHighlightEnabled(false), - m_tabHighlightEnabled(false) -{ -} - -VEditor::~VEditor() -{ - if (m_completer->widget() == m_editor) { - m_completer->setWidget(NULL); - } - - cleanUp(); -} - -void VEditor::cleanUp() -{ - for (auto const & file : m_tempFiles) { - VUtils::deleteFile(file); - } - - m_tempFiles.clear(); -} - -void VEditor::init() -{ - const int labelTimerInterval = 500; - const int extraSelectionHighlightTimer = 500; - const int trailingSpaceUpdateTimer = 500; - const int labelSize = 64; - - m_document = documentW(); - QObject::connect(m_document, &QTextDocument::contentsChanged, - m_object, &VEditorObject::clearFindCache); - - m_selectedWordFg = QColor(g_config->getEditorSelectedWordFg()); - m_selectedWordBg = QColor(g_config->getEditorSelectedWordBg()); - - m_searchedWordFg = QColor(g_config->getEditorSearchedWordFg()); - m_searchedWordBg = QColor(g_config->getEditorSearchedWordBg()); - - m_searchedWordCursorFg = QColor(g_config->getEditorSearchedWordCursorFg()); - m_searchedWordCursorBg = QColor(g_config->getEditorSearchedWordCursorBg()); - - m_incrementalSearchedWordFg = QColor(g_config->getEditorIncrementalSearchedWordFg()); - m_incrementalSearchedWordBg = QColor(g_config->getEditorIncrementalSearchedWordBg()); - - m_trailingSpaceColor = QColor(g_config->getEditorTrailingSpaceBg()); - - m_tabColor = g_config->getMdEditPalette().color(QPalette::Text); - - QPixmap wrapPixmap(":/resources/icons/search_wrap.svg"); - m_wrapLabel = new QLabel(m_editor); - m_wrapLabel->setPixmap(wrapPixmap.scaled(labelSize, labelSize)); - m_wrapLabel->hide(); - m_labelTimer = new QTimer(m_editor); - m_labelTimer->setSingleShot(true); - m_labelTimer->setInterval(labelTimerInterval); - QObject::connect(m_labelTimer, &QTimer::timeout, - m_object, &VEditorObject::labelTimerTimeout); - - m_highlightTimer = new QTimer(m_editor); - m_highlightTimer->setSingleShot(true); - m_highlightTimer->setInterval(extraSelectionHighlightTimer); - QObject::connect(m_highlightTimer, &QTimer::timeout, - m_object, &VEditorObject::doHighlightExtraSelections); - - m_trailingSpaceTimer = new QTimer(m_editor); - m_trailingSpaceTimer->setSingleShot(true); - m_trailingSpaceTimer->setInterval(trailingSpaceUpdateTimer); - QObject::connect(m_trailingSpaceTimer, &QTimer::timeout, - m_object, &VEditorObject::doUpdateTrailingSpaceAndTabHighlights); - - m_extraSelections.resize((int)SelectionId::MaxSelection); - - updateFontAndPalette(); - - m_config.init(QFontMetrics(m_editor->font()), false); - updateEditConfig(); - - // Init shortcuts. - QKeySequence keySeq(g_config->getShortcutKeySequence("PastePlainText")); - QShortcut *pastePlainTextShortcut = new QShortcut(keySeq, m_editor); - pastePlainTextShortcut->setContext(Qt::WidgetShortcut); - QObject::connect(pastePlainTextShortcut, &QShortcut::activated, - m_object, [this]() { - pastePlainText(); - }); -} - -void VEditor::labelTimerTimeout() -{ - m_wrapLabel->hide(); -} - -bool VEditor::needUpdateTrailingSpaceAndTabHighlights() -{ - bool ret = false; - bool space = g_config->getEnableTrailingSpaceHighlight(); - if (m_trailingSpaceHighlightEnabled != space) { - m_trailingSpaceHighlightEnabled = space; - ret = true; - } - - bool tab = g_config->getEnableTabHighlight(); - if (m_tabHighlightEnabled != tab) { - m_tabHighlightEnabled = tab; - ret = true; - } - - if (m_trailingSpaceSelectionTS != m_timeStamp) { - ret = true; - } - - return ret; -} - -void VEditor::updateTrailingSpaceAndTabHighlights() -{ - if (needUpdateTrailingSpaceAndTabHighlights()) { - m_trailingSpaceTimer->start(); - } else { - highlightExtraSelections(false); - } -} - -void VEditor::doHighlightExtraSelections() -{ - int nrExtra = m_extraSelections.size(); - Q_ASSERT(nrExtra == (int)SelectionId::MaxSelection); - QList extraSelects; - for (int i = 0; i < nrExtra; ++i) { - if (i == (int)SelectionId::TrailingSpace) { - filterTrailingSpace(extraSelects, m_extraSelections[i]); - } else { - extraSelects.append(m_extraSelections[i]); - } - } - - setExtraSelectionsW(extraSelects); -} - -void VEditor::doUpdateTrailingSpaceAndTabHighlights() -{ - bool needHighlight = false; - - // Trailing space. - if (!m_trailingSpaceHighlightEnabled) { - QList &selects = m_extraSelections[(int)SelectionId::TrailingSpace]; - if (!selects.isEmpty()) { - selects.clear(); - needHighlight = true; - } - } else { - needHighlight = true; - QTextCharFormat format; - format.setBackground(m_trailingSpaceColor); - QString text("\\s+$"); - highlightTextAll(text, - FindOption::RegularExpression, - SelectionId::TrailingSpace, - format); - } - - // Tab. - if (!m_tabHighlightEnabled) { - QList &selects = m_extraSelections[(int)SelectionId::Tab]; - if (!selects.isEmpty()) { - selects.clear(); - needHighlight = true; - } - } else { - needHighlight = true; - QTextCharFormat format; - format.setBackground(m_tabColor); - QString text("\\t"); - highlightTextAll(text, - FindOption::RegularExpression, - SelectionId::Tab, - format); - } - - m_trailingSpaceSelectionTS = m_timeStamp; - - if (needHighlight) { - highlightExtraSelections(true); - } -} - -void VEditor::updateEditConfig() -{ - // FIXME: we need to use font of the code block here. - QFont font(m_editor->font()); - font.setFamily(VNote::getMonospaceFont()); - m_config.update(QFontMetrics(font)); - - if (m_config.m_tabStopWidth > 0) { - setTabStopWidthW(m_config.m_tabStopWidth); - } - - emit m_object->configUpdated(); -} - -void VEditor::highlightOnCursorPositionChanged() -{ - static QTextCursor lastCursor; - - QTextCursor cursor = textCursorW(); - if (lastCursor.isNull() || cursor.blockNumber() != lastCursor.blockNumber()) { - updateTrailingSpaceAndTabHighlights(); - highlightCurrentLine(); - } else { - // Judge whether we have trailing space at current line. - QString text = cursor.block().text(); - if (!text.isEmpty()) { - auto it = text.rbegin(); - bool needUpdate = it->isSpace(); - if (!needUpdate - && cursor.atBlockEnd() - && text.size() > 1) { - ++it; - needUpdate = it->isSpace(); - // Input two chars at once in Chinese. - if (!needUpdate && text.size() > 2) { - ++it; - needUpdate = it->isSpace(); - } - } - - if (needUpdate) { - updateTrailingSpaceAndTabHighlights(); - } - } - - // Handle word-wrap in one block. - // Highlight current line if in different visual line. - if ((lastCursor.positionInBlock() - lastCursor.columnNumber()) != - (cursor.positionInBlock() - cursor.columnNumber())) { - highlightCurrentLine(); - } - } - - lastCursor = cursor; -} - -void VEditor::updateTimeStamp() -{ - ++m_timeStamp; -} - -void VEditor::highlightCurrentLine() -{ - QList &selects = m_extraSelections[(int)SelectionId::CurrentLine]; - if (g_config->getHighlightCursorLine()) { - // Need to highlight current line. - selects.clear(); - - // A long block maybe splited into multiple visual lines. - QTextEdit::ExtraSelection select; - select.format.setBackground(m_config.m_cursorLineBg); - select.format.setProperty(QTextFormat::FullWidthSelection, true); - - QTextCursor cursor = textCursorW(); - if (m_config.m_highlightWholeBlock) { - cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor, 1); - QTextBlock block = cursor.block(); - int blockEnd = block.position() + block.length(); - int pos = -1; - while (cursor.position() < blockEnd && pos != cursor.position()) { - QTextEdit::ExtraSelection newSelect = select; - newSelect.cursor = cursor; - selects.append(newSelect); - - pos = cursor.position(); - cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 1); - } - } else { - cursor.clearSelection(); - select.cursor = cursor; - selects.append(select); - } - } else { - // Need to clear current line highlight. - if (selects.isEmpty()) { - return; - } - - selects.clear(); - } - - highlightExtraSelections(true); -} - -void VEditor::filterTrailingSpace(QList &p_selects, - const QList &p_src) -{ - QTextCursor cursor = textCursorW(); - bool blockEnd = cursor.atBlockEnd(); - int blockNum = cursor.blockNumber(); - for (auto it = p_src.begin(); it != p_src.end(); ++it) { - if (it->cursor.blockNumber() == blockNum) { - if (blockEnd) { - // When cursor is at block end, we do not display any trailing space - // at current line. - continue; - } - - QString text = cursor.block().text(); - if (text.isEmpty()) { - continue; - } else if (!text[text.size() - 1].isSpace()) { - continue; - } - } - - p_selects.append(*it); - } -} - -void VEditor::highlightExtraSelections(bool p_now) -{ - m_highlightTimer->stop(); - if (p_now) { - doHighlightExtraSelections(); - } else { - m_highlightTimer->start(); - } -} - -void VEditor::highlightTextAll(const QString &p_text, - uint p_options, - SelectionId p_id, - QTextCharFormat p_format, - void (*p_filter)(VEditor *, - QList &)) -{ - QList &selects = m_extraSelections[(int)p_id]; - if (!p_text.isEmpty()) { - selects.clear(); - - QList occurs = findTextAll(p_text, p_options); - for (int i = 0; i < occurs.size(); ++i) { - QTextEdit::ExtraSelection select; - select.format = p_format; - select.cursor = occurs[i]; - selects.append(select); - } - } else { - if (selects.isEmpty()) { - return; - } - selects.clear(); - } - - if (p_filter) { - p_filter(this, selects); - } - - highlightExtraSelections(); -} - -static QTextDocument::FindFlags findOptionsToFlags(uint p_options, bool p_forward) -{ - QTextDocument::FindFlags findFlags; - - if (p_options & FindOption::CaseSensitive) { - findFlags |= QTextDocument::FindCaseSensitively; - } - - if (p_options & FindOption::WholeWordOnly) { - findFlags |= QTextDocument::FindWholeWords; - } - - if (!p_forward) { - findFlags |= QTextDocument::FindBackward; - } - - return findFlags; -} - -QList VEditor::findTextAll(const QString &p_text, - uint p_options, - int p_start, - int p_end) -{ - QList results; - if (p_text.isEmpty()) { - return results; - } - - // Options - bool caseSensitive = p_options & FindOption::CaseSensitive; - QTextDocument::FindFlags findFlags = findOptionsToFlags(p_options, true); - - if (p_options & FindOption::RegularExpression) { - QRegExp exp(p_text, - caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - results = findTextAllInRange(m_document, exp, findFlags, p_start, p_end); - } else { - results = findTextAllInRange(m_document, p_text, findFlags, p_start, p_end); - } - - return results; -} - -static void mergeResult(QList &p_result, const QList &p_part) -{ - if (p_result.isEmpty()) { - p_result = p_part; - return; - } - - int idx = 0; - for (auto const & cur : p_part) { - // Find position to insert into @p_result. - while (idx < p_result.size()) { - const QTextCursor &toCur = p_result[idx]; - if (cur.selectionEnd() <= toCur.selectionStart()) { - // Insert it before toCur. - p_result.insert(idx, cur); - ++idx; - break; - } else if (cur.selectionStart() < toCur.selectionEnd()) { - // Interleave. Abandon it. - break; - } else { - ++idx; - } - } - - // Insert to the end. - if (idx >= p_result.size()) { - p_result.append(cur); - idx = p_result.size(); - } - } -} - -QList VEditor::findTextAll(const VSearchToken &p_token, - int p_start, - int p_end) -{ - QList results; - if (p_token.isEmpty()) { - return results; - } - - QTextDocument::FindFlags flags; - if (p_token.m_caseSensitivity == Qt::CaseSensitive) { - flags |= QTextDocument::FindCaseSensitively; - } - - if (p_token.m_type == VSearchToken::RawString) { - for (auto const & wd : p_token.m_keywords) { - QList part = findTextAllInRange(m_document, wd, flags, p_start, p_end); - mergeResult(results, part); - } - } else { - // Regular expression. - for (auto const & reg : p_token.m_regs) { - QList part = findTextAllInRange(m_document, reg, flags, p_start, p_end); - mergeResult(results, part); - } - } - - return results; -} - -const QList &VEditor::findTextAllCached(const QString &p_text, - uint p_options, - int p_start, - int p_end) -{ - if (p_text.isEmpty()) { - m_findInfo.clear(); - return m_findInfo.m_result; - } - - if (m_findInfo.isCached(p_text, p_options, p_start, p_end)) { - return m_findInfo.m_result; - } - - QList result = findTextAll(p_text, p_options, p_start, p_end); - m_findInfo.update(p_text, p_options, p_start, p_end, result); - - return m_findInfo.m_result; -} - -const QList &VEditor::findTextAllCached(const VSearchToken &p_token, - int p_start, - int p_end) -{ - if (p_token.isEmpty()) { - m_findInfo.clear(); - return m_findInfo.m_result; - } - - if (m_findInfo.isCached(p_token, p_start, p_end)) { - return m_findInfo.m_result; - } - - QList result = findTextAll(p_token, p_start, p_end); - m_findInfo.update(p_token, p_start, p_end, result); - - return m_findInfo.m_result; -} - -void VEditor::highlightSelectedWord() -{ - QList &selects = m_extraSelections[(int)SelectionId::SelectedWord]; - if (!g_config->getHighlightSelectedWord()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - QString text = textCursorW().selectedText().trimmed(); - if (text.isEmpty() || wordInSearchedSelection(text)) { - selects.clear(); - highlightExtraSelections(true); - return; - } - - QTextCharFormat format; - format.setForeground(m_selectedWordFg); - format.setBackground(m_selectedWordBg); - highlightTextAll(text, - FindOption::CaseSensitive, - SelectionId::SelectedWord, - format); -} - -bool VEditor::wordInSearchedSelection(const QString &p_text) -{ - QString text = p_text.trimmed(); - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - for (int i = 0; i < selects.size(); ++i) { - QString searchedWord = selects[i].cursor.selectedText(); - if (text == searchedWord.trimmed()) { - return true; - } - } - - return false; -} - -bool VEditor::isModified() const -{ - return m_document->isModified(); -} - -void VEditor::setModified(bool p_modified) -{ - m_document->setModified(p_modified); -} - -void VEditor::insertImage() -{ - if (m_editOps) { - m_editOps->insertImage(); - } -} - -void VEditor::insertLink() -{ - if (!m_editOps) { - return; - } - - QString text; - QString linkText, linkUrl; - QTextCursor cursor = textCursorW(); - if (cursor.hasSelection()) { - text = VEditUtils::selectedText(cursor).trimmed(); - // Only pure space is accepted. - QRegExp reg("[\\S ]*"); - if (reg.exactMatch(text)) { - QUrl url = QUrl::fromUserInput(text, - m_file->fetchBasePath()); - QRegExp urlReg("[\\.\\\\/]"); - if (url.isValid() - && text.contains(urlReg)) { - // Url. - linkUrl = text; - } else { - // Text. - linkText = text; - } - } - } - - VInsertLinkDialog dialog(QObject::tr("Insert Link"), - "", - "", - linkText, - linkUrl, - false, - m_editor); - if (dialog.exec() == QDialog::Accepted) { - linkText = dialog.getLinkText(); - linkUrl = dialog.getLinkUrl(); - Q_ASSERT(!linkText.isEmpty() && !linkUrl.isEmpty()); - - m_editOps->insertLink(linkText, linkUrl); - } -} - -bool VEditor::peekText(const QString &p_text, uint p_options, bool p_forward) -{ - if (p_text.isEmpty()) { - makeBlockVisible(m_document->findBlock(textCursorW().selectionStart())); - highlightIncrementalSearchedWord(QTextCursor()); - return false; - } - - bool wrapped = false; - QTextCursor retCursor; - int start = textCursorW().position(); - int skipPosition = start; - - bool found = false; - while (true) { - found = findTextHelper(p_text, p_options, p_forward, start, wrapped, retCursor); - if (found) { - if (p_forward && retCursor.selectionStart() == skipPosition) { - // Skip the first match. - skipPosition = -1; - start = retCursor.selectionEnd(); - continue; - } - - makeBlockVisible(m_document->findBlock(retCursor.selectionStart())); - highlightIncrementalSearchedWord(retCursor); - } - - break; - } - - return found; -} - -// @p_cursors is in ascending order. -// If @p_forward is true, find the smallest cursor whose selection start is greater -// than @p_pos or the first cursor if wrapped. -// Otherwise, find the largest cursor whose selection start is smaller than @p_pos -// or the last cursor if wrapped. -static int selectCursor(const QList &p_cursors, - int p_pos, - bool p_forward, - bool &p_wrapped) -{ - Q_ASSERT(!p_cursors.isEmpty()); - - p_wrapped = false; - - int first = 0, last = p_cursors.size() - 1; - int lastMatch = -1; - while (first <= last) { - int mid = (first + last) / 2; - const QTextCursor &cur = p_cursors.at(mid); - if (p_forward) { - if (cur.selectionStart() < p_pos) { - first = mid + 1; - } else if (cur.selectionStart() == p_pos) { - // Next one is the right one. - if (mid < p_cursors.size() - 1) { - lastMatch = mid + 1; - } else { - lastMatch = 0; - p_wrapped = true; - } - break; - } else { - // It is a match. - if (lastMatch == -1 || mid < lastMatch) { - lastMatch = mid; - } - - last = mid - 1; - } - } else { - if (cur.selectionStart() > p_pos) { - last = mid - 1; - } else if (cur.selectionStart() == p_pos) { - // Previous one is the right one. - if (mid > 0) { - lastMatch = mid - 1; - } else { - lastMatch = p_cursors.size() - 1; - p_wrapped = true; - } - break; - } else { - // It is a match. - if (lastMatch == -1 || mid > lastMatch) { - lastMatch = mid; - } - - first = mid + 1; - } - } - } - - if (lastMatch == -1) { - p_wrapped = true; - lastMatch = p_forward ? 0 : (p_cursors.size() - 1); - } - - return lastMatch; -} - -bool VEditor::findText(const QString &p_text, - uint p_options, - bool p_forward, - QTextCursor *p_cursor, - QTextCursor::MoveMode p_moveMode, - bool p_useLeftSideOfCursor) -{ - return findTextInRange(p_text, - p_options, - p_forward, - p_cursor, - p_moveMode, - p_useLeftSideOfCursor); -} - -bool VEditor::findText(const VSearchToken &p_token, bool p_forward, bool p_fromStart) -{ - clearIncrementalSearchedWordHighlight(); - - if (p_token.isEmpty()) { - m_findInfo.clear(); - clearSearchedWordHighlight(); - return false; - } - - const QList &result = findTextAllCached(p_token); - - if (result.isEmpty()) { - clearSearchedWordHighlight(); - - emit m_object->statusMessage(QObject::tr("No match found")); - } else { - // Locate to the right match and update current cursor. - QTextCursor cursor = textCursorW(); - int pos = p_fromStart ? (m_document->characterCount() + 1) : cursor.position(); - bool wrapped = false; - int idx = selectCursor(result, pos, p_forward, wrapped); - const QTextCursor &tcursor = result.at(idx); - if (wrapped && !p_fromStart) { - showWrapLabel(); - } - - cursor.setPosition(tcursor.selectionStart(), QTextCursor::MoveAnchor); - setTextCursorW(cursor); - - highlightSearchedWord(result); - - highlightSearchedWordUnderCursor(tcursor); - - emit m_object->statusMessage(QObject::tr("Match found: %1 of %2") - .arg(idx + 1) - .arg(result.size())); - } - - return !result.isEmpty(); -} - -bool VEditor::findTextInRange(const QString &p_text, - uint p_options, - bool p_forward, - QTextCursor *p_cursor, - QTextCursor::MoveMode p_moveMode, - bool p_useLeftSideOfCursor, - int p_start, - int p_end) -{ - clearIncrementalSearchedWordHighlight(); - - if (p_text.isEmpty()) { - m_findInfo.clear(); - clearSearchedWordHighlight(); - return false; - } - - const QList &result = findTextAllCached(p_text, p_options, p_start, p_end); - - if (result.isEmpty()) { - clearSearchedWordHighlight(); - - emit m_object->statusMessage(QObject::tr("No match found")); - } else { - // Locate to the right match and update current cursor. - QTextCursor cursor = textCursorW(); - int pos = p_cursor ? p_cursor->position() : cursor.position(); - if (p_useLeftSideOfCursor) { - --pos; - } - - bool wrapped = false; - int idx = selectCursor(result, pos, p_forward, wrapped); - const QTextCursor &tcursor = result.at(idx); - if (wrapped) { - showWrapLabel(); - } - - if (p_cursor) { - p_cursor->setPosition(tcursor.selectionStart(), p_moveMode); - } else { - cursor.setPosition(tcursor.selectionStart(), p_moveMode); - setTextCursorW(cursor); - } - - highlightSearchedWord(result); - - highlightSearchedWordUnderCursor(tcursor); - - emit m_object->statusMessage(QObject::tr("Match found: %1 of %2") - .arg(idx + 1) - .arg(result.size())); - } - - return !result.isEmpty(); -} - -bool VEditor::findTextOne(const QString &p_text, uint p_options, bool p_forward) -{ - clearIncrementalSearchedWordHighlight(); - - if (p_text.isEmpty()) { - clearSearchedWordHighlight(); - return false; - } - - QTextCursor cursor = textCursorW(); - bool wrapped = false; - QTextCursor retCursor; - int start = cursor.position(); - bool found = findTextHelper(p_text, p_options, p_forward, start, wrapped, retCursor); - if (found) { - Q_ASSERT(!retCursor.isNull()); - if (wrapped) { - showWrapLabel(); - } - - cursor.setPosition(retCursor.selectionStart(), QTextCursor::MoveAnchor); - setTextCursorW(cursor); - - highlightSearchedWordUnderCursor(retCursor); - } else { - clearSearchedWordHighlight(); - } - - return found; -} - -bool VEditor::findTextInRange(const QString &p_text, - uint p_options, - bool p_forward, - int p_start, - int p_end) -{ - return findTextInRange(p_text, - p_options, - p_forward, - nullptr, - QTextCursor::MoveAnchor, - false, - p_start, - p_end); -} - -void VEditor::highlightIncrementalSearchedWord(const QTextCursor &p_cursor) -{ - QList &selects = m_extraSelections[(int)SelectionId::IncrementalSearchedKeyword]; - if (!g_config->getHighlightSearchedWord() || !p_cursor.hasSelection()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - selects.clear(); - QTextEdit::ExtraSelection select; - select.format.setForeground(m_incrementalSearchedWordFg); - select.format.setBackground(m_incrementalSearchedWordBg); - select.cursor = p_cursor; - selects.append(select); - - highlightExtraSelections(true); -} - -static bool isRegularExpressionSupported(const QRegExp &p_reg) -{ - if (!p_reg.isValid()) { - return false; - } - - // FIXME: hang bug in Qt's find(). - QRegExp test("[$^]+"); - if (test.exactMatch(p_reg.pattern())) { - return false; - } - - return true; -} - -// Use QPlainTextEdit::find() instead of QTextDocument::find() because the later has -// bugs in searching backward. -bool VEditor::findTextHelper(const QString &p_text, - uint p_options, - bool p_forward, - int p_start, - bool &p_wrapped, - QTextCursor &p_cursor) -{ - p_wrapped = false; - bool found = false; - - // Options - bool caseSensitive = p_options & FindOption::CaseSensitive; - QTextDocument::FindFlags findFlags = findOptionsToFlags(p_options, p_forward); - - // Use regular expression - bool useRegExp = p_options & FindOption::RegularExpression; - QRegExp exp; - if (useRegExp) { - useRegExp = true; - exp = QRegExp(p_text, - caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); - if (!isRegularExpressionSupported(exp)) { - return false; - } - } - - // Store current state of the cursor. - QTextCursor cursor = textCursorW(); - if (cursor.position() != p_start) { - if (p_start < 0) { - p_start = 0; - } else if (p_start > m_document->characterCount()) { - p_start = m_document->characterCount(); - } - } - - QTextCursor startCursor = cursor; - // Will clear the selection. - startCursor.setPosition(p_start); - setTextCursorW(startCursor); - - while (!found) { - if (useRegExp) { - found = findW(exp, findFlags); - } else { - found = findW(p_text, findFlags); - } - - if (p_wrapped) { - break; - } - - if (!found) { - // Wrap to the other end of the document to search again. - p_wrapped = true; - QTextCursor wrapCursor = textCursorW(); - if (p_forward) { - wrapCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - } else { - wrapCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); - } - - setTextCursorW(wrapCursor); - } - } - - if (found) { - p_cursor = textCursorW(); - } - - // Restore the original cursor. - setTextCursorW(cursor); - - return found; -} - -void VEditor::clearIncrementalSearchedWordHighlight(bool p_now) -{ - QList &selects = m_extraSelections[(int)SelectionId::IncrementalSearchedKeyword]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(p_now); -} - -void VEditor::clearSearchedWordHighlight() -{ - clearIncrementalSearchedWordHighlight(false); - clearSearchedWordUnderCursorHighlight(false); - - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(true); -} - -void VEditor::clearSearchedWordUnderCursorHighlight(bool p_now) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeywordUnderCursor]; - if (selects.isEmpty()) { - return; - } - - selects.clear(); - highlightExtraSelections(p_now); -} - -void VEditor::showWrapLabel() -{ - int labelW = m_wrapLabel->width(); - int labelH = m_wrapLabel->height(); - int x = (m_editor->width() - labelW) / 2; - int y = (m_editor->height() - labelH) / 2; - if (x < 0) { - x = 0; - } - - if (y < 0) { - y = 0; - } - - m_wrapLabel->move(x, y); - m_wrapLabel->show(); - m_labelTimer->stop(); - m_labelTimer->start(); -} - -void VEditor::highlightSearchedWord(const QList &p_matches) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeyword]; - if (!g_config->getHighlightSearchedWord() || p_matches.isEmpty()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - selects.clear(); - - QTextCharFormat format; - format.setForeground(m_searchedWordFg); - format.setBackground(m_searchedWordBg); - - for (int i = 0; i < p_matches.size(); ++i) { - QTextEdit::ExtraSelection select; - select.format = format; - select.cursor = p_matches[i]; - selects.append(select); - } - - highlightExtraSelections(); -} - -void VEditor::highlightSearchedWordUnderCursor(const QTextCursor &p_cursor) -{ - QList &selects = m_extraSelections[(int)SelectionId::SearchedKeywordUnderCursor]; - if (!p_cursor.hasSelection()) { - if (!selects.isEmpty()) { - selects.clear(); - highlightExtraSelections(true); - } - - return; - } - - selects.clear(); - QTextEdit::ExtraSelection select; - select.format.setForeground(m_searchedWordCursorFg); - select.format.setBackground(m_searchedWordCursorBg); - select.cursor = p_cursor; - selects.append(select); - - highlightExtraSelections(true); -} - -static void fillReplaceTextWithBackReference(QString &p_replaceText, - const QString &p_text, - const QRegExp &p_exp) -{ - int idx = p_exp.indexIn(p_text); - if (idx != 0) { - return; - } - - QStringList caps = p_exp.capturedTexts(); - if (caps.size() < 2) { - return; - } - - QChar sla('\\'); - int pos = 0; - while (pos < p_replaceText.size()) { - int idx = p_replaceText.indexOf(sla, pos); - if (idx == -1 || idx == p_replaceText.size() - 1) { - break; - } - - QChar ne(p_replaceText[idx + 1]); - if (ne == sla) { - // \\ to \. - p_replaceText.remove(idx, 1); - } else if (ne.isDigit()) { - // TODO: for now, we only support 1 - 9. - int num = ne.digitValue(); - if (num > 0 && num < caps.size()) { - // Replace it. - p_replaceText.replace(idx, 2, caps[num]); - pos = idx + caps[num].size() - 2; - continue; - } - } - - pos = idx + 1; - } -} - -void VEditor::replaceText(const QString &p_text, - uint p_options, - const QString &p_replaceText, - bool p_findNext) -{ - QTextCursor cursor = textCursorW(); - bool wrapped = false; - QTextCursor retCursor; - QString newText(p_replaceText); - bool useRegExp = p_options & FindOption::RegularExpression; - QRegExp exp; - if (useRegExp) { - exp = QRegExp(p_text, - (p_options & FindOption::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive); - } - - bool found = findTextHelper(p_text, - p_options, - true, - cursor.position(), - wrapped, - retCursor); - if (found) { - if (retCursor.selectionStart() == cursor.position()) { - // Matched. - if (useRegExp) { - // Handle \1, \2 in replace text. - fillReplaceTextWithBackReference(newText, - VEditUtils::selectedText(retCursor), - exp); - } - - retCursor.beginEditBlock(); - retCursor.insertText(newText); - retCursor.endEditBlock(); - setTextCursorW(retCursor); - } - - if (p_findNext) { - findTextOne(p_text, p_options, true); - } - } -} - -void VEditor::replaceTextAll(const QString &p_text, - uint p_options, - const QString &p_replaceText) -{ - // Replace from the start to the end and restore the cursor. - QTextCursor cursor = textCursorW(); - int nrReplaces = 0; - QTextCursor tmpCursor = cursor; - tmpCursor.setPosition(0); - setTextCursorW(tmpCursor); - int start = tmpCursor.position(); - - QString newText; - bool useRegExp = p_options & FindOption::RegularExpression; - QRegExp exp; - if (useRegExp) { - exp = QRegExp(p_text, - (p_options & FindOption::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive); - } else { - newText = p_replaceText; - } - - while (true) { - bool wrapped = false; - QTextCursor retCursor; - bool found = findTextHelper(p_text, - p_options, - true, - start, - wrapped, - retCursor); - if (!found) { - break; - } else { - if (wrapped) { - // Wrap back. - break; - } - - if (useRegExp) { - newText = p_replaceText; - fillReplaceTextWithBackReference(newText, - VEditUtils::selectedText(retCursor), - exp); - } - - nrReplaces++; - retCursor.beginEditBlock(); - retCursor.insertText(newText); - retCursor.endEditBlock(); - setTextCursorW(retCursor); - start = retCursor.position(); - } - } - - // Restore cursor position. - cursor.clearSelection(); - setTextCursorW(cursor); - qDebug() << "replace all" << nrReplaces << "occurences"; - - emit m_object->statusMessage(QObject::tr("Replace %1 %2").arg(nrReplaces) - .arg(nrReplaces > 1 ? QObject::tr("occurences") - : QObject::tr("occurence"))); -} - -void VEditor::evaluateMagicWords() -{ - QString text; - QTextCursor cursor = textCursorW(); - if (!cursor.hasSelection()) { - // Get the WORD in current cursor. - int start, end; - VEditUtils::findCurrentWORD(cursor, start, end); - - if (start == end) { - return; - } else { - cursor.setPosition(start); - cursor.setPosition(end, QTextCursor::KeepAnchor); - } - } - - text = VEditUtils::selectedText(cursor); - Q_ASSERT(!text.isEmpty()); - QString evaText = g_mwMgr->evaluate(text); - if (text != evaText) { - qDebug() << "evaluateMagicWords" << text << evaText; - - cursor.insertText(evaText); - - if (m_editOps) { - m_editOps->setVimMode(VimMode::Insert); - } - - setTextCursorW(cursor); - } -} - -void VEditor::setReadOnlyAndHighlightCurrentLine(bool p_readonly) -{ - setReadOnlyW(p_readonly); - highlightCurrentLine(); -} - -bool VEditor::handleMousePressEvent(QMouseEvent *p_event) -{ - if (p_event->button() == Qt::LeftButton - && p_event->modifiers() == Qt::ControlModifier - && !textCursorW().hasSelection()) { - m_oriMouseX = p_event->x(); - m_oriMouseY = p_event->y(); - m_readyToScroll = true; - m_mouseMoveScrolled = false; - p_event->accept(); - return true; - } - - m_readyToScroll = false; - m_mouseMoveScrolled = false; - - return false; -} - -bool VEditor::handleMouseReleaseEvent(QMouseEvent *p_event) -{ - if (m_mouseMoveScrolled || m_readyToScroll) { - viewportW()->setCursor(Qt::IBeamCursor); - m_readyToScroll = false; - m_mouseMoveScrolled = false; - p_event->accept(); - return true; - } - - m_readyToScroll = false; - m_mouseMoveScrolled = false; - - return false; -} - -bool VEditor::handleMouseMoveEvent(QMouseEvent *p_event) -{ - const int threshold = 5; - - if (m_readyToScroll) { - int deltaX = p_event->x() - m_oriMouseX; - int deltaY = p_event->y() - m_oriMouseY; - - if (qAbs(deltaX) >= threshold || qAbs(deltaY) >= threshold) { - m_oriMouseX = p_event->x(); - m_oriMouseY = p_event->y(); - - if (!m_mouseMoveScrolled) { - m_mouseMoveScrolled = true; - viewportW()->setCursor(Qt::SizeAllCursor); - } - - QScrollBar *verBar = verticalScrollBarW(); - QScrollBar *horBar = horizontalScrollBarW(); - if (verBar->isVisible()) { - verBar->setValue(verBar->value() - deltaY); - } - - if (horBar->isVisible()) { - horBar->setValue(horBar->value() - deltaX); - } - } - - p_event->accept(); - return true; - } - - return false; -} - -bool VEditor::handleWheelEvent(QWheelEvent *p_event) -{ - Qt::KeyboardModifiers modifiers = p_event->modifiers(); - if (modifiers == Qt::ShiftModifier) { - // Scroll horizontally. - QPoint numPixels = p_event->pixelDelta(); - QPoint numDegrees = p_event->angleDelta() / 8; - - QScrollBar *horBar = horizontalScrollBarW(); - int steps = 0; - if (!numPixels.isNull()) { - steps = numPixels.y(); - } else if (!numDegrees.isNull()) { - QPoint numSteps = numDegrees / 15; - steps = numSteps.y() * horBar->singleStep(); - } - - if (horBar->minimum() != horBar->maximum()) { - horBar->setValue(horBar->value() - steps); - } - - p_event->accept(); - return true; - } else if (modifiers == Qt::ControlModifier) { - // Zoom in/out. - QPoint angle = p_event->angleDelta(); - if (!angle.isNull() && (angle.y() != 0)) { - if (angle.y() > 0) { - zoomInW(); - } else { - zoomOutW(); - } - } - - p_event->accept(); - return true; - } - - return false; -} - -void VEditor::requestUpdateVimStatus() -{ - if (m_editOps) { - m_editOps->requestUpdateVimStatus(); - } else { - emit m_object->vimStatusUpdated(NULL); - } -} - -bool VEditor::handleInputMethodQuery(Qt::InputMethodQuery p_query, - QVariant &p_var) const -{ - if (p_query == Qt::ImEnabled) { - p_var = m_enableInputMethod; - return true; - } - - return false; -} - -void VEditor::setInputMethodEnabled(bool p_enabled) -{ - if (m_enableInputMethod != p_enabled) { - m_enableInputMethod = p_enabled; - - QInputMethod *im = QGuiApplication::inputMethod(); - im->reset(); - - // Ask input method to query current state, which will call inputMethodQuery(). - im->update(Qt::ImEnabled); - } -} - -void VEditor::decorateText(TextDecoration p_decoration, int p_level) -{ - if (m_editOps) { - m_editOps->decorateText(p_decoration, p_level); - } -} - -void VEditor::updateConfig() -{ - updateEditConfig(); -} - -void VEditor::setVimMode(VimMode p_mode) -{ - if (m_editOps) { - m_editOps->setVimMode(p_mode); - } -} - -VVim *VEditor::getVim() const -{ - if (m_editOps) { - return m_editOps->getVim(); - } - - return NULL; -} - -bool VEditor::setCursorPosition(int p_blockNumber, int p_posInBlock) -{ - QTextDocument *doc = documentW(); - QTextBlock block = doc->findBlockByNumber(p_blockNumber); - if (!block.isValid() || block.length() <= p_posInBlock) { - return false; - } - - QTextCursor cursor = textCursorW(); - cursor.setPosition(block.position() + p_posInBlock); - setTextCursorW(cursor); - return true; -} - -static Qt::CaseSensitivity completionCaseSensitivity(const QString &p_text) -{ - bool upperCase = false; - for (int i = 0; i < p_text.size(); ++i) { - if (p_text[i].isUpper()) { - upperCase = true; - break; - } - } - - return upperCase ? Qt::CaseSensitive : Qt::CaseInsensitive; -} - -void VEditor::requestCompletion(bool p_reversed) -{ - QTextCursor cursor = textCursorW(); - cursor.clearSelection(); - setTextCursorW(cursor); - - QStringList words = generateCompletionCandidates(p_reversed); - QString prefix = fetchCompletionPrefix(); - // Smart case. - Qt::CaseSensitivity cs = completionCaseSensitivity(prefix); - - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, prefix.size()); - QRect popupRect = cursorRectW(cursor); - popupRect.setLeft(popupRect.left() + lineNumberAreaWidth()); - - m_completer->performCompletion(words, prefix, cs, p_reversed, popupRect, this); -} - -bool VEditor::isCompletionActivated() const -{ - if (m_completer->widget() == m_editor - && m_completer->isPopupVisible()) { - return true; - } - - return false; -} - -QStringList VEditor::generateCompletionCandidates(bool p_reversed) const -{ - QString content = getContent(); - QTextCursor cursor = textCursorW(); - int start, end; - VEditUtils::findCurrentWord(cursor, start, end, true); - - QRegExp reg("\\W+"); - - QStringList above = content.left(start).split(reg, QString::SkipEmptyParts); - QStringList below = content.mid(end).split(reg, QString::SkipEmptyParts); - - if (p_reversed) { - QStringList rev; - rev.reserve(above.size() + below.size()); - for (auto it = above.rbegin(); it != above.rend(); ++it) { - rev.append(*it); - } - - for (auto it = below.rbegin(); it != below.rend(); ++it) { - rev.append(*it); - } - - rev.removeDuplicates(); - - QStringList res; - res.reserve(rev.size()); - for (auto it = rev.rbegin(); it != rev.rend(); ++it) { - res.append(*it); - } - - return res; - } else { - // below + above. - below.append(above); - below.removeDuplicates(); - return below; - } -} - -QString VEditor::fetchCompletionPrefix() const -{ - QTextCursor cursor = textCursorW(); - if (cursor.atBlockStart()) { - return QString(); - } - - int pos = cursor.position() - 1; - int blockPos = cursor.block().position(); - QString prefix; - while (pos >= blockPos) { - QChar ch = m_document->characterAt(pos); - if (VEditUtils::isSpaceOrWordSeparator(ch)) { - break; - } - - prefix.prepend(ch); - --pos; - } - - return prefix; -} - -// @p_prefix may be longer than @p_completion. -void VEditor::insertCompletion(const QString &p_prefix, const QString &p_completion) -{ - QTextCursor cursor = textCursorW(); - - cursor.joinPreviousEditBlock(); - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, p_prefix.size()); - cursor.insertText(p_completion); - cursor.endEditBlock(); - - setTextCursorW(cursor); -} - -QList VEditor::findTextAllInRange(const QTextDocument *p_doc, - const QString &p_text, - QTextDocument::FindFlags p_flags, - int p_start, - int p_end) -{ - QList results; - if (p_text.isEmpty()) { - return results; - } - - int start = p_start; - int end = p_end == -1 ? p_doc->characterCount() + 1 : p_end; - - while (start < end) { - QTextCursor cursor = p_doc->find(p_text, start, p_flags); - if (cursor.isNull()) { - break; - } else { - start = cursor.selectionEnd(); - if (start <= end) { - results.append(cursor); - } - } - } - - return results; -} - -QList VEditor::findTextAllInRange(const QTextDocument *p_doc, - const QRegExp &p_reg, - QTextDocument::FindFlags p_flags, - int p_start, - int p_end) -{ - QList results; - if (!isRegularExpressionSupported(p_reg)) { - return results; - } - - int start = p_start; - int end = p_end == -1 ? p_doc->characterCount() + 1 : p_end; - - while (start < end) { - QTextCursor cursor = p_doc->find(p_reg, start, p_flags); - if (cursor.isNull()) { - break; - } else { - start = cursor.selectionEnd(); - if (start <= end) { - results.append(cursor); - } - } - } - - return results; -} - -void VEditor::clearFindCache() -{ - m_findInfo.clearResult(); -} - -void VEditor::nextMatch(bool p_forward) -{ - if (m_findInfo.isNull()) { - return; - } - - if (m_findInfo.m_useToken) { - findText(m_findInfo.m_token, p_forward, false); - } else { - findTextInRange(m_findInfo.m_text, - m_findInfo.m_options, - p_forward, - m_findInfo.m_start, - m_findInfo.m_end); - } -} - -void VEditor::pastePlainText() -{ - if (!m_file || !m_file->isModifiable()) { - return; - } - - QClipboard *clipboard = QApplication::clipboard(); - QString text(clipboard->text()); - if (text.isEmpty()) { - return; - } - - m_editOps->insertText(text); -} - -void VEditor::scrollCursorLineIfNecessary() -{ - bool moved = false; - QTextCursor cursor = textCursorW(); - int mode = g_config->getAutoScrollCursorLine(); - switch (mode) { - case AutoScrollEndOfDoc: - V_FALLTHROUGH; - case AutoScrollAlways: - { - const int bc = m_document->blockCount(); - int bn = cursor.blockNumber(); - int margin = -1; - if (mode == AutoScrollAlways) { - margin = m_editor->rect().height() / 8; - } else if (bn == bc - 1) { - margin = m_editor->rect().height() / 4; - } - - if (margin > -1) { - moved = true; - scrollBlockInPage(bn, 1, margin); - } - - break; - } - - default: - break; - } - - if (!moved) { - makeBlockVisible(cursor.block()); - } -} - -QFont VEditor::getFont() const -{ - return m_editor->font(); -} diff --git a/src/veditor.h b/src/veditor.h deleted file mode 100644 index ebcd7bb1..00000000 --- a/src/veditor.h +++ /dev/null @@ -1,677 +0,0 @@ -#ifndef VEDITOR_H -#define VEDITOR_H - -#include -#include -#include -#include -#include -#include - -#include "veditconfig.h" -#include "vconstants.h" -#include "vfile.h" -#include "vwordcountinfo.h" -#include "vtexteditcompleter.h" -#include "vsearchconfig.h" - -class QWidget; -class VEditorObject; -class VEditOperations; -class QTimer; -class QLabel; -class VVim; -enum class VimMode; -class QMouseEvent; - - -enum class SelectionId { - CurrentLine = 0, - SelectedWord, - SearchedKeyword, - SearchedKeywordUnderCursor, - IncrementalSearchedKeyword, - TrailingSpace, - Tab, - MaxSelection -}; - - -// Abstract class for an edit. -// Should inherit this class as well as QPlainTextEdit or QTextEdit. -// Will replace VEdit eventually. -class VEditor -{ -public: - explicit VEditor(VFile *p_file, - QWidget *p_editor, - const QSharedPointer &p_completer); - - virtual ~VEditor(); - - void highlightCurrentLine(); - - virtual void beginEdit() = 0; - - virtual void endEdit() = 0; - - // Save buffer content to VFile. - virtual void saveFile() = 0; - - virtual void reloadFile() = 0; - - virtual bool scrollToBlock(int p_blockNumber) = 0; - - bool isModified() const; - - void setModified(bool p_modified); - - // User requests to insert an image. - void insertImage(); - - // User requests to insert a link. - void insertLink(); - - // User requests to insert a table. - virtual void insertTable() = 0; - - // Used for incremental search. - // User has enter the content to search, but does not enter the "find" button yet. - bool peekText(const QString &p_text, uint p_options, bool p_forward = true); - - // If @p_cursor is not null, set the position of @p_cursor instead of current - // cursor. - bool findText(const QString &p_text, - uint p_options, - bool p_forward, - QTextCursor *p_cursor = nullptr, - QTextCursor::MoveMode p_moveMode = QTextCursor::MoveAnchor, - bool p_useLeftSideOfCursor = false); - - bool findText(const VSearchToken &p_token, bool p_forward, bool p_fromStart); - - // Constrain the scope. - bool findTextInRange(const QString &p_text, - uint p_options, - bool p_forward, - int p_start, - int p_end); - - void replaceText(const QString &p_text, - uint p_options, - const QString &p_replaceText, - bool p_findNext); - - void replaceTextAll(const QString &p_text, - uint p_options, - const QString &p_replaceText); - - // Use m_findInfo to find next match. - void nextMatch(bool p_forward = false); - - // Scroll the content to make @p_block visible. - // If the @p_block is too long to hold in one page, just let it occupy the - // whole page. - // Will not change current cursor. - virtual void makeBlockVisible(const QTextBlock &p_block) = 0; - - // Clear IncrementalSearchedKeyword highlight. - void clearIncrementalSearchedWordHighlight(bool p_now = true); - - // Clear SearchedKeyword highlight. - void clearSearchedWordHighlight(); - - // Clear SearchedKeywordUnderCursor Highlight. - void clearSearchedWordUnderCursorHighlight(bool p_now = true); - - // Evaluate selected text or cursor word as magic words. - void evaluateMagicWords(); - - VFile *getFile() const; - - VEditConfig &getConfig(); - - // Request to update Vim status. - void requestUpdateVimStatus(); - - // Jump to a title. - // @p_forward: jump forward or backward. - // @p_relativeLevel: 0 for the same level as current header; - // negative value for upper level; - // positive value is ignored. - // Returns true if the jump succeeded. - virtual bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) = 0; - - void setInputMethodEnabled(bool p_enabled); - - // Insert decoration markers or decorate selected text. - void decorateText(TextDecoration p_decoration, int p_level); - - virtual bool isBlockVisible(const QTextBlock &p_block) = 0; - - VEditorObject *object() const; - - QWidget *getEditor() const; - - // Scroll block @p_blockNum into the visual window. - // @p_dest is the position of the window: 0 for top, 1 for center, 2 for bottom. - // @p_blockNum is based on 0. - // Will set the cursor to the block. - virtual void scrollBlockInPage(int p_blockNum, int p_dest, int p_margin = 0) = 0; - - // Update config according to global configurations. - virtual void updateConfig(); - - void setVimMode(VimMode p_mode); - - VVim *getVim() const; - - virtual QString getContent() const = 0; - - // @p_modified: if true, delete the whole content and insert the new content. - virtual void setContent(const QString &p_content, bool p_modified = false) = 0; - - virtual VWordCountInfo fetchWordCountInfo() const = 0; - - virtual bool setCursorPosition(int p_blockNumber, int p_posInBlock); - - QString fetchCompletionPrefix() const; - - // Request text completion. - virtual void requestCompletion(bool p_reversed); - - virtual bool isCompletionActivated() const; - - virtual void insertCompletion(const QString &p_prefix, const QString &p_completion); - - QFont getFont() const; - - virtual void updateFontAndPalette() = 0; - -// Wrapper functions for QPlainTextEdit/QTextEdit. -// Ends with W to distinguish it from the original interfaces. -public: - virtual void setExtraSelectionsW(const QList &p_selections) = 0; - - virtual QTextDocument *documentW() const = 0; - - virtual int tabStopWidthW() const = 0; - - virtual void setTabStopWidthW(int p_width) = 0; - - virtual QTextCursor textCursorW() const = 0; - - virtual void setTextCursorW(const QTextCursor &p_cursor) = 0; - - virtual void moveCursorW(QTextCursor::MoveOperation p_operation, - QTextCursor::MoveMode p_mode = QTextCursor::MoveAnchor) = 0; - - virtual QScrollBar *verticalScrollBarW() const = 0; - - virtual QScrollBar *horizontalScrollBarW() const = 0; - - virtual bool findW(const QString &p_exp, - QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) = 0; - - virtual bool findW(const QRegExp &p_exp, - QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) = 0; - - virtual bool isReadOnlyW() const = 0; - virtual void setReadOnlyW(bool p_ro) = 0; - - virtual QWidget *viewportW() const = 0; - - virtual void insertPlainTextW(const QString &p_text) = 0; - - virtual void undoW() = 0; - - virtual void redoW() = 0; - - // Whether display cursor as block. - virtual void setCursorBlockModeW(CursorBlock p_mode) = 0; - - virtual void zoomInW(int p_range = 1) = 0; - - virtual void zoomOutW(int p_range = 1) = 0; - - virtual void ensureCursorVisibleW() = 0; - - virtual QRect cursorRectW() = 0; - - virtual QRect cursorRectW(const QTextCursor &p_cursor) = 0; - -protected: - void init(); - - // Update m_config according to VConfigManager. - void updateEditConfig(); - - // Do some highlight on cursor position changed. - void highlightOnCursorPositionChanged(); - - void updateTimeStamp(); - - // Highlight selected text. - void highlightSelectedWord(); - - bool wordInSearchedSelection(const QString &p_text); - - // Set read-only property and highlight current line. - void setReadOnlyAndHighlightCurrentLine(bool p_readonly); - - // Handle the mouse press event of m_editor. - // Returns true if no further process is needed. - bool handleMousePressEvent(QMouseEvent *p_event); - - bool handleMouseReleaseEvent(QMouseEvent *p_event); - - bool handleMouseMoveEvent(QMouseEvent *p_event); - - bool handleInputMethodQuery(Qt::InputMethodQuery p_query, - QVariant &p_var) const; - - bool handleWheelEvent(QWheelEvent *p_event); - - virtual int lineNumberAreaWidth() const = 0; - - void addTempFile(const QString &p_file); - - // Paste plain text. - void pastePlainText(); - - // Scroll cursor line if in need. - void scrollCursorLineIfNecessary(); - - QWidget *m_editor; - - VEditorObject *m_object; - - QPointer m_file; - - VEditOperations *m_editOps; - - VEditConfig m_config; - -private: - friend class VEditorObject; - - // Info about one find-in-page. - struct FindInfo - { - FindInfo() - : m_start(0), - m_end(-1), - m_useToken(false), - m_options(0), - m_cacheValid(false) - { - } - - void clear() - { - m_start = 0; - m_end = -1; - - m_useToken = false; - - m_text.clear(); - m_options = 0; - - m_token.clear(); - - m_cacheValid = false; - m_result.clear(); - } - - void clearResult() - { - m_cacheValid = false; - m_result.clear(); - } - - bool isCached(const QString &p_text, - uint p_options, - int p_start = 0, - int p_end = -1) const - { - return m_cacheValid - && !m_useToken - && m_text == p_text - && m_options == p_options - && m_start == p_start - && m_end == p_end; - } - - bool isCached(const VSearchToken &p_token, - int p_start = 0, - int p_end = -1) const - { - return m_cacheValid - && m_useToken - && m_token == p_token - && m_start == p_start - && m_end == p_end; - } - - void update(const QString &p_text, - uint p_options, - int p_start, - int p_end, - const QList &p_result) - { - m_start = p_start; - m_end = p_end; - - m_useToken = false; - - m_text = p_text; - m_options = p_options; - - m_cacheValid = true; - m_result = p_result; - - m_token.clear(); - } - - void update(const VSearchToken &p_token, - int p_start, - int p_end, - const QList &p_result) - { - m_start = p_start; - m_end = p_end; - - m_useToken = true; - - m_token = p_token; - - m_cacheValid = true; - m_result = p_result; - - m_text.clear(); - m_options = 0; - } - - bool isNull() const - { - if (m_useToken) { - return m_token.isEmpty(); - } else { - return m_text.isEmpty(); - } - } - - // Find in [m_start, m_end). - int m_start; - int m_end; - - bool m_useToken; - - // Use text and options to search. - QString m_text; - uint m_options; - - // Use token to search. - VSearchToken m_token; - - bool m_cacheValid; - - QList m_result; - }; - - // Filter out the trailing space right before cursor. - void filterTrailingSpace(QList &p_selects, - const QList &p_src); - - // Trigger the timer to request highlight. - // If @p_now is true, stop the timer and highlight immediately. - void highlightExtraSelections(bool p_now = false); - - // @p_fileter: a function to filter out highlight results. - void highlightTextAll(const QString &p_text, - uint p_options, - SelectionId p_id, - QTextCharFormat p_format, - void (*p_filter)(VEditor *, - QList &) = NULL); - - // Find all the occurences of @p_text. - QList findTextAll(const QString &p_text, - uint p_options, - int p_start = 0, - int p_end = -1); - - QList findTextAll(const VSearchToken &p_token, - int p_start = 0, - int p_end = -1); - - const QList &findTextAllCached(const QString &p_text, - uint p_options, - int p_start = 0, - int p_end = -1); - - const QList &findTextAllCached(const VSearchToken &p_token, - int p_start = 0, - int p_end = -1); - - // Highlight @p_cursor as the incremental searched keyword. - void highlightIncrementalSearchedWord(const QTextCursor &p_cursor); - - // Find @p_text in the document starting from @p_start. - // Returns true if @p_text is found and set @p_cursor to indicate - // the position. - // Will NOT change current cursor. - bool findTextHelper(const QString &p_text, - uint p_options, - bool p_forward, - int p_start, - bool &p_wrapped, - QTextCursor &p_cursor); - - void showWrapLabel(); - - void highlightSearchedWord(const QList &p_matches); - - // Highlight @p_cursor as the searched keyword under cursor. - void highlightSearchedWordUnderCursor(const QTextCursor &p_cursor); - - QStringList generateCompletionCandidates(bool p_reversed) const; - - void cleanUp(); - - bool findTextOne(const QString &p_text, uint p_options, bool p_forward); - - // @p_end, -1 indicates the end of doc. - static QList findTextAllInRange(const QTextDocument *p_doc, - const QString &p_text, - QTextDocument::FindFlags p_flags, - int p_start = 0, - int p_end = -1); - - static QList findTextAllInRange(const QTextDocument *p_doc, - const QRegExp &p_reg, - QTextDocument::FindFlags p_flags, - int p_start = 0, - int p_end = -1); - - bool findTextInRange(const QString &p_text, - uint p_options, - bool p_forward, - QTextCursor *p_cursor = nullptr, - QTextCursor::MoveMode p_moveMode = QTextCursor::MoveAnchor, - bool p_useLeftSideOfCursor = false, - int p_start = 0, - int p_end = -1); - - void updateTrailingSpaceAndTabHighlights(); - - bool needUpdateTrailingSpaceAndTabHighlights(); - - QLabel *m_wrapLabel; - QTimer *m_labelTimer; - - QTextDocument *m_document; - - // doHighlightExtraSelections() will highlight these selections. - // Selections are indexed by SelectionId. - QVector > m_extraSelections; - - QColor m_selectedWordFg; - QColor m_selectedWordBg; - - QColor m_searchedWordFg; - QColor m_searchedWordBg; - - QColor m_searchedWordCursorFg; - QColor m_searchedWordCursorBg; - - QColor m_incrementalSearchedWordFg; - QColor m_incrementalSearchedWordBg; - - QColor m_trailingSpaceColor; - QColor m_tabColor; - - // Timer for extra selections highlight. - QTimer *m_highlightTimer; - - // Timer for update trailing space. - QTimer *m_trailingSpaceTimer; - - bool m_readyToScroll; - bool m_mouseMoveScrolled; - int m_oriMouseX; - int m_oriMouseY; - - // Whether enable input method. - bool m_enableInputMethod; - - TimeStamp m_timeStamp; - - TimeStamp m_trailingSpaceSelectionTS; - - QSharedPointer m_completer; - - // Temp files needed to be delete. - QStringList m_tempFiles; - - FindInfo m_findInfo; - - bool m_trailingSpaceHighlightEnabled; - bool m_tabHighlightEnabled; - -// Functions for private slots. -private: - void labelTimerTimeout(); - - // Do the real work to highlight extra selections. - void doHighlightExtraSelections(); - - void doUpdateTrailingSpaceAndTabHighlights(); - - void clearFindCache(); -}; - - -// Since one class could not inherit QObject multiple times, we use this class -// for VEditor to signal/slot. -class VEditorObject : public QObject -{ - Q_OBJECT -public: - explicit VEditorObject(VEditor *p_editor, QObject *p_parent = nullptr) - : QObject(p_parent), m_editor(p_editor) - { - } - -signals: - // Emit when editor config has been updated. - void configUpdated(); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - // Request VEditTab to save and exit edit mode. - void saveAndRead(); - - // Request VEditTab to discard and exit edit mode. - void discardAndRead(); - - // Request VEditTab to edit current note. - void editNote(); - - // Request VEditTab to save this file. - void saveNote(); - - // Emit when Vim status updated. - void vimStatusUpdated(const VVim *p_vim); - - // Emit when all initialization is ready. - void ready(); - - // Request the edit tab to close find and replace dialog. - void requestCloseFindReplaceDialog(); - - void mouseMoved(QMouseEvent *p_event); - - void mousePressed(QMouseEvent *p_event); - - void mouseReleased(QMouseEvent *p_event); - - void mouseDoubleClicked(QMouseEvent *p_event); - - void cursorPositionChanged(); - -private slots: - // Timer for find-wrap label. - void labelTimerTimeout() - { - m_editor->labelTimerTimeout(); - } - - // Do the real work to highlight extra selections. - void doHighlightExtraSelections() - { - m_editor->doHighlightExtraSelections(); - } - - void doUpdateTrailingSpaceAndTabHighlights() - { - m_editor->doUpdateTrailingSpaceAndTabHighlights(); - } - - void clearFindCache() - { - m_editor->clearFindCache(); - } - -private: - friend class VEditor; - - VEditor *m_editor; -}; - -inline VFile *VEditor::getFile() const -{ - return m_file; -} - -inline VEditConfig &VEditor::getConfig() -{ - return m_config; -} - -inline VEditorObject *VEditor::object() const -{ - return m_object; -} - -inline QWidget *VEditor::getEditor() const -{ - return m_editor; -} - -inline void VEditor::addTempFile(const QString &p_file) -{ - m_tempFiles.append(p_file); -} -#endif // VEDITOR_H diff --git a/src/vedittab.cpp b/src/vedittab.cpp deleted file mode 100644 index e9f572ea..00000000 --- a/src/vedittab.cpp +++ /dev/null @@ -1,268 +0,0 @@ -#include "vedittab.h" -#include -#include - -#include "utils/vutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VEditTab::VEditTab(VFile *p_file, VEditArea *p_editArea, QWidget *p_parent) - : QWidget(p_parent), - m_file(p_file), - m_isEditMode(false), - m_outline(p_file), - m_currentHeader(p_file, -1), - m_editArea(p_editArea), - m_checkFileChange(true), - m_fileDiverged(false), - m_ready(0), - m_enableBackupFile(g_config->getEnableBackupFile()) -{ - connect(qApp, &QApplication::focusChanged, - this, &VEditTab::handleFocusChanged); -} - -VEditTab::~VEditTab() -{ - if (m_file) { - m_file->close(); - } -} - -void VEditTab::focusTab() -{ - focusChild(); - emit getFocused(); - updateStatus(); -} - -bool VEditTab::isEditMode() const -{ - return m_isEditMode; -} - -bool VEditTab::isModified() const -{ - return false; -} - -VFile *VEditTab::getFile() const -{ - return m_file; -} - -void VEditTab::handleFocusChanged(QWidget * /* p_old */, QWidget *p_now) -{ - if (p_now == this) { - // When VEditTab get focus, it should focus to current widget. - focusChild(); - - emit getFocused(); - updateStatus(); - } else if (isAncestorOf(p_now)) { - emit getFocused(); - updateStatus(); - } -} - -void VEditTab::wheelEvent(QWheelEvent *p_event) -{ - if (p_event->modifiers() & Qt::ControlModifier) { - QPoint angle = p_event->angleDelta(); - if (!angle.isNull() && (angle.y() != 0)) { - // Zoom in/out current tab. - zoom(angle.y() > 0); - } - - p_event->accept(); - return; - } - - QWidget::wheelEvent(p_event); -} - -VEditTabInfo VEditTab::fetchTabInfo(VEditTabInfo::InfoType p_type) const -{ - VEditTabInfo info; - info.m_type = p_type; - info.m_editTab = const_cast(this); - - return info; -} - -const VHeaderPointer &VEditTab::getCurrentHeader() const -{ - return m_currentHeader; -} - -const VTableOfContent &VEditTab::getOutline() const -{ - return m_outline; -} - -void VEditTab::tryRestoreFromTabInfo(const VEditTabInfo &p_info) -{ - if (p_info.m_editTab != this) { - m_infoToRestore.clear(); - return; - } - - if (restoreFromTabInfo(p_info)) { - m_infoToRestore.clear(); - return; - } - - // Save it and restore later. - m_infoToRestore = p_info; -} - -void VEditTab::updateStatus() -{ - emit statusUpdated(fetchTabInfo()); -} - -void VEditTab::evaluateMagicWords() -{ -} - -bool VEditTab::tabHasFocus() const -{ - QWidget *wid = QApplication::focusWidget(); - return wid == this || isAncestorOf(wid); -} - -void VEditTab::insertLink() -{ -} - -void VEditTab::insertTable() -{ -} - -void VEditTab::applySnippet(const VSnippet *p_snippet) -{ - Q_UNUSED(p_snippet); -} - -void VEditTab::applySnippet() -{ -} - -void VEditTab::checkFileChangeOutside() -{ - if (!m_checkFileChange) { - return; - } - - bool missing = false; - if (m_file->isChangedOutside(missing)) { - // It may be caused by cutting files. - if (missing) { - qWarning() << "file is missing when check file's outside change" << m_file->fetchPath(); - return; - } - - int ret = VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Note %2 has been modified by another program.") - .arg(g_config->c_dataTextStyle).arg(m_file->fetchPath()), - tr("Do you want to reload it?"), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::Yes, - this); - switch (ret) { - case QMessageBox::Yes: - reloadFromDisk(); - break; - - case QMessageBox::No: - m_checkFileChange = false; - m_fileDiverged = true; - updateStatus(); - break; - - default: - Q_ASSERT(false); - break; - } - } -} - -void VEditTab::reloadFromDisk() -{ - bool ret = m_file->reload(); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to reload note %2.") - .arg(g_config->c_dataTextStyle).arg(m_file->getName()), - tr("Please check if file %1 exists.").arg(m_file->fetchPath()), - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - m_fileDiverged = !ret; - m_checkFileChange = ret; - - reload(); -} - -void VEditTab::writeBackupFile() -{ -} - -void VEditTab::handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act) -{ - Q_UNUSED(p_isFile); - Q_UNUSED(p_act); -} - -void VEditTab::handleVimCmdCommandCancelled() -{ - -} - -void VEditTab::handleVimCmdCommandFinished(VVim::CommandLineType p_type, const QString &p_cmd) -{ - Q_UNUSED(p_type); - Q_UNUSED(p_cmd); -} - -void VEditTab::handleVimCmdCommandChanged(VVim::CommandLineType p_type, const QString &p_cmd) -{ - Q_UNUSED(p_type); - Q_UNUSED(p_cmd); -} - -QString VEditTab::handleVimCmdRequestNextCommand(VVim::CommandLineType p_type, const QString &p_cmd) -{ - Q_UNUSED(p_type); - Q_UNUSED(p_cmd); - - return QString(); -} - -QString VEditTab::handleVimCmdRequestPreviousCommand(VVim::CommandLineType p_type, const QString &p_cmd) -{ - Q_UNUSED(p_type); - Q_UNUSED(p_cmd); - - return QString(); -} - -QString VEditTab::handleVimCmdRequestRegister(int p_key, int p_modifiers) -{ - Q_UNUSED(p_key); - Q_UNUSED(p_modifiers); - - return QString(); -} - -VWordCountInfo VEditTab::fetchWordCountInfo(bool p_editMode) const -{ - Q_UNUSED(p_editMode); - - return VWordCountInfo(); -} diff --git a/src/vedittab.h b/src/vedittab.h deleted file mode 100644 index ca045d1a..00000000 --- a/src/vedittab.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef VEDITTAB_H -#define VEDITTAB_H - -#include -#include -#include -#include "vtableofcontent.h" -#include "vfile.h" -#include "utils/vvim.h" -#include "vedittabinfo.h" -#include "vwordcountinfo.h" -#include "vsearchconfig.h" - -class VEditArea; -class VSnippet; - -// VEditTab is the base class of an edit tab inside VEditWindow. -class VEditTab : public QWidget -{ - Q_OBJECT - -public: - VEditTab(VFile *p_file, VEditArea *p_editArea, QWidget *p_parent = 0); - - virtual ~VEditTab(); - - // Close current tab. - // @p_forced: if true, discard the changes. - virtual bool closeFile(bool p_forced) = 0; - - // Enter read mode. - // @p_discard: whether set the discard action as the default one. - virtual void readFile(bool p_discard = false) = 0; - - // Save file. - virtual bool saveFile() = 0; - - bool isEditMode() const; - - virtual bool isModified() const; - - void focusTab(); - - // Whether this tab has focus. - bool tabHasFocus() const; - - // Scroll to @p_header. - // Will emit currentHeaderChanged() if @p_header is valid. - virtual void scrollToHeader(const VHeaderPointer &p_header) { Q_UNUSED(p_header) } - - VFile *getFile() const; - - // User requests to insert image. - virtual void insertImage() = 0; - - // User requests to insert link. - virtual void insertLink(); - - // User requests to table. - virtual void insertTable(); - - // Search @p_text in current note. - virtual void findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward = true) = 0; - - virtual void findText(const VSearchToken &p_token, - bool p_forward = true, - bool p_fromStart = false) = 0; - - // Replace @p_text with @p_replaceText in current note. - virtual void replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) = 0; - - virtual void replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) = 0; - - virtual void nextMatch(const QString &p_text, uint p_options, bool p_forward) = 0; - - // Return selected text. - virtual QString getSelectedText() const = 0; - - virtual void clearSearchedWordHighlight() = 0; - - // Request current tab to propogate its status about Vim. - virtual void requestUpdateVimStatus() = 0; - - // Insert decoration markers or decorate selected text. - virtual void decorateText(TextDecoration p_decoration, int p_level = -1) - { - Q_UNUSED(p_decoration); - Q_UNUSED(p_level); - } - - // Create a filled VEditTabInfo. - virtual VEditTabInfo fetchTabInfo(VEditTabInfo::InfoType p_type = VEditTabInfo::InfoType::All) const; - - const VTableOfContent &getOutline() const; - - const VHeaderPointer &getCurrentHeader() const; - - // Restore status from @p_info. - // If this tab is not ready yet, it will restore once it is ready. - void tryRestoreFromTabInfo(const VEditTabInfo &p_info); - - // Emit signal to update current status. - virtual void updateStatus(); - - // Called by evaluateMagicWordsByCaptain() to evaluate the magic words. - virtual void evaluateMagicWords(); - - // Insert snippet @p_snippet. - virtual void applySnippet(const VSnippet *p_snippet); - - // Prompt for user to apply a snippet. - virtual void applySnippet(); - - // Check whether this file has been changed outside. - void checkFileChangeOutside(); - - // Reload the editor from file. - virtual void reload() = 0; - - // Reload file from disk and reload the editor. - void reloadFromDisk(); - - // Handle the change of file or directory, such as the file has been moved. - virtual void handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act); - - // Fetch tab stat info. - virtual VWordCountInfo fetchWordCountInfo(bool p_editMode) const; - -public slots: - // Enter edit mode - virtual void editFile() = 0; - - virtual void handleVimCmdCommandCancelled(); - - virtual void handleVimCmdCommandFinished(VVim::CommandLineType p_type, const QString &p_cmd); - - virtual void handleVimCmdCommandChanged(VVim::CommandLineType p_type, const QString &p_cmd); - - virtual QString handleVimCmdRequestNextCommand(VVim::CommandLineType p_type, const QString &p_cmd); - - virtual QString handleVimCmdRequestPreviousCommand(VVim::CommandLineType p_type, const QString &p_cmd); - - virtual QString handleVimCmdRequestRegister(int p_key, int p_modifiers); - -protected: - void wheelEvent(QWheelEvent *p_event) Q_DECL_OVERRIDE; - - // Called when VEditTab get focus. Should focus the proper child widget. - virtual void focusChild() = 0; - - // Called to zoom in/out content. - virtual void zoom(bool p_zoomIn, qreal p_step = 0.25) = 0; - - // Restore from @p_fino. - // Return true if succeed. - virtual bool restoreFromTabInfo(const VEditTabInfo &p_info) = 0; - - // Write modified buffer content to backup file. - virtual void writeBackupFile(); - - // File related to this tab. - QPointer m_file; - - bool m_isEditMode; - - // Table of content of this tab. - VTableOfContent m_outline; - - // Current header in m_outline of this tab. - VHeaderPointer m_currentHeader; - - VEditArea *m_editArea; - - // Tab info to restore from once ready. - VEditTabInfo m_infoToRestore; - - // Whether check the file change outside. - bool m_checkFileChange; - - // File has diverged from disk. - bool m_fileDiverged; - - // Tab has been ready or not. - int m_ready; - - // Whether backup file is enabled. - bool m_enableBackupFile; - -signals: - void getFocused(); - - void outlineChanged(const VTableOfContent &p_outline); - - void currentHeaderChanged(const VHeaderPointer &p_header); - - // The status of current tab has updates. - void statusUpdated(const VEditTabInfo &p_info); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - void vimStatusUpdated(const VVim *p_vim); - - // Request to close itself. - void closeRequested(VEditTab *p_tab); - - // Request main window to show Vim cmd line. - void triggerVimCmd(VVim::CommandLineType p_type); - -private slots: - // Called when app focus changed. - void handleFocusChanged(QWidget *p_old, QWidget *p_now); -}; -#endif // VEDITTAB_H diff --git a/src/vedittabinfo.h b/src/vedittabinfo.h deleted file mode 100644 index 71a127fd..00000000 --- a/src/vedittabinfo.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef VEDITTABINFO_H -#define VEDITTABINFO_H - -#include "vwordcountinfo.h" - -class VEditTab; - -struct VEditTabInfo -{ - enum InfoType - { - // Update all information. - All = 0, - - // Update only cursor information. - Cursor - }; - - VEditTabInfo() - : m_type(InfoType::All), - m_editTab(NULL), - m_cursorBlockNumber(-1), - m_cursorPositionInBlock(-1), - m_blockCount(-1), - m_headerIndex(-1) - { - } - - void clear() - { - m_type = InfoType::All; - m_editTab = NULL; - m_cursorBlockNumber = -1; - m_cursorPositionInBlock = -1; - m_blockCount = -1; - m_wordCountInfo.clear(); - m_headerIndex = -1; - } - - InfoType m_type; - - VEditTab *m_editTab; - - // Cursor information. -1 for invalid info. - int m_cursorBlockNumber; - int m_cursorPositionInBlock; - int m_blockCount; - - VWordCountInfo m_wordCountInfo; - - // Header index in outline. - int m_headerIndex; -}; - -#endif // VEDITTABINFO_H diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp deleted file mode 100644 index 7b364606..00000000 --- a/src/veditwindow.cpp +++ /dev/null @@ -1,1334 +0,0 @@ -#include -#include - -#include "veditwindow.h" -#include "vedittab.h" -#include "utils/vutils.h" -#include "vorphanfile.h" -#include "vmainwindow.h" -#include "veditarea.h" -#include "vopenedlistmenu.h" -#include "vmdtab.h" -#include "vhtmltab.h" -#include "vfilelist.h" -#include "vconfigmanager.h" -#include "utils/viconutils.h" -#include "vcart.h" -#include "vhistorylist.h" -#include "vnote.h" -#include "vexplorer.h" - -extern VConfigManager *g_config; - -extern VMainWindow *g_mainWin; - -extern VNote *g_vnote; - -#define GET_TAB_FROM_SENDER() static_cast(sender())->data().toInt() - -VEditWindow::VEditWindow(VEditArea *editArea, QWidget *parent) - : QTabWidget(parent), - m_editArea(editArea), - m_curTabWidget(NULL), - m_lastTabWidget(NULL), - m_removeSplitAct(NULL), - m_maximizeSplitAct(NULL), - m_distributeSplitsAct(NULL) -{ - setAcceptDrops(true); - setupCornerWidget(); - - // Explicit speficy in macOS. - setUsesScrollButtons(true); - setElideMode(Qt::ElideRight); - setTabsClosable(true); - setMovable(true); - setContextMenuPolicy(Qt::CustomContextMenu); - - QTabBar *bar = tabBar(); - bar->setContextMenuPolicy(Qt::CustomContextMenu); - if (g_config->getMiddleClickClostTab()) { - bar->installEventFilter(this); - } - - connect(bar, &QTabBar::customContextMenuRequested, - this, &VEditWindow::tabbarContextMenuRequested); - - connect(this, &VEditWindow::tabCloseRequested, - this, &VEditWindow::closeTab); - connect(this, &VEditWindow::tabBarClicked, - this, &VEditWindow::handleTabbarClicked); - - connect(this, &VEditWindow::tabBarDoubleClicked, - this, [this](int p_index) { - if (p_index != -1 && g_config->getDoubleClickCloseTab()) { - closeTab(p_index); - } - }); - - connect(this, &VEditWindow::currentChanged, - this, &VEditWindow::handleCurrentIndexChanged); - connect(this, &VEditWindow::customContextMenuRequested, - this, &VEditWindow::contextMenuRequested); -} - -void VEditWindow::setupCornerWidget() -{ - // Left button - leftBtn = new QPushButton(VIconUtils::editWindowCornerIcon(":/resources/icons/corner_tablist.svg"), - "", this); - leftBtn->setProperty("CornerBtn", true); - leftBtn->setToolTip(tr("Opened Notes List")); - QString keyText = VUtils::getCaptainShortcutSequenceText("OpenedFileList"); - if (!keyText.isEmpty()) { - leftBtn->setToolTip(QString("%1\t%2").arg(leftBtn->toolTip()).arg(keyText)); - } - - VOpenedListMenu *leftMenu = new VOpenedListMenu(this); - leftMenu->setToolTipsVisible(true); - connect(leftMenu, &VOpenedListMenu::fileTriggered, - this, &VEditWindow::tabListJump); - leftBtn->setMenu(leftMenu); - - // Right button - rightBtn = new QPushButton(VIconUtils::editWindowCornerIcon(":/resources/icons/corner_menu.svg"), - "", this); - rightBtn->setProperty("CornerBtn", true); - rightBtn->setToolTip(tr("Menu")); - QMenu *rightMenu = new QMenu(this); - rightMenu->setToolTipsVisible(true); - rightBtn->setMenu(rightMenu); - connect(rightMenu, &QMenu::aboutToShow, - this, [this, rightMenu]() { - updateSplitMenu(rightMenu); - }); - - // Move all buttons to the right corner. - QWidget *widget = new QWidget(this); - QHBoxLayout *layout = new QHBoxLayout(); - layout->addWidget(leftBtn); - layout->addWidget(rightBtn); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - widget->setLayout(layout); - - setCornerWidget(widget, Qt::TopRightCorner); -} - -void VEditWindow::splitWindow(bool p_right) -{ - emit requestSplitWindow(this, p_right); -} - -void VEditWindow::removeSplit() -{ - // Close all the files one by one - // If user do not want to close a file, just stop removing. - // Otherwise, closeAllFiles() will emit requestRemoveSplit. - closeAllFiles(false); -} - -void VEditWindow::removeEditTab(int p_index) -{ - Q_ASSERT(p_index > -1 && p_index < tabBar()->count()); - - VEditTab *editor = getTab(p_index); - - removeTab(p_index); - - delete editor; -} - -int VEditWindow::insertEditTab(int p_index, VFile *p_file, QWidget *p_page) -{ - int idx = insertTab(p_index, - p_page, - p_file->getName()); - updateTabInfo(idx); - return idx; -} - -int VEditWindow::openFile(VFile *p_file, OpenFileMode p_mode) -{ - qDebug() << "open" << p_file->getName(); - // Find if it has been opened already - int idx = findTabByFile(p_file); - if (idx > -1) { - goto out; - } - - idx = openFileInTab(p_file, p_mode); - -out: - setCurrentIndex(idx); - focusWindow(); - return idx; -} - -// Return true if we closed the file actually -bool VEditWindow::closeFile(const VFile *p_file, bool p_forced) -{ - // Find if it has been opened already - int idx = findTabByFile(p_file); - if (idx == -1) { - return false; - } - - VEditTab *editor = getTab(idx); - Q_ASSERT(editor); - VEditTabInfo tabInfo = editor->fetchTabInfo(); - VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tabInfo); - if (!p_forced) { - setCurrentIndex(idx); - updateTabStatus(idx); - } - - // Even p_forced is true we need to delete unused images. - bool ok = editor->closeFile(p_forced); - if (ok) { - removeEditTab(idx); - - m_editArea->recordClosedFile(info); - } - - if (count() == 0) { - emit requestRemoveSplit(this); - } - - return ok; -} - -bool VEditWindow::closeFile(const VDirectory *p_dir, bool p_forced) -{ - Q_ASSERT(p_dir); - int i = 0; - while (i < count()) { - VEditTab *editor = getTab(i); - QPointer file = editor->getFile(); - if (p_dir->containsFile(file)) { - if (!closeFile(file, p_forced)) { - return false; - } - // Closed a file, so don't need to add i. - } else { - ++i; - } - } - return true; -} - -bool VEditWindow::closeFile(const VNotebook *p_notebook, bool p_forced) -{ - Q_ASSERT(p_notebook); - int i = 0; - while (i < count()) { - VEditTab *editor = getTab(i); - QPointer file = editor->getFile(); - if (p_notebook->containsFile(file)) { - if (!closeFile(file, p_forced)) { - return false; - } - // Closed a file, so don't need to add i. - } else { - ++i; - } - } - return true; -} - -bool VEditWindow::closeAllFiles(bool p_forced) -{ - int nrTab = count(); - bool ret = true; - for (int i = 0; i < nrTab; ++i) { - VEditTab *editor = getTab(0); - - VEditTabInfo tabInfo = editor->fetchTabInfo(); - VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tabInfo); - - if (!p_forced) { - setCurrentIndex(0); - updateTabStatus(0); - } - - // Even p_forced is true we need to delete unused images. - bool ok = editor->closeFile(p_forced); - if (ok) { - removeEditTab(0); - - m_editArea->recordClosedFile(info); - } else { - ret = false; - break; - } - } - - if (count() == 0) { - emit requestRemoveSplit(this); - } - - return ret; -} - -int VEditWindow::openFileInTab(VFile *p_file, OpenFileMode p_mode) -{ - VEditTab *editor = NULL; - switch (p_file->getDocType()) { - case DocType::Markdown: - editor = new VMdTab(p_file, m_editArea, p_mode, this); - break; - - case DocType::Html: - editor = new VHtmlTab(p_file, m_editArea, p_mode, this); - break; - - default: - V_ASSERT(false); - break; - } - - // Connect the signals. - connectEditTab(editor); - - // Insert right after current tab. - // VFileList will depends on this behavior. - return insertEditTab(currentIndex() + 1, p_file, editor); -} - -int VEditWindow::findTabByFile(const VFile *p_file) const -{ - int nrTabs = count(); - for (int i = 0; i < nrTabs; ++i) { - if (getTab(i)->getFile() == p_file) { - return i; - } - } - return -1; -} - -bool VEditWindow::closeTab(int p_index) -{ - VEditTab *editor = getTab(p_index); - Q_ASSERT(editor); - VEditTabInfo tabInfo = editor->fetchTabInfo(); - VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tabInfo); - bool ok = editor->closeFile(false); - if (ok) { - removeEditTab(p_index); - - m_editArea->recordClosedFile(info); - } - - // User clicks the close button. We should make this window - // to be current window. - emit getFocused(); - if (count() == 0) { - emit requestRemoveSplit(this); - } - - return ok; -} - -void VEditWindow::readFile(bool p_discard) -{ - VEditTab *editor = getTab(currentIndex()); - Q_ASSERT(editor); - editor->readFile(p_discard); -} - -void VEditWindow::saveAndReadFile() -{ - saveFile(); - readFile(); -} - -void VEditWindow::editFile() -{ - VEditTab *editor = getTab(currentIndex()); - Q_ASSERT(editor); - editor->editFile(); -} - -void VEditWindow::saveFile() -{ - VEditTab *editor = getTab(currentIndex()); - Q_ASSERT(editor); - editor->saveFile(); -} - -void VEditWindow::updateTabStatus(int p_index) -{ - if (p_index == -1) { - p_index = currentIndex(); - } - - if (p_index == -1) { - emit tabStatusUpdated(VEditTabInfo()); - emit outlineChanged(VTableOfContent()); - emit currentHeaderChanged(VHeaderPointer()); - return; - } - - if (p_index == currentIndex()) { - VEditTab *tab = getTab(p_index); - emit tabStatusUpdated(tab->fetchTabInfo()); - emit outlineChanged(tab->getOutline()); - emit currentHeaderChanged(tab->getCurrentHeader()); - } - - updateTabInfo(p_index); -} - -void VEditWindow::updateTabInfo(int p_index) -{ - static QIcon editModified = VIconUtils::tabBarSpecialIcon(":/resources/icons/editing_modified.svg"); - static QIcon edit = VIconUtils::tabBarIcon(":/resources/icons/editing.svg"); - static QIcon readModified = VIconUtils::tabBarSpecialIcon(":/resources/icons/reading_modified.svg"); - static QIcon read = VIconUtils::tabBarIcon(":/resources/icons/reading.svg"); - - VEditTab *editor = getTab(p_index); - const VFile *file = editor->getFile(); - bool editMode = editor->isEditMode(); - - setTabText(p_index, generateTabText(p_index, editor)); - setTabToolTip(p_index, generateTooltip(file)); - - QIcon icon; - if (editMode) { - icon = editor->isModified() ? editModified : edit; - } else { - icon = editor->isModified() ? readModified : read; - } - - setTabIcon(p_index, icon); -} - -void VEditWindow::updateAllTabsSequence() -{ - for (int i = 0; i < count(); ++i) { - VEditTab *editor = getTab(i); - setTabText(i, generateTabText(i, editor)); - } -} - -VTableOfContent VEditWindow::getOutline() const -{ - int idx = currentIndex(); - if (idx == -1) { - return VTableOfContent(); - } - - return getTab(idx)->getOutline(); -} - -VHeaderPointer VEditWindow::getCurrentHeader() const -{ - int idx = currentIndex(); - if (idx == -1) { - return VHeaderPointer(); - } - - return getTab(idx)->getCurrentHeader(); -} - -// Focus this windows. Try to focus current tab. -void VEditWindow::focusWindow() -{ - int idx = currentIndex(); - if (idx == -1) { - setFocus(); - emit getFocused(); - return; - } - getTab(idx)->focusTab(); -} - -void VEditWindow::handleTabbarClicked(int p_index) -{ - // Only handle the case when (p_index == currentIndex()) here - // because currentIndex() is not changed yet. If we focus window - // now, we may change the current index forcely. - if (p_index == currentIndex()) { - focusWindow(); - } -} - -void VEditWindow::handleCurrentIndexChanged(int p_index) -{ - focusWindow(); - - QWidget *wid = widget(p_index); - if (wid && (wid == m_curTabWidget)) { - return; - } - - m_lastTabWidget = m_curTabWidget; - m_curTabWidget = wid; -} - -void VEditWindow::mousePressEvent(QMouseEvent *event) -{ - focusWindow(); - QTabWidget::mousePressEvent(event); -} - -QAction *VEditWindow::getRemoveSplitAction() -{ - if (!m_removeSplitAct) { - m_removeSplitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/remove_split.svg"), - tr("Remove Split"), - this); - m_removeSplitAct->setToolTip(tr("Remove current split window")); - VUtils::fixTextWithCaptainShortcut(m_removeSplitAct, "RemoveSplit"); - connect(m_removeSplitAct, &QAction::triggered, - this, &VEditWindow::removeSplit); - } - - return m_removeSplitAct; -} - -void VEditWindow::contextMenuRequested(QPoint pos) -{ - QMenu menu(this); - menu.setToolTipsVisible(true); - - if (canRemoveSplit()) { - menu.addAction(getRemoveSplitAction()); - menu.exec(this->mapToGlobal(pos)); - } -} - -void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) -{ - QTabBar *bar = tabBar(); - int tab = bar->tabAt(p_pos); - if (tab == -1) { - return; - } - - QMenu menu(this); - menu.setToolTipsVisible(true); - - QAction *recycleBinAct = new QAction(VIconUtils::menuIcon(":/resources/icons/recycle_bin.svg"), - tr("&Recycle Bin"), - &menu); - recycleBinAct->setToolTip(tr("Open the recycle bin of this note")); - connect(recycleBinAct, &QAction::triggered, - this, [this]() { - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - VFile *file = editor->getFile(); - Q_ASSERT(file); - - QString folderPath; - if (file->getType() == FileType::Note) { - const VNoteFile *tmpFile = static_cast((VFile *)file); - folderPath = tmpFile->getNotebook()->getRecycleBinFolderPath(); - } else if (file->getType() == FileType::Orphan) { - const VOrphanFile *tmpFile = static_cast((VFile *)file); - folderPath = tmpFile->fetchRecycleBinFolderPath(); - } else { - Q_ASSERT(false); - } - - QUrl url = QUrl::fromLocalFile(folderPath); - QDesktopServices::openUrl(url); - }); - - QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"), - tr("Open Note Location"), - &menu); - openLocationAct->setToolTip(tr("Explore the folder containing this note in operating system")); - connect(openLocationAct, &QAction::triggered, - this, [this](){ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - QPointer file = editor->getFile(); - Q_ASSERT(file); - QUrl url = QUrl::fromLocalFile(file->fetchBasePath()); - QDesktopServices::openUrl(url); - }); - - QAction *reloadAct = new QAction(tr("Reload From Disk"), &menu); - reloadAct->setToolTip(tr("Reload the content of this note from disk")); - connect(reloadAct, &QAction::triggered, - this, [this](){ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - editor->reloadFromDisk(); - }); - - QAction *addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"), - tr("Add To Cart"), - &menu); - addToCartAct->setToolTip(tr("Add this note to Cart for further processing")); - connect(addToCartAct, &QAction::triggered, - this, [this](){ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - QPointer file = editor->getFile(); - Q_ASSERT(file); - g_mainWin->getCart()->addFile(file->fetchPath()); - g_mainWin->showStatusMessage(tr("1 note added to Cart")); - }); - - QAction *pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"), - tr("Pin To History"), - &menu); - pinToHistoryAct->setToolTip(tr("Pin this note to History")); - connect(pinToHistoryAct, &QAction::triggered, - this, [this](){ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - QPointer file = editor->getFile(); - Q_ASSERT(file); - QStringList files; - files << file->fetchPath(); - g_mainWin->getHistoryList()->pinFiles(files); - g_mainWin->showStatusMessage(tr("1 note pinned to History")); - }); - - QAction *quickAccessAct = new QAction(VIconUtils::menuIcon(":/resources/icons/quick_access.svg"), - tr("Set As Quick Access"), - &menu); - quickAccessAct->setToolTip(tr("Set this note as quick access")); - connect(quickAccessAct, &QAction::triggered, - this, [this](){ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - QPointer file = editor->getFile(); - Q_ASSERT(file); - QString fp(file->fetchPath()); - g_config->setQuickAccess(fp); - g_mainWin->showStatusMessage(tr("Quick access: %1").arg(fp)); - }); - - QAction *noteInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), - tr("Note Info"), - &menu); - noteInfoAct->setToolTip(tr("View and edit information of the note")); - connect(noteInfoAct, &QAction::triggered, - this, [this](){ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - - VEditTab *editor = getTab(tab); - QPointer file = editor->getFile(); - Q_ASSERT(file); - if (file->getType() == FileType::Note) { - VNoteFile *tmpFile = static_cast((VFile *)file); - g_mainWin->getFileList()->fileInfo(tmpFile); - } else if (file->getType() == FileType::Orphan) { - g_mainWin->editOrphanFileInfo(file); - } - }); - - VEditTab *editor = getTab(tab); - VFile *file = editor->getFile(); - bool isNote = file->getType() == FileType::Note; - bool isNonSystemOrphan = file->getType() == FileType::Orphan - && !(static_cast(file)->isSystemFile()); - if (isNote) { - // Locate to folder. - QAction *locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"), - tr("Locate To Folder"), - &menu); - locateAct->setToolTip(tr("Locate the folder of current note")); - VUtils::fixTextWithCaptainShortcut(locateAct, "LocateCurrentFile"); - connect(locateAct, &QAction::triggered, - this, &VEditWindow::handleLocateAct); - locateAct->setData(tab); - menu.addAction(locateAct); - - menu.addSeparator(); - } - - if (isNote || isNonSystemOrphan) { - recycleBinAct->setData(tab); - menu.addAction(recycleBinAct); - - openLocationAct->setData(tab); - menu.addAction(openLocationAct); - - reloadAct->setData(tab); - menu.addAction(reloadAct); - - addToCartAct->setData(tab); - menu.addAction(addToCartAct); - - pinToHistoryAct->setData(tab); - menu.addAction(pinToHistoryAct); - - quickAccessAct->setData(tab); - menu.addAction(quickAccessAct); - - noteInfoAct->setData(tab); - menu.addAction(noteInfoAct); - } - - int totalWin = m_editArea->windowCount(); - // When there is only one tab and one split window, there is no need to - // display these two actions. - if (totalWin > 1 || count() > 1) { - menu.addSeparator(); - - QAction *moveLeftAct = new QAction(VIconUtils::menuIcon(":/resources/icons/move_tab_left.svg"), - tr("Move One Split Left"), - &menu); - moveLeftAct->setToolTip(tr("Move current tab to the split on the left")); - VUtils::fixTextWithCaptainShortcut(moveLeftAct, "MoveTabSplitLeft"); - connect(moveLeftAct, &QAction::triggered, - this, &VEditWindow::handleMoveLeftAct); - moveLeftAct->setData(tab); - menu.addAction(moveLeftAct); - - QAction *moveRightAct = new QAction(VIconUtils::menuIcon(":/resources/icons/move_tab_right.svg"), - tr("Move One Split Right"), - &menu); - moveRightAct->setToolTip(tr("Move current tab to the split on the right")); - VUtils::fixTextWithCaptainShortcut(moveRightAct, "MoveTabSplitRight"); - connect(moveRightAct, &QAction::triggered, - this, &VEditWindow::handleMoveRightAct); - moveRightAct->setData(tab); - menu.addAction(moveRightAct); - } - - menu.addSeparator(); - - // Close tab, or other tabs, or tabs to the right. - QAction *closeTabAct = new QAction(VIconUtils::menuIcon(":/resources/icons/close.svg"), - tr("Close Tab"), - &menu); - closeTabAct->setToolTip(tr("Close current note tab")); - if (!VUtils::fixTextWithShortcut(closeTabAct, "CloseNote")) { - VUtils::fixTextWithCaptainShortcut(closeTabAct, "CloseNote"); - } - - connect(closeTabAct, &QAction::triggered, - this, [this](){ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - closeTab(tab); - }); - closeTabAct->setData(tab); - menu.addAction(closeTabAct); - - if (count() > 1) { - QAction *closeOthersAct = new QAction(tr("Close Other Tabs"), &menu); - closeOthersAct->setToolTip(tr("Close all other note tabs")); - connect(closeOthersAct, &QAction::triggered, - this, [this](){ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - for (int i = tab - 1; i >= 0; --i) { - this->setCurrentIndex(i); - this->updateTabStatus(i); - if (this->closeTab(i)) { - --tab; - } - } - - for (int i = tab + 1; i < this->count();) { - this->setCurrentIndex(i); - this->updateTabStatus(i); - if (!this->closeTab(i)) { - ++i; - } - } - }); - closeOthersAct->setData(tab); - menu.addAction(closeOthersAct); - - if (tab < count() - 1) { - QAction *closeRightAct = new QAction(tr("Close Tabs To The Right"), &menu); - closeRightAct->setToolTip(tr("Close all the note tabs to the right of current tab")); - connect(closeRightAct, &QAction::triggered, - this, [this](){ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - for (int i = tab + 1; i < this->count();) { - this->setCurrentIndex(i); - this->updateTabStatus(i); - if (!this->closeTab(i)) { - ++i; - } - } - }); - closeRightAct->setData(tab); - menu.addAction(closeRightAct); - } - } - - QAction *closeAllAct = new QAction(tr("Close All Tabs"), &menu); - closeAllAct->setToolTip(tr("Close all the note tabs")); - connect(closeAllAct, &QAction::triggered, - this, [this](){ - for (int i = 0; i < this->count();) { - this->setCurrentIndex(i); - this->updateTabStatus(i); - if (!this->closeTab(i)) { - ++i; - } - } - }); - menu.addAction(closeAllAct); - - if (!menu.actions().isEmpty()) { - menu.exec(bar->mapToGlobal(p_pos)); - } -} - -void VEditWindow::tabListJump(VFile *p_file) -{ - if (!p_file) { - return; - } - - int idx = findTabByFile(p_file); - Q_ASSERT(idx >= 0); - setCurrentIndex(idx); - focusWindow(); - updateTabStatus(idx); -} - -void VEditWindow::updateSplitMenu(QMenu *p_menu) -{ - if (p_menu->isEmpty()) { - QAction *splitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/split_window.svg"), - tr("Split"), - p_menu); - splitAct->setToolTip(tr("Split current window vertically")); - VUtils::fixTextWithCaptainShortcut(splitAct, "VerticalSplit"); - connect(splitAct, &QAction::triggered, - this, [this](){ - splitWindow(true); - }); - p_menu->addAction(splitAct); - - Q_ASSERT(!m_maximizeSplitAct); - m_maximizeSplitAct = new QAction(tr("Maximize Split"), p_menu); - m_maximizeSplitAct->setToolTip(tr("Maximize current split window")); - VUtils::fixTextWithCaptainShortcut(m_maximizeSplitAct, "MaximizeSplit"); - connect(m_maximizeSplitAct, &QAction::triggered, - this, [this]() { - focusWindow(); - m_editArea->maximizeCurrentSplit(); - }); - p_menu->addAction(m_maximizeSplitAct); - - Q_ASSERT(!m_distributeSplitsAct); - m_distributeSplitsAct = new QAction(tr("Distribute Splits"), p_menu); - m_distributeSplitsAct->setToolTip(tr("Distribute all the split windows evenly")); - VUtils::fixTextWithCaptainShortcut(m_distributeSplitsAct, "DistributeSplits"); - connect(m_distributeSplitsAct, &QAction::triggered, - m_editArea, &VEditArea::distributeSplits); - p_menu->addAction(m_distributeSplitsAct); - - p_menu->addAction(getRemoveSplitAction()); - } - - if (m_editArea->windowCount() > 1) { - m_maximizeSplitAct->setVisible(true); - m_distributeSplitsAct->setVisible(true); - } else { - m_maximizeSplitAct->setVisible(false); - m_distributeSplitsAct->setVisible(false); - } - - getRemoveSplitAction()->setVisible(canRemoveSplit()); -} - -bool VEditWindow::canRemoveSplit() -{ - QSplitter *splitter = dynamic_cast(parent()); - Q_ASSERT(splitter); - return splitter->count() > 1; -} - -void VEditWindow::handleTabOutlineChanged(const VTableOfContent &p_outline) -{ - // Only propagate it if it is current tab. - VEditTab *tab = getCurrentTab(); - if (tab) { - if (tab->getFile() == p_outline.getFile()) { - emit outlineChanged(p_outline); - } - } else { - emit outlineChanged(VTableOfContent()); - return; - } -} - -void VEditWindow::handleTabCurrentHeaderChanged(const VHeaderPointer &p_header) -{ - // Only propagate it if it is current tab. - VEditTab *tab = getCurrentTab(); - if (tab) { - if (tab->getFile() == p_header.m_file) { - emit currentHeaderChanged(p_header); - } - } else { - emit currentHeaderChanged(VHeaderPointer()); - return; - } -} - -void VEditWindow::scrollToHeader(const VHeaderPointer &p_header) -{ - VEditTab *tab = getCurrentTab(); - if (tab) { - tab->scrollToHeader(p_header); - } -} - -void VEditWindow::handleTabStatusUpdated(const VEditTabInfo &p_info) -{ - int idx = indexOf(static_cast(sender())); - - if (p_info.m_type == VEditTabInfo::InfoType::All) { - updateTabInfo(idx); - updateAllTabsSequence(); - } - - if (idx == currentIndex()) { - // Current tab. Propogate its status. - emit tabStatusUpdated(p_info); - } -} - -void VEditWindow::handleTabStatusMessage(const QString &p_msg) -{ - int idx = indexOf(static_cast(sender())); - if (idx == currentIndex()) { - emit statusMessage(p_msg); - } -} - -void VEditWindow::handleTabVimStatusUpdated(const VVim *p_vim) -{ - int idx = indexOf(static_cast(sender())); - if (idx == currentIndex()) { - emit vimStatusUpdated(p_vim); - } -} - -void VEditWindow::updateFileInfo(const VFile *p_file, UpdateAction p_act) -{ - if (!p_file) { - return; - } - - int idx = findTabByFile(p_file); - if (idx > -1) { - updateTabStatus(idx); - getTab(idx)->handleFileOrDirectoryChange(true, p_act); - } -} - -void VEditWindow::updateDirectoryInfo(const VDirectory *p_dir, UpdateAction p_act) -{ - if (!p_dir) { - return; - } - - int nrTab = count(); - for (int i = 0; i < nrTab; ++i) { - VEditTab *editor = getTab(i); - QPointer file = editor->getFile(); - if (p_dir->containsFile(file)) { - updateTabStatus(i); - editor->handleFileOrDirectoryChange(false, p_act); - } - } -} - -void VEditWindow::updateNotebookInfo(const VNotebook *p_notebook) -{ - if (!p_notebook) { - return; - } - - int nrTab = count(); - for (int i = 0; i < nrTab; ++i) { - VEditTab *editor = getTab(i); - QPointer file = editor->getFile(); - if (p_notebook->containsFile(file)) { - updateTabStatus(i); - } - } -} - -VEditTab *VEditWindow::getCurrentTab() const -{ - int idx = currentIndex(); - if (idx == -1) { - return NULL; - } - - return getTab(idx); -} - -QVector VEditWindow::getAllTabsInfo() const -{ - int nrTab = count(); - - QVector tabs; - tabs.reserve(nrTab); - for (int i = 0; i < nrTab; ++i) { - VEditTab *editTab = getTab(i); - tabs.push_back(editTab->fetchTabInfo()); - } - - return tabs; -} - -void VEditWindow::handleLocateAct() -{ - int tab = GET_TAB_FROM_SENDER(); - VEditTab *editor = getTab(tab); - QPointer file = editor->getFile(); - if (file->getType() == FileType::Note) { - g_mainWin->locateFile(file); - } -} - -void VEditWindow::handleMoveLeftAct() -{ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - moveTabOneSplit(tab, false); -} - -void VEditWindow::handleMoveRightAct() -{ - int tab = GET_TAB_FROM_SENDER(); - Q_ASSERT(tab != -1); - moveTabOneSplit(tab, true); -} - -void VEditWindow::moveTabOneSplit(int p_tabIdx, bool p_right) -{ - Q_ASSERT(p_tabIdx > -1 && p_tabIdx < count()); - // Add split window if needed. - if (m_editArea->windowCount() < 2) { - // Request VEditArea to split window. - splitWindow(p_right); - - // Though the signal and slot will behave like a function call. We wait - // here until the window split finished. - while (m_editArea->windowCount() < 2) { - VUtils::sleepWait(100); - } - } - - int totalWin = m_editArea->windowCount(); - int idx = m_editArea->windowIndex(this); - int newIdx = p_right ? idx + 1 : idx - 1; - if (newIdx >= totalWin) { - newIdx = 0; - } else if (newIdx < 0) { - newIdx = totalWin - 1; - } - VEditTab *editor = getTab(p_tabIdx); - // Remove it from current window. This won't close the split even if it is - // the only tab. - removeTab(p_tabIdx); - - // Disconnect all the signals. - disconnect(editor, 0, this, 0); - - m_editArea->moveTab(editor, idx, newIdx); - - // If there is no tab, remove current split. - if (count() == 0) { - emit requestRemoveSplit(this); - } -} - -void VEditWindow::moveCurrentTabOneSplit(bool p_right) -{ - int idx = currentIndex(); - if (idx == -1) { - return; - } - - moveTabOneSplit(idx, p_right); -} - -bool VEditWindow::addEditTab(QWidget *p_widget) -{ - if (!p_widget) { - return false; - } - - VEditTab *editor = dynamic_cast(p_widget); - if (!editor) { - return false; - } - - // Connect the signals. - connectEditTab(editor); - - int idx = insertEditTab(currentIndex() + 1, editor->getFile(), editor); - setCurrentIndex(idx); - updateTabStatus(idx); - return true; -} - -void VEditWindow::connectEditTab(const VEditTab *p_tab) -{ - connect(p_tab, &VEditTab::getFocused, - this, [this]() { - setCurrentWidget(static_cast(sender())); - emit getFocused(); - }); - connect(p_tab, &VEditTab::outlineChanged, - this, &VEditWindow::handleTabOutlineChanged); - connect(p_tab, &VEditTab::currentHeaderChanged, - this, &VEditWindow::handleTabCurrentHeaderChanged); - connect(p_tab, &VEditTab::statusUpdated, - this, &VEditWindow::handleTabStatusUpdated); - connect(p_tab, &VEditTab::statusMessage, - this, &VEditWindow::handleTabStatusMessage); - connect(p_tab, &VEditTab::vimStatusUpdated, - this, &VEditWindow::handleTabVimStatusUpdated); - connect(p_tab, &VEditTab::closeRequested, - this, &VEditWindow::tabRequestToClose); -} - -void VEditWindow::setCurrentWindow(bool p_current) -{ - static QIcon menuCur = VIconUtils::editWindowCornerIcon(":/resources/icons/corner_menu_cur.svg"); - static QIcon tablistCur = VIconUtils::editWindowCornerIcon(":/resources/icons/corner_tablist_cur.svg"); - static QIcon menu = VIconUtils::editWindowCornerInactiveIcon(":/resources/icons/corner_menu.svg"); - static QIcon tablist = VIconUtils::editWindowCornerInactiveIcon(":/resources/icons/corner_tablist.svg"); - - if (p_current) { - rightBtn->setIcon(menuCur); - leftBtn->setIcon(tablistCur); - } else { - rightBtn->setIcon(menu); - leftBtn->setIcon(tablist); - } -} - -void VEditWindow::clearSearchedWordHighlight() -{ - int nrTab = count(); - for (int i = 0; i < nrTab; ++i) { - getTab(i)->clearSearchedWordHighlight(); - } -} - -void VEditWindow::focusNextTab(bool p_right) -{ - focusWindow(); - if (count() < 2) { - return; - } - int idx = currentIndex(); - idx = p_right ? idx + 1 : idx - 1; - if (idx < 0) { - idx = count() - 1; - } else if (idx >= count()) { - idx = 0; - } - setCurrentIndex(idx); -} - -bool VEditWindow::showOpenedFileList() -{ - if (count() == 0) { - return false; - } - - leftBtn->showMenu(); - VOpenedListMenu *menu = static_cast(leftBtn->menu()); - return menu->isAccepted(); -} - -bool VEditWindow::activateTab(int p_sequence) -{ - if (p_sequence < c_tabSequenceBase - || p_sequence >= (c_tabSequenceBase + count())) { - return false; - } - - int idx = p_sequence - c_tabSequenceBase; - setCurrentIndex(idx); - // Always need to focus to this tab to meet the requirement of Captain mode. - getTab(idx)->focusTab(); - - return true; -} - -bool VEditWindow::alternateTab() -{ - if (m_lastTabWidget) { - if (-1 != indexOf(m_lastTabWidget)) { - setCurrentWidget(m_lastTabWidget); - return true; - } else { - m_lastTabWidget = NULL; - } - } - return false; -} - -VEditTab* VEditWindow::getTab(int tabIndex) const -{ - return dynamic_cast(widget(tabIndex)); -} - -void VEditWindow::dragEnterEvent(QDragEnterEvent *p_event) -{ - if (p_event->mimeData()->hasFormat("text/uri-list")) { - p_event->acceptProposedAction(); - return; - } - - QTabWidget::dragEnterEvent(p_event); -} - -void VEditWindow::dropEvent(QDropEvent *p_event) -{ - const QMimeData *mime = p_event->mimeData(); - if (mime->hasFormat("text/uri-list") && mime->hasUrls()) { - // Open external files in this edit window or open a direcotry in Explorer. - bool isDir = false; - QStringList files; - QList urls = mime->urls(); - for (int i = 0; i < urls.size(); ++i) { - if (urls[i].isLocalFile()) { - QFileInfo fi(urls[i].toLocalFile()); - if (!fi.exists()) { - continue; - } - - QString file = QDir::cleanPath(fi.absoluteFilePath()); - if (fi.isFile()) { - files.append(file); - } else if (urls.size() == 1) { - isDir = true; - files.append(file); - } - } - } - - if (!files.isEmpty()) { - if (isDir) { - VDirectory *dir = g_vnote->getInternalDirectory(files[0]); - if (dir) { - g_mainWin->locateDirectory(dir); - } else { - // External directory. - g_mainWin->showExplorerPanel(true); - g_mainWin->getExplorer()->setRootDirectory(files[0]); - } - } else { - focusWindow(); - g_mainWin->openFiles(files); - } - } - - p_event->acceptProposedAction(); - return; - } - - QTabWidget::dropEvent(p_event); -} - -QVector VEditWindow::getAllTabs() const -{ - int nrTab = count(); - - QVector tabs; - tabs.reserve(nrTab); - for (int i = 0; i < nrTab; ++i) { - tabs.push_back(getTab(i)); - } - - return tabs; -} - -void VEditWindow::checkFileChangeOutside() -{ - // Only check current tab. - VEditTab *tab = getCurrentTab(); - if (tab) { - tab->checkFileChangeOutside(); - } -} - -void VEditWindow::saveAll() -{ - int nrTab = count(); - for (int i = 0; i < nrTab; ++i) { - getTab(i)->saveFile(); - } -} - -void VEditWindow::tabRequestToClose(VEditTab *p_tab) -{ - bool ok = p_tab->closeFile(false); - if (ok) { - removeTab(indexOf(p_tab)); - - // Disconnect all the signals. - disconnect(p_tab, 0, this, 0); - - p_tab->deleteLater(); - } -} - -int VEditWindow::tabBarHeight() const -{ - return tabBar()->height(); -} - -QVector VEditWindow::getTabsNavigationInfo() const -{ - QVector infos; - QTabBar *bar = tabBar(); - for (int i = 0; i < bar->count(); ++i) { - QPoint tl = bar->tabRect(i).topLeft(); - if (tl.x() < 0 || tl.x() >= bar->width()) { - continue; - } - - TabNavigationInfo info; - info.m_topLeft = bar->mapToParent(tl); - info.m_tab = getTab(i); - infos.append(info); - } - - return infos; -} - -bool VEditWindow::eventFilter(QObject *p_obj, QEvent *p_event) -{ - if (p_obj == tabBar() && p_event->type() == QEvent::MouseButtonRelease) { - QMouseEvent *me = static_cast(p_event); - if (me->button() == Qt::MiddleButton) { - // Close current tab. - int idx = tabBar()->tabAt(me->pos()); - if (idx != -1) { - closeTab(idx); - } - } - } - - return QTabWidget::eventFilter(p_obj, p_event); -} diff --git a/src/veditwindow.h b/src/veditwindow.h deleted file mode 100644 index 85c270be..00000000 --- a/src/veditwindow.h +++ /dev/null @@ -1,249 +0,0 @@ -#ifndef VEDITWINDOW_H -#define VEDITWINDOW_H - -#include -#include -#include -#include -#include -#include "vnotebook.h" -#include "vedittab.h" -#include "vconstants.h" -#include "vnotefile.h" - -class QPushButton; -class QActionGroup; -class VEditArea; -class QMenu; - -// Tab info for navigation mode. -struct TabNavigationInfo -{ - // Top left of the tab relative to edit window. - QPoint m_topLeft; - - VEditTab *m_tab; -}; - - -class VEditWindow : public QTabWidget -{ - Q_OBJECT -public: - explicit VEditWindow(VEditArea *editArea, QWidget *parent = 0); - int findTabByFile(const VFile *p_file) const; - int openFile(VFile *p_file, OpenFileMode p_mode); - bool closeFile(const VFile *p_file, bool p_forced); - bool closeFile(const VDirectory *p_dir, bool p_forced); - bool closeFile(const VNotebook *p_notebook, bool p_forced); - void editFile(); - void saveFile(); - - void readFile(bool p_discard = false); - - void saveAndReadFile(); - bool closeAllFiles(bool p_forced); - - // Return outline of current tab. - VTableOfContent getOutline() const; - - // Return current header of current tab. - VHeaderPointer getCurrentHeader() const; - - // Focus to current tab's editor - void focusWindow(); - - // Scroll current tab to header @p_header. - void scrollToHeader(const VHeaderPointer &p_header); - - void updateFileInfo(const VFile *p_file, UpdateAction p_act); - - void updateDirectoryInfo(const VDirectory *p_dir, UpdateAction p_act); - - void updateNotebookInfo(const VNotebook *p_notebook); - - VEditTab *getCurrentTab() const; - - VEditTab *getTab(int tabIndex) const; - - QVector getAllTabsInfo() const; - - QVector getAllTabs() const; - - // Insert a tab with @p_widget. @p_widget is a fully initialized VEditTab. - bool addEditTab(QWidget *p_widget); - // Set whether it is the current window. - void setCurrentWindow(bool p_current); - void clearSearchedWordHighlight(); - void moveCurrentTabOneSplit(bool p_right); - void focusNextTab(bool p_right); - - // Return true if the file list is shown. - bool showOpenedFileList(); - - bool activateTab(int p_sequence); - - // Switch to previous activated tab. - bool alternateTab(); - - // Ask tab @p_index to update its status and propogate. - // The status here means tab status, outline, current header. - // If @p_index is -1, it is current tab. - void updateTabStatus(int p_index = -1); - - // Check whether opened files have been changed outside. - void checkFileChangeOutside(); - - // Auto save file. - void saveAll(); - - int tabBarHeight() const; - - QVector getTabsNavigationInfo() const; - -protected: - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - - // To accept specific drop. - void dragEnterEvent(QDragEnterEvent *p_event) Q_DECL_OVERRIDE; - - // Drop the data. - void dropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE; - - bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE; - -signals: - // Status of current VEditTab has update. - void tabStatusUpdated(const VEditTabInfo &p_info); - - // Requst VEditArea to split this window. - void requestSplitWindow(VEditWindow *p_window, bool p_right = true); - - void requestRemoveSplit(VEditWindow *curWindow); - // This widget or its children get the focus - void getFocused(); - - void outlineChanged(const VTableOfContent &p_outline); - - void currentHeaderChanged(const VHeaderPointer &p_header); - - // Emit when want to show message in status bar. - void statusMessage(const QString &p_msg); - - // Emit when Vim mode status changed. - void vimStatusUpdated(const VVim *p_vim); - -private slots: - // Close tab @p_index. - bool closeTab(int p_index); - - // Split this window on the right/left. - void splitWindow(bool p_right = true); - - void removeSplit(); - void handleTabbarClicked(int p_index); - void handleCurrentIndexChanged(int p_index); - void contextMenuRequested(QPoint pos); - void tabListJump(VFile *p_file); - - void handleTabOutlineChanged(const VTableOfContent &p_outline); - - void handleTabCurrentHeaderChanged(const VHeaderPointer &p_header); - - void updateSplitMenu(QMenu *p_menu); - - void tabbarContextMenuRequested(QPoint p_pos); - void handleLocateAct(); - void handleMoveLeftAct(); - void handleMoveRightAct(); - - // Handle the statusMessage signal of VEditTab. - void handleTabStatusMessage(const QString &p_msg); - - // Handle the vimStatusUpdated() signal of VEditTab. - void handleTabVimStatusUpdated(const VVim *p_vim); - - // Handle the statusUpdated signal of VEditTab. - void handleTabStatusUpdated(const VEditTabInfo &p_info); - - // @p_tab request to close itself. - void tabRequestToClose(VEditTab *p_tab); - -private: - void setupCornerWidget(); - - void removeEditTab(int p_index); - - int insertEditTab(int p_index, VFile *p_file, QWidget *p_page); - - int openFileInTab(VFile *p_file, OpenFileMode p_mode); - - QString generateTooltip(const VFile *p_file) const; - - QString generateTabText(int p_index, const VEditTab *p_tab) const; - - bool canRemoveSplit(); - - // Move tab at @p_tabIdx one split window. - // @p_right: move right or left. - // If there is only one split window, it will request to split current window - // and move the tab to the new split. - void moveTabOneSplit(int p_tabIdx, bool p_right); - - // Update info of tab @p_idx according to the state of the editor and file. - void updateTabInfo(int p_idx); - - // Update the sequence number of all the tabs. - void updateAllTabsSequence(); - - // Connect the signals of VEditTab to this VEditWindow. - void connectEditTab(const VEditTab *p_tab); - - QAction *getRemoveSplitAction(); - - VEditArea *m_editArea; - - // These two members are only used for alternateTab(). - QWidget *m_curTabWidget; - QWidget *m_lastTabWidget; - - // Button in the right corner - QPushButton *rightBtn; - // Button in the left corner - QPushButton *leftBtn; - - // Actions - QAction *m_removeSplitAct; - QAction *m_maximizeSplitAct; - QAction *m_distributeSplitsAct; -}; - -inline QString VEditWindow::generateTooltip(const VFile *p_file) const -{ - if (!p_file) { - return ""; - } - - // [Notebook]path - if (p_file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast(p_file); - return QString("[%1] %2").arg(tmpFile->getNotebookName()).arg(tmpFile->fetchPath()); - } else { - return QString("%1").arg(p_file->fetchPath()); - } -} - -inline QString VEditWindow::generateTabText(int p_index, const VEditTab *p_tab) const -{ - const VFile *file = p_tab->getFile(); - if (!file) { - return ""; - } - - return QString("%1. %2%3%4").arg(QString::number(p_index + c_tabSequenceBase, 10)) - .arg(file->getName()) - .arg(file->isModifiable() ? "" : "#") - .arg(p_tab->isModified() ? "*" : ""); -} - -#endif // VEDITWINDOW_H diff --git a/src/vexplorer.cpp b/src/vexplorer.cpp deleted file mode 100644 index ed32c373..00000000 --- a/src/vexplorer.cpp +++ /dev/null @@ -1,817 +0,0 @@ -#include "vexplorer.h" - -#include -#include -#include - -#include "utils/viconutils.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" -#include "vmainwindow.h" -#include "vcart.h" -#include "vlineedit.h" -#include "vhistorylist.h" -#include "vorphanfile.h" -#include "utils/vimnavigationforwidget.h" - -extern VMainWindow *g_mainWin; - -extern VConfigManager *g_config; - -const QString VExplorer::c_infoShortcutSequence = "F2"; - -VExplorer::VExplorer(QWidget *p_parent) - : QWidget(p_parent), - m_initialized(false), - m_uiInitialized(false), - m_index(-1) -{ -} - -void VExplorer::setupUI() -{ - if (m_uiInitialized) { - return; - } - - m_uiInitialized = true; - - QLabel *dirLabel = new QLabel(tr("Directory"), this); - - m_openBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/dir_item.svg"), - "", - this); - m_openBtn->setToolTip(tr("Open")); - m_openBtn->setProperty("FlatBtn", true); - connect(m_openBtn, &QPushButton::clicked, - this, [this]() { - static QString defaultPath = g_config->getDocumentPathOrHomePath(); - QString dirPath = QFileDialog::getExistingDirectory(this, - tr("Select Root Directory To Explore"), - defaultPath, - QFileDialog::ShowDirsOnly - | QFileDialog::DontResolveSymlinks); - if (!dirPath.isEmpty()) { - defaultPath = VUtils::basePathFromPath(dirPath); - - int idx = addEntry(dirPath); - updateDirectoryComboBox(); - if (idx != -1) { - setCurrentEntry(idx); - } - } - }); - - m_upBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/up.svg"), - "", - this); - m_upBtn->setToolTip(tr("Up")); - m_upBtn->setProperty("FlatBtn", true); - connect(m_upBtn, &QPushButton::clicked, - this, [this]() { - if (checkIndex()) { - QDir dir(m_entries[m_index].m_directory); - if (dir.cdUp()) { - int idx = addEntry(dir.absolutePath()); - updateDirectoryComboBox(); - if (idx != -1) { - setCurrentEntry(idx); - } - } - } - }); - - m_openLocationBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/open_location.svg"), - "", - this); - m_openLocationBtn->setToolTip(tr("Open Directory Location")); - m_openLocationBtn->setProperty("FlatBtn", true); - connect(m_openLocationBtn, &QPushButton::clicked, - this, [this]() { - if (checkIndex()) { - QUrl url = QUrl::fromLocalFile(m_entries[m_index].m_directory); - QDesktopServices::openUrl(url); - } - }); - - m_starBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/star.svg"), - "", - this); - m_starBtn->setToolTip(tr("Star")); - m_starBtn->setProperty("FlatBtn", true); - connect(m_starBtn, &QPushButton::clicked, - this, [this]() { - if (checkIndex()) { - m_entries[m_index].m_isStarred = !m_entries[m_index].m_isStarred; - - g_config->setExplorerEntries(m_entries); - - updateExplorerEntryIndexInConfig(); - - updateStarButton(); - } - }); - - QHBoxLayout *dirLayout = new QHBoxLayout(); - dirLayout->addWidget(dirLabel); - dirLayout->addStretch(); - dirLayout->addWidget(m_openBtn); - dirLayout->addWidget(m_upBtn); - dirLayout->addWidget(m_openLocationBtn); - dirLayout->addWidget(m_starBtn); - dirLayout->setContentsMargins(0, 0, 0, 0); - - m_dirCB = VUtils::getComboBox(this); - m_dirCB->setEditable(true); - m_dirCB->setLineEdit(new VLineEdit(this)); - m_dirCB->setToolTip(tr("Path of the root directory to explore")); - m_dirCB->lineEdit()->setPlaceholderText(tr("Root path to explore")); - m_dirCB->lineEdit()->setProperty("EmbeddedEdit", true); - connect(m_dirCB->lineEdit(), &QLineEdit::editingFinished, - this, [this]() { - QString text = m_dirCB->currentText(); - int idx = addEntry(text); - updateDirectoryComboBox(); - if (idx != -1) { - setCurrentEntry(idx); - } - }); - QCompleter *completer = new QCompleter(this); - QFileSystemModel *fsModel = new QFileSystemModel(completer); - fsModel->setRootPath(""); - completer->setModel(fsModel); - // Enable styling the popup list via QListView::item. - completer->popup()->setItemDelegate(new QStyledItemDelegate(this)); - completer->setCompletionMode(QCompleter::PopupCompletion); -#if defined(Q_OS_WIN) - completer->setCaseSensitivity(Qt::CaseInsensitive); -#else - completer->setCaseSensitivity(Qt::CaseSensitive); -#endif - m_dirCB->lineEdit()->setCompleter(completer); - connect(m_dirCB, SIGNAL(activated(int)), - this, SLOT(handleEntryActivated(int))); - m_dirCB->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); - - QLabel *imgLabel = new QLabel(tr("Image Folder"), this); - - m_imgFolderEdit = new VLineEdit(this); - m_imgFolderEdit->setPlaceholderText(tr("Use global configuration (%1)") - .arg(g_config->getImageFolderExt())); - QString imgFolderTip = tr("Set the path of the image folder to store images " - "of files within the root directory.\nIf absolute path is used, " - "VNote will not manage those images." - "(empty to use global configuration)"); - m_imgFolderEdit->setToolTip(imgFolderTip); - connect(m_imgFolderEdit, &QLineEdit::editingFinished, - this, [this]() { - if (checkIndex()) { - QString folder = m_imgFolderEdit->text(); - if (folder.isEmpty() || VUtils::checkPathLegal(folder)) { - m_entries[m_index].m_imageFolder = folder; - if (m_entries[m_index].m_isStarred) { - g_config->setExplorerEntries(m_entries); - } - } else { - m_imgFolderEdit->setText(m_entries[m_index].m_imageFolder); - } - } - }); - - // New file/dir. - m_newFileBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/create_note_tb.svg"), - "", - this); - m_newFileBtn->setToolTip(tr("New File")); - m_newFileBtn->setProperty("FlatBtn", true); - connect(m_newFileBtn, &QPushButton::clicked, - this, &VExplorer::newFile); - - m_newDirBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/create_rootdir_tb.svg"), - "", - this); - m_newDirBtn->setToolTip(tr("New Folder")); - m_newDirBtn->setProperty("FlatBtn", true); - connect(m_newDirBtn, &QPushButton::clicked, - this, &VExplorer::newFolder); - - QHBoxLayout *btnLayout = new QHBoxLayout(); - btnLayout->addStretch(); - btnLayout->addWidget(m_newFileBtn); - btnLayout->addWidget(m_newDirBtn); - btnLayout->setContentsMargins(0, 0, 0, 0); - - QFileSystemModel *dirModel = new QFileSystemModel(this); - dirModel->setRootPath(""); - m_tree = new QTreeView(this); - m_tree->setModel(dirModel); - m_tree->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_tree->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_tree, &QTreeView::customContextMenuRequested, - this, &VExplorer::handleContextMenuRequested); - connect(m_tree, &QTreeView::activated, - this, [this](const QModelIndex &p_index) { - QFileSystemModel *model = static_cast(m_tree->model()); - if (!model->isDir(p_index)) { - QStringList files; - files << model->filePath(p_index); - - // If there is no directory entry currently, new one using the parent dir. - if (m_index == -1 || m_entries.isEmpty()) { - setRootDirectory(VUtils::basePathFromPath(files[0])); - } - - openFiles(files, g_config->getNoteOpenMode()); - } - }); - connect(m_tree, &QTreeView::expanded, - this, &VExplorer::resizeTreeToContents); - connect(m_tree, &QTreeView::collapsed, - this, &VExplorer::resizeTreeToContents); - connect(dirModel, &QFileSystemModel::directoryLoaded, - this, &VExplorer::resizeTreeToContents); - - m_tree->setHeaderHidden(true); - // Show only the Name column. - for (int i = 1; i < dirModel->columnCount(); ++i) { - m_tree->hideColumn(i); - } - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(dirLayout); - mainLayout->addWidget(m_dirCB); - mainLayout->addWidget(imgLabel); - mainLayout->addWidget(m_imgFolderEdit); - mainLayout->addLayout(btnLayout); - mainLayout->addWidget(m_tree); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -void VExplorer::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - setupUI(); - - QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this); - infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(infoShortcut, &QShortcut::activated, - this, [this]() { - QModelIndexList selectedIdx = m_tree->selectionModel()->selectedRows(); - if (selectedIdx.size() == 1) { - QFileSystemModel *model = static_cast(m_tree->model()); - QString filePath = model->filePath(selectedIdx[0]); - renameFile(filePath); - } - }); - - g_config->getExplorerEntries(m_entries); - m_index = g_config->getExplorerCurrentIndex(); - if (m_entries.isEmpty()) { - m_index = -1; - g_config->setExplorerCurrentIndex(m_index); - } else if (m_index < 0 || m_index >= m_entries.size()) { - m_index = 0; - g_config->setExplorerCurrentIndex(m_index); - } - - updateDirectoryComboBox(); - - setCurrentEntry(m_index); -} - -void VExplorer::showEvent(QShowEvent *p_event) -{ - init(); - - QWidget::showEvent(p_event); -} - -void VExplorer::focusInEvent(QFocusEvent *p_event) -{ - init(); - - QWidget::focusInEvent(p_event); - - if (m_index < 0) { - m_openBtn->setFocus(); - } else { - m_tree->setFocus(); - } -} - -void VExplorer::updateUI() -{ - -} - -void VExplorer::updateDirectoryComboBox() -{ - m_dirCB->clear(); - - for (int i = 0; i < m_entries.size(); ++i) { - m_dirCB->addItem(QDir::toNativeSeparators(m_entries[i].m_directory)); - m_dirCB->setItemData(i, m_entries[i].m_directory, Qt::ToolTipRole); - } - - m_dirCB->setCurrentIndex(m_index); -} - -int VExplorer::addEntry(const QString &p_dir) -{ - if (p_dir.isEmpty() || !QFileInfo::exists(p_dir) || !QDir::isAbsolutePath(p_dir)) { - return -1; - } - - QString dir(QDir::cleanPath(p_dir)); - int idx = -1; - for (idx = 0; idx < m_entries.size(); ++idx) { - if (VUtils::equalPath(dir, m_entries[idx].m_directory)) { - break; - } - } - - if (idx < m_entries.size()) { - return idx; - } - - m_entries.append(VExplorerEntry(QFileInfo(dir).absoluteFilePath(), "")); - return m_entries.size() - 1; -} - -void VExplorer::handleEntryActivated(int p_idx) -{ - bool valid = false; - QString imgFolder; - - if (p_idx >= 0 && p_idx < m_entries.size()) { - valid = true; - imgFolder = m_entries[p_idx].m_imageFolder; - } else { - p_idx = -1; - } - - m_index = p_idx; - - updateExplorerEntryIndexInConfig(); - - m_imgFolderEdit->setText(imgFolder); - m_imgFolderEdit->setEnabled(valid); - - m_openLocationBtn->setEnabled(valid); - m_upBtn->setEnabled(valid); - m_newFileBtn->setEnabled(valid); - m_newDirBtn->setEnabled(valid); - - updateStarButton(); - - // Check if exists. - if (checkIndex() && !QFileInfo::exists(m_entries[m_index].m_directory)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to open directory %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_entries[m_index].m_directory), - tr("Please check if the directory exists."), - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - } - - updateTree(); -} - -void VExplorer::updateStarButton() -{ - // -1 for disabled, 0 for star, 1 for unstar. - int star = -1; - - if (checkIndex()) { - star = m_entries[m_index].m_isStarred ? 1 : 0; - } - - bool enabled = true; - switch (star) { - default: - enabled = false; - V_FALLTHROUGH; - case 0: - m_starBtn->setEnabled(enabled); - m_starBtn->setIcon(VIconUtils::buttonIcon(":/resources/icons/star.svg")); - m_starBtn->setToolTip(tr("Star")); - break; - - case 1: - m_starBtn->setEnabled(enabled); - m_starBtn->setIcon(VIconUtils::buttonIcon(":/resources/icons/unstar.svg")); - m_starBtn->setToolTip(tr("Unstar")); - break; - } -} - -void VExplorer::setCurrentEntry(int p_index) -{ - m_dirCB->setCurrentIndex(p_index); - - handleEntryActivated(p_index); -} - -void VExplorer::updateExplorerEntryIndexInConfig() -{ - int idx = -1; - if (m_index >= 0 && m_index < m_entries.size()) { - int starIdx = -1; - for (int j = 0; j <= m_index; ++j) { - if (m_entries[j].m_isStarred) { - ++starIdx; - } - } - - if (starIdx > -1) { - idx = starIdx; - } - } - - g_config->setExplorerCurrentIndex(idx); -} - -void VExplorer::updateTree() -{ - if (checkIndex()) { - QString pa = QDir::cleanPath(m_entries[m_index].m_directory); - QFileSystemModel *model = static_cast(m_tree->model()); - model->setRootPath(pa); - const QModelIndex rootIndex = model->index(pa); - if (rootIndex.isValid()) { - m_tree->setRootIndex(rootIndex); - resizeTreeToContents(); - return; - } else { - model->setRootPath(""); - } - } - - m_tree->reset(); - resizeTreeToContents(); -} - -void VExplorer::handleContextMenuRequested(QPoint p_pos) -{ - QModelIndex index = m_tree->indexAt(p_pos); - if (!index.isValid()) { - return; - } - - QMenu menu(this); - menu.setToolTipsVisible(true); - - QFileSystemModel *model = static_cast(m_tree->model()); - QModelIndexList selectedIdx = m_tree->selectionModel()->selectedRows(); - if (selectedIdx.size() == 1 && model->isDir(selectedIdx[0])) { - QString filePath = model->filePath(selectedIdx[0]); - - QAction *setRootAct = new QAction(VIconUtils::menuIcon(":/resources/icons/explore_root.svg"), - tr("Set As Root"), - &menu); - setRootAct->setToolTip(tr("Set current folder as the root directory to explore")); - connect(setRootAct, &QAction::triggered, - this, [this, filePath]() { - setRootDirectory(filePath); - }); - menu.addAction(setRootAct); - - QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"), - tr("Open Folder Location"), - &menu); - openLocationAct->setToolTip(tr("Explore this folder in operating system")); - connect(openLocationAct, &QAction::triggered, - this, [this, filePath]() { - QDesktopServices::openUrl(QUrl::fromLocalFile(filePath)); - }); - menu.addAction(openLocationAct); - - menu.addSeparator(); - - QAction *fileInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), - tr("&Info (Rename)\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)), - &menu); - fileInfoAct->setToolTip(tr("View and edit current folder's information")); - connect(fileInfoAct, &QAction::triggered, - this, [this, filePath]() { - renameFile(filePath); - }); - menu.addAction(fileInfoAct); - - menu.exec(m_tree->mapToGlobal(p_pos)); - return; - } - - bool allFiles = true; - QStringList selectedFiles; - for (auto const & it : selectedIdx) { - if (model->isDir(it)) { - allFiles = false; - break; - } - - selectedFiles << model->filePath(it); - } - - if (!allFiles) { - return; - } - - // Only files are selected. - // We do not support copy/cut/deletion of files. - QAction *openInReadAct = new QAction(VIconUtils::menuIcon(":/resources/icons/reading.svg"), - tr("Open In Read Mode"), - &menu); - openInReadAct->setToolTip(tr("Open selected files in read mode")); - connect(openInReadAct, &QAction::triggered, - this, [this, selectedFiles]() { - openFiles(selectedFiles, OpenFileMode::Read, true); - }); - menu.addAction(openInReadAct); - - QAction *openInEditAct = new QAction(VIconUtils::menuIcon(":/resources/icons/editing.svg"), - tr("Open In Edit Mode"), - &menu); - openInEditAct->setToolTip(tr("Open selected files in edit mode")); - connect(openInEditAct, &QAction::triggered, - this, [this, selectedFiles]() { - openFiles(selectedFiles, OpenFileMode::Edit, true); - }); - menu.addAction(openInEditAct); - - menu.addSeparator(); - - if (selectedFiles.size() == 1) { - QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"), - tr("Open File Location"), - &menu); - openLocationAct->setToolTip(tr("Explore the folder containing this file in operating system")); - connect(openLocationAct, &QAction::triggered, - this, [this, filePath = selectedFiles[0]] () { - QDesktopServices::openUrl(QUrl::fromLocalFile(VUtils::basePathFromPath(filePath))); - }); - menu.addAction(openLocationAct); - - menu.addSeparator(); - } - - QAction *addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"), - tr("Add To Cart"), - &menu); - addToCartAct->setToolTip(tr("Add selected files to Cart for further processing")); - connect(addToCartAct, &QAction::triggered, - this, [this, selectedFiles]() { - VCart *cart = g_mainWin->getCart(); - for (int i = 0; i < selectedFiles.size(); ++i) { - cart->addFile(selectedFiles[i]); - } - - g_mainWin->showStatusMessage(tr("%1 %2 added to Cart") - .arg(selectedFiles.size()) - .arg(selectedFiles.size() > 1 ? tr("files") : tr("file"))); - }); - menu.addAction(addToCartAct); - - QAction *pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"), - tr("Pin To History"), - &menu); - pinToHistoryAct->setToolTip(tr("Pin selected files to History")); - connect(pinToHistoryAct, &QAction::triggered, - this, [this, selectedFiles]() { - g_mainWin->getHistoryList()->pinFiles(selectedFiles); - g_mainWin->showStatusMessage(tr("%1 %2 pinned to History") - .arg(selectedFiles.size()) - .arg(selectedFiles.size() > 1 ? tr("files") : tr("file"))); - }); - menu.addAction(pinToHistoryAct); - - if (selectedFiles.size() == 1) { - QAction *fileInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), - tr("&Info (Rename)\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)), - &menu); - fileInfoAct->setToolTip(tr("View and edit current file's information")); - connect(fileInfoAct, &QAction::triggered, - this, [this, filePath = selectedFiles[0]]() { - renameFile(filePath); - }); - menu.addAction(fileInfoAct); - } - - menu.exec(m_tree->mapToGlobal(p_pos)); -} - -void VExplorer::openFiles(const QStringList &p_files, - OpenFileMode p_mode, - bool p_forceMode) -{ - if (!p_files.isEmpty()) { - Q_ASSERT(checkIndex()); - QString imgFolder = m_entries[m_index].m_imageFolder; - - QVector vfiles = g_mainWin->openFiles(p_files, false, p_mode, p_forceMode, false); - - // Set image folder. - for (auto it : vfiles) { - if (it->getType() == FileType::Orphan) { - static_cast(it)->setImageFolder(imgFolder); - } - } - } -} - -void VExplorer::resizeTreeToContents() -{ - m_tree->resizeColumnToContents(0); -} - -// 1. When only one folder is selected, create a file in that folder. -// 2. Otherwise, create a file in the root directory. -void VExplorer::newFile() -{ - Q_ASSERT(checkIndex()); - - QString parentDir; - - QFileSystemModel *model = static_cast(m_tree->model()); - QModelIndexList selectedIdx = m_tree->selectionModel()->selectedRows(); - if (selectedIdx.size() == 1 && model->isDir(selectedIdx[0])) { - parentDir = model->filePath(selectedIdx[0]); - } else { - parentDir = m_entries[m_index].m_directory; - } - - qDebug() << "new file in" << parentDir; - - QString name = VUtils::promptForFileName(tr("New File"), - tr("File name (%1):").arg(parentDir), - "", - parentDir, - g_mainWin); - - if (name.isEmpty()) { - return; - } - - QDir paDir(parentDir); - QString filePath = paDir.filePath(name); - QFile file(filePath); - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "Fail to create file" << filePath; - VUtils::showMessage(QMessageBox::Warning, - tr("New File"), - tr("Fail to create file %2.") - .arg(g_config->c_dataTextStyle) - .arg(filePath), - "", - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - return; - } - - file.close(); - - m_tree->setFocus(); - - // Select the file. - const QModelIndex fileIndex = model->index(filePath); - Q_ASSERT(fileIndex.isValid()); - m_tree->scrollTo(fileIndex); - m_tree->clearSelection(); - m_tree->setCurrentIndex(fileIndex); -} - -// 1. When only one folder is selected, create a folder in that folder. -// 2. Otherwise, create a folder in the root directory. -void VExplorer::newFolder() -{ - Q_ASSERT(checkIndex()); - - QString parentDir; - - QFileSystemModel *model = static_cast(m_tree->model()); - QModelIndexList selectedIdx = m_tree->selectionModel()->selectedRows(); - if (selectedIdx.size() == 1 && model->isDir(selectedIdx[0])) { - parentDir = model->filePath(selectedIdx[0]); - } else { - parentDir = m_entries[m_index].m_directory; - } - - qDebug() << "new folder in" << parentDir; - - QString name = VUtils::promptForFileName(tr("New Folder"), - tr("Folder name (%1):").arg(parentDir), - "", - parentDir, - g_mainWin); - - if (name.isEmpty()) { - return; - } - - QDir paDir(parentDir); - QString folderPath = paDir.filePath(name); - if (!paDir.mkdir(name)) { - qWarning() << "Fail to create folder" << folderPath; - VUtils::showMessage(QMessageBox::Warning, - tr("New Folder"), - tr("Fail to create folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(folderPath), - "", - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - return; - } - - m_tree->setFocus(); - - // Select the folder. - const QModelIndex folderIndex = model->index(folderPath); - Q_ASSERT(folderIndex.isValid()); - m_tree->scrollTo(folderIndex); - m_tree->clearSelection(); - m_tree->setCurrentIndex(folderIndex); -} - -void VExplorer::renameFile(const QString &p_filePath) -{ - Q_ASSERT(checkIndex()); - - QFileInfo fi(p_filePath); - QString parentDir = fi.path(); - QString oldName = fi.fileName(); - - QString name = VUtils::promptForFileName(tr("File Information"), - tr("Rename file (%1):").arg(p_filePath), - oldName, - parentDir, - g_mainWin); - - if (name.isEmpty()) { - return; - } - - QDir paDir(parentDir); - if (!paDir.rename(oldName, name)) { - qWarning() << "Fail to rename" << p_filePath; - VUtils::showMessage(QMessageBox::Warning, - tr("File Information"), - tr("Fail to rename file %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_filePath), - "", - QMessageBox::Ok, - QMessageBox::Ok, - g_mainWin); - return; - } -} - -void VExplorer::setRootDirectory(const QString &p_path) -{ - if (p_path.isEmpty()) { - return; - } - - init(); - - qDebug() << "set new root directory" << p_path; - - int idx = addEntry(p_path); - updateDirectoryComboBox(); - if (idx != -1) { - setCurrentEntry(idx); - } -} - -void VExplorer::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(m_tree, p_event)) { - return; - } - - QWidget::keyPressEvent(p_event); -} - -QString VExplorer::getRootDirectory() const -{ - const_cast(this)->init(); - - if (checkIndex()) { - return m_entries[m_index].m_directory; - } - - return QString(); -} diff --git a/src/vexplorer.h b/src/vexplorer.h deleted file mode 100644 index e9e5c89b..00000000 --- a/src/vexplorer.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef VEXPLORER_H -#define VEXPLORER_H - -#include -#include - -#include "vexplorerentry.h" -#include "vconstants.h" - -class QPushButton; -class QTreeView; -class QTreeWidgetItem; -class QShowEvent; -class QFocusEvent; -class QComboBox; -class VLineEdit; - -class VExplorer : public QWidget -{ - Q_OBJECT -public: - explicit VExplorer(QWidget *p_parent = nullptr); - - void setRootDirectory(const QString &p_path); - - QString getRootDirectory() const; - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void handleEntryActivated(int p_idx); - - void handleContextMenuRequested(QPoint p_pos); - -private: - void setupUI(); - - void init(); - - void updateUI(); - - void updateDirectoryComboBox(); - - // Add an entry to m_entries with @p_dir being the path of the entry. - // Return the index of the corresponding entry if succeed; otherwise, - // return -1. - int addEntry(const QString &p_dir); - - void setCurrentEntry(int p_index); - - bool checkIndex() const; - - void updateExplorerEntryIndexInConfig(); - - void updateStarButton(); - - void updateTree(); - - void openFiles(const QStringList &p_files, - OpenFileMode p_mode, - bool p_forceMode = false); - - void resizeTreeToContents(); - - void newFile(); - - void newFolder(); - - void renameFile(const QString &p_filePath); - - bool m_initialized; - - bool m_uiInitialized; - - QVector m_entries; - - int m_index; - - QPushButton *m_openBtn; - QPushButton *m_upBtn; - QPushButton *m_openLocationBtn; - QPushButton *m_starBtn; - QComboBox *m_dirCB; - VLineEdit *m_imgFolderEdit; - QPushButton *m_newFileBtn; - QPushButton *m_newDirBtn; - QTreeView *m_tree; - - static const QString c_infoShortcutSequence; -}; - -inline bool VExplorer::checkIndex() const -{ - return m_index >= 0 && m_index < m_entries.size(); -} - -#endif // VEXPLORER_H diff --git a/src/vexplorerentry.h b/src/vexplorerentry.h deleted file mode 100644 index 939f3a48..00000000 --- a/src/vexplorerentry.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef VEXPLORERENTRY_H -#define VEXPLORERENTRY_H - -#include - -namespace ExplorerConfig -{ - static const QString c_directory = "directory"; - static const QString c_imageFolder = "image_folder"; -} - -class VExplorerEntry -{ -public: - VExplorerEntry() - : m_isStarred(false) - { - } - - VExplorerEntry(const QString &p_directory, - const QString &p_imageFolder, - bool p_isStarred = false) - : m_directory(p_directory), - m_imageFolder(p_imageFolder), - m_isStarred(p_isStarred) - { - } - - static VExplorerEntry fromSettings(const QSettings *p_settings) - { - VExplorerEntry entry; - entry.m_directory = p_settings->value(ExplorerConfig::c_directory).toString(); - entry.m_imageFolder = p_settings->value(ExplorerConfig::c_imageFolder).toString(); - entry.m_isStarred = true; - return entry; - } - - void toSettings(QSettings *p_settings) const - { - p_settings->setValue(ExplorerConfig::c_directory, m_directory); - p_settings->setValue(ExplorerConfig::c_imageFolder, m_imageFolder); - } - - QString m_directory; - - QString m_imageFolder; - - bool m_isStarred; -}; - -#endif // VEXPLORERENTRY_H diff --git a/src/vexporter.cpp b/src/vexporter.cpp deleted file mode 100644 index e368cf88..00000000 --- a/src/vexporter.cpp +++ /dev/null @@ -1,1053 +0,0 @@ -#include "vexporter.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vconfigmanager.h" -#include "vfile.h" -#include "vwebview.h" -#include "utils/vutils.h" -#include "vpreviewpage.h" -#include "vconstants.h" -#include "vmarkdownconverter.h" -#include "vdocument.h" -#include "utils/vwebutils.h" - -extern VConfigManager *g_config; - -extern VWebUtils *g_webUtils; - -VExporter::VExporter(QWidget *p_parent) - : QObject(p_parent), - m_webViewer(NULL), - m_state(ExportState::Idle), - m_askedToStop(false) -{ -} - -static QString marginToStrMM(qreal p_margin) -{ - return QString("%1mm").arg(p_margin); -} - -void VExporter::prepareExport(const ExportOption &p_opt) -{ - bool isPdf = p_opt.m_format == ExportFormat::PDF - || p_opt.m_format == ExportFormat::OnePDF - || (p_opt.m_format == ExportFormat::Custom - && p_opt.m_customOpt.m_pdfLike); - bool extraToc = isPdf - && !p_opt.m_pdfOpt.m_wkhtmltopdf - && p_opt.m_pdfOpt.m_enableTableOfContents; - - m_htmlTemplate = VUtils::generateHtmlTemplate(p_opt.m_renderer, - p_opt.m_renderBg, - p_opt.m_renderStyle, - p_opt.m_renderCodeBlockStyle, - isPdf, - isPdf && p_opt.m_pdfOpt.m_wkhtmltopdf, - extraToc); - - bool outline = p_opt.m_htmlOpt.m_outlinePanel - && !isPdf - && (p_opt.m_format == ExportFormat::HTML - || p_opt.m_format == ExportFormat::Custom); - m_exportHtmlTemplate = VUtils::generateExportHtmlTemplate(p_opt.m_renderBg, - isPdf && p_opt.m_pdfOpt.m_wkhtmltopdf, - outline); - - m_pageLayout = *(p_opt.m_pdfOpt.m_layout); - - prepareWKArguments(p_opt.m_pdfOpt); -} - -void VExporter::prepareWKArguments(const ExportPDFOption &p_opt) -{ - m_wkArgs.clear(); - m_wkArgs << "--page-size" << m_pageLayout.pageSize().key(); - m_wkArgs << "--orientation" - << (m_pageLayout.orientation() == QPageLayout::Portrait ? "Portrait" : "Landscape"); - - QMarginsF marginsMM = m_pageLayout.margins(QPageLayout::Millimeter); - m_wkArgs << "--margin-bottom" << marginToStrMM(marginsMM.bottom()); - m_wkArgs << "--margin-left" << marginToStrMM(marginsMM.left()); - m_wkArgs << "--margin-right" << marginToStrMM(marginsMM.right()); - m_wkArgs << "--margin-top" << marginToStrMM(marginsMM.top()); - - QString footer; - switch (p_opt.m_wkPageNumber) { - case ExportPageNumber::Left: - footer = "--footer-left"; - break; - - case ExportPageNumber::Center: - footer = "--footer-center"; - break; - - case ExportPageNumber::Right: - footer = "--footer-right"; - break; - - default: - break; - } - - if (!footer.isEmpty()) { - m_wkArgs << footer << "[page]" - << "--footer-spacing" << QString::number(marginsMM.bottom() / 3, 'f', 2); - } - - // Title. - if (!p_opt.m_wkTitle.isEmpty()) { - m_wkArgs << "--title" << p_opt.m_wkTitle; - } - - m_wkArgs << "--encoding" << "utf-8"; - m_wkArgs << (p_opt.m_wkEnableBackground ? "--background" : "--no-background"); - - // Delay for MathJax. - if (p_opt.m_wkhtmltopdf) { - m_wkArgs << "--javascript-delay" << "10000"; - } - - // Append additional global option. - if (!p_opt.m_wkExtraArgs.isEmpty()) { - m_wkArgs.append(VUtils::parseCombinedArgString(p_opt.m_wkExtraArgs)); - } - - // TOC option. - if (p_opt.m_enableTableOfContents) { - m_wkArgs << "toc" << "--toc-text-size-shrink" << "1.0"; - } -} - -bool VExporter::exportPDF(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg) -{ - return exportViaWebView(p_file, p_opt, p_outputFile, p_errMsg); -} - -bool VExporter::exportHTML(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg) -{ - return exportViaWebView(p_file, p_opt, p_outputFile, p_errMsg); -} - -static void replaceArgument(QString &p_cmd, const QString &p_arg, const QString &p_val) -{ - if (p_val.startsWith("\"")) { - // Check if the arg has been already surrounded by ". - int pos = 0; - while (pos < p_cmd.size()) { - int idx = p_cmd.indexOf(p_arg, pos); - if (idx == -1) { - break; - } - - int len = p_arg.size(); - int nidx = idx; - if (idx > 0 && p_cmd[idx - 1] == '"') { - --nidx; - len += 1; - } - - if (idx + p_arg.size() < p_cmd.size() - && p_cmd[idx + p_arg.size()] == '"') { - len += 1; - } - - p_cmd.replace(nidx, len, p_val); - pos = nidx + p_val.size() - len; - } - } else { - p_cmd.replace(p_arg, p_val); - } -} - -static QString evaluateCommand(const ExportCustomOption &p_opt, - const QString &p_input, - const QString &p_inputFolder, - const QString &p_output) -{ - QString cmd(p_opt.m_cmd); - replaceArgument(cmd, "%0", p_input); - replaceArgument(cmd, "%1", p_output); - replaceArgument(cmd, "%2", QDir::toNativeSeparators(p_opt.m_cssUrl)); - replaceArgument(cmd, "%3", p_inputFolder); - replaceArgument(cmd, "%4", QDir::toNativeSeparators(p_opt.m_codeBlockCssUrl)); - - return cmd; -} - -bool VExporter::exportCustom(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg) -{ - const ExportCustomOption &customOpt = p_opt.m_customOpt; - if (customOpt.m_srcFormat == ExportCustomOption::Markdown) { - // Use Markdown file as input. - QList files; - files.append(QDir::toNativeSeparators(p_file->fetchPath())); - return convertFilesViaCustom(files, p_outputFile, customOpt, p_errMsg); - } else { - return exportViaWebView(p_file, p_opt, p_outputFile, p_errMsg); - } -} - -void VExporter::initWebViewer(VFile *p_file, const ExportOption &p_opt) -{ - Q_ASSERT(!m_webViewer); - - m_webViewer = new VWebView(p_file, static_cast(parent())); - m_webViewer->hide(); - - VPreviewPage *page = new VPreviewPage(m_webViewer); - m_webViewer->setPage(page); - connect(page, &VPreviewPage::loadFinished, - this, &VExporter::handleLoadFinished); - connect(page->profile(), &QWebEngineProfile::downloadRequested, - this, &VExporter::handleDownloadRequested); - - m_webDocument = new VDocument(p_file, m_webViewer); - connect(m_webDocument, &VDocument::logicsFinished, - this, &VExporter::handleLogicsFinished); - - QWebChannel *channel = new QWebChannel(m_webViewer); - channel->registerObject(QStringLiteral("content"), m_webDocument); - page->setWebChannel(channel); - - // Need to generate HTML using Hoedown. - if (p_opt.m_renderer == MarkdownConverterType::Hoedown) { - VMarkdownConverter mdConverter; - QString toc; - QString html = mdConverter.generateHtml(p_file->getContent(), - g_config->getMarkdownExtensions(), - toc); - bool isPdf = p_opt.m_format == ExportFormat::PDF - || p_opt.m_format == ExportFormat::OnePDF; - bool extraToc = isPdf - && !p_opt.m_pdfOpt.m_wkhtmltopdf - && p_opt.m_pdfOpt.m_enableTableOfContents; - if (extraToc && !toc.isEmpty()) { - // Add toc to html. - QString div = "
    " + toc + "
    \n"; - html = div + html; - } - - m_webDocument->setHtml(html); - } - - m_baseUrl = p_file->getBaseUrl(); - m_webViewer->setHtml(m_htmlTemplate, m_baseUrl); -} - -void VExporter::handleLogicsFinished() -{ - Q_ASSERT(!(m_noteState & NoteState::WebLogicsReady)); - m_noteState = NoteState(m_noteState | NoteState::WebLogicsReady); -} - -void VExporter::handleLoadFinished(bool p_ok) -{ - Q_ASSERT(!(m_noteState & NoteState::WebLoadFinished)); - m_noteState = NoteState(m_noteState | NoteState::WebLoadFinished); - - if (!p_ok) { - m_noteState = NoteState(m_noteState | NoteState::Failed); - } -} - -void VExporter::clearWebViewer() -{ - // m_webDocument will be freeed by QObject. - delete m_webViewer; - m_webViewer = NULL; - m_webDocument = NULL; - m_baseUrl.clear(); -} - -bool VExporter::exportToPDF(VWebView *p_webViewer, - const QString &p_filePath, - const QPageLayout &p_layout) -{ - int pdfPrinted = 0; - p_webViewer->page()->printToPdf([&, this](const QByteArray &p_result) { - if (p_result.isEmpty() || this->m_state == ExportState::Cancelled) { - pdfPrinted = -1; - return; - } - - V_ASSERT(!p_filePath.isEmpty()); - - if (!VUtils::writeFileToDisk(p_filePath, p_result)) { - pdfPrinted = -1; - return; - } - - pdfPrinted = 1; - }, p_layout); - - while (pdfPrinted == 0) { - VUtils::sleepWait(100); - - if (m_state == ExportState::Cancelled) { - break; - } - } - - return pdfPrinted == 1; -} - -bool VExporter::exportToPDFViaWK(VDocument *p_webDocument, - const ExportPDFOption &p_opt, - const QString &p_filePath, - QString *p_errMsg) -{ - int pdfExported = 0; - - connect(p_webDocument, &VDocument::htmlContentFinished, - this, [&, this](const QString &p_headContent, - const QString &p_styleContent, - const QString &p_bodyContent) { - if (p_bodyContent.isEmpty() || this->m_state == ExportState::Cancelled) { - pdfExported = -1; - return; - } - - Q_ASSERT(!p_filePath.isEmpty()); - - // Save HTML to a temp dir. - QTemporaryDir tmpDir; - if (!tmpDir.isValid()) { - pdfExported = -1; - return; - } - - QString htmlPath = tmpDir.filePath("vnote_tmp.html"); - QString title = p_webDocument->getFile()->getName(); - title = QFileInfo(title).completeBaseName(); - if (!outputToHTMLFile(htmlPath, - title, - p_headContent, - p_styleContent, - p_bodyContent, - true, - true, - false)) { - pdfExported = -1; - return; - } - - // Convert via wkhtmltopdf. - QList files; - files.append(htmlPath); - if (!htmlsToPDFViaWK(files, p_filePath, p_opt, p_errMsg)) { - pdfExported = -1; - } else { - pdfExported = 1; - } - }); - - p_webDocument->getHtmlContentAsync(); - - while (pdfExported == 0) { - VUtils::sleepWait(100); - - if (m_state == ExportState::Cancelled) { - break; - } - } - - return pdfExported == 1; -} - -bool VExporter::exportToCustom(VDocument *p_webDocument, - const ExportCustomOption &p_opt, - const QString &p_filePath, - QString *p_errMsg) -{ - int exported = 0; - - connect(p_webDocument, &VDocument::htmlContentFinished, - this, [&, this](const QString &p_headContent, - const QString &p_styleContent, - const QString &p_bodyContent) { - if (p_bodyContent.isEmpty() || this->m_state == ExportState::Cancelled) { - exported = -1; - return; - } - - Q_ASSERT(!p_filePath.isEmpty()); - - // Save HTML to a temp dir. - QTemporaryDir tmpDir; - if (!tmpDir.isValid()) { - exported = -1; - return; - } - - QString htmlPath = tmpDir.filePath("vnote_tmp.html"); - QString title = p_webDocument->getFile()->getName(); - title = QFileInfo(title).completeBaseName(); - if (!outputToHTMLFile(htmlPath, - title, - p_headContent, - p_styleContent, - p_bodyContent, - true, - true, - false)) { - exported = -1; - return; - } - - // Convert via custom command. - QList files; - files.append(htmlPath); - if (!convertFilesViaCustom(files, p_filePath, p_opt, p_errMsg)) { - exported = -1; - } else { - exported = 1; - } - }); - - p_webDocument->getHtmlContentAsync(); - - while (exported == 0) { - VUtils::sleepWait(100); - - if (m_state == ExportState::Cancelled) { - break; - } - } - - return exported == 1; -} - -bool VExporter::exportViaWebView(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg) -{ - Q_UNUSED(p_errMsg); - - bool ret = false; - - bool isOpened = p_file->isOpened(); - if (!isOpened && !p_file->open()) { - goto exit; - } - - Q_ASSERT(m_state == ExportState::Idle); - m_state = ExportState::Busy; - - clearNoteState(); - - initWebViewer(p_file, p_opt); - - while (!isNoteStateReady()) { - VUtils::sleepWait(100); - - if (m_state == ExportState::Cancelled) { - goto exit; - } - - if (isNoteStateFailed()) { - m_state = ExportState::Failed; - goto exit; - } - - if (m_askedToStop) { - m_state = ExportState::Cancelled; - goto exit; - } - } - - // Wait to ensure Web side is really ready. - VUtils::sleepWait(200); - - if (m_state == ExportState::Cancelled) { - goto exit; - } - - { - - bool exportRet = false; - switch (p_opt.m_format) { - case ExportFormat::PDF: - V_FALLTHROUGH; - case ExportFormat::OnePDF: - if (p_opt.m_pdfOpt.m_wkhtmltopdf) { - exportRet = exportToPDFViaWK(m_webDocument, - p_opt.m_pdfOpt, - p_outputFile, - p_errMsg); - } else { - exportRet = exportToPDF(m_webViewer, - p_outputFile, - m_pageLayout); - } - - break; - - case ExportFormat::HTML: - if (p_opt.m_htmlOpt.m_mimeHTML) { - exportRet = exportToMHTML(m_webViewer, - p_opt.m_htmlOpt, - p_outputFile); - } else { - exportRet = exportToHTML(m_webDocument, - p_opt.m_htmlOpt, - p_outputFile); - } - - break; - - case ExportFormat::Custom: - exportRet = exportToCustom(m_webDocument, - p_opt.m_customOpt, - p_outputFile, - p_errMsg); - break; - - default: - break; - } - - clearNoteState(); - - if (!isOpened) { - p_file->close(); - } - - if (exportRet) { - m_state = ExportState::Successful; - } else { - m_state = ExportState::Failed; - } - - } - -exit: - clearWebViewer(); - - if (m_state == ExportState::Successful) { - ret = true; - } - - m_state = ExportState::Idle; - - return ret; -} - -bool VExporter::exportToHTML(VDocument *p_webDocument, - const ExportHTMLOption &p_opt, - const QString &p_filePath) -{ - int htmlExported = 0; - - connect(p_webDocument, &VDocument::htmlContentFinished, - this, [&, this](const QString &p_headContent, - const QString &p_styleContent, - const QString &p_bodyContent) { - if (p_bodyContent.isEmpty() || this->m_state == ExportState::Cancelled) { - htmlExported = -1; - return; - } - - Q_ASSERT(!p_filePath.isEmpty()); - - QString title = p_webDocument->getFile()->getName(); - title = QFileInfo(title).completeBaseName(); - if (!outputToHTMLFile(p_filePath, - title, - p_headContent, - p_styleContent, - p_bodyContent, - p_opt.m_embedCssStyle, - p_opt.m_completeHTML, - p_opt.m_embedImages)) { - htmlExported = -1; - return; - } - - htmlExported = 1; - }); - - p_webDocument->getHtmlContentAsync(); - - while (htmlExported == 0) { - VUtils::sleepWait(100); - - if (m_state == ExportState::Cancelled) { - break; - } - } - - return htmlExported == 1; -} - -bool VExporter::fixStyleResources(const QString &p_folder, - QString &p_html) -{ - bool altered = false; - QRegExp reg("\\burl\\(\"((file|qrc):[^\"\\)]+)\"\\);"); - - int pos = 0; - while (pos < p_html.size()) { - int idx = p_html.indexOf(reg, pos); - if (idx == -1) { - break; - } - - QString targetFile = g_webUtils->copyResource(QUrl(reg.cap(1)), p_folder); - if (targetFile.isEmpty()) { - pos = idx + reg.matchedLength(); - } else { - // Replace the url string in html. - QString newUrl = QString("url(\"%1\");").arg(getResourceRelativePath(targetFile)); - p_html.replace(idx, reg.matchedLength(), newUrl); - pos = idx + newUrl.size(); - altered = true; - } - } - - return altered; -} - -bool VExporter::embedStyleResources(QString &p_html) -{ - bool altered = false; - QRegExp reg("\\burl\\(\"((file|qrc):[^\"\\)]+)\"\\);"); - - int pos = 0; - while (pos < p_html.size()) { - int idx = p_html.indexOf(reg, pos); - if (idx == -1) { - break; - } - - QString dataURI = g_webUtils->dataURI(QUrl(reg.cap(1)), false); - if (dataURI.isEmpty()) { - pos = idx + reg.matchedLength(); - } else { - // Replace the url string in html. - QString newUrl = QString("url('%1');").arg(dataURI); - p_html.replace(idx, reg.matchedLength(), newUrl); - pos = idx + newUrl.size(); - altered = true; - } - } - - return altered; -} - -bool VExporter::fixBodyResources(const QUrl &p_baseUrl, - const QString &p_folder, - QString &p_html) -{ - bool altered = false; - if (p_baseUrl.isEmpty()) { - return altered; - } - - QRegExp reg("]*)src=\"([^\"]+)\"([^>]*)>"); - - int pos = 0; - while (pos < p_html.size()) { - int idx = p_html.indexOf(reg, pos); - if (idx == -1) { - break; - } - - if (reg.cap(2).isEmpty()) { - pos = idx + reg.matchedLength(); - continue; - } - - QUrl srcUrl(p_baseUrl.resolved(reg.cap(2))); - QString targetFile = g_webUtils->copyResource(srcUrl, p_folder); - if (targetFile.isEmpty()) { - pos = idx + reg.matchedLength(); - } else { - // Replace the url string in html. - QString newUrl = QString("").arg(reg.cap(1)) - .arg(getResourceRelativePath(targetFile)) - .arg(reg.cap(3)); - p_html.replace(idx, reg.matchedLength(), newUrl); - pos = idx + newUrl.size(); - altered = true; - } - } - - return altered; -} - -bool VExporter::embedBodyResources(const QUrl &p_baseUrl, QString &p_html) -{ - bool altered = false; - if (p_baseUrl.isEmpty()) { - return altered; - } - - QRegExp reg("]*)src=\"([^\"]+)\"([^>]*)>"); - - int pos = 0; - while (pos < p_html.size()) { - int idx = p_html.indexOf(reg, pos); - if (idx == -1) { - break; - } - - if (reg.cap(2).isEmpty()) { - pos = idx + reg.matchedLength(); - continue; - } - - QUrl srcUrl(p_baseUrl.resolved(reg.cap(2))); - QString dataURI = g_webUtils->dataURI(srcUrl); - if (dataURI.isEmpty()) { - pos = idx + reg.matchedLength(); - } else { - // Replace the url string in html. - QString newUrl = QString("").arg(reg.cap(1)) - .arg(dataURI) - .arg(reg.cap(3)); - p_html.replace(idx, reg.matchedLength(), newUrl); - pos = idx + newUrl.size(); - altered = true; - } - } - - return altered; -} - -QString VExporter::getResourceRelativePath(const QString &p_file) -{ - int idx = p_file.lastIndexOf('/'); - int idx2 = p_file.lastIndexOf('/', idx - 1); - Q_ASSERT(idx > 0 && idx2 < idx); - return "." + p_file.mid(idx2); -} - -bool VExporter::exportToMHTML(VWebView *p_webViewer, - const ExportHTMLOption &p_opt, - const QString &p_filePath) -{ - Q_UNUSED(p_opt); - - m_downloadState = QWebEngineDownloadItem::DownloadRequested; - - p_webViewer->page()->save(p_filePath, QWebEngineDownloadItem::MimeHtmlSaveFormat); - - while (m_downloadState == QWebEngineDownloadItem::DownloadRequested - || m_downloadState == QWebEngineDownloadItem::DownloadInProgress) { - VUtils::sleepWait(100); - } - - return m_downloadState == QWebEngineDownloadItem::DownloadCompleted; -} - -void VExporter::handleDownloadRequested(QWebEngineDownloadItem *p_item) -{ - if (p_item->savePageFormat() == QWebEngineDownloadItem::MimeHtmlSaveFormat) { - connect(p_item, &QWebEngineDownloadItem::stateChanged, - this, [this](QWebEngineDownloadItem::DownloadState p_state) { - m_downloadState = p_state; - }); - } -} - -static QString combineArgs(QStringList &p_args) -{ - QString str; - for (const QString &arg : p_args) { - QString tmp; - if (arg.contains(' ')) { - tmp = '"' + arg + '"'; - } else { - tmp = arg; - } - - if (str.isEmpty()) { - str = tmp; - } else { - str = str + ' ' + tmp; - } - } - - return str; -} - -bool VExporter::htmlsToPDFViaWK(const QList &p_htmlFiles, - const QString &p_filePath, - const ExportPDFOption &p_opt, - QString *p_errMsg) -{ - // Note: system's locale settings (Language for non-Unicode programs) is important to wkhtmltopdf. - // Input file could be encoded via QUrl::fromLocalFile(p_htmlFile).toString(QUrl::EncodeUnicode) to - // handle non-ASCII path. - - QStringList args(m_wkArgs); - - for (auto const & it : p_htmlFiles) { - args << QDir::toNativeSeparators(it); - } - - args << QDir::toNativeSeparators(p_filePath); - - QString cmd = p_opt.m_wkPath + " " + combineArgs(args); - emit outputLog(cmd); - qDebug() << "wkhtmltopdf cmd:" << cmd; - int ret = startProcess(p_opt.m_wkPath, args); - qDebug() << "wkhtmltopdf returned" << ret; - if (m_askedToStop) { - return ret == 0; - } - - switch (ret) { - case -2: - VUtils::addErrMsg(p_errMsg, tr("Fail to start wkhtmltopdf (%1).").arg(cmd)); - break; - - case -1: - VUtils::addErrMsg(p_errMsg, tr("wkhtmltopdf crashed (%1).").arg(cmd)); - break; - - default: - break; - } - - return ret == 0; -} - -bool VExporter::convertFilesViaCustom(const QList &p_files, - const QString &p_filePath, - const ExportCustomOption &p_opt, - QString *p_errMsg) -{ - QString input; - QString inputFolder; - for (auto const & it : p_files) { - if (!input.isEmpty()) { - input += " "; - } - - if (!inputFolder.isEmpty()) { - inputFolder += p_opt.m_folderSep; - } - - QString tmp = QDir::toNativeSeparators(it); - input += ("\"" + tmp + "\""); - inputFolder += ("\"" + VUtils::basePathFromPath(tmp) + "\""); - } - - QString output = QDir::toNativeSeparators(p_filePath); - QString cmd = evaluateCommand(p_opt, - input, - inputFolder, - output); - emit outputLog(cmd); - qDebug() << "custom cmd:" << cmd; - int ret = startProcess(cmd); - qDebug() << "custom cmd returned" << ret; - if (m_askedToStop) { - return ret == 0; - } - - switch (ret) { - case -2: - VUtils::addErrMsg(p_errMsg, tr("Fail to start custom command (%1).").arg(cmd)); - break; - - case -1: - VUtils::addErrMsg(p_errMsg, tr("Custom command crashed (%1).").arg(cmd)); - break; - - default: - break; - } - - return ret == 0; -} - -int VExporter::exportPDFInOne(const QList &p_htmlFiles, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg) -{ - if (!htmlsToPDFViaWK(p_htmlFiles, p_outputFile, p_opt.m_pdfOpt, p_errMsg)) { - return 0; - } - - return p_htmlFiles.size(); -} - -int VExporter::startProcess(const QString &p_program, const QStringList &p_args) -{ - int ret = 0; - QScopedPointer process(new QProcess(this)); - process->start(p_program, p_args); - bool finished = false; - bool started = false; - while (true) { - QProcess::ProcessError err = process->error(); - if (err == QProcess::FailedToStart - || err == QProcess::Crashed) { - emit outputLog(tr("QProcess error %1.").arg(err)); - if (err == QProcess::FailedToStart) { - ret = -2; - } else { - ret = -1; - } - - break; - } - - if (started) { - if (process->state() == QProcess::NotRunning) { - finished = true; - } - } else { - if (process->state() != QProcess::NotRunning) { - started = true; - } - } - - if (process->waitForFinished(500)) { - // Finished. - finished = true; - } - - QByteArray outBa = process->readAllStandardOutput(); - QByteArray errBa = process->readAllStandardError(); - QString msg; - if (!outBa.isEmpty()) { - msg += QString::fromLocal8Bit(outBa); - } - - if (!errBa.isEmpty()) { - msg += QString::fromLocal8Bit(errBa); - } - - if (!msg.isEmpty()) { - emit outputLog(msg); - } - - if (finished) { - QProcess::ExitStatus sta = process->exitStatus(); - if (sta == QProcess::CrashExit) { - ret = -1; - break; - } - - ret = process->exitCode(); - break; - } - - QCoreApplication::processEvents(); - - if (m_askedToStop) { - process->kill(); - ret = -1; - break; - } - } - - return ret; -} - -int VExporter::startProcess(const QString &p_cmd) -{ - QStringList args = VUtils::parseCombinedArgString(p_cmd); - if (args.isEmpty()) { - return -2; - } - - return startProcess(args.first(), args.mid(1)); -} - -bool VExporter::outputToHTMLFile(const QString &p_file, - const QString &p_title, - const QString &p_headContent, - const QString &p_styleContent, - const QString &p_bodyContent, - bool p_embedCssStyle, - bool p_completeHTML, - bool p_embedImages) -{ - QFile file(p_file); - if (!file.open(QFile::WriteOnly)) { - return false; - } - - QString resFolder = QFileInfo(p_file).completeBaseName() + "_files"; - QString resFolderPath = QDir(VUtils::basePathFromPath(p_file)).filePath(resFolder); - - qDebug() << "HTML files folder" << resFolderPath; - - QString html(m_exportHtmlTemplate); - if (!p_title.isEmpty()) { - html.replace(HtmlHolder::c_headTitleHolder, - "" + VUtils::escapeHtml(p_title) + ""); - } - - if (!p_styleContent.isEmpty() && p_embedCssStyle) { - QString content(p_styleContent); - embedStyleResources(content); - html.replace(HtmlHolder::c_styleHolder, content); - } - - if (!p_headContent.isEmpty()) { - html.replace(HtmlHolder::c_headHolder, p_headContent); - } - - if (p_completeHTML) { - QString content(p_bodyContent); - if (p_embedImages) { - embedBodyResources(m_baseUrl, content); - } else { - fixBodyResources(m_baseUrl, resFolderPath, content); - } - - html.replace(HtmlHolder::c_bodyHolder, content); - } else { - html.replace(HtmlHolder::c_bodyHolder, p_bodyContent); - } - - file.write(html.toUtf8()); - file.close(); - - // Delete empty resource folder. - QDir dir(resFolderPath); - if (dir.isEmpty()) { - dir.cdUp(); - dir.rmdir(resFolder); - } - - return true; -} - -int VExporter::exportCustomInOne(const QList &p_files, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg) -{ - if (!convertFilesViaCustom(p_files, p_outputFile, p_opt.m_customOpt, p_errMsg)) { - return 0; - } - - return p_files.size(); -} diff --git a/src/vexporter.h b/src/vexporter.h deleted file mode 100644 index d8743224..00000000 --- a/src/vexporter.h +++ /dev/null @@ -1,213 +0,0 @@ -#ifndef VEXPORTER_H -#define VEXPORTER_H - -#include -#include -#include -#include -#include - -#include "dialog/vexportdialog.h" - -class QWidget; -class VWebView; -class VDocument; - -class VExporter : public QObject -{ - Q_OBJECT -public: - explicit VExporter(QWidget *p_parent = nullptr); - - void prepareExport(const ExportOption &p_opt); - - bool exportPDF(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg = NULL); - - bool exportHTML(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg = NULL); - - bool exportCustom(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg = NULL); - - int exportPDFInOne(const QList &p_htmlFiles, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg = NULL); - - int exportCustomInOne(const QList &p_files, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg = NULL); - - void setAskedToStop(bool p_askedToStop); - -signals: - // Request to output log. - void outputLog(const QString &p_log); - -private slots: - void handleLogicsFinished(); - - void handleLoadFinished(bool p_ok); - - void handleDownloadRequested(QWebEngineDownloadItem *p_item); - -private: - enum class ExportState - { - Idle = 0, - Cancelled, - Busy, - Failed, - Successful - }; - - - enum NoteState - { - NotReady = 0, - WebLogicsReady = 0x1, - WebLoadFinished = 0x2, - Ready = 0x3, - Failed = 0x4 - }; - - - void initWebViewer(VFile *p_file, const ExportOption &p_opt); - - void clearWebViewer(); - - void clearNoteState(); - - bool isNoteStateReady() const; - - bool isNoteStateFailed() const; - - bool exportViaWebView(VFile *p_file, - const ExportOption &p_opt, - const QString &p_outputFile, - QString *p_errMsg = NULL); - - bool exportToPDF(VWebView *p_webViewer, - const QString &p_filePath, - const QPageLayout &p_layout); - - bool exportToPDFViaWK(VDocument *p_webDocument, - const ExportPDFOption &p_opt, - const QString &p_filePath, - QString *p_errMsg = NULL); - - bool exportToCustom(VDocument *p_webDocument, - const ExportCustomOption &p_opt, - const QString &p_filePath, - QString *p_errMsg = NULL); - - bool exportToHTML(VDocument *p_webDocument, - const ExportHTMLOption &p_opt, - const QString &p_filePath); - - bool exportToMHTML(VWebView *p_webViewer, - const ExportHTMLOption &p_opt, - const QString &p_filePath); - - bool htmlsToPDFViaWK(const QList &p_htmlFiles, - const QString &p_filePath, - const ExportPDFOption &p_opt, - QString *p_errMsg = NULL); - - bool convertFilesViaCustom(const QList &p_files, - const QString &p_filePath, - const ExportCustomOption &p_opt, - QString *p_errMsg = NULL); - - void prepareWKArguments(const ExportPDFOption &p_opt); - - int startProcess(const QString &p_program, const QStringList &p_args); - - int startProcess(const QString &p_cmd); - - // @p_embedImages: embed as data URI. - bool outputToHTMLFile(const QString &p_file, - const QString &p_title, - const QString &p_headContent, - const QString &p_styleContent, - const QString &p_bodyContent, - bool p_embedCssStyle, - bool p_completeHTML, - bool p_embedImages); - - // Fix @p_html's resources like url("...") with "file" or "qrc" schema. - // Copy the resource to @p_folder and fix the url string. - static bool fixStyleResources(const QString &p_folder, - QString &p_html); - - // Fix @p_html's resources like url("...") with "file" or "qrc" schema. - // Embed the image data in data URIs. - static bool embedStyleResources(QString &p_html); - - // Fix @p_html's resources like . - // Copy the resource to @p_folder and fix the url string. - static bool fixBodyResources(const QUrl &p_baseUrl, - const QString &p_folder, - QString &p_html); - - // Embed @p_html's resources like . - static bool embedBodyResources(const QUrl &p_baseUrl, QString &p_html); - - static QString getResourceRelativePath(const QString &p_file); - - QPageLayout m_pageLayout; - - // Will be allocated and free for each conversion. - VWebView *m_webViewer; - - VDocument *m_webDocument; - - // Base URL of VWebView. - QUrl m_baseUrl; - - QString m_htmlTemplate; - - // Template to hold the export HTML result. - QString m_exportHtmlTemplate; - - NoteState m_noteState; - - ExportState m_state; - - // Download state used for MIME HTML. - QWebEngineDownloadItem::DownloadState m_downloadState; - - // Arguments for wkhtmltopdf. - QStringList m_wkArgs; - - bool m_askedToStop; -}; - -inline void VExporter::clearNoteState() -{ - m_noteState = NoteState::NotReady; -} - -inline bool VExporter::isNoteStateReady() const -{ - return m_noteState == NoteState::Ready; -} - -inline bool VExporter::isNoteStateFailed() const -{ - return m_noteState & NoteState::Failed; -} - -inline void VExporter::setAskedToStop(bool p_askedToStop) -{ - m_askedToStop = p_askedToStop; -} -#endif // VEXPORTER_H diff --git a/src/vfile.cpp b/src/vfile.cpp deleted file mode 100644 index da896309..00000000 --- a/src/vfile.cpp +++ /dev/null @@ -1,229 +0,0 @@ -#include "vfile.h" - -#include -#include -#include -#include -#include -#include -#include "utils/vutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -const QString VFile::c_backupFileHeadMagic = "vnote_backup_file_826537664"; - -VFile::VFile(QObject *p_parent, - const QString &p_name, - FileType p_type, - bool p_modifiable, - QDateTime p_createdTimeUtc, - QDateTime p_modifiedTimeUtc) - : QObject(p_parent), - m_name(p_name), - m_opened(false), - m_docType(VUtils::docTypeFromName(p_name)), - m_type(p_type), - m_modifiable(p_modifiable), - m_createdTimeUtc(p_createdTimeUtc), - m_modifiedTimeUtc(p_modifiedTimeUtc) -{ -} - -VFile::~VFile() -{ -} - -bool VFile::open() -{ - if (m_opened) { - return true; - } - - Q_ASSERT(!m_name.isEmpty()); - Q_ASSERT(m_content.isEmpty()); - - QString filePath = fetchPath(); - if (!QFileInfo::exists(filePath)) { - qWarning() << "file does not exist" << filePath; - return false; - } - - m_content = VUtils::readFileFromDisk(filePath); - m_lastModified = QFileInfo(filePath).lastModified(); - m_opened = true; - return true; -} - -void VFile::close() -{ - if (!m_opened) { - return; - } - - m_content.clear(); - if (!m_backupName.isEmpty()) { - VUtils::deleteFile(fetchBackupFilePath()); - m_backupName.clear(); - } - - m_opened = false; -} - -bool VFile::save() -{ - Q_ASSERT(m_opened); - Q_ASSERT(m_modifiable); - - bool ret = VUtils::writeFileToDisk(fetchPath(), m_content); - if (ret) { - m_lastModified = QFileInfo(fetchPath()).lastModified(); - m_modifiedTimeUtc = QDateTime::currentDateTimeUtc(); - } - - return ret; -} - -QUrl VFile::getBaseUrl() const -{ - // Need to judge the path: Url, local file, resource file. - QUrl baseUrl; - // Use file path to make in page anchor work. - QString filePath = fetchPath(); - QFileInfo pathInfo(filePath); - if (pathInfo.exists()) { - if (pathInfo.isNativePath()) { - // Local file. - baseUrl = QUrl::fromLocalFile(filePath); - } else { - // Resource file. - baseUrl = QUrl("qrc" + filePath); - } - } else { - // Url. - baseUrl = QUrl(filePath); - } - - return baseUrl; -} - -bool VFile::isInternalImageFolder(const QString &p_path) const -{ - return VUtils::equalPath(VUtils::basePathFromPath(p_path), - fetchBasePath()) - || VUtils::equalPath(p_path, fetchImageFolderPath()); -} - -bool VFile::isChangedOutside(bool &p_missing) const -{ - QFileInfo fi(fetchPath()); - if (!fi.exists()) { - p_missing = true; - return true; - } - - p_missing = false; - QDateTime lm = QFileInfo(fetchPath()).lastModified(); - return lm.toSecsSinceEpoch() != m_lastModified.toSecsSinceEpoch(); -} - -bool VFile::reload() -{ - if (!m_opened) { - return false; - } - - QString filePath = fetchPath(); - if (!QFileInfo::exists(filePath)) { - m_content.clear(); - return false; - } - - m_content = VUtils::readFileFromDisk(filePath); - m_lastModified = QFileInfo(filePath).lastModified(); - return true; -} - -QString VFile::backupFileOfPreviousSession() const -{ - Q_ASSERT(m_modifiable && m_backupName.isEmpty()); - - QString basePath = QDir(fetchBasePath()).filePath(g_config->getBackupDirectory()); - QDir dir(basePath); - - QStringList files = getPotentialBackupFiles(basePath); - foreach (const QString &file, files) { - QString filePath = dir.filePath(file); - if (isBackupFile(filePath)) { - return filePath; - } - } - - return QString(); -} - -QString VFile::fetchBackupFilePath() -{ - QString basePath = QDir(fetchBasePath()).filePath(g_config->getBackupDirectory()); - QDir dir(basePath); - - if (m_backupName.isEmpty()) { - m_backupName = VUtils::getFileNameWithSequence(basePath, - m_name + g_config->getBackupExtension(), - true); - - m_lastBackupFilePath = dir.filePath(m_backupName); - } else { - QString filePath = dir.filePath(m_backupName); - if (filePath != m_lastBackupFilePath) { - // File has been moved. - // Delete the original backup file if it still exists. - VUtils::deleteFile(m_lastBackupFilePath); - - m_lastBackupFilePath = filePath; - } - } - - return m_lastBackupFilePath; -} - -QStringList VFile::getPotentialBackupFiles(const QString &p_dir) const -{ - QString nameFilter = QString("%1*%2").arg(m_name).arg(g_config->getBackupExtension()); - QStringList files = QDir(p_dir).entryList(QStringList(nameFilter), - QDir::Files - | QDir::Hidden - | QDir::NoSymLinks - | QDir::NoDotAndDotDot); - return files; -} - -bool VFile::isBackupFile(const QString &p_file) const -{ - QFile file(p_file); - if (!file.open(QFile::ReadOnly | QIODevice::Text)) { - return false; - } - - QTextStream st(&file); - QString head = st.readLine(); - return head == fetchBackupFileHead(); -} - -QString VFile::fetchBackupFileHead() const -{ - return c_backupFileHeadMagic + " " + fetchPath(); -} - -bool VFile::writeBackupFile(const QString &p_content) -{ - return VUtils::writeFileToDisk(fetchBackupFilePath(), - fetchBackupFileHead() + "\n" + p_content); -} - -QString VFile::readBackupFile(const QString &p_file) -{ - const QString content = VUtils::readFileFromDisk(p_file); - int idx = content.indexOf("\n"); - return content.mid(idx + 1); -} diff --git a/src/vfile.h b/src/vfile.h deleted file mode 100644 index f723a445..00000000 --- a/src/vfile.h +++ /dev/null @@ -1,184 +0,0 @@ -#ifndef VFILE_H -#define VFILE_H - -#include -#include -#include -#include -#include "vconstants.h" - -// VFile is an abstract class representing a file in VNote. -class VFile : public QObject -{ - Q_OBJECT -public: - VFile(QObject *p_parent, - const QString &p_name, - FileType p_type, - bool p_modifiable, - QDateTime p_createdTimeUtc, - QDateTime p_modifiedTimeUtc); - - virtual ~VFile(); - - // Open the file to load content into m_content. - // Init m_opened, and m_content. - virtual bool open(); - - // Close the file. - // Clear m_content, m_opened. - virtual void close(); - - // Save m_content to the file. - virtual bool save(); - - // Reload content from disk. - virtual bool reload(); - - const QString &getName() const; - - DocType getDocType() const; - - bool isModifiable() const; - - bool isOpened() const; - - FileType getType() const; - - const QString &getContent() const; - - void setContent(const QString &p_content); - - // Get the absolute full path of the file. - virtual QString fetchPath() const = 0; - - // Get the absolute full path of the directory containing the file. - virtual QString fetchBasePath() const = 0; - - // The path of the image folder to store images of this file. - virtual QString fetchImageFolderPath() const = 0; - - // Return the base URL for this file when loaded in VWebView. - QUrl getBaseUrl() const; - - // Whether the directory @p_path is an internal image folder of this file. - // It is true only when the folder is in the same directory as the parent - // directory of this file or equals to fetchImageFolderPath(). - bool isInternalImageFolder(const QString &p_path) const; - - // Whether use a relative image folder. - virtual bool useRelativeImageFolder() const = 0; - - // Return the image folder part in an image link. - virtual QString getImageFolderInLink() const = 0; - - QDateTime getCreatedTimeUtc() const; - - QDateTime getModifiedTimeUtc() const; - - // Whether this file was changed outside VNote. - bool isChangedOutside(bool &p_missing) const; - - // Return backup file of previous session if there exists one. - QString backupFileOfPreviousSession() const; - - // Write @p_content to backup file. - bool writeBackupFile(const QString &p_content); - - QString readBackupFile(const QString &p_file); - -protected: - // Name of this file. - QString m_name; - - // Whether this file has been opened (content loaded). - bool m_opened; - - // DocType of this file: Html, Markdown. - DocType m_docType; - - // Content of this file. - QString m_content; - - // FileType of this file: Note, Orphan. - FileType m_type; - - // Whether this file is modifiable. - bool m_modifiable; - - // UTC time when creating this file. - QDateTime m_createdTimeUtc; - - // UTC time of last modification to this file in VNote. - QDateTime m_modifiedTimeUtc; - - // Last modified date and local time when the file is last modified - // corresponding to m_content. - QDateTime m_lastModified; - - // Name of the backup file. - QString m_backupName; - - // Used to identify file path change. - QString m_lastBackupFilePath; - -private: - // Fetch backup file path. - QString fetchBackupFilePath(); - - QStringList getPotentialBackupFiles(const QString &p_dir) const; - - // Read the file content to check if it is a backup file. - bool isBackupFile(const QString &p_file) const; - - QString fetchBackupFileHead() const; - - static const QString c_backupFileHeadMagic; -}; - -inline const QString &VFile::getName() const -{ - return m_name; -} - -inline DocType VFile::getDocType() const -{ - return m_docType; -} - -inline bool VFile::isModifiable() const -{ - return m_modifiable; -} - -inline bool VFile::isOpened() const -{ - return m_opened; -} - -inline FileType VFile::getType() const -{ - return m_type; -} - -inline const QString &VFile::getContent() const -{ - return m_content; -} - -inline void VFile::setContent(const QString &p_content) -{ - m_content = p_content; -} - -inline QDateTime VFile::getCreatedTimeUtc() const -{ - return m_createdTimeUtc; -} - -inline QDateTime VFile::getModifiedTimeUtc() const -{ - return m_modifiedTimeUtc; -} - -#endif // VFILE_H diff --git a/src/vfilelist.cpp b/src/vfilelist.cpp deleted file mode 100644 index 0b3f07d6..00000000 --- a/src/vfilelist.cpp +++ /dev/null @@ -1,1547 +0,0 @@ -#include -#include -#include -#include - -#include "vfilelist.h" -#include "vconfigmanager.h" -#include "dialog/vnewfiledialog.h" -#include "dialog/vfileinfodialog.h" -#include "vnote.h" -#include "veditarea.h" -#include "utils/vutils.h" -#include "vnotefile.h" -#include "vconfigmanager.h" -#include "vmdeditor.h" -#include "vmdtab.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "dialog/vsortdialog.h" -#include "vmainwindow.h" -#include "utils/viconutils.h" -#include "dialog/vtipsdialog.h" -#include "vcart.h" -#include "vhistorylist.h" - -extern VConfigManager *g_config; -extern VNote *g_vnote; -extern VMainWindow *g_mainWin; - -VFileList::VFileList(QWidget *parent) - : QWidget(parent), - VNavigationMode(), - m_openWithMenu(NULL), - m_itemClicked(NULL), - m_fileToCloseInSingleClick(NULL) -{ - setupUI(); - initShortcuts(); - - m_clickTimer = new QTimer(this); - m_clickTimer->setSingleShot(true); - m_clickTimer->setInterval(QApplication::doubleClickInterval()); - // When timer timeouts, we need to close the previous tab to simulate the - // effect as opening file in current tab. - connect(m_clickTimer, &QTimer::timeout, - this, [this]() { - m_itemClicked = NULL; - VFile *file = m_fileToCloseInSingleClick; - m_fileToCloseInSingleClick = NULL; - - if (file) { - editArea->closeFile(file, false); - fileList->setFocus(); - } - }); - - updateNumberLabel(); -} - -void VFileList::setupUI() -{ - QLabel *titleLabel = new QLabel(tr("Notes"), this); - titleLabel->setProperty("TitleLabel", true); - - QPushButton *viewBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/view.svg"), - "", - this); - viewBtn->setToolTip(tr("View")); - viewBtn->setProperty("CornerBtn", true); - viewBtn->setFocusPolicy(Qt::NoFocus); - - QMenu *viewMenu = new QMenu(this); - connect(viewMenu, &QMenu::aboutToShow, - this, [this, viewMenu]() { - updateViewMenu(viewMenu); - }); - viewBtn->setMenu(viewMenu); - - m_splitBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/split_window.svg"), - "", - this); - m_splitBtn->setToolTip(tr("Split")); - m_splitBtn->setCheckable(true); - m_splitBtn->setProperty("CornerBtn", true); - m_splitBtn->setFocusPolicy(Qt::NoFocus); - connect(m_splitBtn, &QPushButton::clicked, - this, [this](bool p_checked) { - emit requestSplitOut(p_checked); - }); - - m_numLabel = new QLabel(this); - - QHBoxLayout *titleLayout = new QHBoxLayout(); - titleLayout->addWidget(titleLabel); - titleLayout->addWidget(viewBtn); - titleLayout->addWidget(m_splitBtn); - titleLayout->addStretch(); - titleLayout->addWidget(m_numLabel); - - titleLayout->setContentsMargins(0, 0, 0, 0); - - fileList = new VFileListWidget(this); - fileList->setContextMenuPolicy(Qt::CustomContextMenu); - fileList->setObjectName("FileList"); - fileList->setAttribute(Qt::WA_MacShowFocusRect, false); - fileList->setMimeDataGetter([this](const QString &p_format, - const QList &p_items) { - return getMimeData(p_format, p_items); - }); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addLayout(titleLayout); - mainLayout->addWidget(fileList); - mainLayout->setContentsMargins(0, 0, 0, 0); - - connect(fileList, &QListWidget::customContextMenuRequested, - this, &VFileList::contextMenuRequested); - connect(fileList, &QListWidget::itemClicked, - this, &VFileList::handleItemClicked); - connect(fileList, &QListWidget::itemEntered, - this, &VFileList::showStatusTipAboutItem); - connect(fileList, &QListWidget::currentItemChanged, - this, [this](QListWidgetItem *p_cur, QListWidgetItem *p_pre) { - Q_UNUSED(p_pre); - if (p_cur) { - showStatusTipAboutItem(p_cur); - } - }); - - setLayout(mainLayout); -} - -void VFileList::initShortcuts() -{ - QShortcut *infoShortcut = new QShortcut(QKeySequence(Shortcut::c_info), this); - infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(infoShortcut, &QShortcut::activated, - this, [this](){ - fileInfo(); - }); - - QShortcut *copyShortcut = new QShortcut(QKeySequence(Shortcut::c_copy), this); - copyShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(copyShortcut, &QShortcut::activated, - this, [this](){ - copySelectedFiles(); - }); - - QShortcut *cutShortcut = new QShortcut(QKeySequence(Shortcut::c_cut), this); - cutShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(cutShortcut, &QShortcut::activated, - this, [this](){ - cutSelectedFiles(); - }); - - QShortcut *pasteShortcut = new QShortcut(QKeySequence(Shortcut::c_paste), this); - pasteShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(pasteShortcut, &QShortcut::activated, - this, [this](){ - pasteFilesFromClipboard(); - }); - - QKeySequence seq(g_config->getShortcutKeySequence("OpenViaDefaultProgram")); - if (!seq.isEmpty()) { - QShortcut *defaultProgramShortcut = new QShortcut(seq, this); - defaultProgramShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(defaultProgramShortcut, &QShortcut::activated, - this, &VFileList::openCurrentItemViaDefaultProgram); - } -} - -void VFileList::setDirectory(VDirectory *p_directory) -{ - // QPointer will be set to NULL automatically once the directory was deleted. - // If the last directory is deleted, m_directory and p_directory will both - // be NULL. - if (m_directory == p_directory) { - if (!m_directory) { - fileList->clearAll(); - updateNumberLabel(); - } - - return; - } - - m_directory = p_directory; - if (!m_directory) { - fileList->clearAll(); - updateNumberLabel(); - return; - } - - updateFileList(); -} - -void VFileList::updateFileList() -{ - fileList->clearAll(); - if (!m_directory->open()) { - return; - } - - QVector files = m_directory->getFiles(); - sortFiles(files, (ViewOrder)g_config->getNoteListViewOrder()); - - for (int i = 0; i < files.size(); ++i) { - VNoteFile *file = files[i]; - insertFileListItem(file); - } - - updateNumberLabel(); -} - -void VFileList::fileInfo() -{ - QList items = fileList->selectedItems(); - if (items.size() == 1) { - fileInfo(getVFile(items[0])); - } -} - -void VFileList::openFileLocation() const -{ - QList items = fileList->selectedItems(); - if (items.size() == 1) { - QUrl url = QUrl::fromLocalFile(getVFile(items[0])->fetchBasePath()); - QDesktopServices::openUrl(url); - } -} - -void VFileList::addFileToCart() const -{ - QList items = fileList->selectedItems(); - VCart *cart = g_mainWin->getCart(); - - for (int i = 0; i < items.size(); ++i) { - cart->addFile(getVFile(items[i])->fetchPath()); - } - - g_mainWin->showStatusMessage(tr("%1 %2 added to Cart") - .arg(items.size()) - .arg(items.size() > 1 ? tr("notes") : tr("note"))); -} - -void VFileList::pinFileToHistory() const -{ - QList items = fileList->selectedItems(); - - QStringList files; - for (int i = 0; i < items.size(); ++i) { - files << getVFile(items[i])->fetchPath(); - } - - g_mainWin->getHistoryList()->pinFiles(files); - - g_mainWin->showStatusMessage(tr("%1 %2 pinned to History") - .arg(items.size()) - .arg(items.size() > 1 ? tr("notes") : tr("note"))); -} - -void VFileList::setFileQuickAccess() const -{ - QList items = fileList->selectedItems(); - if (items.size() == 1) { - QString fp(getVFile(items[0])->fetchPath()); - - g_config->setQuickAccess(fp); - g_mainWin->showStatusMessage(tr("Quick access: %1").arg(fp)); - } -} - -void VFileList::fileInfo(VNoteFile *p_file) -{ - if (!p_file) { - return; - } - - VDirectory *dir = p_file->getDirectory(); - QString curName = p_file->getName(); - VFileInfoDialog dialog(tr("Note Information"), "", dir, p_file, this); - if (dialog.exec() == QDialog::Accepted) { - QString name = dialog.getNameInput(); - if (name == curName) { - return; - } - - if (!p_file->rename(name)) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to rename note %2.") - .arg(g_config->c_dataTextStyle).arg(curName), "", - QMessageBox::Ok, QMessageBox::Ok, this); - return; - } - - QListWidgetItem *item = findItem(p_file); - if (item) { - fillItem(item, p_file); - } - - emit fileUpdated(p_file, UpdateAction::InfoChanged); - } -} - -void VFileList::fillItem(QListWidgetItem *p_item, const VNoteFile *p_file) -{ - qulonglong ptr = (qulonglong)p_file; - p_item->setData(Qt::UserRole, ptr); - p_item->setText(p_file->getName()); - - QString createdTime = VUtils::displayDateTime(p_file->getCreatedTimeUtc().toLocalTime()); - QString modifiedTime = VUtils::displayDateTime(p_file->getModifiedTimeUtc().toLocalTime()); - QString tooltip = tr("%1\n\nCreated Time: %2\nModified Time: %3") - .arg(p_file->getName()) - .arg(createdTime) - .arg(modifiedTime); - p_item->setToolTip(tooltip); - V_ASSERT(sizeof(p_file) <= sizeof(ptr)); -} - -QListWidgetItem* VFileList::insertFileListItem(VNoteFile *file, bool atFront) -{ - V_ASSERT(file); - QListWidgetItem *item = new QListWidgetItem(); - fillItem(item, file); - - if (atFront) { - fileList->insertItem(0, item); - } else { - fileList->addItem(item); - } - - // Qt seems not to update the QListWidget correctly. Manually force it to repaint. - fileList->update(); - return item; -} - -void VFileList::removeFileListItem(VNoteFile *p_file) -{ - if (!p_file) { - return; - } - - QListWidgetItem *item = findItem(p_file); - if (!item) { - return; - } - - int row = fileList->row(item); - Q_ASSERT(row >= 0); - - fileList->takeItem(row); - delete item; - - // Qt seems not to update the QListWidget correctly. Manually force it to repaint. - fileList->update(); -} - -void VFileList::newFile() -{ - if (!m_directory) { - return; - } - - QList suffixes = g_config->getDocSuffixes()[(int)DocType::Markdown]; - QString defaultSuf; - QString suffixStr; - for (auto const & suf : suffixes) { - suffixStr += (suffixStr.isEmpty() ? suf : "/" + suf); - if (defaultSuf.isEmpty() || suf == "md") { - defaultSuf = suf; - } - } - - QString info = tr("Create a note in %2.") - .arg(g_config->c_dataTextStyle).arg(m_directory->getName()); - info = info + "
    " + tr("Note with name ending with \"%1\" will be treated as Markdown type.") - .arg(suffixStr); - QString defaultName = QString("new_note.%1").arg(defaultSuf); - defaultName = VUtils::getFileNameWithSequence(m_directory->fetchPath(), - defaultName, - true); - VNewFileDialog dialog(tr("Create Note"), info, defaultName, m_directory, this); - if (dialog.exec() == QDialog::Accepted) { - VNoteFile *file = m_directory->createFile(dialog.getNameInput(), - g_config->getInsertNewNoteInFront()); - if (!file) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to create note %2.") - .arg(g_config->c_dataTextStyle).arg(dialog.getNameInput()), "", - QMessageBox::Ok, QMessageBox::Ok, this); - return; - } - - // Whether need to move the cursor to the end. - bool moveCursorEnd = false; - // Content needed to insert into the new file, title/template. - QString insertContent; - if (dialog.getInsertTitleInput() && file->getDocType() == DocType::Markdown) { - // Insert title. - insertContent = QString("# %1\n").arg(QFileInfo(file->getName()).completeBaseName()); - } - - if (dialog.isTemplateUsed()) { - Q_ASSERT(insertContent.isEmpty()); - insertContent = dialog.getTemplate(); - } - - if (!insertContent.isEmpty()) { - if (!file->open()) { - qWarning() << "fail to open newly-created note" << file->getName(); - } else { - Q_ASSERT(file->getContent().isEmpty()); - file->setContent(insertContent); - if (!file->save()) { - qWarning() << "fail to write to newly-created note" << file->getName(); - } else { - if (dialog.getInsertTitleInput()) { - moveCursorEnd = true; - } - } - - file->close(); - } - } - - updateFileList(); - - locateFile(file); - - // Open it in edit mode - emit fileCreated(file, OpenFileMode::Edit, true); - - // Move cursor down if content has been inserted. - if (moveCursorEnd) { - VMdTab *tab = dynamic_cast(editArea->getCurrentTab()); - if (tab) { - // It will init markdown editor (within 50 ms) - // See VMdTab::VMdTab --> QTimer::singleShot(50, ... - VMdEditor *edit = tab->getEditor(); - if (edit && edit->getFile() == file) { - QTextCursor cursor = edit->textCursor(); - cursor.movePosition(QTextCursor::End); - edit->setTextCursor(cursor); - } - } - } - } -} - -void VFileList::deleteSelectedFiles() -{ - QList items = fileList->selectedItems(); - Q_ASSERT(!items.isEmpty()); - - QVector files; - for (auto const & item : items) { - files.push_back(getVFile(item)); - } - - deleteFiles(files); -} - -// @p_file may or may not be listed in VFileList -void VFileList::deleteFile(VNoteFile *p_file) -{ - if (!p_file) { - return; - } - - QVector files(1, p_file); - deleteFiles(files); -} - -void VFileList::deleteFiles(const QVector &p_files) -{ - if (p_files.isEmpty()) { - return; - } - - QVector items; - for (auto const & file : p_files) { - items.push_back(ConfirmItemInfo(file->getName(), - file->fetchPath(), - file->fetchPath(), - (void *)file)); - } - - QString text = tr("Are you sure to delete these notes?"); - - QString info = tr("WARNING: " - "VNote will delete notes as well as all " - "their images and attachments managed by VNote. " - "Deleted files could be found in the recycle " - "bin of these notes.
    " - "Click \"Cancel\" to leave them untouched.
    " - "The operation is IRREVERSIBLE!") - .arg(g_config->c_warningTextStyle); - - VConfirmDeletionDialog dialog(tr("Confirm Deleting Notes"), - text, - info, - items, - false, - false, - false, - this); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - QVector files; - for (auto const & item : items) { - files.push_back((VNoteFile *)item.m_data); - } - - int nrDeleted = 0; - for (auto file : files) { - editArea->closeFile(file, true); - - // Remove the item before deleting it totally, or file will be invalid. - removeFileListItem(file); - - QString errMsg; - QString fileName = file->getName(); - QString filePath = file->fetchPath(); - if (!VNoteFile::deleteFile(file, &errMsg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete note %2.
    " - "Please check %3 and manually delete it.") - .arg(g_config->c_dataTextStyle) - .arg(fileName) - .arg(filePath), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } else { - Q_ASSERT(errMsg.isEmpty()); - ++nrDeleted; - } - } - - if (nrDeleted > 0) { - g_mainWin->showStatusMessage(tr("%1 %2 deleted") - .arg(nrDeleted) - .arg(nrDeleted > 1 ? tr("notes") : tr("note"))); - updateNumberLabel(); - } - } -} - -void VFileList::contextMenuRequested(QPoint pos) -{ - if (!m_directory) { - return; - } - - QListWidgetItem *item = fileList->itemAt(pos); - QMenu menu(this); - menu.setToolTipsVisible(true); - - int selectedSize = fileList->selectedItems().size(); - - if (item && selectedSize == 1) { - VNoteFile *file = getVFile(item); - if (file) { - if (file->getDocType() == DocType::Markdown) { - QAction *openInReadAct = new QAction(VIconUtils::menuIcon(":/resources/icons/reading.svg"), - tr("&Open In Read Mode"), - &menu); - openInReadAct->setToolTip(tr("Open current note in read mode")); - connect(openInReadAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = fileList->currentItem(); - if (item) { - emit fileClicked(getVFile(item), OpenFileMode::Read, true); - } - }); - menu.addAction(openInReadAct); - - QAction *openInEditAct = new QAction(VIconUtils::menuIcon(":/resources/icons/editing.svg"), - tr("Open In &Edit Mode"), - &menu); - openInEditAct->setToolTip(tr("Open current note in edit mode")); - connect(openInEditAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = fileList->currentItem(); - if (item) { - emit fileClicked(getVFile(item), OpenFileMode::Edit, true); - } - }); - menu.addAction(openInEditAct); - } - - menu.addMenu(getOpenWithMenu()); - - menu.addSeparator(); - } - } - - QAction *newFileAct = new QAction(VIconUtils::menuIcon(":/resources/icons/create_note.svg"), - tr("&New Note"), - &menu); - VUtils::fixTextWithShortcut(newFileAct, "NewNote"); - newFileAct->setToolTip(tr("Create a note in current folder")); - connect(newFileAct, SIGNAL(triggered(bool)), - this, SLOT(newFile())); - menu.addAction(newFileAct); - - if (fileList->count() > 1) { - QAction *sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - &menu); - sortAct->setToolTip(tr("Sort notes in this folder manually")); - connect(sortAct, &QAction::triggered, - this, &VFileList::sortItems); - menu.addAction(sortAct); - } - - if (item) { - menu.addSeparator(); - - QAction *deleteFileAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_note.svg"), - tr("&Delete"), - &menu); - deleteFileAct->setToolTip(tr("Delete selected note")); - connect(deleteFileAct, SIGNAL(triggered(bool)), - this, SLOT(deleteSelectedFiles())); - menu.addAction(deleteFileAct); - - QAction *copyAct = new QAction(VIconUtils::menuIcon(":/resources/icons/copy.svg"), - tr("&Copy\t%1").arg(VUtils::getShortcutText(Shortcut::c_copy)), - &menu); - copyAct->setToolTip(tr("Copy selected notes")); - connect(copyAct, &QAction::triggered, - this, &VFileList::copySelectedFiles); - menu.addAction(copyAct); - - QAction *cutAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cut.svg"), - tr("C&ut\t%1").arg(VUtils::getShortcutText(Shortcut::c_cut)), - &menu); - cutAct->setToolTip(tr("Cut selected notes")); - connect(cutAct, &QAction::triggered, - this, &VFileList::cutSelectedFiles); - menu.addAction(cutAct); - } - - if (pasteAvailable()) { - if (!item) { - menu.addSeparator(); - } - - QAction *pasteAct = new QAction(VIconUtils::menuIcon(":/resources/icons/paste.svg"), - tr("&Paste\t%1").arg(VUtils::getShortcutText(Shortcut::c_paste)), - &menu); - pasteAct->setToolTip(tr("Paste notes in current folder")); - connect(pasteAct, &QAction::triggered, - this, &VFileList::pasteFilesFromClipboard); - menu.addAction(pasteAct); - } - - if (item) { - menu.addSeparator(); - if (selectedSize == 1) { - QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"), - tr("Open Note &Location"), - &menu); - openLocationAct->setToolTip(tr("Explore the folder containing this note in operating system")); - connect(openLocationAct, &QAction::triggered, - this, &VFileList::openFileLocation); - menu.addAction(openLocationAct); - - QAction *copyPathAct = new QAction(tr("Copy File &Path"), &menu); - connect(copyPathAct, &QAction::triggered, - this, [this]() { - QList items = fileList->selectedItems(); - if (items.size() == 1) { - QString filePath = getVFile(items[0])->fetchPath(); - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(filePath); - g_mainWin->showStatusMessage(tr("File path copied %1").arg(filePath)); - } - }); - menu.addAction(copyPathAct); - } - - QAction *addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"), - tr("Add To Cart"), - &menu); - addToCartAct->setToolTip(tr("Add selected notes to Cart for further processing")); - connect(addToCartAct, &QAction::triggered, - this, &VFileList::addFileToCart); - menu.addAction(addToCartAct); - - QAction *pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"), - tr("Pin To History"), - &menu); - pinToHistoryAct->setToolTip(tr("Pin selected notes to History")); - connect(pinToHistoryAct, &QAction::triggered, - this, &VFileList::pinFileToHistory); - menu.addAction(pinToHistoryAct); - - QAction *quickAccessAct = new QAction(VIconUtils::menuIcon(":/resources/icons/quick_access.svg"), - tr("Set As Quick Access"), - &menu); - quickAccessAct->setToolTip(tr("Set current note as quick access")); - connect(quickAccessAct, &QAction::triggered, - this, &VFileList::setFileQuickAccess); - menu.addAction(quickAccessAct); - - if (selectedSize == 1) { - QAction *fileInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), - tr("&Info (Rename)\t%1").arg(VUtils::getShortcutText(Shortcut::c_info)), - &menu); - fileInfoAct->setToolTip(tr("View and edit current note's information")); - connect(fileInfoAct, SIGNAL(triggered(bool)), - this, SLOT(fileInfo())); - menu.addAction(fileInfoAct); - } - } - - menu.exec(fileList->mapToGlobal(pos)); -} - -QListWidgetItem* VFileList::findItem(const VNoteFile *p_file) -{ - if (!p_file || p_file->getDirectory() != m_directory) { - return NULL; - } - - int nrChild = fileList->count(); - for (int i = 0; i < nrChild; ++i) { - QListWidgetItem *item = fileList->item(i); - if (p_file == getVFile(item)) { - return item; - } - } - - return NULL; -} - -void VFileList::handleItemClicked(QListWidgetItem *p_item) -{ - Q_ASSERT(p_item); - - Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); - if (modifiers != Qt::NoModifier) { - return; - } - - m_clickTimer->stop(); - if (m_itemClicked) { - // Timer will not trigger. - if (m_itemClicked == p_item) { - // Double clicked. - m_itemClicked = NULL; - m_fileToCloseInSingleClick = NULL; - return; - } else { - // Handle previous clicked item as single click. - m_itemClicked = NULL; - if (m_fileToCloseInSingleClick) { - editArea->closeFile(m_fileToCloseInSingleClick, false); - m_fileToCloseInSingleClick = NULL; - } - } - } - - // Pending @p_item. - bool singleClickClose = g_config->getSingleClickClosePreviousTab(); - if (singleClickClose) { - VFile *file = getVFile(p_item); - Q_ASSERT(file); - if (editArea->isFileOpened(file)) { - // File already opened. - activateItem(p_item, true); - return; - } - - // EditArea will open Unknown file using system's default program, in which - // case we should now close current file even after single click. - if (file->getDocType() == DocType::Unknown) { - m_fileToCloseInSingleClick = NULL; - } else { - // Get current tab which will be closed if click timer timeouts. - VEditTab *tab = editArea->getCurrentTab(); - if (tab) { - m_fileToCloseInSingleClick = tab->getFile(); - } else { - m_fileToCloseInSingleClick = NULL; - } - } - } - - // Activate it. - activateItem(p_item, true); - - if (singleClickClose) { - m_itemClicked = p_item; - m_clickTimer->start(); - } -} - -void VFileList::showStatusTipAboutItem(QListWidgetItem *p_item) -{ - Q_ASSERT(p_item); - const VNoteFile *file = getVFile(p_item); - const QStringList &tags = file->getTags(); - QString tag; - for (int i = 0; i < tags.size(); ++i) { - if (i == 0) { - tag = "\t[" + tags[i] + "]"; - } else { - tag += " [" + tags[i] + "]"; - } - } - - QString tip(file->getName() + tag); - g_mainWin->showStatusMessage(tip); -} - -void VFileList::activateItem(QListWidgetItem *p_item, bool p_restoreFocus) -{ - if (!p_item) { - emit fileClicked(NULL); - return; - } - - // Qt seems not to update the QListWidget correctly. Manually force it to repaint. - fileList->update(); - emit fileClicked(getVFile(p_item), g_config->getNoteOpenMode()); - - if (p_restoreFocus) { - fileList->setFocus(); - } -} - -bool VFileList::importFiles(const QStringList &p_files, QString *p_errMsg) -{ - if (p_files.isEmpty()) { - return false; - } - - bool ret = true; - Q_ASSERT(m_directory && m_directory->isOpened()); - QString dirPath = m_directory->fetchPath(); - QDir dir(dirPath); - - QVector importedFiles; - for (int i = 0; i < p_files.size(); ++i) { - const QString &file = p_files[i]; - - QFileInfo fi(file); - if (!fi.exists() || !fi.isFile()) { - VUtils::addErrMsg(p_errMsg, tr("Skip importing non-exist file %1.") - .arg(file)); - ret = false; - continue; - } - - QString name = VUtils::fileNameFromPath(file); - Q_ASSERT(!name.isEmpty()); - - bool copyNeeded = true; - if (VUtils::equalPath(dirPath, fi.absolutePath())) { - // Check if it is already a note. - if (m_directory->findFile(name, false)) { - VUtils::addErrMsg(p_errMsg, tr("Skip importing file %1. " - "A note with the same name (case-insensitive) " - "in the same directory already exists.") - .arg(file)); - ret = false; - continue; - } - - qDebug() << "skip cpoy file" << file << "locates in" << dirPath; - copyNeeded = false; - } - - QString targetFilePath; - if (copyNeeded) { - name = VUtils::getFileNameWithSequence(dirPath, name, true); - targetFilePath = dir.filePath(name); - bool ret = VUtils::copyFile(file, targetFilePath, false); - if (!ret) { - VUtils::addErrMsg(p_errMsg, tr("Fail to copy file %1 as %2.") - .arg(file) - .arg(targetFilePath)); - ret = false; - continue; - } - } else { - targetFilePath = file; - } - - VNoteFile *destFile = m_directory->addFile(name, -1); - if (destFile) { - importedFiles.append(destFile); - qDebug() << "imported" << file << "as" << targetFilePath; - } else { - VUtils::addErrMsg(p_errMsg, tr("Fail to add the note %1 to target folder's configuration.") - .arg(file)); - ret = false; - continue; - } - } - - qDebug() << "imported" << importedFiles.size() << "files"; - - updateFileList(); - - selectFiles(importedFiles); - - return ret; -} - -void VFileList::copySelectedFiles(bool p_isCut) -{ - QList items = fileList->selectedItems(); - if (items.isEmpty()) { - return; - } - - QJsonArray files; - for (int i = 0; i < items.size(); ++i) { - VNoteFile *file = getVFile(items[i]); - files.append(file->fetchPath()); - } - - QJsonObject clip; - clip[ClipboardConfig::c_magic] = getNewMagic(); - clip[ClipboardConfig::c_type] = (int)ClipboardOpType::CopyFile; - clip[ClipboardConfig::c_isCut] = p_isCut; - clip[ClipboardConfig::c_files] = files; - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(QJsonDocument(clip).toJson(QJsonDocument::Compact)); - - qDebug() << "copied files info" << clipboard->text(); - - int cnt = files.size(); - g_mainWin->showStatusMessage(tr("%1 %2 %3") - .arg(cnt) - .arg(cnt > 1 ? tr("notes") : tr("note")) - .arg(p_isCut ? tr("cut") : tr("copied"))); -} - -void VFileList::cutSelectedFiles() -{ - copySelectedFiles(true); -} - -void VFileList::pasteFilesFromClipboard() -{ - if (!pasteAvailable()) { - return; - } - - QJsonObject obj = VUtils::clipboardToJson(); - QJsonArray files = obj[ClipboardConfig::c_files].toArray(); - bool isCut = obj[ClipboardConfig::c_isCut].toBool(); - QVector filesToPaste(files.size()); - for (int i = 0; i < files.size(); ++i) { - filesToPaste[i] = files[i].toString(); - } - - pasteFiles(m_directory, filesToPaste, isCut); - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); -} - -void VFileList::pasteFiles(VDirectory *p_destDir, - const QVector &p_files, - bool p_isCut) -{ - if (!p_destDir || p_files.isEmpty()) { - return; - } - - int nrPasted = 0; - for (int i = 0; i < p_files.size(); ++i) { - VNoteFile *file = g_vnote->getInternalFile(p_files[i]); - if (!file) { - qWarning() << "Copied file is not an internal note" << p_files[i]; - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to paste note %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_files[i]), - tr("VNote could not find this note in any notebook."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - - continue; - } - - QString fileName = file->getName(); - if (file->getDirectory() == p_destDir) { - if (p_isCut) { - qDebug() << "skip one note to cut and paste in the same folder" << fileName; - continue; - } - - // Copy and paste in the same folder. - // We do not allow this if the note contains local images. - if (file->getDocType() == DocType::Markdown) { - QVector images = VUtils::fetchImagesFromMarkdownFile(file, - ImageLink::LocalRelativeInternal); - if (!images.isEmpty()) { - qDebug() << "skip one note with internal images to copy and paste in the same folder" - << fileName; - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to copy note %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_files[i]), - tr("VNote does not allow copy and paste notes with internal images " - "in the same folder."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - continue; - } - } - - // Rename it to xxx_copy.md. - fileName = VUtils::generateCopiedFileName(file->fetchBasePath(), - fileName, - true); - } else { - // Rename it to xxx_copy.md if needed. - fileName = VUtils::generateCopiedFileName(p_destDir->fetchPath(), - fileName, - true); - } - - QString msg; - VNoteFile *destFile = NULL; - bool ret = VNoteFile::copyFile(p_destDir, - fileName, - file, - p_isCut, - g_config->getInsertNewNoteInFront() ? 0 : -1, - &destFile, - &msg); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to copy note %2.") - .arg(g_config->c_dataTextStyle) - .arg(p_files[i]), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - if (destFile) { - ++nrPasted; - emit fileUpdated(destFile, p_isCut ? UpdateAction::Moved : UpdateAction::InfoChanged); - } - } - - qDebug() << "pasted" << nrPasted << "files"; - if (nrPasted > 0) { - g_mainWin->showStatusMessage(tr("%1 %2 pasted") - .arg(nrPasted) - .arg(nrPasted > 1 ? tr("notes") : tr("note"))); - } - - updateFileList(); - getNewMagic(); -} - -void VFileList::keyPressEvent(QKeyEvent *p_event) -{ - switch (p_event->key()) { - case Qt::Key_Enter: - case Qt::Key_Return: - { - QListWidgetItem *item = fileList->currentItem(); - if (item) { - VFile *fileToClose = NULL; - VFile *file = getVFile(item); - Q_ASSERT(file); - if (p_event->modifiers() == Qt::NoModifier - && g_config->getSingleClickClosePreviousTab() - && file->getDocType() != DocType::Unknown) { - if (!editArea->isFileOpened(file)) { - VEditTab *tab = editArea->getCurrentTab(); - if (tab) { - fileToClose = tab->getFile(); - } - } - - } - - activateItem(item, false); - if (fileToClose) { - editArea->closeFile(fileToClose, false); - } - } - - break; - } - - default: - break; - } - - QWidget::keyPressEvent(p_event); -} - -void VFileList::focusInEvent(QFocusEvent * /* p_event */) -{ - fileList->setFocus(); -} - -bool VFileList::locateFile(const VNoteFile *p_file) -{ - if (p_file) { - if (p_file->getDirectory() != m_directory) { - return false; - } - - QListWidgetItem *item = findItem(p_file); - if (item) { - fileList->setCurrentItem(item, QItemSelectionModel::ClearAndSelect); - return true; - } - } - - return false; -} - -void VFileList::showNavigation() -{ - VNavigationMode::showNavigation(fileList); -} - -bool VFileList::handleKeyNavigation(int p_key, bool &p_succeed) -{ - return VNavigationMode::handleKeyNavigation(fileList, p_key, p_succeed); -} - -int VFileList::getNewMagic() -{ - m_magicForClipboard = (int)QDateTime::currentDateTime().toTime_t(); - m_magicForClipboard |= qrand(); - - return m_magicForClipboard; -} - -bool VFileList::checkMagic(int p_magic) const -{ - return m_magicForClipboard == p_magic; -} - -bool VFileList::pasteAvailable() const -{ - QJsonObject obj = VUtils::clipboardToJson(); - if (obj.isEmpty()) { - return false; - } - - if (!obj.contains(ClipboardConfig::c_type)) { - return false; - } - - ClipboardOpType type = (ClipboardOpType)obj[ClipboardConfig::c_type].toInt(); - if (type != ClipboardOpType::CopyFile) { - return false; - } - - if (!obj.contains(ClipboardConfig::c_magic) - || !obj.contains(ClipboardConfig::c_isCut) - || !obj.contains(ClipboardConfig::c_files)) { - return false; - } - - int magic = obj[ClipboardConfig::c_magic].toInt(); - if (!checkMagic(magic)) { - return false; - } - - QJsonArray files = obj[ClipboardConfig::c_files].toArray(); - return !files.isEmpty(); -} - -void VFileList::sortItems() -{ - const QVector &files = m_directory->getFiles(); - if (files.size() < 2) { - return; - } - - VSortDialog dialog(tr("Sort Notes"), - tr("Sort notes in folder %2 " - "in the configuration file.") - .arg(g_config->c_dataTextStyle) - .arg(m_directory->getName()), - this); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(3); - QStringList headers; - headers << tr("Name") << tr("Created Time") << tr("Modified Time"); - tree->setHeaderLabels(headers); - - for (int i = 0; i < files.size(); ++i) { - const VNoteFile *file = files[i]; - QString createdTime = VUtils::displayDateTime(file->getCreatedTimeUtc().toLocalTime(), true); - QString modifiedTime = VUtils::displayDateTime(file->getModifiedTimeUtc().toLocalTime(), true); - QStringList cols; - cols << file->getName() << createdTime << modifiedTime; - QTreeWidgetItem *item = new QTreeWidgetItem(tree, cols); - - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == files.size()); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - qDebug() << "sort files" << sortedIdx; - if (!m_directory->sortFiles(sortedIdx)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to sort notes in folder %2.") - .arg(g_config->c_dataTextStyle) - .arg(m_directory->getName()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateFileList(); - } -} - -QMenu *VFileList::getOpenWithMenu() -{ - if (m_openWithMenu) { - return m_openWithMenu; - } - - m_openWithMenu = new QMenu(tr("Open With"), this); - m_openWithMenu->setToolTipsVisible(true); - - auto programs = g_config->getExternalEditors(); - for (auto const & pa : programs) { - QKeySequence seq = QKeySequence(pa.m_shortcut); - QString name = pa.m_name; - if (!seq.isEmpty()) { - name = QString("%1\t%2").arg(pa.m_name) - .arg(VUtils::getShortcutText(pa.m_shortcut)); - } - - QAction *act = new QAction(name, this); - act->setToolTip(tr("Open current note with %1").arg(pa.m_name)); - act->setStatusTip(pa.m_cmd); - act->setData(pa.m_cmd); - - if (!seq.isEmpty()) { - QShortcut *shortcut = new QShortcut(seq, this); - shortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(shortcut, &QShortcut::activated, - this, [act](){ - act->trigger(); - }); - } - - connect(act, &QAction::triggered, - this, &VFileList::handleOpenWithActionTriggered); - - m_openWithMenu->addAction(act); - } - - QKeySequence seq(g_config->getShortcutKeySequence("OpenViaDefaultProgram")); - QString name = tr("System's Default Program"); - if (!seq.isEmpty()) { - name = QString("%1\t%2").arg(name) - .arg(VUtils::getShortcutText(g_config->getShortcutKeySequence("OpenViaDefaultProgram"))); - } - QAction *defaultAct = new QAction(name, this); - defaultAct->setToolTip(tr("Open current note with system's default program")); - connect(defaultAct, &QAction::triggered, - this, &VFileList::openCurrentItemViaDefaultProgram); - - m_openWithMenu->addAction(defaultAct); - - QAction *addAct = new QAction(VIconUtils::menuIcon(":/resources/icons/add_program.svg"), - tr("Add External Program"), - this); - addAct->setToolTip(tr("Add external program")); - connect(addAct, &QAction::triggered, - this, [this]() { - VTipsDialog dialog(VUtils::getDocFile("tips_external_program.md"), - tr("Add External Program"), - []() { -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - // On macOS, it seems that we could not open that ini file directly. - QUrl url = QUrl::fromLocalFile(g_config->getConfigFolder()); -#else - QUrl url = QUrl::fromLocalFile(g_config->getConfigFilePath()); -#endif - QDesktopServices::openUrl(url); - }, - this); - dialog.exec(); - }); - - m_openWithMenu->addAction(addAct); - - return m_openWithMenu; -} - -void VFileList::handleOpenWithActionTriggered() -{ - QAction *act = static_cast(sender()); - QString cmd = act->data().toString(); - - QListWidgetItem *item = fileList->currentItem(); - if (item) { - VNoteFile *file = getVFile(item); - if (file - && (!g_config->getCloseBeforeExternalEditor() - || !editArea->isFileOpened(file) - || editArea->closeFile(file, false))) { - cmd.replace("%0", file->fetchPath()); - QProcess *process = new QProcess(this); - connect(process, static_cast(&QProcess::finished), - process, &QProcess::deleteLater); - process->start(cmd); - } - } -} - -void VFileList::updateNumberLabel() const -{ - int cnt = fileList->count(); - m_numLabel->setText(tr("%1 %2").arg(cnt) - .arg(cnt > 1 ? tr("Items") : tr("Item"))); -} - -void VFileList::updateViewMenu(QMenu *p_menu) -{ - if (p_menu->isEmpty()) { - QActionGroup *ag = new QActionGroup(p_menu); - - QAction *act = new QAction(tr("View By Configuration File"), ag); - act->setCheckable(true); - act->setData(ViewOrder::Config); - act->setChecked(true); - p_menu->addAction(act); - - act = new QAction(tr("View By Name"), ag); - act->setCheckable(true); - act->setData(ViewOrder::Name); - p_menu->addAction(act); - - act = new QAction(tr("View By Name (Reverse)"), ag); - act->setCheckable(true); - act->setData(ViewOrder::NameReverse); - p_menu->addAction(act); - - act = new QAction(tr("View By Created Time"), ag); - act->setCheckable(true); - act->setData(ViewOrder::CreatedTime); - p_menu->addAction(act); - - act = new QAction(tr("View By Created Time (Reverse)"), ag); - act->setCheckable(true); - act->setData(ViewOrder::CreatedTimeReverse); - p_menu->addAction(act); - - act = new QAction(tr("View By Modified Time"), ag); - act->setCheckable(true); - act->setData(ViewOrder::ModifiedTime); - p_menu->addAction(act); - - act = new QAction(tr("View By Modified Time (Reverse)"), ag); - act->setCheckable(true); - act->setData(ViewOrder::ModifiedTimeReverse); - p_menu->addAction(act); - - int config = g_config->getNoteListViewOrder(); - for (auto act : ag->actions()) { - if (act->data().toInt() == config) { - act->setChecked(true); - } - } - - connect(ag, &QActionGroup::triggered, - this, [this](QAction *p_action) { - int order = p_action->data().toInt(); - g_config->setNoteListViewOrder(order); - - sortFileList((ViewOrder)order); - }); - } -} - -void VFileList::sortFileList(ViewOrder p_order) -{ - if (!m_directory) { - return; - } - - QVector files = m_directory->getFiles(); - if (files.isEmpty()) { - return; - } - - sortFiles(files, p_order); - - int cnt = files.size(); - Q_ASSERT(cnt == fileList->count()); - for (int i = 0; i < cnt; ++i) { - int row = -1; - for (int j = i; j < cnt; ++j) { - QListWidgetItem *item = fileList->item(j); - if (files[i] == getVFile(item)) { - row = j; - break; - } - } - - Q_ASSERT(row > -1); - QListWidgetItem *item = fileList->takeItem(row); - fileList->insertItem(i, item); - } -} - -void VFileList::sortFiles(QVector &p_files, ViewOrder p_order) -{ - bool reverse = false; - - switch (p_order) { - case ViewOrder::Config: - break; - - case ViewOrder::NameReverse: - reverse = true; - V_FALLTHROUGH; - case ViewOrder::Name: - std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) { - if (reverse) { - return p_b->getName() < p_a->getName(); - } else { - return p_a->getName() < p_b->getName(); - } - }); - break; - - case ViewOrder::CreatedTimeReverse: - reverse = true; - V_FALLTHROUGH; - case ViewOrder::CreatedTime: - std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) { - if (reverse) { - return p_b->getCreatedTimeUtc() < p_a->getCreatedTimeUtc(); - } else { - return p_a->getCreatedTimeUtc() < p_b->getCreatedTimeUtc(); - } - }); - break; - - case ViewOrder::ModifiedTimeReverse: - reverse = true; - V_FALLTHROUGH; - case ViewOrder::ModifiedTime: - std::sort(p_files.begin(), p_files.end(), [reverse](const VNoteFile *p_a, const VNoteFile *p_b) { - if (reverse) { - return p_b->getModifiedTimeUtc() < p_a->getModifiedTimeUtc(); - } else { - return p_a->getModifiedTimeUtc() < p_b->getModifiedTimeUtc(); - } - }); - break; - - default: - break; - } -} - -void VFileList::selectFiles(const QVector &p_files) -{ - bool first = true; - for (auto const & file : p_files) { - QListWidgetItem *item = findItem(file); - if (item) { - if (first) { - first = false; - fileList->setCurrentItem(item, QItemSelectionModel::ClearAndSelect); - } else { - item->setSelected(true); - } - } - } -} - -QByteArray VFileList::getMimeData(const QString &p_format, - const QList &p_items) const -{ - Q_UNUSED(p_format); - Q_ASSERT(p_format ==ClipboardConfig::c_format); - - QJsonArray files; - for (int i = 0; i < p_items.size(); ++i) { - VNoteFile *file = getVFile(p_items[i]); - files.append(file->fetchPath()); - } - - QJsonObject obj; - obj[ClipboardConfig::c_type] = (int)ClipboardOpType::CopyFile; - obj[ClipboardConfig::c_files] = files; - - return QJsonDocument(obj).toJson(QJsonDocument::Compact); -} - -void VFileList::setEnableSplitOut(bool p_enabled) -{ - m_splitBtn->setChecked(p_enabled); -} - -void VFileList::openCurrentItemViaDefaultProgram() -{ - QListWidgetItem *item = fileList->currentItem(); - if (item) { - VNoteFile *file = getVFile(item); - if (file - && (!g_config->getCloseBeforeExternalEditor() - || !editArea->isFileOpened(file) - || editArea->closeFile(file, false))) { - QUrl url = QUrl::fromLocalFile(file->fetchPath()); - QDesktopServices::openUrl(url); - } - } -} diff --git a/src/vfilelist.h b/src/vfilelist.h deleted file mode 100644 index 6505d7a5..00000000 --- a/src/vfilelist.h +++ /dev/null @@ -1,244 +0,0 @@ -#ifndef VFILELIST_H -#define VFILELIST_H - -#include -#include -#include -#include -#include -#include -#include -#include "vnotebook.h" -#include "vconstants.h" -#include "vdirectory.h" -#include "vnotefile.h" -#include "vnavigationmode.h" -#include "vfilelistwidget.h" - -class VNote; -class QPushButton; -class VEditArea; -class QFocusEvent; -class QLabel; -class QMenu; -class QTimer; - -class VFileList : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VFileList(QWidget *parent = 0); - - // Import external files @p_files to current directory. - // Only copy the files itself. - bool importFiles(const QStringList &p_files, QString *p_errMsg = NULL); - - inline void setEditArea(VEditArea *editArea); - - // View and edit information of @p_file. - void fileInfo(VNoteFile *p_file); - - // Delete file @p_file. - // It is not necessary that @p_file exists in the list. - void deleteFile(VNoteFile *p_file); - - // Locate @p_file in the list widget. - bool locateFile(const VNoteFile *p_file); - - const VDirectory *currentDirectory() const; - - QWidget *getContentWidget() const; - - // Paste files given path by @p_files to destination directory @p_destDir. - void pasteFiles(VDirectory *p_destDir, - const QVector &p_files, - bool p_isCut); - - void setEnableSplitOut(bool p_enabled); - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -public slots: - // Set VFileList to display content of @p_directory directory. - void setDirectory(VDirectory *p_directory); - - // Create a note. - void newFile(); - -signals: - void fileClicked(VNoteFile *p_file, - OpenFileMode p_mode = OpenFileMode::Read, - bool p_forceMode = false); - - void fileCreated(VNoteFile *p_file, - OpenFileMode p_mode = OpenFileMode::Read, - bool p_forceMode = false); - - void fileUpdated(const VNoteFile *p_file, UpdateAction p_act); - - // Request to split self out of the notebook panel. - void requestSplitOut(bool p_enabled); - -private slots: - void contextMenuRequested(QPoint pos); - - void handleItemClicked(QListWidgetItem *p_item); - - void showStatusTipAboutItem(QListWidgetItem *p_item); - - // View and edit information of selected file. - // Valid only when there is only one selected file. - void fileInfo(); - - // Open the folder containing selected file in system's file browser. - // Valid only when there is only one selected file. - void openFileLocation() const; - - // Add selected files to Cart. - void addFileToCart() const; - - // Add selected files to History and pin them. - void pinFileToHistory() const; - - void setFileQuickAccess() const; - - // Copy selected files to clipboard. - // Will put a Json string into the clipboard which contains the information - // about copied files. - void copySelectedFiles(bool p_isCut = false); - - void cutSelectedFiles(); - - // Paste files from clipboard. - void pasteFilesFromClipboard(); - - // Delete selected files. - void deleteSelectedFiles(); - - // Delete files @p_files. - void deleteFiles(const QVector &p_files); - - // Sort files in this list. - void sortItems(); - - // Hanlde Open With action's triggered signal. - void handleOpenWithActionTriggered(); - - void openCurrentItemViaDefaultProgram(); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private: - // Should be aligned with note_list_view_order in vnote.ini. - enum ViewOrder - { - Config = 0, - Name, - NameReverse, - CreatedTime, - CreatedTimeReverse, - ModifiedTime, - ModifiedTimeReverse, - Max - }; - - void setupUI(); - - // Init shortcuts. - void initShortcuts(); - - // Clear and re-fill the list widget according to m_directory. - void updateFileList(); - - // Insert a new item into the list widget. - // @file: the file represented by the new item. - // @atFront: insert at the front or back of the list widget. - QListWidgetItem *insertFileListItem(VNoteFile *file, bool atFront = false); - - // Remove and delete item related to @p_file from list widget. - void removeFileListItem(VNoteFile *p_file); - - // Return the corresponding QListWidgetItem of @p_file. - QListWidgetItem *findItem(const VNoteFile *p_file); - - inline QPointer getVFile(QListWidgetItem *p_item) const; - - // Fill the info of @p_item according to @p_file. - void fillItem(QListWidgetItem *p_item, const VNoteFile *p_file); - - // Generate new magic to m_magicForClipboard. - int getNewMagic(); - - // Check if @p_magic equals to m_magicForClipboard. - bool checkMagic(int p_magic) const; - - // Check if there are files in clipboard available to paste. - bool pasteAvailable() const; - - QMenu *getOpenWithMenu(); - - void activateItem(QListWidgetItem *p_item, bool p_restoreFocus = false); - - void updateNumberLabel() const; - - // Update the View menu. - void updateViewMenu(QMenu *p_menu); - - // Sort file list. - void sortFileList(ViewOrder p_order); - - void sortFiles(QVector &p_files, ViewOrder p_order); - - void selectFiles(const QVector &p_files); - - QByteArray getMimeData(const QString &p_format, const QList &p_items) const; - - VEditArea *editArea; - - VFileListWidget *fileList; - - QPushButton *m_splitBtn; - - QLabel *m_numLabel; - - QPointer m_directory; - - // Magic number for clipboard operations. - int m_magicForClipboard; - - // Context sub-menu of Open With. - QMenu *m_openWithMenu; - - QTimer *m_clickTimer; - - QListWidgetItem *m_itemClicked; - - VFile *m_fileToCloseInSingleClick; -}; - -inline void VFileList::setEditArea(VEditArea *editArea) -{ - this->editArea = editArea; -} - -inline QPointer VFileList::getVFile(QListWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - return (VNoteFile *)p_item->data(Qt::UserRole).toULongLong(); -} - -inline const VDirectory *VFileList::currentDirectory() const -{ - return m_directory; -} - -inline QWidget *VFileList::getContentWidget() const -{ - return fileList; -} -#endif // VFILELIST_H diff --git a/src/vfilelistwidget.cpp b/src/vfilelistwidget.cpp deleted file mode 100644 index 61a8dcba..00000000 --- a/src/vfilelistwidget.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "vfilelistwidget.h" - -#include -#include -#include -#include -#include - -#include "vconstants.h" - -VFileListWidget::VFileListWidget(QWidget *p_parent) - : VListWidget(p_parent) -{ - setSelectionMode(QAbstractItemView::ExtendedSelection); - setDragEnabled(true); - setMouseTracking(true); -} - -QStringList VFileListWidget::mimeTypes() const -{ - return QStringList(ClipboardConfig::c_format); -} - -QMimeData *VFileListWidget::mimeData(const QList p_items) const -{ - const QString format(ClipboardConfig::c_format); - QStringList types = mimeTypes(); - if (!types.contains(format) || p_items.isEmpty()) { - return NULL; - } - - if (m_mimeDataGetter) { - QMimeData *data = new QMimeData(); - data->setData(format, m_mimeDataGetter(format, p_items)); - return data; - } - - return NULL; -} - -void VFileListWidget::setMimeDataGetter(const MimeDataGetterFunc &p_getter) -{ - m_mimeDataGetter = p_getter; -} diff --git a/src/vfilelistwidget.h b/src/vfilelistwidget.h deleted file mode 100644 index 8d2b7109..00000000 --- a/src/vfilelistwidget.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef VFILELISTWIDGET_H -#define VFILELISTWIDGET_H - -#include "vlistwidget.h" - -#include -#include - -typedef std::function &)> MimeDataGetterFunc; - -class VFileListWidget : public VListWidget -{ - Q_OBJECT -public: - explicit VFileListWidget(QWidget *p_parent = nullptr); - - void setMimeDataGetter(const MimeDataGetterFunc &p_getter); - -protected: - QStringList mimeTypes() const Q_DECL_OVERRIDE; - - QMimeData *mimeData(const QList p_items) const Q_DECL_OVERRIDE; - -private: - MimeDataGetterFunc m_mimeDataGetter; -}; - -#endif // VFILELISTWIDGET_H diff --git a/src/vfilesessioninfo.cpp b/src/vfilesessioninfo.cpp deleted file mode 100644 index 91c478c8..00000000 --- a/src/vfilesessioninfo.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "vfilesessioninfo.h" - -#include - -#include "vedittabinfo.h" -#include "vtableofcontent.h" -#include "vedittab.h" - - -VFileSessionInfo::VFileSessionInfo() - : m_mode(OpenFileMode::Read), - m_active(false), - m_headerIndex(-1), - m_cursorBlockNumber(-1), - m_cursorPositionInBlock(-1) -{ -} - -VFileSessionInfo::VFileSessionInfo(const QString &p_file, - OpenFileMode p_mode) - : m_file(p_file), - m_mode(p_mode), - m_active(false), - m_headerIndex(-1), - m_cursorBlockNumber(-1), - m_cursorPositionInBlock(-1) -{ -} - -// Fetch VFileSessionInfo from @p_tabInfo. -VFileSessionInfo VFileSessionInfo::fromEditTabInfo(const VEditTabInfo *p_tabInfo) -{ - Q_ASSERT(p_tabInfo); - VEditTab *tab = p_tabInfo->m_editTab; - VFileSessionInfo info(tab->getFile()->fetchPath(), - tab->isEditMode() ? OpenFileMode::Edit : OpenFileMode::Read); - info.m_headerIndex = p_tabInfo->m_headerIndex; - info.m_cursorBlockNumber = p_tabInfo->m_cursorBlockNumber; - info.m_cursorPositionInBlock = p_tabInfo->m_cursorPositionInBlock; - - return info; -} - -void VFileSessionInfo::toEditTabInfo(VEditTabInfo *p_tabInfo) const -{ - p_tabInfo->m_headerIndex = m_headerIndex; - p_tabInfo->m_cursorBlockNumber = m_cursorBlockNumber; - p_tabInfo->m_cursorPositionInBlock = m_cursorPositionInBlock; -} - -VFileSessionInfo VFileSessionInfo::fromSettings(const QSettings *p_settings) -{ - VFileSessionInfo info; - info.m_file = p_settings->value(FileSessionConfig::c_file).toString(); - int tmpMode = p_settings->value(FileSessionConfig::c_mode).toInt(); - if (tmpMode >= (int)OpenFileMode::Read && tmpMode < (int)OpenFileMode::Invalid) { - info.m_mode = (OpenFileMode)tmpMode; - } else { - info.m_mode = OpenFileMode::Read; - } - - info.m_active = p_settings->value(FileSessionConfig::c_active).toBool(); - info.m_headerIndex = p_settings->value(FileSessionConfig::c_headerIndex).toInt(); - info.m_cursorBlockNumber = p_settings->value(FileSessionConfig::c_cursorBlockNumber).toInt(); - info.m_cursorPositionInBlock = p_settings->value(FileSessionConfig::c_cursorPositionInBlock).toInt(); - - return info; -} - -void VFileSessionInfo::toSettings(QSettings *p_settings) const -{ - p_settings->setValue(FileSessionConfig::c_file, m_file); - p_settings->setValue(FileSessionConfig::c_mode, (int)m_mode); - p_settings->setValue(FileSessionConfig::c_active, m_active); - p_settings->setValue(FileSessionConfig::c_headerIndex, m_headerIndex); - p_settings->setValue(FileSessionConfig::c_cursorBlockNumber, m_cursorBlockNumber); - p_settings->setValue(FileSessionConfig::c_cursorPositionInBlock, m_cursorPositionInBlock); -} diff --git a/src/vfilesessioninfo.h b/src/vfilesessioninfo.h deleted file mode 100644 index 5edbd075..00000000 --- a/src/vfilesessioninfo.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef VFILESESSIONINFO_H -#define VFILESESSIONINFO_H - -#include "vconstants.h" - -struct VEditTabInfo; -class QSettings; - -namespace FileSessionConfig -{ - static const QString c_file = "file"; - static const QString c_mode = "mode"; - - // Whether it is current file. - static const QString c_active = "active"; - - // Index in outline of the anchor. - static const QString c_headerIndex = "header_index"; - - static const QString c_cursorBlockNumber = "cursor_block_number"; - static const QString c_cursorPositionInBlock = "cursor_position_in_block"; -} - -// Information about an opened file (session). -class VFileSessionInfo -{ -public: - VFileSessionInfo(); - - VFileSessionInfo(const QString &p_file, - OpenFileMode p_mode); - - // Fetch VFileSessionInfo from @p_tabInfo. - static VFileSessionInfo fromEditTabInfo(const VEditTabInfo *p_tabInfo); - - // Fill corresponding fields of @p_tabInfo. - void toEditTabInfo(VEditTabInfo *p_tabInfo) const; - - // Fetch VFileSessionInfo from @p_settings. - static VFileSessionInfo fromSettings(const QSettings *p_settings); - - void toSettings(QSettings *p_settings) const; - - void setActive(bool p_active) - { - m_active = p_active; - } - - // Absolute path of the file. - QString m_file; - - // Mode of this file in this session. - OpenFileMode m_mode; - - // Whether this file is current file. - bool m_active; - - // Index in outline of the header. - int m_headerIndex; - - // Block number of cursor block. - int m_cursorBlockNumber; - - // Position in block of cursor. - int m_cursorPositionInBlock; -}; - -#endif // VFILESESSIONINFO_H diff --git a/src/vgraphvizhelper.cpp b/src/vgraphvizhelper.cpp deleted file mode 100644 index fa3ed04c..00000000 --- a/src/vgraphvizhelper.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include "vgraphvizhelper.h" - -#include -#include - -#include "vconfigmanager.h" -#include "utils/vprocessutils.h" - -extern VConfigManager *g_config; - -#define TaskIdProperty "GraphvizTaskId" -#define TaskFormatProperty "GraphvizTaskFormat" -#define TaskTimeStampProperty "GraphvizTaskTimeStamp" - -VGraphvizHelper::VGraphvizHelper(QObject *p_parent) - : QObject(p_parent) -{ - prepareCommand(m_program, m_args); -} - -void VGraphvizHelper::processAsync(int p_id, TimeStamp p_timeStamp, const QString &p_format, const QString &p_text) -{ - QProcess *process = new QProcess(this); - process->setProperty(TaskIdProperty, p_id); - process->setProperty(TaskTimeStampProperty, p_timeStamp); - process->setProperty(TaskFormatProperty, p_format); - connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), - this, SLOT(handleProcessFinished(int, QProcess::ExitStatus))); - - QStringList args(m_args); - args << ("-T" + p_format); - - qDebug() << m_program << args; - - process->start(m_program, args); - if (process->write(p_text.toUtf8()) == -1) { - qWarning() << "fail to write to QProcess:" << process->errorString(); - } - - process->closeWriteChannel(); -} - -void VGraphvizHelper::prepareCommand(QString &p_program, QStringList &p_args) const -{ - const QString &dot = g_config->getGraphvizDot(); - if (dot.isEmpty()) { - p_program = "dot"; - } else { - p_program = dot; - } - - p_args.clear(); -} - -void VGraphvizHelper::handleProcessFinished(int p_exitCode, QProcess::ExitStatus p_exitStatus) -{ - QProcess *process = static_cast(sender()); - int id = process->property(TaskIdProperty).toInt(); - QString format = process->property(TaskFormatProperty).toString(); - TimeStamp timeStamp = process->property(TaskTimeStampProperty).toULongLong(); - qDebug() << QString("Graphviz finished: id %1 timestamp %2 format %3 exitcode %4 exitstatus %5") - .arg(id) - .arg(timeStamp) - .arg(format) - .arg(p_exitCode) - .arg(p_exitStatus); - bool failed = true; - if (p_exitStatus == QProcess::NormalExit) { - if (p_exitCode < 0) { - qWarning() << "Graphviz fail" << p_exitCode; - } else { - failed = false; - QByteArray outBa = process->readAllStandardOutput(); - if (format == "svg") { - emit resultReady(id, timeStamp, format, QString::fromLocal8Bit(outBa)); - } else { - emit resultReady(id, timeStamp, format, QString::fromLocal8Bit(outBa.toBase64())); - } - } - } else { - qWarning() << "fail to start Graphviz process" << p_exitCode << p_exitStatus; - } - - QByteArray errBa = process->readAllStandardError(); - if (!errBa.isEmpty()) { - QString errStr(QString::fromLocal8Bit(errBa)); - if (failed) { - qWarning() << "Graphviz stderr:" << errStr; - } else { - qDebug() << "Graphviz stderr:" << errStr; - } - } - - if (failed) { - emit resultReady(id, timeStamp, format, ""); - } - - process->deleteLater(); -} - -bool VGraphvizHelper::testGraphviz(const QString &p_dot, QString &p_msg) -{ - QString program(p_dot); - QStringList args; - args << "-Tsvg"; - - QString testGraph("digraph G {VNote->Markdown}"); - - int exitCode = -1; - QByteArray out, err; - int ret = VProcessUtils::startProcess(program, args, testGraph.toUtf8(), exitCode, out, err); - - p_msg = QString("Command: %1 %2\nExitCode: %3\nOutput: %4\nError: %5") - .arg(program) - .arg(args.join(' ')) - .arg(exitCode) - .arg(QString::fromLocal8Bit(out)) - .arg(QString::fromLocal8Bit(err)); - - return ret == 0 && exitCode == 0; -} - -QByteArray VGraphvizHelper::process(const QString &p_format, const QString &p_text) -{ - VGraphvizHelper inst; - - int exitCode = -1; - QByteArray out, err; - - QStringList args(inst.m_args); - args << ("-T" + p_format); - int ret = VProcessUtils::startProcess(inst.m_program, - args, - p_text.toUtf8(), - exitCode, - out, - err); - - if (ret != 0 || exitCode < 0) { - qWarning() << "Graphviz fail" << ret << exitCode << QString::fromLocal8Bit(err); - } - - return out; -} diff --git a/src/vgraphvizhelper.h b/src/vgraphvizhelper.h deleted file mode 100644 index bf56e3a0..00000000 --- a/src/vgraphvizhelper.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef VGRAPHVIZHELPER_H -#define VGRAPHVIZHELPER_H - -#include - -#include -#include - -#include "vconstants.h" - -class VGraphvizHelper : public QObject -{ - Q_OBJECT -public: - explicit VGraphvizHelper(QObject *p_parent = nullptr); - - void processAsync(int p_id, TimeStamp p_timeStamp, const QString &p_format, const QString &p_text); - - static bool testGraphviz(const QString &p_dot, QString &p_msg); - - static QByteArray process(const QString &p_format, const QString &p_text); - -signals: - void resultReady(int p_id, TimeStamp p_timeStamp, const QString &p_format, const QString &p_result); - -private slots: - void handleProcessFinished(int p_exitCode, QProcess::ExitStatus p_exitStatus); - -private: - void prepareCommand(QString &p_cmd, QStringList &p_args) const; - - QString m_program; - QStringList m_args; -}; - -#endif // VGRAPHVIZHELPER_H diff --git a/src/vhelpue.cpp b/src/vhelpue.cpp deleted file mode 100644 index 894c0b6c..00000000 --- a/src/vhelpue.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "vhelpue.h" - -#include "vlistwidget.h" - - -VHelpUE::VHelpUE(QObject *p_parent) - : IUniversalEntry(p_parent), - m_listWidget(NULL) -{ -} - -void VHelpUE::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - m_listWidget = new VListWidget(m_widgetParent); - m_listWidget->setFitContent(true); -} - -QString VHelpUE::description(int p_id) const -{ - Q_UNUSED(p_id); - return tr("View help information about Universal Entry"); -} - -QWidget *VHelpUE::widget(int p_id) -{ - Q_UNUSED(p_id); - - init(); - - return m_listWidget; -} - -void VHelpUE::processCommand(int p_id, const QString &p_cmd) -{ - Q_UNUSED(p_id); - Q_UNUSED(p_cmd); - - init(); - - if (initListWidget()) { - m_listWidget->updateGeometry(); - emit widgetUpdated(); - } - - emit stateUpdated(State::Success); -} - -void VHelpUE::clear(int p_id) -{ - Q_UNUSED(p_id); - m_listWidget->clearAll(); -} - -bool VHelpUE::initListWidget() -{ - if (m_listWidget->count() == 0) { - m_listWidget->addItem(tr("Esc or Ctrl+[: Hide Universal Entry")); - m_listWidget->addItem(tr("Ctrl+U: Clear the command input")); - m_listWidget->addItem(tr("Ctrl+E: Clear the command input except the entry key")); - m_listWidget->addItem(tr("Ctrl+F: Select the entry key to change")); - m_listWidget->addItem(tr("Ctrl+D: Cancel the command")); - m_listWidget->addItem(tr("Ctrl+J: Go to next item")); - m_listWidget->addItem(tr("Ctrl+K: Go to previous item")); - m_listWidget->addItem(tr("Ctrl+L: Go to current item's parent item")); - m_listWidget->addItem(tr("Ctrl+I: Expand/Collapse current item")); - m_listWidget->addItem(tr("Ctrl+B: Expand/Collapse all items")); - m_listWidget->addItem(tr("Ctrl+S: Sort items")); - m_listWidget->addItem(tr("Enter: Activate current item")); - m_listWidget->addItem(tr("Ctrl+M: Browse current item folder or the folder containing current item")); - m_listWidget->addItem(tr("Magic Switches:")); - m_listWidget->addItem(tr("\\c or \\C: Case insensitive or sensitive")); - m_listWidget->addItem(tr("\\r or \\R: Disable or enable regular expression")); - m_listWidget->addItem(tr("\\f or \\F: Disable or enable fuzzy search")); - m_listWidget->addItem(tr("\\w or \\W: Disable or enable whole word only")); - - return true; - } - - return false; -} diff --git a/src/vhelpue.h b/src/vhelpue.h deleted file mode 100644 index 8a5ac1cb..00000000 --- a/src/vhelpue.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef VHELPUE_H -#define VHELPUE_H - -#include "iuniversalentry.h" - -class VListWidget; - -class VHelpUE : public IUniversalEntry -{ - Q_OBJECT -public: - explicit VHelpUE(QObject *p_parent = nullptr); - - QString description(int p_id) const Q_DECL_OVERRIDE; - - QWidget *widget(int p_id) Q_DECL_OVERRIDE; - - void processCommand(int p_id, const QString &p_cmd) Q_DECL_OVERRIDE; - - void clear(int p_id) Q_DECL_OVERRIDE; - -protected: - void init() Q_DECL_OVERRIDE; - -private: - bool initListWidget(); - - VListWidget *m_listWidget; -}; - -#endif // VHELPUE_H diff --git a/src/vhistoryentry.h b/src/vhistoryentry.h deleted file mode 100644 index 84d25354..00000000 --- a/src/vhistoryentry.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef VHISTORYENTRY_H -#define VHISTORYENTRY_H - -#include -#include - -namespace HistoryConfig -{ - static const QString c_file = "file"; - static const QString c_date = "date"; - static const QString c_pinned = "pinned"; - static const QString c_isFolder = "is_folder"; -} - -class VHistoryEntry -{ -public: - VHistoryEntry() - : m_isPinned(false), - m_isFolder(false) - { - } - - VHistoryEntry(const QString &p_file, - const QDate &p_date, - bool p_isPinned = false, - bool p_isFolder = false) - : m_file(p_file), m_isPinned(p_isPinned), m_isFolder(p_isFolder) - { - m_date = p_date.toString(Qt::ISODate); - } - - // Fetch VHistoryEntry from @p_settings. - static VHistoryEntry fromSettings(const QSettings *p_settings) - { - VHistoryEntry entry; - entry.m_file = p_settings->value(HistoryConfig::c_file).toString(); - entry.m_date = p_settings->value(HistoryConfig::c_date).toString(); - entry.m_isPinned = p_settings->value(HistoryConfig::c_pinned).toBool(); - entry.m_isFolder = p_settings->value(HistoryConfig::c_isFolder).toBool(); - return entry; - } - - void toSettings(QSettings *p_settings) const - { - p_settings->setValue(HistoryConfig::c_file, m_file); - p_settings->setValue(HistoryConfig::c_date, m_date); - p_settings->setValue(HistoryConfig::c_pinned, m_isPinned); - p_settings->setValue(HistoryConfig::c_isFolder, m_isFolder); - } - - // File path. - QString m_file; - - // Accessed date. - // UTC in Qt::ISODate format. - QString m_date; - - bool m_isPinned; - - bool m_isFolder; -}; - -#endif // VHISTORYENTRY_H diff --git a/src/vhistorylist.cpp b/src/vhistorylist.cpp deleted file mode 100644 index fb615f9b..00000000 --- a/src/vhistorylist.cpp +++ /dev/null @@ -1,512 +0,0 @@ -#include "vhistorylist.h" - -#include - -#include "utils/viconutils.h" -#include "utils/vutils.h" -#include "vlistwidget.h" -#include "vconfigmanager.h" -#include "vmainwindow.h" -#include "vcart.h" -#include "vnote.h" -#include "vnotefile.h" -#include "vdirectory.h" - -extern VMainWindow *g_mainWin; - -extern VConfigManager *g_config; - -extern VNote *g_vnote; - -VHistoryList::VHistoryList(QWidget *p_parent) - : QWidget(p_parent), - m_initialized(false), - m_uiInitialized(false), - m_updatePending(true), - m_currentDate(QDate::currentDate()) -{ -} - -void VHistoryList::setupUI() -{ - if (m_uiInitialized) { - return; - } - - m_uiInitialized = true; - - m_clearBtn = new QPushButton(VIconUtils::buttonDangerIcon(":/resources/icons/clear_history.svg"), ""); - m_clearBtn->setToolTip(tr("Clear")); - m_clearBtn->setProperty("FlatBtn", true); - connect(m_clearBtn, &QPushButton::clicked, - this, [this]() { - init(); - - if (m_histories.size() > 0) { - int ret = VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Are you sure to clear History?"), - "", - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - g_mainWin, - MessageBoxType::Danger); - if (ret == QMessageBox::Ok) { - m_histories.clear(); - g_config->setHistory(m_histories); - m_updatePending = true; - updateList(); - } - } - }); - - QHBoxLayout *btnLayout = new QHBoxLayout; - btnLayout->addWidget(m_clearBtn); - btnLayout->addStretch(); - btnLayout->setContentsMargins(0, 0, 0, 0); - - m_itemList = new VListWidget(); - m_itemList->setAttribute(Qt::WA_MacShowFocusRect, false); - m_itemList->setContextMenuPolicy(Qt::CustomContextMenu); - m_itemList->setSelectionMode(QAbstractItemView::ExtendedSelection); - connect(m_itemList, &QListWidget::customContextMenuRequested, - this, &VHistoryList::handleContextMenuRequested); - connect(m_itemList, &QListWidget::itemActivated, - this, &VHistoryList::openItem); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(btnLayout); - mainLayout->addWidget(m_itemList); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -void VHistoryList::addFile(const QString &p_filePath) -{ - init(); - - QStringList files; - files << p_filePath; - addFilesInternal(files, false); - - if (isVisible()) { - updateList(); - } -} - -void VHistoryList::pinFiles(const QStringList &p_files) -{ - init(); - - addFilesInternal(p_files, true); - if (isVisible()) { - updateList(); - } -} - -void VHistoryList::unpinFiles(const QStringList &p_files) -{ - init(); - - for (auto const & file : p_files) { - auto it = findFileInHistory(file); - if (it != m_histories.end()) { - it->m_isPinned = false; - } - } - - g_config->setHistory(m_histories); - m_updatePending = true; -} - -void VHistoryList::pinFolder(const QString &p_folder) -{ - init(); - - auto it = findFileInHistory(p_folder); - if (it != m_histories.end()) { - return; - } - - m_histories.append(VHistoryEntry(p_folder, QDate::currentDate(), true, true)); - - checkHistorySize(); - - g_config->setHistory(m_histories); - m_updatePending = true; - - if (isVisible()) { - updateList(); - } -} - -void VHistoryList::addFilesInternal(const QStringList &p_files, bool p_isPinned) -{ - for (auto const & file : p_files) { - // Find it in existing entries. - bool pinnedBefore = false; - auto it = findFileInHistory(file); - if (it != m_histories.end()) { - pinnedBefore = it->m_isPinned; - m_histories.erase(it); - } - - // Append an entry at the end. - bool pin = p_isPinned ? true : (pinnedBefore ? true : false); - m_histories.append(VHistoryEntry(file, QDate::currentDate(), pin)); - } - - checkHistorySize(); - - g_config->setHistory(m_histories); - m_updatePending = true; -} - -void VHistoryList::checkHistorySize() -{ - int numToRemove = m_histories.size() - g_config->getHistorySize(); - for (auto rit = m_histories.begin(); numToRemove > 0 && rit != m_histories.end();) { - if (rit->m_isPinned) { - ++rit; - continue; - } - - rit = m_histories.erase(rit); - --numToRemove; - } -} - -void VHistoryList::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - setupUI(); - - g_config->getHistory(m_histories); - - m_updatePending = true; -} - -void VHistoryList::showEvent(QShowEvent *p_event) -{ - init(); - - if (m_currentDate != QDate::currentDate()) { - m_currentDate = QDate::currentDate(); - m_updatePending = true; - } - - updateList(); - - QWidget::showEvent(p_event); -} - -QLinkedList::iterator VHistoryList::findFileInHistory(const QString &p_file) -{ - for (QLinkedList::iterator it = m_histories.begin(); - it != m_histories.end(); - ++it) { - if (VUtils::equalPath(p_file, it->m_file)) { - return it; - } - } - - return m_histories.end(); -} - -struct SeparatorItem -{ - SeparatorItem() - : m_valid(false) - { - } - - QString m_date; - QListWidgetItem *m_item; - bool m_valid; -}; - -void VHistoryList::updateList() -{ - if (!m_updatePending) { - return; - } - - m_updatePending = false; - - m_itemList->clearAll(); - - if (m_histories.isEmpty()) { - return; - } - - // Add separators. - // Pinned separator. - SeparatorItem pinItem; - pinItem.m_item = VListWidget::createSeparatorItem(tr("Pinned")); - m_itemList->addItem(pinItem.m_item); - - const int sepSize = 4; - QString sepText[4] = {tr("Today"), tr("Yesterday"), tr("Last 7 Days"), tr("Older")}; - QVector seps(sepSize); - - seps[0].m_date = m_currentDate.toString(Qt::ISODate); - seps[1].m_date = m_currentDate.addDays(-1).toString(Qt::ISODate); - seps[2].m_date = m_currentDate.addDays(-7).toString(Qt::ISODate); - // Leave the last string empty. - - for (int i = 0; i < sepSize; ++i) { - seps[i].m_item = VListWidget::createSeparatorItem(sepText[i]); - m_itemList->addItem(seps[i].m_item); - } - - QIcon noteIcon(VIconUtils::treeViewIcon(":/resources/icons/note_item.svg")); - QIcon folderIcon(VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg")); - for (auto it = m_histories.cbegin(); it != m_histories.cend(); ++it) { - QListWidgetItem *item = new QListWidgetItem(VUtils::fileNameFromPath(it->m_file)); - item->setToolTip(it->m_file); - item->setData(Qt::UserRole, (qulonglong)&(*it)); - - if (it->m_isFolder) { - item->setIcon(folderIcon); - } else { - item->setIcon(noteIcon); - } - - if (it->m_isPinned) { - m_itemList->insertItem(m_itemList->row(pinItem.m_item) + 1, item); - pinItem.m_valid = true; - continue; - } - - for (int i = 0; i < sepSize; ++i) { - if (it->m_date >= seps[i].m_date) { - m_itemList->insertItem(m_itemList->row(seps[i].m_item) + 1, item); - seps[i].m_valid = true; - break; - } - } - } - - // We always display pinned separator. - - for (int i = 0; i < sepSize; ++i) { - if (!seps[i].m_valid) { - delete seps[i].m_item; - } - } - - seps.clear(); -} - -void VHistoryList::handleContextMenuRequested(QPoint p_pos) -{ - QListWidgetItem *item = m_itemList->itemAt(p_pos); - if (!item || VListWidget::isSeparatorItem(item)) { - return; - } - - QMenu menu(this); - menu.setToolTipsVisible(true); - - QAction *openAct = new QAction(tr("&Open"), &menu); - openAct->setToolTip(tr("Open selected notes")); - connect(openAct, &QAction::triggered, - this, &VHistoryList::openSelectedItems); - menu.addAction(openAct); - - QList selectedItems = m_itemList->selectedItems(); - if (selectedItems.size() == 1) { - QAction *locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"), - tr("&Locate To Folder"), - &menu); - locateAct->setToolTip(tr("Locate the folder of current note")); - connect(locateAct, &QAction::triggered, - this, &VHistoryList::locateCurrentItem); - menu.addAction(locateAct); - } - - bool allPinned = true, allUnpinned = true; - for (auto const & it : selectedItems) { - if (getHistoryEntry(it)->m_isPinned) { - allUnpinned = false; - } else { - allPinned = false; - } - } - - if (allUnpinned) { - QAction *pinAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"), - tr("Pin"), - &menu); - pinAct->setToolTip(tr("Pin selected notes in History")); - connect(pinAct, &QAction::triggered, - this, &VHistoryList::pinSelectedItems); - menu.addAction(pinAct); - } else if (allPinned) { - QAction *unpinAct = new QAction(tr("Unpin"), &menu); - unpinAct->setToolTip(tr("Unpin selected notes in History")); - connect(unpinAct, &QAction::triggered, - this, &VHistoryList::unpinSelectedItems); - menu.addAction(unpinAct); - } - - menu.addSeparator(); - - QAction *addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"), - tr("Add To Cart"), - &menu); - addToCartAct->setToolTip(tr("Add selected notes to Cart for further processing")); - connect(addToCartAct, &QAction::triggered, - this, &VHistoryList::addFileToCart); - menu.addAction(addToCartAct); - - menu.exec(m_itemList->mapToGlobal(p_pos)); -} - -bool VHistoryList::isFolder(const QListWidgetItem *p_item) const -{ - return getHistoryEntry(p_item)->m_isFolder; -} - -VHistoryEntry *VHistoryList::getHistoryEntry(const QListWidgetItem *p_item) const -{ - return (VHistoryEntry *)p_item->data(Qt::UserRole).toULongLong(); -} - -QString VHistoryList::getFilePath(const QListWidgetItem *p_item) const -{ - return getHistoryEntry(p_item)->m_file; -} - -void VHistoryList::pinSelectedItems() -{ - QStringList files; - QList selectedItems = m_itemList->selectedItems(); - for (auto it : selectedItems) { - files << getFilePath(it); - } - - pinFiles(files); -} - -void VHistoryList::unpinSelectedItems() -{ - QStringList files; - QList selectedItems = m_itemList->selectedItems(); - for (auto it : selectedItems) { - files << getFilePath(it); - } - - unpinFiles(files); - - if (isVisible()) { - updateList(); - } -} - -void VHistoryList::openSelectedItems() const -{ - QStringList files; - QList selectedItems = m_itemList->selectedItems(); - - if (selectedItems.size() == 1 && isFolder(selectedItems.first())) { - // Locate to the folder. - VDirectory *dir = g_vnote->getInternalDirectory(getFilePath(selectedItems.first())); - if (dir) { - g_mainWin->locateDirectory(dir); - } - - return; - } - - for (auto it : selectedItems) { - if (isFolder(it)) { - // Skip folders. - continue; - } - - files << getFilePath(it); - } - - if (!files.isEmpty()) { - g_mainWin->openFiles(files); - } -} - -void VHistoryList::openItem(const QListWidgetItem *p_item) const -{ - if (!p_item) { - return; - } - - if (isFolder(p_item)) { - // Locate to the folder. - VDirectory *dir = g_vnote->getInternalDirectory(getFilePath(p_item)); - if (dir) { - g_mainWin->locateDirectory(dir); - } - - return; - } - - QStringList files; - files << getFilePath(p_item); - g_mainWin->openFiles(files); -} - -void VHistoryList::locateCurrentItem() const -{ - auto item = m_itemList->currentItem(); - if (!item) { - return; - } - - VFile *file = g_vnote->getInternalFile(getFilePath(item)); - if (file) { - g_mainWin->locateFile(file); - } -} - -void VHistoryList::showNavigation() -{ - setupUI(); - - VNavigationMode::showNavigation(m_itemList); -} - -bool VHistoryList::handleKeyNavigation(int p_key, bool &p_succeed) -{ - setupUI(); - - return VNavigationMode::handleKeyNavigation(m_itemList, - p_key, - p_succeed); -} - -void VHistoryList::addFileToCart() const -{ - QList items = m_itemList->selectedItems(); - VCart *cart = g_mainWin->getCart(); - - for (int i = 0; i < items.size(); ++i) { - cart->addFile(getFilePath(items[i])); - } - - g_mainWin->showStatusMessage(tr("%1 %2 added to Cart") - .arg(items.size()) - .arg(items.size() > 1 ? tr("notes") : tr("note"))); -} - -void VHistoryList::focusInEvent(QFocusEvent *p_event) -{ - init(); - - QWidget::focusInEvent(p_event); - m_itemList->setFocus(); -} diff --git a/src/vhistorylist.h b/src/vhistorylist.h deleted file mode 100644 index 480973a3..00000000 --- a/src/vhistorylist.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef VHISTORYLIST_H -#define VHISTORYLIST_H - -#include -#include - -#include "vhistoryentry.h" -#include "vnavigationmode.h" - -class QPushButton; -class VListWidget; -class QListWidgetItem; -class QShowEvent; -class QFocusEvent; - -class VHistoryList : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VHistoryList(QWidget *p_parent = nullptr); - - void pinFiles(const QStringList &p_files); - - void pinFolder(const QString &p_folder); - - const QLinkedList &getHistoryEntries() const; - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -public slots: - void addFile(const QString &p_filePath); - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void handleContextMenuRequested(QPoint p_pos); - - void openSelectedItems() const; - - void openItem(const QListWidgetItem *p_item) const; - - void pinSelectedItems(); - - void unpinSelectedItems(); - - void locateCurrentItem() const; - - // Add selected files to Cart. - void addFileToCart() const; - -private: - void setupUI(); - - // Read data from config file. - void init(); - - void updateList(); - - QLinkedList::iterator findFileInHistory(const QString &p_file); - - QString getFilePath(const QListWidgetItem *p_item) const; - - VHistoryEntry *getHistoryEntry(const QListWidgetItem *p_item) const; - - bool isFolder(const QListWidgetItem *p_item) const; - - // @p_isPinned won't change it if an item is pinned already. - void addFilesInternal(const QStringList &p_files, bool p_isPinned); - - void unpinFiles(const QStringList &p_files); - - void checkHistorySize(); - - QPushButton *m_clearBtn; - VListWidget *m_itemList; - - // Whether data is loaded. - bool m_initialized; - - bool m_uiInitialized; - - // New files are appended to the end. - QLinkedList m_histories; - - // Whether we need to update the list. - bool m_updatePending; - - QDate m_currentDate; -}; - -inline const QLinkedList &VHistoryList::getHistoryEntries() const -{ - const_cast(this)->init(); - - return m_histories; -} -#endif // VHISTORYLIST_H diff --git a/src/vhtmltab.cpp b/src/vhtmltab.cpp deleted file mode 100644 index c40d8a89..00000000 --- a/src/vhtmltab.cpp +++ /dev/null @@ -1,297 +0,0 @@ -#include -#include -#include "vhtmltab.h" -#include "vedit.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" -#include "vnotebook.h" -#include "dialog/vfindreplacedialog.h" -#include "veditarea.h" -#include "vconstants.h" - -extern VConfigManager *g_config; - -VHtmlTab::VHtmlTab(VFile *p_file, VEditArea *p_editArea, - OpenFileMode p_mode, QWidget *p_parent) - : VEditTab(p_file, p_editArea, p_parent) -{ - V_ASSERT(m_file->getDocType() == DocType::Html); - - m_file->open(); - - setupUI(); - - if (p_mode == OpenFileMode::Edit) { - showFileEditMode(); - } else { - showFileReadMode(); - } -} - -void VHtmlTab::setupUI() -{ - m_editor = new VEdit(m_file, this); - connect(m_editor, &VEdit::textChanged, - this, &VHtmlTab::updateStatus); - connect(m_editor, &VEdit::saveAndRead, - this, &VHtmlTab::saveAndRead); - connect(m_editor, &VEdit::discardAndRead, - this, &VHtmlTab::discardAndRead); - connect(m_editor, &VEdit::editNote, - this, &VHtmlTab::editFile); - connect(m_editor, &VEdit::statusMessage, - this, &VEditTab::statusMessage); - connect(m_editor, &VEdit::vimStatusUpdated, - this, &VEditTab::vimStatusUpdated); - - m_editor->reloadFile(); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_editor); - mainLayout->setContentsMargins(0, 0, 0, 0); - setLayout(mainLayout); -} - -void VHtmlTab::showFileReadMode() -{ - m_isEditMode = false; - - m_editor->setReadOnly(true); - - updateStatus(); -} - -void VHtmlTab::showFileEditMode() -{ - m_isEditMode = true; - - m_editor->beginEdit(); - m_editor->setFocus(); - - updateStatus(); -} - -bool VHtmlTab::closeFile(bool p_forced) -{ - if (p_forced && m_isEditMode) { - // Discard buffer content - m_editor->reloadFile(); - m_editor->endEdit(); - - showFileReadMode(); - } else { - readFile(); - } - - return !m_isEditMode; -} - -void VHtmlTab::editFile() -{ - if (m_isEditMode) { - return; - } - - showFileEditMode(); -} - -void VHtmlTab::readFile(bool p_discard) -{ - if (!m_isEditMode) { - return; - } - - if (m_editor && isModified()) { - // Prompt to save the changes. - bool modifiable = m_file->isModifiable(); - int ret = VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Note %2 has been modified.") - .arg(g_config->c_dataTextStyle).arg(m_file->getName()), - tr("Do you want to save your changes?"), - modifiable ? (QMessageBox::Save - | QMessageBox::Discard - | QMessageBox::Cancel) - : (QMessageBox::Discard - | QMessageBox::Cancel), - modifiable ? (p_discard ? QMessageBox::Discard : QMessageBox::Save) - : QMessageBox::Cancel, - this); - switch (ret) { - case QMessageBox::Save: - if (!saveFile()) { - return; - } - - V_FALLTHROUGH; - - case QMessageBox::Discard: - m_editor->reloadFile(); - break; - - case QMessageBox::Cancel: - // Nothing to do if user cancel this action - return; - - default: - Q_ASSERT(false); - return; - } - } - - if (m_editor) { - m_editor->endEdit(); - } - - showFileReadMode(); -} - -bool VHtmlTab::saveFile() -{ - if (!m_isEditMode || !isModified()) { - return true; - } - - QString filePath = m_file->fetchPath(); - - if (!m_file->isModifiable()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Could not modify a read-only note %2.") - .arg(g_config->c_dataTextStyle).arg(filePath), - tr("Please save your changes to other notes manually."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return false; - } - - // Make sure the file already exists. Temporary deal with cases when user delete or move - // a file. - if (!QFileInfo::exists(filePath)) { - qWarning() << filePath << "being written has been removed"; - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), - tr("File %2 being written has been removed.") - .arg(g_config->c_dataTextStyle).arg(filePath), - QMessageBox::Ok, QMessageBox::Ok, this); - return false; - } - - m_editor->saveFile(); - bool ret = m_file->save(); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), - tr("Fail to write to disk when saving a note. Please try it again."), - QMessageBox::Ok, QMessageBox::Ok, this); - m_editor->setModified(true); - } else { - m_fileDiverged = false; - m_checkFileChange = true; - } - - updateStatus(); - - return ret; -} - -bool VHtmlTab::isModified() const -{ - return m_editor->isModified() || m_fileDiverged; -} - -void VHtmlTab::saveAndRead() -{ - saveFile(); - readFile(); -} - -void VHtmlTab::discardAndRead() -{ - readFile(); -} - -void VHtmlTab::insertImage() -{ -} - -void VHtmlTab::findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward) -{ - if (p_peek) { - m_editor->peekText(p_text, p_options); - } else { - m_editor->findText(p_text, p_options, p_forward); - } -} - -void VHtmlTab::findText(const VSearchToken &p_token, - bool p_forward, - bool p_fromStart) -{ - // TODO - Q_UNUSED(p_token); - Q_UNUSED(p_forward); - Q_UNUSED(p_fromStart); - return; -} - -void VHtmlTab::replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) -{ - if (m_isEditMode) { - m_editor->replaceText(p_text, p_options, p_replaceText, p_findNext); - } -} - -void VHtmlTab::replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) -{ - if (m_isEditMode) { - m_editor->replaceTextAll(p_text, p_options, p_replaceText); - } -} - -void VHtmlTab::nextMatch(const QString &p_text, uint p_options, bool p_forward) -{ - findText(p_text, p_options, false, p_forward); -} - -QString VHtmlTab::getSelectedText() const -{ - QTextCursor cursor = m_editor->textCursor(); - return cursor.selectedText(); -} - -void VHtmlTab::clearSearchedWordHighlight() -{ - m_editor->clearSearchedWordHighlight(); -} - -void VHtmlTab::zoom(bool /* p_zoomIn */, qreal /* p_step */) -{ -} - -void VHtmlTab::focusChild() -{ - m_editor->setFocus(); -} - -void VHtmlTab::requestUpdateVimStatus() -{ - m_editor->requestUpdateVimStatus(); -} - -bool VHtmlTab::restoreFromTabInfo(const VEditTabInfo &p_info) -{ - if (p_info.m_editTab != this) { - return false; - } - - return true; -} - -void VHtmlTab::reload() -{ - m_editor->reloadFile(); - updateStatus(); -} diff --git a/src/vhtmltab.h b/src/vhtmltab.h deleted file mode 100644 index ffd90da6..00000000 --- a/src/vhtmltab.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef VHTMLTAB_H -#define VHTMLTAB_H - -#include -#include -#include "vedittab.h" -#include "vconstants.h" - -class VEdit; - -class VHtmlTab : public VEditTab -{ - Q_OBJECT - -public: - VHtmlTab(VFile *p_file, VEditArea *p_editArea, OpenFileMode p_mode, QWidget *p_parent = 0); - - // Close current tab. - // @p_forced: if true, discard the changes. - bool closeFile(bool p_forced) Q_DECL_OVERRIDE; - - // Enter read mode. - // Will prompt user to save the changes. - void readFile(bool p_discard = false) Q_DECL_OVERRIDE; - - // Save file. - bool saveFile() Q_DECL_OVERRIDE; - - bool isModified() const Q_DECL_OVERRIDE; - - void insertImage() Q_DECL_OVERRIDE; - - // Search @p_text in current note. - void findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward = true) Q_DECL_OVERRIDE; - - void findText(const VSearchToken &p_token, - bool p_forward = true, - bool p_fromStart = false) Q_DECL_OVERRIDE; - - // Replace @p_text with @p_replaceText in current note. - void replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) Q_DECL_OVERRIDE; - - void replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) Q_DECL_OVERRIDE; - - void nextMatch(const QString &p_text, uint p_options, bool p_forward) Q_DECL_OVERRIDE; - - QString getSelectedText() const Q_DECL_OVERRIDE; - - void clearSearchedWordHighlight() Q_DECL_OVERRIDE; - - void requestUpdateVimStatus() Q_DECL_OVERRIDE; - - void reload() Q_DECL_OVERRIDE; - -public slots: - // Enter edit mode. - void editFile() Q_DECL_OVERRIDE; - -private slots: - // m_editor requests to save changes and enter read mode. - void saveAndRead(); - - // m_editor requests to discard changes and enter read mode. - void discardAndRead(); - -private: - // Setup UI. - void setupUI(); - - // Show the file content in read mode. - void showFileReadMode(); - - // Show the file content in edit mode. - void showFileEditMode(); - - // Called to zoom in/out content. - void zoom(bool p_zoomIn, qreal p_step = 0.25) Q_DECL_OVERRIDE; - - // Focus the proper child widget. - void focusChild() Q_DECL_OVERRIDE; - - // Restore from @p_fino. - // Return true if succeed. - bool restoreFromTabInfo(const VEditTabInfo &p_info) Q_DECL_OVERRIDE; - - VEdit *m_editor; -}; -#endif // VHTMLTAB_H diff --git a/src/vimagehosting.cpp b/src/vimagehosting.cpp deleted file mode 100644 index 07194cfa..00000000 --- a/src/vimagehosting.cpp +++ /dev/null @@ -1,1616 +0,0 @@ -#include "vimagehosting.h" -#include "utils/vutils.h" -#include "veditor.h" -#include "vfile.h" -#include "utils/vclipboardutils.h" - -extern VConfigManager *g_config; - -VGithubImageHosting::VGithubImageHosting(VFile *p_file, QObject *p_parent) - :QObject(p_parent), - m_file(p_file) -{ - reply = Q_NULLPTR; - imageUploaded = false; -} - -void VGithubImageHosting::handleUploadImageToGithubRequested() -{ - qDebug() << "Start processing the image upload request to GitHub"; - - if(g_config->getGithubPersonalAccessToken().isEmpty() || - g_config->getGithubReposName().isEmpty() || - g_config->getGithubUserName().isEmpty()) - { - qDebug() << "Please configure the GitHub image hosting first!"; - QMessageBox::warning(nullptr, - tr("GitHub Image Hosting"), - tr("Please configure the GitHub image hosting first!")); - return; - } - - authenticateGithubImageHosting(g_config->getGithubPersonalAccessToken()); -} - -void VGithubImageHosting::authenticateGithubImageHosting(QString p_token) -{ - qDebug() << "start the authentication process "; - QApplication::setOverrideCursor(Qt::WaitCursor); - QNetworkRequest request; - QUrl url = QUrl("https://api.github.com"); - QString ptoken = "token " + p_token; - request.setRawHeader("Authorization", ptoken.toLocal8Bit()); - request.setUrl(url); - if(reply != Q_NULLPTR) - { - reply->deleteLater(); - } - reply = manager.get(request); - connect(reply, &QNetworkReply::finished, this, &VGithubImageHosting::githubImageBedAuthFinished); -} - -void VGithubImageHosting::githubImageBedAuthFinished() -{ - switch (reply->error()) { - case QNetworkReply::NoError: - { - QByteArray bytes = reply->readAll(); - - if(bytes.contains("Bad credentials")) - { - qDebug() << "Authentication failed"; - QApplication::restoreOverrideCursor(); // Recovery pointer - QMessageBox::warning(nullptr, tr("GitHub Image Hosting"), tr("Bad credentials! ") + - tr("Please check your GitHub Image Hosting parameters!")); - return; - } - else - { - qDebug() << "Authentication completed"; - - qDebug() << "The current article path is: " << m_file->fetchPath(); - imageBasePath = m_file->fetchBasePath(); - newFileContent = m_file->getContent(); - - QVector images = VUtils::fetchImagesFromMarkdownFile(m_file,ImageLink::LocalRelativeInternal); - QApplication::restoreOverrideCursor(); // Recovery pointer - if(images.size() > 0) - { - proDlg = new QProgressDialog(tr("Uploading images to GitHub..."), - tr("Abort"), - 0, - images.size(), - nullptr); - proDlg->setWindowModality(Qt::WindowModal); - proDlg->setWindowTitle(tr("Uploading Images To Github")); - proDlg->setMinimumDuration(1); - - uploadImageCount = images.size(); - uploadImageCountIndex = uploadImageCount; - for(int i=0;igetName() << " No local images to upload"; - QString info = tr("No local images to upload: %1").arg(m_file->getName()); - QMessageBox::information(nullptr, tr("GitHub Image Hosting"), info); - } - } - break; - } - default: - { - QApplication::restoreOverrideCursor(); // Recovery pointer - qDebug() << "Network error: " << reply->errorString() << " error " << reply->error(); - QString info = tr("Network error: ") + reply->errorString() + tr("\n\nPlease check your network!"); - QMessageBox::warning(nullptr, tr("GitHub Image Hosting"), info); - } - } -} - -void VGithubImageHosting::githubImageBedUploadManager() -{ - uploadImageCountIndex--; - - QString imageToUpload; - QMapIterator it(imageUrlMap); - while(it.hasNext()) - { - it.next(); - if(it.value() == "") - { - imageToUpload = it.key(); - proDlg->setValue(uploadImageCount - 1 - uploadImageCountIndex); - proDlg->setLabelText(tr("Uploading image: %1").arg(imageToUpload)); - break; - } - } - - if(imageToUpload == "") - { - qDebug() << "All images have been uploaded"; - githubImageBedReplaceLink(newFileContent, m_file->fetchPath()); - return; - } - - if(g_config->getGithubPersonalAccessToken().isEmpty() || - g_config->getGithubReposName().isEmpty() || - g_config->getGithubUserName().isEmpty()) - { - qDebug() << "Please configure the GitHub image hosting first!"; - QMessageBox::warning(nullptr, tr("GitHub Image Hosting"), tr("Please configure the GitHub image hosting first!")); - imageUrlMap.clear(); - return; - } - - QString path = imageBasePath + QDir::separator(); - path += imageToUpload; - githubImageBedUploadImage(g_config->getGithubUserName(), - g_config->getGithubReposName(), - path, - g_config->getGithubPersonalAccessToken()); -} - -void VGithubImageHosting::githubImageBedUploadImage(const QString &p_username, - const QString &p_repository, - const QString &p_imagePath, - const QString &p_token) -{ - QFileInfo fileInfo(p_imagePath.toLocal8Bit()); - if(!fileInfo.exists()) - { - qDebug() << "The picture does not exist in this path: " << p_imagePath.toLocal8Bit(); - QString info = tr("The picture does not exist in this path: ") + p_imagePath.toLocal8Bit(); - QMessageBox::warning(nullptr, tr("GitHub Image Hosting"), info); - imageUrlMap.clear(); - if(imageUploaded) - { - githubImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - return; - } - - QString fileSuffix = fileInfo.suffix(); // file extension - QString fileName = fileInfo.fileName(); // filename - QString uploadUrl; // Image upload URL - uploadUrl = "https://api.github.com/repos/" + - p_username + - "/" + - p_repository + - "/contents/" + - QString::number(QDateTime::currentDateTime().toTime_t()) + - "_" + - fileName; - if(fileSuffix != QString::fromLocal8Bit("jpg") && - fileSuffix != QString::fromLocal8Bit("png") && - fileSuffix != QString::fromLocal8Bit("gif")) - { - qDebug() << "Unsupported type..."; - QString info = tr("Unsupported type: ") + fileSuffix; - QMessageBox::warning(nullptr, tr("GitHub Image Hosting"), info); - imageUrlMap.clear(); - if(imageUploaded) - { - githubImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - return; - } - - QNetworkRequest request; - QUrl url = QUrl(uploadUrl); - QString ptoken = "token " + p_token; - request.setRawHeader("Authorization", ptoken.toLocal8Bit()); - request.setUrl(url); - if(reply != Q_NULLPTR) - { - reply->deleteLater(); - } - - QString param = githubImageBedGenerateParam(p_imagePath); - QByteArray postData; - postData.append(param); - reply = manager.put(request, postData); - qDebug() << "Start uploading images: " + p_imagePath + " Waiting for upload to complete"; - uploadImageStatus = true; - currentUploadImage = p_imagePath; - connect(reply, &QNetworkReply::finished, this, &VGithubImageHosting::githubImageBedUploadFinished); -} - -void VGithubImageHosting::githubImageBedUploadFinished() -{ - if (proDlg->wasCanceled()) - { - qDebug() << "User stops uploading"; - reply->abort(); // Stop network request - imageUrlMap.clear(); - // The ones that have been uploaded successfully before still need to stay - if(imageUploaded) - { - githubImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - return; - } - - switch (reply->error()) - { - case QNetworkReply::NoError: - { - QByteArray bytes = reply->readAll(); - int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if(httpStatus == 201) - { - qDebug() << "Upload success"; - - QString downloadUrl; - QString imageName; - QJsonDocument doucment = QJsonDocument::fromJson(bytes); - if (!doucment.isNull()) - { - if (doucment.isObject()) - { - QJsonObject object = doucment.object(); - if (object.contains("content")) - { - QJsonValue value = object.value("content"); - if (value.isObject()) - { - QJsonObject obj = value.toObject(); - if (obj.contains("download_url")) - { - QJsonValue value = obj.value("download_url"); - if (value.isString()) - { - downloadUrl = value.toString(); - qDebug() << "JSON decode: download_url : " << downloadUrl; - imageUploaded = true; // On behalf of successfully uploaded images - proDlg->setValue(uploadImageCount); - } - } - if(obj.contains("name")) - { - QJsonValue value = obj.value("name"); - if(value.isString()) - { - imageName = value.toString(); - } - } - - // Traverse key in imageurlmap - QList klist = imageUrlMap.keys(); - QString temp; - for(int i=0;ifetchPath()); - } - QString info = tr("JSON decode error. Please contact the developer."); - QMessageBox::warning(nullptr, tr("GitHub Image Hosting"), info); - } - } - else - { - // If status is not 201, it means there is a problem. - delete proDlg; - imageUrlMap.clear(); - qDebug() << "Upload failure"; - if(imageUploaded) - { - githubImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - QString info = tr("GitHub status code != 201. Please contact the developer."); - QMessageBox::warning(nullptr, tr("GitHub Image Hosting"), info); - } - break; - } - default: - { - delete proDlg; - imageUrlMap.clear(); - qDebug()<<"network error: " << reply->errorString() << " error " << reply->error(); - QByteArray bytes = reply->readAll(); - qDebug() << bytes; - int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - qDebug() << "status: " << httpStatus; - - if(imageUploaded) - { - githubImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - QString info = tr("Uploading ") + - currentUploadImage + - tr(" \n\nNetwork error: ") + - reply->errorString() + - tr("\n\nPlease check the network or image size"); - QMessageBox::warning(nullptr, tr("GitHub Image Hosting"), info); - } - } -} - -void VGithubImageHosting::githubImageBedReplaceLink(QString p_fileContent, const QString p_filePath) -{ - Q_UNUSED(p_filePath); - - // This function must be executed when the upload is completed or fails in the middle. - if(!g_config->getGithubKeepImgScale()) - { - // delete image scale - p_fileContent.replace(QRegExp("\\s+=\\d+x"),""); - } - - if(!g_config->getGithubDoNotReplaceLink()) { - // Write content to file. - m_editor->setContent(p_fileContent, true); - } else { - VClipboardUtils::setTextToClipboard(QApplication::clipboard(), p_fileContent); - emit m_editor->object()->statusMessage(tr("Copied contents with new image links")); - } - - // Reset. - imageUrlMap.clear(); - imageUploaded = false; -} - -QString VGithubImageHosting::githubImageBedGenerateParam(const QString p_imagePath) -{ - // According to the requirements of GitHub interface, pictures must be in Base64 format. - // Image to base64. - QByteArray hexed; - QFile imgFile(p_imagePath); - imgFile.open(QIODevice::ReadOnly); - hexed = imgFile.readAll().toBase64(); - - QString imgBase64 = hexed; - QJsonObject json; - json.insert("message", QString("updatetest")); - json.insert("content", imgBase64); - - QJsonDocument document; - document.setObject(json); - QByteArray byteArray = document.toJson(QJsonDocument::Compact); - QString jsonStr(byteArray); - return jsonStr; -} - -void VGithubImageHosting::setEditor(VEditor *p_editor) -{ - m_editor = p_editor; -} - -VGiteeImageHosting::VGiteeImageHosting(VFile *p_file, QObject *p_parent) - :QObject(p_parent), - m_file(p_file) -{ - reply = Q_NULLPTR; - imageUploaded = false; -} - -void VGiteeImageHosting::handleUploadImageToGiteeRequested() -{ - qDebug() << "Start processing the image upload request to Gitee"; - - if(g_config->getGiteePersonalAccessToken().isEmpty() || - g_config->getGiteeReposName().isEmpty() || - g_config->getGiteeUserName().isEmpty()) - { - qDebug() << "Please configure the Gitee image hosting first!"; - QMessageBox::warning(nullptr, - tr("Gitee Image Hosting"), - tr("Please configure the Gitee image hosting first!")); - return; - } - - authenticateGiteeImageHosting(g_config->getGiteeUserName(), - g_config->getGiteeReposName(), - g_config->getGiteePersonalAccessToken()); -} - -void VGiteeImageHosting::authenticateGiteeImageHosting(const QString &p_username, - const QString &p_repository, - const QString &p_token) -{ - qDebug() << "start the authentication process "; - QApplication::setOverrideCursor(Qt::WaitCursor); - QNetworkRequest request; - QString url = "https://gitee.com/api/v5/repos/"; - url += p_username + "/"; - url += p_repository + "/branches/master?access_token="; - url += p_token; - qDebug() << "gitee url: " << url; - QUrl qurl = QUrl(url); - request.setUrl(qurl); - if(reply != Q_NULLPTR) - { - reply->deleteLater(); - } - reply = manager.get(request); - connect(reply, &QNetworkReply::finished, this, &VGiteeImageHosting::giteeImageBedAuthFinished); -} - -void VGiteeImageHosting::giteeImageBedAuthFinished() -{ - switch (reply->error()) - { - case QNetworkReply::NoError: - { - QByteArray bytes = reply->readAll(); - - qDebug() << "Authentication completed"; - - qDebug() << "The current article path is: " << m_file->fetchPath(); - imageBasePath = m_file->fetchBasePath(); - newFileContent = m_file->getContent(); - - QVector images = VUtils::fetchImagesFromMarkdownFile(m_file, ImageLink::LocalRelativeInternal); - QApplication::restoreOverrideCursor(); // Recovery pointer - if(images.size() > 0) - { - proDlg = new QProgressDialog(tr("Uploading images to Gitee..."), - tr("Abort"), - 0, - images.size(), - nullptr); - proDlg->setWindowModality(Qt::WindowModal); - proDlg->setWindowTitle(tr("Uploading Images To Gitee")); - proDlg->setMinimumDuration(1); - - uploadImageCount = images.size(); - uploadImageCountIndex = uploadImageCount; - for(int i=0;igetName() << " No images to upload"; - QString info = tr("No local images to upload: %1").arg(m_file->getName()); - QMessageBox::information(nullptr, tr("Gitee Image Hosting"), info); - } - break; - } - default: - { - QApplication::restoreOverrideCursor(); // Recovery pointer - int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if(httpStatus == 401 || httpStatus == 404) - { - qDebug() << "Authentication failed: " << reply->errorString() << " error " << reply->error(); - QString info = tr("Authentication failed: ") + - reply->errorString() + - tr("\n\nPlease check your Gitee Image Hosting parameters!"); - QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info); - } - else - { - qDebug() << "Network error: " << reply->errorString() << " error " << reply->error(); - QString info = tr("Network error: ") + reply->errorString() + tr("\n\nPlease check your network!"); - QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info); - } - } - } -} - -void VGiteeImageHosting::giteeImageBedUploadManager() -{ - uploadImageCountIndex--; - - QString imageToUpload; - QMapIterator it(imageUrlMap); - while(it.hasNext()) - { - it.next(); - if(it.value() == "") - { - imageToUpload = it.key(); - proDlg->setValue(uploadImageCount - 1 - uploadImageCountIndex); - proDlg->setLabelText(tr("Uploading image: %1").arg(imageToUpload)); - break; - } - } - - if(imageToUpload == "") - { - qDebug() << "All images have been uploaded"; - giteeImageBedReplaceLink(newFileContent, m_file->fetchPath()); - return; - } - - if(g_config->getGiteePersonalAccessToken().isEmpty() || - g_config->getGiteeReposName().isEmpty() || - g_config->getGiteeUserName().isEmpty()) - { - qDebug() << "Please configure the Gitee image hosting first!"; - QMessageBox::warning(nullptr, - tr("Gitee Image Hosting"), - tr("Please configure the Gitee image hosting first!")); - imageUrlMap.clear(); - return; - } - - QString path = imageBasePath + QDir::separator(); - path += imageToUpload; - giteeImageBedUploadImage(g_config->getGiteeUserName(), - g_config->getGiteeReposName(), - path, - g_config->getGiteePersonalAccessToken()); -} - -void VGiteeImageHosting::giteeImageBedUploadImage(const QString &p_username, - const QString &p_repository, - const QString &p_imagePath, - const QString &p_token) -{ - QFileInfo fileInfo(p_imagePath.toLocal8Bit()); - if(!fileInfo.exists()) - { - qDebug() << "The picture does not exist in this path: " << p_imagePath.toLocal8Bit(); - QString info = tr("The picture does not exist in this path: ") + p_imagePath.toLocal8Bit(); - QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info); - imageUrlMap.clear(); - if(imageUploaded) - { - giteeImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - return; - } - - QString fileSuffix = fileInfo.suffix(); // file extension - QString fileName = fileInfo.fileName(); // filename - QString uploadUrl; // Image upload URL - uploadUrl = "https://gitee.com/api/v5/repos/" + - p_username + - "/" + - p_repository + - "/contents/" + - QString::number(QDateTime::currentDateTime().toTime_t()) + - "_" + - fileName; - if(fileSuffix != QString::fromLocal8Bit("jpg") && - fileSuffix != QString::fromLocal8Bit("png") && - fileSuffix != QString::fromLocal8Bit("gif")) - { - qDebug() << "Unsupported type..."; - QString info = tr("Unsupported type: ") + fileSuffix; - QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info); - imageUrlMap.clear(); - if(imageUploaded) - { - giteeImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - return; - } - - QNetworkRequest request; - QUrl url = QUrl(uploadUrl); - request.setUrl(url); - request.setRawHeader("Content-Type", "application/json;charset=UTF-8"); - if(reply != Q_NULLPTR) - { - reply->deleteLater(); - } - - QString param = giteeImageBedGenerateParam(p_imagePath, p_token); - QByteArray postData; - postData.append(param); - reply = manager.post(request, postData); - qDebug() << "Start uploading images: " + p_imagePath + " Waiting for upload to complete"; - uploadImageStatus = true; - currentUploadImage = p_imagePath; - connect(reply, &QNetworkReply::finished, this, &VGiteeImageHosting::giteeImageBedUploadFinished); -} - -void VGiteeImageHosting::giteeImageBedUploadFinished() -{ - if (proDlg->wasCanceled()) - { - qDebug() << "User stops uploading"; - reply->abort(); // Stop network request - imageUrlMap.clear(); - // The ones that have been uploaded successfully before still need to stay - if(imageUploaded) - { - giteeImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - return; - } - - switch (reply->error()) - { - case QNetworkReply::NoError: - { - QByteArray bytes = reply->readAll(); - int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if(httpStatus == 201) - { - qDebug() << "Upload success"; - - QString downloadUrl; - QString imageName; - QJsonDocument doucment = QJsonDocument::fromJson(bytes); - if (!doucment.isNull()) - { - if (doucment.isObject()) - { - QJsonObject object = doucment.object(); - if (object.contains("content")) - { - QJsonValue value = object.value("content"); - if (value.isObject()) { - QJsonObject obj = value.toObject(); - if (obj.contains("download_url")) - { - QJsonValue value = obj.value("download_url"); - if (value.isString()) - { - downloadUrl = value.toString(); - qDebug() << "json decode: download_url : " << downloadUrl; - imageUploaded = true; // On behalf of successfully uploaded images - proDlg->setValue(uploadImageCount); - } - } - if(obj.contains("name")) - { - QJsonValue value = obj.value("name"); - if(value.isString()) - { - imageName = value.toString(); - } - } - - // Traverse key in imageurlmap - QList klist = imageUrlMap.keys(); - QString temp; - for(int i=0;ifetchPath()); - } - QString info = tr("JSON decode error. Please contact the developer."); - QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info); - } - }else{ - // If status is not 201, it means there is a problem. - delete proDlg; - imageUrlMap.clear(); - qDebug() << "Upload failure"; - if(imageUploaded) - { - giteeImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - QString info = tr("Gitee status code != 201. Please contact the developer."); - QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info); - } - break; - } - default: - { - delete proDlg; - imageUrlMap.clear(); - qDebug()<<"network error: " << reply->errorString() << " error " << reply->error(); - QByteArray bytes = reply->readAll(); - qDebug() << bytes; - int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - qDebug() << "status: " << httpStatus; - - if(imageUploaded) - { - giteeImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - QString info = tr("Uploading ") + - currentUploadImage + - tr(" \n\nNetwork error: ") + - reply->errorString() + - tr("\n\nPlease check the network or image size"); - QMessageBox::warning(nullptr, tr("Gitee Image Hosting"), info); - } - } -} - -void VGiteeImageHosting::giteeImageBedReplaceLink(QString p_fileContent, const QString p_filePath) -{ - Q_UNUSED(p_filePath); - - // This function must be executed when the upload is completed or fails in the middle. - if(!g_config->getGiteeKeepImgScale()) - { - // delete image scale - p_fileContent.replace(QRegExp("\\s+=\\d+x"),""); - } - - if(!g_config->getGiteeDoNotReplaceLink()) - { - // Write content to file. - m_editor->setContent(p_fileContent, true); - } else { - VClipboardUtils::setTextToClipboard(QApplication::clipboard(), p_fileContent); - emit m_editor->object()->statusMessage(tr("Copied contents with new image links")); - } - - // Reset. - imageUrlMap.clear(); - imageUploaded = false; -} - -QString VGiteeImageHosting::giteeImageBedGenerateParam(const QString &p_imagePath, const QString &p_token) -{ - // According to the requirements of GitHub interface, pictures must be in Base64 format. - // Image to base64. - QByteArray hexed; - QFile imgFile(p_imagePath); - imgFile.open(QIODevice::ReadOnly); - hexed = imgFile.readAll().toBase64(); - - QString imgBase64 = hexed; - QJsonObject json; - json.insert("access_token", p_token); - json.insert("message", QString("updatetest")); - json.insert("content", imgBase64); - - QJsonDocument document; - document.setObject(json); - QByteArray byteArray = document.toJson(QJsonDocument::Compact); - QString jsonStr(byteArray); - return jsonStr; -} - -void VGiteeImageHosting::setEditor(VEditor *p_editor) -{ - m_editor = p_editor; -} - -VWechatImageHosting::VWechatImageHosting(VFile *p_file, QObject *p_parent) - :QObject(p_parent), - m_file(p_file) -{ - reply = Q_NULLPTR; - imageUploaded = false; -} - -void VWechatImageHosting::handleUploadImageToWechatRequested() -{ - qDebug() << "Start processing image upload request to Wechat"; - QString appid = g_config->getWechatAppid(); - QString secret = g_config->getWechatSecret(); - if(appid.isEmpty() || secret.isEmpty()) - { - qDebug() << "Please configure the Wechat image hosting first!"; - QMessageBox::warning(nullptr, - tr("Wechat Image Hosting"), - tr("Please configure the Wechat image hosting first!")); - return; - } - - authenticateWechatImageHosting(appid, secret); -} - -void VWechatImageHosting::authenticateWechatImageHosting(const QString p_appid, const QString p_secret) -{ - qDebug() << "Start certification"; - // Set the mouse to wait - QApplication::setOverrideCursor(Qt::WaitCursor); - QNetworkRequest request; - QString auth_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + - p_appid.toLocal8Bit() + - "&secret=" + - p_secret.toLocal8Bit(); - QUrl url = QUrl(auth_url); - request.setUrl(url); - if(reply != Q_NULLPTR) - { - reply->deleteLater(); - } - reply = manager.get(request); - connect(reply, &QNetworkReply::finished, this, &VWechatImageHosting::wechatImageBedAuthFinished); -} - -void VWechatImageHosting::wechatImageBedAuthFinished() -{ - switch (reply->error()) - { - case QNetworkReply::NoError: - { - QByteArray bytes = reply->readAll(); - QJsonDocument document = QJsonDocument::fromJson(bytes); - if(!document.isNull()) - { - if(document.isObject()){ - QJsonObject object = document.object(); - if(object.contains("access_token")) - { - QJsonValue value = object.value("access_token"); - if(value.isString()) - { - qDebug() << "Authentication successful, get token"; - // Parsing token. - wechatAccessToken = value.toString(); - - qDebug() << "The current article path is: " << m_file->fetchPath(); - imageBasePath = m_file->fetchBasePath(); - newFileContent = m_file->getContent(); - - QVector images = VUtils::fetchImagesFromMarkdownFile(m_file,ImageLink::LocalRelativeInternal); - QApplication::restoreOverrideCursor(); // Recovery pointer - if(images.size() > 0) - { - proDlg = new QProgressDialog(tr("Uploading images to Wechat..."), - tr("Abort"), - 0, - images.size(), - nullptr); - proDlg->setWindowModality(Qt::WindowModal); - proDlg->setWindowTitle(tr("Uploading Images To Wechat")); - proDlg->setMinimumDuration(1); - uploadImageCount = images.size(); - uploadImageCountIndex = uploadImageCount; - for(int i=0;igetName() << " No pictures to upload"; - QString info = tr("No local images to upload: %1").arg(m_file->getName()); - QMessageBox::information(nullptr, tr("Wechat Image Hosting"), info); - } - } - } - else - { - qDebug() << "Authentication failed"; - QString string = bytes; - qDebug() << string; - // You can refine the error here. - QApplication::restoreOverrideCursor(); - if(string.contains("invalid ip")) - { - QString ip = string.split(" ")[2]; - QClipboard *board = QApplication::clipboard(); - board->setText(ip); - QMessageBox::warning(nullptr, - tr("Wechat Image Hosting"), - tr("Your ip address was set to the Clipboard!") + - tr("\nPlease add the IP address: ") + - ip + - tr(" to the Wechat ip whitelist!")); - } - else - { - QMessageBox::warning(nullptr, - tr("Wechat Image Hosting"), - tr("Please check your Wechat Image Hosting parameters!\n") + - string); - } - return; - } - } - } - else - { - delete proDlg; - imageUrlMap.clear(); - qDebug() << "Resolution failure!"; - qDebug() << "Resolution failure's json: " << bytes; - QString info = tr("JSON decode error. Please contact the developer."); - QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info); - } - - break; - } - default: - { - QApplication::restoreOverrideCursor(); - qDebug() << "Network error: " << reply->errorString() << " error " << reply->error(); - QString info = tr("Network error: ") + reply->errorString() + tr("\n\nPlease check your network!"); - QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info); - } - } -} - -void VWechatImageHosting::wechatImageBedUploadManager() -{ - uploadImageCountIndex--; - - QString image_to_upload = ""; - QMapIterator it(imageUrlMap); - while(it.hasNext()) - { - it.next(); - if(it.value() == "") - { - image_to_upload = it.key(); - proDlg->setValue(uploadImageCount - 1 - uploadImageCountIndex); - proDlg->setLabelText(tr("Uploading image: %1").arg(image_to_upload)); - break; - } - } - - if(image_to_upload == "") - { - qDebug() << "All pictures have been uploaded"; - // Copy content to clipboard. - wechatImageBedReplaceLink(newFileContent, m_file->fetchPath()); - return; - } - - QString path = imageBasePath + QDir::separator(); - path += image_to_upload; - currentUploadRelativeImagePah = image_to_upload; - wechatImageBedUploadImage(path, wechatAccessToken); -} - -void VWechatImageHosting::wechatImageBedUploadImage(const QString p_imagePath, const QString p_token) -{ - qDebug() << "To deal with: " << p_imagePath; - QFileInfo fileInfo(p_imagePath.toLocal8Bit()); - if(!fileInfo.exists()) - { - delete proDlg; - imageUrlMap.clear(); - qDebug() << "The picture does not exist in this path: " << p_imagePath.toLocal8Bit(); - QString info = tr("The picture does not exist in this path: ") + p_imagePath.toLocal8Bit(); - QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info); - return; - } - - QString file_suffix = fileInfo.suffix(); // File extension. - QString file_name = fileInfo.fileName(); // Filename. - if(file_suffix != QString::fromLocal8Bit("jpg") && file_suffix != QString::fromLocal8Bit("png")) - { - delete proDlg; - imageUrlMap.clear(); - qDebug() << "Unsupported type..."; - QString info = tr("Unsupported type: ") + file_suffix; - QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info); - return; - } - - qint64 file_size = fileInfo.size(); // Unit is byte. - qDebug() << "Image size: " << file_size; - if(file_size > 1024*1024) - { - delete proDlg; - imageUrlMap.clear(); - qDebug() << "The size of the picture is more than 1M"; - QString info = tr("The size of the picture is more than 1M! Wechat API does not support!"); - QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info); - return; - } - - QString upload_img_url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=" + p_token; - - QNetworkRequest request; - request.setUrl(upload_img_url); - if(reply != Q_NULLPTR) - { - reply->deleteLater(); - } - - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - QHttpPart imagePart; - imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png")); - QString filename = p_imagePath.split(QDir::separator()).last(); - QString contentVariant = QString("form-data; name=\"media\"; filename=\"%1\";").arg(filename); - imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(contentVariant)); - QFile *file = new QFile(p_imagePath); - if(!file->open(QIODevice::ReadOnly)) - { - qDebug() << "File open failed"; - } - imagePart.setBodyDevice(file); - file->setParent(multiPart); - multiPart->append(imagePart); - - // Set boundary - // Because boundary is quoted by QNetworkAccessManager, the wechat api is not recognized... - QByteArray m_boundary; - m_boundary.append("multipart/form-data; boundary="); - m_boundary.append(multiPart->boundary()); - request.setRawHeader(QByteArray("Content-Type"), m_boundary); - - reply = manager.post(request, multiPart); - multiPart->setParent(reply); - - qDebug() << "Start uploading images: " + p_imagePath + " Waiting for upload to complete"; - uploadImageStatus=true; - currentUploadImage = p_imagePath; - connect(reply, &QNetworkReply::finished, this, &VWechatImageHosting::wechatImageBedUploadFinished); -} - -void VWechatImageHosting::wechatImageBedUploadFinished() -{ - if(proDlg->wasCanceled()) - { - qDebug() << "User stops uploading"; - reply->abort(); - // If the upload was successful, don't use it!!! - imageUrlMap.clear(); - return; - } - - switch (reply->error()) - { - case QNetworkReply::NoError: - { - QByteArray bytes = reply->readAll(); - - QJsonDocument document = QJsonDocument::fromJson(bytes); - if(!document.isNull()) - { - if(document.isObject()) - { - QJsonObject object = document.object(); - if(object.contains("url")) - { - QJsonValue value = object.value("url"); - if(value.isString()) - { - qDebug() << "Authentication successful, get online link"; - imageUploaded = true; - proDlg->setValue(uploadImageCount); - - imageUrlMap.insert(currentUploadRelativeImagePah, value.toString()); - newFileContent.replace(currentUploadRelativeImagePah, value.toString()); - // Start calling the method. - // Whether the value in the map is empty determines whether to stop - wechatImageBedUploadManager(); - } - } - else - { - delete proDlg; - imageUrlMap.clear(); - qDebug() << "Upload failure: "; - QString error = bytes; - qDebug() << bytes; - QString info = tr("Upload failed! Please contact the developer."); - QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info); - } - } - } - else - { - delete proDlg; - imageUrlMap.clear(); - qDebug() << "Resolution failure!"; - qDebug() << "Resolution failure's json: " << bytes; - QString info = tr("JSON decode error. Please contact the developer."); - QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info); - } - - break; - } - default: - { - delete proDlg; - qDebug()<<"Network error: " << reply->errorString() << " error " << reply->error(); - - QString info = tr("Uploading ") + - currentUploadImage + - tr(" \n\nNetwork error: ") + - reply->errorString() + - tr("\n\nPlease check the network or image size"); - QMessageBox::warning(nullptr, tr("Wechat Image Hosting"), info); - } - } -} - -void VWechatImageHosting::wechatImageBedReplaceLink(QString &p_fileContent, const QString &p_filePath) -{ - Q_UNUSED(p_filePath); - - if(!g_config->getWechatKeepImgScale()) - { - // delete image scale - p_fileContent.replace(QRegExp("\\s+=\\d+x"),""); - } - - if(!g_config->getWechatDoNotReplaceLink()) - { - // Write content to file. - m_editor->setContent(p_fileContent, true); - } - - VClipboardUtils::setTextToClipboard(QApplication::clipboard(), p_fileContent); - emit m_editor->object()->statusMessage(tr("Copied contents with new image links")); - - QString url = g_config->getMarkdown2WechatToolUrl(); - if(!url.isEmpty()) { - QMessageBox::StandardButton result; - result = QMessageBox::question(nullptr, - tr("Wechat Image Hosting"), - tr("Contents with new image links are copied. ") + - tr("Do you want to open the link of Markdown2Wechat tool?"), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::Yes); - if(result == QMessageBox::Yes) - { - QDesktopServices::openUrl(QUrl(url)); - } - } - - // Reset. - imageUrlMap.clear(); - imageUploaded = false; -} - -void VWechatImageHosting::setEditor(VEditor *p_editor) -{ - m_editor = p_editor; -} - -VTencentImageHosting::VTencentImageHosting(VFile *p_file, QObject *p_parent) - :QObject(p_parent), - m_file(p_file) -{ - reply = Q_NULLPTR; - imageUploaded = false; -} - -void VTencentImageHosting::handleUploadImageToTencentRequested() -{ - qDebug() << "Start processing the image upload request to Tencent Cloud"; - - if(g_config->getTencentAccessDomainName().isEmpty() || - g_config->getTencentSecretId().isEmpty() || - g_config->getTencentSecretKey().isEmpty()) - { - qDebug() << "Please configure the Tencent Cloud image hosting first!"; - QMessageBox::warning(nullptr, - tr("Tencent Cloud Image Hosting"), - tr("Please configure the Tencent Cloud image hosting first!")); - return; - } - - findAndStartUploadImage(); -} - -void VTencentImageHosting::findAndStartUploadImage() -{ - qDebug() << "The current article path is: " << m_file->fetchPath(); - imageBasePath = m_file->fetchBasePath(); - newFileContent = m_file->getContent(); - - QVector images = VUtils::fetchImagesFromMarkdownFile(m_file,ImageLink::LocalRelativeInternal); - if(images.size() > 0) - { - proDlg = new QProgressDialog(tr("Uploading images to Tencent Cloud..."), - tr("Abort"), - 0, - images.size(), - nullptr); - proDlg->setWindowModality(Qt::WindowModal); - proDlg->setWindowTitle(tr("Uploading Images To Tencent Cloud")); - proDlg->setMinimumDuration(1); - - uploadImageCount = images.size(); - uploadImageCountIndex = uploadImageCount; - for(int i=0;igetName() << " No images to upload"; - QString info = tr("No local images to upload: %1").arg(m_file->getName()); - QMessageBox::information(nullptr, tr("Tencent Cloud Image Hosting"), info); - } -} - -void VTencentImageHosting::tencentImageBedUploadManager() -{ - uploadImageCountIndex--; - - QString image_to_upload = ""; - QMapIterator it(imageUrlMap); - while(it.hasNext()) - { - it.next(); - if(it.value() == "") - { - image_to_upload = it.key(); - proDlg->setValue(uploadImageCount - 1 - uploadImageCountIndex); - proDlg->setLabelText(tr("Uploading image: %1").arg(image_to_upload)); - break; - } - } - - if(image_to_upload == "") - { - qDebug() << "All pictures have been uploaded"; - tencentImageBedReplaceLink(newFileContent, m_file->fetchPath()); - return; - } - - QString path = imageBasePath + QDir::separator(); - path += image_to_upload; - currentUploadRelativeImagePah = image_to_upload; - tencentImageBedUploadImage(path, - g_config->getTencentAccessDomainName(), - g_config->getTencentSecretId(), - g_config->getTencentSecretKey()); -} - -void VTencentImageHosting::tencentImageBedUploadImage(const QString &p_imagePath, - const QString &p_accessDomainName, - const QString &p_secretId, - const QString &p_secretKey) -{ - QFileInfo fileInfo(p_imagePath.toLocal8Bit()); - if(!fileInfo.exists()) - { - qDebug() << "The picture does not exist in this path: " << p_imagePath.toLocal8Bit(); - QString info = tr("The picture does not exist in this path: ") + p_imagePath.toLocal8Bit(); - QMessageBox::warning(nullptr, tr("Tencent Cloud Image Hosting"), info); - imageUrlMap.clear(); - if(imageUploaded) - { - tencentImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - return; - } - - QString fileSuffix = fileInfo.suffix(); // file extension - QString fileName = fileInfo.fileName(); // filename - QString uploadUrl; // Image upload URL - new_file_name = QString::number(QDateTime::currentDateTime().toTime_t()) +"_" + fileName; - - if(fileSuffix != QString::fromLocal8Bit("jpg") && fileSuffix != QString::fromLocal8Bit("png")) - { - qDebug() << "Unsupported type..."; - QString info = tr("Unsupported type: ") + fileSuffix; - QMessageBox::warning(nullptr, tr("Tencent Cloud Image Hosting"), info); - imageUrlMap.clear(); - if(imageUploaded) - { - tencentImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - return; - } - - QByteArray postData = getImgContent(p_imagePath); - QNetworkRequest request; - uploadUrl = "https://" + p_accessDomainName + "/" + new_file_name; - request.setRawHeader(QByteArray("Host"), p_accessDomainName.toUtf8()); - if(fileSuffix == QString::fromLocal8Bit("jpg")) - { - request.setHeader(QNetworkRequest::ContentTypeHeader, "image/jpeg"); - } - else if(fileSuffix == QString::fromLocal8Bit("png")) - { - request.setHeader(QNetworkRequest::ContentTypeHeader, "image/png"); - } - - request.setHeader(QNetworkRequest::ContentLengthHeader, postData.size()); - QString str = getAuthorizationString(p_secretId, p_secretKey, new_file_name); - request.setRawHeader(QByteArray("Authorization"), str.toUtf8()); - request.setRawHeader(QByteArray("Connection"), QByteArray("close")); - - request.setUrl(QUrl(uploadUrl)); - if(reply != Q_NULLPTR) - { - reply->deleteLater(); - } - - reply = manager.put(request, postData); - - qDebug() << "Start uploading images: " + p_imagePath + " Waiting for upload to complete"; - uploadImageStatus = true; - currentUploadImage = p_imagePath; - connect(reply, &QNetworkReply::finished, this, &VTencentImageHosting::tencentImageBedUploadFinished); -} - -void VTencentImageHosting::tencentImageBedUploadFinished() -{ - if(proDlg->wasCanceled()) - { - qDebug() << "User stops uploading"; - reply->abort(); // Stop network request - imageUrlMap.clear(); - // The ones that have been uploaded successfully before still need to stay - if(imageUploaded) - { - tencentImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - return; - } - - switch (reply->error()) - { - case QNetworkReply::NoError: - { - QByteArray bytes = reply->readAll(); - QString replyContent = bytes; - if(replyContent.size() > 0) - { - // If there is a value returned, it means there is a problem. - qDebug() << "Upload failure"; - qDebug() << replyContent; - delete proDlg; - imageUrlMap.clear(); - if(imageUploaded) - { - tencentImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - QMessageBox::warning(nullptr, tr("Tencent Cloud Image Hosting"), replyContent); - } - else - { - qDebug() << "Upload success"; - imageUploaded = true; // On behalf of successfully uploaded images - proDlg->setValue(uploadImageCount); - - QString downloadUrl = "https://" + - g_config->getTencentAccessDomainName() + - "/" + - new_file_name; - - imageUrlMap.insert(currentUploadRelativeImagePah, downloadUrl); - newFileContent.replace(currentUploadRelativeImagePah, downloadUrl); - // Start calling the method. - // Whether the value in the map is empty determines whether to stop. - tencentImageBedUploadManager(); - } - break; - } - default: - { - delete proDlg; - imageUrlMap.clear(); - if(imageUploaded) - { - tencentImageBedReplaceLink(newFileContent, m_file->fetchPath()); - } - - qDebug()<<"network error: " << reply->error(); - if(reply->error() == 3) // HostNotFoundError - { - QString info = tr(" \n\nNetwork error: HostNotFoundError") + - tr("\n\nPlease check your network"); - QMessageBox::warning(nullptr, tr("Tencent Cloud Image Hosting"), info); - } - else - { - QByteArray bytes = reply->readAll(); - QString replyContent = bytes; - qDebug() << replyContent; - - QString errorCode; - QString errorMessage; - QRegExp rc("([a-zA-Z0-9 ]+)"); - QRegExp rx("([a-zA-Z0-9 ]+)"); - if(rc.indexIn(replyContent) != -1) - { - qDebug() << "Error Code: " + rc.cap(1); - errorCode = rc.cap(1); - } - if(rx.indexIn(replyContent) != -1) - { - qDebug() << "Error Message: " + rx.cap(1); - errorMessage = rx.cap(1); - } - - QString info = tr("Uploading ") + - currentUploadImage + - "\n\n" + - errorCode + - "\n\n" + - errorMessage; - QMessageBox::warning(nullptr, tr("Tencent Cloud Image Hosting"), info); - } - } - } -} - -void VTencentImageHosting::tencentImageBedReplaceLink(QString &p_fileContent, const QString &p_filePath) -{ - Q_UNUSED(p_filePath); - - if(!g_config->getTencentKeepImgScale()) - { - // delete image scale - p_fileContent.replace(QRegExp("\\s+=\\d+x"),""); - } - - if(!g_config->getTencentDoNotReplaceLink()) - { - // Write content to file. - m_editor->setContent(p_fileContent, true); - } else { - VClipboardUtils::setTextToClipboard(QApplication::clipboard(), p_fileContent); - emit m_editor->object()->statusMessage(tr("Copied contents with new image links")); - } - - // Reset. - imageUrlMap.clear(); - imageUploaded = false; -} - -QByteArray VTencentImageHosting::hmacSha1(const QByteArray &p_key, const QByteArray &p_baseString) -{ - int blockSize = 64; - QByteArray key = p_key; - if (key.length() > blockSize) - { - key = QCryptographicHash::hash(key, QCryptographicHash::Sha1); - } - QByteArray innerPadding(blockSize, char(0x36)); - QByteArray outerPadding(blockSize, char(0x5c)); - - for (int i = 0; i < key.length(); i++) - { - innerPadding[i] = innerPadding[i] ^ key.at(i); - outerPadding[i] = outerPadding[i] ^ key.at(i); - } - QByteArray total = outerPadding; - QByteArray part = innerPadding; - part.append(p_baseString); - - total.append(QCryptographicHash::hash(part, QCryptographicHash::Sha1)); - QByteArray hashed = QCryptographicHash::hash(total, QCryptographicHash::Sha1); - - return hashed.toHex(); -} - -QString VTencentImageHosting::getAuthorizationString(const QString &p_secretId, - const QString &p_secretKey, - const QString &p_imgName) -{ - unsigned int now=QDateTime::currentDateTime().toTime_t(); - QString keyTime=QString::number(now) + ";" + QString::number(now+3600); - QString SignKey=hmacSha1(p_secretKey.toUtf8(), keyTime.toUtf8()); - QString HttpString="put\n/" + p_imgName + "\n\n\n"; - QString StringToSign = "sha1\n" + - keyTime + - "\n" + - QCryptographicHash::hash(HttpString.toUtf8(), QCryptographicHash::Sha1).toHex() + - "\n"; - QString signature=hmacSha1(SignKey.toUtf8(), StringToSign.toUtf8()); - QString Authorization; - Authorization = "q-sign-algorithm=sha1"; - Authorization += "&q-ak="; - Authorization += p_secretId; - Authorization += "&q-sign-time="; - Authorization += keyTime; - Authorization += "&q-key-time="; - Authorization += keyTime; - Authorization += "&q-header-list="; - Authorization += "&q-url-param-list="; - Authorization += "&q-signature="; - Authorization += signature; - return Authorization; -} - -QByteArray VTencentImageHosting::getImgContent(const QString &p_imagePath) -{ - QFile file(p_imagePath); - file.open(QIODevice::ReadOnly); - QByteArray fdata = file.readAll(); - file.close(); - return fdata; -} - -void VTencentImageHosting::setEditor(VEditor *p_editor) -{ - m_editor = p_editor; -} diff --git a/src/vimagehosting.h b/src/vimagehosting.h deleted file mode 100644 index 6ba54d5b..00000000 --- a/src/vimagehosting.h +++ /dev/null @@ -1,267 +0,0 @@ -#ifndef VGITHUBIMAGEHOSTING_H -#define VGITHUBIMAGEHOSTING_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class VEditor; -class VFile; - -class VGithubImageHosting : public QObject -{ - Q_OBJECT -public: - explicit VGithubImageHosting(VFile *p_file, QObject *p_parent = nullptr); - - // GitHub identity authentication. - void authenticateGithubImageHosting(QString p_token); - - // Upload a single image. - void githubImageBedUploadImage(const QString &p_username, - const QString &p_repository, - const QString &p_imagePath, - const QString &p_token); - - // Parameters needed to generate uploaded images. - QString githubImageBedGenerateParam(const QString p_imagePath); - - // Control image to upload. - void githubImageBedUploadManager(); - - // Replace old links with new ones for images. - void githubImageBedReplaceLink(QString p_fileContent, const QString p_filePath); - - // Process the image upload request to GitHub. - void handleUploadImageToGithubRequested(); - - void setEditor(VEditor *p_editor); - -public slots: - // GitHub image hosting identity authentication completed. - void githubImageBedAuthFinished(); - - // GitHub image hosting upload completed. - void githubImageBedUploadFinished(); - -private: - QNetworkAccessManager manager; - QNetworkReply *reply; - QMap imageUrlMap; - // Similar to "_v_image/". - QString imageBasePath; - // Replace the file content with the new link. - QString newFileContent; - // Whether the picture has been uploaded successfully. - bool imageUploaded; - // Image upload progress bar. - QProgressDialog *proDlg; - // Total number of images to upload. - int uploadImageCount; - int uploadImageCountIndex; - // Currently uploaded picture name. - QString currentUploadImage; - // Image upload status. - bool uploadImageStatus; - VFile *m_file; - - VEditor *m_editor = nullptr; -}; - -class VGiteeImageHosting : public QObject -{ - Q_OBJECT -public: - explicit VGiteeImageHosting(VFile *p_file, QObject *p_parent = nullptr); - - // GitHub identity authentication. - void authenticateGiteeImageHosting(const QString &p_username, - const QString &p_repository, - const QString &p_token); - - // Upload a single image. - void giteeImageBedUploadImage(const QString &p_username, - const QString &p_repository, - const QString &p_imagePath, - const QString &p_token); - - // Parameters needed to generate uploaded images. - QString giteeImageBedGenerateParam(const QString &p_imagePath, const QString &p_token); - - // Control image to upload. - void giteeImageBedUploadManager(); - - // Replace old links with new ones for images. - void giteeImageBedReplaceLink(QString p_fileContent, const QString p_filePath); - - // Process the image upload request to Gitee. - void handleUploadImageToGiteeRequested(); - - void setEditor(VEditor *p_editor); - -public slots: - // Gitee image hosting identity authentication completed. - void giteeImageBedAuthFinished(); - - // Gitee image hosting upload completed. - void giteeImageBedUploadFinished(); - -private: - QNetworkAccessManager manager; - QNetworkReply *reply; - QMap imageUrlMap; - // Similar to "_v_image/". - QString imageBasePath; - // Replace the file content with the new link. - QString newFileContent; - // Whether the picture has been uploaded successfully. - bool imageUploaded; - // Image upload progress bar. - QProgressDialog *proDlg; - // Total number of images to upload. - int uploadImageCount; - int uploadImageCountIndex; - // Currently uploaded picture name. - QString currentUploadImage; - // Image upload status. - bool uploadImageStatus; - VFile *m_file; - - VEditor *m_editor = nullptr; -}; - -class VWechatImageHosting : public QObject -{ - Q_OBJECT -public: - explicit VWechatImageHosting(VFile *p_file, QObject *p_parent = nullptr); - - // Wechat identity authentication. - void authenticateWechatImageHosting(const QString p_appid, const QString p_secret); - - // Control image to upload. - void wechatImageBedUploadManager(); - - // Replace old links with new ones for images. - void wechatImageBedReplaceLink(QString &p_fileContent, const QString &p_filePath); - - // Upload a single image. - void wechatImageBedUploadImage(const QString p_imagePath, const QString p_token); - - // Process image upload request to wechat. - void handleUploadImageToWechatRequested(); - - void setEditor(VEditor *p_editor); - -public slots: - // Wechat mage hosting identity authentication completed. - void wechatImageBedAuthFinished(); - - // Wechat image hosting upload completed. - void wechatImageBedUploadFinished(); - -private: - QNetworkAccessManager manager; - QNetworkReply *reply; - QMap imageUrlMap; - // Similar to "_v_image/". - QString imageBasePath; - // Replace the file content with the new link. - QString newFileContent; - // Whether the picture has been uploaded successfully. - bool imageUploaded; - // Image upload progress bar. - QProgressDialog *proDlg; - // Total number of images to upload. - int uploadImageCount; - int uploadImageCountIndex; - // Currently uploaded picture name. - QString currentUploadImage; - // Image upload status - bool uploadImageStatus; - // Token returned after successful wechat authentication. - QString wechatAccessToken; - // Relative image path currently Uploaded. - QString currentUploadRelativeImagePah; - VFile *m_file; - - VEditor *m_editor = nullptr; -}; - -class VTencentImageHosting : public QObject -{ - Q_OBJECT -public: - explicit VTencentImageHosting(VFile *p_file, QObject *p_parent = nullptr); - - QByteArray hmacSha1(const QByteArray &p_key, const QByteArray &p_baseString); - - QString getAuthorizationString(const QString &p_secretId, - const QString &p_secretKey, - const QString &p_imgName); - - void findAndStartUploadImage(); - - QByteArray getImgContent(const QString &p_imagePath); - - // Control image to upload. - void tencentImageBedUploadManager(); - - // Replace old links with new ones for images. - void tencentImageBedReplaceLink(QString &p_fileContent, const QString &p_filePath); - - // Upload a single image. - void tencentImageBedUploadImage(const QString &p_imagePath, - const QString &p_accessDomainName, - const QString &p_secretId, - const QString &p_secretKey); - - // Process image upload request to tencent. - void handleUploadImageToTencentRequested(); - - void setEditor(VEditor *p_editor); - -public slots: - // Tencent image hosting upload completed. - void tencentImageBedUploadFinished(); - -private: - QNetworkAccessManager manager; - QNetworkReply *reply; - QMap imageUrlMap; - // Similar to "_v_image/". - QString imageBasePath; - // Replace the file content with the new link. - QString newFileContent; - // Whether the picture has been uploaded successfully. - bool imageUploaded; - // Image upload progress bar. - QProgressDialog *proDlg; - // Total number of images to upload. - int uploadImageCount; - int uploadImageCountIndex; - // Currently uploaded picture name. - QString currentUploadImage; - // Image upload status - bool uploadImageStatus; - // Token returned after successful wechat authentication. - QString wechatAccessToken; - // Relative image path currently Uploaded. - QString currentUploadRelativeImagePah; - QString new_file_name; - - VFile *m_file; - - VEditor *m_editor = nullptr; -}; -#endif // VGITHUBIMAGEHOSTING_H diff --git a/src/vimageresourcemanager.cpp b/src/vimageresourcemanager.cpp deleted file mode 100644 index b4eeb6f3..00000000 --- a/src/vimageresourcemanager.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "vimageresourcemanager.h" - -#include - -#include "vplaintextedit.h" - - -VImageResourceManager::VImageResourceManager() - : m_maximumImageWidth(0) -{ -} - -void VImageResourceManager::addImage(const QString &p_name, - const QPixmap &p_image) -{ - m_images.insert(p_name, p_image); -} - -bool VImageResourceManager::contains(const QString &p_name) const -{ - return m_images.contains(p_name); -} - -void VImageResourceManager::updateBlockInfos(const QVector &p_blocksInfo, - int p_maximumWidth) -{ - QSet usedImages; - m_blocksInfo.clear(); - m_maximumImageWidth = 0; - - for (auto const & info : p_blocksInfo) { - auto it = m_blocksInfo.insert(info.m_blockNumber, info); - VBlockImageInfo &newInfo = it.value(); - auto imageIt = m_images.find(newInfo.m_imageName); - if (imageIt != m_images.end()) { - // Fill the width and height. - newInfo.m_imageWidth = imageIt.value().width(); - newInfo.m_imageHeight = imageIt.value().height(); - adjustWidthAndHeight(newInfo, p_maximumWidth); - updateMaximumImageWidth(newInfo, p_maximumWidth); - usedImages.insert(newInfo.m_imageName); - } - } - - // Clear unused images. - for (auto it = m_images.begin(); it != m_images.end();) { - if (!usedImages.contains(it.key())) { - // Remove the image. - it = m_images.erase(it); - } else { - ++it; - } - } - - qDebug() << "updateBlockInfos() blocks" << m_blocksInfo.size() - << "images" << m_images.size(); -} - -const VBlockImageInfo *VImageResourceManager::findImageInfoByBlock(int p_blockNumber) const -{ - auto it = m_blocksInfo.find(p_blockNumber); - if (it != m_blocksInfo.end()) { - return &it.value(); - } - - return NULL; -} - -const QPixmap *VImageResourceManager::findImage(const QString &p_name) const -{ - auto it = m_images.find(p_name); - if (it != m_images.end()) { - return &it.value(); - } - - return NULL; -} - -void VImageResourceManager::clear() -{ - m_blocksInfo.clear(); - m_images.clear(); -} - -void VImageResourceManager::updateImageWidth(int p_maximumWidth) -{ - qDebug() << "updateImageWidth()" << p_maximumWidth; - m_maximumImageWidth = 0; - for (auto it = m_blocksInfo.begin(); it != m_blocksInfo.end(); ++it) { - VBlockImageInfo &info = it.value(); - auto imageIt = m_images.find(info.m_imageName); - if (imageIt != m_images.end()) { - info.m_imageWidth = imageIt.value().width(); - info.m_imageHeight = imageIt.value().height(); - adjustWidthAndHeight(info, p_maximumWidth); - updateMaximumImageWidth(info, p_maximumWidth); - } - } -} - -void VImageResourceManager::adjustWidthAndHeight(VBlockImageInfo &p_info, - int p_maximumWidth) -{ - int oriWidth = p_info.m_imageWidth; - int availableWidth = p_maximumWidth - p_info.m_margin; - if (availableWidth < p_info.m_imageWidth) { - if (availableWidth >= VPlainTextEdit::c_minimumImageWidth) { - p_info.m_imageWidth = availableWidth; - } else { - // Omit the margin when displaying this image. - p_info.m_imageWidth = p_maximumWidth; - } - } - - if (oriWidth != p_info.m_imageWidth) { - // Update the height respecting the ratio. - p_info.m_imageHeight = (1.0 * p_info.m_imageWidth / oriWidth) * p_info.m_imageHeight; - } -} - -void VImageResourceManager::updateMaximumImageWidth(const VBlockImageInfo &p_info, - int p_maximumWidth) -{ - int width = p_info.m_imageWidth + p_info.m_margin; - if (width > p_maximumWidth) { - width = p_info.m_imageWidth; - } - - if (width > m_maximumImageWidth) { - m_maximumImageWidth = width; - } -} diff --git a/src/vimageresourcemanager.h b/src/vimageresourcemanager.h deleted file mode 100644 index 517e7717..00000000 --- a/src/vimageresourcemanager.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef VIMAGERESOURCEMANAGER_H -#define VIMAGERESOURCEMANAGER_H - -#include -#include -#include -#include -#include - -struct VBlockImageInfo; - - -class VImageResourceManager -{ -public: - VImageResourceManager(); - - // Add an image to the resource with @p_name as the key. - // If @p_name already exists in the resources, it will update it. - void addImage(const QString &p_name, const QPixmap &p_image); - - // Whether the resources contains image with name @p_name. - bool contains(const QString &p_name) const; - - // Update the block-image info for all blocks. - // @p_maximumWidth: maximum width of the images plus the margin. - void updateBlockInfos(const QVector &p_blocksInfo, - int p_maximumWidth = INT_MAX); - - const VBlockImageInfo *findImageInfoByBlock(int p_blockNumber) const; - - const QPixmap *findImage(const QString &p_name) const; - - void clear(); - - // Update the width of all the block info. - void updateImageWidth(int p_maximumWidth); - - // Get the maximum width of all block images. - int getMaximumImageWidth() const; - -private: - // Adjust the width and height according to @p_maximumWidth and margin. - void adjustWidthAndHeight(VBlockImageInfo &p_info, int p_maximumWidth); - - void updateMaximumImageWidth(const VBlockImageInfo &p_info, int p_maximumWidth); - - // All the images resources. - QHash m_images; - - // Image info of all the blocks with image. - QHash m_blocksInfo; - - // Maximum width of all images from m_blocksInfo. - int m_maximumImageWidth; -}; - -inline int VImageResourceManager::getMaximumImageWidth() const -{ - return m_maximumImageWidth; -} - -#endif // VIMAGERESOURCEMANAGER_H diff --git a/src/vimageresourcemanager2.cpp b/src/vimageresourcemanager2.cpp deleted file mode 100644 index 45e97ff7..00000000 --- a/src/vimageresourcemanager2.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "vimageresourcemanager2.h" - - -VImageResourceManager2::VImageResourceManager2() -{ -} - -void VImageResourceManager2::addImage(const QString &p_name, - const QPixmap &p_image) -{ - m_images.insert(p_name, p_image); -} - -bool VImageResourceManager2::contains(const QString &p_name) const -{ - return m_images.contains(p_name); -} - -const QPixmap *VImageResourceManager2::findImage(const QString &p_name) const -{ - auto it = m_images.find(p_name); - if (it != m_images.end()) { - return &it.value(); - } - - return NULL; -} - -void VImageResourceManager2::clear() -{ - m_images.clear(); -} - -void VImageResourceManager2::removeImage(const QString &p_name) -{ - m_images.remove(p_name); -} diff --git a/src/vimageresourcemanager2.h b/src/vimageresourcemanager2.h deleted file mode 100644 index 61407a96..00000000 --- a/src/vimageresourcemanager2.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef VIMAGERESOURCEMANAGER2_H -#define VIMAGERESOURCEMANAGER2_H - -#include -#include -#include - - -class VImageResourceManager2 -{ -public: - VImageResourceManager2(); - - // Add an image to the resource with @p_name as the key. - // If @p_name already exists in the resources, it will update it. - void addImage(const QString &p_name, const QPixmap &p_image); - - // Remove image @p_name. - void removeImage(const QString &p_name); - - // Whether the resources contains image with name @p_name. - bool contains(const QString &p_name) const; - - const QPixmap *findImage(const QString &p_name) const; - - void clear(); - -private: - // All the images resources. - QHash m_images; -}; - -#endif // VIMAGERESOURCEMANAGER2_H diff --git a/src/vinsertselector.cpp b/src/vinsertselector.cpp deleted file mode 100644 index 53860bf1..00000000 --- a/src/vinsertselector.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "vinsertselector.h" - -#include -#include "utils/vutils.h" - -VSelectorItemWidget::VSelectorItemWidget(QWidget *p_parent) - : QWidget(p_parent) -{ -} - -VSelectorItemWidget::VSelectorItemWidget(const VInsertSelectorItem &p_item, QWidget *p_parent) - : QWidget(p_parent), m_name(p_item.m_name) -{ - QLabel *shortcutLabel = new QLabel(p_item.m_shortcut); - shortcutLabel->setProperty("SelectorItemShortcutLabel", true); - - m_btn = new QPushButton(p_item.m_name); - m_btn->setToolTip(p_item.m_toolTip); - m_btn->setProperty("SelectionBtn", true); - connect(m_btn, &QPushButton::clicked, - this, [this]() { - emit clicked(m_name); - }); - - QHBoxLayout *layout = new QHBoxLayout(); - layout->addWidget(shortcutLabel); - layout->addWidget(m_btn, 1); - layout->setContentsMargins(0, 0, 0, 0); - - setLayout(layout); -} - -VInsertSelector::VInsertSelector(int p_nrRows, - const QVector &p_items, - QWidget *p_parent) - : QWidget(p_parent), - m_items(p_items) -{ - setupUI(p_nrRows < 1 ? 1 : p_nrRows); -} - -void VInsertSelector::setupUI(int p_nrRows) -{ - QGridLayout *layout = new QGridLayout(); - - int row = 0, col = 0; - for (auto const & it : m_items) { - QWidget *wid = createItemWidget(it); - layout->addWidget(wid, row, col); - if (++row == p_nrRows) { - row = 0; - ++col; - } - } - - setLayout(layout); -} - -QWidget *VInsertSelector::createItemWidget(const VInsertSelectorItem &p_item) -{ - VSelectorItemWidget *widget = new VSelectorItemWidget(p_item); - connect(widget, &VSelectorItemWidget::clicked, - this, &VInsertSelector::itemClicked); - - return widget; -} - -void VInsertSelector::itemClicked(const QString &p_name) -{ - m_clickedItemName = p_name; - emit accepted(true); -} - -void VInsertSelector::keyPressEvent(QKeyEvent *p_event) -{ - QWidget::keyPressEvent(p_event); - - if (p_event->key() == Qt::Key_BracketLeft - && VUtils::isControlModifierForVim(p_event->modifiers())) { - m_clickedItemName.clear(); - emit accepted(false); - return; - } - - QChar ch = VUtils::keyToChar(p_event->key()); - if (!ch.isNull()) { - // Activate corresponding item. - const VInsertSelectorItem *item = findItemByShortcut(ch); - if (item) { - itemClicked(item->m_name); - } - } -} - -const VInsertSelectorItem *VInsertSelector::findItemByShortcut(QChar p_shortcut) const -{ - for (auto const & it : m_items) { - if (it.m_shortcut == p_shortcut) { - return ⁢ - } - } - - return NULL; -} - -void VInsertSelector::showEvent(QShowEvent *p_event) -{ - QWidget::showEvent(p_event); - - if (!hasFocus()) { - setFocus(); - } -} - -void VInsertSelector::paintEvent(QPaintEvent *p_event) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - - QWidget::paintEvent(p_event); -} diff --git a/src/vinsertselector.h b/src/vinsertselector.h deleted file mode 100644 index ee04fa36..00000000 --- a/src/vinsertselector.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef VINSERTSELECTOR_H -#define VINSERTSELECTOR_H - -#include -#include - -class QPushButton; -class QKeyEvent; -class QShowEvent; -class QPaintEvent; - -struct VInsertSelectorItem -{ - VInsertSelectorItem() - { - } - - VInsertSelectorItem(const QString &p_name, - const QString &p_toolTip, - QChar p_shortcut = QChar()) - : m_name(p_name), m_toolTip(p_toolTip), m_shortcut(p_shortcut) - { - } - - QString m_name; - - QString m_toolTip; - - QChar m_shortcut; -}; - -class VSelectorItemWidget : public QWidget -{ - Q_OBJECT -public: - explicit VSelectorItemWidget(QWidget *p_parent = nullptr); - - VSelectorItemWidget(const VInsertSelectorItem &p_item, QWidget *p_parent = nullptr); - -signals: - // This item widget is clicked. - void clicked(const QString &p_name); - -private: - QString m_name; - - QPushButton *m_btn; -}; - -class VInsertSelector : public QWidget -{ - Q_OBJECT -public: - explicit VInsertSelector(int p_nrRows, - const QVector &p_items, - QWidget *p_parent = nullptr); - - const QString &getClickedItem() const; - -signals: - void accepted(bool p_accepted = true); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void itemClicked(const QString &p_name); - -private: - void setupUI(int p_nrRows); - - QWidget *createItemWidget(const VInsertSelectorItem &p_item); - - const VInsertSelectorItem *findItemByShortcut(QChar p_shortcut) const; - - QVector m_items; - - QString m_clickedItemName; -}; - -inline const QString &VInsertSelector::getClickedItem() const -{ - return m_clickedItemName; -} - -#endif // VINSERTSELECTOR_H diff --git a/src/vlineedit.cpp b/src/vlineedit.cpp deleted file mode 100644 index 06a6ce21..00000000 --- a/src/vlineedit.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "vlineedit.h" - -#include - -#include "utils/vutils.h" - -VLineEdit::VLineEdit(QWidget *p_parent) - : QLineEdit(p_parent), - m_ctrlKEnabled(true), - m_ctrlEEnabled(true) -{ -} - -VLineEdit::VLineEdit(const QString &p_contents, QWidget *p_parent) - : QLineEdit(p_contents, p_parent), - m_ctrlKEnabled(true), - m_ctrlEEnabled(true) -{ -} - -void VLineEdit::keyPressEvent(QKeyEvent *p_event) -{ - // Note that QKeyEvent starts with isAccepted() == true, so you do not - // need to call QKeyEvent::accept() - just do not call the base class - // implementation if you act upon the key. - - bool accept = false; - int modifiers = p_event->modifiers(); - switch (p_event->key()) { - case Qt::Key_H: - // Backspace. - if (VUtils::isControlModifierForVim(modifiers)) { - backspace(); - accept = true; - } - - break; - - case Qt::Key_W: - // Delete one word backward. - if (VUtils::isControlModifierForVim(modifiers)) { - if (!hasSelectedText()) { - cursorWordBackward(true); - } - - backspace(); - accept = true; - } - - break; - - case Qt::Key_U: - { - if (VUtils::isControlModifierForVim(modifiers)) { - if (hasSelectedText()) { - backspace(); - } else { - int pos = cursorPosition(); - if (pos > 0) { - cursorBackward(true, pos); - backspace(); - } - } - - accept = true; - } - - break; - } - - case Qt::Key_K: - { - if (VUtils::isControlModifierForVim(modifiers) && !m_ctrlKEnabled) { - QWidget::keyPressEvent(p_event); - accept = true; - } - - break; - } - - case Qt::Key_E: - { - if (VUtils::isControlModifierForVim(modifiers) && !m_ctrlEEnabled) { - QWidget::keyPressEvent(p_event); - accept = true; - } - - break; - } - - default: - break; - } - - if (!accept) { - QLineEdit::keyPressEvent(p_event); - } -} diff --git a/src/vlineedit.h b/src/vlineedit.h deleted file mode 100644 index d9ef52a4..00000000 --- a/src/vlineedit.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef VLINEEDIT_H -#define VLINEEDIT_H - -#include - - -class VLineEdit : public QLineEdit -{ - Q_OBJECT -public: - explicit VLineEdit(QWidget *p_parent = nullptr); - - VLineEdit(const QString &p_contents, QWidget *p_parent = nullptr); - - void setCtrlKEnabled(bool p_enabled); - - void setCtrlEEnabled(bool p_enabled); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - -private: - // Enable Ctrl+K shortcut. - // In QLineEdit, Ctrl+K will delete till the end. - bool m_ctrlKEnabled; - - // Enable Ctrl+E shortcut. - // In QLineEdit, Ctrl+E will move the cursor to the end. - bool m_ctrlEEnabled; -}; - -inline void VLineEdit::setCtrlKEnabled(bool p_enabled) -{ - m_ctrlKEnabled = p_enabled; -} - -inline void VLineEdit::setCtrlEEnabled(bool p_enabled) -{ - m_ctrlEEnabled = p_enabled; -} -#endif // VLINEEDIT_H diff --git a/src/vlinenumberarea.cpp b/src/vlinenumberarea.cpp deleted file mode 100644 index a7c3c25b..00000000 --- a/src/vlinenumberarea.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "vlinenumberarea.h" - -#include -#include - -VLineNumberArea::VLineNumberArea(VTextEditWithLineNumber *p_editor, - const QTextDocument *p_document, - int p_digitWidth, - QWidget *p_parent) - : QWidget(p_parent), - m_editor(p_editor), - m_document(p_document), - m_width(0), - m_blockCount(-1), - m_digitWidth(p_digitWidth), - m_foregroundColor("black"), - m_backgroundColor("grey") -{ -} - -int VLineNumberArea::calculateWidth() const -{ - int bc = m_document->blockCount(); - if (m_blockCount == bc) { - return m_width; - } - - const_cast(this)->m_blockCount = bc; - int digits = 1; - int max = qMax(1, m_blockCount); - while (max >= 10) { - max /= 10; - ++digits; - } - - const_cast(this)->m_width = m_digitWidth * digits + 3; - - return m_width; -} diff --git a/src/vlinenumberarea.h b/src/vlinenumberarea.h deleted file mode 100644 index 55155bab..00000000 --- a/src/vlinenumberarea.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef VLINENUMBERAREA_H -#define VLINENUMBERAREA_H - -#include -#include - -class QPaintEvent; -class QTextDocument; - - -enum class LineNumberType -{ - None = 0, - Absolute, - Relative, - CodeBlock, - Invalid -}; - - -class VTextEditWithLineNumber -{ -public: - virtual ~VTextEditWithLineNumber() {} - - virtual void paintLineNumberArea(QPaintEvent *p_event) = 0; -}; - - -// To use VLineNumberArea, the editor should implement VTextEditWithLineNumber. -class VLineNumberArea : public QWidget -{ - Q_OBJECT -public: - VLineNumberArea(VTextEditWithLineNumber *p_editor, - const QTextDocument *p_document, - int p_digitWidth, - QWidget *p_parent = nullptr); - - QSize sizeHint() const Q_DECL_OVERRIDE - { - return QSize(calculateWidth(), 0); - } - - void setDigitWidth(int p_width); - - int calculateWidth() const; - - const QColor &getBackgroundColor() const; - void setBackgroundColor(const QColor &p_color); - - const QColor &getForegroundColor() const; - void setForegroundColor(const QColor &p_color); - -protected: - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE - { - m_editor->paintLineNumberArea(p_event); - } - -private: - VTextEditWithLineNumber *m_editor; - const QTextDocument *m_document; - int m_width; - int m_blockCount; - int m_digitWidth; - QColor m_foregroundColor; - QColor m_backgroundColor; -}; - -inline const QColor &VLineNumberArea::getBackgroundColor() const -{ - return m_backgroundColor; -} - -inline void VLineNumberArea::setBackgroundColor(const QColor &p_color) -{ - m_backgroundColor = p_color; -} - -inline const QColor &VLineNumberArea::getForegroundColor() const -{ - return m_foregroundColor; -} - -inline void VLineNumberArea::setForegroundColor(const QColor &p_color) -{ - m_foregroundColor = p_color; -} - -inline void VLineNumberArea::setDigitWidth(int p_width) -{ - m_digitWidth = p_width; - m_blockCount = -1; - calculateWidth(); -} -#endif // VLINENUMBERAREA_H diff --git a/src/vlistfolderue.cpp b/src/vlistfolderue.cpp deleted file mode 100644 index e4ecfdce..00000000 --- a/src/vlistfolderue.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#include "vlistfolderue.h" - -#include -#include -#include - -#include "vlistwidget.h" -#include "vdirectory.h" -#include "vdirectorytree.h" -#include "vmainwindow.h" -#include "vnote.h" -#include "utils/viconutils.h" -#include "vnotefile.h" -#include "vsearchue.h" -#include "utils/vutils.h" -#include "vnotebook.h" -#include "vuetitlecontentpanel.h" - -extern VMainWindow *g_mainWin; - -extern VNote *g_vnote; - -VListFolderUE::VListFolderUE(QObject *p_parent) - : IUniversalEntry(p_parent), - m_listWidget(NULL) -{ -} - -QString VListFolderUE::description(int p_id) const -{ - Q_UNUSED(p_id); - - return tr("List and search the folders and notes of current folder"); -} - -void VListFolderUE::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - m_noteIcon = VIconUtils::treeViewIcon(":/resources/icons/note_item.svg"); - m_folderIcon = VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg"); - - m_listWidget = new VListWidget(m_widgetParent); - m_listWidget->setFitContent(true); - connect(m_listWidget, SIGNAL(itemActivated(QListWidgetItem *)), - this, SLOT(activateItem(QListWidgetItem *))); - - m_panel = new VUETitleContentPanel(m_listWidget, m_widgetParent); - m_panel->hide(); -} - -QWidget *VListFolderUE::widget(int p_id) -{ - Q_UNUSED(p_id); - - init(); - - return m_panel; -} - -void VListFolderUE::processCommand(int p_id, const QString &p_cmd) -{ - Q_UNUSED(p_id); - - init(); - - QString folderPath = m_folderPath; - if (folderPath.isEmpty()) { - VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory(); - folderPath = dir->fetchPath(); - } - - listFolder(folderPath, p_cmd); - - m_listWidget->updateGeometry(); - emit widgetUpdated(); - emit stateUpdated(State::Success); -} - -void VListFolderUE::clear(int p_id) -{ - Q_UNUSED(p_id); - - m_panel->clearTitle(); - m_listWidget->clearAll(); - m_data.clear(); - - m_folderPath.clear(); - m_currentFolderPath.clear(); -} - -void VListFolderUE::selectNextItem(int p_id, bool p_forward) -{ - Q_UNUSED(p_id); - - m_listWidget->selectNextItem(p_forward); -} - -void VListFolderUE::selectParentItem(int p_id) -{ - Q_UNUSED(p_id); - - if (m_currentFolderPath.isEmpty()) { - return; - } - - if (listFolder(VUtils::basePathFromPath(m_currentFolderPath), QString())) { - m_folderPath = m_currentFolderPath; - } - - m_listWidget->updateGeometry(); - emit widgetUpdated(); -} - -void VListFolderUE::activate(int p_id) -{ - Q_UNUSED(p_id); - activateItem(m_listWidget->currentItem()); -} - -const QSharedPointer &VListFolderUE::itemResultData(const QListWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - int idx = p_item->data(Qt::UserRole).toInt(); - Q_ASSERT(idx >= 0 && idx < m_data.size()); - return m_data[idx]; -} - -void VListFolderUE::activateItem(QListWidgetItem *p_item) -{ - if (!p_item) { - return; - } - - emit requestHideUniversalEntry(); - - VSearchUE::activateItem(itemResultData(p_item)); -} - -void VListFolderUE::sort(int p_id) -{ - Q_UNUSED(p_id); - static bool noteFirst = false; - - int cnt = m_listWidget->count(); - if (noteFirst) { - int idx = cnt - 1; - while (true) { - if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) { - // Move it to the first row. - m_listWidget->moveItem(idx, 0); - } else { - break; - } - } - } else { - int idx = 0; - while (true) { - if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) { - // Move it to the last row. - m_listWidget->moveItem(idx, cnt - 1); - } else { - break; - } - } - } - - if (cnt) { - m_listWidget->setCurrentRow(0); - } - - noteFirst = !noteFirst; -} - -void VListFolderUE::addResultItem(const QSharedPointer &p_item) -{ - m_data.append(p_item); - - QString text; - if (p_item->m_text.isEmpty()) { - text = p_item->m_path; - } else { - text = p_item->m_text; - } - - QIcon *icon = NULL; - switch (p_item->m_type) { - case VSearchResultItem::Note: - icon = &m_noteIcon; - break; - - case VSearchResultItem::Folder: - icon = &m_folderIcon; - break; - - default: - break; - } - - QListWidgetItem *item = new QListWidgetItem(*icon, text); - item->setData(Qt::UserRole, m_data.size() - 1); - item->setToolTip(p_item->m_path); - - m_listWidget->addItem(item); - - if (m_listWidget->count() == 1) { - m_listWidget->setCurrentRow(0); - } -} - -void VListFolderUE::entryShown(int p_id, const QString &p_cmd) -{ - processCommand(p_id, p_cmd); -} - -void VListFolderUE::setFolderPath(const QString &p_path) -{ - m_folderPath = p_path; -} - -QString VListFolderUE::currentItemFolder(int p_id) -{ - Q_UNUSED(p_id); - QString folder; - QListWidgetItem *item = m_listWidget->currentItem(); - if (item) { - const QSharedPointer &resItem = itemResultData(item); - if (resItem->m_type == VSearchResultItem::Folder) { - folder = resItem->m_path; - } - } - - return folder; -} - -bool VListFolderUE::listFolder(const QString &p_path, const QString &p_cmd) -{ - VDirectory *dir = g_vnote->getInternalDirectory(p_path); - if (!dir) { - // See if it is a notebook. - VNotebook *nb = g_vnote->getNotebook(p_path); - if (!nb) { - return false; - } - - dir = nb->getRootDir(); - } - - m_panel->clearTitle(); - m_listWidget->clearAll(); - m_data.clear(); - - m_currentFolderPath = dir->fetchPath(); - m_panel->setTitle(m_currentFolderPath); - - if (!dir->open()) { - return true; - } - - if (p_cmd.isEmpty()) { - // List the content. - for (auto const & it : dir->getSubDirs()) { - QSharedPointer item(new VSearchResultItem(VSearchResultItem::Folder, - VSearchResultItem::LineNumber, - it->getName(), - it->fetchPath())); - addResultItem(item); - } - - for (auto const & file : dir->getFiles()) { - QSharedPointer item(new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - file->getName(), - file->fetchPath())); - addResultItem(item); - } - } else { - // Search the content. - VSearchConfig config(VSearchConfig::CurrentFolder, - VSearchConfig::Name, - VSearchConfig::Note | VSearchConfig::Folder, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString()); - - for (auto const & it : dir->getSubDirs()) { - QString name = it->getName(); - if (!config.m_token.matched(name)) { - continue; - } - - QSharedPointer item(new VSearchResultItem(VSearchResultItem::Folder, - VSearchResultItem::LineNumber, - name, - it->fetchPath())); - addResultItem(item); - } - - for (auto const & file : dir->getFiles()) { - QString name = file->getName(); - if (!config.m_token.matched(name)) { - continue; - } - - QSharedPointer item(new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - name, - file->fetchPath())); - addResultItem(item); - } - } - - return true; -} diff --git a/src/vlistfolderue.h b/src/vlistfolderue.h deleted file mode 100644 index d1a45e47..00000000 --- a/src/vlistfolderue.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef VLISTFOLDERUE_H -#define VLISTFOLDERUE_H - -#include "iuniversalentry.h" -#include -#include - -#include "vsearchconfig.h" - -class VListWidget; -class QListWidgetItem; -class QLabel; -class VUETitleContentPanel; - -// Universal Entry to list contents of folder. -class VListFolderUE : public IUniversalEntry -{ - Q_OBJECT -public: - explicit VListFolderUE(QObject *p_parent = nullptr); - - QString description(int p_id) const Q_DECL_OVERRIDE; - - QWidget *widget(int p_id) Q_DECL_OVERRIDE; - - void processCommand(int p_id, const QString &p_cmd) Q_DECL_OVERRIDE; - - void clear(int p_id) Q_DECL_OVERRIDE; - - void selectNextItem(int p_id, bool p_forward) Q_DECL_OVERRIDE; - - void selectParentItem(int p_id) Q_DECL_OVERRIDE; - - void activate(int p_id) Q_DECL_OVERRIDE; - - void sort(int p_id) Q_DECL_OVERRIDE; - - void entryShown(int p_id, const QString &p_cmd) Q_DECL_OVERRIDE; - - QString currentItemFolder(int p_id) Q_DECL_OVERRIDE; - - void setFolderPath(const QString &p_path); - -protected: - void init() Q_DECL_OVERRIDE; - -private slots: - void activateItem(QListWidgetItem *p_item); - -private: - void addResultItem(const QSharedPointer &p_item); - - const QSharedPointer &itemResultData(const QListWidgetItem *p_item) const; - - bool listFolder(const QString &p_path, const QString &p_cmd); - - QVector > m_data; - - QIcon m_noteIcon; - QIcon m_folderIcon; - - // Folder path to list. - // If empty, use current folder. - QString m_folderPath; - - // Current folder path. - QString m_currentFolderPath; - - VListWidget *m_listWidget; - - VUETitleContentPanel *m_panel; -}; - -#endif // VLISTFOLDERUE_H diff --git a/src/vlistue.cpp b/src/vlistue.cpp deleted file mode 100644 index 9994aa8e..00000000 --- a/src/vlistue.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include "vlistue.h" - -#include -#include -#include - -#include "vlistwidgetdoublerows.h" -#include "vdirectory.h" -#include "vdirectorytree.h" -#include "vmainwindow.h" -#include "vnote.h" -#include "utils/viconutils.h" -#include "vnotefile.h" -#include "vsearchue.h" -#include "utils/vutils.h" -#include "vnotebook.h" -#include "vuetitlecontentpanel.h" -#include "vhistorylist.h" -#include "vuniversalentry.h" - -extern VMainWindow *g_mainWin; - -extern VNote *g_vnote; - -VListUE::VListUE(QObject *p_parent) - : IUniversalEntry(p_parent), - m_listWidget(NULL) -{ -} - -QString VListUE::description(int p_id) const -{ - switch (p_id) { - case ID::History: - return tr("List and search history"); - - default: - Q_ASSERT(false); - return tr("Invalid ID %1").arg(p_id); - } -} - -void VListUE::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - m_noteIcon = VIconUtils::treeViewIcon(":/resources/icons/note_item.svg"); - m_folderIcon = VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg"); - - m_listWidget = new VListWidgetDoubleRows(m_widgetParent); - m_listWidget->setFitContent(true); - connect(m_listWidget, SIGNAL(itemActivated(QListWidgetItem *)), - this, SLOT(activateItem(QListWidgetItem *))); - - m_panel = new VUETitleContentPanel(m_listWidget, m_widgetParent); - m_panel->hide(); -} - -QWidget *VListUE::widget(int p_id) -{ - Q_UNUSED(p_id); - - init(); - - return m_panel; -} - -void VListUE::processCommand(int p_id, const QString &p_cmd) -{ - Q_UNUSED(p_id); - - init(); - - clear(-1); - - switch (p_id) { - case ID::History: - listHistory(p_cmd); - break; - - default: - break; - } - - m_listWidget->updateGeometry(); - emit widgetUpdated(); - emit stateUpdated(State::Success); -} - -void VListUE::clear(int p_id) -{ - Q_UNUSED(p_id); - - m_panel->clearTitle(); - m_listWidget->clearAll(); - m_data.clear(); -} - -void VListUE::selectNextItem(int p_id, bool p_forward) -{ - Q_UNUSED(p_id); - - m_listWidget->selectNextItem(p_forward); -} - -void VListUE::activate(int p_id) -{ - Q_UNUSED(p_id); - activateItem(m_listWidget->currentItem()); -} - -const QSharedPointer &VListUE::itemResultData(const QListWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - int idx = p_item->data(Qt::UserRole).toInt(); - Q_ASSERT(idx >= 0 && idx < m_data.size()); - return m_data[idx]; -} - -void VListUE::activateItem(QListWidgetItem *p_item) -{ - if (!p_item) { - return; - } - - emit requestHideUniversalEntry(); - - VSearchUE::activateItem(itemResultData(p_item)); -} - -void VListUE::sort(int p_id) -{ - Q_UNUSED(p_id); - static bool noteFirst = false; - - int cnt = m_listWidget->count(); - if (noteFirst) { - int idx = cnt - 1; - while (true) { - if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) { - // Move it to the first row. - m_listWidget->moveItem(idx, 0); - } else { - break; - } - } - } else { - int idx = 0; - while (true) { - if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) { - // Move it to the last row. - m_listWidget->moveItem(idx, cnt - 1); - } else { - break; - } - } - } - - if (cnt) { - m_listWidget->setCurrentRow(0); - } - - noteFirst = !noteFirst; -} - -void VListUE::addResultItem(const QSharedPointer &p_item) -{ - m_data.append(p_item); - - QString first, second; - if (p_item->m_text.isEmpty()) { - first = p_item->m_path; - } else { - if (p_item->m_type != VSearchResultItem::Notebook) { - first = VUniversalEntry::fileNameWithDir(p_item->m_text, p_item->m_path); - } else { - first = p_item->m_text; - } - second = p_item->m_path; - } - - QIcon *icon = NULL; - switch (p_item->m_type) { - case VSearchResultItem::Note: - icon = &m_noteIcon; - break; - - case VSearchResultItem::Folder: - icon = &m_folderIcon; - break; - - default: - break; - } - - QListWidgetItem *item = m_listWidget->addDoubleRowsItem(*icon, first, second); - item->setData(Qt::UserRole, m_data.size() - 1); - item->setToolTip(p_item->m_path); - - if (m_listWidget->count() == 1) { - m_listWidget->setCurrentRow(0); - } -} - -void VListUE::listHistory(const QString &p_cmd) -{ - m_panel->setTitle(tr("History")); - - VHistoryList *history = g_mainWin->getHistoryList(); - const QLinkedList &entries = history->getHistoryEntries(); - if (p_cmd.isEmpty()) { - // List the content. - for (auto it = entries.rbegin(); it != entries.rend(); ++it) { - QSharedPointer item(new VSearchResultItem(it->m_isFolder ? VSearchResultItem::Folder : VSearchResultItem::Note, - VSearchResultItem::LineNumber, - VUtils::fileNameFromPath(it->m_file), - it->m_file)); - addResultItem(item); - } - } else { - // Search the content. - VSearchConfig config(VSearchConfig::CurrentFolder, - VSearchConfig::Name, - VSearchConfig::Note | VSearchConfig::Folder, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString()); - - for (auto it = entries.rbegin(); it != entries.rend(); ++it) { - QString name = VUtils::fileNameFromPath(it->m_file); - if (!config.m_token.matched(name)) { - continue; - } - - QSharedPointer item(new VSearchResultItem(it->m_isFolder ? VSearchResultItem::Folder : VSearchResultItem::Note, - VSearchResultItem::LineNumber, - name, - it->m_file)); - addResultItem(item); - } - } -} diff --git a/src/vlistue.h b/src/vlistue.h deleted file mode 100644 index ffb85f2b..00000000 --- a/src/vlistue.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef VLISTUE_H -#define VLISTUE_H - -#include "iuniversalentry.h" - -#include -#include -#include -#include - -#include "vsearchconfig.h" - -class VListWidgetDoubleRows; -class QListWidgetItem; -class QLabel; -class VUETitleContentPanel; - -class VListUE : public IUniversalEntry -{ - Q_OBJECT -public: - enum ID - { - // List and search the history. - History = 0 - }; - - explicit VListUE(QObject *p_parent = nullptr); - - QString description(int p_id) const Q_DECL_OVERRIDE; - - QWidget *widget(int p_id) Q_DECL_OVERRIDE; - - void processCommand(int p_id, const QString &p_cmd) Q_DECL_OVERRIDE; - - void clear(int p_id) Q_DECL_OVERRIDE; - - void selectNextItem(int p_id, bool p_forward) Q_DECL_OVERRIDE; - - void activate(int p_id) Q_DECL_OVERRIDE; - - void sort(int p_id) Q_DECL_OVERRIDE; - -protected: - void init() Q_DECL_OVERRIDE; - -private slots: - void activateItem(QListWidgetItem *p_item); - -private: - void addResultItem(const QSharedPointer &p_item); - - const QSharedPointer &itemResultData(const QListWidgetItem *p_item) const; - - void listHistory(const QString &p_cmd); - - QVector > m_data; - - QIcon m_noteIcon; - QIcon m_folderIcon; - - VListWidgetDoubleRows *m_listWidget; - - VUETitleContentPanel *m_panel; -}; - -#endif // VLISTUE_H diff --git a/src/vlistwidget.cpp b/src/vlistwidget.cpp deleted file mode 100644 index 98f991a8..00000000 --- a/src/vlistwidget.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include "vlistwidget.h" - -#include -#include -#include -#include - -#include "utils/vutils.h" -#include "utils/vimnavigationforwidget.h" -#include "vstyleditemdelegate.h" -#include "vpalette.h" - -extern VPalette *g_palette; - -VListWidget::VListWidget(QWidget *p_parent) - : QListWidget(p_parent), - ISimpleSearch(), - m_fitContent(false) -{ - m_searchInput = new VSimpleSearchInput(this, this); - connect(m_searchInput, &VSimpleSearchInput::triggered, - this, &VListWidget::handleSearchModeTriggered); - - m_searchInput->hide(); - - m_delegate = new VStyledItemDelegate(this, NULL); - setItemDelegate(m_delegate); -} - -void VListWidget::keyPressEvent(QKeyEvent *p_event) -{ - if (m_searchInput->tryHandleKeyPressEvent(p_event)) { - return; - } - - if (VimNavigationForWidget::injectKeyPressEventForVim(this, p_event)) { - return; - } - - QListWidget::keyPressEvent(p_event); -} - -void VListWidget::clearAll() -{ - m_searchInput->clear(); - setSearchInputVisible(false); - - QListWidget::clear(); -} - -void VListWidget::setSearchInputVisible(bool p_visible) -{ - m_searchInput->setVisible(p_visible); - - int bottomMargin = 0; - if (p_visible) { - bottomMargin = m_searchInput->height(); - } - - setViewportMargins(0, 0, 0, bottomMargin); -} - -void VListWidget::resizeEvent(QResizeEvent *p_event) -{ - QListWidget::resizeEvent(p_event); - - QRect rect = contentsRect(); - int width = rect.width(); - QScrollBar *vbar = verticalScrollBar(); - if (vbar && (vbar->minimum() != vbar->maximum())) { - width -= vbar->width(); - } - - int y = rect.bottom() - m_searchInput->height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && (hbar->minimum() != hbar->maximum())) { - y -= hbar->height(); - } - - m_searchInput->setGeometry(QRect(rect.left(), - y, - width, - m_searchInput->height())); -} - -void VListWidget::handleSearchModeTriggered(bool p_inSearchMode, bool p_focus) -{ - if (p_inSearchMode) { - setSearchInputVisible(p_inSearchMode); - } else { - // Hiding search input will make QWebEngine get focus which will consume - // the Esc key sequence by mistake. - if (p_focus) { - setFocus(); - } - - setSearchInputVisible(p_inSearchMode); - clearItemsHighlight(); - } - - if (p_focus) { - setFocus(); - } -} - -QList VListWidget::searchItems(const QString &p_text, - Qt::MatchFlags p_flags) const -{ - QList items = findItems(p_text, p_flags); - - QList res; - res.reserve(items.size()); - for (int i = 0; i < items.size(); ++i) { - if (items[i]->type() == ItemTypeSeparator) { - continue; - } - - res.append(items[i]); - } - - return res; -} - -void VListWidget::highlightHitItems(const QList &p_items) -{ - clearItemsHighlight(); - - QSet hitIndexes; - for (auto it : p_items) { - QModelIndex index = indexFromItem(static_cast(it)); - if (index.isValid()) { - hitIndexes.insert(index); - } - } - - if (!hitIndexes.isEmpty()) { - m_delegate->setHitItems(hitIndexes); - update(); - } -} - -void VListWidget::clearItemsHighlight() -{ - m_delegate->clearHitItems(); - update(); -} - -void VListWidget::selectHitItem(void *p_item) -{ - setCurrentItem(static_cast(p_item), - QItemSelectionModel::ClearAndSelect); -} - -int VListWidget::totalNumberOfItems() -{ - return count(); -} - -void VListWidget::selectNextItem(bool p_forward) -{ - if (count() == 0) { - return; - } - - int cur = currentRow(); - cur = cur + (p_forward ? 1 : -1); - if (cur < 0) { - cur = 0; - } else if (cur >= count()) { - cur = count() - 1; - } - - setCurrentRow(cur, QItemSelectionModel::ClearAndSelect); -} - -void VListWidget::sortListWidget(QListWidget *p_list, const QVector &p_sortedIdx) -{ - int cnt = p_list->count(); - Q_ASSERT(cnt == p_sortedIdx.size()); - - QVector sortedItems(cnt); - for (int i = 0; i < cnt; ++i) { - sortedItems[i] = p_list->item(p_sortedIdx[i]); - } - - for (int i = 0; i < cnt; ++i) { - QListWidgetItem *it = p_list->takeItem(p_list->row(sortedItems[i])); - p_list->insertItem(i, it); - } -} - -QSize VListWidget::sizeHint() const -{ - int cnt = count(); - if (cnt == 0 || !m_fitContent) { - return QListWidget::sizeHint(); - } else { - // Adjust size to content. - int hei = 0; - int wid = sizeHintForColumn(0) + 10; - for (int i = 0; i < cnt; ++i) { - hei += sizeHintForRow(i); - } - - hei += 2 * cnt; - - // Scrollbar. - QScrollBar *verBar = verticalScrollBar(); - QScrollBar *horBar = horizontalScrollBar(); - if (verBar && (verBar->minimum() != verBar->maximum())) { - wid += verBar->width(); - } - - if (horBar && (horBar->minimum() != horBar->maximum())) { - hei += horBar->height(); - } - - return QSize(wid, hei); - } -} - -QListWidgetItem *VListWidget::createSeparatorItem(const QString &p_text) -{ - QListWidgetItem *item = new QListWidgetItem(p_text, NULL, ItemTypeSeparator); - item->setFlags(Qt::NoItemFlags); - return item; -} - -bool VListWidget::isSeparatorItem(const QListWidgetItem *p_item) -{ - return p_item->type() == ItemTypeSeparator; -} - -void VListWidget::moveItem(int p_srcRow, int p_destRow) -{ - QListWidgetItem *it = takeItem(p_srcRow); - if (it) { - insertItem(p_destRow, it); - } -} diff --git a/src/vlistwidget.h b/src/vlistwidget.h deleted file mode 100644 index e6caf6a2..00000000 --- a/src/vlistwidget.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef VLISTWIDGET_H -#define VLISTWIDGET_H - -#include -#include - -#include "vsimplesearchinput.h" - -class VStyledItemDelegate; - - -class VListWidget : public QListWidget, public ISimpleSearch -{ -public: - explicit VListWidget(QWidget *p_parent = Q_NULLPTR); - - // Clear list widget as well as other data. - // clear() is not virtual to override. - virtual void clearAll(); - - // Implement ISimpleSearch. - virtual QList searchItems(const QString &p_text, - Qt::MatchFlags p_flags) const Q_DECL_OVERRIDE; - - virtual void highlightHitItems(const QList &p_items) Q_DECL_OVERRIDE; - - virtual void clearItemsHighlight() Q_DECL_OVERRIDE; - - virtual void selectHitItem(void *p_item) Q_DECL_OVERRIDE; - - virtual int totalNumberOfItems() Q_DECL_OVERRIDE; - - virtual void selectNextItem(bool p_forward) Q_DECL_OVERRIDE; - - virtual QSize sizeHint() const Q_DECL_OVERRIDE; - - virtual void moveItem(int p_srcRow, int p_destRow); - - void setFitContent(bool p_enabled); - - // Sort @p_list according to @p_sortedIdx. - static void sortListWidget(QListWidget *p_list, const QVector &p_sortedIdx); - - static QListWidgetItem *createSeparatorItem(const QString &p_text); - - static bool isSeparatorItem(const QListWidgetItem *p_item); - -private slots: - void handleSearchModeTriggered(bool p_inSearchMode, bool p_focus); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - -private: - // Show or hide search input. - void setSearchInputVisible(bool p_visible); - - VSimpleSearchInput *m_searchInput; - - VStyledItemDelegate *m_delegate; - - // Whether fit the size to content. - bool m_fitContent; -}; - -inline void VListWidget::setFitContent(bool p_enabled) -{ - m_fitContent = p_enabled; -} -#endif // VLISTWIDGET_H diff --git a/src/vlistwidgetdoublerows.cpp b/src/vlistwidgetdoublerows.cpp deleted file mode 100644 index 529bf4c5..00000000 --- a/src/vlistwidgetdoublerows.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "vlistwidgetdoublerows.h" - -#include -#include -#include - -#include "vdoublerowitemwidget.h" - -VListWidgetDoubleRows::VListWidgetDoubleRows(QWidget *p_parent) - : VListWidget(p_parent) -{ -} - -QListWidgetItem *VListWidgetDoubleRows::addDoubleRowsItem(const QIcon &p_icon, - const QString &p_firstRow, - const QString &p_secondRow) -{ - return insertDoubleRowsItem(count(), - p_icon, - p_firstRow, - p_secondRow); -} - -QListWidgetItem *VListWidgetDoubleRows::insertDoubleRowsItem(int p_row, - const QIcon &p_icon, - const QString &p_firstRow, - const QString &p_secondRow) -{ - VDoubleRowItemWidget *itemWidget = new VDoubleRowItemWidget(this); - itemWidget->setText(p_firstRow, p_secondRow); - QSize sz = itemWidget->sizeHint(); - QSize iconSz = iconSize(); - if (!iconSz.isValid()) { - iconSz = QSize(sz.height(), sz.height()); - setIconSize(iconSz); - } - - sz.setHeight(sz.height() * 1.25); - - QListWidgetItem *item = new QListWidgetItem(); - if (!p_icon.isNull()) { - item->setIcon(p_icon); - sz.setWidth(sz.width() + iconSz.width()); - sz.setHeight(qMax(sz.height(), iconSz.height())); - } - - item->setSizeHint(sz); - - insertItem(p_row, item); - setItemWidget(item, itemWidget); - return item; -} - -void VListWidgetDoubleRows::clearAll() -{ - // Delete the item widget for each item. - int cnt = count(); - for (int i = 0; i < cnt; ++i) { - QListWidgetItem *it = item(i); - QWidget *wid = itemWidget(it); - removeItemWidget(it); - delete wid; - } - - VListWidget::clearAll(); - - setIconSize(QSize()); -} - -void VListWidgetDoubleRows::moveItem(int p_srcRow, int p_destRow) -{ - QListWidgetItem *it = item(p_srcRow); - QWidget *wid = itemWidget(it); - - takeItem(p_srcRow); - insertItem(p_destRow, it); - - if (wid) { - QWidget *newWid = VDoubleRowItemWidget::cloneWidget(static_cast(wid), this); - removeItemWidget(it); - delete wid; - - setItemWidget(it, newWid); - } -} diff --git a/src/vlistwidgetdoublerows.h b/src/vlistwidgetdoublerows.h deleted file mode 100644 index 6437d31e..00000000 --- a/src/vlistwidgetdoublerows.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef VLISTWIDGETDOUBLEROWS_H -#define VLISTWIDGETDOUBLEROWS_H - -#include "vlistwidget.h" - -#include - -class QListWidgetItem; - - -class VListWidgetDoubleRows : public VListWidget -{ - Q_OBJECT -public: - explicit VListWidgetDoubleRows(QWidget *p_parent = nullptr); - - QListWidgetItem *addDoubleRowsItem(const QIcon &p_icon, - const QString &p_firstRow, - const QString &p_secondRow); - - QListWidgetItem *insertDoubleRowsItem(int p_row, - const QIcon &p_icon, - const QString &p_firstRow, - const QString &p_secondRow); - - void moveItem(int p_srcRow, int p_destRow) Q_DECL_OVERRIDE; - - void clearAll() Q_DECL_OVERRIDE; -}; - -#endif // VLISTWIDGETDOUBLEROWS_H diff --git a/src/vlivepreviewhelper.cpp b/src/vlivepreviewhelper.cpp deleted file mode 100644 index 1e8d8129..00000000 --- a/src/vlivepreviewhelper.cpp +++ /dev/null @@ -1,587 +0,0 @@ -#include "vlivepreviewhelper.h" - -#include -#include - -#include "veditor.h" -#include "vdocument.h" -#include "vconfigmanager.h" -#include "vgraphvizhelper.h" -#include "vplantumlhelper.h" -#include "vmainwindow.h" -#include "veditarea.h" -#include "vmathjaxpreviewhelper.h" -#include "utils/veditutils.h" - -extern VConfigManager *g_config; - -extern VMainWindow *g_mainWin; - -// Use the highest 4 bits (31-28) to indicate the lang. -#define LANG_PREFIX_GRAPHVIZ 0x10000000UL -#define LANG_PREFIX_PLANTUML 0x20000000UL -#define LANG_PREFIX_MATHJAX 0x30000000UL -#define LANG_PREFIX_MASK 0xf0000000UL - -// Use th 27th bit to indicate the preview type. -#define TYPE_LIVE_PREVIEW 0x0UL -#define TYPE_INPLACE_PREVIEW 0x08000000UL -#define TYPE_MASK 0x08000000UL - -#define INDEX_MASK 0x00ffffffUL - -CodeBlockPreviewInfo::CodeBlockPreviewInfo() -{ -} - -CodeBlockPreviewInfo::CodeBlockPreviewInfo(const VCodeBlock &p_cb) - : m_codeBlock(p_cb) -{ -} - -void CodeBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor, - const QTextDocument *p_doc, - const QPixmap &p_image, - const QString &p_imageName, - const QString &p_background) -{ - QTextBlock block = p_doc->findBlockByNumber(m_codeBlock.m_endBlock); - if (block.isValid()) { - VImageToPreview *preview = new VImageToPreview(); - - preview->m_startPos = block.position(); - preview->m_endPos = block.position() + block.length(); - preview->m_blockPos = block.position(); - preview->m_blockNumber = m_codeBlock.m_endBlock; - preview->m_padding = VPreviewManager::calculateBlockMargin(block, - p_editor->tabStopWidthW()); - if (!p_imageName.isEmpty()) { - preview->m_name = p_imageName; - } else { - preview->m_name = QString::number(getImageIndex()); - } - - preview->m_background = p_background; - preview->m_isBlock = true; - - preview->m_image = p_image; - - m_inplacePreview.reset(preview); - } else { - m_inplacePreview.clear(); - } -} - - -#define CODE_BLOCK_IMAGE_CACHE_SIZE_DIFF 10 -#define CODE_BLOCK_IMAGE_CACHE_TIME_DIFF 5 - -VLivePreviewHelper::VLivePreviewHelper(VEditor *p_editor, - VDocument *p_document, - QObject *p_parent) - : QObject(p_parent), - m_editor(p_editor), - m_document(p_document), - m_doc(p_editor->documentW()), - m_cbIndex(-1), - m_livePreviewEnabled(false), - m_inplacePreviewEnabled(false), - m_graphvizHelper(NULL), - m_plantUMLHelper(NULL), - m_lastInplacePreviewSize(0), - m_timeStamp(0), - m_scaleFactor(VUtils::calculateScaleFactor()), - m_lastCursorBlock(-1) -{ - m_livePreviewTimer = new QTimer(this); - m_livePreviewTimer->setSingleShot(true); - m_livePreviewTimer->setInterval(500); - connect(m_livePreviewTimer, &QTimer::timeout, - this, &VLivePreviewHelper::handleCursorPositionChanged); - - connect(m_editor->object(), SIGNAL(cursorPositionChanged()), - m_livePreviewTimer, SLOT(start())); - - m_flowchartEnabled = g_config->getEnableFlowchart(); - m_mermaidEnabled = g_config->getEnableMermaid(); - m_wavedromEnabled = g_config->getEnableWavedrom(); - m_plantUMLMode = g_config->getPlantUMLMode(); - m_graphvizEnabled = g_config->getEnableGraphviz(); - m_mathjaxEnabled = g_config->getEnableMathjax(); - - m_mathJaxHelper = g_mainWin->getEditArea()->getMathJaxPreviewHelper(); - m_mathJaxID = m_mathJaxHelper->registerIdentifier(); - connect(m_mathJaxHelper, &VMathJaxPreviewHelper::mathjaxPreviewResultReady, - this, &VLivePreviewHelper::mathjaxPreviewResultReady); - connect(m_mathJaxHelper, &VMathJaxPreviewHelper::diagramPreviewResultReady, - // The same handle logics. - this, &VLivePreviewHelper::mathjaxPreviewResultReady); -} - -void VLivePreviewHelper::checkLang(const QString &p_lang, - bool &p_livePreview, - bool &p_inplacePreview) const -{ - if (m_flowchartEnabled && (p_lang == "flow" || p_lang == "flowchart")) { - p_livePreview = p_inplacePreview = true; - } else if (m_wavedromEnabled && p_lang == "wavedrom") { - p_livePreview = true; - p_inplacePreview = false; - } else if (m_plantUMLMode != PlantUMLMode::DisablePlantUML && p_lang == "puml") { - p_livePreview = p_inplacePreview = true; - } else if (m_graphvizEnabled && p_lang == "dot") { - p_livePreview = p_inplacePreview = true; - } else if (m_mermaidEnabled && p_lang == "mermaid") { - p_livePreview = true; - p_inplacePreview = false; - } else if (m_mathjaxEnabled && p_lang == "mathjax") { - p_livePreview = false; - p_inplacePreview = true; - } else { - p_livePreview = p_inplacePreview = false; - } -} - -void VLivePreviewHelper::updateCodeBlocks(TimeStamp p_timeStamp, const QVector &p_codeBlocks) -{ - Q_UNUSED(p_timeStamp); - if (!m_livePreviewEnabled && !m_inplacePreviewEnabled) { - return; - } - - ++m_timeStamp; - - int lastIndex = m_cbIndex; - m_cbIndex = -1; - int cursorBlock = m_editor->textCursorW().block().blockNumber(); - bool needUpdate = m_livePreviewEnabled; - bool manualInplacePreview = m_inplacePreviewEnabled; - m_codeBlocks.clear(); - - for (int i = 0; i < p_codeBlocks.size(); ++i) { - const VCodeBlock &vcb = p_codeBlocks[i]; - bool livePreview = false, inplacePreview = false; - checkLang(vcb.m_lang, livePreview, inplacePreview); - if (!livePreview && !inplacePreview) { - continue; - } - - const QString &text = vcb.m_text; - bool cached = false; - - m_codeBlocks.append(CodeBlockPreviewInfo(vcb)); - int idx = m_codeBlocks.size() - 1; - - bool oldCache = false; - auto it = m_cache.find(text); - if (it != m_cache.end()) { - QSharedPointer &entry = it.value(); - // If this cache is not used at the last timestamp, we still need to - // update the live preview. - if (entry->m_ts < m_timeStamp - 1) { - oldCache = true; - } - - entry->m_ts = m_timeStamp; - cached = true; - m_codeBlocks[idx].setImageData(entry->m_imgFormat, entry->m_imgData); - m_codeBlocks[idx].updateInplacePreview(m_editor, - m_doc, - entry->m_image, - entry->m_imageName, - entry->m_imageBackground); - } - - if (m_inplacePreviewEnabled - && inplacePreview - && (!cached || !m_codeBlocks[idx].inplacePreviewReady())) { - manualInplacePreview = false; - processForInplacePreview(idx); - } - - if (m_livePreviewEnabled - && livePreview - && vcb.m_startBlock <= cursorBlock - && vcb.m_endBlock >= cursorBlock) { - if (lastIndex == idx && cached && !oldCache) { - needUpdate = false; - m_curLivePreviewInfo.update(vcb); - } - - m_cbIndex = idx; - } - } - - if (manualInplacePreview) { - updateInplacePreview(); - } - - if (needUpdate) { - updateLivePreview(); - performSmartLivePreview(); - } - - clearObsoleteCache(); -} - -void VLivePreviewHelper::handleCursorPositionChanged() -{ - if (!m_livePreviewEnabled || m_codeBlocks.isEmpty()) { - m_lastCursorBlock = -1; - return; - } - - int cursorBlock = m_editor->textCursorW().block().blockNumber(); - if (m_lastCursorBlock != cursorBlock) { - m_lastCursorBlock = cursorBlock; - - int left = 0, right = m_codeBlocks.size() - 1; - int mid = left; - while (left <= right) { - mid = (left + right) / 2; - const CodeBlockPreviewInfo &cb = m_codeBlocks[mid]; - const VCodeBlock &vcb = cb.codeBlock(); - if (vcb.m_startBlock <= cursorBlock && vcb.m_endBlock >= cursorBlock) { - break; - } else if (vcb.m_startBlock > cursorBlock) { - right = mid - 1; - } else { - left = mid + 1; - } - } - - if (left <= right) { - if (m_cbIndex != mid) { - m_cbIndex = mid; - updateLivePreview(); - } - } - } - - performSmartLivePreview(); -} - -void VLivePreviewHelper::updateLivePreview() -{ - if (m_cbIndex < 0) { - m_curLivePreviewInfo.clear(); - return; - } - - Q_ASSERT(!(m_cbIndex & ~INDEX_MASK)); - const CodeBlockPreviewInfo &cb = m_codeBlocks[m_cbIndex]; - const VCodeBlock &vcb = cb.codeBlock(); - - m_curLivePreviewInfo.update(vcb); - - if (vcb.m_lang == "dot") { - if (!m_graphvizHelper) { - m_graphvizHelper = new VGraphvizHelper(this); - connect(m_graphvizHelper, &VGraphvizHelper::resultReady, - this, &VLivePreviewHelper::localAsyncResultReady); - } - - if (!cb.hasImageData()) { - m_graphvizHelper->processAsync(m_cbIndex | LANG_PREFIX_GRAPHVIZ | TYPE_LIVE_PREVIEW, - m_timeStamp, - "svg", - VEditUtils::removeCodeBlockFence(vcb.m_text)); - } else { - m_document->setPreviewContent(vcb.m_lang, cb.imageData()); - } - } else if (vcb.m_lang == "puml" && m_plantUMLMode == PlantUMLMode::LocalPlantUML) { - if (!m_plantUMLHelper) { - m_plantUMLHelper = new VPlantUMLHelper(this); - connect(m_plantUMLHelper, &VPlantUMLHelper::resultReady, - this, &VLivePreviewHelper::localAsyncResultReady); - } - - if (!cb.hasImageData()) { - m_plantUMLHelper->processAsync(m_cbIndex | LANG_PREFIX_PLANTUML | TYPE_LIVE_PREVIEW, - m_timeStamp, - "svg", - VEditUtils::removeCodeBlockFence(vcb.m_text)); - } else { - m_document->setPreviewContent(vcb.m_lang, cb.imageData()); - } - } else if (vcb.m_lang != "mathjax") { - // No need to live preview MathJax. - m_document->previewCodeBlock(m_cbIndex, - vcb.m_lang, - VEditUtils::removeCodeBlockFence(vcb.m_text), - true); - } -} - -void VLivePreviewHelper::setLivePreviewEnabled(bool p_enabled) -{ - if (m_livePreviewEnabled == p_enabled) { - return; - } - - m_livePreviewEnabled = p_enabled; - if (!m_livePreviewEnabled) { - m_cbIndex = -1; - m_document->previewCodeBlock(-1, "", "", true); - - if (!m_inplacePreviewEnabled) { - m_codeBlocks.clear(); - m_cache.clear(); - updateInplacePreview(); - } - } -} - -void VLivePreviewHelper::setInplacePreviewEnabled(bool p_enabled) -{ - if (m_inplacePreviewEnabled == p_enabled) { - return; - } - - m_inplacePreviewEnabled = p_enabled; - if (!m_inplacePreviewEnabled && !m_livePreviewEnabled) { - m_codeBlocks.clear(); - m_cache.clear(); - } - - updateInplacePreview(); -} - -void VLivePreviewHelper::localAsyncResultReady(int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QString &p_result) -{ - if (p_timeStamp != m_timeStamp) { - return; - } - - Q_UNUSED(p_format); - Q_ASSERT(p_format == "svg"); - - int idx = p_id & INDEX_MASK; - if (idx >= m_codeBlocks.size()) { - return; - } - - bool livePreview = (p_id & TYPE_MASK) == TYPE_LIVE_PREVIEW; - - QString lang; - QString background; - switch (p_id & LANG_PREFIX_MASK) { - case LANG_PREFIX_PLANTUML: - lang = "puml"; - background = g_config->getEditorPreviewImageBg(); - break; - - case LANG_PREFIX_GRAPHVIZ: - lang = "dot"; - break; - - default: - return; - } - - CodeBlockPreviewInfo &cb = m_codeBlocks[idx]; - QSharedPointer entry(new CodeBlockImageCacheEntry(p_timeStamp, - p_format, - p_result, - background, - getScaleFactor(cb))); - m_cache.insert(cb.codeBlock().m_text, entry); - - cb.setImageData(p_format, p_result); - cb.updateInplacePreview(m_editor, m_doc, entry->m_image, QString(), background); - - if (cb.inplacePreview()) { - entry->m_imageName = cb.inplacePreview()->m_name; - } - - if (livePreview) { - if (idx != m_cbIndex) { - return; - } - - m_document->setPreviewContent(lang, p_result); - performSmartLivePreview(); - } else { - // Inplace preview. - updateInplacePreview(); - } -} - -void VLivePreviewHelper::processForInplacePreview(int p_idx) -{ - CodeBlockPreviewInfo &cb = m_codeBlocks[p_idx]; - const VCodeBlock &vcb = cb.codeBlock(); - Q_ASSERT(!cb.hasImageData()); - if (vcb.m_lang == "dot") { - if (!m_graphvizHelper) { - m_graphvizHelper = new VGraphvizHelper(this); - connect(m_graphvizHelper, &VGraphvizHelper::resultReady, - this, &VLivePreviewHelper::localAsyncResultReady); - } - - m_graphvizHelper->processAsync(p_idx | LANG_PREFIX_GRAPHVIZ | TYPE_INPLACE_PREVIEW, - m_timeStamp, - "svg", - VEditUtils::removeCodeBlockFence(vcb.m_text)); - } else if (vcb.m_lang == "puml") { - if (m_plantUMLMode == PlantUMLMode::LocalPlantUML) { - if (!m_plantUMLHelper) { - m_plantUMLHelper = new VPlantUMLHelper(this); - connect(m_plantUMLHelper, &VPlantUMLHelper::resultReady, - this, &VLivePreviewHelper::localAsyncResultReady); - } - - m_plantUMLHelper->processAsync(p_idx | LANG_PREFIX_PLANTUML | TYPE_INPLACE_PREVIEW, - m_timeStamp, - "svg", - VEditUtils::removeCodeBlockFence(vcb.m_text)); - } else { - m_mathJaxHelper->previewDiagram(m_mathJaxID, - p_idx, - m_timeStamp, - vcb.m_lang, - VEditUtils::removeCodeBlockFence(vcb.m_text)); - } - } else if (vcb.m_lang == "flow" - || vcb.m_lang == "flowchart") { - m_mathJaxHelper->previewDiagram(m_mathJaxID, - p_idx, - m_timeStamp, - vcb.m_lang, - VEditUtils::removeCodeBlockFence(vcb.m_text)); - } else if (vcb.m_lang == "mathjax") { - m_mathJaxHelper->previewMathJax(m_mathJaxID, - p_idx, - m_timeStamp, - VEditUtils::removeCodeBlockFence(vcb.m_text)); - } -} - -void VLivePreviewHelper::updateInplacePreview() -{ - QSet blocks; - QVector > images; - for (int i = 0; i < m_codeBlocks.size(); ++i) { - CodeBlockPreviewInfo &cb = m_codeBlocks[i]; - if (cb.inplacePreviewReady()) { - if (!cb.inplacePreview()->m_image.isNull()) { - images.append(cb.inplacePreview()); - } else { - blocks.insert(cb.inplacePreview()->m_blockNumber); - } - } else { - blocks.insert(cb.codeBlock().m_endBlock); - } - } - - if (images.isEmpty() && m_lastInplacePreviewSize == 0) { - return; - } - - emit inplacePreviewCodeBlockUpdated(images); - - m_lastInplacePreviewSize = images.size(); - - if (!blocks.isEmpty()) { - emit checkBlocksForObsoletePreview(blocks.toList()); - } -} - -void VLivePreviewHelper::mathjaxPreviewResultReady(int p_identitifer, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QByteArray &p_data) -{ - if (p_identitifer != m_mathJaxID || p_timeStamp != m_timeStamp) { - return; - } - - if (p_id >= m_codeBlocks.size() || p_data.isEmpty()) { - updateInplacePreview(); - return; - } - - CodeBlockPreviewInfo &cb = m_codeBlocks[p_id]; - const VCodeBlock &vcb = cb.codeBlock(); - - QString background; - if (vcb.m_lang == "puml") { - background = g_config->getEditorPreviewImageBg(); - } - - QSharedPointer entry(new CodeBlockImageCacheEntry(p_timeStamp, - p_format, - p_data, - background, - getScaleFactor(cb))); - m_cache.insert(vcb.m_text, entry); - - cb.updateInplacePreview(m_editor, m_doc, entry->m_image, QString(), background); - - if (cb.inplacePreview()) { - entry->m_imageName = cb.inplacePreview()->m_name; - } - - updateInplacePreview(); -} - -void VLivePreviewHelper::clearObsoleteCache() -{ - if (m_cache.size() - m_codeBlocks.size() <= CODE_BLOCK_IMAGE_CACHE_SIZE_DIFF) { - return; - } - - for (auto it = m_cache.begin(); it != m_cache.end();) { - if (m_timeStamp - it.value()->m_ts > CODE_BLOCK_IMAGE_CACHE_TIME_DIFF) { - it.value().clear(); - it = m_cache.erase(it); - } else { - ++it; - } - } -} - -void VLivePreviewHelper::performSmartLivePreview() -{ - if (m_cbIndex < 0 - || m_cbIndex >= m_codeBlocks.size() - || !(g_config->getSmartLivePreview() & SmartLivePreview::EditorToWeb)) { - return; - } - - const CodeBlockPreviewInfo &cb = m_codeBlocks[m_cbIndex]; - const VCodeBlock &vcb = cb.codeBlock(); - if (!cb.hasImageData() && !isOnlineLivePreview(vcb.m_lang)) { - return; - } - - const QTextBlock block = m_editor->textCursorW().block(); - if (block.blockNumber() <= vcb.m_startBlock - || block.blockNumber() >= vcb.m_endBlock) { - return; - } - - QString keyword, hints; - bool isRegex = false; - if (vcb.m_lang == "puml") { - keyword = VPlantUMLHelper::keywordForSmartLivePreview(block.text(), - hints, - isRegex); - } - - m_document->performSmartLivePreview(vcb.m_lang, keyword, hints, isRegex); -} - -bool VLivePreviewHelper::isOnlineLivePreview(const QString &p_lang) const -{ - if (p_lang == "dot" - || (p_lang == "puml" && m_plantUMLMode == PlantUMLMode::LocalPlantUML)) { - return false; - } - - return true; -} diff --git a/src/vlivepreviewhelper.h b/src/vlivepreviewhelper.h deleted file mode 100644 index 00e20dec..00000000 --- a/src/vlivepreviewhelper.h +++ /dev/null @@ -1,336 +0,0 @@ -#ifndef VLIVEPREVIEWHELPER_H -#define VLIVEPREVIEWHELPER_H - -#include -#include - -#include "pegmarkdownhighlighter.h" -#include "vpreviewmanager.h" -#include "vconstants.h" - -class VEditor; -class VDocument; -class VGraphvizHelper; -class VPlantUMLHelper; -class VMathJaxPreviewHelper; - -class CodeBlockPreviewInfo -{ -public: - CodeBlockPreviewInfo(); - - explicit CodeBlockPreviewInfo(const VCodeBlock &p_cb); - - void updateInplacePreview(const VEditor *p_editor, - const QTextDocument *p_doc, - const QPixmap &p_image, - const QString &p_imageName, - const QString &p_background); - - void updateInplacePreview(const VEditor *p_editor, - const QTextDocument *p_doc, - const QPixmap &p_image) - { - updateInplacePreview(p_editor, p_doc, p_image, QString(), QString()); - } - - VCodeBlock &codeBlock() - { - return m_codeBlock; - } - - const VCodeBlock &codeBlock() const - { - return m_codeBlock; - } - - bool inplacePreviewReady() const - { - return !m_inplacePreview.isNull(); - } - - bool hasImageData() const - { - return !m_imgData.isEmpty(); - } - - const QString &imageData() const - { - return m_imgData; - } - - const QString &imageFormat() const - { - return m_imgFormat; - } - - void setImageData(const QString &p_format, const QString &p_data) - { - m_imgFormat = p_format; - m_imgData = p_data; - } - - const QSharedPointer &inplacePreview() const - { - return m_inplacePreview; - } - -private: - static int getImageIndex() - { - static int index = 0; - return ++index; - } - - VCodeBlock m_codeBlock; - - QString m_imgData; - - QString m_imgFormat; - - QSharedPointer m_inplacePreview; -}; - - -struct LivePreviewInfo -{ - LivePreviewInfo() - : m_startPos(), - m_endPos() - { - } - - void clear() - { - m_startPos = 0; - m_endPos = 0; - } - - void update(const VCodeBlock &p_cb) - { - m_startPos = p_cb.m_startPos; - m_endPos = p_cb.m_startPos + p_cb.m_text.size(); - } - - bool isValid() const - { - return m_endPos > m_startPos; - } - - int m_startPos; - int m_endPos; -}; - - -// Manage live preview and inplace preview. -class VLivePreviewHelper : public QObject -{ - Q_OBJECT -public: - VLivePreviewHelper(VEditor *p_editor, - VDocument *p_document, - QObject *p_parent = nullptr); - - void updateLivePreview(); - - void setLivePreviewEnabled(bool p_enabled); - - void setInplacePreviewEnabled(bool p_enabled); - - bool isPreviewEnabled() const; - - const LivePreviewInfo &getLivePreviewInfo() const; - -public slots: - void updateCodeBlocks(TimeStamp p_timeStamp, const QVector &p_codeBlocks); - -signals: - void inplacePreviewCodeBlockUpdated(const QVector > &p_images); - - void checkBlocksForObsoletePreview(const QList &p_blocks); - -private slots: - void handleCursorPositionChanged(); - - void localAsyncResultReady(int p_id, TimeStamp p_timeStamp, const QString &p_format, const QString &p_result); - - void mathjaxPreviewResultReady(int p_identitifer, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QByteArray &p_data); - -private: - struct CodeBlockImageCacheEntry - { - #define SCALE_FACTOR_THRESHOLD 1.1 - - CodeBlockImageCacheEntry() - : m_ts(0) - { - } - - CodeBlockImageCacheEntry(TimeStamp p_ts, - const QString &p_format, - const QByteArray &p_data, - const QString &p_background, - qreal p_scaleFactor) - : m_ts(p_ts) - { - if (!p_data.isEmpty()) { - m_imageBackground = p_background; - - if (p_scaleFactor < SCALE_FACTOR_THRESHOLD) { - m_image.loadFromData(p_data, - p_format.toLocal8Bit().data()); - } else { - if (p_format == "svg") { - m_image = VUtils::svgToPixmap(p_data, - m_imageBackground, - p_scaleFactor); - } else { - QPixmap tmpImg; - tmpImg.loadFromData(p_data, - p_format.toLocal8Bit().data()); - m_image = tmpImg.scaledToWidth(tmpImg.width() * p_scaleFactor, - Qt::SmoothTransformation); - } - } - } - } - - CodeBlockImageCacheEntry(TimeStamp p_ts, - const QString &p_format, - const QString &p_data, - const QString &p_background, - qreal p_scaleFactor) - : m_ts(p_ts), - m_imgData(p_data), - m_imgFormat(p_format) - { - if (!p_data.isEmpty()) { - m_imageBackground = p_background; - - if (p_scaleFactor < SCALE_FACTOR_THRESHOLD) { - m_image.loadFromData(p_data.toUtf8(), - p_format.toLocal8Bit().data()); - } else { - if (p_format == "svg") { - m_image = VUtils::svgToPixmap(p_data.toUtf8(), - m_imageBackground, - p_scaleFactor); - } else { - QPixmap tmpImg; - tmpImg.loadFromData(p_data.toUtf8(), - p_format.toLocal8Bit().data()); - m_image = tmpImg.scaledToWidth(tmpImg.width() * p_scaleFactor, - Qt::SmoothTransformation); - } - } - } - } - - bool hasImageData() const - { - return !m_imgData.isEmpty(); - } - - bool hasImage() const - { - return !m_image.isNull(); - } - - TimeStamp m_ts; - - // For live preview. - QString m_imgData; - QString m_imgFormat; - - // For in-place preview. - QPixmap m_image; - QString m_imageName; - QString m_imageBackground; - }; - - void checkLang(const QString &p_lang, bool &p_livePreview, bool &p_inplacePreview) const; - - // Get image data for this code block for inplace preview. - void processForInplacePreview(int p_idx); - - // Emit signal to update inplace preview. - void updateInplacePreview(); - - qreal getScaleFactor(const CodeBlockPreviewInfo &p_cb); - - void clearObsoleteCache(); - - void performSmartLivePreview(); - - bool isOnlineLivePreview(const QString &p_lang) const; - - // Sorted by m_startBlock in ascending order. - QVector m_codeBlocks; - - VEditor *m_editor; - - VDocument *m_document; - - QTextDocument *m_doc; - - // Current previewed code block index in m_codeBlocks. - int m_cbIndex; - - bool m_flowchartEnabled; - bool m_mermaidEnabled; - bool m_wavedromEnabled; - int m_plantUMLMode; - bool m_graphvizEnabled; - bool m_mathjaxEnabled; - - bool m_livePreviewEnabled; - - bool m_inplacePreviewEnabled; - - VGraphvizHelper *m_graphvizHelper; - VPlantUMLHelper *m_plantUMLHelper; - - VMathJaxPreviewHelper *m_mathJaxHelper; - - // Identification for VMathJaxPreviewHelper. - int m_mathJaxID; - - int m_lastInplacePreviewSize; - - TimeStamp m_timeStamp; - - const qreal m_scaleFactor; - - // Indexed by content. - QHash> m_cache; - - int m_lastCursorBlock; - - QTimer *m_livePreviewTimer; - - LivePreviewInfo m_curLivePreviewInfo; -}; - -inline bool VLivePreviewHelper::isPreviewEnabled() const -{ - return m_inplacePreviewEnabled || m_livePreviewEnabled; -} - -inline qreal VLivePreviewHelper::getScaleFactor(const CodeBlockPreviewInfo &p_cb) -{ - if (p_cb.codeBlock().m_lang == QStringLiteral("mathjax")) { - return 1.0; - } else { - return m_scaleFactor; - } -} - -inline const LivePreviewInfo &VLivePreviewHelper::getLivePreviewInfo() const -{ - return m_curLivePreviewInfo; -} -#endif // VLIVEPREVIEWHELPER_H diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp deleted file mode 100644 index 9cce375a..00000000 --- a/src/vmainwindow.cpp +++ /dev/null @@ -1,3749 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "vmainwindow.h" -#include "vdirectorytree.h" -#include "vnote.h" -#include "vfilelist.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "veditarea.h" -#include "voutline.h" -#include "vnotebookselector.h" -#include "dialog/vfindreplacedialog.h" -#include "dialog/vsettingsdialog.h" -#include "vcaptain.h" -#include "vedittab.h" -#include "vwebview.h" -#include "vexporter.h" -#include "vmdtab.h" -#include "vvimindicator.h" -#include "vvimcmdlineedit.h" -#include "vtabindicator.h" -#include "dialog/vupdater.h" -#include "vorphanfile.h" -#include "dialog/vorphanfileinfodialog.h" -#include "vsingleinstanceguard.h" -#include "vnotefile.h" -#include "vbuttonwithwidget.h" -#include "vattachmentlist.h" -#include "vfilesessioninfo.h" -#include "vsnippetlist.h" -#include "vtoolbox.h" -#include "vbuttonmenuitem.h" -#include "vpalette.h" -#include "utils/viconutils.h" -#include "dialog/vtipsdialog.h" -#include "vcart.h" -#include "dialog/vexportdialog.h" -#include "vsearcher.h" -#include "vuniversalentry.h" -#include "vsearchue.h" -#include "voutlineue.h" -#include "vhelpue.h" -#include "vlistfolderue.h" -#include "dialog/vfixnotebookdialog.h" -#include "vhistorylist.h" -#include "vexplorer.h" -#include "vlistue.h" -#include "vtagexplorer.h" -#include "vmdeditor.h" -#include "utils/vSync.h" - -extern VConfigManager *g_config; - -extern VPalette *g_palette; - -VMainWindow *g_mainWin; - -VNote *g_vnote; - -VWebUtils *g_webUtils; - -const int VMainWindow::c_sharedMemTimerInterval = 1000; - -#if defined(QT_NO_DEBUG) -extern QFile g_logFile; -#endif - -#define COLOR_PIXMAP_ICON_SIZE 64 - -enum NaviBoxIndex -{ - NotebookPanel = 0, - HistoryList, - Explorer, - TagExplorer -}; - - -VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent) - : QMainWindow(p_parent), - m_guard(p_guard), - m_windowOldState(Qt::WindowNoState), - m_requestQuit(false), - m_printer(NULL), - m_ue(NULL), - m_syncNoteListToCurrentTab(true) -{ - qsrand(QDateTime::currentDateTime().toTime_t()); - - g_mainWin = this; - - setWindowIcon(QIcon(":/resources/icons/vnote.ico")); - - vnote = new VNote(this); - g_vnote = vnote; - - m_webUtils.init(); - g_webUtils = &m_webUtils; - - initCaptain(); - - setupUI(); - - initMenuBar(); - - initToolBar(); - - initShortcuts(); - - initDockWindows(); - - initSync(); - - int state = g_config->getPanelViewState(); - if (state < 0 || state >= (int)PanelViewState::Invalid) { - state = (int)PanelViewState::VerticalMode; - } - - changePanelView((PanelViewState)state); - - restoreStateAndGeometry(); - - setContextMenuPolicy(Qt::NoContextMenu); - - m_notebookSelector->update(); - - initSharedMemoryWatcher(); - - initUpdateTimer(); - - registerCaptainAndNavigationTargets(); -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - QApplication::setQuitOnLastWindowClosed(false); -#endif -} - -void VMainWindow::initSharedMemoryWatcher() -{ - m_sharedMemTimer = new QTimer(this); - m_sharedMemTimer->setSingleShot(false); - m_sharedMemTimer->setInterval(c_sharedMemTimerInterval); - connect(m_sharedMemTimer, &QTimer::timeout, - this, &VMainWindow::checkSharedMemory); - - m_sharedMemTimer->start(); -} - -void VMainWindow::initCaptain() -{ - // VCaptain should be visible to accpet key focus. But VCaptain - // may hide other widgets. - m_captain = new VCaptain(this); - connect(m_captain, &VCaptain::captainModeChanged, - this, [this](bool p_captainMode) { - static QString normalStyle = m_avatarBtn->styleSheet(); - static QString captainStyle = QString("color: %1; background: %2;") - .arg(g_palette->color("avatar_captain_mode_fg")) - .arg(g_palette->color("avatar_captain_mode_bg")); - - if (p_captainMode) { - m_avatarBtn->setStyleSheet(captainStyle); - } else { - m_avatarBtn->setStyleSheet(normalStyle); - } - }); -} - -void VMainWindow::registerCaptainAndNavigationTargets() -{ - m_captain->registerNavigationTarget(m_naviBox); - m_captain->registerNavigationTarget(m_notebookSelector); - m_captain->registerNavigationTarget(m_dirTree); - m_captain->registerNavigationTarget(m_fileList); - m_captain->registerNavigationTarget(m_historyList); - - m_tagExplorer->registerNavigationTarget(); - - m_captain->registerNavigationTarget(m_editArea); - - m_tabIndicator->registerNavigationTarget(); - - m_captain->registerNavigationTarget(m_toolBox); - m_captain->registerNavigationTarget(outline); - m_captain->registerNavigationTarget(m_snippetList); - m_captain->registerNavigationTarget(m_cart); - m_captain->registerNavigationTarget(m_searcher); - - // Register Captain mode targets. - m_captain->registerCaptainTarget(tr("AttachmentList"), - g_config->getCaptainShortcutKeySequence("AttachmentList"), - this, - showAttachmentListByCaptain); - m_captain->registerCaptainTarget(tr("LocateCurrentFile"), - g_config->getCaptainShortcutKeySequence("LocateCurrentFile"), - this, - locateCurrentFileByCaptain); - m_captain->registerCaptainTarget(tr("ExpandMode"), - g_config->getCaptainShortcutKeySequence("ExpandMode"), - this, - toggleExpandModeByCaptain); - m_captain->registerCaptainTarget(tr("CurrentNoteInfo"), - g_config->getCaptainShortcutKeySequence("CurrentNoteInfo"), - this, - currentNoteInfoByCaptain); - m_captain->registerCaptainTarget(tr("DiscardAndRead"), - g_config->getCaptainShortcutKeySequence("DiscardAndRead"), - this, - discardAndReadByCaptain); - m_captain->registerCaptainTarget(tr("ToolBar"), - g_config->getCaptainShortcutKeySequence("ToolBar"), - this, - toggleToolBarByCaptain); - m_captain->registerCaptainTarget(tr("ToolsDock"), - g_config->getCaptainShortcutKeySequence("ToolsDock"), - this, - toggleToolsDockByCaptain); - m_captain->registerCaptainTarget(tr("SearchDock"), - g_config->getCaptainShortcutKeySequence("SearchDock"), - this, - toggleSearchDockByCaptain); - m_captain->registerCaptainTarget(tr("CloseNote"), - g_config->getCaptainShortcutKeySequence("CloseNote"), - this, - closeFileByCaptain); - m_captain->registerCaptainTarget(tr("ShortcutsHelp"), - g_config->getCaptainShortcutKeySequence("ShortcutsHelp"), - this, - shortcutsHelpByCaptain); - m_captain->registerCaptainTarget(tr("FlushLogFile"), - g_config->getCaptainShortcutKeySequence("FlushLogFile"), - this, - flushLogFileByCaptain); - m_captain->registerCaptainTarget(tr("Export"), - g_config->getCaptainShortcutKeySequence("Export"), - this, - exportByCaptain); - m_captain->registerCaptainTarget(tr("FocusEditArea"), - g_config->getCaptainShortcutKeySequence("FocusEditArea"), - this, - focusEditAreaByCaptain); -} - -void VMainWindow::setupUI() -{ - setupNaviBox(); - - m_editArea = new VEditArea(); - m_editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_findReplaceDialog = m_editArea->getFindReplaceDialog(); - m_fileList->setEditArea(m_editArea); - m_dirTree->setEditArea(m_editArea); - - connect(m_editArea, &VEditArea::fileClosed, - m_historyList, &VHistoryList::addFile); - - // Main Splitter - m_mainSplitter = new QSplitter(); - m_mainSplitter->setObjectName("MainSplitter"); - m_mainSplitter->addWidget(m_naviBox); - m_mainSplitter->addWidget(m_editArea); - m_mainSplitter->setStretchFactor(0, 0); - m_mainSplitter->setStretchFactor(1, 1); - - connect(m_dirTree, &VDirectoryTree::directoryUpdated, - m_editArea, &VEditArea::handleDirectoryUpdated); - - connect(m_notebookSelector, &VNotebookSelector::notebookUpdated, - m_editArea, &VEditArea::handleNotebookUpdated); - connect(m_notebookSelector, &VNotebookSelector::notebookCreated, - m_dirTree, [this](const QString &p_name, bool p_import) { - Q_UNUSED(p_name); - if (!p_import) { - m_dirTree->newRootDirectory(); - } - }); - - connect(m_fileList, &VFileList::fileClicked, - m_editArea, &VEditArea::openFile); - connect(m_fileList, &VFileList::fileCreated, - m_editArea, [this](VNoteFile *p_file, - OpenFileMode p_mode, - bool p_forceMode) { - if (p_file->getDocType() == DocType::Markdown - || p_file->getDocType() == DocType::Html) { - m_editArea->openFile(p_file, p_mode, p_forceMode); - } - }); - connect(m_fileList, &VFileList::fileUpdated, - m_editArea, &VEditArea::handleFileUpdated); - connect(m_editArea, &VEditArea::tabStatusUpdated, - this, &VMainWindow::handleAreaTabStatusUpdated); - connect(m_editArea, &VEditArea::statusMessage, - this, &VMainWindow::showStatusMessage); - connect(m_editArea, &VEditArea::vimStatusUpdated, - this, &VMainWindow::handleVimStatusUpdated); - connect(m_findReplaceDialog, &VFindReplaceDialog::findTextChanged, - this, &VMainWindow::handleFindDialogTextChanged); - - setCentralWidget(m_mainSplitter); - - initVimCmd(); - - m_vimIndicator = new VVimIndicator(this); - m_vimIndicator->hide(); - - m_tabIndicator = new VTabIndicator(this); - m_tabIndicator->hide(); - - // Create and show the status bar - statusBar()->addPermanentWidget(m_vimCmd); - statusBar()->addPermanentWidget(m_vimIndicator); - statusBar()->addPermanentWidget(m_tabIndicator); - - initTrayIcon(); -} - -void VMainWindow::setupNaviBox() -{ - m_naviBox = new VToolBox(); - m_naviBox->setObjectName("MainToolBox"); - - setupNotebookPanel(); - m_naviBox->addItem(m_nbSplitter, - ":/resources/icons/notebook.svg", - tr("Notebooks"), - m_dirTree); - - m_historyList = new VHistoryList(); - m_naviBox->addItem(m_historyList, - ":/resources/icons/history.svg", - tr("History")); - - m_explorer = new VExplorer(); - m_naviBox->addItem(m_explorer, - ":/resources/icons/explorer.svg", - tr("Explorer")); - - m_tagExplorer = new VTagExplorer(); - m_naviBox->addItem(m_tagExplorer, - ":/resources/icons/tag_explorer.svg", - tr("Tags")); - connect(m_notebookSelector, &VNotebookSelector::curNotebookChanged, - m_tagExplorer, &VTagExplorer::setNotebook); - - connect(m_fileList, &VFileList::requestSplitOut, - this, &VMainWindow::splitFileListOut); -} - -void VMainWindow::setupNotebookPanel() -{ - m_notebookSelector = new VNotebookSelector(); - m_notebookSelector->setObjectName("NotebookSelector"); - m_notebookSelector->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); - - // Folders. - QLabel *directoryLabel = new QLabel(tr("Folders")); - directoryLabel->setProperty("TitleLabel", true); - - m_dirTree = new VDirectoryTree; - - QVBoxLayout *naviLayout = new QVBoxLayout; - naviLayout->addWidget(m_notebookSelector); - naviLayout->addWidget(directoryLabel); - naviLayout->addWidget(m_dirTree); - naviLayout->setContentsMargins(0, 0, 0, 0); - naviLayout->setSpacing(0); - QWidget *naviWidget = new QWidget(); - naviWidget->setLayout(naviLayout); - - // Notes. - m_fileList = new VFileList(); - m_fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); - - m_nbSplitter = new QSplitter(); - m_nbSplitter->setObjectName("NotebookSplitter"); - m_nbSplitter->addWidget(naviWidget); - m_nbSplitter->addWidget(m_fileList); - - setupFileListSplitOut(g_config->getEnableSplitFileList()); - - connect(m_notebookSelector, &VNotebookSelector::curNotebookChanged, - this, [this](VNotebook *p_notebook) { - m_dirTree->setNotebook(p_notebook); - m_dirTree->setFocus(); - }); - - connect(m_notebookSelector, &VNotebookSelector::curNotebookChanged, - this, &VMainWindow::handleCurrentNotebookChanged); - - connect(m_dirTree, &VDirectoryTree::currentDirectoryChanged, - this, &VMainWindow::handleCurrentDirectoryChanged); - - connect(m_dirTree, &VDirectoryTree::currentDirectoryChanged, - m_fileList, &VFileList::setDirectory); -} - -void VMainWindow::initToolBar() -{ - const int tbIconSize = g_config->getToolBarIconSize() * VUtils::calculateScaleFactor(); - QSize iconSize(tbIconSize, tbIconSize); - - m_toolBars.append(initFileToolBar(iconSize)); - m_toolBars.append(initViewToolBar(iconSize)); - m_toolBars.append(initEditToolBar(iconSize)); - m_toolBars.append(initNoteToolBar(iconSize)); - - setToolBarVisible(g_config->getToolBarChecked()); -} - -QToolBar *VMainWindow::initViewToolBar(QSize p_iconSize) -{ - m_viewToolBar = addToolBar(tr("View")); - m_viewToolBar->setObjectName("ViewToolBar"); - m_viewToolBar->setMovable(false); - if (p_iconSize.isValid()) { - m_viewToolBar->setIconSize(p_iconSize); - } - - QAction *fullScreenAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/fullscreen.svg"), - tr("Full Screen"), - this); - QString keySeq = g_config->getShortcutKeySequence("FullScreen"); - QKeySequence seq(keySeq); - if (!seq.isEmpty()) { - fullScreenAct->setText(tr("Full Screen\t%1").arg(VUtils::getShortcutText(keySeq))); - fullScreenAct->setShortcut(seq); - } - - fullScreenAct->setStatusTip(tr("Toggle full screen")); - connect(fullScreenAct, &QAction::triggered, - this, [this]() { - if (windowState() & Qt::WindowFullScreen) { - if (m_windowOldState & Qt::WindowMaximized) { - showMaximized(); - } else { - showNormal(); - } - } else { - showFullScreen(); - } - }); - - QAction *stayOnTopAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/stay_on_top.svg"), - tr("Stay On Top"), - this); - stayOnTopAct->setStatusTip(tr("Toggle stay-on-top")); - stayOnTopAct->setCheckable(true); - connect(stayOnTopAct, &QAction::triggered, - this, &VMainWindow::stayOnTop); - - QAction *menuBarAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/menubar.svg"), - tr("Menu Bar"), - this); - menuBarAct->setStatusTip(tr("Toggle menu bar")); - menuBarAct->setCheckable(true); - menuBarAct->setChecked(g_config->getMenuBarChecked()); - connect(menuBarAct, &QAction::triggered, - this, [this](bool p_checked) { - setMenuBarVisible(p_checked); - g_config->setMenuBarChecked(p_checked); - }); - - QMenu *viewMenu = new QMenu(this); - viewMenu->setToolTipsVisible(true); - viewMenu->addAction(fullScreenAct); - viewMenu->addAction(stayOnTopAct); - viewMenu->addAction(menuBarAct); - - expandViewAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/expand.svg"), - tr("Expand Edit Area"), - this); - VUtils::fixTextWithCaptainShortcut(expandViewAct, "ExpandMode"); - expandViewAct->setStatusTip(tr("Expand the edit area")); - expandViewAct->setCheckable(true); - expandViewAct->setMenu(viewMenu); - connect(expandViewAct, &QAction::triggered, - this, [this](bool p_checked) { - changePanelView(p_checked ? PanelViewState::ExpandMode - : PanelViewState::VerticalMode); - }); - - m_viewToolBar->addAction(expandViewAct); - - return m_viewToolBar; -} - -// Enable/disable all actions of @p_widget. -static void setActionsEnabled(QWidget *p_widget, bool p_enabled) -{ - Q_ASSERT(p_widget); - QList actions = p_widget->actions(); - for (auto const & act : actions) { - act->setEnabled(p_enabled); - } -} - -QToolBar *VMainWindow::initEditToolBar(QSize p_iconSize) -{ - m_editToolBar = addToolBar(tr("Edit Toolbar")); - m_editToolBar->setObjectName("EditToolBar"); - m_editToolBar->setMovable(false); - if (p_iconSize.isValid()) { - m_editToolBar->setIconSize(p_iconSize); - } - - m_editToolBar->addSeparator(); - - m_headingSequenceAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/heading_sequence.svg"), - tr("Heading Sequence"), - this); - m_headingSequenceAct->setStatusTip(tr("Enable heading sequence in current note in edit mode")); - m_headingSequenceAct->setCheckable(true); - connect(m_headingSequenceAct, &QAction::triggered, - this, [this](bool p_checked){ - if (isHeadingSequenceApplicable()) { - VMdTab *tab = dynamic_cast(m_curTab.data()); - Q_ASSERT(tab); - tab->enableHeadingSequence(p_checked); - } - }); - - m_editToolBar->addAction(m_headingSequenceAct); - - initHeadingButton(m_editToolBar); - - QAction *boldAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/bold.svg"), - tr("Bold\t%1").arg(VUtils::getShortcutText("Ctrl+B")), - this); - boldAct->setStatusTip(tr("Insert bold text or change selected text to bold")); - connect(boldAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::Bold); - } - }); - - m_editToolBar->addAction(boldAct); - - QAction *italicAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/italic.svg"), - tr("Italic\t%1").arg(VUtils::getShortcutText("Ctrl+I")), - this); - italicAct->setStatusTip(tr("Insert italic text or change selected text to italic")); - connect(italicAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::Italic); - } - }); - - m_editToolBar->addAction(italicAct); - - QAction *strikethroughAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/strikethrough.svg"), - tr("Strikethrough\t%1").arg(VUtils::getShortcutText("Ctrl+D")), - this); - strikethroughAct->setStatusTip(tr("Insert strikethrough text or change selected text to strikethroughed")); - connect(strikethroughAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::Strikethrough); - } - }); - - m_editToolBar->addAction(strikethroughAct); - - QAction *inlineCodeAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/inline_code.svg"), - tr("Inline Code\t%1").arg(VUtils::getShortcutText("Ctrl+;")), - this); - inlineCodeAct->setStatusTip(tr("Insert inline-code text or change selected text to inline-coded")); - connect(inlineCodeAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::InlineCode); - } - }); - - m_editToolBar->addAction(inlineCodeAct); - - QAction *codeBlockAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/code_block.svg"), - tr("Code Block\t%1").arg(VUtils::getShortcutText("Ctrl+M")), - this); - codeBlockAct->setStatusTip(tr("Insert fenced code block text or wrap selected text into a fenced code block")); - connect(codeBlockAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->decorateText(TextDecoration::CodeBlock); - } - }); - - m_editToolBar->addAction(codeBlockAct); - - QAction *tableAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/table.svg"), - tr("Table\t%1").arg(VUtils::getShortcutText("Ctrl+.")), - this); - tableAct->setStatusTip(tr("Insert a table")); - connect(tableAct, &QAction::triggered, - this, [this](){ - if (m_curTab) { - m_curTab->insertTable(); - } - }); - - m_editToolBar->addAction(tableAct); - - // Insert link. - QAction *insetLinkAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/link.svg"), - tr("Link\t%1").arg(VUtils::getShortcutText("Ctrl+L")), - this); - insetLinkAct->setStatusTip(tr("Insert a link")); - connect(insetLinkAct, &QAction::triggered, - this, [this]() { - if (m_curTab) { - m_curTab->insertLink(); - } - }); - - m_editToolBar->addAction(insetLinkAct); - - // Insert image. - QAction *insertImageAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/insert_image.svg"), - tr("Image\t%1").arg(VUtils::getShortcutText("Ctrl+'")), - this); - insertImageAct->setStatusTip(tr("Insert an image from file or URL")); - connect(insertImageAct, &QAction::triggered, - this, [this]() { - if (m_curTab) { - m_curTab->insertImage(); - } - }); - - m_editToolBar->addAction(insertImageAct); - - setActionsEnabled(m_editToolBar, false); - - return m_editToolBar; -} - -QToolBar *VMainWindow::initNoteToolBar(QSize p_iconSize) -{ - m_noteToolBar = addToolBar(tr("Note Toolbar")); - m_noteToolBar->setObjectName("NoteToolBar"); - m_noteToolBar->setMovable(false); - if (p_iconSize.isValid()) { - m_noteToolBar->setIconSize(p_iconSize); - } - - m_noteToolBar->addSeparator(); - - // Attachment. - m_attachmentList = new VAttachmentList(this); - m_attachmentBtn = new VButtonWithWidget(VIconUtils::toolButtonIcon(":/resources/icons/attachment.svg"), - "", - m_attachmentList, - this); - m_attachmentBtn->setBubbleColor(g_palette->color("bubble_fg"), - g_palette->color("bubble_bg")); - m_attachmentBtn->setToolTip(tr("Attachments (drag files here to add attachments)")); - m_attachmentBtn->setProperty("CornerBtn", true); - m_attachmentBtn->setFocusPolicy(Qt::NoFocus); - m_attachmentBtn->setEnabled(false); - - QAction *flashPageAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/flash_page.svg"), - tr("Flash Page"), - this); - flashPageAct->setStatusTip(tr("Open the Flash Page to edit")); - QString keySeq = g_config->getShortcutKeySequence("FlashPage"); - QKeySequence seq(keySeq); - if (!seq.isEmpty()) { - flashPageAct->setText(tr("Flash Page\t%1").arg(VUtils::getShortcutText(keySeq))); - flashPageAct->setShortcut(seq); - } - - connect(flashPageAct, &QAction::triggered, - this, &VMainWindow::openFlashPage); - - QAction *quickAccessAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/quick_access.svg"), - tr("Quick Access"), - this); - quickAccessAct->setStatusTip(tr("Open quick access note")); - keySeq = g_config->getShortcutKeySequence("QuickAccess"); - seq = QKeySequence(keySeq); - if (!seq.isEmpty()) { - quickAccessAct->setText(tr("Quick Access\t%1").arg(VUtils::getShortcutText(keySeq))); - quickAccessAct->setShortcut(seq); - } - - connect(quickAccessAct, &QAction::triggered, - this, &VMainWindow::openQuickAccess); - - QAction *universalEntryAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/universal_entry_tb.svg"), - tr("Universal Entry"), - this); - universalEntryAct->setStatusTip(tr("Activate Universal Entry")); - keySeq = g_config->getShortcutKeySequence("UniversalEntry"); - seq = QKeySequence(keySeq); - if (!seq.isEmpty()) { - universalEntryAct->setText(tr("Universal Entry\t%1").arg(VUtils::getShortcutText(keySeq))); - universalEntryAct->setShortcut(seq); - } - - connect(universalEntryAct, &QAction::triggered, - this, &VMainWindow::activateUniversalEntry); - - m_noteToolBar->addWidget(m_attachmentBtn); - m_noteToolBar->addAction(flashPageAct); - m_noteToolBar->addAction(quickAccessAct); - m_noteToolBar->addAction(universalEntryAct); - - return m_noteToolBar; -} - -QToolBar *VMainWindow::initFileToolBar(QSize p_iconSize) -{ - m_fileToolBar = addToolBar(tr("Note")); - m_fileToolBar->setObjectName("FileToolBar"); - m_fileToolBar->setMovable(false); - if (p_iconSize.isValid()) { - m_fileToolBar->setIconSize(p_iconSize); - } - - m_avatarBtn = new QPushButton("VNote", this); - m_avatarBtn->setProperty("AvatarBtn", true); - m_avatarBtn->setFocusPolicy(Qt::NoFocus); - m_avatarBtn->setToolTip(tr("Log In (Not Implemented Yet)")); - - newRootDirAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/create_rootdir_tb.svg"), - tr("New Root Folder"), - this); - newRootDirAct->setStatusTip(tr("Create a root folder in current notebook")); - connect(newRootDirAct, &QAction::triggered, - m_dirTree, &VDirectoryTree::newRootDirectory); - - newNoteAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/create_note_tb.svg"), - tr("New Note"), this); - newNoteAct->setStatusTip(tr("Create a note in current folder")); - QString keySeq = g_config->getShortcutKeySequence("NewNote"); - QKeySequence seq(keySeq); - if (!seq.isEmpty()) { - newNoteAct->setText(tr("New Note\t%1").arg(VUtils::getShortcutText(keySeq))); - newNoteAct->setShortcut(seq); - } - - connect(newNoteAct, &QAction::triggered, - m_fileList, &VFileList::newFile); - - noteInfoAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/note_info_tb.svg"), - tr("Note Info"), - this); - VUtils::fixTextWithCaptainShortcut(noteInfoAct, "CurrentNoteInfo"); - noteInfoAct->setStatusTip(tr("View and edit current note's information")); - connect(noteInfoAct, &QAction::triggered, - this, &VMainWindow::curEditFileInfo); - - deleteNoteAct = new QAction(VIconUtils::toolButtonDangerIcon(":/resources/icons/delete_note_tb.svg"), - tr("Delete Note"), this); - deleteNoteAct->setStatusTip(tr("Delete current note")); - connect(deleteNoteAct, &QAction::triggered, - this, &VMainWindow::deleteCurNote); - - m_editReadAct = new QAction(this); - connect(m_editReadAct, &QAction::triggered, - this, &VMainWindow::toggleEditReadMode); - - m_discardExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/discard_exit.svg"), - tr("Discard Changes And Read"), - this); - VUtils::fixTextWithCaptainShortcut(m_discardExitAct, "DiscardAndRead"); - m_discardExitAct->setStatusTip(tr("Discard changes and exit edit mode")); - connect(m_discardExitAct, &QAction::triggered, - this, [this]() { - m_editArea->readFile(true); - }); - - updateEditReadAct(NULL); - - saveNoteAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/save_note.svg"), - tr("Save"), this); - saveNoteAct->setStatusTip(tr("Save changes to current note")); - keySeq = g_config->getShortcutKeySequence("SaveNote"); - seq = QKeySequence(keySeq); - if (!seq.isEmpty()) { - saveNoteAct->setText(tr("Save\t%1").arg(VUtils::getShortcutText(keySeq))); - saveNoteAct->setShortcut(seq); - } - - connect(saveNoteAct, &QAction::triggered, - m_editArea, &VEditArea::saveFile); - - newRootDirAct->setEnabled(false); - newNoteAct->setEnabled(false); - noteInfoAct->setEnabled(false); - deleteNoteAct->setEnabled(false); - m_editReadAct->setEnabled(false); - m_discardExitAct->setEnabled(false); - saveNoteAct->setEnabled(false); - - m_fileToolBar->addWidget(m_avatarBtn); - m_fileToolBar->addAction(newRootDirAct); - m_fileToolBar->addAction(newNoteAct); - m_fileToolBar->addAction(deleteNoteAct); - m_fileToolBar->addAction(noteInfoAct); - m_fileToolBar->addAction(m_editReadAct); - m_fileToolBar->addAction(m_discardExitAct); - m_fileToolBar->addAction(saveNoteAct); - - return m_fileToolBar; -} - -void VMainWindow::initMenuBar() -{ - initFileMenu(); - initEditMenu(); - initViewMenu(); - initMarkdownMenu(); -#if defined(Q_OS_WIN) - initSyncMenu(); -#endif - initHelpMenu(); - - setMenuBarVisible(g_config->getMenuBarChecked()); -} - -void VMainWindow::initHelpMenu() -{ - QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->setToolTipsVisible(true); - -#if defined(QT_NO_DEBUG) - QAction *logAct = new QAction(tr("View &Log"), this); - logAct->setToolTip(tr("View VNote's debug log (%1)").arg(g_config->getLogFilePath())); - connect(logAct, &QAction::triggered, - this, [](){ - QUrl url = QUrl::fromLocalFile(g_config->getLogFilePath()); - QDesktopServices::openUrl(url); - }); -#endif - - QAction *shortcutAct = new QAction(tr("&Shortcuts Help"), this); - shortcutAct->setToolTip(tr("View information about shortcut keys")); - VUtils::fixTextWithCaptainShortcut(shortcutAct, "ShortcutsHelp"); - connect(shortcutAct, &QAction::triggered, - this, &VMainWindow::shortcutsHelp); - - QAction *mdGuideAct = new QAction(tr("&Markdown Guide"), this); - mdGuideAct->setToolTip(tr("A quick guide of Markdown syntax")); - connect(mdGuideAct, &QAction::triggered, - this, [this](){ - QString docFile = VUtils::getDocFile(VNote::c_markdownGuideDocFile); - VFile *file = vnote->getFile(docFile, true); - m_editArea->openFile(file, OpenFileMode::Read); - }); - - QAction *docAct = new QAction(tr("&Documentation"), this); - docAct->setToolTip(tr("View VNote's documentation")); - connect(docAct, &QAction::triggered, - this, []() { - QString url("https://tamlok.github.io/vnote"); - QDesktopServices::openUrl(url); - }); - - QAction *donateAct = new QAction(tr("Do&nate"), this); - donateAct->setToolTip(tr("Donate to VNote or view the donate list")); - connect(donateAct, &QAction::triggered, - this, []() { - QString url("https://tamlok.github.io/vnote/en_us/#!donate.md"); - QDesktopServices::openUrl(url); - }); - - QAction *updateAct = new QAction(tr("Check For &Updates"), this); - updateAct->setToolTip(tr("Check for updates of VNote")); - connect(updateAct, &QAction::triggered, - this, [this](){ - VUpdater updater(this); - updater.exec(); - }); - - QAction *starAct = new QAction(tr("Star VNote on &GitHub"), this); - starAct->setToolTip(tr("Give a star to VNote on GitHub project")); - connect(starAct, &QAction::triggered, - this, []() { - QString url("https://github.com/tamlok/vnote"); - QDesktopServices::openUrl(url); - }); - - QAction *feedbackAct = new QAction(tr("&Feedback"), this); - feedbackAct->setToolTip(tr("Open an issue on GitHub")); - connect(feedbackAct, &QAction::triggered, - this, []() { - QString url("https://github.com/tamlok/vnote/issues"); - QDesktopServices::openUrl(url); - }); - - QAction *aboutAct = new QAction(tr("&About VNote"), this); - aboutAct->setToolTip(tr("View information about VNote")); - aboutAct->setMenuRole(QAction::AboutRole); - connect(aboutAct, &QAction::triggered, - this, &VMainWindow::aboutMessage); - - QAction *aboutQtAct = new QAction(tr("About &Qt"), this); - aboutQtAct->setToolTip(tr("View information about Qt")); - aboutQtAct->setMenuRole(QAction::AboutQtRole); - connect(aboutQtAct, &QAction::triggered, - qApp, &QApplication::aboutQt); - - helpMenu->addAction(shortcutAct); - helpMenu->addAction(mdGuideAct); - helpMenu->addAction(docAct); - helpMenu->addAction(donateAct); - helpMenu->addAction(updateAct); - helpMenu->addAction(starAct); - helpMenu->addAction(feedbackAct); - -#if defined(QT_NO_DEBUG) - helpMenu->addAction(logAct); -#endif - - helpMenu->addAction(aboutQtAct); - helpMenu->addAction(aboutAct); -} - -void VMainWindow::initMarkdownMenu() -{ - QMenu *markdownMenu = menuBar()->addMenu(tr("&Markdown")); - markdownMenu->setToolTipsVisible(true); - - initConverterMenu(markdownMenu); - - initMarkdownitOptionMenu(markdownMenu); - - markdownMenu->addSeparator(); - - initRenderStyleMenu(markdownMenu); - - initRenderBackgroundMenu(markdownMenu); - - initCodeBlockStyleMenu(markdownMenu); - - QAction *constrainImageAct = new QAction(tr("Constrain The Width Of Images"), this); - constrainImageAct->setToolTip(tr("Constrain the width of images to the window in read mode (re-open current tabs to make it work)")); - constrainImageAct->setCheckable(true); - connect(constrainImageAct, &QAction::triggered, - this, &VMainWindow::enableImageConstraint); - markdownMenu->addAction(constrainImageAct); - constrainImageAct->setChecked(g_config->getEnableImageConstraint()); - - QAction *imageCaptionAct = new QAction(tr("Enable Image Caption"), this); - imageCaptionAct->setToolTip(tr("Center the images and display the alt text as caption (re-open current tabs to make it work)")); - imageCaptionAct->setCheckable(true); - connect(imageCaptionAct, &QAction::triggered, - this, &VMainWindow::enableImageCaption); - markdownMenu->addAction(imageCaptionAct); - imageCaptionAct->setChecked(g_config->getEnableImageCaption()); - - markdownMenu->addSeparator(); - - initMarkdownExtensionMenu(markdownMenu); - - markdownMenu->addSeparator(); - - QAction *codeBlockAct = new QAction(tr("Highlight Code Blocks In Edit Mode"), this); - codeBlockAct->setToolTip(tr("Enable syntax highlight within code blocks in edit mode")); - codeBlockAct->setCheckable(true); - connect(codeBlockAct, &QAction::triggered, - this, &VMainWindow::enableCodeBlockHighlight); - markdownMenu->addAction(codeBlockAct); - codeBlockAct->setChecked(g_config->getEnableCodeBlockHighlight()); - - QAction *lineNumberAct = new QAction(tr("Display Line Number In Code Blocks"), this); - lineNumberAct->setToolTip(tr("Enable line number in code blocks in read mode")); - lineNumberAct->setCheckable(true); - connect(lineNumberAct, &QAction::triggered, - this, [](bool p_checked){ - g_config->setEnableCodeBlockLineNumber(p_checked); - }); - markdownMenu->addAction(lineNumberAct); - lineNumberAct->setChecked(g_config->getEnableCodeBlockLineNumber()); - - QAction *previewImageAct = new QAction(tr("In-Place Preview"), this); - previewImageAct->setToolTip(tr("Enable in-place preview (images, diagrams, and formulas) in edit mode (re-open current tabs to make it work)")); - previewImageAct->setCheckable(true); - connect(previewImageAct, &QAction::triggered, - this, &VMainWindow::enableImagePreview); - markdownMenu->addAction(previewImageAct); - previewImageAct->setChecked(g_config->getEnablePreviewImages()); - - QAction *previewWidthAct = new QAction(tr("Constrain The Width Of In-Place Preview"), this); - previewWidthAct->setToolTip(tr("Constrain the width of in-place preview to the edit window in edit mode")); - previewWidthAct->setCheckable(true); - connect(previewWidthAct, &QAction::triggered, - this, &VMainWindow::enableImagePreviewConstraint); - markdownMenu->addAction(previewWidthAct); - previewWidthAct->setChecked(g_config->getEnablePreviewImageConstraint()); -} - -void VMainWindow::initSyncMenu() -{ - m_syncMenu = menuBar()->addMenu(tr("Git &Sync")); - m_syncMenu->setToolTipsVisible(true); - QAction* uploadAction = new QAction(tr("&Upload"), this); - uploadAction->setToolTip(tr("Upload notes to Git repo")); - connect(uploadAction, &QAction::triggered, this, &VMainWindow::upload); - m_syncMenu->addAction(uploadAction); - - QAction* downloadAction = new QAction(tr("&Download"), this); - downloadAction->setToolTip(tr("Download notes from Git repo")); - connect(downloadAction, &QAction::triggered, this, &VMainWindow::download); - m_syncMenu->addAction(downloadAction); -} - -void VMainWindow::upload() -{ - QVector& noteBooks = vnote->getNotebooks(); - for (QVector::iterator i = noteBooks.begin(); i < noteBooks.end(); i++) - { - QString notebookDir = (*i)->getPath(); - QString notebookName = (*i)->getName(); - if ((*i)->isOpened()) - { - qDebug() << "notebook name: " << notebookName << "notebook path: " << notebookDir; - int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"), - tr("Are you sure to close opened notes"), - tr("VNote will close all the opened notes before upload."), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - this); - switch (ret) - { - case QMessageBox::Ok: - this->m_editArea->closeAllFiles(true); - break; - - case QMessageBox::Cancel: - return; - - default: - return; - } - m_git->setDir(notebookDir); - m_git->upload(); - break; - } - } -} - -void VMainWindow::download() -{ - QVector ¬eBooks = vnote->getNotebooks(); - for (QVector::iterator i = noteBooks.begin(); i < noteBooks.end(); i++) - { - QString notebookDir = (*i)->getPath(); - QString notebookName = (*i)->getName(); - if ((*i)->isOpened()) - { - qDebug() << "notebook name: " << notebookName << "notebook path: " << notebookDir; - m_git->setDir(notebookDir); - m_git->download(); - break; - } - } -} - -void VMainWindow::initViewMenu() -{ - m_viewMenu = menuBar()->addMenu(tr("&View")); - m_viewMenu->setToolTipsVisible(true); - - m_toolBarAct = new QAction(tr("Tool Bar"), this); - m_toolBarAct->setToolTip(tr("Toogle the tool bar")); - VUtils::fixTextWithCaptainShortcut(m_toolBarAct, "ToolBar"); - m_toolBarAct->setCheckable(true); - m_toolBarAct->setChecked(g_config->getToolBarChecked()); - connect(m_toolBarAct, &QAction::triggered, - this, [this] (bool p_checked) { - g_config->setToolBarChecked(p_checked); - setToolBarVisible(p_checked); - }); - - m_viewMenu->addAction(m_toolBarAct); -} - -void VMainWindow::initFileMenu() -{ - QMenu *fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->setToolTipsVisible(true); - - // Open external files. - QAction *openAct = new QAction(tr("&Open"), this); - openAct->setToolTip(tr("Open external file to edit")); - connect(openAct, &QAction::triggered, - this, [this](){ - static QString lastPath = QDir::homePath(); - QStringList files = QFileDialog::getOpenFileNames(this, - tr("Select External Files To Open"), - lastPath); - - if (files.isEmpty()) { - return; - } - - // Update lastPath - lastPath = QFileInfo(files[0]).path(); - - openFiles(VUtils::filterFilePathsToOpen(files), - false, - g_config->getNoteOpenMode(), - false, - false); - }); - - fileMenu->addAction(openAct); - - // Import notes from files. - m_importNoteAct = newAction(VIconUtils::menuIcon(":/resources/icons/import_note.svg"), - tr("&New Notes From Files"), this); - m_importNoteAct->setToolTip(tr("Create notes from external files in current folder " - "(will copy files if they do not locate in current folder)")); - connect(m_importNoteAct, &QAction::triggered, - this, &VMainWindow::importNoteFromFile); - m_importNoteAct->setEnabled(false); - - fileMenu->addAction(m_importNoteAct); - - fileMenu->addSeparator(); - - // Export as PDF. - m_exportAct = new QAction(tr("E&xport"), this); - m_exportAct->setToolTip(tr("Export notes")); - VUtils::fixTextWithCaptainShortcut(m_exportAct, "Export"); - connect(m_exportAct, &QAction::triggered, - this, &VMainWindow::handleExportAct); - - fileMenu->addAction(m_exportAct); - - // Print. - m_printAct = new QAction(VIconUtils::menuIcon(":/resources/icons/print.svg"), - tr("&Print"), this); - m_printAct->setToolTip(tr("Print current note")); - connect(m_printAct, &QAction::triggered, - this, &VMainWindow::printNote); - m_printAct->setEnabled(false); - - fileMenu->addAction(m_printAct); - - fileMenu->addSeparator(); - - // Themes. - initThemeMenu(fileMenu); - - // Settings. - QAction *settingsAct = newAction(VIconUtils::menuIcon(":/resources/icons/settings.svg"), - tr("&Settings"), this); - settingsAct->setToolTip(tr("View and change settings for VNote")); - settingsAct->setMenuRole(QAction::PreferencesRole); - connect(settingsAct, &QAction::triggered, - this, &VMainWindow::viewSettings); - - fileMenu->addAction(settingsAct); - - QAction *openConfigAct = new QAction(tr("Open Configuration Folder"), this); - openConfigAct->setToolTip(tr("Open configuration folder of VNote")); - connect(openConfigAct, &QAction::triggered, - this, [](){ - QUrl url = QUrl::fromLocalFile(g_config->getConfigFolder()); - QDesktopServices::openUrl(url); - }); - - fileMenu->addAction(openConfigAct); - - QAction *customShortcutAct = new QAction(tr("Customize Shortcuts"), this); - customShortcutAct->setToolTip(tr("Customize some standard shortcuts")); - connect(customShortcutAct, &QAction::triggered, - this, &VMainWindow::customShortcut); - - fileMenu->addAction(customShortcutAct); - - fileMenu->addSeparator(); - - // Restart. - QAction *restartAct = new QAction(tr("Restart"), this); - connect(restartAct, &QAction::triggered, - this, &VMainWindow::restartVNote); - fileMenu->addAction(restartAct); - - // Exit. - QAction *exitAct = new QAction(tr("&Quit"), this); - exitAct->setToolTip(tr("Quit VNote")); - exitAct->setShortcut(QKeySequence("Ctrl+Q")); - exitAct->setMenuRole(QAction::QuitRole); - connect(exitAct, &QAction::triggered, - this, &VMainWindow::quitApp); - - fileMenu->addAction(exitAct); -} - -void VMainWindow::quitApp() -{ - m_requestQuit = true; - close(); -} - -void VMainWindow::initEditMenu() -{ - QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->setToolTipsVisible(true); - - // Find/Replace. - m_findReplaceAct = newAction(VIconUtils::menuIcon(":/resources/icons/find_replace.svg"), - tr("Find/Replace"), this); - m_findReplaceAct->setToolTip(tr("Open Find/Replace dialog to search in current note")); - QString keySeq = g_config->getShortcutKeySequence("Find"); - qDebug() << "set Find shortcut to" << keySeq; - m_findReplaceAct->setShortcut(QKeySequence(keySeq)); - connect(m_findReplaceAct, &QAction::triggered, - this, &VMainWindow::openFindDialog); - - QAction *advFindAct = new QAction(tr("Advanced Find"), this); - advFindAct->setToolTip(tr("Advanced find within VNote")); - keySeq = g_config->getShortcutKeySequence("AdvancedFind"); - qDebug() << "set AdvancedFind shortcut to" << keySeq; - advFindAct->setShortcut(QKeySequence(keySeq)); - connect(advFindAct, &QAction::triggered, - this, [this]() { - m_searchDock->setVisible(true); - m_searcher->focusToSearch(); - }); - - m_findNextAct = new QAction(tr("Find Next"), this); - m_findNextAct->setToolTip(tr("Find next occurence")); - keySeq = g_config->getShortcutKeySequence("FindNext"); - qDebug() << "set FindNext shortcut to" << keySeq; - m_findNextAct->setShortcut(QKeySequence(keySeq)); - connect(m_findNextAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(findNext())); - - m_findPreviousAct = new QAction(tr("Find Previous"), this); - m_findPreviousAct->setToolTip(tr("Find previous occurence")); - keySeq = g_config->getShortcutKeySequence("FindPrevious"); - qDebug() << "set FindPrevious shortcut to" << keySeq; - m_findPreviousAct->setShortcut(QKeySequence(keySeq)); - connect(m_findPreviousAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(findPrevious())); - - m_replaceAct = new QAction(tr("Replace"), this); - m_replaceAct->setToolTip(tr("Replace current occurence")); - connect(m_replaceAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(replace())); - - m_replaceFindAct = new QAction(tr("Replace && Find"), this); - m_replaceFindAct->setToolTip(tr("Replace current occurence and find the next one")); - connect(m_replaceFindAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(replaceFind())); - - m_replaceAllAct = new QAction(tr("Replace All"), this); - m_replaceAllAct->setToolTip(tr("Replace all occurences in current note")); - connect(m_replaceAllAct, SIGNAL(triggered(bool)), - m_findReplaceDialog, SLOT(replaceAll())); - - QAction *searchedWordAct = new QAction(tr("Highlight Searched Pattern"), this); - searchedWordAct->setToolTip(tr("Highlight all occurences of searched pattern")); - searchedWordAct->setCheckable(true); - connect(searchedWordAct, &QAction::triggered, - this, &VMainWindow::changeHighlightSearchedWord); - - // Expand Tab into spaces. - QAction *expandTabAct = new QAction(tr("&Expand Tab"), this); - expandTabAct->setToolTip(tr("Expand entered Tab to spaces")); - expandTabAct->setCheckable(true); - connect(expandTabAct, &QAction::triggered, - this, &VMainWindow::changeExpandTab); - - // Tab stop width. - QActionGroup *tabStopWidthAct = new QActionGroup(this); - QAction *twoSpaceTabAct = new QAction(tr("2 Spaces"), tabStopWidthAct); - twoSpaceTabAct->setToolTip(tr("Expand Tab to 2 spaces")); - twoSpaceTabAct->setCheckable(true); - twoSpaceTabAct->setData(2); - QAction *fourSpaceTabAct = new QAction(tr("4 Spaces"), tabStopWidthAct); - fourSpaceTabAct->setToolTip(tr("Expand Tab to 4 spaces")); - fourSpaceTabAct->setCheckable(true); - fourSpaceTabAct->setData(4); - QAction *eightSpaceTabAct = new QAction(tr("8 Spaces"), tabStopWidthAct); - eightSpaceTabAct->setToolTip(tr("Expand Tab to 8 spaces")); - eightSpaceTabAct->setCheckable(true); - eightSpaceTabAct->setData(8); - connect(tabStopWidthAct, &QActionGroup::triggered, - this, &VMainWindow::setTabStopWidth); - - // Auto Indent. - m_autoIndentAct = new QAction(tr("Auto Indent"), this); - m_autoIndentAct->setToolTip(tr("Indent automatically when inserting a new line")); - m_autoIndentAct->setCheckable(true); - connect(m_autoIndentAct, &QAction::triggered, - this, &VMainWindow::changeAutoIndent); - - // Auto List. - QAction *autoListAct = new QAction(tr("Auto List"), this); - autoListAct->setToolTip(tr("Continue the list automatically when inserting a new line")); - autoListAct->setCheckable(true); - connect(autoListAct, &QAction::triggered, - this, &VMainWindow::changeAutoList); - - // Highlight current cursor line. - QAction *cursorLineAct = new QAction(tr("Highlight Cursor Line"), this); - cursorLineAct->setToolTip(tr("Highlight current cursor line")); - cursorLineAct->setCheckable(true); - connect(cursorLineAct, &QAction::triggered, - this, &VMainWindow::changeHighlightCursorLine); - - // Highlight selected word. - QAction *selectedWordAct = new QAction(tr("Highlight Selected Words"), this); - selectedWordAct->setToolTip(tr("Highlight all occurences of selected words")); - selectedWordAct->setCheckable(true); - connect(selectedWordAct, &QAction::triggered, - this, &VMainWindow::changeHighlightSelectedWord); - - // Highlight trailing space. - QAction *trailingSapceAct = new QAction(tr("Highlight Trailing Spaces"), this); - trailingSapceAct->setToolTip(tr("Highlight all the spaces at the end of a line")); - trailingSapceAct->setCheckable(true); - connect(trailingSapceAct, &QAction::triggered, - this, &VMainWindow::changeHighlightTrailingSapce); - - // Highlight tab. - QAction *tabAct = new QAction(tr("Highlight Tabs"), this); - tabAct->setToolTip(tr("Highlight all the tabs")); - tabAct->setCheckable(true); - connect(tabAct, &QAction::triggered, - this, [](bool p_checked) { - g_config->setEnableTabHighlight(p_checked); - }); - - QMenu *findReplaceMenu = editMenu->addMenu(tr("Find/Replace")); - findReplaceMenu->setToolTipsVisible(true); - findReplaceMenu->addAction(m_findReplaceAct); - findReplaceMenu->addAction(advFindAct); - findReplaceMenu->addSeparator(); - findReplaceMenu->addAction(m_findNextAct); - findReplaceMenu->addAction(m_findPreviousAct); - findReplaceMenu->addAction(m_replaceAct); - findReplaceMenu->addAction(m_replaceFindAct); - findReplaceMenu->addAction(m_replaceAllAct); - findReplaceMenu->addSeparator(); - findReplaceMenu->addAction(searchedWordAct); - searchedWordAct->setChecked(g_config->getHighlightSearchedWord()); - - m_findReplaceAct->setEnabled(false); - m_findNextAct->setEnabled(false); - m_findPreviousAct->setEnabled(false); - m_replaceAct->setEnabled(false); - m_replaceFindAct->setEnabled(false); - m_replaceAllAct->setEnabled(false); - - editMenu->addSeparator(); - editMenu->addAction(expandTabAct); - if (g_config->getIsExpandTab()) { - expandTabAct->setChecked(true); - } else { - expandTabAct->setChecked(false); - } - - QMenu *tabStopWidthMenu = editMenu->addMenu(tr("Tab Stop Width")); - tabStopWidthMenu->setToolTipsVisible(true); - tabStopWidthMenu->addAction(twoSpaceTabAct); - tabStopWidthMenu->addAction(fourSpaceTabAct); - tabStopWidthMenu->addAction(eightSpaceTabAct); - int tabStopWidth = g_config->getTabStopWidth(); - switch (tabStopWidth) { - case 2: - twoSpaceTabAct->setChecked(true); - break; - case 4: - fourSpaceTabAct->setChecked(true); - break; - case 8: - eightSpaceTabAct->setChecked(true); - break; - default: - qWarning() << "unsupported tab stop width" << tabStopWidth << "in config"; - } - - editMenu->addAction(m_autoIndentAct); - m_autoIndentAct->setChecked(g_config->getAutoIndent()); - - editMenu->addAction(autoListAct); - if (g_config->getAutoList()) { - // Let the trigger handler to trigger m_autoIndentAct, too. - autoListAct->trigger(); - } - Q_ASSERT(!(autoListAct->isChecked() && !m_autoIndentAct->isChecked())); - - editMenu->addSeparator(); - - initEditorStyleMenu(editMenu); - - initEditorBackgroundMenu(editMenu); - - initEditorLineNumberMenu(editMenu); - - editMenu->addAction(cursorLineAct); - cursorLineAct->setChecked(g_config->getHighlightCursorLine()); - - editMenu->addAction(selectedWordAct); - selectedWordAct->setChecked(g_config->getHighlightSelectedWord()); - - editMenu->addAction(trailingSapceAct); - trailingSapceAct->setChecked(g_config->getEnableTrailingSpaceHighlight()); - - editMenu->addAction(tabAct); - tabAct->setChecked(g_config->getEnableTabHighlight()); - - initAutoScrollCursorLineMenu(editMenu); - - // Smart table. - QAction *smartTableAct = new QAction(tr("Smart Table"), this); - smartTableAct->setToolTip(tr("Format table automatically")); - smartTableAct->setCheckable(true); - connect(smartTableAct, &QAction::triggered, - this, [](bool p_checked) { - g_config->setEnableSmartTable(p_checked); - }); - editMenu->addAction(smartTableAct); - smartTableAct->setChecked(g_config->getEnableSmartTable()); -} - -void VMainWindow::initDockWindows() -{ - setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::West); - setTabPosition(Qt::RightDockWidgetArea, QTabWidget::East); - setTabPosition(Qt::TopDockWidgetArea, QTabWidget::North); - setTabPosition(Qt::BottomDockWidgetArea, QTabWidget::North); - - setDockNestingEnabled(true); - - initToolsDock(); - initSearchDock(); -} - -void VMainWindow::initToolsDock() -{ - m_toolDock = new QDockWidget(tr("Tools"), this); - m_toolDock->setObjectName("ToolsDock"); - m_toolDock->setAllowedAreas(Qt::AllDockWidgetAreas); - - // Outline tree. - outline = new VOutline(this); - connect(m_editArea, &VEditArea::outlineChanged, - outline, &VOutline::updateOutline); - connect(m_editArea, &VEditArea::currentHeaderChanged, - outline, &VOutline::updateCurrentHeader); - connect(outline, &VOutline::outlineItemActivated, - m_editArea, &VEditArea::scrollToHeader); - - // Snippets. - m_snippetList = new VSnippetList(this); - - // Cart. - m_cart = new VCart(this); - - m_toolBox = new VToolBox(this); - m_toolBox->addItem(outline, - ":/resources/icons/outline.svg", - tr("Outline")); - m_toolBox->addItem(m_snippetList, - ":/resources/icons/snippets.svg", - tr("Snippets")); - m_toolBox->addItem(m_cart, - ":/resources/icons/cart.svg", - tr("Cart")); - - m_toolDock->setWidget(m_toolBox); - addDockWidget(Qt::RightDockWidgetArea, m_toolDock); - - QAction *toggleAct = m_toolDock->toggleViewAction(); - toggleAct->setToolTip(tr("Toggle the tools dock widget")); - VUtils::fixTextWithCaptainShortcut(toggleAct, "ToolsDock"); - - m_viewMenu->addAction(toggleAct); -} - -void VMainWindow::initSearchDock() -{ - m_searchDock = new QDockWidget(tr("Search"), this); - m_searchDock->setObjectName("SearchDock"); - m_searchDock->setAllowedAreas(Qt::AllDockWidgetAreas); - - m_searcher = new VSearcher(this); - - m_searchDock->setWidget(m_searcher); - - addDockWidget(Qt::RightDockWidgetArea, m_searchDock); - - QAction *toggleAct = m_searchDock->toggleViewAction(); - toggleAct->setToolTip(tr("Toggle the search dock widget")); - VUtils::fixTextWithCaptainShortcut(toggleAct, "SearchDock"); - - m_viewMenu->addAction(toggleAct); -} - -void VMainWindow::importNoteFromFile() -{ - static QString lastPath = QDir::homePath(); - QStringList files = QFileDialog::getOpenFileNames(this, - tr("Select Files To Create Notes"), - lastPath); - if (files.isEmpty()) { - return; - } - - // Update lastPath - lastPath = QFileInfo(files[0]).path(); - - QString msg; - if (!m_fileList->importFiles(files, &msg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to create notes for all the files."), - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } else { - int cnt = files.size(); - showStatusMessage(tr("%1 %2 created from external files") - .arg(cnt) - .arg(cnt > 1 ? tr("notes") : tr("note"))); - } -} - -void VMainWindow::changeMarkdownConverter(QAction *action) -{ - if (!action) { - return; - } - - MarkdownConverterType type = (MarkdownConverterType)action->data().toInt(); - - g_config->setMarkdownConverterType(type); -} - -void VMainWindow::aboutMessage() -{ - QString info = tr("VNote"); - info += "
    "; - info += tr("Version: %1").arg(VConfigManager::c_version); - info += "
    "; - info += tr("Author: Le Tan (tamlok)"); - info += "

    "; - info += tr("VNote is a free and open source note-taking application that knows programmers and Markdown better."); - info += "

    "; - info += tr("Please visit VNote for more information."); - QMessageBox::about(this, tr("About VNote"), info); -} - -void VMainWindow::changeExpandTab(bool checked) -{ - g_config->setIsExpandTab(checked); -} - -void VMainWindow::enableMermaid(bool p_checked) -{ - g_config->setEnableMermaid(p_checked); - VUtils::promptForReopen(this); -} - -void VMainWindow::enableMathjax(bool p_checked) -{ - g_config->setEnableMathjax(p_checked); - VUtils::promptForReopen(this); -} - -void VMainWindow::changeHighlightCursorLine(bool p_checked) -{ - g_config->setHighlightCursorLine(p_checked); -} - -void VMainWindow::changeHighlightSelectedWord(bool p_checked) -{ - g_config->setHighlightSelectedWord(p_checked); -} - -void VMainWindow::changeHighlightSearchedWord(bool p_checked) -{ - g_config->setHighlightSearchedWord(p_checked); -} - -void VMainWindow::changeHighlightTrailingSapce(bool p_checked) -{ - g_config->setEnableTrailingSapceHighlight(p_checked); -} - -void VMainWindow::setTabStopWidth(QAction *action) -{ - if (!action) { - return; - } - g_config->setTabStopWidth(action->data().toInt()); -} - -void VMainWindow::setEditorBackgroundColor(QAction *action) -{ - if (!action) { - return; - } - - g_config->setCurBackgroundColor(action->data().toString()); -} - -void VMainWindow::initConverterMenu(QMenu *p_menu) -{ - QMenu *converterMenu = p_menu->addMenu(tr("&Renderer")); - converterMenu->setToolTipsVisible(true); - - QActionGroup *converterAct = new QActionGroup(this); - QAction *markedAct = new QAction(tr("Marked"), converterAct); - markedAct->setToolTip(tr("Use Marked to convert Markdown to HTML (re-open current tabs to make it work)")); - markedAct->setCheckable(true); - markedAct->setData(int(MarkdownConverterType::Marked)); - - QAction *hoedownAct = new QAction(tr("Hoedown"), converterAct); - hoedownAct->setToolTip(tr("Use Hoedown to convert Markdown to HTML (re-open current tabs to make it work)")); - hoedownAct->setCheckable(true); - hoedownAct->setData(int(MarkdownConverterType::Hoedown)); - - QAction *markdownitAct = new QAction(tr("Markdown-it"), converterAct); - markdownitAct->setToolTip(tr("Use Markdown-it to convert Markdown to HTML (re-open current tabs to make it work)")); - markdownitAct->setCheckable(true); - markdownitAct->setData(int(MarkdownConverterType::MarkdownIt)); - - QAction *showdownAct = new QAction(tr("Showdown"), converterAct); - showdownAct->setToolTip(tr("Use Showdown to convert Markdown to HTML (re-open current tabs to make it work)")); - showdownAct->setCheckable(true); - showdownAct->setData(int(MarkdownConverterType::Showdown)); - - connect(converterAct, &QActionGroup::triggered, - this, &VMainWindow::changeMarkdownConverter); - converterMenu->addAction(hoedownAct); - converterMenu->addAction(markedAct); - converterMenu->addAction(markdownitAct); - converterMenu->addAction(showdownAct); - - MarkdownConverterType converterType = g_config->getMdConverterType(); - switch (converterType) { - case MarkdownConverterType::Marked: - markedAct->setChecked(true); - break; - - case MarkdownConverterType::Hoedown: - hoedownAct->setChecked(true); - break; - - case MarkdownConverterType::MarkdownIt: - markdownitAct->setChecked(true); - break; - - case MarkdownConverterType::Showdown: - showdownAct->setChecked(true); - break; - - default: - Q_ASSERT(false); - } -} - -void VMainWindow::initMarkdownitOptionMenu(QMenu *p_menu) -{ - QMenu *optMenu = p_menu->addMenu(tr("Markdown-it Options")); - optMenu->setToolTipsVisible(true); - - const MarkdownitOption &opt = g_config->getMarkdownitOption(); - - QAction *htmlAct = new QAction(tr("HTML"), this); - htmlAct->setToolTip(tr("Enable HTML tags in source (re-open current tabs to make it work)")); - htmlAct->setCheckable(true); - htmlAct->setChecked(opt.m_html); - connect(htmlAct, &QAction::triggered, - this, [](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_html = p_checked; - g_config->setMarkdownitOption(opt); - }); - - QAction *breaksAct = new QAction(tr("Line Break"), this); - breaksAct->setToolTip(tr("Convert '\\n' in paragraphs into line break (re-open current tabs to make it work)")); - breaksAct->setCheckable(true); - breaksAct->setChecked(opt.m_breaks); - connect(breaksAct, &QAction::triggered, - this, [](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_breaks = p_checked; - g_config->setMarkdownitOption(opt); - }); - - QAction *linkifyAct = new QAction(tr("Linkify"), this); - linkifyAct->setToolTip(tr("Convert URL-like text into links (re-open current tabs to make it work)")); - linkifyAct->setCheckable(true); - linkifyAct->setChecked(opt.m_linkify); - connect(linkifyAct, &QAction::triggered, - this, [](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_linkify = p_checked; - g_config->setMarkdownitOption(opt); - }); - - QAction *supAct = new QAction(tr("Superscript"), this); - supAct->setToolTip(tr("Enable superscript like ^vnote^ (re-open current tabs to make it work)")); - supAct->setCheckable(true); - supAct->setChecked(opt.m_sup); - connect(supAct, &QAction::triggered, - this, [](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_sup = p_checked; - g_config->setMarkdownitOption(opt); - }); - - QAction *subAct = new QAction(tr("Subscript"), this); - subAct->setToolTip(tr("Enable subscript like ~vnote~ (re-open current tabs to make it work)")); - subAct->setCheckable(true); - subAct->setChecked(opt.m_sub); - connect(subAct, &QAction::triggered, - this, [](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_sub = p_checked; - g_config->setMarkdownitOption(opt); - }); - - QAction *metadataAct = new QAction(tr("Metadata Aware"), this); - metadataAct->setToolTip(tr("Be aware of metadata in YAML format (re-open current tabs to make it work)")); - metadataAct->setCheckable(true); - metadataAct->setChecked(opt.m_metadata); - connect(metadataAct, &QAction::triggered, - this, [](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_metadata = p_checked; - g_config->setMarkdownitOption(opt); - }); - - QAction *emojiAct = new QAction(tr("Emoji"), this); - emojiAct->setToolTip(tr("Enable emoji and emoticon (re-open current tabs to make it work)")); - emojiAct->setCheckable(true); - emojiAct->setChecked(opt.m_emoji); - connect(emojiAct, &QAction::triggered, - this, [](bool p_checked) { - MarkdownitOption opt = g_config->getMarkdownitOption(); - opt.m_emoji = p_checked; - g_config->setMarkdownitOption(opt); - }); - - optMenu->addAction(htmlAct); - optMenu->addAction(breaksAct); - optMenu->addAction(linkifyAct); - optMenu->addAction(supAct); - optMenu->addAction(subAct); - optMenu->addAction(metadataAct); - optMenu->addAction(emojiAct); -} - -void VMainWindow::initMarkdownExtensionMenu(QMenu *p_menu) -{ - QMenu *optMenu = p_menu->addMenu(tr("Extensions")); - optMenu->setToolTipsVisible(true); - - QAction *mermaidAct = new QAction(tr("&Mermaid"), optMenu); - mermaidAct->setToolTip(tr("Enable Mermaid for graph and diagram (re-open current tabs to make it work)")); - mermaidAct->setCheckable(true); - mermaidAct->setChecked(g_config->getEnableMermaid()); - connect(mermaidAct, &QAction::triggered, - this, &VMainWindow::enableMermaid); - optMenu->addAction(mermaidAct); - - QAction *flowchartAct = new QAction(tr("&Flowchart.js"), optMenu); - flowchartAct->setToolTip(tr("Enable Flowchart.js for flowchart diagram (re-open current tabs to make it work)")); - flowchartAct->setCheckable(true); - flowchartAct->setChecked(g_config->getEnableFlowchart()); - connect(flowchartAct, &QAction::triggered, - this, [this](bool p_enabled){ - g_config->setEnableFlowchart(p_enabled); - VUtils::promptForReopen(this); - }); - optMenu->addAction(flowchartAct); - - QAction *mathjaxAct = new QAction(tr("Math&Jax"), optMenu); - mathjaxAct->setToolTip(tr("Enable MathJax for math support in Markdown (re-open current tabs to make it work)")); - mathjaxAct->setCheckable(true); - mathjaxAct->setChecked(g_config->getEnableMathjax()); - connect(mathjaxAct, &QAction::triggered, - this, &VMainWindow::enableMathjax); - optMenu->addAction(mathjaxAct); - - QAction *wavedromAct = new QAction(tr("&WaveDrom"), optMenu); - wavedromAct->setToolTip(tr("Enable WaveDrom for digital timing diagram (re-open current tabs to make it work)")); - wavedromAct->setCheckable(true); - wavedromAct->setChecked(g_config->getEnableWavedrom()); - connect(wavedromAct, &QAction::triggered, - this, [this](bool p_enabled){ - g_config->setEnableWavedrom(p_enabled); - VUtils::promptForReopen(this); - }); - optMenu->addAction(wavedromAct); -} - -void VMainWindow::initRenderBackgroundMenu(QMenu *menu) -{ - QActionGroup *renderBackgroundAct = new QActionGroup(this); - connect(renderBackgroundAct, &QActionGroup::triggered, - this, &VMainWindow::setRenderBackgroundColor); - - QMenu *renderBgMenu = menu->addMenu(tr("&Rendering Background")); - renderBgMenu->setToolTipsVisible(true); - const QString &curBgColor = g_config->getCurRenderBackgroundColor(); - QAction *tmpAct = new QAction(tr("System"), renderBackgroundAct); - tmpAct->setToolTip(tr("Use system's background color configuration for Markdown rendering")); - tmpAct->setCheckable(true); - tmpAct->setData("System"); - if (curBgColor == "System") { - tmpAct->setChecked(true); - } - - renderBgMenu->addAction(tmpAct); - - tmpAct = new QAction(tr("Transparent"), renderBackgroundAct); - tmpAct->setToolTip(tr("Use a transparent background for Markdown rendering")); - tmpAct->setCheckable(true); - tmpAct->setData("Transparent"); - if (curBgColor == "Transparent") { - tmpAct->setChecked(true); - } - - renderBgMenu->addAction(tmpAct); - - const QVector &bgColors = g_config->getCustomColors(); - for (int i = 0; i < bgColors.size(); ++i) { - tmpAct = new QAction(bgColors[i].m_name, renderBackgroundAct); - tmpAct->setToolTip(tr("Set as the background color for Markdown rendering " - "(re-open current tabs to make it work)")); - tmpAct->setCheckable(true); - tmpAct->setData(bgColors[i].m_name); - -#if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC) - QColor color(bgColors[i].m_color); - QPixmap pixmap(COLOR_PIXMAP_ICON_SIZE, COLOR_PIXMAP_ICON_SIZE); - pixmap.fill(color); - tmpAct->setIcon(QIcon(pixmap)); -#endif - - if (curBgColor == bgColors[i].m_name) { - tmpAct->setChecked(true); - } - - renderBgMenu->addAction(tmpAct); - } -} - -void VMainWindow::initRenderStyleMenu(QMenu *p_menu) -{ - QMenu *styleMenu = p_menu->addMenu(tr("Rendering &Style")); - styleMenu->setToolTipsVisible(true); - - QAction *addAct = newAction(VIconUtils::menuIcon(":/resources/icons/add_style.svg"), - tr("Add Style"), - styleMenu); - addAct->setToolTip(tr("Add custom style of read mode")); - connect(addAct, &QAction::triggered, - this, [this]() { - VTipsDialog dialog(VUtils::getDocFile("tips_add_style.md"), - tr("Add Style"), - []() { - QUrl url = QUrl::fromLocalFile(g_config->getStyleConfigFolder()); - QDesktopServices::openUrl(url); - }, - this); - dialog.exec(); - }); - - styleMenu->addAction(addAct); - - QActionGroup *ag = new QActionGroup(this); - connect(ag, &QActionGroup::triggered, - this, [](QAction *p_action) { - QString data = p_action->data().toString(); - g_config->setCssStyle(data); - g_vnote->updateTemplate(); - }); - - QList styles = g_config->getCssStyles(); - QString curStyle = g_config->getCssStyle(); - for (auto const &style : styles) { - QAction *act = new QAction(style, ag); - act->setToolTip(tr("Set as the CSS style for Markdown rendering " - "(re-open current tabs to make it work)")); - act->setCheckable(true); - act->setData(style); - - // Add it to the menu. - styleMenu->addAction(act); - - if (curStyle == style) { - act->setChecked(true); - } - } -} - -void VMainWindow::initCodeBlockStyleMenu(QMenu *p_menu) -{ - QMenu *styleMenu = p_menu->addMenu(tr("Code Block Style")); - styleMenu->setToolTipsVisible(true); - - QAction *addAct = newAction(VIconUtils::menuIcon(":/resources/icons/add_style.svg"), - tr("Add Style"), - styleMenu); - addAct->setToolTip(tr("Add custom style of code block in read mode")); - connect(addAct, &QAction::triggered, - this, [this]() { - VTipsDialog dialog(VUtils::getDocFile("tips_add_style.md"), - tr("Add Style"), - []() { - QUrl url = QUrl::fromLocalFile(g_config->getCodeBlockStyleConfigFolder()); - QDesktopServices::openUrl(url); - }, - this); - dialog.exec(); - }); - - styleMenu->addAction(addAct); - - QActionGroup *ag = new QActionGroup(this); - connect(ag, &QActionGroup::triggered, - this, [](QAction *p_action) { - QString data = p_action->data().toString(); - g_config->setCodeBlockCssStyle(data); - g_vnote->updateTemplate(); - }); - - QList styles = g_config->getCodeBlockCssStyles(); - QString curStyle = g_config->getCodeBlockCssStyle(); - for (auto const &style : styles) { - QAction *act = new QAction(style, ag); - act->setToolTip(tr("Set as the code block CSS style for Markdown rendering " - "(re-open current tabs to make it work)")); - act->setCheckable(true); - act->setData(style); - - // Add it to the menu. - styleMenu->addAction(act); - - if (curStyle == style) { - act->setChecked(true); - } - } -} - -void VMainWindow::initEditorBackgroundMenu(QMenu *menu) -{ - QMenu *backgroundColorMenu = menu->addMenu(tr("&Background Color")); - backgroundColorMenu->setToolTipsVisible(true); - - QActionGroup *backgroundColorAct = new QActionGroup(this); - connect(backgroundColorAct, &QActionGroup::triggered, - this, &VMainWindow::setEditorBackgroundColor); - - // System background color - const QString &curBgColor = g_config->getCurBackgroundColor(); - QAction *tmpAct = new QAction(tr("System"), backgroundColorAct); - tmpAct->setToolTip(tr("Use system's background color configuration for editor")); - tmpAct->setCheckable(true); - tmpAct->setData("System"); - if (curBgColor == "System") { - tmpAct->setChecked(true); - } - backgroundColorMenu->addAction(tmpAct); - const QVector &bgColors = g_config->getCustomColors(); - for (int i = 0; i < bgColors.size(); ++i) { - tmpAct = new QAction(bgColors[i].m_name, backgroundColorAct); - tmpAct->setToolTip(tr("Set as the background color for editor (re-open current tabs to make it work)")); - tmpAct->setCheckable(true); - tmpAct->setData(bgColors[i].m_name); - -#if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC) - QColor color(bgColors[i].m_color); - QPixmap pixmap(COLOR_PIXMAP_ICON_SIZE, COLOR_PIXMAP_ICON_SIZE); - pixmap.fill(color); - tmpAct->setIcon(QIcon(pixmap)); -#endif - - if (curBgColor == bgColors[i].m_name) { - tmpAct->setChecked(true); - } - - backgroundColorMenu->addAction(tmpAct); - } -} - -void VMainWindow::initEditorLineNumberMenu(QMenu *p_menu) -{ - QMenu *lineNumMenu = p_menu->addMenu(tr("Line Number")); - lineNumMenu->setToolTipsVisible(true); - - QActionGroup *lineNumAct = new QActionGroup(lineNumMenu); - connect(lineNumAct, &QActionGroup::triggered, - this, [this](QAction *p_action){ - if (!p_action) { - return; - } - - g_config->setEditorLineNumber(p_action->data().toInt()); - emit editorConfigUpdated(); - }); - - int lineNumberMode = g_config->getEditorLineNumber(); - - QAction *act = lineNumAct->addAction(tr("None")); - act->setToolTip(tr("Do not display line number in edit mode")); - act->setCheckable(true); - act->setData(0); - lineNumMenu->addAction(act); - if (lineNumberMode == 0) { - act->setChecked(true); - } - - act = lineNumAct->addAction(tr("Absolute")); - act->setToolTip(tr("Display absolute line number in edit mode")); - act->setCheckable(true); - act->setData(1); - lineNumMenu->addAction(act); - if (lineNumberMode == 1) { - act->setChecked(true); - } - - act = lineNumAct->addAction(tr("Relative")); - act->setToolTip(tr("Display line number relative to current cursor line in edit mode")); - act->setCheckable(true); - act->setData(2); - lineNumMenu->addAction(act); - if (lineNumberMode == 2) { - act->setChecked(true); - } - - act = lineNumAct->addAction(tr("CodeBlock")); - act->setToolTip(tr("Display line number in code block in edit mode (for Markdown only)")); - act->setCheckable(true); - act->setData(3); - lineNumMenu->addAction(act); - if (lineNumberMode == 3) { - act->setChecked(true); - } -} - -void VMainWindow::initEditorStyleMenu(QMenu *p_menu) -{ - QMenu *styleMenu = p_menu->addMenu(tr("Editor &Style")); - styleMenu->setToolTipsVisible(true); - - QAction *addAct = newAction(VIconUtils::menuIcon(":/resources/icons/add_style.svg"), - tr("Add Style"), - styleMenu); - addAct->setToolTip(tr("Add custom style of editor")); - connect(addAct, &QAction::triggered, - this, [this]() { - VTipsDialog dialog(VUtils::getDocFile("tips_add_style.md"), - tr("Add Style"), - []() { - QUrl url = QUrl::fromLocalFile(g_config->getStyleConfigFolder()); - QDesktopServices::openUrl(url); - }, - this); - dialog.exec(); - }); - - styleMenu->addAction(addAct); - - QActionGroup *ag = new QActionGroup(this); - connect(ag, &QActionGroup::triggered, - this, [](QAction *p_action) { - QString data = p_action->data().toString(); - g_config->setEditorStyle(data); - }); - - QList styles = g_config->getEditorStyles(); - QString style = g_config->getEditorStyle(); - for (auto const &item : styles) { - QAction *act = new QAction(item, ag); - act->setToolTip(tr("Set as the editor style (re-open current tabs to make it work)")); - act->setCheckable(true); - act->setData(item); - - // Add it to the menu. - styleMenu->addAction(act); - - if (style == item) { - act->setChecked(true); - } - } -} - -void VMainWindow::initAutoScrollCursorLineMenu(QMenu *p_menu) -{ - QMenu *subMenu = p_menu->addMenu(tr("Auto Scroll Cursor Line")); - subMenu->setToolTipsVisible(true); - - QActionGroup *ag = new QActionGroup(this); - connect(ag, &QActionGroup::triggered, - this, [](QAction *p_action) { - g_config->setAutoScrollCursorLine(p_action->data().toInt()); - }); - - int mode = g_config->getAutoScrollCursorLine(); - - int data = AutoScrollDisabled; - QAction *act = new QAction(tr("Disabled"), ag); - act->setCheckable(true); - act->setData(data); - subMenu->addAction(act); - if (mode == data) { - act->setChecked(true); - } - - data = AutoScrollEndOfDoc; - act = new QAction(tr("End Of Document"), ag); - act->setToolTip(tr("Scroll cursor line into the center when it locates at the end of document")); - act->setCheckable(true); - act->setData(data); - subMenu->addAction(act); - if (mode == data) { - act->setChecked(true); - } - - data = AutoScrollAlways; - act = new QAction(tr("Always"), ag); - act->setToolTip(tr("Always scroll cursor line into the center")); - act->setCheckable(true); - act->setData(data); - subMenu->addAction(act); - if (mode == data) { - act->setChecked(true); - } -} - -void VMainWindow::setRenderBackgroundColor(QAction *action) -{ - if (!action) { - return; - } - - g_config->setCurRenderBackgroundColor(action->data().toString()); - vnote->updateTemplate(); -} - -void VMainWindow::updateActionsStateFromTab(const VEditTab *p_tab) -{ - const VFile *file = p_tab ? p_tab->getFile() : NULL; - bool editMode = p_tab ? p_tab->isEditMode() : false; - bool systemFile = file - && file->getType() == FileType::Orphan - && dynamic_cast(file)->isSystemFile(); - - m_printAct->setEnabled(file && file->getDocType() == DocType::Markdown); - - updateEditReadAct(p_tab); - - saveNoteAct->setEnabled(file && editMode && file->isModifiable()); - deleteNoteAct->setEnabled(file && file->getType() == FileType::Note); - noteInfoAct->setEnabled(file && !systemFile); - - m_attachmentBtn->setEnabled(file && file->getType() == FileType::Note); - - m_headingBtn->setEnabled(file && editMode); - - setActionsEnabled(m_editToolBar, file && editMode); - - // Handle heading sequence act independently. - m_headingSequenceAct->setEnabled(editMode - && file->isModifiable() - && isHeadingSequenceApplicable()); - const VMdTab *mdTab = dynamic_cast(p_tab); - m_headingSequenceAct->setChecked(mdTab - && editMode - && file->isModifiable() - && mdTab->isHeadingSequenceEnabled()); - - // Find/Replace - m_findReplaceAct->setEnabled(file); - m_findNextAct->setEnabled(file); - m_findPreviousAct->setEnabled(file); - m_replaceAct->setEnabled(file && editMode); - m_replaceFindAct->setEnabled(file && editMode); - m_replaceAllAct->setEnabled(file && editMode); - - if (!file) { - m_findReplaceDialog->closeDialog(); - } - - m_updateTimer->start(); -} - -void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info) -{ - if (m_curTab != p_info.m_editTab) { - if (m_curTab) { - if (m_vimCmd->isVisible()) { - m_curTab->handleVimCmdCommandCancelled(); - } - - // Disconnect the trigger signal from edit tab. - disconnect((VEditTab *)m_curTab, 0, m_vimCmd, 0); - } - - m_curTab = p_info.m_editTab; - if (m_curTab) { - connect((VEditTab *)m_curTab, &VEditTab::triggerVimCmd, - m_vimCmd, &VVimCmdLineEdit::reset); - } - - m_vimCmd->hide(); - } - - if (m_curTab) { - m_curFile = m_curTab->getFile(); - } else { - m_curFile = NULL; - } - - if (p_info.m_type == VEditTabInfo::InfoType::All) { - updateActionsStateFromTab(m_curTab); - - m_attachmentList->setFile(dynamic_cast(m_curFile.data())); - - if (m_syncNoteListToCurrentTab && g_config->getSyncNoteListToTab()) { - locateFile(m_curFile, false, false); - } - - QString title; - if (m_curFile) { - m_findReplaceDialog->updateState(m_curFile->getDocType(), - m_curTab->isEditMode()); - - if (m_curFile->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast((VFile *)m_curFile); - title = QString("[%1] %2").arg(tmpFile->getNotebookName()).arg(tmpFile->fetchPath()); - } else { - title = QString("%1").arg(m_curFile->fetchPath()); - } - - if (!m_curFile->isModifiable()) { - title.append('#'); - } - - if (m_curTab->isModified()) { - title.append('*'); - } - } - - updateWindowTitle(title); - } - - updateStatusInfo(p_info); -} - -void VMainWindow::changePanelView(PanelViewState p_state) -{ - switch (p_state) { - case PanelViewState::ExpandMode: - m_mainSplitter->widget(0)->hide(); - m_mainSplitter->widget(1)->show(); - break; - - case PanelViewState::HorizontalMode: - case PanelViewState::VerticalMode: - m_mainSplitter->widget(0)->show(); - m_mainSplitter->widget(1)->show(); - break; - - default: - Q_ASSERT(false); - break; - } - - g_config->setPanelViewState((int)p_state); - - expandViewAct->setChecked(p_state == PanelViewState::ExpandMode); -} - -void VMainWindow::updateWindowTitle(const QString &str) -{ - QString title = "VNote"; - if (!str.isEmpty()) { - title = title + " - " + str; - } - setWindowTitle(title); -} - -void VMainWindow::curEditFileInfo() -{ - Q_ASSERT(m_curFile); - - if (m_curFile->getType() == FileType::Note) { - VNoteFile *file = dynamic_cast((VFile *)m_curFile); - Q_ASSERT(file); - m_fileList->fileInfo(file); - } else if (m_curFile->getType() == FileType::Orphan) { - VOrphanFile *file = dynamic_cast((VFile *)m_curFile); - Q_ASSERT(file); - if (!file->isSystemFile()) { - editOrphanFileInfo(m_curFile); - } - } -} - -void VMainWindow::deleteCurNote() -{ - if (!m_curFile || m_curFile->getType() != FileType::Note) { - return; - } - - VNoteFile *file = dynamic_cast((VFile *)m_curFile); - m_fileList->deleteFile(file); -} - -void VMainWindow::closeEvent(QCloseEvent *event) -{ - bool isExit = m_requestQuit || !g_config->getMinimizeToStystemTray(); - m_requestQuit = false; - - m_captain->exitCaptainMode(); - -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - // Do not support minimized to tray on macOS. - if (!isExit) { - event->accept(); - return; - } -#endif - - if (!isExit && g_config->getMinimizeToStystemTray() == -1) { - // Not initialized yet. Prompt for user. - int ret = VUtils::showMessage(QMessageBox::Information, - tr("Close VNote"), - tr("Do you want to minimize VNote to system tray " - "instead of quitting it when closing VNote?"), - tr("You could change the option in Settings later."), - QMessageBox::Ok | QMessageBox::No | QMessageBox::Cancel, - QMessageBox::Ok, - this); - if (ret == QMessageBox::Ok) { - g_config->setMinimizeToSystemTray(1); - } else if (ret == QMessageBox::No) { - g_config->setMinimizeToSystemTray(0); - isExit = true; - } else { - event->ignore(); - return; - } - } - - if (isVisible()) { - saveStateAndGeometry(); - } - - if (isExit || !m_trayIcon->isVisible()) { - // Get all the opened tabs. - bool saveOpenedNotes = g_config->getStartupPageType() == StartupPageType::ContinueLeftOff; - QVector fileInfos; - QVector tabs; - if (saveOpenedNotes) { - tabs = m_editArea->getAllTabsInfo(); - - fileInfos.reserve(tabs.size()); - - for (auto const & tab : tabs) { - // Skip system file. - VFile *file = tab.m_editTab->getFile(); - if (file->getType() == FileType::Orphan - && dynamic_cast(file)->isSystemFile()) { - continue; - } - - VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tab); - if (tab.m_editTab == m_curTab) { - info.setActive(true); - } - - fileInfos.push_back(info); - - qDebug() << "file session:" << info.m_file << (info.m_mode == OpenFileMode::Edit); - } - } - - m_syncNoteListToCurrentTab = false; - - if (!m_editArea->closeAllFiles(false)) { - // Fail to close all the opened files, cancel closing app. - event->ignore(); - m_syncNoteListToCurrentTab = true; - return; - } - - if (saveOpenedNotes) { - g_config->setLastOpenedFiles(fileInfos); - } - - QMainWindow::closeEvent(event); - qApp->quit(); - } else { - hide(); - event->ignore(); - } -} - -void VMainWindow::saveStateAndGeometry() -{ - g_config->setMainWindowGeometry(saveGeometry()); - g_config->setMainWindowState(saveState()); - g_config->setToolsDockChecked(m_toolDock->isVisible()); - g_config->setSearchDockChecked(m_searchDock->isVisible()); - g_config->setMainSplitterState(m_mainSplitter->saveState()); - g_config->setNotebookSplitterState(m_nbSplitter->saveState()); - m_tagExplorer->saveStateAndGeometry(); - g_config->setNaviBoxCurrentIndex(m_naviBox->currentIndex()); -} - -void VMainWindow::restoreStateAndGeometry() -{ - const QByteArray geometry = g_config->getMainWindowGeometry(); - if (!geometry.isEmpty()) { - restoreGeometry(geometry); - } - - const QByteArray state = g_config->getMainWindowState(); - if (!state.isEmpty()) { - // restoreState() will restore the state of dock widgets. - restoreState(state); - } - - const QByteArray splitterState = g_config->getMainSplitterState(); - if (!splitterState.isEmpty()) { - m_mainSplitter->restoreState(splitterState); - } - - const QByteArray nbSplitterState = g_config->getNotebookSplitterState(); - if (!nbSplitterState.isEmpty()) { - m_nbSplitter->restoreState(nbSplitterState); - } - - m_naviBox->setCurrentIndex(g_config->getNaviBoxCurrentIndex()); -} - -void VMainWindow::handleCurrentDirectoryChanged(const VDirectory *p_dir) -{ - newNoteAct->setEnabled(p_dir); - m_importNoteAct->setEnabled(p_dir); -} - -void VMainWindow::handleCurrentNotebookChanged(const VNotebook *p_notebook) -{ - newRootDirAct->setEnabled(p_notebook); -} - -void VMainWindow::keyPressEvent(QKeyEvent *event) -{ - int key = event->key(); - Qt::KeyboardModifiers modifiers = event->modifiers(); - if (key == Qt::Key_Escape - || (key == Qt::Key_BracketLeft - && modifiers == Qt::ControlModifier)) { - m_findReplaceDialog->closeDialog(); - event->accept(); - return; - } - QMainWindow::keyPressEvent(event); -} - -bool VMainWindow::locateFile(VFile *p_file, bool p_focus, bool p_show) -{ - bool ret = false; - if (!p_file || p_file->getType() != FileType::Note) { - return ret; - } - - VNoteFile *file = dynamic_cast(p_file); - VNotebook *notebook = file->getNotebook(); - if (m_notebookSelector->locateNotebook(notebook)) { - while (m_dirTree->currentNotebook() != notebook) { - QCoreApplication::sendPostedEvents(); - } - - VDirectory *dir = file->getDirectory(); - if (m_dirTree->locateDirectory(dir)) { - while (m_fileList->currentDirectory() != dir) { - QCoreApplication::sendPostedEvents(); - } - - if (m_fileList->locateFile(file)) { - ret = true; - if (p_focus) { - m_fileList->setFocus(); - } - } - } - } - - // Open the directory and file panels after location. - if (ret && p_show) { - showNotebookPanel(); - } - - return ret; -} - -bool VMainWindow::locateDirectory(VDirectory *p_directory) -{ - bool ret = false; - if (!p_directory) { - return ret; - } - - VNotebook *notebook = p_directory->getNotebook(); - if (m_notebookSelector->locateNotebook(notebook)) { - while (m_dirTree->currentNotebook() != notebook) { - QCoreApplication::sendPostedEvents(); - } - - if (m_dirTree->locateDirectory(p_directory)) { - ret = true; - m_dirTree->setFocus(); - } - } - - // Open the directory and file panels after location. - if (ret) { - showNotebookPanel(); - } - - return ret; -} - -bool VMainWindow::locateNotebook(VNotebook *p_notebook) -{ - bool ret = false; - if (!p_notebook) { - return ret; - } - - if (m_notebookSelector->locateNotebook(p_notebook)) { - ret = true; - m_dirTree->setFocus(); - } - - // Open the directory and file panels after location. - if (ret) { - showNotebookPanel(); - } - - return ret; -} - -void VMainWindow::handleFindDialogTextChanged(const QString &p_text, uint /* p_options */) -{ - bool enabled = true; - if (p_text.isEmpty()) { - enabled = false; - } - m_findNextAct->setEnabled(enabled); - m_findPreviousAct->setEnabled(enabled); - m_replaceAct->setEnabled(enabled); - m_replaceFindAct->setEnabled(enabled); - m_replaceAllAct->setEnabled(enabled); -} - -void VMainWindow::openFindDialog() -{ - m_findReplaceDialog->openDialog(m_editArea->getSelectedText()); -} - -void VMainWindow::viewSettings() -{ - VSettingsDialog settingsDialog(this); - if (settingsDialog.exec()) { - if (settingsDialog.getNeedUpdateEditorFont()) { - updateFontOfAllTabs(); - } - } -} - -void VMainWindow::closeCurrentFile() -{ - if (m_curFile) { - m_editArea->closeFile(m_curFile, false); - } -} - -void VMainWindow::changeAutoIndent(bool p_checked) -{ - g_config->setAutoIndent(p_checked); -} - -void VMainWindow::changeAutoList(bool p_checked) -{ - g_config->setAutoList(p_checked); - if (p_checked) { - if (!m_autoIndentAct->isChecked()) { - m_autoIndentAct->trigger(); - } - m_autoIndentAct->setEnabled(false); - } else { - m_autoIndentAct->setEnabled(true); - } -} - -void VMainWindow::enableCodeBlockHighlight(bool p_checked) -{ - g_config->setEnableCodeBlockHighlight(p_checked); -} - -void VMainWindow::enableImagePreview(bool p_checked) -{ - g_config->setEnablePreviewImages(p_checked); - - emit editorConfigUpdated(); -} - -void VMainWindow::enableImagePreviewConstraint(bool p_checked) -{ - g_config->setEnablePreviewImageConstraint(p_checked); - - emit editorConfigUpdated(); -} - -void VMainWindow::enableImageConstraint(bool p_checked) -{ - g_config->setEnableImageConstraint(p_checked); - - vnote->updateTemplate(); -} - -void VMainWindow::enableImageCaption(bool p_checked) -{ - g_config->setEnableImageCaption(p_checked); -} - -void VMainWindow::shortcutsHelp() -{ - QString docFile = VUtils::getDocFile(VNote::c_shortcutsDocFile); - VFile *file = vnote->getFile(docFile, true); - m_editArea->openFile(file, OpenFileMode::Read); -} - -void VMainWindow::printNote() -{ - if (m_printer - || !m_curFile - || m_curFile->getDocType() != DocType::Markdown) { - return; - } - - m_printer = new QPrinter(); - QPrintDialog dialog(m_printer, this); - dialog.setWindowTitle(tr("Print Note")); - - V_ASSERT(m_curTab); - - VMdTab *mdTab = dynamic_cast((VEditTab *)m_curTab); - VWebView *webView = mdTab->getWebViewer(); - - V_ASSERT(webView); - - if (webView->hasSelection()) { - dialog.addEnabledOption(QAbstractPrintDialog::PrintSelection); - } - - if (dialog.exec() == QDialog::Accepted) { - webView->page()->print(m_printer, [this](bool p_succ) { - qDebug() << "print web page callback" << p_succ; - delete m_printer; - m_printer = NULL; - }); - } else { - delete m_printer; - m_printer = NULL; - } -} - -QAction *VMainWindow::newAction(const QIcon &p_icon, - const QString &p_text, - QObject *p_parent) -{ -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - Q_UNUSED(p_icon); - return new QAction(p_text, p_parent); -#else - return new QAction(p_icon, p_text, p_parent); -#endif -} - -void VMainWindow::showStatusMessage(const QString &p_msg) -{ - const int timeout = 5000; - statusBar()->showMessage(p_msg, timeout); -} - -void VMainWindow::updateStatusInfo(const VEditTabInfo &p_info) -{ - if (m_curTab) { - m_tabIndicator->update(p_info); - m_tabIndicator->show(); - - if (m_curTab->isEditMode()) { - if (p_info.m_type == VEditTabInfo::InfoType::All) { - m_curTab->requestUpdateVimStatus(); - } - } else { - m_vimIndicator->hide(); - } - } else { - m_tabIndicator->hide(); - m_vimIndicator->hide(); - } -} - -void VMainWindow::handleVimStatusUpdated(const VVim *p_vim) -{ - m_vimIndicator->update(p_vim); - if (!p_vim || !m_curTab || !m_curTab->isEditMode()) { - m_vimIndicator->hide(); - } else { - m_vimIndicator->show(); - } -} - -bool VMainWindow::tryOpenInternalFile(const QString &p_filePath) -{ - if (p_filePath.isEmpty()) { - return false; - } - - if (QFileInfo::exists(p_filePath)) { - VFile *file = vnote->getInternalFile(p_filePath); - - if (file) { - m_editArea->openFile(file, OpenFileMode::Read); - return true; - } - } - - return false; -} - -QVector VMainWindow::openFiles(const QStringList &p_files, - bool p_forceOrphan, - OpenFileMode p_mode, - bool p_forceMode, - bool p_oneByOne) -{ - QVector vfiles; - vfiles.reserve(p_files.size()); - - for (int i = 0; i < p_files.size(); ++i) { - if (!QFileInfo::exists(p_files[i])) { - qWarning() << "file" << p_files[i] << "does not exist"; - continue; - } - - VFile *file = vnote->getFile(p_files[i], p_forceOrphan); - - m_editArea->openFile(file, p_mode, p_forceMode); - vfiles.append(file); - - if (p_oneByOne) { - QCoreApplication::sendPostedEvents(); - } - } - - return vfiles; -} - -void VMainWindow::editOrphanFileInfo(VFile *p_file) -{ - VOrphanFile *file = dynamic_cast(p_file); - Q_ASSERT(file); - - VOrphanFileInfoDialog dialog(file, this); - if (dialog.exec() == QDialog::Accepted) { - QString imgFolder = dialog.getImageFolder(); - file->setImageFolder(imgFolder); - } -} - -void VMainWindow::checkSharedMemory() -{ - QStringList files = m_guard->fetchFilesToOpen(); - if (!files.isEmpty()) { - qDebug() << "shared memory fetch files" << files; - openFiles(files, false, g_config->getNoteOpenMode(), false, false); - - // Eliminate the signal. - m_guard->fetchAskedToShow(); - - showMainWindow(); - } else if (m_guard->fetchAskedToShow()) { - qDebug() << "shared memory asked to show up"; - showMainWindow(); - } -} - -void VMainWindow::initTrayIcon() -{ - QMenu *menu = new QMenu(this); - QAction *showMainWindowAct = menu->addAction(tr("Show VNote")); - connect(showMainWindowAct, &QAction::triggered, - this, &VMainWindow::showMainWindow); - - QAction *exitAct = menu->addAction(tr("Quit")); - connect(exitAct, &QAction::triggered, - this, &VMainWindow::quitApp); - - QIcon sysIcon(":/resources/icons/256x256/vnote.png"); - -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - sysIcon.setIsMask(true); -#endif - - m_trayIcon = new QSystemTrayIcon(sysIcon, this); - m_trayIcon->setToolTip(tr("VNote")); - m_trayIcon->setContextMenu(menu); - - connect(m_trayIcon, &QSystemTrayIcon::activated, - this, [this](QSystemTrayIcon::ActivationReason p_reason){ -#if !defined(Q_OS_MACOS) && !defined(Q_OS_MAC) - if (p_reason == QSystemTrayIcon::Trigger) { - this->showMainWindow(); - } -#endif - }); - - m_trayIcon->show(); -} - -void VMainWindow::changeEvent(QEvent *p_event) -{ - if (p_event->type() == QEvent::WindowStateChange) { - QWindowStateChangeEvent *eve = dynamic_cast(p_event); - m_windowOldState = eve->oldState(); - } - - QMainWindow::changeEvent(p_event); -} - -void VMainWindow::showMainWindow() -{ - if (this->isMinimized()) { - if (m_windowOldState & Qt::WindowMaximized) { - this->showMaximized(); - } else if (m_windowOldState & Qt::WindowFullScreen) { - this->showFullScreen(); - } else { - this->showNormal(); - } - } else { - this->show(); - // Need to call raise() in macOS. - this->raise(); - } - - this->activateWindow(); -} - -void VMainWindow::openStartupPages() -{ - StartupPageType type = g_config->getStartupPageType(); - switch (type) { - case StartupPageType::ContinueLeftOff: - { - QVector files = g_config->getLastOpenedFiles(); - qDebug() << "open" << files.size() << "last opened files"; - m_editArea->openFiles(files, true); - break; - } - - case StartupPageType::SpecificPages: - { - QStringList pagesToOpen = VUtils::filterFilePathsToOpen(g_config->getStartupPages()); - qDebug() << "open startup pages" << pagesToOpen; - openFiles(pagesToOpen, false, g_config->getNoteOpenMode(), false, true); - break; - } - - default: - break; - } -} - -bool VMainWindow::isHeadingSequenceApplicable() const -{ - if (!m_curTab) { - return false; - } - - Q_ASSERT(m_curFile); - - if (!m_curFile->isModifiable() - || m_curFile->getDocType() != DocType::Markdown) { - return false; - } - - return true; -} - -// Popup the attachment list if it is enabled. -bool VMainWindow::showAttachmentListByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - if (obj->m_attachmentBtn->isEnabled()) { - // Show tool bar first. - bool toolBarChecked = obj->m_toolBarAct->isChecked(); - if (!toolBarChecked) { - obj->setToolBarVisible(true); - - // Make it visible first. - QCoreApplication::sendPostedEvents(); - } - - obj->m_attachmentBtn->showPopupWidget(); - - if (!toolBarChecked) { - obj->setToolBarVisible(false); - } - } - - return true; -} - -bool VMainWindow::locateCurrentFileByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - if (obj->m_curFile) { - if (obj->locateFile(obj->m_curFile)) { - return false; - } - } - - return true; -} - -bool VMainWindow::toggleExpandModeByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - obj->expandViewAct->trigger(); - return true; -} - -bool VMainWindow::currentNoteInfoByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - if (obj->noteInfoAct->isEnabled()) { - obj->curEditFileInfo(); - } - - return true; -} - -bool VMainWindow::discardAndReadByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - if (obj->m_curTab) { - obj->m_discardExitAct->trigger(); - obj->m_curTab->setFocus(); - - return false; - } - - return true; -} - -bool VMainWindow::toggleToolBarByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - obj->m_toolBarAct->trigger(); - return true; -} - -bool VMainWindow::toggleToolsDockByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - obj->m_toolDock->setVisible(!obj->m_toolDock->isVisible()); - return true; -} - -bool VMainWindow::toggleSearchDockByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - bool visible = obj->m_searchDock->isVisible(); - obj->m_searchDock->setVisible(!visible); - if (!visible) { - obj->m_searcher->focusToSearch(); - return false; - } - - return true; -} - -bool VMainWindow::closeFileByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - obj->closeCurrentFile(); - - QWidget *nextFocus = obj->m_editArea->getCurrentTab(); - if (nextFocus) { - nextFocus->setFocus(); - } else { - obj->m_fileList->setFocus(); - } - - return false; -} - -bool VMainWindow::shortcutsHelpByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - VMainWindow *obj = static_cast(p_target); - obj->shortcutsHelp(); - return false; -} - -bool VMainWindow::flushLogFileByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_target); - Q_UNUSED(p_data); - -#if defined(QT_NO_DEBUG) - // Flush g_logFile. - g_logFile.flush(); -#endif - - return true; -} - -bool VMainWindow::exportByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - - VMainWindow *obj = static_cast(p_target); - QTimer::singleShot(50, obj, SLOT(handleExportAct())); - - return true; -} - -bool VMainWindow::focusEditAreaByCaptain(void *p_target, void *p_data) -{ - Q_UNUSED(p_data); - - VMainWindow *obj = static_cast(p_target); - obj->focusEditArea(); - return false; -} - -void VMainWindow::promptNewNotebookIfEmpty() -{ - if (vnote->getNotebooks().isEmpty()) { - m_notebookSelector->newNotebook(); - } -} - -void VMainWindow::initShortcuts() -{ - QString keySeq = g_config->getShortcutKeySequence("CloseNote"); - qDebug() << "set CloseNote shortcut to" << keySeq; - if (!keySeq.isEmpty()) { - QShortcut *closeNoteShortcut = new QShortcut(QKeySequence(keySeq), this); - closeNoteShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(closeNoteShortcut, &QShortcut::activated, - this, &VMainWindow::closeCurrentFile); - } -} - -void VMainWindow::openFlashPage() -{ - openFiles(QStringList() << g_config->getFlashPage(), - false, - OpenFileMode::Edit, - true); -} - -void VMainWindow::openQuickAccess() -{ - const QString &qaPath = g_config->getQuickAccess(); - if (qaPath.isEmpty()) { - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Quick Access is not set."), - tr("Please specify the note for Quick Access in the settings dialog " - "or the context menu of a note."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - openFiles(QStringList(qaPath), false, g_config->getNoteOpenMode()); -} - -void VMainWindow::initHeadingButton(QToolBar *p_tb) -{ - m_headingBtn = new QPushButton(VIconUtils::toolButtonIcon(":/resources/icons/heading.svg"), - "", - this); - m_headingBtn->setToolTip(tr("Headings")); - m_headingBtn->setProperty("CornerBtn", true); - m_headingBtn->setFocusPolicy(Qt::NoFocus); - m_headingBtn->setEnabled(false); - - QMenu *menu = new QMenu(this); - QString text(tr("Heading %1")); - QString tooltip(tr("Heading %1\t%2")); - QWidgetAction *wact = new QWidgetAction(menu); - wact->setData(1); - VButtonMenuItem *w = new VButtonMenuItem(wact, text.arg(1), this); - w->setToolTip(tooltip.arg(1).arg(VUtils::getShortcutText("Ctrl+1"))); - w->setProperty("Heading1", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(2); - w = new VButtonMenuItem(wact, text.arg(2), this); - w->setToolTip(tooltip.arg(2).arg(VUtils::getShortcutText("Ctrl+2"))); - w->setProperty("Heading2", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(3); - w = new VButtonMenuItem(wact, text.arg(3), this); - w->setToolTip(tooltip.arg(3).arg(VUtils::getShortcutText("Ctrl+3"))); - w->setProperty("Heading3", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(4); - w = new VButtonMenuItem(wact, text.arg(4), this); - w->setToolTip(tooltip.arg(4).arg(VUtils::getShortcutText("Ctrl+4"))); - w->setProperty("Heading4", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(5); - w = new VButtonMenuItem(wact, text.arg(5), this); - w->setToolTip(tooltip.arg(5).arg(VUtils::getShortcutText("Ctrl+5"))); - w->setProperty("Heading5", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(6); - w = new VButtonMenuItem(wact, text.arg(6), this); - w->setToolTip(tooltip.arg(6).arg(VUtils::getShortcutText("Ctrl+6"))); - w->setProperty("Heading6", true); - wact->setDefaultWidget(w); - menu->addAction(wact); - - wact = new QWidgetAction(menu); - wact->setData(0); - w = new VButtonMenuItem(wact, tr("Clear"), this); - w->setToolTip(tr("Clear\t%1").arg(VUtils::getShortcutText("Ctrl+7"))); - wact->setDefaultWidget(w); - menu->addAction(wact); - - connect(menu, &QMenu::triggered, - this, [this, menu](QAction *p_action) { - if (m_curTab) { - int level = p_action->data().toInt(); - m_curTab->decorateText(TextDecoration::Heading, level); - } - - menu->hide(); - }); - - m_headingBtn->setMenu(menu); - p_tb->addWidget(m_headingBtn); -} - -void VMainWindow::initThemeMenu(QMenu *p_menu) -{ - QMenu *themeMenu = p_menu->addMenu(tr("Theme")); - themeMenu->setToolTipsVisible(true); - - QAction *addAct = newAction(VIconUtils::menuIcon(":/resources/icons/add_style.svg"), - tr("Add Theme"), - themeMenu); - addAct->setToolTip(tr("Add custom theme")); - connect(addAct, &QAction::triggered, - this, [this]() { - VTipsDialog dialog(VUtils::getDocFile("tips_add_theme.md"), - tr("Add Theme"), - []() { - QUrl url = QUrl::fromLocalFile(g_config->getThemeConfigFolder()); - QDesktopServices::openUrl(url); - }, - this); - dialog.exec(); - }); - - themeMenu->addAction(addAct); - - QActionGroup *ag = new QActionGroup(this); - connect(ag, &QActionGroup::triggered, - this, [this](QAction *p_action) { - QString data = p_action->data().toString(); - g_config->setTheme(data); - - promptForVNoteRestart(); - }); - - QList themes = g_config->getThemes(); - QString theme = g_config->getTheme(); - for (auto const &item : themes) { - QAction *act = new QAction(item, ag); - act->setToolTip(tr("Set as the theme of VNote (restart VNote to make it work)")); - act->setCheckable(true); - act->setData(item); - - // Add it to the menu. - themeMenu->addAction(act); - - if (theme == item) { - act->setChecked(true); - } - } -} - -void VMainWindow::customShortcut() -{ - VTipsDialog dialog(VUtils::getDocFile("tips_custom_shortcut.md"), - tr("Customize Shortcuts"), - []() { -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - // On macOS, it seems that we could not open that ini file directly. - QUrl url = QUrl::fromLocalFile(g_config->getConfigFolder()); -#else - QUrl url = QUrl::fromLocalFile(g_config->getConfigFilePath()); -#endif - QDesktopServices::openUrl(url); - }, - this); - dialog.exec(); -} - -void VMainWindow::initVimCmd() -{ - m_vimCmd = new VVimCmdLineEdit(this); - m_vimCmd->setProperty("VimCommandLine", true); - - connect(m_vimCmd, &VVimCmdLineEdit::commandCancelled, - this, [this]() { - if (m_curTab) { - m_curTab->focusTab(); - } - - // NOTICE: should not hide before setting focus to edit tab. - m_vimCmd->hide(); - - if (m_curTab) { - m_curTab->handleVimCmdCommandCancelled(); - } - }); - - connect(m_vimCmd, &VVimCmdLineEdit::commandFinished, - this, [this](VVim::CommandLineType p_type, const QString &p_cmd) { - if (m_curTab) { - m_curTab->focusTab(); - } - - m_vimCmd->hide(); - - // Hide the cmd line edit before execute the command. - // If we execute the command first, we will get Chinese input - // method enabled after returning to read mode. - if (m_curTab) { - m_curTab->handleVimCmdCommandFinished(p_type, p_cmd); - } - }); - - connect(m_vimCmd, &VVimCmdLineEdit::commandChanged, - this, [this](VVim::CommandLineType p_type, const QString &p_cmd) { - if (m_curTab) { - m_curTab->handleVimCmdCommandChanged(p_type, p_cmd); - } - }); - - connect(m_vimCmd, &VVimCmdLineEdit::requestNextCommand, - this, [this](VVim::CommandLineType p_type, const QString &p_cmd) { - if (m_curTab) { - QString cmd = m_curTab->handleVimCmdRequestNextCommand(p_type, p_cmd); - if (!cmd.isNull()) { - m_vimCmd->setCommand(cmd); - } else { - m_vimCmd->restoreUserLastInput(); - } - } - }); - - connect(m_vimCmd, &VVimCmdLineEdit::requestPreviousCommand, - this, [this](VVim::CommandLineType p_type, const QString &p_cmd) { - if (m_curTab) { - QString cmd = m_curTab->handleVimCmdRequestPreviousCommand(p_type, p_cmd); - if (!cmd.isNull()) { - m_vimCmd->setCommand(cmd); - } - } - }); - - connect(m_vimCmd, &VVimCmdLineEdit::requestRegister, - this, [this](int p_key, int p_modifiers){ - if (m_curTab) { - QString val = m_curTab->handleVimCmdRequestRegister(p_key, p_modifiers); - if (!val.isEmpty()) { - m_vimCmd->setText(m_vimCmd->text() + val); - } - } - }); - - m_vimCmd->hide(); -} - -void VMainWindow::toggleEditReadMode() -{ - if (!m_curTab) { - return; - } - - if (m_curTab->isEditMode()) { - // Save changes and read. - m_editArea->saveAndReadFile(); - } else { - // Edit. - m_editArea->editFile(); - } -} - -void VMainWindow::updateEditReadAct(const VEditTab *p_tab) -{ - static QIcon editIcon = VIconUtils::toolButtonIcon(":/resources/icons/edit_note.svg"); - static QString editText; - static QIcon readIcon = VIconUtils::toolButtonIcon(":/resources/icons/save_exit.svg"); - static QString readText; - - if (editText.isEmpty()) { - QString keySeq = g_config->getShortcutKeySequence("EditReadNote"); - QKeySequence seq(keySeq); - if (!seq.isEmpty()) { - QString shortcutText = VUtils::getShortcutText(keySeq); - editText = tr("Edit\t%1").arg(shortcutText); - readText = tr("Save Changes And Read\t%1").arg(shortcutText); - - m_editReadAct->setShortcut(seq); - } else { - editText = tr("Edit"); - readText = tr("Save Changes And Read"); - } - } - - if (!p_tab || !p_tab->isEditMode()) { - // Edit. - m_editReadAct->setIcon(editIcon); - m_editReadAct->setText(editText); - m_editReadAct->setStatusTip(tr("Edit current note")); - - m_discardExitAct->setEnabled(false); - } else { - // Read. - m_editReadAct->setIcon(readIcon); - m_editReadAct->setText(readText); - m_editReadAct->setStatusTip(tr("Save changes and exit edit mode")); - - m_discardExitAct->setEnabled(true); - } - - m_editReadAct->setEnabled(p_tab); -} - -void VMainWindow::handleExportAct() -{ - VExportDialog dialog(m_notebookSelector->currentNotebook(), - m_dirTree->currentDirectory(), - m_curFile, - m_cart, - g_config->getMdConverterType(), - this); - dialog.exec(); -} - -VNotebook *VMainWindow::getCurrentNotebook() const -{ - return m_notebookSelector->currentNotebook(); -} - -void VMainWindow::activateUniversalEntry() -{ - if (!m_ue) { - initUniversalEntry(); - } - - m_captain->setCaptainModeEnabled(false); - - // Move it to the top left corner of edit area. - QPoint topLeft = m_editArea->mapToGlobal(QPoint(0, 0)); - QRect eaRect = m_editArea->editAreaRect(); - topLeft += eaRect.topLeft(); - - // Use global position. - m_ue->move(topLeft); - - eaRect.moveTop(0); - m_ue->setAvailableRect(eaRect); - - m_ue->show(); - m_ue->raise(); -} - -void VMainWindow::initUniversalEntry() -{ - m_ue = new VUniversalEntry(this); - m_ue->hide(); - -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - // Qt::Popup on macOS does not work well with input method. - m_ue->setWindowFlags(Qt::Tool - | Qt::NoDropShadowWindowHint); - m_ue->setWindowModality(Qt::ApplicationModal); -#else - m_ue->setWindowFlags(Qt::Popup - | Qt::FramelessWindowHint - | Qt::NoDropShadowWindowHint); -#endif - - connect(m_ue, &VUniversalEntry::exited, - this, [this]() { - m_captain->setCaptainModeEnabled(true); - }); - - // Register entries. - VSearchUE *searchUE = new VSearchUE(this); - m_ue->registerEntry('q', searchUE, VSearchUE::Name_FolderNote_AllNotebook); - m_ue->registerEntry('a', searchUE, VSearchUE::Content_Note_AllNotebook); - m_ue->registerEntry('z', searchUE, VSearchUE::Tag_Note_AllNotebook); - m_ue->registerEntry('w', searchUE, VSearchUE::Name_Notebook_AllNotebook); - m_ue->registerEntry('e', searchUE, VSearchUE::Name_FolderNote_CurrentNotebook); - m_ue->registerEntry('d', searchUE, VSearchUE::Content_Note_CurrentNotebook); - m_ue->registerEntry('c', searchUE, VSearchUE::Tag_Note_CurrentNotebook); - m_ue->registerEntry('r', searchUE, VSearchUE::Name_FolderNote_CurrentFolder); - m_ue->registerEntry('f', searchUE, VSearchUE::Content_Note_CurrentFolder); - m_ue->registerEntry('v', searchUE, VSearchUE::Tag_Note_CurrentFolder); - m_ue->registerEntry('t', searchUE, VSearchUE::Name_Note_Buffer); - m_ue->registerEntry('g', searchUE, VSearchUE::Content_Note_Buffer); - m_ue->registerEntry('b', searchUE, VSearchUE::Outline_Note_Buffer); - m_ue->registerEntry('u', searchUE, VSearchUE::Content_Note_ExplorerDirectory); - m_ue->registerEntry('y', new VOutlineUE(this), 0); - m_ue->registerEntry('h', searchUE, VSearchUE::Path_FolderNote_AllNotebook); - m_ue->registerEntry('n', searchUE, VSearchUE::Path_FolderNote_CurrentNotebook); - m_ue->registerEntry('m', new VListFolderUE(this), 0); - m_ue->registerEntry('j', new VListUE(this), VListUE::History); - m_ue->registerEntry('?', new VHelpUE(this), 0); -} - -void VMainWindow::checkNotebooks() -{ - bool updated = false; - QVector ¬ebooks = g_vnote->getNotebooks(); - for (int i = 0; i < notebooks.size(); ++i) { - VNotebook *nb = notebooks[i]; - if (nb->isValid()) { - continue; - } - - VFixNotebookDialog dialog(nb, notebooks, this); - if (dialog.exec()) { - qDebug() << "fix path of notebook" << nb->getName() << "to" << dialog.getPathInput(); - nb->updatePath(dialog.getPathInput()); - } else { - notebooks.removeOne(nb); - --i; - } - - updated = true; - } - - if (updated) { - g_config->setNotebooks(notebooks); - - m_notebookSelector->update(); - } - - m_notebookSelector->restoreCurrentNotebook(); -} - -void VMainWindow::setMenuBarVisible(bool p_visible) -{ - // Hiding the menubar will disable the shortcut of QActions. - if (p_visible) { - menuBar()->setFixedSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); - } else { - menuBar()->setFixedHeight(0); - } -} - -void VMainWindow::setToolBarVisible(bool p_visible) -{ - for (auto bar : m_toolBars) { - if (p_visible) { - bar->setFixedSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); - } else { - bar->setFixedHeight(0); - } - } -} - -void VMainWindow::kickOffStartUpTimer(const QStringList &p_files) -{ - QTimer::singleShot(300, [this, p_files]() { - m_syncNoteListToCurrentTab = false; - - checkNotebooks(); - QCoreApplication::sendPostedEvents(); - promptNewNotebookIfEmpty(); - QCoreApplication::sendPostedEvents(); - openStartupPages(); - openFiles(p_files, false, g_config->getNoteOpenMode(), false, true); - - checkIfNeedToShowWelcomePage(); - - if (g_config->versionChanged() && !g_config->getAllowUserTrack()) { - // Ask user whether allow tracking. - int ret = VUtils::showMessage(QMessageBox::Information, - tr("Collect User Statistics"), - tr("VNote would like to send a request to count active users." - "Do you allow this request?"), - tr("A request to https://tamlok.github.io/user_track/vnote.html will be sent if allowed."), - QMessageBox::Ok | QMessageBox::No, - QMessageBox::Ok, - this); - g_config->setAllowUserTrack(ret == QMessageBox::Ok); - } - - if (g_config->getAllowUserTrack()) { - int interval = (30 + qrand() % 60) * 1000; - QTimer::singleShot(interval, this, SLOT(collectUserStat())); - } - - m_syncNoteListToCurrentTab = true; - -#if defined(Q_OS_WIN) - if (g_config->isFreshInstall()) { - VUtils::showMessage(QMessageBox::Information, - tr("Notices for Windows Users"), - tr("OpenGL requried by VNote may not work well on Windows by default." - "You may update your display card driver or set another openGL option in VNote's Settings dialog." - "Check GitHub issue for details."), - tr("Strange behaviors include:
    " - "* Interface freezes and does not response;
    " - "* Widgets are out of order after maximizing and restoring the main window;
    " - "* No cursor in edit mode;
    " - "* Menus are not clickable in full screen mode."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - } -#endif - - g_config->updateLastStartDateTime(); - }); -} - -void VMainWindow::showNotebookPanel() -{ - changePanelView(PanelViewState::VerticalMode); - m_naviBox->setCurrentIndex(NaviBoxIndex::NotebookPanel, false); -} - -void VMainWindow::showExplorerPanel(bool p_focus) -{ - changePanelView(PanelViewState::VerticalMode); - m_naviBox->setCurrentIndex(NaviBoxIndex::Explorer, p_focus); -} - -void VMainWindow::stayOnTop(bool p_enabled) -{ - bool shown = isVisible(); - Qt::WindowFlags flags = this->windowFlags(); - - Qt::WindowFlags magicFlag = Qt::WindowStaysOnTopHint; - if (p_enabled) { - setWindowFlags(flags | magicFlag); - } else { - setWindowFlags(flags ^ magicFlag); - } - - if (shown) { - show(); - } -} - -void VMainWindow::focusEditArea() const -{ - QWidget *widget = m_editArea->getCurrentTab(); - if (!widget) { - widget = m_editArea; - } - - widget->setFocus(); -} - -void VMainWindow::setCaptainModeEnabled(bool p_enabled) -{ - m_captain->setCaptainModeEnabled(p_enabled); -} - -void VMainWindow::initUpdateTimer() -{ - m_updateTimer = new QTimer(this); - m_updateTimer->setSingleShot(true); - m_updateTimer->setInterval(200); - connect(m_updateTimer, &QTimer::timeout, - this, [this]() { - m_fileToolBar->update(); - m_viewToolBar->update(); - m_editToolBar->update(); - m_noteToolBar->update(); - }); -} - -void VMainWindow::restartVNote() -{ - QCoreApplication::exit(RESTART_EXIT_CODE); -} - -void VMainWindow::updateFontOfAllTabs() -{ - QVector tabs = m_editArea->getAllTabs(); - for (auto tab : tabs) { - const VMdTab *mdTab = dynamic_cast(tab); - if (mdTab && mdTab->getEditor()) { - mdTab->getEditor()->updateFontAndPalette(); - } - } -} - -void VMainWindow::splitFileListOut(bool p_enabled) -{ - showNotebookPanel(); - - g_config->setEnableSplitFileList(p_enabled); - - setupFileListSplitOut(p_enabled); - - g_config->setNotebookSplitterState(m_nbSplitter->saveState()); -} - -void VMainWindow::setupFileListSplitOut(bool p_enabled) -{ - m_fileList->setEnableSplitOut(p_enabled); - if (p_enabled) { - m_nbSplitter->setOrientation(Qt::Horizontal); - m_nbSplitter->setStretchFactor(0, 0); - m_nbSplitter->setStretchFactor(1, 1); - } else { - m_nbSplitter->setOrientation(Qt::Vertical); - m_nbSplitter->setStretchFactor(0, 1); - m_nbSplitter->setStretchFactor(1, 2); - } -} - -void VMainWindow::collectUserStat() const -{ - // One request per day. - auto lastCheckDate = g_config->getLastUserTrackDate(); - if (lastCheckDate != QDate::currentDate()) { - g_config->updateLastUserTrackDate(); - - qDebug() << "send user track" << QDate::currentDate(); - - QWebEnginePage *page = new QWebEnginePage; - - QString url = QString("https://tamlok.github.io/user_track/vnote/vnote_%1.html").arg(VConfigManager::c_version); - page->load(QUrl(url)); - connect(page, &QWebEnginePage::loadFinished, - this, [page](bool) { - VUtils::sleepWait(2000); - page->deleteLater(); - }); - } - - QTimer::singleShot(30 * 60 * 1000, this, SLOT(collectUserStat())); -} - -void VMainWindow::promptForVNoteRestart() -{ - int ret = VUtils::showMessage(QMessageBox::Information, - tr("Restart Needed"), - tr("Do you want to restart VNote now?"), - tr("VNote needs to restart to apply new configurations."), - QMessageBox::Ok | QMessageBox::No, - QMessageBox::Ok, - this); - if (ret == QMessageBox::Ok) { - restartVNote(); - } -} - -void VMainWindow::checkIfNeedToShowWelcomePage() -{ - if (g_config->versionChanged() - || (QDate::currentDate().dayOfYear() % 64 == 1 - && g_config->getLastStartDateTime().date() != QDate::currentDate())) { - QString docFile = VUtils::getDocFile("welcome.md"); - VFile *file = vnote->getFile(docFile, true); - m_editArea->openFile(file, OpenFileMode::Read); - } -} - -void VMainWindow::initSync() -{ - m_git = new VSync(); - connect(m_git, &VSync::downloadSuccess, this, &VMainWindow::onDownloadSuccess); - connect(m_git, &VSync::uploadSuccess, this, &VMainWindow::onUploadSuccess); -} - -void VMainWindow::onDownloadSuccess() -{ - if (m_dirTree) - { - m_dirTree->reloadAllFromDisk(); - } -} - -void VMainWindow::onUploadSuccess() -{ - -} diff --git a/src/vmainwindow.h b/src/vmainwindow.h deleted file mode 100644 index fa0192b0..00000000 --- a/src/vmainwindow.h +++ /dev/null @@ -1,588 +0,0 @@ -#ifndef VMAINWINDOW_H -#define VMAINWINDOW_H - -#include -#include -#include -#include -#include -#include "vfile.h" -#include "vedittab.h" -#include "utils/vwebutils.h" - -class QLabel; -class QComboBox; -class VDirectoryTree; -class QSplitter; -class QListWidget; -class QTabWidget; -class QToolBar; -class VNote; -class QAction; -class QPushButton; -class VNotebook; -class QActionGroup; -class VFileList; -class VEditArea; -class VToolBox; -class VOutline; -class VNotebookSelector; -class VFindReplaceDialog; -class VCaptain; -class VVimIndicator; -class VVimCmdLineEdit; -class VTabIndicator; -class VSingleInstanceGuard; -class QTimer; -class QSystemTrayIcon; -class VButtonWithWidget; -class VAttachmentList; -class VSnippetList; -class VCart; -class VSearcher; -class QPrinter; -class VUniversalEntry; -class VHistoryList; -class VExplorer; -class VTagExplorer; -class VSync; - -#define RESTART_EXIT_CODE 1000 - -enum class PanelViewState -{ - ExpandMode = 0, - HorizontalMode, - VerticalMode, - Invalid -}; - -class VMainWindow : public QMainWindow -{ - Q_OBJECT - -public: - VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent = 0); - - // Returns true if the location succeeds. - bool locateFile(VFile *p_file, bool p_focus = true, bool p_show = true); - - // Returns true if the location succeeds. - bool locateDirectory(VDirectory *p_directory); - - // Returns true if the location succeeds. - bool locateNotebook(VNotebook *p_notebook); - - VFileList *getFileList() const; - - VEditArea *getEditArea() const; - - VSnippetList *getSnippetList() const; - - VCart *getCart() const; - - VDirectoryTree *getDirectoryTree() const; - - VNotebookSelector *getNotebookSelector() const; - - VHistoryList *getHistoryList() const; - - // View and edit the information of @p_file, which is an orphan file. - void editOrphanFileInfo(VFile *p_file); - - // Open files @p_files as orphan files or internal note files. - // If @p_forceOrphan is false, for each file, VNote will try to find out if - // it is a note inside VNote. If yes, VNote will open it as internal file. - QVector openFiles(const QStringList &p_files, - bool p_forceOrphan = false, - OpenFileMode p_mode = OpenFileMode::Read, - bool p_forceMode = false, - bool p_oneByOne = false); - - // Try to open @p_filePath as internal note. - bool tryOpenInternalFile(const QString &p_filePath); - - // Show a temporary message in status bar. - void showStatusMessage(const QString &p_msg); - - // Open startup pages according to configuration. - void openStartupPages(); - - VCaptain *getCaptain() const; - - // Prompt user for new notebook if there is no notebook. - void promptNewNotebookIfEmpty(); - - // Check invalid notebooks. Set current notebook according to config. - void checkNotebooks(); - - VFile *getCurrentFile() const; - - VEditTab *getCurrentTab() const; - - VNotebook *getCurrentNotebook() const; - - // Kick off timer to do things after start. - void kickOffStartUpTimer(const QStringList &p_files); - - void focusEditArea() const; - - void showExplorerPanel(bool p_focus = false); - - VExplorer *getExplorer() const; - - void setCaptainModeEnabled(bool p_enabled); - -public slots: - void restartVNote(); - -signals: - // Emit when editor related configurations were changed by user. - void editorConfigUpdated(); - -private slots: - void importNoteFromFile(); - void viewSettings(); - void changeMarkdownConverter(QAction *action); - void aboutMessage(); - - // Display shortcuts help. - void shortcutsHelp(); - - void changeExpandTab(bool checked); - void setTabStopWidth(QAction *action); - void setEditorBackgroundColor(QAction *action); - void setRenderBackgroundColor(QAction *action); - - void changeHighlightCursorLine(bool p_checked); - void changeHighlightSelectedWord(bool p_checked); - void changeHighlightSearchedWord(bool p_checked); - void changeHighlightTrailingSapce(bool p_checked); - void curEditFileInfo(); - void deleteCurNote(); - void handleCurrentDirectoryChanged(const VDirectory *p_dir); - void handleCurrentNotebookChanged(const VNotebook *p_notebook); - void handleFindDialogTextChanged(const QString &p_text, uint p_options); - void openFindDialog(); - void enableMermaid(bool p_checked); - void enableMathjax(bool p_checked); - void changeAutoIndent(bool p_checked); - void changeAutoList(bool p_checked); - void enableCodeBlockHighlight(bool p_checked); - void enableImagePreview(bool p_checked); - void enableImagePreviewConstraint(bool p_checked); - void enableImageConstraint(bool p_checked); - void enableImageCaption(bool p_checked); - void printNote(); - - // Open export dialog. - void handleExportAct(); - - // Handle Vim status updated. - void handleVimStatusUpdated(const VVim *p_vim); - - // Handle the status update of the current tab of VEditArea. - // Will be called frequently. - void handleAreaTabStatusUpdated(const VEditTabInfo &p_info); - - // Check the shared memory between different instances to see if we have - // files to open. - void checkSharedMemory(); - - void quitApp(); - - // Restore main window. - void showMainWindow(); - - // Close current note. - void closeCurrentFile(); - - // Open flash page in edit mode. - void openFlashPage(); - - void openQuickAccess(); - - void customShortcut(); - - void toggleEditReadMode(); - - // Activate Universal Entry. - void activateUniversalEntry(); - - void stayOnTop(bool p_enabled); - - void splitFileListOut(bool p_enabled); - - void collectUserStat() const; - -protected: - void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - - void changeEvent(QEvent *p_event) Q_DECL_OVERRIDE; - -private: - void setupUI(); - - void setupNaviBox(); - - void setupNotebookPanel(); - - void setupFileListSplitOut(bool p_enabled); - - void initToolBar(); - - QToolBar *initFileToolBar(QSize p_iconSize = QSize()); - - QToolBar *initViewToolBar(QSize p_iconSize = QSize()); - - QToolBar *initNoteToolBar(QSize p_iconSize = QSize()); - - QToolBar *initEditToolBar(QSize p_iconSize = QSize()); - - void initMenuBar(); - void initFileMenu(); - void initEditMenu(); - void initViewMenu(); - void initMarkdownMenu(); - void initHelpMenu(); - void initSyncMenu(); - void initSync(); - void upload(); - void download(); - void onDownloadSuccess(); - void onUploadSuccess(); - - void initDockWindows(); - - void initToolsDock(); - - void initSearchDock(); - - void initRenderBackgroundMenu(QMenu *menu); - - void initRenderStyleMenu(QMenu *p_menu); - - void initCodeBlockStyleMenu(QMenu *p_menu); - - void initConverterMenu(QMenu *p_menu); - - void initMarkdownitOptionMenu(QMenu *p_menu); - - void initMarkdownExtensionMenu(QMenu *p_menu); - - void initEditorBackgroundMenu(QMenu *menu); - - // Init the Line Number submenu in Edit menu. - void initEditorLineNumberMenu(QMenu *p_menu); - - void initEditorStyleMenu(QMenu *p_menu); - - void initAutoScrollCursorLineMenu(QMenu *p_menu); - - void updateWindowTitle(const QString &str); - - void initVimCmd(); - - // Update state of actions according to @p_tab. - void updateActionsStateFromTab(const VEditTab *p_tab); - - void saveStateAndGeometry(); - void restoreStateAndGeometry(); - - // Should init VCaptain before setupUI(). - void initCaptain(); - - void registerCaptainAndNavigationTargets(); - - // Update status bar information. - void updateStatusInfo(const VEditTabInfo &p_info); - - // Wrapper to create a QAction. - QAction *newAction(const QIcon &p_icon, - const QString &p_text, - QObject *p_parent = nullptr); - - // Init a timer to watch the change of the shared memory between instances of - // VNote. - void initSharedMemoryWatcher(); - - void initUpdateTimer(); - - // Init system tray icon and correspondign context menu. - void initTrayIcon(); - - // Change the panel view according to @p_state. - void changePanelView(PanelViewState p_state); - - // Whether heading sequence is applicable to current tab. - // Only available for writable Markdown file. - bool isHeadingSequenceApplicable() const; - - void initShortcuts(); - - void initHeadingButton(QToolBar *p_tb); - - void initThemeMenu(QMenu *p_emnu); - - void updateEditReadAct(const VEditTab *p_tab); - - void initUniversalEntry(); - - void setMenuBarVisible(bool p_visible); - - void setToolBarVisible(bool p_visible); - - void showNotebookPanel(); - - void updateFontOfAllTabs(); - - void promptForVNoteRestart(); - - void checkIfNeedToShowWelcomePage(); - - // Captain mode functions. - - // Popup the attachment list if it is enabled. - static bool showAttachmentListByCaptain(void *p_target, void *p_data); - - static bool locateCurrentFileByCaptain(void *p_target, void *p_data); - - static bool toggleExpandModeByCaptain(void *p_target, void *p_data); - - static bool currentNoteInfoByCaptain(void *p_target, void *p_data); - - static bool discardAndReadByCaptain(void *p_target, void *p_data); - - static bool toggleToolBarByCaptain(void *p_target, void *p_data); - - static bool toggleToolsDockByCaptain(void *p_target, void *p_data); - - static bool toggleSearchDockByCaptain(void *p_target, void *p_data); - - static bool closeFileByCaptain(void *p_target, void *p_data); - - static bool shortcutsHelpByCaptain(void *p_target, void *p_data); - - static bool flushLogFileByCaptain(void *p_target, void *p_data); - - static bool exportByCaptain(void *p_target, void *p_data); - - static bool focusEditAreaByCaptain(void *p_target, void *p_data); - - // End Captain mode functions. - - VNote *vnote; - QPointer m_curFile; - QPointer m_curTab; - - VCaptain *m_captain; - - VNotebookSelector *m_notebookSelector; - - VFileList *m_fileList; - - VDirectoryTree *m_dirTree; - - VToolBox *m_naviBox; - - // Splitter for directory | files | edit. - QSplitter *m_mainSplitter; - - // Splitter for folders/notes. - QSplitter *m_nbSplitter; - - VEditArea *m_editArea; - - QDockWidget *m_toolDock; - - QDockWidget *m_searchDock; - - // Tool box in the dock widget. - VToolBox *m_toolBox; - - VOutline *outline; - - // View and manage snippets. - VSnippetList *m_snippetList; - - // View and manage cart. - VCart *m_cart; - - // Advanced search. - VSearcher *m_searcher; - - VFindReplaceDialog *m_findReplaceDialog; - - VVimCmdLineEdit *m_vimCmd; - - VVimIndicator *m_vimIndicator; - - VTabIndicator *m_tabIndicator; - - // Actions - QAction *newRootDirAct; - QAction *newNoteAct; - QAction *noteInfoAct; - - QAction *deleteNoteAct; - - // Toggle read and edit note. - QAction *m_editReadAct; - - QAction *saveNoteAct; - - QAction *m_discardExitAct; - - QAction *expandViewAct; - - QAction *m_importNoteAct; - - QAction *m_printAct; - - QAction *m_exportAct; - - QAction *m_findReplaceAct; - - QAction *m_findNextAct; - QAction *m_findPreviousAct; - QAction *m_replaceAct; - QAction *m_replaceFindAct; - QAction *m_replaceAllAct; - - QAction *m_autoIndentAct; - - // Enable heading sequence for current note. - QAction *m_headingSequenceAct; - - QAction *m_toolBarAct; - - // Act group for render styles. - QActionGroup *m_renderStyleActs; - - // Act group for code block render styles. - QActionGroup *m_codeBlockStyleActs; - - // Menus - QMenu *m_viewMenu; - - QToolBar *m_fileToolBar; - - QToolBar *m_viewToolBar; - - QToolBar *m_editToolBar; - - QToolBar *m_noteToolBar; - - // sync menu - QMenu *m_syncMenu; - - // All the ToolBar. - QVector m_toolBars; - - // Attachment button. - VButtonWithWidget *m_attachmentBtn; - - // Attachment list. - VAttachmentList *m_attachmentList; - - QPushButton *m_headingBtn; - - QPushButton *m_avatarBtn; - - // Single instance guard. - VSingleInstanceGuard *m_guard; - - // Timer to check the shared memory between instances of VNote. - QTimer *m_sharedMemTimer; - - // Timer to update gui. - // Sometimes the toolbar buttons do not refresh themselves. - QTimer *m_updateTimer; - - // Tray icon. - QSystemTrayIcon *m_trayIcon; - - // The old state of window. - Qt::WindowStates m_windowOldState; - - // Whether user request VNote to quit. - bool m_requestQuit; - - VWebUtils m_webUtils; - - QPrinter *m_printer; - - VUniversalEntry *m_ue; - - VHistoryList *m_historyList; - - VExplorer *m_explorer; - - VTagExplorer *m_tagExplorer; - - VSync *m_git; - - // Whether sync note list to current tab. - bool m_syncNoteListToCurrentTab; - - // Interval of the shared memory timer in ms. - static const int c_sharedMemTimerInterval; -}; - -inline VFileList *VMainWindow::getFileList() const -{ - return m_fileList; -} - -inline VEditArea *VMainWindow::getEditArea() const -{ - return m_editArea; -} - -inline VCaptain *VMainWindow::getCaptain() const -{ - return m_captain; -} - -inline VFile *VMainWindow::getCurrentFile() const -{ - return m_curFile; -} - -inline VEditTab *VMainWindow::getCurrentTab() const -{ - return m_curTab; -} - -inline VSnippetList *VMainWindow::getSnippetList() const -{ - return m_snippetList; -} - -inline VCart *VMainWindow::getCart() const -{ - return m_cart; -} - -inline VHistoryList *VMainWindow::getHistoryList() const -{ - return m_historyList; -} - -inline VDirectoryTree *VMainWindow::getDirectoryTree() const -{ - return m_dirTree; -} - -inline VNotebookSelector *VMainWindow::getNotebookSelector() const -{ - return m_notebookSelector; -} - -inline VExplorer *VMainWindow::getExplorer() const -{ - return m_explorer; -} -#endif // VMAINWINDOW_H diff --git a/src/vmarkdownconverter.cpp b/src/vmarkdownconverter.cpp deleted file mode 100644 index 8d262845..00000000 --- a/src/vmarkdownconverter.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "vmarkdownconverter.h" -#include - -VMarkdownConverter::VMarkdownConverter() -{ - hoedownHtmlFlags = (hoedown_html_flags)0; - nestingLevel = 16; - - htmlRenderer = hoedown_html_renderer_new(hoedownHtmlFlags, nestingLevel); - tocRenderer = hoedown_html_toc_renderer_new(nestingLevel); -} - -VMarkdownConverter::~VMarkdownConverter() -{ - if (htmlRenderer) { - hoedown_html_renderer_free(htmlRenderer); - } - if (tocRenderer) { - hoedown_html_renderer_free(tocRenderer); - } -} - -QString VMarkdownConverter::generateHtml(const QString &markdown, hoedown_extensions options) -{ - if (markdown.isEmpty()) { - return QString(); - } - hoedown_document *document = hoedown_document_new(htmlRenderer, options, - nestingLevel); - QByteArray data = markdown.toUtf8(); - hoedown_buffer *outBuf = hoedown_buffer_new(data.size()); - hoedown_document_render(document, outBuf, (const uint8_t *)data.constData(), data.size()); - hoedown_document_free(document); - QString html = QString::fromUtf8(hoedown_buffer_cstr(outBuf)); - hoedown_buffer_free(outBuf); - - return html; -} - -QString VMarkdownConverter::generateHtml(const QString &markdown, hoedown_extensions options, QString &toc) -{ - if (markdown.isEmpty()) { - return QString(); - } - - QString html = generateHtml(markdown, options); - QRegularExpression tocExp("

    \\[TOC\\]<\\/p>", QRegularExpression::CaseInsensitiveOption); - toc = generateToc(markdown, options); - html.replace(tocExp, toc); - - return html; -} - -static void processToc(QString &p_toc) -{ - // Hoedown will add '\n'. - p_toc.replace("\n", ""); - // Hoedown will translate `_` in title to ``. - p_toc.replace("", "_"); - p_toc.replace("", "_"); -} - -QString VMarkdownConverter::generateToc(const QString &markdown, hoedown_extensions options) -{ - if (markdown.isEmpty()) { - return QString(); - } - - hoedown_document *document = hoedown_document_new(tocRenderer, options, nestingLevel); - QByteArray data = markdown.toUtf8(); - hoedown_buffer *outBuf = hoedown_buffer_new(16); - hoedown_document_render(document, outBuf, (const uint8_t *)data.constData(), data.size()); - hoedown_document_free(document); - QString toc = QString::fromUtf8(hoedown_buffer_cstr(outBuf)); - hoedown_buffer_free(outBuf); - - processToc(toc); - - return toc; -} diff --git a/src/vmarkdownconverter.h b/src/vmarkdownconverter.h deleted file mode 100644 index cdadfe25..00000000 --- a/src/vmarkdownconverter.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef VMARKDOWNCONVERTER_H -#define VMARKDOWNCONVERTER_H - -#include - -extern "C" { -#include -#include -} - -class VMarkdownConverter -{ -public: - VMarkdownConverter(); - ~VMarkdownConverter(); - - QString generateHtml(const QString &markdown, hoedown_extensions options, QString &toc); - - QString generateToc(const QString &markdown, hoedown_extensions options); - -private: - QString generateHtml(const QString &markdown, hoedown_extensions options); - - // VMarkdownDocument *generateDocument(const QString &markdown); - hoedown_html_flags hoedownHtmlFlags; - int nestingLevel; - hoedown_renderer *htmlRenderer; - hoedown_renderer *tocRenderer; -}; - -#endif // VMARKDOWNCONVERTER_H diff --git a/src/vmathjaxinplacepreviewhelper.cpp b/src/vmathjaxinplacepreviewhelper.cpp deleted file mode 100644 index 26ad8aa7..00000000 --- a/src/vmathjaxinplacepreviewhelper.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#include "vmathjaxinplacepreviewhelper.h" - -#include - -#include "veditor.h" -#include "vdocument.h" -#include "vmainwindow.h" -#include "veditarea.h" -#include "vmathjaxpreviewhelper.h" - -extern VMainWindow *g_mainWin; - -MathjaxBlockPreviewInfo::MathjaxBlockPreviewInfo() -{ -} - -MathjaxBlockPreviewInfo::MathjaxBlockPreviewInfo(const VMathjaxBlock &p_mb) - : m_mathjaxBlock(p_mb) -{ -} - -void MathjaxBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor, - const QTextDocument *p_doc, - const QPixmap &p_image, - const QString &p_imageName) -{ - QTextBlock block = p_doc->findBlockByNumber(m_mathjaxBlock.m_blockNumber); - if (block.isValid()) { - VImageToPreview *preview = new VImageToPreview(); - - preview->m_startPos = block.position() + m_mathjaxBlock.m_index; - preview->m_endPos = preview->m_startPos + m_mathjaxBlock.m_length; - preview->m_blockPos = block.position(); - preview->m_blockNumber = m_mathjaxBlock.m_blockNumber; - preview->m_padding = VPreviewManager::calculateBlockMargin(block, - p_editor->tabStopWidthW()); - if (!p_imageName.isEmpty()) { - preview->m_name = p_imageName; - } else { - preview->m_name = QString::number(getImageIndex()); - } - - preview->m_isBlock = m_mathjaxBlock.m_previewedAsBlock; - - preview->m_image = p_image; - - m_inplacePreview.reset(preview); - } else { - m_inplacePreview.clear(); - } -} - -#define MATHJAX_IMAGE_CACHE_SIZE_DIFF 20 -#define MATHJAX_IMAGE_CACHE_TIME_DIFF 5 - -VMathJaxInplacePreviewHelper::VMathJaxInplacePreviewHelper(VEditor *p_editor, - VDocument *p_document, - QObject *p_parent) - : QObject(p_parent), - m_editor(p_editor), - m_document(p_document), - m_doc(p_editor->documentW()), - m_enabled(false), - m_lastInplacePreviewSize(0), - m_timeStamp(0) -{ - m_mathJaxHelper = g_mainWin->getEditArea()->getMathJaxPreviewHelper(); - m_mathJaxID = m_mathJaxHelper->registerIdentifier(); - connect(m_mathJaxHelper, &VMathJaxPreviewHelper::mathjaxPreviewResultReady, - this, &VMathJaxInplacePreviewHelper::mathjaxPreviewResultReady); - - m_documentID = m_document->registerIdentifier(); - connect(m_document, &VDocument::textToHtmlFinished, - this, &VMathJaxInplacePreviewHelper::textToHtmlFinished); -} - -void VMathJaxInplacePreviewHelper::setEnabled(bool p_enabled) -{ - if (m_enabled != p_enabled) { - m_enabled = p_enabled; - - if (!m_enabled) { - m_mathjaxBlocks.clear(); - m_cache.clear(); - } - - updateInplacePreview(); - } -} - -void VMathJaxInplacePreviewHelper::updateMathjaxBlocks(const QVector &p_blocks) -{ - if (!m_enabled) { - return; - } - - ++m_timeStamp; - - m_mathjaxBlocks.clear(); - m_mathjaxBlocks.reserve(p_blocks.size()); - bool manualUpdate = true; - for (int i = 0; i < p_blocks.size(); ++i) { - const VMathjaxBlock &vmb = p_blocks[i]; - const QString &text = vmb.m_text; - bool cached = false; - - m_mathjaxBlocks.append(MathjaxBlockPreviewInfo(vmb)); - - auto it = m_cache.find(text); - if (it != m_cache.end()) { - QSharedPointer &entry = it.value(); - entry->m_ts = m_timeStamp; - cached = true; - m_mathjaxBlocks.last().updateInplacePreview(m_editor, - m_doc, - entry->m_image, - entry->m_imageName); - } - - if (!cached || !m_mathjaxBlocks.last().inplacePreviewReady()) { - manualUpdate = false; - processForInplacePreview(m_mathjaxBlocks.size() - 1); - } - } - - if (manualUpdate) { - updateInplacePreview(); - } - - clearObsoleteCache(); -} - -void VMathJaxInplacePreviewHelper::processForInplacePreview(int p_idx) -{ - MathjaxBlockPreviewInfo &mb = m_mathjaxBlocks[p_idx]; - const VMathjaxBlock &vmb = mb.mathjaxBlock(); - if (vmb.m_text.isEmpty()) { - updateInplacePreview(); - } else { - if (!textToHtmlViaWebView(vmb.m_text, p_idx, m_timeStamp)) { - updateInplacePreview(); - } - } -} - -bool VMathJaxInplacePreviewHelper::textToHtmlViaWebView(const QString &p_text, - int p_id, - int p_timeStamp) -{ - if (!m_document->isReadyToTextToHtml()) { - qDebug() << "web side is not ready to convert text to HTML"; - return false; - } - - m_document->textToHtmlAsync(m_documentID, p_id, p_timeStamp, p_text, false); - return true; -} - -void VMathJaxInplacePreviewHelper::updateInplacePreview() -{ - QSet blocks; - QVector > images; - for (int i = 0; i < m_mathjaxBlocks.size(); ++i) { - MathjaxBlockPreviewInfo &mb = m_mathjaxBlocks[i]; - if (mb.inplacePreviewReady()) { - if (!mb.inplacePreview()->m_image.isNull()) { - images.append(mb.inplacePreview()); - } else { - blocks.insert(mb.inplacePreview()->m_blockNumber); - } - } else { - blocks.insert(mb.mathjaxBlock().m_blockNumber); - } - } - - if (images.isEmpty() && m_lastInplacePreviewSize == 0) { - return; - } - - emit inplacePreviewMathjaxBlockUpdated(images); - - m_lastInplacePreviewSize = images.size(); - - if (!blocks.isEmpty()) { - emit checkBlocksForObsoletePreview(blocks.toList()); - } -} - -void VMathJaxInplacePreviewHelper::mathjaxPreviewResultReady(int p_identitifer, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QByteArray &p_data) -{ - if (p_identitifer != m_mathJaxID || p_timeStamp != m_timeStamp) { - return; - } - - if (p_id >= m_mathjaxBlocks.size() || p_data.isEmpty()) { - updateInplacePreview(); - return; - } - - MathjaxBlockPreviewInfo &mb = m_mathjaxBlocks[p_id]; - // Update the cache. - QSharedPointer entry(new MathjaxImageCacheEntry(p_timeStamp, - p_data, - p_format)); - m_cache.insert(mb.mathjaxBlock().m_text, entry); - mb.updateInplacePreview(m_editor, m_doc, entry->m_image, QString()); - - if (mb.inplacePreview()) { - entry->m_imageName = mb.inplacePreview()->m_name; - } - - updateInplacePreview(); -} - -void VMathJaxInplacePreviewHelper::textToHtmlFinished(int p_identitifer, - int p_id, - int p_timeStamp, - const QString &p_html) -{ - if (m_documentID != p_identitifer || m_timeStamp != (TimeStamp)p_timeStamp) { - return; - } - - Q_ASSERT(p_html.startsWith("<")); - m_mathJaxHelper->previewMathJaxFromHtml(m_mathJaxID, - p_id, - p_timeStamp, - p_html); -} - -void VMathJaxInplacePreviewHelper::clearObsoleteCache() -{ - if (m_cache.size() - m_mathjaxBlocks.size() <= MATHJAX_IMAGE_CACHE_SIZE_DIFF) { - return; - } - - for (auto it = m_cache.begin(); it != m_cache.end();) { - if (m_timeStamp - it.value()->m_ts > MATHJAX_IMAGE_CACHE_TIME_DIFF) { - it.value().clear(); - it = m_cache.erase(it); - } else { - ++it; - } - } -} diff --git a/src/vmathjaxinplacepreviewhelper.h b/src/vmathjaxinplacepreviewhelper.h deleted file mode 100644 index 8e0ccb89..00000000 --- a/src/vmathjaxinplacepreviewhelper.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef VMATHJAXINPLACEPREVIEWHELPER_H -#define VMATHJAXINPLACEPREVIEWHELPER_H - -#include - -#include "pegmarkdownhighlighter.h" -#include "vpreviewmanager.h" -#include "vconstants.h" - -class VEditor; -class VDocument; -class QTextDocument; -class VMathJaxPreviewHelper; - -class MathjaxBlockPreviewInfo -{ -public: - MathjaxBlockPreviewInfo(); - - explicit MathjaxBlockPreviewInfo(const VMathjaxBlock &p_mb); - - void updateInplacePreview(const VEditor *p_editor, - const QTextDocument *p_doc, - const QPixmap &p_image, - const QString &p_imageName); - - VMathjaxBlock &mathjaxBlock() - { - return m_mathjaxBlock; - } - - const VMathjaxBlock &mathjaxBlock() const - { - return m_mathjaxBlock; - } - - bool inplacePreviewReady() const - { - return !m_inplacePreview.isNull(); - } - - const QSharedPointer &inplacePreview() const - { - return m_inplacePreview; - } - -private: - static int getImageIndex() - { - static int index = 0; - return ++index; - } - - VMathjaxBlock m_mathjaxBlock; - - QSharedPointer m_inplacePreview; -}; - - -class VMathJaxInplacePreviewHelper : public QObject -{ - Q_OBJECT -public: - VMathJaxInplacePreviewHelper(VEditor *p_editor, - VDocument *p_document, - QObject *p_parent = nullptr); - - void setEnabled(bool p_enabled); - -public slots: - void updateMathjaxBlocks(const QVector &p_blocks); - -signals: - void inplacePreviewMathjaxBlockUpdated(const QVector > &p_images); - - void checkBlocksForObsoletePreview(const QList &p_blocks); - -private slots: - void mathjaxPreviewResultReady(int p_identitifer, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QByteArray &p_data); - - void textToHtmlFinished(int p_identitifer, int p_id, int p_timeStamp, const QString &p_html); - -private: - struct MathjaxImageCacheEntry - { - MathjaxImageCacheEntry() - : m_ts(0) - { - } - - MathjaxImageCacheEntry(TimeStamp p_ts, - const QByteArray &p_dataBa, - const QString &p_format) - : m_ts(p_ts) - { - if (!p_dataBa.isEmpty()) { - m_image.loadFromData(p_dataBa, p_format.toLocal8Bit().data()); - } - } - - TimeStamp m_ts; - QPixmap m_image; - QString m_imageName; - }; - - - void processForInplacePreview(int p_idx); - - // Emit signal to update inplace preview. - void updateInplacePreview(); - - bool textToHtmlViaWebView(const QString &p_text, - int p_id, - int p_timeStamp); - - void clearObsoleteCache(); - - VEditor *m_editor; - - VDocument *m_document; - - QTextDocument *m_doc; - - bool m_enabled; - - VMathJaxPreviewHelper *m_mathJaxHelper; - - // Identification for VMathJaxPreviewHelper. - int m_mathJaxID; - - int m_lastInplacePreviewSize; - - TimeStamp m_timeStamp; - - // Sorted by m_blockNumber in ascending order. - QVector m_mathjaxBlocks; - - int m_documentID; - - // Indexed by content. - QHash> m_cache; -}; - -#endif // VMATHJAXINPLACEPREVIEWHELPER_H diff --git a/src/vmathjaxpreviewhelper.cpp b/src/vmathjaxpreviewhelper.cpp deleted file mode 100644 index 127a4827..00000000 --- a/src/vmathjaxpreviewhelper.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include "vmathjaxpreviewhelper.h" - -#include -#include - -#include "utils/vutils.h" -#include "vmathjaxwebdocument.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VMathJaxPreviewHelper::VMathJaxPreviewHelper(QWidget *p_parentWidget, QObject *p_parent) - : QObject(p_parent), - m_parentWidget(p_parentWidget), - m_initialized(false), - m_nextID(0), - m_webView(NULL), - m_webReady(false) -{ -} - -VMathJaxPreviewHelper::~VMathJaxPreviewHelper() -{ -} - -void VMathJaxPreviewHelper::doInit() -{ - Q_ASSERT(!m_initialized); - Q_ASSERT(m_parentWidget); - - m_initialized = true; - - m_webView = new QWebEngineView(m_parentWidget); - connect(m_webView, &QWebEngineView::loadFinished, - this, [this]() { - m_webReady = true; - for (auto const & it : m_pendingFunc) { - it(); - } - - m_pendingFunc.clear(); - }); - m_webView->hide(); - m_webView->setFocusPolicy(Qt::NoFocus); - - m_webDoc = new VMathJaxWebDocument(m_webView); - connect(m_webDoc, &VMathJaxWebDocument::mathjaxPreviewResultReady, - this, [this](int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QString &p_data) { - QByteArray ba = QByteArray::fromBase64(p_data.toUtf8()); - emit mathjaxPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, ba); - }); - - connect(m_webDoc, &VMathJaxWebDocument::diagramPreviewResultReady, - this, [this](int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QString &p_data) { - QByteArray ba; - if (p_format == "png") { - ba = QByteArray::fromBase64(p_data.toUtf8()); - } else { - ba = p_data.toUtf8(); - } - - emit diagramPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, ba); - }); - - QWebChannel *channel = new QWebChannel(m_webView); - channel->registerObject(QStringLiteral("content"), m_webDoc); - m_webView->page()->setWebChannel(channel); - - // setHtml() will change focus if it is not disabled. - m_webView->setEnabled(false); - QUrl baseUrl(QUrl::fromLocalFile(g_config->getDocumentPathOrHomePath() + QDir::separator())); - m_webView->setHtml(VUtils::generateMathJaxPreviewTemplate(), baseUrl); - m_webView->setEnabled(true); -} - -void VMathJaxPreviewHelper::previewMathJax(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_text) -{ - init(); - - if (!m_webReady) { - auto func = std::bind(&VMathJaxWebDocument::previewMathJax, - m_webDoc, - p_identifier, - p_id, - p_timeStamp, - p_text, - false); - m_pendingFunc.append(func); - } else { - m_webDoc->previewMathJax(p_identifier, p_id, p_timeStamp, p_text, false); - } -} - -void VMathJaxPreviewHelper::previewMathJaxFromHtml(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_html) -{ - init(); - - if (!m_webReady) { - auto func = std::bind(&VMathJaxWebDocument::previewMathJax, - m_webDoc, - p_identifier, - p_id, - p_timeStamp, - p_html, - true); - m_pendingFunc.append(func); - } else { - m_webDoc->previewMathJax(p_identifier, p_id, p_timeStamp, p_html, true); - } -} - -void VMathJaxPreviewHelper::previewDiagram(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_lang, - const QString &p_text) -{ - init(); - - if (!m_webReady) { - auto func = std::bind(&VMathJaxWebDocument::previewDiagram, - m_webDoc, - p_identifier, - p_id, - p_timeStamp, - p_lang, - p_text); - m_pendingFunc.append(func); - } else { - m_webDoc->previewDiagram(p_identifier, p_id, p_timeStamp, p_lang, p_text); - } -} diff --git a/src/vmathjaxpreviewhelper.h b/src/vmathjaxpreviewhelper.h deleted file mode 100644 index 04e0b1ca..00000000 --- a/src/vmathjaxpreviewhelper.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef VMATHJAXPREVIEWHELPER_H -#define VMATHJAXPREVIEWHELPER_H - -#include -#include -#include - -#include "vconstants.h" - -class QWebEngineView; -class VMathJaxWebDocument; -class QWidget; - -typedef std::function PendingFunc; - -class VMathJaxPreviewHelper : public QObject -{ - Q_OBJECT -public: - explicit VMathJaxPreviewHelper(QWidget *p_parentWidget, QObject *p_parent = nullptr); - - ~VMathJaxPreviewHelper(); - - // Get an ID for identification. - int registerIdentifier(); - - // Preview @p_text and return PNG data asynchronously. - // @p_identifier: identifier the caller registered; - // @p_id: internal id for each caller; - // @p_text: raw text of the MathJax script. - void previewMathJax(int p_identifier, int p_id, TimeStamp p_timeStamp, const QString &p_text); - - void previewMathJaxFromHtml(int p_identitifer, int p_id, TimeStamp p_timeStamp, const QString &p_html); - - // Preview @p_text and return PNG data asynchronously. - // @p_identifier: identifier the caller registered; - // @p_id: internal id for each caller; - // @p_lang: language of the diagram; - // @p_text: raw text of the script. - void previewDiagram(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_lang, - const QString &p_text); - -signals: - void mathjaxPreviewResultReady(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QByteArray &p_data); - - void diagramPreviewResultReady(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QByteArray &p_data); - -private: - void init(); - - void doInit(); - - QWidget *m_parentWidget; - - int m_initialized; - - int m_nextID; - - QWebEngineView *m_webView; - - VMathJaxWebDocument *m_webDoc; - - bool m_webReady; - - QVector m_pendingFunc; -}; - -inline int VMathJaxPreviewHelper::registerIdentifier() -{ - return m_nextID++; -} - -inline void VMathJaxPreviewHelper::init() -{ - if (!m_initialized) { - doInit(); - } -} -#endif // VMATHJAXPREVIEWHELPER_H diff --git a/src/vmathjaxwebdocument.cpp b/src/vmathjaxwebdocument.cpp deleted file mode 100644 index 6f2d87ce..00000000 --- a/src/vmathjaxwebdocument.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "vmathjaxwebdocument.h" - -#include - -VMathJaxWebDocument::VMathJaxWebDocument(QObject *p_parent) - : QObject(p_parent) -{ -} - -void VMathJaxWebDocument::previewMathJax(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_text, - bool p_isHtml) -{ - emit requestPreviewMathJax(p_identifier, p_id, p_timeStamp, p_text, p_isHtml); -} - -void VMathJaxWebDocument::mathjaxResultReady(int p_identifier, - int p_id, - unsigned long long p_timeStamp, - const QString &p_format, - const QString &p_data) -{ - emit mathjaxPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, p_data); -} - -void VMathJaxWebDocument::diagramResultReady(int p_identifier, - int p_id, - unsigned long long p_timeStamp, - const QString &p_format, - const QString &p_data) -{ - emit diagramPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, p_data); -} - -void VMathJaxWebDocument::previewDiagram(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_lang, - const QString &p_text) -{ - emit requestPreviewDiagram(p_identifier, - p_id, - p_timeStamp, - p_lang, - p_text); -} - -void VMathJaxWebDocument::setLog(const QString &p_log) -{ - qDebug() << "JS:" << p_log; -} - diff --git a/src/vmathjaxwebdocument.h b/src/vmathjaxwebdocument.h deleted file mode 100644 index 7216dfdd..00000000 --- a/src/vmathjaxwebdocument.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef VMATHJAXWEBDOCUMENT_H -#define VMATHJAXWEBDOCUMENT_H - -#include - -#include "vconstants.h" - -class VMathJaxWebDocument : public QObject -{ - Q_OBJECT -public: - explicit VMathJaxWebDocument(QObject *p_parent = nullptr); - - void previewMathJax(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_text, - bool p_isHtml); - - void previewDiagram(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_lang, - const QString &p_text); - -public slots: - // Will be called in the HTML side - - void mathjaxResultReady(int p_identifier, - int p_id, - unsigned long long p_timeStamp, - const QString &p_format, - const QString &p_data); - - void diagramResultReady(int p_identifier, - int p_id, - unsigned long long p_timeStamp, - const QString &p_format, - const QString &p_data); - - void setLog(const QString &p_log); - -signals: - void requestPreviewMathJax(int p_identifier, - int p_id, - unsigned long long p_timeStamp, - const QString &p_text, - bool p_isHtml); - - void requestPreviewDiagram(int p_identifier, - int p_id, - unsigned long long p_timeStamp, - const QString &p_lang, - const QString &p_text); - - void mathjaxPreviewResultReady(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QString &p_data); - - void diagramPreviewResultReady(int p_identifier, - int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QString &p_data); -}; - -#endif // VMATHJAXWEBDOCUMENT_H diff --git a/src/vmdedit.cpp b/src/vmdedit.cpp deleted file mode 100644 index 459c4bde..00000000 --- a/src/vmdedit.cpp +++ /dev/null @@ -1,836 +0,0 @@ -#include -#include "vmdedit.h" -#include "pegmarkdownhighlighter.h" -#include "vmdeditoperations.h" -#include "vnote.h" -#include "vconfigmanager.h" -#include "vtableofcontent.h" -#include "utils/vutils.h" -#include "utils/veditutils.h" -#include "utils/vpreviewutils.h" -#include "dialog/vselectdialog.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "vtextblockdata.h" -#include "vorphanfile.h" - -extern VConfigManager *g_config; -extern VNote *g_vnote; - -const int VMdEdit::c_numberOfAysncJobs = 2; - -VMdEdit::VMdEdit(VFile *p_file, VDocument *p_vdoc, MarkdownConverterType p_type, - QWidget *p_parent) - : VEdit(p_file, p_parent), m_mdHighlighter(NULL), m_freshEdit(true), - m_finishedAsyncJobs(c_numberOfAysncJobs) -{ - Q_UNUSED(p_type); - Q_UNUSED(p_vdoc); - - V_ASSERT(p_file->getDocType() == DocType::Markdown); - - setAcceptRichText(false); - - /* - m_mdHighlighter = new HGMarkdownHighlighter(g_config->getMdHighlightingStyles(), - g_config->getCodeBlockStyles(), - g_config->getMarkdownHighlightInterval(), - document()); - - connect(m_mdHighlighter, &HGMarkdownHighlighter::headersUpdated, - this, &VMdEdit::updateHeaders); - // After highlight, the cursor may trun into non-visible. We should make it visible - // in this case. - connect(m_mdHighlighter, &HGMarkdownHighlighter::highlightCompleted, - this, [this]() { - makeBlockVisible(textCursor().block()); - }); - */ - - /* - m_imagePreviewer = new VImagePreviewer(this, m_mdHighlighter); - connect(m_mdHighlighter, &HGMarkdownHighlighter::imageLinksUpdated, - m_imagePreviewer, &VImagePreviewer::imageLinksChanged); - connect(m_imagePreviewer, &VImagePreviewer::requestUpdateImageLinks, - m_mdHighlighter, &HGMarkdownHighlighter::updateHighlight); - connect(m_imagePreviewer, &VImagePreviewer::previewFinished, - this, [this](){ - if (m_freshEdit) { - finishOneAsyncJob(0); - } - }); - - connect(m_imagePreviewer, &VImagePreviewer::previewWidthUpdated, - this, [this](){ - if (m_freshEdit) { - finishOneAsyncJob(1); - } - }); - */ - - // Comment out these lines since we use VMdEditor to replace VMdEdit. - /* - m_editOps = new VMdEditOperations(this, m_file); - - connect(m_editOps, &VEditOperations::statusMessage, - this, &VEdit::statusMessage); - connect(m_editOps, &VEditOperations::vimStatusUpdated, - this, &VEdit::vimStatusUpdated); - - connect(this, &VMdEdit::cursorPositionChanged, - this, &VMdEdit::updateCurrentHeader); - - connect(QApplication::clipboard(), &QClipboard::changed, - this, &VMdEdit::handleClipboardChanged); - */ - - updateFontAndPalette(); - - updateConfig(); -} - -void VMdEdit::updateFontAndPalette() -{ - setFont(g_config->getMdEditFont()); - setPalette(g_config->getMdEditPalette()); -} - -void VMdEdit::beginEdit() -{ - updateFontAndPalette(); - - updateConfig(); - - Q_ASSERT(m_file->getContent() == toPlainTextWithoutImg()); - - initInitImages(); - - setModified(false); - - if (m_freshEdit) { - // Will set to false when all async jobs completed. - setReadOnlyAndHighlight(true); - // Disable and clear undo stacks temporary. - setUndoRedoEnabled(false); - } else { - setReadOnlyAndHighlight(false); - } - - updateHeaders(m_mdHighlighter->getHeaderRegions()); -} - -void VMdEdit::endEdit() -{ - setReadOnlyAndHighlight(true); - clearUnusedImages(); -} - -void VMdEdit::saveFile() -{ - Q_ASSERT(m_file->isModifiable()); - - if (!document()->isModified()) { - return; - } - - m_file->setContent(toPlainTextWithoutImg()); - setModified(false); -} - -void VMdEdit::reloadFile() -{ - const QString &content = m_file->getContent(); - Q_ASSERT(content.indexOf(QChar::ObjectReplacementCharacter) == -1); - - setPlainText(content); - - setModified(false); -} - -void VMdEdit::keyPressEvent(QKeyEvent *event) -{ - if (m_editOps->handleKeyPressEvent(event)) { - return; - } - VEdit::keyPressEvent(event); -} - -bool VMdEdit::canInsertFromMimeData(const QMimeData *source) const -{ - return source->hasImage() || source->hasUrls() - || VEdit::canInsertFromMimeData(source); -} - -void VMdEdit::insertFromMimeData(const QMimeData *source) -{ - VSelectDialog dialog(tr("Insert From Clipboard"), this); - dialog.addSelection(tr("Insert As Image"), 0); - dialog.addSelection(tr("Insert As Text"), 1); - - if (source->hasImage()) { - // Image data in the clipboard - if (source->hasText()) { - if (dialog.exec() == QDialog::Accepted) { - if (dialog.getSelection() == 1) { - // Insert as text. - Q_ASSERT(source->hasText() && source->hasImage()); - VEdit::insertFromMimeData(source); - return; - } - } else { - return; - } - } - m_editOps->insertImageFromMimeData(source); - return; - } else if (source->hasUrls()) { - QList urls = source->urls(); - if (urls.size() == 1 && VUtils::isImageURL(urls[0])) { - if (dialog.exec() == QDialog::Accepted) { - // FIXME: After calling dialog.exec(), source->hasUrl() returns false. - if (dialog.getSelection() == 0) { - // Insert as image. - m_editOps->insertImageFromURL(urls[0]); - return; - } - QMimeData newSource; - newSource.setUrls(urls); - VEdit::insertFromMimeData(&newSource); - return; - } else { - return; - } - } - } else if (source->hasText()) { - QString text = source->text(); - if (VUtils::isImageURLText(text)) { - // The text is a URL to an image. - if (dialog.exec() == QDialog::Accepted) { - if (dialog.getSelection() == 0) { - // Insert as image. - QUrl url(text); - if (url.isValid()) { - m_editOps->insertImageFromURL(QUrl(text)); - } - return; - } - } else { - return; - } - } - Q_ASSERT(source->hasText()); - } - VEdit::insertFromMimeData(source); -} - -void VMdEdit::imageInserted(const QString &p_path) -{ - ImageLink link; - link.m_path = p_path; - if (m_file->useRelativeImageFolder()) { - link.m_type = ImageLink::LocalRelativeInternal; - } else { - link.m_type = ImageLink::LocalAbsolute; - } - - m_insertedImages.append(link); -} - -void VMdEdit::initInitImages() -{ - m_initImages = VUtils::fetchImagesFromMarkdownFile(m_file, - ImageLink::LocalRelativeInternal); -} - -void VMdEdit::clearUnusedImages() -{ - QVector images = VUtils::fetchImagesFromMarkdownFile(m_file, - ImageLink::LocalRelativeInternal); - - QVector unusedImages; - - if (!m_insertedImages.isEmpty()) { - for (int i = 0; i < m_insertedImages.size(); ++i) { - const ImageLink &link = m_insertedImages[i]; - - if (link.m_type != ImageLink::LocalRelativeInternal) { - continue; - } - - int j; - for (j = 0; j < images.size(); ++j) { - if (VUtils::equalPath(link.m_path, images[j].m_path)) { - break; - } - } - - // This inserted image is no longer in the file. - if (j == images.size()) { - unusedImages.push_back(link.m_path); - } - } - - m_insertedImages.clear(); - } - - for (int i = 0; i < m_initImages.size(); ++i) { - const ImageLink &link = m_initImages[i]; - - V_ASSERT(link.m_type == ImageLink::LocalRelativeInternal); - - int j; - for (j = 0; j < images.size(); ++j) { - if (VUtils::equalPath(link.m_path, images[j].m_path)) { - break; - } - } - - // Original local relative image is no longer in the file. - if (j == images.size()) { - unusedImages.push_back(link.m_path); - } - } - - if (!unusedImages.isEmpty()) { - if (g_config->getConfirmImagesCleanUp()) { - QVector items; - for (auto const & img : unusedImages) { - items.push_back(ConfirmItemInfo(img, - img, - img, - NULL)); - - } - - QString text = tr("Following images seems not to be used in this note anymore. " - "Please confirm the deletion of these images."); - - QString info = tr("Deleted files could be found in the recycle " - "bin of this note.
    " - "Click \"Cancel\" to leave them untouched."); - - VConfirmDeletionDialog dialog(tr("Confirm Cleaning Up Unused Images"), - text, - info, - items, - true, - true, - true, - this); - - unusedImages.clear(); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - g_config->setConfirmImagesCleanUp(dialog.getAskAgainEnabled()); - - for (auto const & item : items) { - unusedImages.push_back(item.m_name); - } - } - } - - for (int i = 0; i < unusedImages.size(); ++i) { - bool ret = false; - if (m_file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast((VFile *)m_file); - ret = VUtils::deleteFile(tmpFile->getNotebook(), unusedImages[i], false); - } else if (m_file->getType() == FileType::Orphan) { - const VOrphanFile *tmpFile = dynamic_cast((VFile *)m_file); - ret = VUtils::deleteFile(tmpFile, unusedImages[i], false); - } else { - Q_ASSERT(false); - } - - if (!ret) { - qWarning() << "fail to delete unused original image" << unusedImages[i]; - } else { - qDebug() << "delete unused image" << unusedImages[i]; - } - } - } - - m_initImages.clear(); -} - -void VMdEdit::updateCurrentHeader() -{ - emit currentHeaderChanged(textCursor().block().blockNumber()); -} - -static void addHeaderSequence(QVector &p_sequence, int p_level, int p_baseLevel) -{ - Q_ASSERT(p_level >= 1 && p_level < p_sequence.size()); - if (p_level < p_baseLevel) { - p_sequence.fill(0); - return; - } - - ++p_sequence[p_level]; - for (int i = p_level + 1; i < p_sequence.size(); ++i) { - p_sequence[i] = 0; - } -} - -static QString headerSequenceStr(const QVector &p_sequence) -{ - QString res; - for (int i = 1; i < p_sequence.size(); ++i) { - if (p_sequence[i] != 0) { - res = res + QString::number(p_sequence[i]) + '.'; - } else if (res.isEmpty()) { - continue; - } else { - break; - } - } - - return res; -} - -static void insertSequenceToHeader(QTextBlock p_block, - QRegExp &p_reg, - QRegExp &p_preReg, - const QString &p_seq) -{ - if (!p_block.isValid()) { - return; - } - - QString text = p_block.text(); - bool matched = p_reg.exactMatch(text); - Q_ASSERT(matched); - - matched = p_preReg.exactMatch(text); - Q_ASSERT(matched); - - int start = p_reg.cap(1).length() + 1; - int end = p_preReg.cap(1).length(); - - Q_ASSERT(start <= end); - - QTextCursor cursor(p_block); - cursor.setPosition(p_block.position() + start); - if (start != end) { - cursor.setPosition(p_block.position() + end, QTextCursor::KeepAnchor); - } - - if (p_seq.isEmpty()) { - cursor.removeSelectedText(); - } else { - cursor.insertText(p_seq + ' '); - } -} - -void VMdEdit::updateHeaders(const QVector &p_headerRegions) -{ - QTextDocument *doc = document(); - - QVector headers; - QVector headerBlockNumbers; - QVector headerSequences; - if (!p_headerRegions.isEmpty()) { - headers.reserve(p_headerRegions.size()); - headerBlockNumbers.reserve(p_headerRegions.size()); - headerSequences.reserve(p_headerRegions.size()); - } - - // Assume that each block contains only one line - // Only support # syntax for now - QRegExp headerReg(VUtils::c_headerRegExp); - int baseLevel = -1; - for (auto const & reg : p_headerRegions) { - QTextBlock block = doc->findBlock(reg.m_startPos); - if (!block.isValid()) { - continue; - } - - Q_ASSERT(block.lineCount() == 1); - - if (!block.contains(reg.m_endPos - 1)) { - continue; - } - - if ((block.userState() == HighlightBlockState::Normal) && - headerReg.exactMatch(block.text())) { - int level = headerReg.cap(1).length(); - VTableOfContentItem header(headerReg.cap(2).trimmed(), - level, - block.blockNumber(), - headers.size()); - headers.append(header); - headerBlockNumbers.append(block.blockNumber()); - headerSequences.append(headerReg.cap(3)); - - if (baseLevel == -1) { - baseLevel = level; - } else if (baseLevel > level) { - baseLevel = level; - } - } - } - - m_headers.clear(); - - bool autoSequence = m_config.m_enableHeadingSequence - && !isReadOnly() - && m_file->isModifiable(); - int headingSequenceBaseLevel = g_config->getHeadingSequenceBaseLevel(); - if (headingSequenceBaseLevel < 1 || headingSequenceBaseLevel > 6) { - headingSequenceBaseLevel = 1; - } - - QVector seqs(7, 0); - QRegExp preReg(VUtils::c_headerPrefixRegExp); - int curLevel = baseLevel - 1; - for (int i = 0; i < headers.size(); ++i) { - VTableOfContentItem &item = headers[i]; - while (item.m_level > curLevel + 1) { - curLevel += 1; - - // Insert empty level which is an invalid header. - m_headers.append(VTableOfContentItem(c_emptyHeaderName, - curLevel, - -1, - m_headers.size())); - if (autoSequence) { - addHeaderSequence(seqs, curLevel, headingSequenceBaseLevel); - } - } - - item.m_index = m_headers.size(); - m_headers.append(item); - curLevel = item.m_level; - if (autoSequence) { - addHeaderSequence(seqs, item.m_level, headingSequenceBaseLevel); - - QString seqStr = headerSequenceStr(seqs); - if (headerSequences[i] != seqStr) { - // Insert correct sequence. - insertSequenceToHeader(doc->findBlockByNumber(headerBlockNumbers[i]), - headerReg, - preReg, - seqStr); - } - } - } - - emit headersChanged(m_headers); - - updateCurrentHeader(); -} - -bool VMdEdit::scrollToHeader(int p_blockNumber) -{ - if (p_blockNumber < 0) { - return false; - } - - return scrollToBlock(p_blockNumber); -} - -QString VMdEdit::toPlainTextWithoutImg() -{ - QString text; - bool readOnly = isReadOnly(); - setReadOnlyAndHighlight(true); - text = getPlainTextWithoutPreviewImage(); - setReadOnlyAndHighlight(readOnly); - - return text; -} - -QString VMdEdit::getPlainTextWithoutPreviewImage() const -{ - QVector deletions; - - while (true) { - deletions.clear(); - - /* - while (m_imagePreviewer->isPreviewing()) { - VUtils::sleepWait(100); - } - */ - - // Iterate all the block to get positions for deletion. - // QTextBlock block = document()->begin(); - bool tryAgain = false; - /* - while (block.isValid()) { - if (VTextBlockData::containsPreviewImage(block)) { - if (!getPreviewImageRegionOfBlock(block, deletions)) { - tryAgain = true; - break; - } - } - - block = block.next(); - } - */ - - if (tryAgain) { - continue; - } - - QString text = toPlainText(); - // deletions is sorted by m_startPos. - // From back to front. - for (int i = deletions.size() - 1; i >= 0; --i) { - const Region ® = deletions[i]; - qDebug() << "img region to delete" << reg.m_startPos << reg.m_endPos; - text.remove(reg.m_startPos, reg.m_endPos - reg.m_startPos); - } - - return text; - } -} - -bool VMdEdit::getPreviewImageRegionOfBlock(const QTextBlock &p_block, - QVector &p_regions) const -{ - QTextDocument *doc = document(); - QVector regs; - QString text = p_block.text(); - int nrOtherChar = 0; - int nrImage = 0; - bool hasBlock = false; - - // From back to front. - for (int i = text.size() - 1; i >= 0; --i) { - if (text[i].isSpace()) { - continue; - } - - if (text[i] == QChar::ObjectReplacementCharacter) { - int pos = p_block.position() + i; - Q_ASSERT(doc->characterAt(pos) == QChar::ObjectReplacementCharacter); - - QTextImageFormat imageFormat = VPreviewUtils::fetchFormatFromPosition(doc, pos); - if (imageFormat.isValid()) { - ++nrImage; - bool isBlock = VPreviewUtils::getPreviewImageType(imageFormat) == PreviewImageType::Block; - if (isBlock) { - hasBlock = true; - } else { - regs.push_back(Region(pos, pos + 1)); - } - } else { - return false; - } - } else { - ++nrOtherChar; - } - } - - if (hasBlock) { - if (nrOtherChar > 0 || nrImage > 1) { - // Inconsistent state. - return false; - } - - regs.push_back(Region(p_block.position(), p_block.position() + p_block.length())); - } - - p_regions.append(regs); - return true; -} - -void VMdEdit::handleClipboardChanged(QClipboard::Mode p_mode) -{ - if (!hasFocus()) { - return; - } - - if (p_mode == QClipboard::Clipboard) { - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - if (mimeData->hasText()) { - QString text = mimeData->text(); - if (clipboard->ownsClipboard()) { - if (text.trimmed() == QString(QChar::ObjectReplacementCharacter)) { - QImage image = tryGetSelectedImage(); - clipboard->clear(QClipboard::Clipboard); - if (!image.isNull()) { - clipboard->setImage(image, QClipboard::Clipboard); - } - } else { - // Try to remove all the preview image in text. - VEditUtils::removeObjectReplacementCharacter(text); - if (text.size() != mimeData->text().size()) { - clipboard->clear(QClipboard::Clipboard); - clipboard->setText(text); - } - } - } - } - } -} - -QImage VMdEdit::tryGetSelectedImage() -{ - QImage image; - QTextCursor cursor = textCursor(); - if (!cursor.hasSelection()) { - return image; - } - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - QTextDocument *doc = document(); - QTextImageFormat format; - for (int i = start; i < end; ++i) { - if (doc->characterAt(i) == QChar::ObjectReplacementCharacter) { - format = VPreviewUtils::fetchFormatFromPosition(doc, i); - break; - } - } - - if (format.isValid()) { - PreviewImageSource src = VPreviewUtils::getPreviewImageSource(format); - // long long id = VPreviewUtils::getPreviewImageID(format); - if (src == PreviewImageSource::Image) { - /* - Q_ASSERT(m_imagePreviewer->isEnabled()); - image = m_imagePreviewer->fetchCachedImageByID(id); - */ - } - } - - return image; -} - -void VMdEdit::resizeEvent(QResizeEvent *p_event) -{ - /* - m_imagePreviewer->updatePreviewImageWidth(); - */ - - VEdit::resizeEvent(p_event); -} - -int VMdEdit::indexOfCurrentHeader() const -{ - if (m_headers.isEmpty()) { - return -1; - } - - int blockNumber = textCursor().block().blockNumber(); - for (int i = m_headers.size() - 1; i >= 0; --i) { - if (!m_headers[i].isEmpty() - && m_headers[i].m_blockNumber <= blockNumber) { - return i; - } - } - - return -1; -} - -bool VMdEdit::jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) -{ - if (m_headers.isEmpty()) { - return false; - } - - QTextCursor cursor = textCursor(); - int cursorLine = cursor.block().blockNumber(); - int targetIdx = -1; - // -1: skip level check. - int targetLevel = 0; - int idx = indexOfCurrentHeader(); - if (idx == -1) { - // Cursor locates at the beginning, before any headers. - if (p_relativeLevel < 0 || !p_forward) { - return false; - } - } - - int delta = 1; - if (!p_forward) { - delta = -1; - } - - bool firstHeader = true; - for (targetIdx = idx == -1 ? 0 : idx; - targetIdx >= 0 && targetIdx < m_headers.size(); - targetIdx += delta) { - const VTableOfContentItem &header = m_headers[targetIdx]; - if (header.isEmpty()) { - continue; - } - - if (targetLevel == 0) { - // The target level has not been init yet. - Q_ASSERT(firstHeader); - targetLevel = header.m_level; - if (p_relativeLevel < 0) { - targetLevel += p_relativeLevel; - if (targetLevel < 1) { - // Invalid level. - return false; - } - } else if (p_relativeLevel > 0) { - targetLevel = -1; - } - } - - if (targetLevel == -1 || header.m_level == targetLevel) { - if (firstHeader - && (cursorLine == header.m_blockNumber - || p_forward) - && idx != -1) { - // This header is not counted for the repeat. - firstHeader = false; - continue; - } - - if (--p_repeat == 0) { - // Found. - break; - } - } else if (header.m_level < targetLevel) { - // Stop by higher level. - return false; - } - - firstHeader = false; - } - - if (targetIdx < 0 || targetIdx >= m_headers.size()) { - return false; - } - - // Jump to target header. - int line = m_headers[targetIdx].m_blockNumber; - if (line > -1) { - QTextBlock block = document()->findBlockByNumber(line); - if (block.isValid()) { - cursor.setPosition(block.position()); - setTextCursor(cursor); - return true; - } - } - - return false; -} - -void VMdEdit::finishOneAsyncJob(int p_idx) -{ - Q_ASSERT(m_freshEdit); - if (m_finishedAsyncJobs[p_idx]) { - return; - } - - m_finishedAsyncJobs[p_idx] = true; - if (-1 == m_finishedAsyncJobs.indexOf(false)) { - // All jobs finished. - setUndoRedoEnabled(true); - - setReadOnlyAndHighlight(false); - - setModified(false); - m_freshEdit = false; - emit statusChanged(); - - updateHeaders(m_mdHighlighter->getHeaderRegions()); - - emit ready(); - } -} diff --git a/src/vmdedit.h b/src/vmdedit.h deleted file mode 100644 index 81207bfb..00000000 --- a/src/vmdedit.h +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef VMDEDIT_H -#define VMDEDIT_H - -#include "vedit.h" -#include -#include -#include -#include -#include -#include "vtableofcontent.h" -#include "veditoperations.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" - -class VDocument; -class PegMarkdownHighlighter; - -class VMdEdit : public VEdit -{ - Q_OBJECT -public: - VMdEdit(VFile *p_file, VDocument *p_vdoc, MarkdownConverterType p_type, - QWidget *p_parent = 0); - void beginEdit() Q_DECL_OVERRIDE; - void endEdit() Q_DECL_OVERRIDE; - void saveFile() Q_DECL_OVERRIDE; - void reloadFile() Q_DECL_OVERRIDE; - - // An image has been inserted. The image is relative. - // @p_path is the absolute path of the inserted image. - void imageInserted(const QString &p_path); - - // Scroll to header @p_blockNumber. - // Return true if @p_blockNumber is valid to scroll to. - bool scrollToHeader(int p_blockNumber); - - // Like toPlainText(), but remove image preview characters. - QString toPlainTextWithoutImg(); - -public slots: - bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) Q_DECL_OVERRIDE; - -signals: - // Signal when headers change. - void headersChanged(const QVector &p_headers); - - // Signal when current header change. - void currentHeaderChanged(int p_blockNumber); - - // Signal when the status of VMdEdit changed. - // Will be emitted by VImagePreviewer for now. - void statusChanged(); - -private slots: - // Update m_headers according to elements. - void updateHeaders(const QVector &p_headerRegions); - - // Update current header according to cursor position. - // When there is no header in current cursor, will signal an invalid header. - void updateCurrentHeader(); - - void handleClipboardChanged(QClipboard::Mode p_mode); - -protected: - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - bool canInsertFromMimeData(const QMimeData *source) const Q_DECL_OVERRIDE; - void insertFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE; - void updateFontAndPalette() Q_DECL_OVERRIDE; - void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - -private: - struct Region - { - Region() : m_startPos(-1), m_endPos(-1) - { - } - - Region(int p_start, int p_end) - : m_startPos(p_start), m_endPos(p_end) - { - } - - int m_startPos; - int m_endPos; - }; - - // Get the initial images from file before edit. - void initInitImages(); - - // Clear two kind of images according to initial images and current images: - // 1. Newly inserted images which are deleted later; - // 2. Initial images which are deleted; - void clearUnusedImages(); - - // There is a QChar::ObjectReplacementCharacter (and maybe some spaces) - // in the selection. Get the QImage. - QImage tryGetSelectedImage(); - - QString getPlainTextWithoutPreviewImage() const; - - // Try to get all the regions of preview image within @p_block. - // Returns false if preview image is not ready yet. - bool getPreviewImageRegionOfBlock(const QTextBlock &p_block, - QVector &p_regions) const; - - void finishOneAsyncJob(int p_idx); - - // Index in m_headers of current header which contains the cursor. - int indexOfCurrentHeader() const; - - PegMarkdownHighlighter *m_mdHighlighter; - // VImagePreviewer *m_imagePreviewer; - - // Image links inserted while editing. - QVector m_insertedImages; - - // Image links right at the beginning of the edit. - QVector m_initImages; - - // Mainly used for title jump. - QVector m_headers; - - bool m_freshEdit; - - QVector m_finishedAsyncJobs; - - static const int c_numberOfAysncJobs; -}; - -#endif // VMDEDIT_H diff --git a/src/vmdeditoperations.cpp b/src/vmdeditoperations.cpp deleted file mode 100644 index 1206dd33..00000000 --- a/src/vmdeditoperations.cpp +++ /dev/null @@ -1,1240 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vmdeditoperations.h" -#include "dialog/vinsertimagedialog.h" -#include "dialog/vselectdialog.h" -#include "utils/vutils.h" -#include "veditor.h" -#include "vdownloader.h" -#include "vfile.h" -#include "vmdeditor.h" -#include "vconfigmanager.h" -#include "utils/vvim.h" -#include "utils/veditutils.h" - -extern VConfigManager *g_config; - -const QString VMdEditOperations::c_defaultImageTitle = ""; - -VMdEditOperations::VMdEditOperations(VEditor *p_editor, VFile *p_file) - : VEditOperations(p_editor, p_file), m_autoIndentPos(-1) -{ -} - -bool VMdEditOperations::insertImageFromMimeData(const QMimeData *source) -{ - QImage image = qvariant_cast(source->imageData()); - if (image.isNull()) { - return false; - } - - VInsertImageDialog dialog(tr("Insert Image From Clipboard"), - c_defaultImageTitle, - "", - false, - m_editor->getEditor()); - dialog.setImage(image); - if (dialog.exec() == QDialog::Accepted) { - insertImageFromQImage(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - image, - dialog.getOverridenWidth()); - } - - return true; -} - -// @p_width, @p_height: 0 if no override. -static QString imageLink(const QString &p_title, - const QString &p_url, - int p_width = 0, - int p_height = 0) -{ - QString scale; - if (p_width > 0) { - if (p_height > 0) { - scale = QString(" =%1x%2").arg(p_width).arg(p_height); - } else { - scale = QString(" =%1x").arg(p_width); - } - } else if (p_height > 0) { - scale = QString(" =x%1").arg(p_height); - } - - return QString("![%1](%2%3)").arg(p_title).arg(p_url).arg(scale); -} - -void VMdEditOperations::insertImageFromQImage(const QString &p_title, - const QString &p_folderPath, - const QString &p_folderInLink, - const QImage &p_image, - int p_width, - int p_height) -{ - QString fileName = VUtils::generateImageFileName(p_folderPath, p_title); - QString filePath = QDir(p_folderPath).filePath(fileName); - V_ASSERT(!QFile(filePath).exists()); - - QString errStr; - bool ret = VUtils::makePath(p_folderPath); - if (!ret) { - errStr = tr("Fail to create image folder %2.") - .arg(g_config->c_dataTextStyle).arg(p_folderPath); - } else { - ret = p_image.save(filePath); - if (!ret) { - errStr = tr("Fail to save image %2.") - .arg(g_config->c_dataTextStyle).arg(filePath); - } - } - - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to insert image %2.").arg(g_config->c_dataTextStyle).arg(p_title), - errStr, - QMessageBox::Ok, - QMessageBox::Ok, - m_editor->getEditor()); - return; - } - - QString url = QDir::fromNativeSeparators(QString("%1/%2").arg(p_folderInLink).arg(fileName)); - url = VUtils::encodeSpacesInPath(url); - if (g_config->getPrependDotInRelativePath()) { - VUtils::prependDotIfRelative(url); - } - - insertText(imageLink(p_title, url, p_width, p_height)); - - qDebug() << "insert image" << p_title << filePath; - - VMdEditor *mdEditor = dynamic_cast(m_editor); - Q_ASSERT(mdEditor); - mdEditor->imageInserted(filePath, url); -} - -void VMdEditOperations::insertImageFromPath(const QString &p_title, - const QString &p_folderPath, - const QString &p_folderInLink, - const QString &p_srcImagePath, - int p_width, - int p_height) -{ - QString destImagePath; - QString urlInLink; - - insertImageFromPath(p_title, - p_folderPath, - p_folderInLink, - p_srcImagePath, - true, - destImagePath, - urlInLink, - p_width, - p_height); -} - -void VMdEditOperations::insertImageFromPath(const QString &p_title, - const QString &p_folderPath, - const QString &p_folderInLink, - const QString &p_srcImagePath, - bool p_insertText, - QString &p_destImagePath, - QString &p_urlInLink, - int p_width, - int p_height) -{ - p_destImagePath.clear(); - p_urlInLink.clear(); - - // Make sure src image is valid. - if (VUtils::imageFromFile(p_srcImagePath).isNull()) { - qWarning() << "fail to insert invalid source image" << p_srcImagePath; - return; - } - - QString fileName = VUtils::generateImageFileName(p_folderPath, - p_title, - QFileInfo(p_srcImagePath).suffix()); - QString filePath = QDir(p_folderPath).filePath(fileName); - V_ASSERT(!QFile(filePath).exists()); - - QString errStr; - bool ret = VUtils::makePath(p_folderPath); - if (!ret) { - errStr = tr("Fail to create image folder %2.") - .arg(g_config->c_dataTextStyle).arg(p_folderPath); - } else { - ret = QFile::copy(p_srcImagePath, filePath); - if (!ret) { - errStr = tr("Fail to copy image %2.") - .arg(g_config->c_dataTextStyle).arg(filePath); - } - } - - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to insert image %2.") - .arg(g_config->c_dataTextStyle).arg(p_title), - errStr, - QMessageBox::Ok, - QMessageBox::Ok, - m_editor->getEditor()); - return; - } - - p_urlInLink = QDir::fromNativeSeparators(QString("%1/%2").arg(p_folderInLink).arg(fileName)); - p_urlInLink = VUtils::encodeSpacesInPath(p_urlInLink); - if (g_config->getPrependDotInRelativePath()) { - VUtils::prependDotIfRelative(p_urlInLink); - } - - p_destImagePath = filePath; - - if (p_insertText) { - insertText(imageLink(p_title, p_urlInLink, p_width, p_height)); - } - - qDebug() << "insert image" << p_title << filePath; - - VMdEditor *mdEditor = static_cast(m_editor); - Q_ASSERT(mdEditor); - mdEditor->imageInserted(filePath, p_urlInLink); -} - -bool VMdEditOperations::insertImageFromURL(const QUrl &imageUrl) -{ - QString imagePath; - QImage image; - bool isLocal = imageUrl.isLocalFile(); - QString title; - - // Whether it is a local file or web URL - if (isLocal) { - imagePath = imageUrl.toLocalFile(); - image = VUtils::imageFromFile(imagePath); - if (image.isNull()) { - qWarning() << "inserted image is null" << imagePath; - return false; - } - - title = tr("Insert Image From File"); - } else { - imagePath = imageUrl.toString(); - title = tr("Insert Image From Network"); - } - - - VInsertImageDialog dialog(title, - c_defaultImageTitle, - imagePath, - false, - m_editor->getEditor()); - if (isLocal) { - dialog.setImage(image); - } else { - // Download it to a QImage - VDownloader *downloader = new VDownloader(&dialog); - connect(downloader, &VDownloader::downloadFinished, - &dialog, &VInsertImageDialog::imageDownloaded); - downloader->download(imageUrl); - } - if (dialog.exec() == QDialog::Accepted) { - if (isLocal) { - insertImageFromPath(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - imagePath, - dialog.getOverridenWidth()); - } else { - if (dialog.getImageType() == VInsertImageDialog::ImageType::LocalFile) { - insertImageFromPath(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - dialog.getPathInput(), - dialog.getOverridenWidth()); - } else { - insertImageFromQImage(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - dialog.getImage(), - dialog.getOverridenWidth()); - } - } - } - return true; -} - -bool VMdEditOperations::insertImage() -{ - // Use empty title and path to let the dialog auto complete. - VInsertImageDialog dialog(tr("Insert Image"), - "", - "", - true, - m_editor->getEditor()); - if (dialog.exec() == QDialog::Accepted) { - VInsertImageDialog::ImageType type = dialog.getImageType(); - if (type == VInsertImageDialog::ImageType::LocalFile) { - insertImageFromPath(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - dialog.getPathInput(), - dialog.getOverridenWidth()); - } else { - QImage img = dialog.getImage(); - if (!img.isNull()) { - insertImageFromQImage(dialog.getImageTitleInput(), - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - img, - dialog.getOverridenWidth()); - } - } - } - - return true; -} - -bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event) -{ - if (m_editConfig->m_enableVimMode - && m_vim->handleKeyPressEvent(p_event, &m_autoIndentPos)) { - return true; - } - - bool ret = false; - int key = p_event->key(); - int modifiers = p_event->modifiers(); - - switch (key) { - case Qt::Key_1: - case Qt::Key_2: - case Qt::Key_3: - case Qt::Key_4: - case Qt::Key_5: - case Qt::Key_6: - case Qt::Key_7: - { - if (modifiers == Qt::ControlModifier) { - // Ctrl + : insert title at level . - if (decorateHeading(key == Qt::Key_7 ? 0 : key - Qt::Key_0)) { - p_event->accept(); - ret = true; - goto exit; - } - } - break; - } - - case Qt::Key_Tab: - { - if (handleKeyTab(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_Backtab: - { - if (handleKeyBackTab(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_B: - { - if (modifiers == Qt::ControlModifier) { - decorateBold(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_H: - { - if (handleKeyH(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_I: - { - if (modifiers == Qt::ControlModifier) { - decorateItalic(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_L: - { - if (modifiers == Qt::ControlModifier) { - m_editor->insertLink(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_Apostrophe: - { - if (modifiers == Qt::ControlModifier) { - m_editor->insertImage(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_M: - { - if (modifiers == Qt::ControlModifier) { - decorateCodeBlock(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_Semicolon: - { - if (modifiers == Qt::ControlModifier) { - decorateInlineCode(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_U: - { - if (handleKeyU(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_W: - { - if (handleKeyW(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_BracketLeft: - { - if (handleKeyBracketLeft(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_Escape: - { - if (handleKeyEsc(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_Enter: - // Fall through. - V_FALLTHROUGH; - case Qt::Key_Return: - { - if (handleKeyReturn(p_event)) { - ret = true; - goto exit; - } - break; - } - - case Qt::Key_D: - { - if (modifiers == Qt::ControlModifier) { - decorateStrikethrough(); - p_event->accept(); - ret = true; - } - - break; - } - - case Qt::Key_J: - { - if (VUtils::isControlModifierForVim(modifiers)) { - // Scroll down without changing cursor. - QScrollBar *vbar = m_editor->verticalScrollBarW(); - if (vbar && (vbar->minimum() != vbar->maximum())) { - vbar->triggerAction(QAbstractSlider::SliderSingleStepAdd); - } - - ret = true; - } - - break; - } - - case Qt::Key_K: - { - if (VUtils::isControlModifierForVim(modifiers)) { - // Scroll up without changing cursor. - QScrollBar *vbar = m_editor->verticalScrollBarW(); - if (vbar && (vbar->minimum() != vbar->maximum())) { - vbar->triggerAction(QAbstractSlider::SliderSingleStepSub); - } - - ret = true; - } - - break; - } - - case Qt::Key_N: - { - if (VUtils::isControlModifierForVim(modifiers)) { - // Completion. - if (!m_editor->isCompletionActivated()) { - m_editor->requestCompletion(false); - } - - ret = true; - } - - break; - } - - case Qt::Key_P: - { - if (VUtils::isControlModifierForVim(modifiers)) { - // Completion. - if (!m_editor->isCompletionActivated()) { - m_editor->requestCompletion(true); - } - - ret = true; - } - - break; - } - - case Qt::Key_Period: - { - if (modifiers == Qt::ControlModifier) { - m_editor->insertTable(); - p_event->accept(); - ret = true; - } - - break; - } - - default: - break; - } - -exit: - // Qt::Key_Return, Qt::Key_Tab and Qt::Key_Backtab will handle m_autoIndentPos. - if (key != Qt::Key_Return - && key != Qt::Key_Enter - && key != Qt::Key_Tab - && key != Qt::Key_Backtab - && key != Qt::Key_Shift - && key != Qt::Key_Control - // For mapping Caps as Ctrl in KDE. - && key != Qt::Key_CapsLock) { - m_autoIndentPos = -1; - } - - return ret; -} - -// Let Ctrl+[ behave exactly like ESC. -bool VMdEditOperations::handleKeyBracketLeft(QKeyEvent *p_event) -{ - // 1. If there is any selection, clear it. - // 2. Otherwise, ignore this event and let parent handles it. - if (p_event->modifiers() == Qt::ControlModifier) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.clearSelection(); - m_editor->setTextCursorW(cursor); - p_event->accept(); - return true; - } - } - - return false; -} - -bool VMdEditOperations::handleKeyTab(QKeyEvent *p_event) -{ - QString text(m_editConfig->m_tabSpaces); - - if (p_event->modifiers() == Qt::NoModifier) { - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - m_autoIndentPos = -1; - cursor.beginEditBlock(); - // Indent each selected line. - VEditUtils::indentSelectedBlocks(cursor, text, true); - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - } else { - // If it is a Tab key following auto list, increase the indent level. - QTextBlock block = cursor.block(); - int seq = -1; - if (m_autoIndentPos == cursor.position() - && VEditUtils::isListBlock(block, &seq)) { - QTextCursor blockCursor(block); - blockCursor.beginEditBlock(); - blockCursor.insertText(text); - if (seq != -1) { - changeListBlockSeqNumber(block, 1); - } - blockCursor.endEditBlock(); - // Change m_autoIndentPos to let it can be repeated. - m_autoIndentPos = m_editor->textCursorW().position(); - } else { - // Just insert "tab". - insertText(text); - m_autoIndentPos = -1; - } - } - } else { - m_autoIndentPos = -1; - return false; - } - p_event->accept(); - return true; -} - -bool VMdEditOperations::handleKeyBackTab(QKeyEvent *p_event) -{ - if (p_event->modifiers() != Qt::ShiftModifier) { - m_autoIndentPos = -1; - return false; - } - - QTextCursor cursor = m_editor->textCursorW(); - QTextBlock block = m_editor->documentW()->findBlock(cursor.selectionStart()); - bool continueAutoIndent = false; - int seq = -1; - if (cursor.position() == m_autoIndentPos - && VEditUtils::isListBlock(block, &seq) && - !cursor.hasSelection()) { - continueAutoIndent = true; - } - - cursor.beginEditBlock(); - if (continueAutoIndent && seq != -1) { - changeListBlockSeqNumber(block, 1); - } - - VEditUtils::indentSelectedBlocks(cursor, m_editConfig->m_tabSpaces, false); - cursor.endEditBlock(); - - if (continueAutoIndent) { - m_autoIndentPos = m_editor->textCursorW().position(); - } else { - m_autoIndentPos = -1; - } - p_event->accept(); - return true; -} - -bool VMdEditOperations::handleKeyH(QKeyEvent *p_event) -{ - if (p_event->modifiers() == Qt::ControlModifier) { - // Ctrl+H, equal to backspace. - QTextCursor cursor = m_editor->textCursorW(); - cursor.deletePreviousChar(); - - p_event->accept(); - return true; - } - return false; -} - -bool VMdEditOperations::handleKeyU(QKeyEvent *p_event) -{ - if (p_event->modifiers() == Qt::ControlModifier) { - // Ctrl+U, delete till the start of line. - QTextCursor cursor = m_editor->textCursorW(); - bool ret; - if (cursor.atBlockStart()) { - ret = cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); - } else { - int indent = VEditUtils::fetchIndentation(cursor.block()); - int pib = cursor.positionInBlock(); - if (pib <= indent) { - ret = cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor); - } else { - ret = cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, pib - indent); - } - } - - if (ret) { - cursor.removeSelectedText(); - } - - p_event->accept(); - return true; - } - return false; -} - -bool VMdEditOperations::handleKeyW(QKeyEvent *p_event) -{ - if (p_event->modifiers() == Qt::ControlModifier) { - // Ctrl+W, delete till the start of previous word. - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.removeSelectedText(); - } else { - bool ret = cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); - if (ret) { - cursor.removeSelectedText(); - } - } - p_event->accept(); - return true; - } - return false; -} - -bool VMdEditOperations::handleKeyEsc(QKeyEvent *p_event) -{ - // 1. If there is any selection, clear it. - // 2. Otherwise, ignore this event and let parent handles it. - QTextCursor cursor = m_editor->textCursorW(); - if (cursor.hasSelection()) { - cursor.clearSelection(); - m_editor->setTextCursorW(cursor); - p_event->accept(); - return true; - } - - return false; -} - -bool VMdEditOperations::handleKeyReturn(QKeyEvent *p_event) -{ - bool autolist = true; - bool autoQuote = true; - if (p_event->modifiers() & Qt::ControlModifier) { - m_autoIndentPos = -1; - return false; - } else if (p_event->modifiers() & Qt::ShiftModifier) { - // Insert two spaces and a new line. - m_autoIndentPos = -1; - - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - cursor.removeSelectedText(); - cursor.insertText(" "); - cursor.endEditBlock(); - - // Let remaining logics handle inserting the new block except that we - // do not need to insert auto list. - // But we still need auto quote. - autolist = false; - } - - // See if we need to cancel auto indent. - if (m_autoIndentPos > -1) { - // Cancel the auto indent/list if the pos is the same and cursor is at - // the end of a block. - QTextCursor cursor = m_editor->textCursorW(); - if (VEditUtils::needToCancelAutoIndent(m_autoIndentPos, cursor)) { - m_autoIndentPos = -1; - VEditUtils::deleteIndentAndListMark(cursor); - m_editor->setTextCursorW(cursor); - return true; - } - } - - bool handled = false; - m_autoIndentPos = -1; - if (g_config->getAutoIndent()) { - handled = true; - - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - cursor.removeSelectedText(); - - // Indent the new line as previous line. - bool textInserted = VEditUtils::insertBlockWithIndent(cursor); - - // Continue the list from previous line. - bool listInserted = false; - if (autolist && g_config->getAutoList()) { - listInserted = VEditUtils::insertListMarkAsPreviousBlock(cursor); - textInserted = listInserted || textInserted; - } - - if (autoQuote && !listInserted && g_config->getAutoQuote()) { - textInserted = VEditUtils::insertQuoteMarkAsPreviousBlock(cursor) || textInserted; - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - if (textInserted) { - m_autoIndentPos = m_editor->textCursorW().position(); - } - } - - return handled; -} - -void VMdEditOperations::changeListBlockSeqNumber(QTextBlock &p_block, int p_seq) -{ - QString text = p_block.text(); - QRegExp regExp("^(\\s*)(\\d+)\\.\\s"); - - int idx = regExp.indexIn(text); - if (idx == -1 || regExp.captureCount() != 2) { - return; - } - - int oriSeq = -1; - bool ok = false; - oriSeq = regExp.capturedTexts()[2].toInt(&ok); - if (ok && oriSeq == p_seq) { - return; - } - - QTextCursor cursor(p_block); - bool ret = cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, - regExp.capturedTexts()[1].size()); - if (!ret) { - return; - } - - ret = cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, - regExp.capturedTexts()[2].size()); - if (!ret) { - return; - } - - cursor.removeSelectedText(); - cursor.insertText(QString::number(p_seq)); -} - -bool VMdEditOperations::decorateHeading(int p_level) -{ - QTextDocument *doc = m_editor->documentW(); - QTextCursor cursor = m_editor->textCursorW(); - int firstBlock = cursor.block().blockNumber(); - int lastBlock = firstBlock; - - if (cursor.hasSelection()) { - // Insert title # in front of the selected blocks. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - firstBlock = doc->findBlock(start).blockNumber(); - lastBlock = doc->findBlock(end).blockNumber(); - } - - cursor.beginEditBlock(); - for (int i = firstBlock; i <= lastBlock; ++i) { - VEditUtils::insertTitleMark(cursor, doc->findBlockByNumber(i), p_level); - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - return true; -} - -void VMdEditOperations::decorateText(TextDecoration p_decoration, int p_level) -{ - if (p_decoration == TextDecoration::None) { - return; - } - - bool validDecoration = true; - switch (p_decoration) { - case TextDecoration::Bold: - decorateBold(); - break; - - case TextDecoration::Italic: - decorateItalic(); - break; - - case TextDecoration::Strikethrough: - decorateStrikethrough(); - break; - - case TextDecoration::InlineCode: - decorateInlineCode(); - break; - - case TextDecoration::CodeBlock: - decorateCodeBlock(); - break; - - case TextDecoration::Heading: - decorateHeading(p_level); - break; - - default: - validDecoration = false; - qDebug() << "decoration" << (int)p_decoration << "is not implemented yet"; - break; - } - - if (validDecoration && m_editConfig->m_enableVimMode) { - Q_ASSERT(m_vim); - m_vim->setMode(VimMode::Insert, false); - } -} - -void VMdEditOperations::decorateBold() -{ - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert ** around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - cursor.clearSelection(); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.insertText("**"); - cursor.setPosition(end + 2, QTextCursor::MoveAnchor); - cursor.insertText("**"); - } else { - // Insert **** and place cursor in the middle. - // Or if there are two * after current cursor, just skip them or delete - // them if four * appear. - int pos = cursor.positionInBlock(); - bool hasStars = false; - bool emptyMarkers = false; - QString text = cursor.block().text(); - if (pos <= text.size() - 2) { - if (text[pos] == '*' && text[pos + 1] == '*') { - hasStars = true; - - if (pos >= 2 - && text[pos - 1] == '*' - && text[pos - 2] == '*') { - emptyMarkers = true; - } - } - } - - if (hasStars) { - if (emptyMarkers) { - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 2); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 4); - cursor.removeSelectedText(); - } else { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2); - } - } else { - cursor.insertText("****"); - cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -void VMdEditOperations::decorateItalic() -{ - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert * around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - cursor.clearSelection(); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.insertText("*"); - cursor.setPosition(end + 1, QTextCursor::MoveAnchor); - cursor.insertText("*"); - } else { - // Insert ** and place cursor in the middle. - // Or if there are one * after current cursor, just skip them or delete - // them if two * appear. - int pos = cursor.positionInBlock(); - bool hasStar = false; - bool emptyMarkers = false; - QString text = cursor.block().text(); - if (pos <= text.size() - 1) { - if (text[pos] == '*' - && (pos == text.size() - 1 || text[pos + 1] != '*')) { - hasStar = true; - - if (pos >= 1 && text[pos - 1] == '*') { - emptyMarkers = true; - } - } - } - - if (hasStar) { - if (emptyMarkers) { - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 1); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2); - cursor.removeSelectedText(); - } else { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - } - } else { - cursor.insertText("**"); - cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -void VMdEditOperations::decorateInlineCode() -{ - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert ` around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - cursor.clearSelection(); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.insertText("`"); - cursor.setPosition(end + 1, QTextCursor::MoveAnchor); - cursor.insertText("`"); - } else { - // Insert `` and place cursor in the middle. - // Or if there are one ` after current cursor, just skip them or delete - // them if two ` appear. - int pos = cursor.positionInBlock(); - bool hasBackquote = false; - bool emptyMarkers = false; - QString text = cursor.block().text(); - if (pos <= text.size() - 1) { - if (text[pos] == '`') { - hasBackquote = true; - - if (pos >= 1 && text[pos - 1] == '`') { - emptyMarkers = true; - } - } - } - - if (hasBackquote) { - if (emptyMarkers) { - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 1); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2); - cursor.removeSelectedText(); - } else { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1); - } - } else { - cursor.insertText("``"); - cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -void VMdEditOperations::decorateCodeBlock() -{ - const QString marker("```"); - - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert ``` around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - - QString indentation = VEditUtils::fetchIndentSpaces(cursor.block()); - - // Insert the end marker first. - cursor.setPosition(end, QTextCursor::MoveAnchor); - VEditUtils::insertBlock(cursor, false); - VEditUtils::indentBlock(cursor, indentation); - cursor.insertText(marker); - - // Insert the start marker. - cursor.setPosition(start, QTextCursor::MoveAnchor); - VEditUtils::insertBlock(cursor, true); - VEditUtils::indentBlock(cursor, indentation); - cursor.insertText(marker); - } else { - // Insert ``` ``` and place cursor after the first marker. - // Or if current block or next block is ```, we will skip it. - QTextBlock block = cursor.block(); - int state = block.userState(); - if (state == HighlightBlockState::CodeBlock - || state == HighlightBlockState::CodeBlockStart - || state == HighlightBlockState::CodeBlockEnd) { - // Find the block end. - QTextBlock endBlock = block; - while (endBlock.isValid()) { - if (endBlock.userState() == HighlightBlockState::CodeBlockEnd) { - break; - } - - endBlock = endBlock.next(); - } - - if (endBlock.isValid()) { - // It is CodeBlockEnd. - if (endBlock.previous().isValid() - && endBlock.previous().userState() == HighlightBlockState::CodeBlockStart) { - // Delete empty code blocks. - cursor.setPosition(endBlock.previous().position()); - cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - cursor.removeSelectedText(); - } else { - cursor.setPosition(endBlock.position()); - if (endBlock.next().isValid()) { - cursor.movePosition(QTextCursor::NextBlock); - cursor.movePosition(QTextCursor::StartOfBlock); - } else { - cursor.movePosition(QTextCursor::EndOfBlock); - } - } - } else { - // Reach the end of the document. - cursor.movePosition(QTextCursor::End); - } - } else { - bool insertInline = false; - if (!cursor.atBlockEnd()) { - cursor.insertBlock(); - cursor.movePosition(QTextCursor::PreviousBlock); - } else if (cursor.atBlockStart() || VEditUtils::isSpaceBlock(block)) { - insertInline = true; - } - - if (!insertInline) { - VEditUtils::insertBlock(cursor, false); - VEditUtils::indentBlockAsBlock(cursor, false); - } - - cursor.insertText(marker); - - VEditUtils::insertBlock(cursor, true); - VEditUtils::indentBlockAsBlock(cursor, true); - cursor.insertText(marker); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -void VMdEditOperations::decorateStrikethrough() -{ - QTextCursor cursor = m_editor->textCursorW(); - cursor.beginEditBlock(); - if (cursor.hasSelection()) { - // Insert ~~ around the selected text. - int start = cursor.selectionStart(); - int end = cursor.selectionEnd(); - cursor.clearSelection(); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.insertText("~~"); - cursor.setPosition(end + 2, QTextCursor::MoveAnchor); - cursor.insertText("~~"); - } else { - // Insert ~~~~ and place cursor in the middle. - // Or if there are one ~~ after current cursor, just skip it or delete - // it if for ~ appear. - int pos = cursor.positionInBlock(); - bool hasStrikethrough = false; - bool emptyMarkers = false; - QString text = cursor.block().text(); - if (pos <= text.size() - 2) { - if (text[pos] == '~' && text[pos + 1] == '~') { - hasStrikethrough = true; - - if (pos >= 2 - && text[pos - 1] == '~' - && text[pos - 2] == '~') { - emptyMarkers = true; - } - } - } - - if (hasStrikethrough) { - if (emptyMarkers) { - cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, 2); - cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 4); - cursor.removeSelectedText(); - } else { - cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2); - } - } else { - cursor.insertText("~~~~"); - cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); - } - } - - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); -} - -bool VMdEditOperations::insertLink(const QString &p_linkText, - const QString &p_linkUrl) -{ - QString link = QString("[%1](%2)").arg(p_linkText).arg(QDir::fromNativeSeparators(p_linkUrl)); - insertText(link); - - setVimMode(VimMode::Insert); - - return true; -} - -bool VMdEditOperations::insertImageLink(const QString &p_linkText, - const QString &p_linkUrl) -{ - QTextCursor cursor = m_editor->textCursorW(); - cursor.insertText(imageLink(p_linkText, QDir::fromNativeSeparators(p_linkUrl))); - m_editor->setTextCursorW(cursor); - - setVimMode(VimMode::Insert); - - return true; -} diff --git a/src/vmdeditoperations.h b/src/vmdeditoperations.h deleted file mode 100644 index 3c932fc8..00000000 --- a/src/vmdeditoperations.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef VMDEDITOPERATIONS_H -#define VMDEDITOPERATIONS_H - -#include -#include -#include -#include -#include -#include "veditoperations.h" - -class QTimer; - -// Editor operations for Markdown -class VMdEditOperations : public VEditOperations -{ - Q_OBJECT -public: - VMdEditOperations(VEditor *p_editor, VFile *p_file); - - bool insertImageFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE; - - bool insertImage() Q_DECL_OVERRIDE; - - bool handleKeyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - bool insertImageFromURL(const QUrl &p_imageUrl) Q_DECL_OVERRIDE; - - bool insertLink(const QString &p_linkText, - const QString &p_linkUrl) Q_DECL_OVERRIDE; - - // Insert decoration markers or decorate selected text. - // If it is Vim Normal mode, change to Insert mode first. - void decorateText(TextDecoration p_decoration, int p_level = -1) Q_DECL_OVERRIDE; - - bool insertImageLink(const QString &p_linkText, const QString &p_linkUrl); - - // @p_urlInLink and @p_destImagePath will be empty on failure. - void insertImageFromPath(const QString &p_title, - const QString &p_folderPath, - const QString &p_folderInLink, - const QString &p_srcImagePath, - bool p_insertText, - QString &p_destImagePath, - QString &p_urlInLink, - int p_width = 0, - int p_height = 0); - -private: - // Insert image from @p_srcImagePath as to @p_folderPath. - // @p_folderInLink: the folder part in the image link. - void insertImageFromPath(const QString &p_title, - const QString &p_folderPath, - const QString &p_folderInLink, - const QString &p_srcImagePath, - int p_width = 0, - int p_height = 0); - - // @p_title: title of the inserted image; - // @p_folderPath: the image folder path to insert the image in; - // @p_folderInLink: the folder part in the image link. - // @p_image: the image to be inserted; - void insertImageFromQImage(const QString &p_title, - const QString &p_folderPath, - const QString &p_folderInLink, - const QImage &p_image, - int p_width = 0, - int p_height = 0); - - // Key press handlers. - bool handleKeyTab(QKeyEvent *p_event); - bool handleKeyBackTab(QKeyEvent *p_event); - bool handleKeyH(QKeyEvent *p_event); - bool handleKeyU(QKeyEvent *p_event); - bool handleKeyW(QKeyEvent *p_event); - bool handleKeyEsc(QKeyEvent *p_event); - bool handleKeyReturn(QKeyEvent *p_event); - bool handleKeyBracketLeft(QKeyEvent *p_event); - - // Change the sequence number of a list block. - void changeListBlockSeqNumber(QTextBlock &p_block, int p_seq); - - // Insert bold marker or set selected text bold. - void decorateBold(); - - // Insert italic marker or set selected text italic. - void decorateItalic(); - - // Insert inline-code marker or set selected text inline-coded. - void decorateInlineCode(); - - // Insert inline-code marker or set selected text inline-coded. - void decorateCodeBlock(); - - // Insert strikethrough marker or set selected text strikethrough. - void decorateStrikethrough(); - - // Insert title of level @p_level. - // Will detect if current block already has some leading #s. If yes, - // will delete it and insert the correct #s. - // @p_level: 0 to cancel title. - bool decorateHeading(int p_level); - - // The cursor position after auto indent or auto list. - // It will be -1 if last key press do not trigger the auto indent or auto list. - int m_autoIndentPos; - - static const QString c_defaultImageTitle; -}; - -#endif // VMDEDITOPERATIONS_H diff --git a/src/vmdeditor.cpp b/src/vmdeditor.cpp deleted file mode 100644 index b741fb60..00000000 --- a/src/vmdeditor.cpp +++ /dev/null @@ -1,2309 +0,0 @@ -#include "vmdeditor.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vdocument.h" -#include "utils/veditutils.h" -#include "vedittab.h" -#include "pegmarkdownhighlighter.h" -#include "vcodeblockhighlighthelper.h" -#include "vmdeditoperations.h" -#include "vtableofcontent.h" -#include "utils/veditutils.h" -#include "dialog/vselectdialog.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "vtextblockdata.h" -#include "vorphanfile.h" -#include "vnotefile.h" -#include "vpreviewmanager.h" -#include "utils/viconutils.h" -#include "dialog/vcopytextashtmldialog.h" -#include "utils/vwebutils.h" -#include "dialog/vinsertlinkdialog.h" -#include "utils/vclipboardutils.h" -#include "vplantumlhelper.h" -#include "vgraphvizhelper.h" -#include "vmdtab.h" -#include "vdownloader.h" -#include "vtablehelper.h" -#include "dialog/vinserttabledialog.h" - -extern VWebUtils *g_webUtils; - -extern VConfigManager *g_config; - -#define LINE_NUMBER_AREA_FONT_DELTA -2 - -VMdEditor::VMdEditor(VFile *p_file, - VDocument *p_doc, - MarkdownConverterType p_type, - const QSharedPointer &p_completer, - QWidget *p_parent) - : VTextEdit(p_parent), - VEditor(p_file, this, p_completer), - m_pegHighlighter(NULL), - m_freshEdit(true), - m_textToHtmlDialog(NULL), - m_zoomDelta(0), - m_editTab(NULL), - m_copyTimeStamp(0) -{ - Q_ASSERT(p_file->getDocType() == DocType::Markdown); - - VEditor::init(); - - // Hook functions from VEditor. - connect(this, &VTextEdit::cursorPositionChanged, - this, [this]() { - highlightOnCursorPositionChanged(); - }); - - connect(document(), &QTextDocument::contentsChange, - this, [this](int p_position, int p_charsRemoved, int p_charsAdded) { - Q_UNUSED(p_position); - if (p_charsRemoved > 0 || p_charsAdded > 0) { - updateTimeStamp(); - } - }); - - connect(this, &VTextEdit::selectionChanged, - this, [this]() { - highlightSelectedWord(); - }); - // End. - - setReadOnly(true); - - m_pegHighlighter = new PegMarkdownHighlighter(document(), this); - m_pegHighlighter->init(g_config->getMdHighlightingStyles(), - g_config->getCodeBlockStyles(), - g_config->getEnableMathjax(), - g_config->getMarkdownHighlightInterval()); - connect(m_pegHighlighter, &PegMarkdownHighlighter::headersUpdated, - this, &VMdEditor::updateHeaders); - - // After highlight, the cursor may trun into non-visible. We should make it visible - // in this case. - connect(m_pegHighlighter, &PegMarkdownHighlighter::highlightCompleted, - this, [this]() { - scrollCursorLineIfNecessary(); - - if (m_freshEdit) { - m_freshEdit = false; - emit m_object->ready(); - } - }); - - m_cbHighlighter = new VCodeBlockHighlightHelper(m_pegHighlighter, - p_doc, - p_type); - - m_previewMgr = new VPreviewManager(this, m_pegHighlighter); - connect(m_pegHighlighter, &PegMarkdownHighlighter::imageLinksUpdated, - m_previewMgr, &VPreviewManager::updateImageLinks); - connect(m_previewMgr, &VPreviewManager::requestUpdateImageLinks, - m_pegHighlighter, &PegMarkdownHighlighter::updateHighlight); - - m_tableHelper = new VTableHelper(this); - connect(m_pegHighlighter, &PegMarkdownHighlighter::tableBlocksUpdated, - m_tableHelper, &VTableHelper::updateTableBlocks); - - m_editOps = new VMdEditOperations(this, m_file); - connect(m_editOps, &VEditOperations::statusMessage, - m_object, &VEditorObject::statusMessage); - connect(m_editOps, &VEditOperations::vimStatusUpdated, - m_object, &VEditorObject::vimStatusUpdated); - - connect(this, &VTextEdit::cursorPositionChanged, - this, &VMdEditor::updateCurrentHeader); - - connect(this, &VTextEdit::cursorPositionChanged, - m_object, &VEditorObject::cursorPositionChanged); - - setDisplayScaleFactor(VUtils::calculateScaleFactor()); - - updateFontAndPalette(); - - updateConfig(); -} - -void VMdEditor::updateFontAndPalette() -{ - QFont font(g_config->getMdEditFont()); - font.setPointSize(font.pointSize() + m_zoomDelta); - setFont(font); - - const QPalette &palette = g_config->getMdEditPalette(); - - /* - Do not use this function in conjunction with Qt Style Sheets. When - using style sheets, the palette of a widget can be customized using - the "color", "background-color", "selection-color", - "selection-background-color" and "alternate-background-color". - */ - // setPalette(palette); - // setTextColor(palette.color(QPalette::Text)); - - // Only this could override the font-family set of QWidget in QSS. - setFontAndPaletteByStyleSheet(font, palette); - - font.setPointSize(font.pointSize() + LINE_NUMBER_AREA_FONT_DELTA); - updateLineNumberAreaWidth(QFontMetrics(font)); -} - -void VMdEditor::beginEdit() -{ - updateConfig(); - - initInitImages(); - - setModified(false); - - setReadOnlyAndHighlightCurrentLine(false); - - emit statusChanged(); - - if (m_freshEdit) { - m_pegHighlighter->updateHighlight(); - relayout(); - } else { - updateHeaders(m_pegHighlighter->getHeaderRegions()); - } -} - -void VMdEditor::endEdit() -{ - setReadOnlyAndHighlightCurrentLine(true); - - clearUnusedImages(); -} - -void VMdEditor::saveFile() -{ - Q_ASSERT(m_file->isModifiable()); - - if (!document()->isModified()) { - return; - } - - m_file->setContent(toPlainText()); - setModified(false); - - clearUnusedImages(); - - initInitImages(); -} - -void VMdEditor::reloadFile() -{ - bool readonly = isReadOnly(); - setReadOnly(true); - - const QString &content = m_file->getContent(); - setPlainText(content); - setModified(false); - - setReadOnly(readonly); - - if (!m_freshEdit) { - m_freshEdit = true; - refreshPreview(); - } -} - -bool VMdEditor::scrollToBlock(int p_blockNumber) -{ - QTextBlock block = document()->findBlockByNumber(p_blockNumber); - if (block.isValid()) { - scrollBlockInPage(block.blockNumber(), 0); - moveCursor(QTextCursor::EndOfBlock); - return true; - } - - return false; -} - -// Get the visual offset of a block. -#define GETVISUALOFFSETY(x) (contentOffsetY() + (int)(x).y()) - -void VMdEditor::makeBlockVisible(const QTextBlock &p_block) -{ - if (!p_block.isValid() || !p_block.isVisible()) { - return; - } - - QScrollBar *vbar = verticalScrollBar(); - if (!vbar || (vbar->minimum() == vbar->maximum())) { - // No vertical scrollbar. No need to scroll. - return; - } - - int height = rect().height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && (hbar->minimum() != hbar->maximum())) { - height -= hbar->height(); - } - - bool moved = false; - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - QRectF rt = layout->blockBoundingRect(p_block); - int y = GETVISUALOFFSETY(rt); - int rectHeight = (int)rt.height(); - - // Handle the case rectHeight >= height. - if (rectHeight >= height) { - if (y < 0) { - // Need to scroll up. - while (y + rectHeight < height && vbar->value() > vbar->minimum()) { - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - rt = layout->blockBoundingRect(p_block); - rectHeight = (int)rt.height(); - y = GETVISUALOFFSETY(rt); - } - } else if (y > 0) { - // Need to scroll down. - while (y > 0 && vbar->value() < vbar->maximum()) { - moved = true; - vbar->setValue(vbar->value() + vbar->singleStep()); - rt = layout->blockBoundingRect(p_block); - rectHeight = (int)rt.height(); - y = GETVISUALOFFSETY(rt); - } - - if (y < 0) { - // One step back. - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - } - } - - return; - } - - // There is an extra line leading in the layout, so there will always be a scroll - // action to scroll the page down. - while (y < 0 && vbar->value() > vbar->minimum()) { - moved = true; - vbar->setValue(vbar->value() - vbar->singleStep()); - rt = layout->blockBoundingRect(p_block); - y = GETVISUALOFFSETY(rt); - } - - if (moved) { - return; - } - - while (y + rectHeight > height && vbar->value() < vbar->maximum()) { - vbar->setValue(vbar->value() + vbar->singleStep()); - rt = layout->blockBoundingRect(p_block); - rectHeight = (int)rt.height(); - y = GETVISUALOFFSETY(rt); - } -} - -static QAction *getActionByObjectName(const QList &p_actions, - const QString &p_objName) -{ - for (auto act : p_actions) { - if (act->objectName() == p_objName) { - return act; - } - } - - return NULL; -} - -// Insert @p_action into @p_menu after action @p_after. -static void insertActionAfter(QAction *p_after, QAction *p_action, QMenu *p_menu) -{ - p_menu->insertAction(p_after, p_action); - if (p_after) { - p_menu->removeAction(p_after); - p_menu->insertAction(p_action, p_after); - } -} - -static QAction *insertMenuAfter(QAction *p_after, QMenu *p_subMenu, QMenu *p_menu) -{ - QAction *menuAct = p_menu->insertMenu(p_after, p_subMenu); - if (p_after) { - p_menu->removeAction(p_after); - p_menu->insertAction(menuAct, p_after); - } - - return menuAct; -} - -void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event) -{ - if (!m_editTab || !m_editTab->isEditMode()) { - return; - } - - QScopedPointer menu(createStandardContextMenu()); - menu->setToolTipsVisible(true); - - QAction *copyAct, *pasteAct, *firstAct; - { - const QList actions = menu->actions(); - firstAct = actions.isEmpty() ? NULL : actions.first(); - copyAct = getActionByObjectName(actions, "edit-copy"); - pasteAct = getActionByObjectName(actions, "edit-paste"); - } - - if (copyAct && copyAct->isEnabled()) { - initCopyAsMenu(copyAct, menu.data()); - } - - if (pasteAct && pasteAct->isEnabled()) { - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - if (mimeData->hasText()) { - initPasteAsBlockQuoteMenu(pasteAct, menu.data()); - } - - if (mimeData->hasHtml()) { - initPasteAfterParseMenu(pasteAct, menu.data()); - } - - QAction *pptAct = new QAction(tr("Paste As Plain Text"), menu.data()); - VUtils::fixTextWithShortcut(pptAct, "PastePlainText"); - connect(pptAct, &QAction::triggered, - this, [this]() { - pastePlainText(); - }); - insertActionAfter(pasteAct, pptAct, menu.data()); - } - - if (!textCursor().hasSelection()) { - initLinkAndPreviewMenu(firstAct, menu.data(), p_event->pos()); - - QAction *saveExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/save_exit.svg"), - tr("&Save Changes And Read"), - menu.data()); - saveExitAct->setToolTip(tr("Save changes and exit edit mode")); - connect(saveExitAct, &QAction::triggered, - this, [this]() { - emit m_object->saveAndRead(); - }); - - QAction *discardExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/discard_exit.svg"), - tr("&Discard Changes And Read"), - menu.data()); - discardExitAct->setToolTip(tr("Discard changes and exit edit mode")); - connect(discardExitAct, &QAction::triggered, - this, [this]() { - emit m_object->discardAndRead(); - }); - - VMdTab *mdtab = dynamic_cast(m_editTab); - if (mdtab) { - QAction *toggleLivePreviewAct = new QAction(tr("Live Preview For Graphs"), menu.data()); - toggleLivePreviewAct->setToolTip(tr("Toggle live preview panel for graphs")); - VUtils::fixTextWithCaptainShortcut(toggleLivePreviewAct, "LivePreview"); - connect(toggleLivePreviewAct, &QAction::triggered, - this, [mdtab]() { - mdtab->toggleLivePreview(); - }); - - menu->insertAction(firstAct, toggleLivePreviewAct); - menu->insertAction(toggleLivePreviewAct, discardExitAct); - menu->insertAction(discardExitAct, saveExitAct); - menu->insertSeparator(toggleLivePreviewAct); - } else { - menu->insertAction(firstAct, discardExitAct); - menu->insertAction(discardExitAct, saveExitAct); - menu->insertSeparator(discardExitAct); - } - - if (firstAct) { - menu->insertSeparator(firstAct); - } - - initAttachmentMenu(menu.data()); - - initImageHostingMenu(menu.data()); - } - - menu->exec(p_event->globalPos()); -} - -void VMdEditor::mousePressEvent(QMouseEvent *p_event) -{ - if (handleMousePressEvent(p_event)) { - return; - } - - VTextEdit::mousePressEvent(p_event); - - emit m_object->mousePressed(p_event); -} - -void VMdEditor::mouseDoubleClickEvent(QMouseEvent *p_event) -{ - VTextEdit::mouseDoubleClickEvent(p_event); - - emit m_object->mouseDoubleClicked(p_event); -} - -void VMdEditor::mouseReleaseEvent(QMouseEvent *p_event) -{ - if (handleMouseReleaseEvent(p_event)) { - return; - } - - VTextEdit::mouseReleaseEvent(p_event); - - emit m_object->mouseReleased(p_event); -} - -void VMdEditor::mouseMoveEvent(QMouseEvent *p_event) -{ - if (handleMouseMoveEvent(p_event)) { - return; - } - - VTextEdit::mouseMoveEvent(p_event); - - emit m_object->mouseMoved(p_event); -} - -QVariant VMdEditor::inputMethodQuery(Qt::InputMethodQuery p_query) const -{ - QVariant ret; - if (handleInputMethodQuery(p_query, ret)) { - return ret; - } - - return VTextEdit::inputMethodQuery(p_query); -} - -bool VMdEditor::isBlockVisible(const QTextBlock &p_block) -{ - if (!p_block.isValid() || !p_block.isVisible()) { - return false; - } - - QScrollBar *vbar = verticalScrollBar(); - if (!vbar || !vbar->isVisible()) { - // No vertical scrollbar. - return true; - } - - int height = rect().height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && hbar->isVisible()) { - height -= hbar->height(); - } - - QAbstractTextDocumentLayout *layout = document()->documentLayout(); - QRectF rt = layout->blockBoundingRect(p_block); - int y = GETVISUALOFFSETY(rt); - int rectHeight = (int)rt.height(); - - return (y >= 0 && y < height) || (y < 0 && y + rectHeight > 0); -} - -static void addHeaderSequence(QVector &p_sequence, int p_level, int p_baseLevel) -{ - Q_ASSERT(p_level >= 1 && p_level < p_sequence.size()); - if (p_level < p_baseLevel) { - p_sequence.fill(0); - return; - } - - ++p_sequence[p_level]; - for (int i = p_level + 1; i < p_sequence.size(); ++i) { - p_sequence[i] = 0; - } -} - -static QString headerSequenceStr(const QVector &p_sequence) -{ - QString res; - for (int i = 1; i < p_sequence.size(); ++i) { - if (p_sequence[i] != 0) { - res = res + QString::number(p_sequence[i]) + '.'; - } else if (res.isEmpty()) { - continue; - } else { - break; - } - } - - return res; -} - -static void insertSequenceToHeader(QTextCursor& p_cursor, - const QTextBlock &p_block, - QRegExp &p_reg, - QRegExp &p_preReg, - const QString &p_seq) -{ - if (!p_block.isValid()) { - return; - } - - QString text = p_block.text(); - bool matched = p_reg.exactMatch(text); - Q_ASSERT(matched); - - matched = p_preReg.exactMatch(text); - Q_ASSERT(matched); - - int start = p_reg.cap(1).length() + 1; - int end = p_preReg.cap(1).length(); - - Q_ASSERT(start <= end); - - p_cursor.setPosition(p_block.position() + start); - if (start != end) { - p_cursor.setPosition(p_block.position() + end, QTextCursor::KeepAnchor); - } - - if (p_seq.isEmpty()) { - p_cursor.removeSelectedText(); - } else { - p_cursor.insertText(p_seq + ' '); - } -} - -void VMdEditor::updateHeaderSequenceByConfigChange() -{ - updateHeadersHelper(m_pegHighlighter->getHeaderRegions(), true); -} - -void VMdEditor::updateHeadersHelper(const QVector &p_headerRegions, bool p_configChanged) -{ - QTextDocument *doc = document(); - - QVector headers; - QVector headerBlockNumbers; - QVector headerSequences; - if (!p_headerRegions.isEmpty()) { - headers.reserve(p_headerRegions.size()); - headerBlockNumbers.reserve(p_headerRegions.size()); - headerSequences.reserve(p_headerRegions.size()); - } - - // Assume that each block contains only one line - // Only support # syntax for now - QRegExp headerReg(VUtils::c_headerRegExp); - int baseLevel = -1; - for (auto const & reg : p_headerRegions) { - QTextBlock block = doc->findBlock(reg.m_startPos); - if (!block.isValid()) { - continue; - } - - if (!block.contains(reg.m_endPos - 1)) { - qWarning() << "header accross multiple blocks, starting from block" - << block.blockNumber() - << block.text(); - } - - if (headerReg.exactMatch(block.text())) { - int level = headerReg.cap(1).length(); - VTableOfContentItem header(headerReg.cap(2).trimmed(), - level, - block.blockNumber(), - headers.size()); - headers.append(header); - headerBlockNumbers.append(block.blockNumber()); - headerSequences.append(headerReg.cap(3)); - - if (baseLevel == -1) { - baseLevel = level; - } else if (baseLevel > level) { - baseLevel = level; - } - } - } - - m_headers.clear(); - - bool autoSequence = m_config.m_enableHeadingSequence - && !isReadOnly() - && m_file->isModifiable(); - int headingSequenceBaseLevel = g_config->getHeadingSequenceBaseLevel(); - if (headingSequenceBaseLevel < 1 || headingSequenceBaseLevel > 6) { - headingSequenceBaseLevel = 1; - } - - QVector seqs(7, 0); - QRegExp preReg(VUtils::c_headerPrefixRegExp); - int curLevel = baseLevel - 1; - QTextCursor cursor(doc); - if(autoSequence || p_configChanged) { - cursor.beginEditBlock(); - } - - for (int i = 0; i < headers.size(); ++i) { - VTableOfContentItem &item = headers[i]; - while (item.m_level > curLevel + 1) { - curLevel += 1; - - // Insert empty level which is an invalid header. - m_headers.append(VTableOfContentItem(c_emptyHeaderName, - curLevel, - -1, - m_headers.size())); - if (autoSequence || p_configChanged) { - addHeaderSequence(seqs, curLevel, headingSequenceBaseLevel); - } - } - - item.m_index = m_headers.size(); - m_headers.append(item); - curLevel = item.m_level; - if (autoSequence || p_configChanged) { - addHeaderSequence(seqs, item.m_level, headingSequenceBaseLevel); - - QString seqStr = autoSequence ? headerSequenceStr(seqs) : ""; - if (headerSequences[i] != seqStr) { - // Insert correct sequence. - insertSequenceToHeader(cursor, - doc->findBlockByNumber(headerBlockNumbers[i]), - headerReg, - preReg, - seqStr); - } - } - } - - if (autoSequence || p_configChanged) { - cursor.endEditBlock(); - } - - emit headersChanged(m_headers); - - updateCurrentHeader(); -} - -void VMdEditor::updateHeaders(const QVector &p_headerRegions) -{ - updateHeadersHelper(p_headerRegions, false); -} - -void VMdEditor::updateCurrentHeader() -{ - emit currentHeaderChanged(textCursor().block().blockNumber()); -} - -void VMdEditor::initInitImages() -{ - m_initImages = VUtils::fetchImagesFromMarkdownFile(m_file, - ImageLink::LocalRelativeInternal); -} - -void VMdEditor::clearUnusedImages() -{ - QVector images = VUtils::fetchImagesFromMarkdownFile(m_file, - ImageLink::LocalRelativeInternal); - - QSet unusedImages; - - if (!m_insertedImages.isEmpty()) { - for (int i = 0; i < m_insertedImages.size(); ++i) { - const ImageLink &link = m_insertedImages[i]; - - if (link.m_type != ImageLink::LocalRelativeInternal) { - continue; - } - - int j; - for (j = 0; j < images.size(); ++j) { - if (VUtils::equalPath(link.m_path, images[j].m_path)) { - break; - } - } - - // This inserted image is no longer in the file. - if (j == images.size()) { - unusedImages.insert(link.m_path); - } - } - - m_insertedImages.clear(); - } - - for (int i = 0; i < m_initImages.size(); ++i) { - const ImageLink &link = m_initImages[i]; - - V_ASSERT(link.m_type == ImageLink::LocalRelativeInternal); - - int j; - for (j = 0; j < images.size(); ++j) { - if (VUtils::equalPath(link.m_path, images[j].m_path)) { - break; - } - } - - // Original local relative image is no longer in the file. - if (j == images.size()) { - unusedImages.insert(link.m_path); - } - } - - if (!unusedImages.isEmpty()) { - if (g_config->getConfirmImagesCleanUp()) { - QVector items; - for (auto const & img : unusedImages) { - items.push_back(ConfirmItemInfo(img, - img, - img, - NULL)); - - } - - QString text = tr("Following images seems not to be used in this note anymore. " - "Please confirm the deletion of these images."); - - QString info = tr("Deleted files could be found in the recycle " - "bin of this note.
    " - "Click \"Cancel\" to leave them untouched."); - - VConfirmDeletionDialog dialog(tr("Confirm Cleaning Up Unused Images"), - text, - info, - items, - true, - true, - true, - this); - - unusedImages.clear(); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - g_config->setConfirmImagesCleanUp(dialog.getAskAgainEnabled()); - - for (auto const & item : items) { - unusedImages.insert(item.m_name); - } - } - } - - for (auto const & item : unusedImages) { - bool ret = false; - if (m_file->getType() == FileType::Note) { - const VNoteFile *tmpFile = static_cast((VFile *)m_file); - ret = VUtils::deleteFile(tmpFile->getNotebook(), item, false); - } else if (m_file->getType() == FileType::Orphan) { - const VOrphanFile *tmpFile = static_cast((VFile *)m_file); - ret = VUtils::deleteFile(tmpFile, item, false); - } else { - Q_ASSERT(false); - } - - if (!ret) { - qWarning() << "fail to delete unused original image" << item; - } else { - qDebug() << "delete unused image" << item; - } - } - } - - m_initImages.clear(); -} - -void VMdEditor::keyPressEvent(QKeyEvent *p_event) -{ - int key = p_event->key(); - int modifiers = p_event->modifiers(); - switch (key) { - case Qt::Key_Minus: - case Qt::Key_Underscore: - // Zoom out. - if (modifiers & Qt::ControlModifier) { - zoomPage(false); - return; - } - - break; - - case Qt::Key_Plus: - case Qt::Key_Equal: - // Zoom in. - if (modifiers & Qt::ControlModifier) { - zoomPage(true); - return; - } - - break; - - case Qt::Key_0: - // Restore zoom. - if (modifiers & Qt::ControlModifier) { - if (m_zoomDelta > 0) { - zoomPage(false, m_zoomDelta); - } else if (m_zoomDelta < 0) { - zoomPage(true, -m_zoomDelta); - } - - return; - } - - break; - - default: - break; - } - - if (m_editOps && m_editOps->handleKeyPressEvent(p_event)) { - return; - } - - // Esc to exit edit mode when Vim is disabled. - if (key == Qt::Key_Escape) { - emit m_object->discardAndRead(); - return; - } - - VTextEdit::keyPressEvent(p_event); -} - -bool VMdEditor::canInsertFromMimeData(const QMimeData *p_source) const -{ - return p_source->hasImage() - || p_source->hasUrls() - || VTextEdit::canInsertFromMimeData(p_source); -} - -void VMdEditor::insertFromMimeData(const QMimeData *p_source) -{ - if (processHtmlFromMimeData(p_source)) { - return; - } - - if (processImageFromMimeData(p_source)) { - return; - } - - if (processUrlFromMimeData(p_source)) { - return; - } - - VTextEdit::insertFromMimeData(p_source); -} - -void VMdEditor::imageInserted(const QString &p_path, const QString &p_url) -{ - ImageLink link; - link.m_path = p_path; - link.m_url = p_url; - if (m_file->useRelativeImageFolder()) { - link.m_type = ImageLink::LocalRelativeInternal; - } else { - link.m_type = ImageLink::LocalAbsolute; - } - - m_insertedImages.append(link); -} - -bool VMdEditor::scrollToHeader(int p_blockNumber) -{ - if (p_blockNumber < 0) { - return false; - } - - return scrollToBlock(p_blockNumber); -} - -int VMdEditor::indexOfCurrentHeader() const -{ - if (m_headers.isEmpty()) { - return -1; - } - - int blockNumber = textCursor().block().blockNumber(); - for (int i = m_headers.size() - 1; i >= 0; --i) { - if (!m_headers[i].isEmpty() - && m_headers[i].m_blockNumber <= blockNumber) { - return i; - } - } - - return -1; -} - -bool VMdEditor::jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) -{ - if (m_headers.isEmpty()) { - return false; - } - - QTextCursor cursor = textCursor(); - int cursorLine = cursor.block().blockNumber(); - int targetIdx = -1; - // -1: skip level check. - int targetLevel = 0; - int idx = indexOfCurrentHeader(); - if (idx == -1) { - // Cursor locates at the beginning, before any headers. - if (p_relativeLevel < 0 || !p_forward) { - return false; - } - } - - int delta = 1; - if (!p_forward) { - delta = -1; - } - - bool firstHeader = true; - for (targetIdx = idx == -1 ? 0 : idx; - targetIdx >= 0 && targetIdx < m_headers.size(); - targetIdx += delta) { - const VTableOfContentItem &header = m_headers[targetIdx]; - if (header.isEmpty()) { - continue; - } - - if (targetLevel == 0) { - // The target level has not been init yet. - Q_ASSERT(firstHeader); - targetLevel = header.m_level; - if (p_relativeLevel < 0) { - targetLevel += p_relativeLevel; - if (targetLevel < 1) { - // Invalid level. - return false; - } - } else if (p_relativeLevel > 0) { - targetLevel = -1; - } - } - - if (targetLevel == -1 || header.m_level == targetLevel) { - if (firstHeader - && (cursorLine == header.m_blockNumber - || p_forward) - && idx != -1) { - // This header is not counted for the repeat. - firstHeader = false; - continue; - } - - if (--p_repeat == 0) { - // Found. - break; - } - } else if (header.m_level < targetLevel) { - // Stop by higher level. - return false; - } - - firstHeader = false; - } - - if (targetIdx < 0 || targetIdx >= m_headers.size()) { - return false; - } - - // Jump to target header. - int line = m_headers[targetIdx].m_blockNumber; - if (line > -1) { - QTextBlock block = document()->findBlockByNumber(line); - if (block.isValid()) { - cursor.setPosition(block.position()); - setTextCursor(cursor); - return true; - } - } - - return false; -} - -void VMdEditor::scrollBlockInPage(int p_blockNum, int p_dest, int p_margin) -{ - VEditUtils::scrollBlockInPage(this, p_blockNum, p_dest, p_margin); -} - -void VMdEditor::updateTextEditConfig() -{ - setBlockImageEnabled(g_config->getEnablePreviewImages()); - - setImageWidthConstrainted(g_config->getEnablePreviewImageConstraint()); - - setLineLeading(m_config.m_lineDistanceHeight); - - setImageLineColor(g_config->getEditorPreviewImageLineFg()); - - setEnableExtraBuffer(g_config->getEnableExtraBuffer()); - - int lineNumber = g_config->getEditorLineNumber(); - if (lineNumber < (int)LineNumberType::None || lineNumber >= (int)LineNumberType::Invalid) { - lineNumber = (int)LineNumberType::None; - } - - setLineNumberType((LineNumberType)lineNumber); - setLineNumberColor(g_config->getEditorLineNumberFg(), - g_config->getEditorLineNumberBg()); - - m_previewMgr->setPreviewEnabled(g_config->getEnablePreviewImages()); -} - -void VMdEditor::updateConfig() -{ - updateEditConfig(); - updateTextEditConfig(); -} - -QString VMdEditor::getContent() const -{ - return toPlainText(); -} - -void VMdEditor::setContent(const QString &p_content, bool p_modified) -{ - if (p_modified) { - QTextCursor cursor = textCursor(); - cursor.select(QTextCursor::Document); - cursor.insertText(p_content); - setTextCursor(cursor); - } else { - setPlainText(p_content); - } -} - -void VMdEditor::refreshPreview() -{ - m_previewMgr->refreshPreview(); -} - -void VMdEditor::updateInitAndInsertedImages(bool p_fileChanged, UpdateAction p_act) -{ - if (p_fileChanged && p_act == UpdateAction::InfoChanged) { - return; - } - - if (!isModified()) { - Q_ASSERT(m_insertedImages.isEmpty()); - m_insertedImages.clear(); - - if (!m_initImages.isEmpty()) { - // Re-generate init images. - initInitImages(); - } - - return; - } - - // Update init images. - QVector tmp = m_initImages; - initInitImages(); - Q_ASSERT(tmp.size() == m_initImages.size()); - - QDir dir(m_file->fetchBasePath()); - - // File has been moved. - if (p_fileChanged) { - // Since we clear unused images once user save the note, all images - // in m_initImages now are moved already. - - // Update inserted images. - // Inserted images should be moved manually here. Then update all the - // paths. - for (auto & link : m_insertedImages) { - if (link.m_type == ImageLink::LocalAbsolute) { - continue; - } - - QString newPath = QDir::cleanPath(dir.absoluteFilePath(link.m_url)); - if (VUtils::equalPath(link.m_path, newPath)) { - continue; - } - - if (!VUtils::copyFile(link.m_path, newPath, true)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to move unsaved inserted image %1 to %2.") - .arg(link.m_path) - .arg(newPath), - tr("Please check it manually to avoid image loss."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - continue; - } - - link.m_path = newPath; - } - } else { - // Directory changed. - // Update inserted images. - for (auto & link : m_insertedImages) { - if (link.m_type == ImageLink::LocalAbsolute) { - continue; - } - - QString newPath = QDir::cleanPath(dir.absoluteFilePath(link.m_url)); - link.m_path = newPath; - } - } -} - -void VMdEditor::handleCopyAsAction(QAction *p_act) -{ - ++m_copyTimeStamp; - - QTextCursor cursor = textCursor(); - Q_ASSERT(cursor.hasSelection()); - - QString text = VEditUtils::selectedText(cursor); - Q_ASSERT(!text.isEmpty()); - - Q_ASSERT(!m_textToHtmlDialog); - m_textToHtmlDialog = new VCopyTextAsHtmlDialog(text, p_act->data().toString(), this); - - // For Hoedown, we use marked.js to convert the text to have a general interface. - emit requestTextToHtml(text, 0, m_copyTimeStamp); - - m_textToHtmlDialog->exec(); - - delete m_textToHtmlDialog; - m_textToHtmlDialog = NULL; -} - -void VMdEditor::textToHtmlFinished(int p_id, - int p_timeStamp, - const QUrl &p_baseUrl, - const QString &p_html) -{ - Q_UNUSED(p_id); - if (m_textToHtmlDialog && p_timeStamp == m_copyTimeStamp) { - m_textToHtmlDialog->setConvertedHtml(p_baseUrl, p_html); - } -} - -void VMdEditor::htmlToTextFinished(int p_id, int p_timeStamp, const QString &p_text) -{ - Q_UNUSED(p_id); - if (m_copyTimeStamp == p_timeStamp && !p_text.isEmpty()) { - emit m_object->statusMessage(tr("Inserting parsed Markdown text")); - - QString text(p_text); - if (g_config->getParsePasteLocalImage()) { - // May take long time. - replaceTextWithLocalImages(text); - } - - m_editOps->insertText(text); - emit m_object->statusMessage(tr("Parsed Markdown text inserted")); - } -} - -void VMdEditor::wheelEvent(QWheelEvent *p_event) -{ - if (handleWheelEvent(p_event)) { - return; - } - - VTextEdit::wheelEvent(p_event); -} - -void VMdEditor::zoomPage(bool p_zoomIn, int p_range) -{ - if (p_range == 0) { - return; - } - - const int minSize = 2; - - int delta = p_zoomIn ? p_range : -p_range; - - // zoomIn() and zoomOut() does not work if we set stylesheet of VMdEditor. - int ptSz = font().pointSize() + delta; - if (ptSz < minSize) { - ptSz = minSize; - } - - setFontPointSizeByStyleSheet(ptSz); - - emit m_object->statusMessage(QObject::tr("Set base font point size %1").arg(ptSz)); - - m_zoomDelta += delta; - - QVector &styles = m_pegHighlighter->getStyles(); - for (auto & it : styles) { - int size = it.format.fontPointSize(); - if (size == 0) { - // It contains no font size format. - continue; - } - - size += delta; - if (size < minSize) { - size = minSize; - } - - it.format.setFontPointSize(size); - } - - QHash &cbStyles = m_pegHighlighter->getCodeBlockStyles(); - for (auto it = cbStyles.begin(); it != cbStyles.end(); ++it) { - int size = it.value().fontPointSize(); - if (size == 0) { - // It contains no font size format. - continue; - } - - size += delta; - if (size < minSize) { - size = minSize; - } - - it.value().setFontPointSize(size); - } - - m_pegHighlighter->rehighlight(); -} - -QAction *VMdEditor::initCopyAsMenu(QAction *p_after, QMenu *p_menu) -{ - QStringList targets = g_webUtils->getCopyTargetsName(); - if (targets.isEmpty()) { - return NULL; - } - - QMenu *subMenu = new QMenu(tr("Copy HTML As"), p_menu); - subMenu->setToolTipsVisible(true); - for (auto const & target : targets) { - QAction *act = new QAction(target, subMenu); - act->setData(target); - act->setToolTip(tr("Copy selected content as HTML using rules specified by target %1").arg(target)); - - subMenu->addAction(act); - } - - connect(subMenu, &QMenu::triggered, - this, &VMdEditor::handleCopyAsAction); - return insertMenuAfter(p_after, subMenu, p_menu); -} - -QAction *VMdEditor::initPasteAsBlockQuoteMenu(QAction *p_after, QMenu *p_menu) -{ - QAction *pbqAct = new QAction(tr("Paste As Block &Quote"), p_menu); - pbqAct->setToolTip(tr("Paste text from clipboard as block quote")); - connect(pbqAct, &QAction::triggered, - this, [this]() { - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - QString text = mimeData->text(); - - QTextCursor cursor = textCursor(); - cursor.removeSelectedText(); - QTextBlock block = cursor.block(); - QString indent = VEditUtils::fetchIndentSpaces(block); - - // Insert '> ' in front of each line. - VEditUtils::insertBeforeEachLine(text, indent + QStringLiteral("> ")); - - if (VEditUtils::isSpaceBlock(block)) { - if (!indent.isEmpty()) { - // Remove the indent. - cursor.movePosition(QTextCursor::StartOfBlock); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - cursor.removeSelectedText(); - } - } else { - // Insert a new block. - VEditUtils::insertBlock(cursor, false); - } - - cursor.insertText(text); - setTextCursor(cursor); - }); - - - insertActionAfter(p_after, pbqAct, p_menu); - return pbqAct; -} - -QAction *VMdEditor::initPasteAfterParseMenu(QAction *p_after, QMenu *p_menu) -{ - QAction *papAct = new QAction(tr("Paste Parsed &Markdown Text"), p_menu); - VUtils::fixTextWithCaptainShortcut(papAct, "ParseAndPaste"); - papAct->setToolTip(tr("Parse HTML to Markdown text and paste")); - connect(papAct, &QAction::triggered, - this, &VMdEditor::parseAndPaste); - - insertActionAfter(p_after, papAct, p_menu); - return papAct; -} - -void VMdEditor::insertImageLink(const QString &p_text, const QString &p_url) -{ - VInsertLinkDialog dialog(tr("Insert Image Link"), - "", - "", - p_text, - p_url, - true, - this); - if (dialog.exec() == QDialog::Accepted) { - QString linkText = dialog.getLinkText(); - QString linkUrl = dialog.getLinkUrl(); - static_cast(m_editOps)->insertImageLink(linkText, linkUrl); - } -} - -VWordCountInfo VMdEditor::fetchWordCountInfo() const -{ - VWordCountInfo info; - QTextDocument *doc = document(); - - // Char without spaces. - int cns = 0; - int wc = 0; - // Remove th ending new line. - int cc = doc->characterCount() - 1; - // 0 - not in word; - // 1 - in English word; - // 2 - in non-English word; - int state = 0; - - for (int i = 0; i < cc; ++i) { - QChar ch = doc->characterAt(i); - if (ch.isSpace()) { - if (state) { - state = 0; - } - - continue; - } else if (ch.unicode() < 128) { - if (state != 1) { - state = 1; - ++wc; - } - } else { - state = 2; - ++wc; - } - - ++cns; - } - - info.m_mode = VWordCountInfo::Edit; - info.m_wordCount = wc; - info.m_charWithoutSpacesCount = cns; - info.m_charWithSpacesCount = cc; - return info; -} - -void VMdEditor::setEditTab(VEditTab *p_editTab) -{ - m_editTab = p_editTab; -} - -void VMdEditor::setFontPointSizeByStyleSheet(int p_ptSize) -{ - QFont ft = font(); - ft.setPointSize(p_ptSize); - - const QPalette &palette = g_config->getMdEditPalette(); - setFontAndPaletteByStyleSheet(ft, palette); - - ensurePolished(); - - ft.setPointSize(p_ptSize + LINE_NUMBER_AREA_FONT_DELTA); - updateLineNumberAreaWidth(QFontMetrics(ft)); -} - -void VMdEditor::setFontAndPaletteByStyleSheet(const QFont &p_font, const QPalette &p_palette) -{ - QString styles(QString("VMdEditor, VLineNumberArea {" - "font-family: \"%1\";" - "font-size: %2pt;" - "color: %3;" - "background-color: %4;" - "selection-color: %5;" - "selection-background-color: %6; } " - "VLineNumberArea {" - "font-size: %7pt; }") - .arg(p_font.family()) - .arg(p_font.pointSize()) - .arg(p_palette.color(QPalette::Text).name()) - .arg(p_palette.color(QPalette::Base).name()) - .arg(p_palette.color(QPalette::HighlightedText).name()) - .arg(p_palette.color(QPalette::Highlight).name()) - .arg(p_font.pointSize() + LINE_NUMBER_AREA_FONT_DELTA)); - - setStyleSheet(styles); -} - -int VMdEditor::lineNumberAreaWidth() const -{ - return VTextEdit::lineNumberAreaWidth(); -} - -void VMdEditor::initLinkAndPreviewMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_pos) -{ - QTextCursor cursor = cursorForPosition(p_pos); - const int pos = cursor.position(); - QTextBlock block = cursor.block(); - const QString text(block.text()); - - // Image. - QRegExp regExp(VUtils::c_imageLinkRegExp); - if (regExp.indexIn(text) > -1) { - const QVector &imgRegs = m_pegHighlighter->getImageRegions(); - for (auto const & reg : imgRegs) { - if (!reg.contains(pos) - && (!reg.contains(pos - 1) || pos != (block.position() + text.size()))) { - continue; - } - - if (reg.m_endPos > block.position() + text.length()) { - return; - } - - QString linkText = text.mid(reg.m_startPos - block.position(), - reg.m_endPos - reg.m_startPos); - QString surl = VUtils::fetchImageLinkUrl(linkText); - if (surl.isEmpty()) { - return; - } - - QString imgPath = VUtils::linkUrlToPath(m_file->fetchBasePath(), surl); - bool isLocalFile = QFileInfo::exists(imgPath); - - QAction *viewImageAct = new QAction(tr("View Image"), p_menu); - connect(viewImageAct, &QAction::triggered, - this, [imgPath]() { - QDesktopServices::openUrl(VUtils::pathToUrl(imgPath)); - }); - p_menu->insertAction(p_before, viewImageAct); - - QAction *copyImageLinkAct = new QAction(tr("Copy Image URL"), p_menu); - connect(copyImageLinkAct, &QAction::triggered, - this, [imgPath]() { - QClipboard *clipboard = QApplication::clipboard(); - VClipboardUtils::setLinkToClipboard(clipboard, - imgPath, - QClipboard::Clipboard); - }); - p_menu->insertAction(p_before, copyImageLinkAct); - - if (isLocalFile) { - QAction *copyImagePathAct = new QAction(tr("Copy Image Path"), p_menu); - connect(copyImagePathAct, &QAction::triggered, - this, [imgPath]() { - QClipboard *clipboard = QApplication::clipboard(); - QMimeData *data = new QMimeData(); - data->setText(imgPath); - VClipboardUtils::setMimeDataToClipboard(clipboard, - data, - QClipboard::Clipboard); - }); - p_menu->insertAction(p_before, copyImagePathAct); - - QAction *copyImageAct = new QAction(tr("Copy Image"), p_menu); - connect(copyImageAct, &QAction::triggered, - this, [this, imgPath]() { - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); - QImage img = VUtils::imageFromFile(imgPath); - if (!img.isNull()) { - VClipboardUtils::setImageToClipboard(clipboard, - img, - QClipboard::Clipboard); - } - }); - p_menu->insertAction(p_before, copyImageAct); - } else { - // Copy in-place preview. - initInPlacePreviewMenu(p_before, p_menu, block, pos); - } - - p_menu->insertSeparator(p_before); - return; - } - } - - // Link. - QRegExp regExp2(VUtils::c_linkRegExp); - QString linkText; - int p = 0; - const int pib = pos - block.position(); - while (p < text.size()) { - int idx = text.indexOf(regExp2, p); - if (idx == -1) { - break; - } - - p = idx + regExp2.matchedLength(); - if (pib >= idx && pib < p) { - linkText = regExp2.cap(2); - break; - } - } - - if (!linkText.isEmpty()) { - QString linkUrl = VUtils::linkUrlToPath(m_file->fetchBasePath(), linkText); - bool isLocalFile = QFileInfo::exists(linkUrl); - - QAction *viewLinkAct = new QAction(tr("View Link"), p_menu); - connect(viewLinkAct, &QAction::triggered, - this, [linkUrl]() { - QDesktopServices::openUrl(VUtils::pathToUrl(linkUrl)); - }); - p_menu->insertAction(p_before, viewLinkAct); - - QAction *copyLinkAct = new QAction(tr("Copy Link URL"), p_menu); - connect(copyLinkAct, &QAction::triggered, - this, [linkUrl]() { - QClipboard *clipboard = QApplication::clipboard(); - VClipboardUtils::setLinkToClipboard(clipboard, - linkUrl, - QClipboard::Clipboard); - }); - p_menu->insertAction(p_before, copyLinkAct); - - if (isLocalFile) { - QAction *copyLinkPathAct = new QAction(tr("Copy Link Path"), p_menu); - connect(copyLinkPathAct, &QAction::triggered, - this, [linkUrl]() { - QClipboard *clipboard = QApplication::clipboard(); - QMimeData *data = new QMimeData(); - data->setText(linkUrl); - VClipboardUtils::setMimeDataToClipboard(clipboard, - data, - QClipboard::Clipboard); - }); - p_menu->insertAction(p_before, copyLinkPathAct); - } - - p_menu->insertSeparator(p_before); - return; - } - - bool needSeparator = false; - if (initInPlacePreviewMenu(p_before, p_menu, block, pos)) { - needSeparator = true; - } - - if (initExportAndCopyMenu(p_before, p_menu, block, pos)) { - needSeparator = true; - } - - if (needSeparator) { - p_menu->insertSeparator(p_before); - } -} - -bool VMdEditor::initInPlacePreviewMenu(QAction *p_before, - QMenu *p_menu, - const QTextBlock &p_block, - int p_pos) -{ - VTextBlockData *data = VTextBlockData::blockData(p_block); - if (!data) { - return false; - } - - const QVector &previews = data->getPreviews(); - if (previews.isEmpty()) { - return false; - } - - QPixmap image; - QString background; - int pib = p_pos - p_block.position(); - for (auto info : previews) { - const VPreviewedImageInfo &pii = info->m_imageInfo; - if (pii.contains(pib) - || (pii.contains(pib - 1) && pib == p_block.length() - 1)) { - const QPixmap *img = findImage(pii.m_imageName); - if (img) { - image = *img; - background = pii.m_background; - } - - break; - } - } - - if (image.isNull()) { - return false; - } - - QAction *copyImageAct = new QAction(tr("Copy In-Place Preview"), p_menu); - connect(copyImageAct, &QAction::triggered, - this, [this, image, background]() { - QColor co(background); - if (!co.isValid()) { - co = palette().color(QPalette::Base); - } - - QImage img(image.size(), QImage::Format_ARGB32); - img.fill(co); - QPainter pter(&img); - pter.drawPixmap(img.rect(), image); - - QClipboard *clipboard = QApplication::clipboard(); - VClipboardUtils::setImageToClipboard(clipboard, - img, - QClipboard::Clipboard); - }); - p_menu->insertAction(p_before, copyImageAct); - return true; -} - -bool VMdEditor::initExportAndCopyMenu(QAction *p_before, - QMenu *p_menu, - const QTextBlock &p_block, - int p_pos) -{ - Q_UNUSED(p_pos); - int state = p_block.userState(); - if (state != HighlightBlockState::CodeBlockStart - && state != HighlightBlockState::CodeBlock - && state != HighlightBlockState::CodeBlockEnd) { - return false; - } - - int blockNum = p_block.blockNumber(); - const QVector &cbs = m_pegHighlighter->getCodeBlocks(); - int idx = 0; - for (idx = 0; idx < cbs.size(); ++idx) { - if (cbs[idx].m_startBlock <= blockNum - && cbs[idx].m_endBlock >= blockNum) { - break; - } - } - - if (idx >= cbs.size()) { - return false; - } - - const VCodeBlock &cb = cbs[idx]; - if (cb.m_lang != "puml" && cb.m_lang != "dot") { - return false; - } - - QMenu *subMenu = new QMenu(tr("Copy Graph"), p_menu); - subMenu->setToolTipsVisible(true); - - QAction *pngAct = new QAction(tr("PNG"), subMenu); - pngAct->setToolTip(tr("Export graph as PNG to a temporary file and copy")); - connect(pngAct, &QAction::triggered, - this, [this, lang = cb.m_lang, text = cb.m_text]() { - exportGraphAndCopy(lang, text, "png"); - }); - subMenu->addAction(pngAct); - - QAction *svgAct = new QAction(tr("SVG"), subMenu); - svgAct->setToolTip(tr("Export graph as SVG to a temporary file and copy")); - connect(svgAct, &QAction::triggered, - this, [this, lang = cb.m_lang, text = cb.m_text]() { - exportGraphAndCopy(lang, text, "svg"); - }); - subMenu->addAction(svgAct); - - p_menu->insertMenu(p_before, subMenu); - return true; -} - -void VMdEditor::exportGraphAndCopy(const QString &p_lang, - const QString &p_text, - const QString &p_format) -{ - m_exportTempFile.reset(VUtils::createTemporaryFile(p_format)); - if (!m_exportTempFile->open()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to open a temporary file for export."), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - m_exportTempFile.clear(); - return; - } - - emit m_object->statusMessage(tr("Exporting graph")); - - QString filePath(m_exportTempFile->fileName()); - QByteArray out; - if (p_lang == "puml") { - out = VPlantUMLHelper::process(p_format, - VEditUtils::removeCodeBlockFence(p_text)); - } else if (p_lang == "dot") { - out = VGraphvizHelper::process(p_format, - VEditUtils::removeCodeBlockFence(p_text)); - } - - if (out.isEmpty() || m_exportTempFile->write(out) == -1) { - m_exportTempFile->close(); - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to export graph."), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } else { - m_exportTempFile->close(); - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(); - - QImage img; - img.loadFromData(out, p_format.toLocal8Bit().data()); - if (!img.isNull()) { - VClipboardUtils::setImageAndLinkToClipboard(clipboard, - img, - filePath, - QClipboard::Clipboard); - emit m_object->statusMessage(tr("Graph exported and copied")); - } else { - emit m_object->statusMessage(tr("Fail to read exported image: %1").arg(filePath)); - } - } -} - -void VMdEditor::parseAndPaste() -{ - if (!m_editTab - || !m_editTab->isEditMode() - || isReadOnly()) { - return; - } - - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - QString html(mimeData->html()); - if (!html.isEmpty()) { - ++m_copyTimeStamp; - emit requestHtmlToText(html, 0, m_copyTimeStamp); - } -} - -bool VMdEditor::processHtmlFromMimeData(const QMimeData *p_source) -{ - if (!p_source->hasHtml()) { - return false; - } - - // Handle . - QRegExp reg("]*)src=\"([^\"]+)\"([^>]*)>"); - QString html(p_source->html()); - if (reg.indexIn(html) != -1 && VUtils::onlyHasImgInHtml(html)) { - if (p_source->hasImage()) { - // Both image data and URL are embedded. - VSelectDialog dialog(tr("Insert From Clipboard"), this); - dialog.addSelection(tr("Insert From URL"), 0); - dialog.addSelection(tr("Insert From Image Data"), 1); - dialog.addSelection(tr("Insert As Image Link"), 2); - - if (dialog.exec() == QDialog::Accepted) { - int selection = dialog.getSelection(); - if (selection == 1) { - // Insert from image data. - m_editOps->insertImageFromMimeData(p_source); - return true; - } else if (selection == 2) { - // Insert as link. - insertImageLink("", reg.cap(2)); - return true; - } - } else { - return true; - } - } - - m_editOps->insertImageFromURL(QUrl(reg.cap(2))); - return true; - } - - return false; -} - -bool VMdEditor::processImageFromMimeData(const QMimeData *p_source) -{ - if (!p_source->hasImage()) { - return false; - } - - // Image data in the clipboard - if (p_source->hasText()) { - VSelectDialog dialog(tr("Insert From Clipboard"), this); - dialog.addSelection(tr("Insert As Image"), 0); - dialog.addSelection(tr("Insert As Text"), 1); - dialog.addSelection(tr("Insert As Image Link"), 2); - - if (dialog.exec() == QDialog::Accepted) { - int selection = dialog.getSelection(); - if (selection == 1) { - // Insert as text. - Q_ASSERT(p_source->hasText() && p_source->hasImage()); - VTextEdit::insertFromMimeData(p_source); - return true; - } else if (selection == 2) { - // Insert as link. - insertImageLink("", p_source->text()); - return true; - } - } else { - return true; - } - } - - m_editOps->insertImageFromMimeData(p_source); - return true; -} - -bool VMdEditor::processUrlFromMimeData(const QMimeData *p_source) -{ - QUrl url; - if (p_source->hasUrls()) { - QList urls = p_source->urls(); - if (urls.size() == 1) { - url = urls[0]; - } - } else if (p_source->hasText()) { - // Try to get URL from text. - QString text = p_source->text(); - if (QFileInfo::exists(text)) { - url = QUrl::fromLocalFile(text); - } else { - url = QUrl(text); - if (url.scheme() != "https" && url.scheme() != "http") { - url.clear(); - } - } - } - - if (!url.isValid()) { - return false; - } - - bool isImage = VUtils::isImageURL(url); - bool isLocalFile = url.isLocalFile() - && QFileInfo::exists(url.toLocalFile()); - - QString localTextFilePath; - if (!isImage && isLocalFile) { - localTextFilePath = url.toLocalFile(); - QMimeDatabase mimeDatabase; - const QMimeType mimeType = mimeDatabase.mimeTypeForFile(localTextFilePath); - if (mimeType.isValid() && !mimeType.inherits(QStringLiteral("text/plain"))) { - localTextFilePath.clear(); - } - } - - VSelectDialog dialog(tr("Insert From Clipboard"), this); - if (isImage) { - dialog.addSelection(tr("Insert As Image"), 0); - dialog.addSelection(tr("Insert As Image Link"), 1); - if (isLocalFile) { - dialog.addSelection(tr("Insert As Relative Image Link"), 7); - } - } - - dialog.addSelection(tr("Insert As Link"), 2); - if (isLocalFile) { - dialog.addSelection(tr("Insert As Relative Link"), 3); - - // Attach as attachment. - if (m_file->getType() == FileType::Note) { - VNoteFile *note = static_cast((VFile *)m_file); - if (-1 == note->findAttachmentByPath(url.toLocalFile(), false)) { - dialog.addSelection(tr("Attach And Insert Link"), 6); - } - } - } - - dialog.addSelection(tr("Insert As Text"), 4); - if (!localTextFilePath.isEmpty()) { - dialog.addSelection(tr("Insert File Content"), 5); - } - - // FIXME: After calling dialog.exec(), p_source->hasUrl() returns false. - if (dialog.exec() == QDialog::Accepted) { - bool relativeLink = false; - switch (dialog.getSelection()) { - case 0: - { - // Insert As Image. - m_editOps->insertImageFromURL(url); - return true; - } - - case 7: - // Insert As Relative Image Link. - relativeLink = true; - V_FALLTHROUGH; - - case 1: - { - // Insert As Image Link. - QString ut; - if (relativeLink) { - QDir dir(m_file->fetchBasePath()); - ut = dir.relativeFilePath(url.toLocalFile()); - ut = QUrl(ut).toString(QUrl::EncodeSpaces); - if (g_config->getPrependDotInRelativePath()) { - VUtils::prependDotIfRelative(ut); - } - } else { - ut = url.toString(QUrl::EncodeSpaces); - } - - insertImageLink("", ut); - return true; - } - - case 6: - { - // Attach And Insert Link. - QString file = url.toLocalFile(); - - Q_ASSERT(m_file->getType() == FileType::Note); - VNoteFile *note = static_cast((VFile *)m_file); - QString destFile; - if (!note->addAttachment(file, &destFile)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to add attachment %1 for note %3.") - .arg(file) - .arg(g_config->c_dataTextStyle) - .arg(note->getName()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - return true; - } - - emit m_object->statusMessage(tr("1 file added as attachment")); - - // Update url to point to the attachment file. - Q_ASSERT(!destFile.isEmpty()); - url = QUrl::fromLocalFile(destFile); - - V_FALLTHROUGH; - } - - case 3: - // Insert As Relative link. - relativeLink = true; - V_FALLTHROUGH; - - case 2: - { - // Insert As Link. - QString initLinkText; - if (isLocalFile) { - initLinkText = QFileInfo(url.toLocalFile()).fileName(); - } - - QString ut; - if (relativeLink) { - QDir dir(m_file->fetchBasePath()); - ut = dir.relativeFilePath(url.toLocalFile()); - ut = QUrl(ut).toString(QUrl::EncodeSpaces); - if (g_config->getPrependDotInRelativePath()) { - VUtils::prependDotIfRelative(ut); - } - } else { - ut = url.toString(QUrl::EncodeSpaces); - } - - VInsertLinkDialog ld(QObject::tr("Insert Link"), - "", - "", - initLinkText, - ut, - false, - this); - if (ld.exec() == QDialog::Accepted) { - QString linkText = ld.getLinkText(); - QString linkUrl = ld.getLinkUrl(); - Q_ASSERT(!linkText.isEmpty() && !linkUrl.isEmpty()); - m_editOps->insertLink(linkText, linkUrl); - } - - return true; - } - - case 4: - { - // Insert As Text. - if (p_source->hasText()) { - m_editOps->insertText(p_source->text()); - } else { - m_editOps->insertText(url.toString()); - } - - return true; - } - - case 5: - { - // Insert File Content. - Q_ASSERT(!localTextFilePath.isEmpty()); - m_editOps->insertText(VUtils::readFileFromDisk(localTextFilePath)); - return true; - } - - default: - Q_ASSERT(false); - break; - } - } - - return true; -} - -void VMdEditor::replaceTextWithLocalImages(QString &p_text) -{ - QVector regs = VUtils::fetchImageRegionsUsingParser(p_text); - if (regs.isEmpty()) { - return; - } - - // Sort it in ascending order. - std::sort(regs.begin(), regs.end()); - - QProgressDialog proDlg(tr("Fetching images to local folder..."), - tr("Abort"), - 0, - regs.size(), - this); - proDlg.setWindowModality(Qt::WindowModal); - proDlg.setWindowTitle(tr("Fetching Images To Local Folder")); - - QRegExp zhihuRegExp("^https?://www\\.zhihu\\.com/equation\\?tex=(.+)$"); - - QRegExp regExp(VUtils::c_imageLinkRegExp); - for (int i = regs.size() - 1; i >= 0; --i) { - proDlg.setValue(regs.size() - 1 - i); - if (proDlg.wasCanceled()) { - break; - } - - const VElementRegion ® = regs[i]; - QString linkText = p_text.mid(reg.m_startPos, reg.m_endPos - reg.m_startPos); - if (regExp.indexIn(linkText) == -1) { - continue; - } - - QString imageTitle = VUtils::purifyImageTitle(regExp.cap(1).trimmed()); - QString imageUrl = regExp.cap(2).trimmed(); - - const int maxUrlLength = 100; - QString urlToDisplay(imageUrl); - if (urlToDisplay.size() > maxUrlLength) { - urlToDisplay = urlToDisplay.left(maxUrlLength) + "..."; - } - proDlg.setLabelText(tr("Fetching image: %1").arg(urlToDisplay)); - - // Handle equation from zhihu.com like http://www.zhihu.com/equation?tex=P. - if (zhihuRegExp.indexIn(imageUrl) != -1) { - QString tex = zhihuRegExp.cap(1).trimmed(); - - // Remove the +. - tex.replace(QChar('+'), " "); - - tex = QUrl::fromPercentEncoding(tex.toUtf8()); - if (tex.isEmpty()) { - continue; - } - - tex = "$" + tex + "$"; - p_text.replace(reg.m_startPos, - reg.m_endPos - reg.m_startPos, - tex); - continue; - } - - QString destImagePath, urlInLink; - - // Only handle absolute file path or network path. - QString srcImagePath; - QFileInfo info(VUtils::purifyUrl(imageUrl)); - - // For network image. - QScopedPointer tmpFile; - - if (info.exists()) { - if (info.isAbsolute()) { - // Absolute local path. - srcImagePath = info.absoluteFilePath(); - } - } else { - // Network path. - QByteArray data = VDownloader::downloadSync(QUrl(imageUrl)); - if (!data.isEmpty()) { - tmpFile.reset(VUtils::createTemporaryFile(info.suffix())); - if (tmpFile->open() && tmpFile->write(data) > -1) { - srcImagePath = tmpFile->fileName(); - } - - // Need to close it explicitly to flush cache of small file. - tmpFile->close(); - } - } - - if (srcImagePath.isEmpty()) { - continue; - } - - // Insert image without inserting text. - auto ops = static_cast(m_editOps); - ops->insertImageFromPath(imageTitle, - m_file->fetchImageFolderPath(), - m_file->getImageFolderInLink(), - srcImagePath, - false, - destImagePath, - urlInLink); - if (urlInLink.isEmpty()) { - continue; - } - - // Replace URL in link. - QString newLink = QString("![%1](%2%3%4)") - .arg(imageTitle) - .arg(urlInLink) - .arg(regExp.cap(3)) - .arg(regExp.cap(6)); - p_text.replace(reg.m_startPos, - reg.m_endPos - reg.m_startPos, - newLink); - } - - proDlg.setValue(regs.size()); -} - -void VMdEditor::initAttachmentMenu(QMenu *p_menu) -{ - if (m_file->getType() != FileType::Note) { - return; - } - - const VNoteFile *note = static_cast((VFile *)m_file); - const QVector &attas = note->getAttachments(); - if (attas.isEmpty()) { - return; - } - - QMenu *subMenu = new QMenu(tr("Link To Attachment"), p_menu); - for (auto const & att : attas) { - QAction *act = new QAction(att.m_name, subMenu); - act->setData(att.m_name); - subMenu->addAction(act); - } - - connect(subMenu, &QMenu::triggered, - this, &VMdEditor::handleLinkToAttachmentAction); - - p_menu->addSeparator(); - p_menu->addMenu(subMenu); -} - -void VMdEditor::handleLinkToAttachmentAction(QAction *p_act) -{ - Q_ASSERT(m_file->getType() == FileType::Note); - VNoteFile *note = static_cast((VFile *)m_file); - QString name = p_act->data().toString(); - QString folderPath = note->fetchAttachmentFolderPath(); - QString filePath = QDir(folderPath).filePath(name); - - QDir dir(note->fetchBasePath()); - QString ut = dir.relativeFilePath(filePath); - ut = QUrl(ut).toString(QUrl::EncodeSpaces); - if (g_config->getPrependDotInRelativePath()) { - VUtils::prependDotIfRelative(ut); - } - - VInsertLinkDialog ld(QObject::tr("Insert Link"), - "", - "", - name, - ut, - false, - this); - if (ld.exec() == QDialog::Accepted) { - QString linkText = ld.getLinkText(); - QString linkUrl = ld.getLinkUrl(); - Q_ASSERT(!linkText.isEmpty() && !linkUrl.isEmpty()); - m_editOps->insertLink(linkText, linkUrl); - } -} - -void VMdEditor::insertTable() -{ - // Get the dialog info. - VInsertTableDialog td(this); - if (td.exec() != QDialog::Accepted) { - return; - } - - int rowCount = td.getRowCount(); - int colCount = td.getColumnCount(); - VTable::Alignment alignment = td.getAlignment(); - - QTextCursor cursor = textCursorW(); - if (cursor.hasSelection()) { - cursor.clearSelection(); - setTextCursorW(cursor); - } - - bool newBlock = !cursor.atBlockEnd(); - if (!newBlock && !cursor.atBlockStart()) { - QString text = cursor.block().text().trimmed(); - if (!text.isEmpty() && text != ">") { - // Insert a new block before inserting table. - newBlock = true; - } - } - - if (newBlock) { - VEditUtils::insertBlock(cursor, false); - VEditUtils::indentBlockAsBlock(cursor, false); - setTextCursorW(cursor); - } - - // Insert table right at cursor. - m_tableHelper->insertTable(rowCount, colCount, alignment); -} - -void VMdEditor::initImageHostingMenu(QMenu *p_menu) -{ - QMenu *uploadImageMenu = new QMenu(tr("&Upload Image To"), p_menu); - - // Upload the image to GitHub image hosting. - QAction *uploadImageToGithub = new QAction(tr("&GitHub"), uploadImageMenu); - connect(uploadImageToGithub, &QAction::triggered, this, &VMdEditor::requestUploadImageToGithub); - uploadImageMenu->addAction(uploadImageToGithub); - - // Upload the image to Gitee image hosting. - QAction *uploadImageToGitee = new QAction(tr("G&itee"), uploadImageMenu); - connect(uploadImageToGitee, &QAction::triggered, this, &VMdEditor::requestUploadImageToGitee); - uploadImageMenu->addAction(uploadImageToGitee); - - // Upload the image to Wechat image hosting - QAction *uploadImageToWechat = new QAction(tr("&Wechat"), uploadImageMenu); - connect(uploadImageToWechat, &QAction::triggered, this, &VMdEditor::requestUploadImageToWechat); - uploadImageMenu->addAction(uploadImageToWechat); - - // Upload the image to Tencent image hosting. - QAction *uploadImageToTencent = new QAction(tr("&Tencent"), uploadImageMenu); - connect(uploadImageToTencent, &QAction::triggered, this, &VMdEditor::requestUploadImageToTencent); - uploadImageMenu->addAction(uploadImageToTencent); - - p_menu->addSeparator(); - p_menu->addMenu(uploadImageMenu); -} diff --git a/src/vmdeditor.h b/src/vmdeditor.h deleted file mode 100644 index b7f9257c..00000000 --- a/src/vmdeditor.h +++ /dev/null @@ -1,380 +0,0 @@ -#ifndef VMDEDITOR_H -#define VMDEDITOR_H - -#include -#include -#include -#include -#include -#include -#include - -#include "vtextedit.h" -#include "veditor.h" -#include "vconfigmanager.h" -#include "vtableofcontent.h" -#include "vconfigmanager.h" -#include "utils/vutils.h" - -class PegMarkdownHighlighter; -class VCodeBlockHighlightHelper; -class VDocument; -class VPreviewManager; -class VCopyTextAsHtmlDialog; -class VEditTab; -class VTableHelper; - -class VMdEditor : public VTextEdit, public VEditor -{ - Q_OBJECT -public: - VMdEditor(VFile *p_file, - VDocument *p_doc, - MarkdownConverterType p_type, - const QSharedPointer &p_completer, - QWidget *p_parent = nullptr); - - void beginEdit() Q_DECL_OVERRIDE; - - void endEdit() Q_DECL_OVERRIDE; - - void saveFile() Q_DECL_OVERRIDE; - - void reloadFile() Q_DECL_OVERRIDE; - - bool scrollToBlock(int p_blockNumber) Q_DECL_OVERRIDE; - - void makeBlockVisible(const QTextBlock &p_block) Q_DECL_OVERRIDE; - - QVariant inputMethodQuery(Qt::InputMethodQuery p_query) const Q_DECL_OVERRIDE; - - bool isBlockVisible(const QTextBlock &p_block) Q_DECL_OVERRIDE; - - // An image has been inserted. The image is relative. - // @p_path is the absolute path of the inserted image. - // @p_url is the URL text within (). - void imageInserted(const QString &p_path, const QString &p_url); - - // Scroll to header @p_blockNumber. - // Return true if @p_blockNumber is valid to scroll to. - bool scrollToHeader(int p_blockNumber); - - void scrollBlockInPage(int p_blockNum, int p_dest, int p_margin = 0) Q_DECL_OVERRIDE; - - void updateConfig() Q_DECL_OVERRIDE; - - QString getContent() const Q_DECL_OVERRIDE; - - void setContent(const QString &p_content, bool p_modified = false) Q_DECL_OVERRIDE; - - void refreshPreview(); - - // Update m_initImages and m_insertedImages to handle the change of the note path. - void updateInitAndInsertedImages(bool p_fileChanged, UpdateAction p_act); - - VWordCountInfo fetchWordCountInfo() const Q_DECL_OVERRIDE; - - void setEditTab(VEditTab *p_editTab); - - PegMarkdownHighlighter *getMarkdownHighlighter() const; - - VPreviewManager *getPreviewManager() const; - - void updateHeaderSequenceByConfigChange(); - - void updateFontAndPalette() Q_DECL_OVERRIDE; - - void insertTable() Q_DECL_OVERRIDE; - -public slots: - bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) Q_DECL_OVERRIDE; - - void textToHtmlFinished(int p_id, int p_timeStamp, const QUrl &p_baseUrl, const QString &p_html); - - void htmlToTextFinished(int p_id, int p_timeStamp, const QString &p_html); - - void parseAndPaste(); - -// Wrapper functions for QPlainTextEdit/QTextEdit. -public: - void setExtraSelectionsW(const QList &p_selections) Q_DECL_OVERRIDE - { - setExtraSelections(p_selections); - } - - QTextDocument *documentW() const Q_DECL_OVERRIDE - { - return document(); - } - - int tabStopWidthW() const Q_DECL_OVERRIDE - { - return tabStopWidth(); - } - - void setTabStopWidthW(int p_width) Q_DECL_OVERRIDE - { - setTabStopWidth(p_width); - } - - QTextCursor textCursorW() const Q_DECL_OVERRIDE - { - return textCursor(); - } - - void moveCursorW(QTextCursor::MoveOperation p_operation, - QTextCursor::MoveMode p_mode) Q_DECL_OVERRIDE - { - moveCursor(p_operation, p_mode); - } - - QScrollBar *verticalScrollBarW() const Q_DECL_OVERRIDE - { - return verticalScrollBar(); - } - - QScrollBar *horizontalScrollBarW() const Q_DECL_OVERRIDE - { - return horizontalScrollBar(); - } - - void setTextCursorW(const QTextCursor &p_cursor) Q_DECL_OVERRIDE - { - setTextCursor(p_cursor); - } - - bool findW(const QString &p_exp, - QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) Q_DECL_OVERRIDE - { - return find(p_exp, p_options); - } - - bool findW(const QRegExp &p_exp, - QTextDocument::FindFlags p_options = QTextDocument::FindFlags()) Q_DECL_OVERRIDE - { - return find(p_exp, p_options); - } - - bool isReadOnlyW() const Q_DECL_OVERRIDE - { - return isReadOnly(); - } - - void setReadOnlyW(bool p_ro) Q_DECL_OVERRIDE - { - setReadOnly(p_ro); - } - - QWidget *viewportW() const Q_DECL_OVERRIDE - { - return viewport(); - } - - void insertPlainTextW(const QString &p_text) Q_DECL_OVERRIDE - { - insertPlainText(p_text); - } - - void undoW() Q_DECL_OVERRIDE - { - undo(); - } - - void redoW() Q_DECL_OVERRIDE - { - redo(); - } - - // Whether display cursor as block. - void setCursorBlockModeW(CursorBlock p_mode) Q_DECL_OVERRIDE - { - setCursorBlockMode(p_mode); - } - - void zoomInW(int p_range = 1) Q_DECL_OVERRIDE - { - zoomPage(true, p_range); - } - - void zoomOutW(int p_range = 1) Q_DECL_OVERRIDE - { - zoomPage(false, p_range); - } - - void ensureCursorVisibleW() Q_DECL_OVERRIDE - { - ensureCursorVisible(); - } - - QRect cursorRectW() Q_DECL_OVERRIDE - { - return cursorRect(); - } - - QRect cursorRectW(const QTextCursor &p_cursor) Q_DECL_OVERRIDE - { - return cursorRect(p_cursor); - } - -signals: - // Signal when headers change. - void headersChanged(const QVector &p_headers); - - // Signal when current header change. - void currentHeaderChanged(int p_blockNumber); - - // Signal when the status of VMdEdit changed. - // Will be emitted by VImagePreviewer for now. - void statusChanged(); - - // Request to convert @p_text to Html. - void requestTextToHtml(const QString &p_text, int p_id, int p_timeStamp); - - // Request to convert @p_html to Markdown text. - void requestHtmlToText(const QString &p_html, int p_id, int p_timeStamp); - - void requestUploadImageToGithub(); - - void requestUploadImageToGitee(); - - void requestUploadImageToWechat(); - - void requestUploadImageToTencent(); - -protected: - void contextMenuEvent(QContextMenuEvent *p_event) Q_DECL_OVERRIDE; - - // Used to implement dragging mouse with Ctrl and left button pressed to scroll. - void mousePressEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void mouseReleaseEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void mouseMoveEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void mouseDoubleClickEvent(QMouseEvent *p_event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - bool canInsertFromMimeData(const QMimeData *p_source) const Q_DECL_OVERRIDE; - - void insertFromMimeData(const QMimeData *p_source) Q_DECL_OVERRIDE; - - void wheelEvent(QWheelEvent *p_event) Q_DECL_OVERRIDE; - - int lineNumberAreaWidth() const Q_DECL_OVERRIDE; - -private slots: - // Update m_headers according to elements. - void updateHeaders(const QVector &p_headerRegions); - - // Update current header according to cursor position. - // When there is no header in current cursor, will signal an invalid header. - void updateCurrentHeader(); - - // Copy selected text as HTML. - void handleCopyAsAction(QAction *p_act); - - void handleLinkToAttachmentAction(QAction *p_act); - -private: - void updateHeadersHelper(const QVector &p_headerRegions, bool p_configChanged); - - // Update the config of VTextEdit according to global configurations. - void updateTextEditConfig(); - - // Get the initial images from file before edit. - void initInitImages(); - - // Clear two kind of images according to initial images and current images: - // 1. Newly inserted images which are deleted later; - // 2. Initial images which are deleted; - void clearUnusedImages(); - - // Index in m_headers of current header which contains the cursor. - int indexOfCurrentHeader() const; - - // Zoom in/out. - // We need to maintain the styles font size. - void zoomPage(bool p_zoomIn, int p_range = 1); - - QAction *initCopyAsMenu(QAction *p_after, QMenu *p_menu); - - QAction *initPasteAsBlockQuoteMenu(QAction *p_after, QMenu *p_menu); - - QAction *initPasteAfterParseMenu(QAction *p_after, QMenu *p_menu); - - void initLinkAndPreviewMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_pos); - - bool initInPlacePreviewMenu(QAction *p_before, - QMenu *p_menu, - const QTextBlock &p_block, - int p_pos); - - bool initExportAndCopyMenu(QAction *p_before, - QMenu *p_menu, - const QTextBlock &p_block, - int p_pos); - - void initAttachmentMenu(QMenu *p_menu); - - void initImageHostingMenu(QMenu *p_menu); - - void insertImageLink(const QString &p_text, const QString &p_url); - - void setFontPointSizeByStyleSheet(int p_ptSize); - - void setFontAndPaletteByStyleSheet(const QFont &p_font, const QPalette &p_palette); - - void exportGraphAndCopy(const QString &p_lang, - const QString &p_text, - const QString &p_format); - - bool processHtmlFromMimeData(const QMimeData *p_source); - - bool processImageFromMimeData(const QMimeData *p_source); - - bool processUrlFromMimeData(const QMimeData *p_source); - - void replaceTextWithLocalImages(QString &p_text); - - PegMarkdownHighlighter *m_pegHighlighter; - - VCodeBlockHighlightHelper *m_cbHighlighter; - - VPreviewManager *m_previewMgr; - - VTableHelper *m_tableHelper; - - // Image links inserted while editing. - QVector m_insertedImages; - - // Image links right at the beginning of the edit. - QVector m_initImages; - - // Mainly used for title jump. - QVector m_headers; - - bool m_freshEdit; - - VCopyTextAsHtmlDialog *m_textToHtmlDialog; - - int m_zoomDelta; - - VEditTab *m_editTab; - - int m_copyTimeStamp; - - // Temp file used for ExportAndCopy. - QSharedPointer m_exportTempFile; -}; - -inline PegMarkdownHighlighter *VMdEditor::getMarkdownHighlighter() const -{ - return m_pegHighlighter; -} - -inline VPreviewManager *VMdEditor::getPreviewManager() const -{ - return m_previewMgr; -} -#endif // VMDEDITOR_H diff --git a/src/vmdtab.cpp b/src/vmdtab.cpp deleted file mode 100644 index c0892cc3..00000000 --- a/src/vmdtab.cpp +++ /dev/null @@ -1,1777 +0,0 @@ -#include -#include -#include -#include -#include -#include "vmdtab.h" -#include "vdocument.h" -#include "vnote.h" -#include "utils/vutils.h" -#include "vpreviewpage.h" -#include "pegmarkdownhighlighter.h" -#include "vconfigmanager.h" -#include "vmarkdownconverter.h" -#include "vnotebook.h" -#include "vtableofcontent.h" -#include "dialog/vfindreplacedialog.h" -#include "veditarea.h" -#include "vconstants.h" -#include "vwebview.h" -#include "vmdeditor.h" -#include "vmainwindow.h" -#include "vsnippet.h" -#include "vinsertselector.h" -#include "vsnippetlist.h" -#include "vlivepreviewhelper.h" -#include "vmathjaxinplacepreviewhelper.h" -#include "vdirectory.h" -#include "vdirectorytree.h" - -extern VMainWindow *g_mainWin; - -extern VConfigManager *g_config; - - -VMdTab::VMdTab(VFile *p_file, VEditArea *p_editArea, - OpenFileMode p_mode, QWidget *p_parent) - : VEditTab(p_file, p_editArea, p_parent), - m_editor(NULL), - m_webViewer(NULL), - m_document(NULL), - m_mdConType(g_config->getMdConverterType()), - m_enableHeadingSequence(false), - m_backupFileChecked(false), - m_mode(Mode::InvalidMode), - m_livePreviewHelper(NULL), - m_mathjaxPreviewHelper(NULL) -{ - V_ASSERT(m_file->getDocType() == DocType::Markdown); - - if (!m_file->open()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to open note %2.") - .arg(g_config->c_dataTextStyle).arg(m_file->getName()), - tr("Please check if file %1 exists.").arg(m_file->fetchPath()), - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - HeadingSequenceType headingSequenceType = g_config->getHeadingSequenceType(); - if (headingSequenceType == HeadingSequenceType::Enabled) { - m_enableHeadingSequence = true; - } else if (headingSequenceType == HeadingSequenceType::EnabledNoteOnly - && m_file->getType() == FileType::Note) { - m_enableHeadingSequence = true; - } - - setupUI(); - - m_backupTimer = new QTimer(this); - m_backupTimer->setSingleShot(true); - m_backupTimer->setInterval(g_config->getFileTimerInterval()); - connect(m_backupTimer, &QTimer::timeout, - this, [this]() { - writeBackupFile(); - }); - - m_livePreviewTimer = new QTimer(this); - m_livePreviewTimer->setSingleShot(true); - m_livePreviewTimer->setInterval(500); - connect(m_livePreviewTimer, &QTimer::timeout, - this, [this]() { - QString text = m_webViewer->selectedText().trimmed(); - if (text.isEmpty()) { - return; - } - - const LivePreviewInfo &info = m_livePreviewHelper->getLivePreviewInfo(); - if (info.isValid()) { - m_editor->findTextInRange(text, - FindOption::CaseSensitive, - true, - info.m_startPos, - info.m_endPos); - } - }); - - QTimer::singleShot(50, this, [this, p_mode]() { - if (p_mode == OpenFileMode::Edit) { - showFileEditMode(); - } else { - showFileReadMode(); - } - }); -} - -void VMdTab::setupUI() -{ - m_splitter = new QSplitter(this); - m_splitter->setOrientation(Qt::Horizontal); - - setupMarkdownViewer(); - - // Setup editor when we really need it. - m_editor = NULL; - - // The following is the image hosting initialization - vGithubImageHosting = new VGithubImageHosting(m_file, this); - vGiteeImageHosting = new VGiteeImageHosting(m_file, this); - vWechatImageHosting = new VWechatImageHosting(m_file, this); - vTencentImageHosting = new VTencentImageHosting(m_file, this); - - QVBoxLayout *layout = new QVBoxLayout(); - layout->addWidget(m_splitter); - layout->setContentsMargins(0, 0, 0, 0); - setLayout(layout); -} - -void VMdTab::showFileReadMode() -{ - m_isEditMode = false; - - // Will recover the header when web side is ready. - m_headerFromEditMode = m_currentHeader; - - updateWebView(); - - setCurrentMode(Mode::Read); - - clearSearchedWordHighlight(); - - updateStatus(); -} - -void VMdTab::updateWebView() -{ - if (m_mdConType == MarkdownConverterType::Hoedown) { - viewWebByConverter(); - } else { - m_document->updateText(); - updateOutlineFromHtml(m_document->getToc()); - } -} - -bool VMdTab::scrollWebViewToHeader(const VHeaderPointer &p_header) -{ - if (!m_outline.isMatched(p_header) - || m_outline.getType() != VTableOfContentType::Anchor) { - return false; - } - - if (p_header.isValid()) { - const VTableOfContentItem *item = m_outline.getItem(p_header); - if (item) { - if (item->m_anchor.isEmpty()) { - return false; - } - - m_currentHeader = p_header; - m_document->scrollToAnchor(item->m_anchor); - } else { - return false; - } - } else { - if (m_outline.isEmpty()) { - // Let it be. - m_currentHeader = p_header; - } else { - // Scroll to top. - m_currentHeader = p_header; - m_document->scrollToAnchor(""); - } - } - - emit currentHeaderChanged(m_currentHeader); - return true; -} - -bool VMdTab::scrollEditorToHeader(const VHeaderPointer &p_header, bool p_force) -{ - if (!m_outline.isMatched(p_header) - || m_outline.getType() != VTableOfContentType::BlockNumber) { - return false; - } - - VMdEditor *mdEdit = getEditor(); - - int blockNumber = -1; - if (p_header.isValid()) { - const VTableOfContentItem *item = m_outline.getItem(p_header); - if (item) { - blockNumber = item->m_blockNumber; - if (blockNumber == -1) { - // Empty item. - return false; - } - } else { - return false; - } - } else { - if (m_outline.isEmpty()) { - // No outline and scroll to -1 index. - // Just let it be. - m_currentHeader = p_header; - return true; - } else { - // Has outline and scroll to -1 index. - // Scroll to top. - blockNumber = 0; - } - } - - // If the cursor are now under the right title, we should not change it right at - // the title. - if (!p_force) { - int curBlockNumber = mdEdit->textCursor().block().blockNumber(); - if (m_outline.indexOfItemByBlockNumber(curBlockNumber) - == m_outline.indexOfItemByBlockNumber(blockNumber)) { - m_currentHeader = p_header; - return true; - } - } - - if (mdEdit->scrollToHeader(blockNumber)) { - m_currentHeader = p_header; - return true; - } else { - return false; - } -} - -bool VMdTab::scrollToHeaderInternal(const VHeaderPointer &p_header) -{ - if (m_isEditMode) { - return scrollEditorToHeader(p_header); - } else { - return scrollWebViewToHeader(p_header); - } -} - -void VMdTab::viewWebByConverter() -{ - VMarkdownConverter mdConverter; - QString toc; - QString html = mdConverter.generateHtml(m_file->getContent(), - g_config->getMarkdownExtensions(), - toc); - m_document->setHtml(html); - updateOutlineFromHtml(toc); -} - -void VMdTab::showFileEditMode() -{ - VHeaderPointer header(m_currentHeader); - - m_isEditMode = true; - - VMdEditor *mdEdit = getEditor(); - - setCurrentMode(Mode::Edit); - - mdEdit->beginEdit(); - - // If editor is not init, we need to wait for it to init headers. - // Generally, beginEdit() will generate the headers. Wait is needed when - // highlight completion is going to re-generate the headers. - int nrRetry = 10; - do { - // We still need to wait even when there is no header to scroll since - // setCurrentMode()'s sendPostedEvents(). - VUtils::sleepWait(100); - } while (header.m_index > -1 - && nrRetry-- >= 0 - && (m_outline.isEmpty() || m_outline.getType() != VTableOfContentType::BlockNumber)); - - scrollEditorToHeader(header, false); - - mdEdit->setFocus(); -} - -bool VMdTab::closeFile(bool p_forced) -{ - if (p_forced && m_isEditMode) { - // Discard buffer content - Q_ASSERT(m_editor); - m_editor->reloadFile(); - m_editor->endEdit(); - - showFileReadMode(); - } else { - readFile(); - } - - return !m_isEditMode; -} - -void VMdTab::editFile() -{ - if (m_isEditMode) { - return; - } - - showFileEditMode(); -} - -void VMdTab::readFile(bool p_discard) -{ - if (!m_isEditMode) { - return; - } - - if (m_editor && isModified()) { - // Prompt to save the changes. - bool modifiable = m_file->isModifiable(); - int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"), - tr("Note %2 has been modified.") - .arg(g_config->c_dataTextStyle).arg(m_file->getName()), - tr("Do you want to save your changes?"), - modifiable ? (QMessageBox::Save - | QMessageBox::Discard - | QMessageBox::Cancel) - : (QMessageBox::Discard - | QMessageBox::Cancel), - modifiable ? (p_discard ? QMessageBox::Discard: QMessageBox::Save) - : QMessageBox::Cancel, - this); - switch (ret) { - case QMessageBox::Save: - if (!saveFile()) { - return; - } - - V_FALLTHROUGH; - - case QMessageBox::Discard: - m_editor->reloadFile(); - break; - - case QMessageBox::Cancel: - // Nothing to do if user cancel this action - return; - - default: - qWarning() << "wrong return value from QMessageBox:" << ret; - return; - } - } - - if (m_editor) { - m_editor->endEdit(); - } - - showFileReadMode(); -} - -bool VMdTab::saveFile() -{ - if (!m_isEditMode) { - return true; - } - - Q_ASSERT(m_editor); - - if (!isModified()) { - return true; - } - - QString filePath = m_file->fetchPath(); - - if (!m_file->isModifiable()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Could not modify a read-only note %2.") - .arg(g_config->c_dataTextStyle).arg(filePath), - tr("Please save your changes to other notes manually."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - return false; - } - - bool ret = true; - // Make sure the file already exists. Temporary deal with cases when user delete or move - // a file. - if (!QFileInfo::exists(filePath)) { - qWarning() << filePath << "being written has been removed"; - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), - tr("File %2 being written has been removed.") - .arg(g_config->c_dataTextStyle).arg(filePath), - QMessageBox::Ok, QMessageBox::Ok, this); - ret = false; - } else { - m_checkFileChange = false; - m_editor->saveFile(); - ret = m_file->save(); - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to save note."), - tr("Fail to write to disk when saving a note. Please try it again."), - QMessageBox::Ok, - QMessageBox::Ok, - this); - m_editor->setModified(true); - } else { - m_fileDiverged = false; - m_checkFileChange = true; - } - } - - updateStatus(); - - return ret; -} - -bool VMdTab::isModified() const -{ - return (m_editor ? m_editor->isModified() : false) || m_fileDiverged; -} - -void VMdTab::saveAndRead() -{ - saveFile(); - readFile(); -} - -void VMdTab::discardAndRead() -{ - readFile(); -} - -void VMdTab::setupMarkdownViewer() -{ - m_webViewer = new VWebView(m_file, this); - connect(m_webViewer, &VWebView::editNote, - this, &VMdTab::editFile); - connect(m_webViewer, &VWebView::requestSavePage, - this, &VMdTab::handleSavePageRequested); - connect(m_webViewer, &VWebView::selectionChanged, - this, &VMdTab::handleWebSelectionChanged); - connect(m_webViewer, &VWebView::requestExpandRestorePreviewArea, - this, &VMdTab::expandRestorePreviewArea); - - VPreviewPage *page = new VPreviewPage(m_webViewer); - m_webViewer->setPage(page); - m_webViewer->setZoomFactor(g_config->getWebZoomFactor()); - connect(page->profile(), &QWebEngineProfile::downloadRequested, - this, &VMdTab::handleDownloadRequested); - connect(page, &QWebEnginePage::linkHovered, - this, &VMdTab::statusMessage); - - // Avoid white flash before loading content. - // Setting Qt::transparent will force GrayScale antialias rendering. - page->setBackgroundColor(g_config->getBaseBackground()); - - m_document = new VDocument(m_file, m_webViewer); - m_documentID = m_document->registerIdentifier(); - - QWebChannel *channel = new QWebChannel(m_webViewer); - channel->registerObject(QStringLiteral("content"), m_document); - connect(m_document, &VDocument::tocChanged, - this, &VMdTab::updateOutlineFromHtml); - connect(m_document, SIGNAL(headerChanged(const QString &)), - this, SLOT(updateCurrentHeader(const QString &))); - connect(m_document, &VDocument::keyPressed, - this, &VMdTab::handleWebKeyPressed); - connect(m_document, &VDocument::logicsFinished, - this, [this]() { - if (m_ready & TabReady::ReadMode) { - // Recover header from edit mode. - scrollWebViewToHeader(m_headerFromEditMode); - m_headerFromEditMode.clear(); - m_document->muteWebView(false); - return; - } - - m_ready |= TabReady::ReadMode; - - tabIsReady(TabReady::ReadMode); - }); - connect(m_document, &VDocument::textToHtmlFinished, - this, [this](int p_identitifer, int p_id, int p_timeStamp, const QString &p_html) { - Q_ASSERT(m_editor); - if (m_documentID != p_identitifer) { - return; - } - - m_editor->textToHtmlFinished(p_id, p_timeStamp, m_webViewer->url(), p_html); - }); - connect(m_document, &VDocument::htmlToTextFinished, - this, [this](int p_identitifer, int p_id, int p_timeStamp, const QString &p_text) { - Q_ASSERT(m_editor); - if (m_documentID != p_identitifer) { - return; - } - - m_editor->htmlToTextFinished(p_id, p_timeStamp, p_text); - }); - connect(m_document, &VDocument::wordCountInfoUpdated, - this, [this]() { - VEditTabInfo info = fetchTabInfo(VEditTabInfo::InfoType::All); - if (m_isEditMode) { - info.m_wordCountInfo = m_document->getWordCountInfo(); - } - - emit statusUpdated(info); - }); - - page->setWebChannel(channel); - - m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType), - m_file->getBaseUrl()); - - m_splitter->addWidget(m_webViewer); -} - -void VMdTab::setupMarkdownEditor() -{ - Q_ASSERT(!m_editor); - - m_editor = new VMdEditor(m_file, - m_document, - m_mdConType, - m_editArea->getCompleter(), - this); - m_editor->setProperty("MainEditor", true); - m_editor->setEditTab(this); - int delta = g_config->getEditorZoomDelta(); - if (delta > 0) { - m_editor->zoomInW(delta); - } else if (delta < 0) { - m_editor->zoomOutW(-delta); - } - - connect(m_editor, &VMdEditor::headersChanged, - this, &VMdTab::updateOutlineFromHeaders); - connect(m_editor, SIGNAL(currentHeaderChanged(int)), - this, SLOT(updateCurrentHeader(int))); - connect(m_editor, &VMdEditor::statusChanged, - this, &VMdTab::updateStatus); - connect(m_editor, &VMdEditor::textChanged, - this, &VMdTab::updateStatus); - connect(g_mainWin, &VMainWindow::editorConfigUpdated, - m_editor, &VMdEditor::updateConfig); - connect(m_editor->object(), &VEditorObject::cursorPositionChanged, - this, &VMdTab::updateCursorStatus); - connect(m_editor->object(), &VEditorObject::saveAndRead, - this, &VMdTab::saveAndRead); - connect(m_editor->object(), &VEditorObject::discardAndRead, - this, &VMdTab::discardAndRead); - connect(m_editor->object(), &VEditorObject::saveNote, - this, &VMdTab::saveFile); - connect(m_editor->object(), &VEditorObject::statusMessage, - this, &VEditTab::statusMessage); - connect(m_editor->object(), &VEditorObject::vimStatusUpdated, - this, &VEditTab::vimStatusUpdated); - connect(m_editor->object(), &VEditorObject::requestCloseFindReplaceDialog, - this, [this]() { - this->m_editArea->getFindReplaceDialog()->closeDialog(); - }); - connect(m_editor->object(), &VEditorObject::ready, - this, [this]() { - if (m_ready & TabReady::EditMode) { - return; - } - - m_ready |= TabReady::EditMode; - - tabIsReady(TabReady::EditMode); - }); - connect(m_editor, &VMdEditor::requestTextToHtml, - this, &VMdTab::textToHtmlViaWebView); - connect(m_editor, &VMdEditor::requestHtmlToText, - this, &VMdTab::htmlToTextViaWebView); - - connect(m_editor, &VMdEditor::requestUploadImageToGithub, - this, &VMdTab::handleUploadImageToGithubRequested); - connect(m_editor, &VMdEditor::requestUploadImageToGitee, - this, &VMdTab::handleUploadImageToGiteeRequested); - connect(m_editor, &VMdEditor::requestUploadImageToWechat, - this, &VMdTab::handleUploadImageToWechatRequested); - connect(m_editor, &VMdEditor::requestUploadImageToTencent, - this, &VMdTab::handleUploadImageToTencentRequested); - - if (m_editor->getVim()) { - connect(m_editor->getVim(), &VVim::commandLineTriggered, - this, [this](VVim::CommandLineType p_type) { - if (m_isEditMode) { - emit triggerVimCmd(p_type); - } - }); - } - - enableHeadingSequence(m_enableHeadingSequence); - m_editor->reloadFile(); - m_splitter->insertWidget(0, m_editor); - - m_livePreviewHelper = new VLivePreviewHelper(m_editor, m_document, this); - connect(m_editor->getMarkdownHighlighter(), &PegMarkdownHighlighter::codeBlocksUpdated, - m_livePreviewHelper, &VLivePreviewHelper::updateCodeBlocks); - connect(m_editor->getPreviewManager(), &VPreviewManager::previewEnabledChanged, - m_livePreviewHelper, &VLivePreviewHelper::setInplacePreviewEnabled); - connect(m_livePreviewHelper, &VLivePreviewHelper::inplacePreviewCodeBlockUpdated, - m_editor->getPreviewManager(), &VPreviewManager::updateCodeBlocks); - connect(m_livePreviewHelper, &VLivePreviewHelper::checkBlocksForObsoletePreview, - m_editor->getPreviewManager(), &VPreviewManager::checkBlocksForObsoletePreview); - m_livePreviewHelper->setInplacePreviewEnabled(m_editor->getPreviewManager()->isPreviewEnabled()); - - m_mathjaxPreviewHelper = new VMathJaxInplacePreviewHelper(m_editor, m_document, this); - connect(m_editor->getMarkdownHighlighter(), &PegMarkdownHighlighter::mathjaxBlocksUpdated, - m_mathjaxPreviewHelper, &VMathJaxInplacePreviewHelper::updateMathjaxBlocks); - connect(m_editor->getPreviewManager(), &VPreviewManager::previewEnabledChanged, - m_mathjaxPreviewHelper, &VMathJaxInplacePreviewHelper::setEnabled); - connect(m_mathjaxPreviewHelper, &VMathJaxInplacePreviewHelper::inplacePreviewMathjaxBlockUpdated, - m_editor->getPreviewManager(), &VPreviewManager::updateMathjaxBlocks); - connect(m_mathjaxPreviewHelper, &VMathJaxInplacePreviewHelper::checkBlocksForObsoletePreview, - m_editor->getPreviewManager(), &VPreviewManager::checkBlocksForObsoletePreview); - m_mathjaxPreviewHelper->setEnabled(m_editor->getPreviewManager()->isPreviewEnabled()); - - vGithubImageHosting->setEditor(m_editor); - vGiteeImageHosting->setEditor(m_editor); - vWechatImageHosting->setEditor(m_editor); - vTencentImageHosting->setEditor(m_editor); -} - -void VMdTab::updateOutlineFromHtml(const QString &p_tocHtml) -{ - if (m_isEditMode) { - return; - } - - m_outline.clear(); - - if (m_outline.parseTableFromHtml(p_tocHtml)) { - m_outline.setFile(m_file); - m_outline.setType(VTableOfContentType::Anchor); - } - - m_currentHeader.reset(); - - emit outlineChanged(m_outline); -} - -void VMdTab::updateOutlineFromHeaders(const QVector &p_headers) -{ - if (!m_isEditMode) { - return; - } - - m_outline.update(m_file, - p_headers, - VTableOfContentType::BlockNumber); - - m_currentHeader.reset(); - - emit outlineChanged(m_outline); -} - -void VMdTab::scrollToHeader(const VHeaderPointer &p_header) -{ - if (m_outline.isMatched(p_header)) { - // Scroll only when @p_header is valid. - scrollToHeaderInternal(p_header); - } -} - -void VMdTab::updateCurrentHeader(const QString &p_anchor) -{ - if (m_isEditMode) { - return; - } - - // Find the index of the anchor in outline. - int idx = m_outline.indexOfItemByAnchor(p_anchor); - m_currentHeader.update(m_file, idx); - - emit currentHeaderChanged(m_currentHeader); -} - -void VMdTab::updateCurrentHeader(int p_blockNumber) -{ - if (!m_isEditMode) { - return; - } - - // Find the index of the block number in outline. - int idx = m_outline.indexOfItemByBlockNumber(p_blockNumber); - m_currentHeader.update(m_file, idx); - - emit currentHeaderChanged(m_currentHeader); -} - -void VMdTab::insertImage() -{ - if (!m_isEditMode) { - return; - } - - Q_ASSERT(m_editor); - m_editor->insertImage(); -} - -void VMdTab::insertLink() -{ - if (!m_isEditMode) { - return; - } - - Q_ASSERT(m_editor); - m_editor->insertLink(); -} - -void VMdTab::insertTable() -{ - if (!m_isEditMode) { - return; - } - - Q_ASSERT(m_editor); - m_editor->insertTable(); -} - -void VMdTab::findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward) -{ - if (m_isEditMode && !previewExpanded()) { - if (p_peek) { - m_editor->peekText(p_text, p_options); - } else { - m_editor->findText(p_text, p_options, p_forward); - } - } else { - findTextInWebView(p_text, p_options, p_peek, p_forward); - } -} - -void VMdTab::findText(const VSearchToken &p_token, - bool p_forward, - bool p_fromStart) -{ - if (m_isEditMode) { - m_editor->findText(p_token, p_forward, p_fromStart); - } else { - // TODO - Q_ASSERT(false); - } -} - -void VMdTab::replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) -{ - if (m_isEditMode) { - Q_ASSERT(m_editor); - m_editor->replaceText(p_text, p_options, p_replaceText, p_findNext); - } -} - -void VMdTab::replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) -{ - if (m_isEditMode) { - Q_ASSERT(m_editor); - m_editor->replaceTextAll(p_text, p_options, p_replaceText); - } -} - -void VMdTab::nextMatch(const QString &p_text, uint p_options, bool p_forward) -{ - if (m_isEditMode) { - Q_ASSERT(m_editor); - m_editor->nextMatch(p_forward); - } else { - findTextInWebView(p_text, p_options, false, p_forward); - } -} - -void VMdTab::findTextInWebView(const QString &p_text, uint p_options, - bool /* p_peek */, bool p_forward) -{ - V_ASSERT(m_webViewer); - - QWebEnginePage::FindFlags flags; - if (p_options & FindOption::CaseSensitive) { - flags |= QWebEnginePage::FindCaseSensitively; - } - - if (!p_forward) { - flags |= QWebEnginePage::FindBackward; - } - - m_webViewer->findText(p_text, flags); -} - -QString VMdTab::getSelectedText() const -{ - if (m_isEditMode) { - Q_ASSERT(m_editor); - QTextCursor cursor = m_editor->textCursor(); - return cursor.selectedText(); - } else { - return m_webViewer->selectedText(); - } -} - -void VMdTab::clearSearchedWordHighlight() -{ - if (m_webViewer) { - m_webViewer->findText(""); - } - - if (m_editor) { - m_editor->clearSearchedWordHighlight(); - } -} - -void VMdTab::handleWebKeyPressed(int p_key, bool p_ctrl, bool p_shift, bool p_meta) -{ - V_ASSERT(m_webViewer); - -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - bool macCtrl = p_meta; -#else - Q_UNUSED(p_meta); - bool macCtrl = false; -#endif - - switch (p_key) { - // Esc - case 27: - m_editArea->getFindReplaceDialog()->closeDialog(); - break; - - // Dash - case 189: - if (p_ctrl || macCtrl) { - // Zoom out. - zoomWebPage(false); - } - - break; - - // Equal - case 187: - if (p_ctrl || macCtrl) { - // Zoom in. - zoomWebPage(true); - } - - break; - - // 0 - case 48: - if (p_ctrl || macCtrl) { - // Recover zoom. - m_webViewer->setZoomFactor(1); - } - - break; - - // / or ? - case 191: - if (!p_ctrl) { - VVim::CommandLineType type = VVim::CommandLineType::SearchForward; - if (p_shift) { - // ?, search backward. - type = VVim::CommandLineType::SearchBackward; - } - - emit triggerVimCmd(type); - } - - break; - - // : - case 186: - if (!p_ctrl && p_shift) { - VVim::CommandLineType type = VVim::CommandLineType::Command; - - emit triggerVimCmd(type); - } - - break; - - // n or N - case 78: - if (!p_ctrl) { - if (!m_lastSearchItem.isEmpty()) { - bool forward = !p_shift; - findTextInWebView(m_lastSearchItem.m_text, - m_lastSearchItem.m_options, - false, - forward ? m_lastSearchItem.m_forward : !m_lastSearchItem.m_forward); - } - } - - break; - - default: - break; - } -} - -void VMdTab::zoom(bool p_zoomIn, qreal p_step) -{ - if (!m_isEditMode || m_mode == Mode::EditPreview) { - zoomWebPage(p_zoomIn, p_step); - } -} - -void VMdTab::zoomWebPage(bool p_zoomIn, qreal p_step) -{ - V_ASSERT(m_webViewer); - - qreal curFactor = m_webViewer->zoomFactor(); - qreal newFactor = p_zoomIn ? curFactor + p_step : curFactor - p_step; - if (newFactor < c_webZoomFactorMin) { - newFactor = c_webZoomFactorMin; - } else if (newFactor > c_webZoomFactorMax) { - newFactor = c_webZoomFactorMax; - } - - m_webViewer->setZoomFactor(newFactor); -} - -VWebView *VMdTab::getWebViewer() const -{ - return m_webViewer; -} - -MarkdownConverterType VMdTab::getMarkdownConverterType() const -{ - return m_mdConType; -} - -void VMdTab::focusChild() -{ - switch (m_mode) { - case Mode::Read: - m_webViewer->setFocus(); - break; - - case Mode::Edit: - m_editor->setFocus(); - break; - - case Mode::EditPreview: - if (m_editor->isVisible()) { - m_editor->setFocus(); - } else { - m_webViewer->setFocus(); - } - - break; - - default: - this->setFocus(); - break; - } -} - -void VMdTab::requestUpdateVimStatus() -{ - if (m_editor) { - m_editor->requestUpdateVimStatus(); - } else { - emit vimStatusUpdated(NULL); - } -} - -VEditTabInfo VMdTab::fetchTabInfo(VEditTabInfo::InfoType p_type) const -{ - VEditTabInfo info = VEditTab::fetchTabInfo(p_type); - - if (m_editor) { - QTextCursor cursor = m_editor->textCursor(); - info.m_cursorBlockNumber = cursor.block().blockNumber(); - info.m_cursorPositionInBlock = cursor.positionInBlock(); - info.m_blockCount = m_editor->document()->blockCount(); - } - - if (m_isEditMode) { - if (m_editor) { - // We do not get the full word count info in edit mode. - info.m_wordCountInfo.m_mode = VWordCountInfo::Edit; - info.m_wordCountInfo.m_charWithSpacesCount = m_editor->document()->characterCount() - 1; - } - } else { - info.m_wordCountInfo = m_document->getWordCountInfo(); - } - - info.m_headerIndex = m_currentHeader.m_index; - - return info; -} - -void VMdTab::decorateText(TextDecoration p_decoration, int p_level) -{ - if (m_editor) { - m_editor->decorateText(p_decoration, p_level); - } -} - -bool VMdTab::restoreFromTabInfo(const VEditTabInfo &p_info) -{ - if (p_info.m_editTab != this) { - return false; - } - - bool ret = false; - // Restore cursor position. - if (m_isEditMode - && m_editor - && p_info.m_cursorBlockNumber > -1 - && p_info.m_cursorPositionInBlock > -1) { - ret = m_editor->setCursorPosition(p_info.m_cursorBlockNumber, p_info.m_cursorPositionInBlock); - } - - // Restore header. - if (!ret) { - VHeaderPointer header(m_file, p_info.m_headerIndex); - ret = scrollToHeaderInternal(header); - } - - return ret; -} - -void VMdTab::restoreFromTabInfo() -{ - restoreFromTabInfo(m_infoToRestore); - - // Clear it anyway. - m_infoToRestore.clear(); -} - -void VMdTab::enableHeadingSequence(bool p_enabled) -{ - m_enableHeadingSequence = p_enabled; - - if (m_editor) { - VEditConfig &config = m_editor->getConfig(); - config.m_enableHeadingSequence = m_enableHeadingSequence; - if (isEditMode()) { - m_editor->updateHeaderSequenceByConfigChange(); - } - } -} - -bool VMdTab::isHeadingSequenceEnabled() const -{ - return m_enableHeadingSequence; -} - -void VMdTab::evaluateMagicWords() -{ - if (isEditMode() && m_file->isModifiable()) { - getEditor()->evaluateMagicWords(); - } -} - -void VMdTab::applySnippet(const VSnippet *p_snippet) -{ - Q_ASSERT(p_snippet); - - if (isEditMode() - && m_file->isModifiable() - && p_snippet->getType() == VSnippet::Type::PlainText) { - Q_ASSERT(m_editor); - QTextCursor cursor = m_editor->textCursor(); - bool changed = p_snippet->apply(cursor); - if (changed) { - m_editor->setTextCursor(cursor); - - m_editor->setVimMode(VimMode::Insert); - - g_mainWin->showStatusMessage(tr("Snippet applied")); - - focusTab(); - } - } else { - g_mainWin->showStatusMessage(tr("Snippet %1 is not applicable").arg(p_snippet->getName())); - } -} - -void VMdTab::applySnippet() -{ - if (!isEditMode() || !m_file->isModifiable()) { - g_mainWin->showStatusMessage(tr("Snippets are not applicable")); - return; - } - - QPoint pos(m_editor->cursorRect().bottomRight()); - QMenu menu(this); - VInsertSelector *sel = prepareSnippetSelector(&menu); - if (!sel) { - g_mainWin->showStatusMessage(tr("No available snippets defined with shortcuts")); - return; - } - - QWidgetAction *act = new QWidgetAction(&menu); - act->setDefaultWidget(sel); - connect(sel, &VInsertSelector::accepted, - this, [&menu]() { - QKeyEvent *escEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, - Qt::NoModifier); - QCoreApplication::postEvent(&menu, escEvent); - }); - - menu.addAction(act); - - menu.exec(m_editor->mapToGlobal(pos)); - - QString chosenItem = sel->getClickedItem(); - if (!chosenItem.isEmpty()) { - const VSnippet *snip = g_mainWin->getSnippetList()->getSnippet(chosenItem); - if (snip) { - applySnippet(snip); - } - } -} - -static bool selectorItemCmp(const VInsertSelectorItem &p_a, const VInsertSelectorItem &p_b) -{ - if (p_a.m_shortcut < p_b.m_shortcut) { - return true; - } - - return false; -} - -VInsertSelector *VMdTab::prepareSnippetSelector(QWidget *p_parent) -{ - auto snippets = g_mainWin->getSnippetList()->getSnippets(); - QVector items; - for (auto const & snip : snippets) { - if (!snip.getShortcut().isNull()) { - items.push_back(VInsertSelectorItem(snip.getName(), - snip.getName(), - snip.getShortcut())); - } - } - - if (items.isEmpty()) { - return NULL; - } - - // Sort items by shortcut. - std::sort(items.begin(), items.end(), selectorItemCmp); - - VInsertSelector *sel = new VInsertSelector(7, items, p_parent); - return sel; -} - -void VMdTab::reload() -{ - // Reload editor. - if (m_editor) { - m_editor->reloadFile(); - } - - if (m_isEditMode) { - m_editor->endEdit(); - m_editor->beginEdit(); - updateStatus(); - } - - if (!m_isEditMode) { - updateWebView(); - } - - // Reload web viewer. - m_ready &= ~TabReady::ReadMode; - m_webViewer->reload(); - - if (!m_isEditMode) { - VUtils::sleepWait(500); - showFileReadMode(); - } -} - -void VMdTab::tabIsReady(TabReady p_mode) -{ - bool isCurrentMode = (m_isEditMode && p_mode == TabReady::EditMode) - || (!m_isEditMode && p_mode == TabReady::ReadMode); - - if (isCurrentMode) { - if (p_mode == TabReady::ReadMode) { - m_document->muteWebView(false); - } - - restoreFromTabInfo(); - - if (m_enableBackupFile - && !m_backupFileChecked - && m_file->isModifiable()) { - if (!checkPreviousBackupFile()) { - return; - } - } - } - - if (m_enableBackupFile - && m_file->isModifiable() - && p_mode == TabReady::EditMode) { - // contentsChanged will be emitted even the content is not changed. - connect(m_editor->document(), &QTextDocument::contentsChange, - this, [this]() { - if (m_isEditMode) { - m_backupTimer->stop(); - m_backupTimer->start(); - } - }); - } - - if (m_editor - && p_mode == TabReady::ReadMode - && m_livePreviewHelper->isPreviewEnabled()) { - // Need to re-preview. - m_editor->getMarkdownHighlighter()->updateHighlight(); - } -} - -void VMdTab::writeBackupFile() -{ - Q_ASSERT(m_enableBackupFile && m_file->isModifiable()); - m_file->writeBackupFile(m_editor->getContent()); -} - -bool VMdTab::checkPreviousBackupFile() -{ - m_backupFileChecked = true; - - QString preFile = m_file->backupFileOfPreviousSession(); - if (preFile.isEmpty()) { - return true; - } - - QString backupContent = m_file->readBackupFile(preFile); - if (m_file->getContent() == backupContent) { - // Found backup file with identical content. - // Just discard the backup file. - VUtils::deleteFile(preFile); - return true; - } - - QMessageBox box(QMessageBox::Warning, - tr("Backup File Found"), - tr("Found backup file %2 " - "when opening note %3.") - .arg(g_config->c_dataTextStyle) - .arg(preFile) - .arg(m_file->fetchPath()), - QMessageBox::NoButton, - this); - QString info = tr("VNote may crash while editing this note before.
    " - "Please choose to recover from the backup file or delete it.

    " - "Note file last modified: %2
    " - "Backup file last modified: %3") - .arg(g_config->c_dataTextStyle) - .arg(VUtils::displayDateTime(QFileInfo(m_file->fetchPath()).lastModified())) - .arg(VUtils::displayDateTime(QFileInfo(preFile).lastModified())); - box.setInformativeText(info); - QPushButton *recoverBtn = box.addButton(tr("Recover From Backup File"), QMessageBox::YesRole); - box.addButton(tr("Discard Backup File"), QMessageBox::NoRole); - QPushButton *cancelBtn = box.addButton(tr("Cancel"), QMessageBox::RejectRole); - - box.setDefaultButton(cancelBtn); - box.setTextInteractionFlags(Qt::TextSelectableByMouse); - - box.exec(); - QAbstractButton *btn = box.clickedButton(); - if (btn == cancelBtn || !btn) { - // Close current tab. - emit closeRequested(this); - return false; - } else if (btn == recoverBtn) { - // Load content from the backup file. - if (!m_isEditMode) { - showFileEditMode(); - } - - Q_ASSERT(m_editor); - m_editor->setContent(backupContent, true); - - updateStatus(); - } - - VUtils::deleteFile(preFile); - - return true; -} - -void VMdTab::updateCursorStatus() -{ - emit statusUpdated(fetchTabInfo(VEditTabInfo::InfoType::Cursor)); -} - -void VMdTab::handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act) -{ - // Reload the web view with new base URL. - m_headerFromEditMode = m_currentHeader; - m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType), - m_file->getBaseUrl()); - - if (m_editor) { - m_editor->updateInitAndInsertedImages(p_isFile, p_act); - - // Refresh the previewed images in edit mode. - m_editor->refreshPreview(); - } -} - -void VMdTab::textToHtmlViaWebView(const QString &p_text, int p_id, int p_timeStamp) -{ - int maxRetry = 50; - while (!m_document->isReadyToTextToHtml() && maxRetry > 0) { - qDebug() << "wait for web side ready to convert text to HTML"; - VUtils::sleepWait(100); - --maxRetry; - } - - if (maxRetry == 0) { - qWarning() << "web side is not ready to convert text to HTML"; - return; - } - - m_document->textToHtmlAsync(m_documentID, p_id, p_timeStamp, p_text, true); -} - -void VMdTab::htmlToTextViaWebView(const QString &p_html, int p_id, int p_timeStamp) -{ - int maxRetry = 50; - while (!m_document->isReadyToTextToHtml() && maxRetry > 0) { - qDebug() << "wait for web side ready to convert HTML to text"; - VUtils::sleepWait(100); - --maxRetry; - } - - if (maxRetry == 0) { - qWarning() << "web side is not ready to convert HTML to text"; - return; - } - - m_document->htmlToTextAsync(m_documentID, p_id, p_timeStamp, p_html); -} - -void VMdTab::handleVimCmdCommandCancelled() -{ - if (m_isEditMode) { - VVim *vim = getEditor()->getVim(); - if (vim) { - vim->processCommandLineCancelled(); - } - } -} - -void VMdTab::handleVimCmdCommandFinished(VVim::CommandLineType p_type, const QString &p_cmd) -{ - if (m_isEditMode && !previewExpanded()) { - VVim *vim = getEditor()->getVim(); - if (vim) { - vim->processCommandLine(p_type, p_cmd); - } - } else { - if (p_type == VVim::CommandLineType::SearchForward - || p_type == VVim::CommandLineType::SearchBackward) { - m_lastSearchItem = VVim::fetchSearchItem(p_type, p_cmd); - findTextInWebView(m_lastSearchItem.m_text, - m_lastSearchItem.m_options, - false, - m_lastSearchItem.m_forward); - } else { - executeVimCommandInWebView(p_cmd); - } - } -} - -void VMdTab::handleVimCmdCommandChanged(VVim::CommandLineType p_type, const QString &p_cmd) -{ - Q_UNUSED(p_type); - Q_UNUSED(p_cmd); - if (m_isEditMode && !previewExpanded()) { - VVim *vim = getEditor()->getVim(); - if (vim) { - vim->processCommandLineChanged(p_type, p_cmd); - } - } else { - if (p_type == VVim::CommandLineType::SearchForward - || p_type == VVim::CommandLineType::SearchBackward) { - VVim::SearchItem item = VVim::fetchSearchItem(p_type, p_cmd); - findTextInWebView(item.m_text, item.m_options, true, item.m_forward); - } - } -} - -QString VMdTab::handleVimCmdRequestNextCommand(VVim::CommandLineType p_type, const QString &p_cmd) -{ - Q_UNUSED(p_type); - Q_UNUSED(p_cmd); - if (m_isEditMode) { - VVim *vim = getEditor()->getVim(); - if (vim) { - return vim->getNextCommandHistory(p_type, p_cmd); - } - } - - return QString(); -} - -QString VMdTab::handleVimCmdRequestPreviousCommand(VVim::CommandLineType p_type, const QString &p_cmd) -{ - Q_UNUSED(p_type); - Q_UNUSED(p_cmd); - if (m_isEditMode) { - VVim *vim = getEditor()->getVim(); - if (vim) { - return vim->getPreviousCommandHistory(p_type, p_cmd); - } - } - - return QString(); -} - -QString VMdTab::handleVimCmdRequestRegister(int p_key, int p_modifiers) -{ - Q_UNUSED(p_key); - Q_UNUSED(p_modifiers); - if (m_isEditMode) { - VVim *vim = getEditor()->getVim(); - if (vim) { - return vim->readRegister(p_key, p_modifiers); - } - } - - return QString(); -} - -bool VMdTab::executeVimCommandInWebView(const QString &p_cmd) -{ - bool validCommand = true; - QString msg; - - if (p_cmd.isEmpty()) { - return true; - } else if (p_cmd == "q") { - // :q, close the note. - emit closeRequested(this); - msg = tr("Quit"); - } else if (p_cmd == "nohlsearch" || p_cmd == "noh") { - // :nohlsearch, clear highlight search. - m_webViewer->findText(""); - } else if (p_cmd == "e") { - // :e, enter edit mode. - showFileEditMode(); - } else if (p_cmd.size() > 2 && p_cmd.left(2) == "e ") { - // :e , open a note in edit mode. - auto filePath = p_cmd.mid(2).trimmed(); - - if(filePath.left(2) == "~/") { - filePath.remove(0, 1).insert(0, QDir::homePath()); - } else if(filePath.left(2) == "./" || filePath[0] != '/') { - VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory(); - if(filePath.left(2) == "./") { - filePath.remove(0, 1); - } else { - filePath.insert(0, '/'); - } - filePath.insert(0, dir->fetchPath()); - } - - if(g_mainWin->openFiles(QStringList(filePath), false, OpenFileMode::Edit).size()) { - msg = tr("Open %1 in edit mode.").arg(filePath); - } else { - msg = tr("Unable to open %1").arg(filePath); - } - } else { - validCommand = false; - } - - if (!validCommand) { - g_mainWin->showStatusMessage(tr("Not an editor command: %1").arg(p_cmd)); - } else { - g_mainWin->showStatusMessage(msg); - } - - return validCommand; -} - -void VMdTab::handleDownloadRequested(QWebEngineDownloadItem *p_item) -{ - connect(p_item, &QWebEngineDownloadItem::stateChanged, - this, [p_item, this](QWebEngineDownloadItem::DownloadState p_state) { - QString msg; - switch (p_state) { - case QWebEngineDownloadItem::DownloadCompleted: - emit statusMessage(tr("Page saved to %1").arg(p_item->path())); - break; - - case QWebEngineDownloadItem::DownloadCancelled: - case QWebEngineDownloadItem::DownloadInterrupted: - emit statusMessage(tr("Fail to save page to %1").arg(p_item->path())); - break; - - default: - break; - } - }); -} - -void VMdTab::handleSavePageRequested() -{ - static QString lastPath = g_config->getDocumentPathOrHomePath(); - - QStringList filters; - filters << tr("Single HTML (*.html)") << tr("Complete HTML (*.html)") << tr("MIME HTML (*.mht)"); - QList formats; - formats << QWebEngineDownloadItem::SingleHtmlSaveFormat - << QWebEngineDownloadItem::CompleteHtmlSaveFormat - << QWebEngineDownloadItem::MimeHtmlSaveFormat; - - QString selectedFilter = filters[1]; - QString fileName = QFileDialog::getSaveFileName(this, - tr("Save Page"), - lastPath, - filters.join(";;"), - &selectedFilter); - if (fileName.isEmpty()) { - return; - } - - lastPath = QFileInfo(fileName).path(); - - QWebEngineDownloadItem::SavePageFormat format = formats.at(filters.indexOf(selectedFilter)); - - qDebug() << "save page as" << format << "to" << fileName; - - emit statusMessage(tr("Saving page to %1").arg(fileName)); - - m_webViewer->page()->save(fileName, format); -} - -void VMdTab::handleUploadImageToGithubRequested() -{ - if (isModified()) { - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Please save changes to file before uploading images."), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - vGithubImageHosting->handleUploadImageToGithubRequested(); -} - -void VMdTab::handleUploadImageToGiteeRequested() -{ - if (isModified()) { - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Please save changes to file before uploading images."), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - vGiteeImageHosting->handleUploadImageToGiteeRequested(); -} - -void VMdTab::handleUploadImageToWechatRequested() -{ - if (isModified()) { - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Please save changes to file before uploading images."), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - vWechatImageHosting->handleUploadImageToWechatRequested(); -} - -void VMdTab::handleUploadImageToTencentRequested() -{ - if (isModified()) { - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - tr("Please save changes to file before uploading images."), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - return; - } - - vTencentImageHosting->handleUploadImageToTencentRequested(); -} - -VWordCountInfo VMdTab::fetchWordCountInfo(bool p_editMode) const -{ - if (p_editMode) { - if (m_editor) { - return m_editor->fetchWordCountInfo(); - } - } else { - // Request to update with current text. - if (m_isEditMode) { - const_cast(this)->updateWebView(); - } - - return m_document->getWordCountInfo(); - } - - return VWordCountInfo(); -} - -void VMdTab::setCurrentMode(Mode p_mode) -{ - if (m_mode == p_mode) { - return; - } - - qreal factor = m_webViewer->zoomFactor(); - if (m_mode == Mode::Read) { - m_readWebViewState->m_zoomFactor = factor; - } else if (m_mode == Mode::EditPreview) { - m_previewWebViewState->m_zoomFactor = factor; - m_livePreviewHelper->setLivePreviewEnabled(false); - } - - m_mode = p_mode; - - switch (p_mode) { - case Mode::Read: - if (m_editor) { - m_editor->hide(); - } - - m_webViewer->setInPreview(false); - m_webViewer->show(); - - // Fix the bug introduced by 051088be31dbffa3c04e2d382af15beec40d5fdb - // which replace QStackedLayout with QSplitter. - QCoreApplication::sendPostedEvents(); - - if (m_readWebViewState.isNull()) { - m_readWebViewState.reset(new WebViewState()); - m_readWebViewState->m_zoomFactor = factor; - } else if (factor != m_readWebViewState->m_zoomFactor) { - m_webViewer->setZoomFactor(m_readWebViewState->m_zoomFactor); - } - - m_document->setPreviewEnabled(false); - break; - - case Mode::Edit: - m_document->muteWebView(true); - m_webViewer->hide(); - m_editor->show(); - - QCoreApplication::sendPostedEvents(); - - break; - - case Mode::EditPreview: - Q_ASSERT(m_editor); - m_document->muteWebView(true); - m_webViewer->setInPreview(true); - m_webViewer->show(); - m_editor->show(); - - QCoreApplication::sendPostedEvents(); - - if (m_previewWebViewState.isNull()) { - m_previewWebViewState.reset(new WebViewState()); - m_previewWebViewState->m_zoomFactor = factor; - - // Init the size of two splits. - QList sizes = m_splitter->sizes(); - Q_ASSERT(sizes.size() == 2); - int a = (sizes[0] + sizes[1]) / 2; - if (a <= 0) { - a = 1; - } - - int b = (sizes[0] + sizes[1]) - a; - - QList newSizes; - newSizes.append(a); - newSizes.append(b); - m_splitter->setSizes(newSizes); - } else if (factor != m_previewWebViewState->m_zoomFactor) { - m_webViewer->setZoomFactor(m_previewWebViewState->m_zoomFactor); - } - - m_document->setPreviewEnabled(true); - m_livePreviewHelper->setLivePreviewEnabled(true); - m_editor->getMarkdownHighlighter()->updateHighlight(); - break; - - default: - break; - } - - focusChild(); -} - -bool VMdTab::toggleLivePreview() -{ - bool ret = false; - - switch (m_mode) { - case Mode::EditPreview: - setCurrentMode(Mode::Edit); - ret = true; - break; - - case Mode::Edit: - setCurrentMode(Mode::EditPreview); - ret = true; - break; - - default: - break; - } - - return ret; -} - -void VMdTab::handleWebSelectionChanged() -{ - if (m_mode != Mode::EditPreview - || !(g_config->getSmartLivePreview() & SmartLivePreview::WebToEditor)) { - return; - } - - m_livePreviewTimer->start(); -} - -bool VMdTab::expandRestorePreviewArea() -{ - if (m_mode != Mode::EditPreview) { - return false; - } - - if (m_editor->isVisible()) { - m_editor->hide(); - m_webViewer->setFocus(); - } else { - m_editor->show(); - m_editor->setFocus(); - } - - return true; -} - -bool VMdTab::previewExpanded() const -{ - return (m_mode == Mode::EditPreview) && !m_editor->isVisible(); -} diff --git a/src/vmdtab.h b/src/vmdtab.h deleted file mode 100644 index 3c5d5416..00000000 --- a/src/vmdtab.h +++ /dev/null @@ -1,315 +0,0 @@ -#ifndef VMDTAB_H -#define VMDTAB_H - -#include -#include -#include -#include "vedittab.h" -#include "vconstants.h" -#include "vmarkdownconverter.h" -#include "vconfigmanager.h" -#include "vimagehosting.h" - -class VWebView; -class VDocument; -class VMdEditor; -class VInsertSelector; -class QTimer; -class QWebEngineDownloadItem; -class QSplitter; -class VLivePreviewHelper; -class VMathJaxInplacePreviewHelper; - -class VMdTab : public VEditTab -{ - Q_OBJECT - -public: - VMdTab(VFile *p_file, VEditArea *p_editArea, OpenFileMode p_mode, QWidget *p_parent = 0); - - // Close current tab. - // @p_forced: if true, discard the changes. - bool closeFile(bool p_forced) Q_DECL_OVERRIDE; - - // Enter read mode. - // Will prompt user to save the changes. - void readFile(bool p_discard = false) Q_DECL_OVERRIDE; - - // Save file. - bool saveFile() Q_DECL_OVERRIDE; - - bool isModified() const Q_DECL_OVERRIDE; - - // Scroll to @p_header. - void scrollToHeader(const VHeaderPointer &p_header) Q_DECL_OVERRIDE; - - void insertImage() Q_DECL_OVERRIDE; - - void insertTable() Q_DECL_OVERRIDE; - - void insertLink() Q_DECL_OVERRIDE; - - // Search @p_text in current note. - void findText(const QString &p_text, uint p_options, bool p_peek, - bool p_forward = true) Q_DECL_OVERRIDE; - - void findText(const VSearchToken &p_token, - bool p_forward = true, - bool p_fromStart = false) Q_DECL_OVERRIDE; - - // Replace @p_text with @p_replaceText in current note. - void replaceText(const QString &p_text, uint p_options, - const QString &p_replaceText, bool p_findNext) Q_DECL_OVERRIDE; - - void replaceTextAll(const QString &p_text, uint p_options, - const QString &p_replaceText) Q_DECL_OVERRIDE; - - void nextMatch(const QString &p_text, uint p_options, bool p_forward) Q_DECL_OVERRIDE; - - QString getSelectedText() const Q_DECL_OVERRIDE; - - void clearSearchedWordHighlight() Q_DECL_OVERRIDE; - - VWebView *getWebViewer() const; - - // Get the markdown editor. If not init yet, init and return it. - VMdEditor *getEditor(); - - VMdEditor *getEditor() const; - - MarkdownConverterType getMarkdownConverterType() const; - - void requestUpdateVimStatus() Q_DECL_OVERRIDE; - - // Insert decoration markers or decorate selected text. - void decorateText(TextDecoration p_decoration, int p_level = -1) Q_DECL_OVERRIDE; - - // Create a filled VEditTabInfo. - VEditTabInfo fetchTabInfo(VEditTabInfo::InfoType p_type = VEditTabInfo::InfoType::All) const Q_DECL_OVERRIDE; - - // Enable or disable heading sequence. - void enableHeadingSequence(bool p_enabled); - - bool isHeadingSequenceEnabled() const; - - // Evaluate magic words. - void evaluateMagicWords() Q_DECL_OVERRIDE; - - void applySnippet(const VSnippet *p_snippet) Q_DECL_OVERRIDE; - - void applySnippet() Q_DECL_OVERRIDE; - - void reload() Q_DECL_OVERRIDE; - - void handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act) Q_DECL_OVERRIDE; - - // Fetch tab stat info. - VWordCountInfo fetchWordCountInfo(bool p_editMode) const Q_DECL_OVERRIDE; - - // Toggle live preview in edit mode. - bool toggleLivePreview(); - - bool expandRestorePreviewArea(); - -public slots: - // Enter edit mode. - void editFile() Q_DECL_OVERRIDE; - - void handleVimCmdCommandCancelled() Q_DECL_OVERRIDE; - - void handleVimCmdCommandFinished(VVim::CommandLineType p_type, const QString &p_cmd) Q_DECL_OVERRIDE; - - void handleVimCmdCommandChanged(VVim::CommandLineType p_type, const QString &p_cmd) Q_DECL_OVERRIDE; - - QString handleVimCmdRequestNextCommand(VVim::CommandLineType p_type, const QString &p_cmd) Q_DECL_OVERRIDE; - - QString handleVimCmdRequestPreviousCommand(VVim::CommandLineType p_type, const QString &p_cmd) Q_DECL_OVERRIDE; - - QString handleVimCmdRequestRegister(int p_key, int p_modifiers) Q_DECL_OVERRIDE; - -protected: - void writeBackupFile() Q_DECL_OVERRIDE; - -private slots: - // Update m_outline according to @p_tocHtml for read mode. - void updateOutlineFromHtml(const QString &p_tocHtml); - - // Update m_outline accroding to @p_headers for edit mode. - void updateOutlineFromHeaders(const QVector &p_headers); - - // Web viewer requests to update current header. - // @p_anchor is the anchor of the header, like "toc_1". - void updateCurrentHeader(const QString &p_anchor); - - // Editor requests to update current header. - void updateCurrentHeader(int p_blockNumber); - - // Handle key press event in Web view. - void handleWebKeyPressed(int p_key, bool p_ctrl, bool p_shift, bool p_meta); - - // m_editor requests to save changes and enter read mode. - void saveAndRead(); - - // m_editor requests to discard changes and enter read mode. - void discardAndRead(); - - // Restore from m_infoToRestore. - void restoreFromTabInfo(); - - // Handle download request from web page. - void handleDownloadRequested(QWebEngineDownloadItem *p_item); - - // Handle save page request. - void handleSavePageRequested(); - - // Selection changed in web. - void handleWebSelectionChanged(); - - // Process the image upload request to GitHub. - void handleUploadImageToGithubRequested(); - - // Process the image upload request to Gitee. - void handleUploadImageToGiteeRequested(); - - // Process image upload request to wechat. - void handleUploadImageToWechatRequested(); - - // Process image upload request to tencent. - void handleUploadImageToTencentRequested(); - -private: - enum TabReady { None = 0, ReadMode = 0x1, EditMode = 0x2 }; - - enum Mode { InvalidMode = 0, Read, Edit, EditPreview }; - - struct WebViewState - { - qreal m_zoomFactor; - }; - - // Setup UI. - void setupUI(); - - // Show the file content in read mode. - void showFileReadMode(); - - // Show the file content in edit mode. - void showFileEditMode(); - - // Setup Markdown viewer. - void setupMarkdownViewer(); - - // Setup Markdown editor. - void setupMarkdownEditor(); - - // Use VMarkdownConverter (hoedown) to generate the Web view. - void viewWebByConverter(); - - // Scroll Web view to given header. - // Return true if scroll was made. - bool scrollWebViewToHeader(const VHeaderPointer &p_header); - - // @p_force: when true, will scroll even current mouse is under the specified header. - bool scrollEditorToHeader(const VHeaderPointer &p_header, bool p_force = true); - - // Scroll web/editor to given header. - // Return true if scroll was made. - bool scrollToHeaderInternal(const VHeaderPointer &p_header); - - // Search text in Web view. - void findTextInWebView(const QString &p_text, uint p_options, bool p_peek, - bool p_forward); - - // Called to zoom in/out content. - void zoom(bool p_zoomIn, qreal p_step = 0.25) Q_DECL_OVERRIDE; - - // Zoom Web View. - void zoomWebPage(bool p_zoomIn, qreal p_step = 0.25); - - // Focus the proper child widget. - void focusChild() Q_DECL_OVERRIDE; - - // Restore from @p_fino. - // Return true if succeed. - bool restoreFromTabInfo(const VEditTabInfo &p_info) Q_DECL_OVERRIDE; - - // Prepare insert selector with snippets. - VInsertSelector *prepareSnippetSelector(QWidget *p_parent = nullptr); - - // Called once read or edit mode is ready. - void tabIsReady(TabReady p_mode); - - // Check if there exists backup file from previous session. - // Return true if we could continue. - bool checkPreviousBackupFile(); - - // updateStatus() with only cursor position information. - void updateCursorStatus(); - - void textToHtmlViaWebView(const QString &p_text, int p_id, int p_timeStamp); - - void htmlToTextViaWebView(const QString &p_html, int p_id, int p_timeStamp); - - bool executeVimCommandInWebView(const QString &p_cmd); - - // Update web view by current content. - void updateWebView(); - - void setCurrentMode(Mode p_mode); - - bool previewExpanded() const; - - VMdEditor *m_editor; - VWebView *m_webViewer; - VDocument *m_document; - MarkdownConverterType m_mdConType; - - // Whether heading sequence is enabled. - bool m_enableHeadingSequence; - - QSplitter *m_splitter; - - // Timer to write backup file when content has been changed. - QTimer *m_backupTimer; - - QTimer *m_livePreviewTimer; - - bool m_backupFileChecked; - - // Used to scroll to the header of edit mode in read mode. - VHeaderPointer m_headerFromEditMode; - - VVim::SearchItem m_lastSearchItem; - - Mode m_mode; - - QSharedPointer m_readWebViewState; - QSharedPointer m_previewWebViewState; - - VLivePreviewHelper *m_livePreviewHelper; - VMathJaxInplacePreviewHelper *m_mathjaxPreviewHelper; - - int m_documentID; - - VGithubImageHosting *vGithubImageHosting; - VGiteeImageHosting *vGiteeImageHosting; - VWechatImageHosting *vWechatImageHosting; - VTencentImageHosting * vTencentImageHosting; -}; - -inline VMdEditor *VMdTab::getEditor() -{ - if (m_editor) { - return m_editor; - } else { - setupMarkdownEditor(); - return m_editor; - } -} - -inline VMdEditor *VMdTab::getEditor() const -{ - return m_editor; -} - -#endif // VMDTAB_H diff --git a/src/vmetawordlineedit.cpp b/src/vmetawordlineedit.cpp deleted file mode 100644 index 5d400469..00000000 --- a/src/vmetawordlineedit.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "vmetawordlineedit.h" - -#include -#include - -#include "utils/vmetawordmanager.h" - -extern VMetaWordManager *g_mwMgr; - - -VMetaWordLineEdit::VMetaWordLineEdit(QWidget *p_parent) - : VLineEdit(p_parent) -{ - init(); -} - -VMetaWordLineEdit::VMetaWordLineEdit(const QString &p_contents, QWidget *p_parent) - : VLineEdit(p_contents, p_parent) -{ - init(); -} - -void VMetaWordLineEdit::handleTextChanged(const QString &p_text) -{ - m_evaluatedText = g_mwMgr->evaluate(p_text); - - if (m_evaluatedText == p_text) { - return; - } - - // Display tooltip at bottom-left. - QPoint pos = mapToGlobal(QPoint(0, height())); - QToolTip::showText(pos, m_evaluatedText, this); -} - -void VMetaWordLineEdit::init() -{ - m_evaluatedText = g_mwMgr->evaluate(text()); - - connect(this, &VLineEdit::textChanged, - this, &VMetaWordLineEdit::handleTextChanged); -} - -const QString &VMetaWordLineEdit::getEvaluatedText() const -{ - return m_evaluatedText; -} - -QString VMetaWordLineEdit::evaluateText(const QString &p_text) const -{ - return g_mwMgr->evaluate(p_text); -} diff --git a/src/vmetawordlineedit.h b/src/vmetawordlineedit.h deleted file mode 100644 index f192c7fc..00000000 --- a/src/vmetawordlineedit.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef VMETAWORDLINEEDIT_H -#define VMETAWORDLINEEDIT_H - -#include "vlineedit.h" - - -// VLineEdit with meta word support. -class VMetaWordLineEdit : public VLineEdit -{ - Q_OBJECT -public: - explicit VMetaWordLineEdit(QWidget *p_parent = nullptr); - - VMetaWordLineEdit(const QString &p_contents, QWidget *p_parent = Q_NULLPTR); - - // Return the evaluated text. - const QString &getEvaluatedText() const; - - QString evaluateText(const QString &p_text) const; - -private slots: - void handleTextChanged(const QString &p_text); - -private: - void init(); - - // We should keep the evaluated text identical with what's displayed. - QString m_evaluatedText; -}; - -#endif // VMETAWORDLINEEDIT_H diff --git a/src/vnavigationmode.cpp b/src/vnavigationmode.cpp deleted file mode 100644 index 86dca465..00000000 --- a/src/vnavigationmode.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include "vnavigationmode.h" - -#include -#include -#include -#include -#include - -#include "vnote.h" -#include "utils/vutils.h" -#include "vtreewidget.h" - -extern VNote *g_vnote; - -VNavigationMode::VNavigationMode() - : m_isSecondKey(false) -{ -} - -VNavigationMode::~VNavigationMode() -{ -} - -void VNavigationMode::registerNavigation(QChar p_majorKey) -{ - m_majorKey = p_majorKey; - Q_ASSERT(m_keyMap.empty()); - Q_ASSERT(m_naviLabels.empty()); -} - -void VNavigationMode::hideNavigation() -{ - clearNavigation(); -} - -void VNavigationMode::showNavigation(QListWidget *p_widget) -{ - clearNavigation(); - - if (!p_widget->isVisible()) { - return; - } - - // Generate labels for visible items. - auto items = getVisibleItems(p_widget); - for (int i = 0; i < 26 && i < items.size(); ++i) { - QChar key('a' + i); - m_keyMap[key] = items[i]; - - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, p_widget); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str)); - label->show(); - QRect rect = p_widget->visualItemRect(items[i]); - // Display the label at the end to show the file name. - // Fix: take the vertical scrollbar into account. - int extraWidth = label->width() + 2; - QScrollBar *vbar = p_widget->verticalScrollBar(); - if (vbar && vbar->minimum() != vbar->maximum()) { - extraWidth += vbar->width(); - } - - label->move(rect.x() + p_widget->rect().width() - extraWidth, - rect.y()); - - m_naviLabels.append(label); - } -} - -QList VNavigationMode::getVisibleItems(const QListWidget *p_widget) const -{ - QList items; - // The first visible item. - QListWidgetItem *firstItem = p_widget->itemAt(0, 0); - if (!firstItem) { - return items; - } - - QListWidgetItem *lastItem = NULL; - lastItem = p_widget->itemAt(p_widget->viewport()->rect().bottomLeft()); - - int first = p_widget->row(firstItem); - int last = lastItem ? p_widget->row(lastItem) : (p_widget->count() - 1); - - for (int i = first; i <= last; ++i) { - QListWidgetItem *item = p_widget->item(i); - if (!item->isHidden() && item->flags() != Qt::NoItemFlags) { - items.append(item); - } - } - - return items; -} - -QList VNavigationMode::getVisibleItems(const QTreeWidget *p_widget) const -{ - QList items; - - // The first visible item. - QTreeWidgetItem *firstItem = p_widget->itemAt(0, 0); - if (!firstItem) { - return items; - } - - QTreeWidgetItem *lastItem = NULL; - lastItem = p_widget->itemAt(p_widget->viewport()->rect().bottomLeft()); - - QTreeWidgetItem *item = firstItem; - while (item) { - items.append(item); - if (item == lastItem) { - break; - } - - item = VTreeWidget::nextItem(p_widget, item, true); - } - - return items; -} - -bool VNavigationMode::handleKeyNavigation(QListWidget *p_widget, - int p_key, - bool &p_succeed) -{ - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (m_isSecondKey && !keyChar.isNull()) { - m_isSecondKey = false; - p_succeed = true; - auto it = m_keyMap.find(keyChar); - if (it != m_keyMap.end()) { - ret = true; - p_widget->setCurrentItem(static_cast(it.value()), - QItemSelectionModel::ClearAndSelect); - p_widget->setFocus(); - } - } else if (keyChar == m_majorKey) { - // Major key pressed. - // Need second key if m_keyMap is not empty. - if (m_keyMap.isEmpty()) { - p_succeed = true; - } else { - m_isSecondKey = true; - } - - ret = true; - } - - return ret; -} - -void VNavigationMode::showNavigation(QTreeWidget *p_widget) -{ - clearNavigation(); - - if (!p_widget->isVisible()) { - return; - } - - // Generate labels for visible items. - auto items = getVisibleItems(p_widget); - for (int i = 0; i < 26 && i < items.size(); ++i) { - QChar key('a' + i); - m_keyMap[key] = items[i]; - - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, p_widget); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str)); - label->move(p_widget->visualItemRect(items[i]).topLeft()); - label->show(); - m_naviLabels.append(label); - } -} - -void VNavigationMode::clearNavigation() -{ - m_isSecondKey = false; - - m_keyMap.clear(); - for (auto label : m_naviLabels) { - delete label; - } - - m_naviLabels.clear(); -} - -bool VNavigationMode::handleKeyNavigation(QTreeWidget *p_widget, - int p_key, - bool &p_succeed) -{ - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (m_isSecondKey && !keyChar.isNull()) { - m_isSecondKey = false; - p_succeed = true; - auto it = m_keyMap.find(keyChar); - if (it != m_keyMap.end()) { - ret = true; - p_widget->setCurrentItem(static_cast(it.value())); - p_widget->setFocus(); - } - } else if (keyChar == m_majorKey) { - // Major key pressed. - // Need second key if m_keyMap is not empty. - if (m_keyMap.isEmpty()) { - p_succeed = true; - } else { - m_isSecondKey = true; - } - - ret = true; - } - - return ret; -} diff --git a/src/vnavigationmode.h b/src/vnavigationmode.h deleted file mode 100644 index 30f5bcbc..00000000 --- a/src/vnavigationmode.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef VNAVIGATIONMODE_H -#define VNAVIGATIONMODE_H - -#include -#include -#include -#include -#include - -class QLabel; -class QListWidget; -class QListWidgetItem; -class QTreeWidget; -class QTreeWidgetItem; - -// Interface class for Navigation Mode in Captain Mode. -class VNavigationMode -{ -public: - VNavigationMode(); - - virtual ~VNavigationMode(); - - virtual void registerNavigation(QChar p_majorKey); - - virtual void showNavigation() = 0; - - virtual void hideNavigation(); - - // Return true if this object could consume p_key. - // p_succeed indicates whether the keys hit a target successfully. - virtual bool handleKeyNavigation(int p_key, bool &p_succeed) = 0; - -protected: - void clearNavigation(); - - void showNavigation(QListWidget *p_widget); - - void showNavigation(QTreeWidget *p_widget); - - bool handleKeyNavigation(QListWidget *p_widget, - int p_key, - bool &p_succeed); - - bool handleKeyNavigation(QTreeWidget *p_widget, - int p_key, - bool &p_succeed); - - QChar m_majorKey; - - // Map second key to item. - QMap m_keyMap; - - bool m_isSecondKey; - - QVector m_naviLabels; - -private: - QList getVisibleItems(const QListWidget *p_widget) const; - - QList getVisibleItems(const QTreeWidget *p_widget) const; -}; - - -class VNavigationModeListWidgetWrapper : public QObject, public VNavigationMode -{ - Q_OBJECT -public: - explicit VNavigationModeListWidgetWrapper(QListWidget *p_widget, QObject *p_parent = nullptr) - : QObject(p_parent), - m_widget(p_widget) - { - } - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE - { - VNavigationMode::showNavigation(m_widget); - } - - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE - { - return VNavigationMode::handleKeyNavigation(m_widget, - p_key, - p_succeed); - } - -private: - QListWidget *m_widget; -}; -#endif // VNAVIGATIONMODE_H diff --git a/src/vnofocusitemdelegate.cpp b/src/vnofocusitemdelegate.cpp deleted file mode 100644 index 2ea6c008..00000000 --- a/src/vnofocusitemdelegate.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "vnofocusitemdelegate.h" - -VNoFocusItemDelegate::VNoFocusItemDelegate(QWidget *parent) - : QStyledItemDelegate(parent) -{ - -} - -void VNoFocusItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const -{ - QStyleOptionViewItem itemOp(option); - if (itemOp.state & QStyle::State_HasFocus) { - itemOp.state ^= QStyle::State_HasFocus; - } - QStyledItemDelegate::paint(painter, itemOp, index); -} diff --git a/src/vnofocusitemdelegate.h b/src/vnofocusitemdelegate.h deleted file mode 100644 index 794db0ab..00000000 --- a/src/vnofocusitemdelegate.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef VNOFOCUSITEMDELEGATE_H -#define VNOFOCUSITEMDELEGATE_H - -#include - -class VNoFocusItemDelegate : public QStyledItemDelegate -{ - Q_OBJECT -public: - explicit VNoFocusItemDelegate(QWidget *parent = 0); - void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE; -}; - -#endif // VNOFOCUSITEMDELEGATE_H diff --git a/src/vnote.cpp b/src/vnote.cpp deleted file mode 100644 index c96f3656..00000000 --- a/src/vnote.cpp +++ /dev/null @@ -1,389 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vnote.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" -#include "vorphanfile.h" -#include "vnotefile.h" -#include "vpalette.h" - -extern VConfigManager *g_config; - -extern VPalette *g_palette; - -// Meta word manager. -VMetaWordManager *g_mwMgr; - -QString VNote::s_simpleHtmlTemplate; - -QString VNote::s_markdownTemplate; - -QString VNote::s_sloganTemplate = "

    Hi Markdown, I'm VNote

    "; - -const QString VNote::c_hoedownJsFile = ":/resources/hoedown.js"; - -const QString VNote::c_markedJsFile = ":/resources/marked.js"; -const QString VNote::c_markedExtraFile = ":/utils/marked/marked.min.js"; - -const QString VNote::c_markdownitJsFile = ":/resources/markdown-it.js"; -const QString VNote::c_markdownitExtraFile = ":/utils/markdown-it/markdown-it.min.js"; -const QString VNote::c_markdownitAnchorExtraFile = ":/utils/markdown-it/markdown-it-headinganchor.js"; -const QString VNote::c_markdownitTaskListExtraFile = ":/utils/markdown-it/markdown-it-task-lists.min.js"; -const QString VNote::c_markdownitSubExtraFile = ":/utils/markdown-it/markdown-it-sub.min.js"; -const QString VNote::c_markdownitSupExtraFile = ":/utils/markdown-it/markdown-it-sup.min.js"; -const QString VNote::c_markdownitFootnoteExtraFile = ":/utils/markdown-it/markdown-it-footnote.min.js"; -const QString VNote::c_markdownitFrontMatterExtraFile = ":/utils/markdown-it/markdown-it-front-matter.js"; -const QString VNote::c_markdownitImsizeExtraFile = ":/utils/markdown-it/markdown-it-imsize.min.js"; -const QString VNote::c_markdownitEmojiExtraFile = ":/utils/markdown-it/markdown-it-emoji.min.js"; -const QString VNote::c_markdownitTexMathExtraFile = ":/utils/markdown-it/markdown-it-texmath.js"; -const QString VNote::c_markdownitContainerExtraFile = ":/utils/markdown-it/markdown-it-container.min.js"; - -const QString VNote::c_showdownJsFile = ":/resources/showdown.js"; -const QString VNote::c_showdownExtraFile = ":/utils/showdown/showdown.min.js"; -const QString VNote::c_showdownAnchorExtraFile = ":/utils/showdown/showdown-headinganchor.js"; - -const QString VNote::c_turndownJsFile = ":/utils/turndown/turndown.js"; -const QString VNote::c_turndownGfmExtraFile = ":/utils/turndown/turndown-plugin-gfm.js"; - -const QString VNote::c_mermaidApiJsFile = ":/utils/mermaid/mermaid.min.js"; -const QString VNote::c_mermaidForestCssFile = ":/utils/mermaid/mermaid.forest.css"; - -const QString VNote::c_flowchartJsFile = ":/utils/flowchart.js/flowchart.min.js"; -const QString VNote::c_raphaelJsFile = ":/utils/flowchart.js/raphael.min.js"; - -const QString VNote::c_wavedromJsFile = ":/utils/wavedrom/wavedrom.min.js"; -const QString VNote::c_wavedromThemeFile = ":/utils/wavedrom/wavedrom-theme.js"; - -const QString VNote::c_plantUMLJsFile = ":/utils/plantuml/synchro2.js"; -const QString VNote::c_plantUMLZopfliJsFile = ":/utils/plantuml/zopfli.raw.min.js"; - -const QString VNote::c_highlightjsLineNumberExtraFile = ":/utils/highlightjs/highlightjs-line-numbers.min.js"; - -const QString VNote::c_docFileFolder = ":/resources/docs"; - -const QString VNote::c_shortcutsDocFile = "shortcuts.md"; - -const QString VNote::c_markdownGuideDocFile = "markdown_guide.md"; - -VNote::VNote(QObject *parent) - : QObject(parent) -{ - initTemplate(); - - g_config->getNotebooks(m_notebooks, this); - - g_mwMgr = &m_metaWordMgr; -} - -void VNote::initTemplate() -{ - if (s_markdownTemplate.isEmpty()) { - updateSimpletHtmlTemplate(); - - updateTemplate(); - } -} - -void VNote::updateSimpletHtmlTemplate() -{ - const QString c_simpleHtmlTemplatePath(":/resources/simple_template.html"); - - const QString cssHolder("CSS_PLACE_HOLDER"); - - s_simpleHtmlTemplate = VUtils::readFileFromDisk(c_simpleHtmlTemplatePath); - g_palette->fillStyle(s_simpleHtmlTemplate); - - s_simpleHtmlTemplate.replace(cssHolder, g_config->getCssStyleUrl()); -} - -QString VNote::generateHtmlTemplate(const QString &p_renderBg, - const QString &p_renderStyleUrl, - const QString &p_codeBlockStyleUrl, - bool p_isPDF) -{ - const QString c_markdownTemplatePath(":/resources/markdown_template.html"); - - QString cssStyle; - if (!p_renderBg.isEmpty()) { - cssStyle += "body { background-color: " + p_renderBg + " !important; }\n"; - } - - if (g_config->getEnableImageConstraint()) { - // Constain the image width. - cssStyle += "img { max-width: 100% !important; height: auto !important; }\n"; - } - - QString templ = VUtils::readFileFromDisk(c_markdownTemplatePath); - g_palette->fillStyle(templ); - - // Must replace the code block holder first. - templ.replace(HtmlHolder::c_commonCssHolder, g_config->getCommonCssUrl()); - templ.replace(HtmlHolder::c_codeBlockCssHolder, p_codeBlockStyleUrl); - templ.replace(HtmlHolder::c_cssHolder, p_renderStyleUrl); - - if (p_isPDF) { - // Shoudl not display scrollbar in PDF. - cssStyle += "pre { white-space: pre-wrap !important; " - "word-break: break-all !important; }\n" - "pre code { white-space: pre-wrap !important; " - "word-break: break-all !important; }\n" - "code { word-break: break-all !important; }\n" - "div.flowchart-diagram { overflow: hidden !important; }\n" - "div.mermaid-diagram { overflow: hidden !important; }\n" - "div.plantuml-diagram { overflow: hidden !important; }\n" - "a { word-break: break-all !important; }\n" - "td.hljs-ln-code { white-space: pre-wrap !important; " - "word-break: break-all !important; }\n"; - if (!g_config->getEnableImageConstraint()) { - // Constain the image width by force in PDF, otherwise, the PDF will - // be cut off. - cssStyle += "img { max-width: 100% !important; height: auto !important; }\n"; - } - } - - if (!cssStyle.isEmpty()) { - templ.replace(HtmlHolder::c_globalStyleHolder, cssStyle); - } - - return templ; -} - -QString VNote::generateExportHtmlTemplate(const QString &p_renderBg) -{ - const QString c_exportTemplatePath(":/resources/export/export_template.html"); - - QString cssStyle; - if (!p_renderBg.isEmpty()) { - cssStyle += "body { background-color: " + p_renderBg + " !important; }\n"; - } - - if (g_config->getEnableImageConstraint()) { - // Constain the image width. - cssStyle += "img { max-width: 100% !important; height: auto !important; }\n"; - } - - QString templ = VUtils::readFileFromDisk(c_exportTemplatePath); - g_palette->fillStyle(templ); - - if (!cssStyle.isEmpty()) { - templ.replace(HtmlHolder::c_globalStyleHolder, cssStyle); - } - - return templ; -} - -QString VNote::generateMathJaxPreviewTemplate() -{ - const QString c_templatePath(":/resources/mathjax_preview_template.html"); - QString templ = VUtils::readFileFromDisk(c_templatePath); - g_palette->fillStyle(templ); - - QString cssStyle; - cssStyle += "div.flowchart-diagram { margin: 0px !important; " - " padding: 0px 5px 0px 5px !important; }\n" - "div.mermaid-diagram { margin: 0px !important; " - " padding: 0px 5px 0px 5px !important; }\n"; - - templ.replace(HtmlHolder::c_globalStyleHolder, cssStyle); - - templ.replace(HtmlHolder::c_cssHolder, g_config->getCssStyleUrl()); - - templ.replace(HtmlHolder::c_scaleFactorHolder, QString::number(VUtils::calculateScaleFactor())); - - return templ; -} - -void VNote::updateTemplate() -{ - QString renderBg = g_config->getRenderBackgroundColor(g_config->getCurRenderBackgroundColor()); - - s_markdownTemplate = generateHtmlTemplate(renderBg, - g_config->getCssStyleUrl(), - g_config->getCodeBlockCssStyleUrl(), - false); -} - -const QVector &VNote::getNotebooks() const -{ - return m_notebooks; -} - -QVector &VNote::getNotebooks() -{ - return m_notebooks; -} - -QString VNote::getNavigationLabelStyle(const QString &p_str, bool p_small) const -{ - static int lastLen = -1; - static int pxWidth = 24; - static int pxHeight = 24; - const int fontPt = p_small ? 12 : 15; - - QString fontFamily = getMonospaceFont(); - - if (p_str.size() != lastLen) { - QFont font(fontFamily, fontPt); - font.setBold(true); - QFontMetrics fm(font); - pxWidth = fm.width(p_str); - pxHeight = fm.capHeight() + 5; - lastLen = p_str.size(); - } - - QColor bg(g_palette->color("navigation_label_bg")); - bg.setAlpha(200); - - QString style = QString("background-color: %1;" - "color: %2;" - "font-size: %3pt;" - "font: bold;" - "font-family: %4;" - "border-radius: 3px;" - "min-width: %5px;" - "max-width: %5px;") - .arg(bg.name(QColor::HexArgb)) - .arg(g_palette->color("navigation_label_fg")) - .arg(fontPt) - .arg(fontFamily) - .arg(pxWidth); - - if (p_small) { - style += QString("margin: 0px;" - "padding: 0px;" - "min-height: %1px;" - "max-height: %1px;") - .arg(pxHeight); - } - - return style; -} - -const QString &VNote::getMonospaceFont() -{ - static QString font; - if (font.isNull()) { - QStringList candidates; - candidates << "Consolas" << "Monaco" << "Andale Mono" << "Monospace" << "Courier New"; - QStringList availFamilies = QFontDatabase().families(); - - for (int i = 0; i < candidates.size(); ++i) { - QString family = candidates[i].trimmed().toLower(); - for (int j = 0; j < availFamilies.size(); ++j) { - QString availFamily = availFamilies[j]; - availFamily.remove(QRegExp("\\[.*\\]")); - if (family == availFamily.trimmed().toLower()) { - font = availFamily; - return font; - } - } - } - - // Fallback to current font. - font = QFont().family(); - } - return font; -} - -VOrphanFile *VNote::getOrphanFile(const QString &p_path, bool p_modifiable, bool p_systemFile) -{ - if (p_path.isEmpty()) { - return NULL; - } - - QString path = QDir::cleanPath(p_path); - // See if the file has already been opened before. - for (auto const &file : m_externalFiles) { - if (VUtils::equalPath(QDir::cleanPath(file->fetchPath()), path)) { - Q_ASSERT(file->isModifiable() == p_modifiable); - Q_ASSERT(file->isSystemFile() == p_systemFile); - return file; - } - } - - freeOrphanFiles(); - - // Create a VOrphanFile for path. - VOrphanFile *file = new VOrphanFile(this, path, p_modifiable, p_systemFile); - m_externalFiles.append(file); - return file; -} - -VNoteFile *VNote::getInternalFile(const QString &p_path) -{ - VNoteFile *file = NULL; - for (auto & nb : m_notebooks) { - file = nb->tryLoadFile(p_path); - if (file) { - break; - } - } - - return file; -} - -VFile *VNote::getFile(const QString &p_path, bool p_forceOrphan) -{ - VFile *file = NULL; - if (!p_forceOrphan) { - file = getInternalFile(p_path); - } - - if (!file) { - QFileInfo fi(p_path); - if (fi.isNativePath()) { - file = getOrphanFile(p_path, true, false); - } else { - // File in Qt resource system. - file = getOrphanFile(p_path, false, true); - } - } - - return file; -} - -VDirectory *VNote::getInternalDirectory(const QString &p_path) -{ - VDirectory *dir = NULL; - for (auto & nb : m_notebooks) { - dir = nb->tryLoadDirectory(p_path); - if (dir) { - break; - } - } - - return dir; - -} - -VNotebook *VNote::getNotebook(const QString &p_path) -{ - for (auto & nb : m_notebooks) { - if (VUtils::equalPath(nb->getPath(), p_path)) { - return nb; - } - } - - return NULL; -} - -void VNote::freeOrphanFiles() -{ - for (int i = 0; i < m_externalFiles.size();) { - VOrphanFile *file = m_externalFiles[i]; - if (!file->isOpened()) { - qDebug() << "release orphan file" << file; - m_externalFiles.removeAt(i); - delete file; - } else { - ++i; - } - } -} diff --git a/src/vnote.desktop b/src/vnote.desktop deleted file mode 100644 index 9bc683c4..00000000 --- a/src/vnote.desktop +++ /dev/null @@ -1,11 +0,0 @@ -[Desktop Entry] -Type=Application -Version=1.0 -Name=VNote -GenericName=Markdown Note -Comment=Note-taking application for pleasant Markdown -Icon=vnote -Terminal=false -Exec=VNote %F -MimeType=text/markdown; -Categories=Qt;Utility;TextEditor;Office; diff --git a/src/vnote.h b/src/vnote.h deleted file mode 100644 index 333523d0..00000000 --- a/src/vnote.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef VNOTE_H -#define VNOTE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vnotebook.h" -#include "vconstants.h" -#include "utils/vmetawordmanager.h" - -class VOrphanFile; -class VNoteFile; - - -class VNote : public QObject -{ - Q_OBJECT -public: - VNote(QObject *parent = 0); - - const QVector &getNotebooks() const; - QVector &getNotebooks(); - - void initTemplate(); - - static QString s_sloganTemplate; - - static QString s_simpleHtmlTemplate; - - static QString s_markdownTemplate; - - // Hoedown - static const QString c_hoedownJsFile; - - // Marked - static const QString c_markedJsFile; - static const QString c_markedExtraFile; - - // Markdown-it - static const QString c_markdownitJsFile; - static const QString c_markdownitExtraFile; - static const QString c_markdownitAnchorExtraFile; - static const QString c_markdownitTaskListExtraFile; - static const QString c_markdownitSubExtraFile; - static const QString c_markdownitSupExtraFile; - static const QString c_markdownitFootnoteExtraFile; - static const QString c_markdownitFrontMatterExtraFile; - static const QString c_markdownitImsizeExtraFile; - static const QString c_markdownitEmojiExtraFile; - static const QString c_markdownitTexMathExtraFile; - static const QString c_markdownitContainerExtraFile; - - // Showdown - static const QString c_showdownJsFile; - static const QString c_showdownExtraFile; - static const QString c_showdownAnchorExtraFile; - - // Turndown - static const QString c_turndownJsFile; - static const QString c_turndownGfmExtraFile; - - // Mermaid - static const QString c_mermaidApiJsFile; - static const QString c_mermaidForestCssFile; - - // flowchart.js - static const QString c_flowchartJsFile; - static const QString c_raphaelJsFile; - - // WaveDrom - static const QString c_wavedromJsFile; - static const QString c_wavedromThemeFile; - - // PlantUML - static const QString c_plantUMLJsFile; - static const QString c_plantUMLZopfliJsFile; - - // Highlight.js line number plugin - static const QString c_highlightjsLineNumberExtraFile; - - static const QString c_docFileFolder; - - static const QString c_shortcutsDocFile; - - static const QString c_markdownGuideDocFile; - - // Get the label style in Navigation mode. - QString getNavigationLabelStyle(const QString &p_str, bool p_small = false) const; - - // Given the path of a file, first try to open it as note file, - // then try to open it as orphan file. - VFile *getFile(const QString &p_path, bool p_forceOrphan = false); - - // Given the path of a file, try to find it in all notebooks. - // Returns a VNoteFile struct if it is a note in one notebook. - // Otherwise, returns NULL. - VNoteFile *getInternalFile(const QString &p_path); - - // Given the path of a folder, try to find it in all notebooks. - // Returns a VDirectory struct if it is a folder in one notebook. - // Otherwise, returns NULL. - VDirectory *getInternalDirectory(const QString &p_path); - - // Given the path of a file, try to find it in all notebooks. - // Returns a VNotebook struct if it is the root folder of a notebook. - VNotebook *getNotebook(const QString &p_path); - - void freeOrphanFiles(); - - // @p_renderBg: background color, empty to not specify given color. - static QString generateHtmlTemplate(const QString &p_renderBg, - const QString &p_renderStyleUrl, - const QString &p_codeBlockStyleUrl, - bool p_isPDF); - - // @p_renderBg: background color, empty to not specify given color. - static QString generateExportHtmlTemplate(const QString &p_renderBg); - - static QString generateMathJaxPreviewTemplate(); - - static const QString &getMonospaceFont(); - -public slots: - void updateTemplate(); - - void updateSimpletHtmlTemplate(); - -private: - // Given the path of an external file, create a VOrphanFile struct. - VOrphanFile *getOrphanFile(const QString &p_path, - bool p_modifiable, - bool p_systemFile = false); - - // Maintain all the notebooks. Other holder should use QPointer. - QVector m_notebooks; - - VMetaWordManager m_metaWordMgr; - - // Hold all external file: Orphan File. - // Need to clean up periodly. - QList m_externalFiles; -}; - -#endif // VNOTE_H diff --git a/src/vnote.qrc b/src/vnote.qrc deleted file mode 100644 index 61d077e2..00000000 --- a/src/vnote.qrc +++ /dev/null @@ -1,362 +0,0 @@ - - - resources/qwebchannel.js - utils/marked/marked.min.js - utils/highlightjs/highlight.pack.js - resources/vnote.ini - resources/icons/create_note_tb.svg - resources/icons/save_note.svg - resources/icons/edit_note.svg - resources/icons/save_exit.svg - resources/icons/discard_exit.svg - resources/icons/create_note.svg - resources/icons/create_notebook.svg - resources/icons/create_rootdir.svg - resources/icons/delete_dir.svg - resources/icons/delete_note.svg - resources/icons/delete_notebook.svg - resources/icons/note_info.svg - resources/icons/dir_info.svg - resources/icons/notebook_info.svg - resources/icons/expand.svg - resources/icons/split_window.svg - resources/icons/corner_menu.svg - resources/icons/remove_split.svg - resources/icons/corner_tablist.svg - resources/icons/outline.svg - resources/icons/create_rootdir_tb.svg - resources/icons/vnote.svg - resources/icons/vnote.ico - resources/icons/note_info_tb.svg - resources/icons/delete_note_tb.svg - resources/icons/copy.svg - resources/icons/cut.svg - resources/icons/paste.svg - resources/icons/dir_item.svg - resources/icons/notebook_item.svg - resources/icons/vnote.png - resources/icons/insert_image.svg - resources/icons/import_note.svg - resources/icons/editing.svg - resources/icons/reading.svg - resources/icons/locate_note.svg - resources/icons/move_tab_left.svg - resources/icons/move_tab_right.svg - resources/icons/corner_menu_cur.svg - resources/icons/corner_tablist_cur.svg - resources/icons/close.svg - resources/icons/find_replace.svg - resources/icons/search_wrap.svg - resources/icons/settings.svg - resources/markdown_template.html - resources/markdown_template.js - resources/hoedown.js - resources/marked.js - resources/markdown-it.js - utils/markdown-it/markdown-it.min.js - utils/markdown-it/markdown-it-headinganchor.js - utils/markdown-it/markdown-it-task-lists.min.js - resources/icons/close_red.svg - utils/showdown/showdown.min.js - resources/showdown.js - utils/showdown/showdown-headinganchor.js - resources/icons/print.svg - utils/markdown-it/markdown-it-sub.min.js - utils/markdown-it/markdown-it-sup.min.js - utils/markdown-it/markdown-it-footnote.min.js - resources/icons/vnote_update.svg - utils/flowchart.js/flowchart.min.js - utils/flowchart.js/raphael.min.js - resources/icons/bold.svg - resources/icons/italic.svg - resources/icons/strikethrough.svg - resources/icons/inline_code.svg - resources/icons/close_note_tb.svg - resources/icons/editing_modified.svg - utils/highlightjs/highlightjs-line-numbers.min.js - resources/icons/recycle_bin.svg - resources/icons/empty_recycle_bin.svg - resources/icons/attachment.svg - resources/icons/add_attachment.svg - resources/icons/clear_attachment.svg - resources/icons/locate_attachment.svg - resources/icons/delete_attachment.svg - resources/icons/sort.svg - resources/icons/create_subdir.svg - resources/icons/heading_sequence.svg - resources/icons/link.svg - resources/icons/code_block.svg - resources/icons/manage_template.svg - resources/icons/snippets.svg - resources/icons/add_snippet.svg - resources/icons/locate_snippet.svg - resources/icons/delete_snippet.svg - resources/icons/snippet_info.svg - resources/icons/apply_snippet.svg - resources/icons/reading_modified.svg - resources/icons/flash_page.svg - resources/icons/heading.svg - resources/themes/v_pure/arrow_dropdown.svg - resources/themes/v_pure/branch_closed.svg - resources/themes/v_pure/branch_end.svg - resources/themes/v_pure/branch_more.svg - resources/themes/v_pure/branch_open.svg - resources/themes/v_pure/checkbox_checked.svg - resources/themes/v_pure/checkbox_unchecked.svg - resources/themes/v_pure/close.svg - resources/themes/v_pure/close_grey.svg - resources/themes/v_pure/down.svg - resources/themes/v_pure/down_disabled.svg - resources/themes/v_pure/float.svg - resources/themes/v_pure/left.svg - resources/themes/v_pure/left_disabled.svg - resources/themes/v_pure/line.svg - resources/themes/v_pure/radiobutton_checked.svg - resources/themes/v_pure/radiobutton_unchecked.svg - resources/themes/v_pure/right.svg - resources/themes/v_pure/right_disabled.svg - resources/themes/v_pure/up.svg - resources/themes/v_pure/up_disabled.svg - resources/themes/v_pure/v_pure.palette - resources/themes/v_pure/v_pure.qss - resources/themes/v_pure/menu_checkbox.svg - resources/themes/v_pure/menu_radiobutton.svg - resources/themes/v_pure/v_pure.mdhl - resources/themes/v_pure/v_pure.css - resources/themes/v_pure/v_pure_codeblock.css - resources/themes/v_moonlight/arrow_dropdown.svg - resources/themes/v_moonlight/branch_closed.svg - resources/themes/v_moonlight/branch_open.svg - resources/themes/v_moonlight/checkbox_checked.svg - resources/themes/v_moonlight/checkbox_unchecked.svg - resources/themes/v_moonlight/close.svg - resources/themes/v_moonlight/close_grey.svg - resources/themes/v_moonlight/down.svg - resources/themes/v_moonlight/down_disabled.svg - resources/themes/v_moonlight/float.svg - resources/themes/v_moonlight/left.svg - resources/themes/v_moonlight/left_disabled.svg - resources/themes/v_moonlight/menu_checkbox.svg - resources/themes/v_moonlight/menu_radiobutton.svg - resources/themes/v_moonlight/radiobutton_checked.svg - resources/themes/v_moonlight/radiobutton_unchecked.svg - resources/themes/v_moonlight/right.svg - resources/themes/v_moonlight/right_disabled.svg - resources/themes/v_moonlight/up.svg - resources/themes/v_moonlight/up_disabled.svg - resources/themes/v_moonlight/v_moonlight.css - resources/themes/v_moonlight/v_moonlight.mdhl - resources/themes/v_moonlight/v_moonlight.palette - resources/themes/v_moonlight/v_moonlight.qss - resources/themes/v_moonlight/v_moonlight_codeblock.css - resources/simple_template.html - resources/typewriter.css - resources/icons/add_style.svg - resources/icons/add_program.svg - translations/widgets_zh_CN.qm - translations/qdialogbuttonbox_zh_CN.qm - translations/qwebengine_zh_CN.qm - translations/qt_zh_CN.qm - resources/icons/clear_cart.svg - resources/icons/cart.svg - resources/icons/delete_cart_item.svg - resources/icons/fullscreen.svg - resources/icons/menubar.svg - resources/themes/v_pure/v_pure_mermaid.css - resources/themes/v_moonlight/v_moonlight_mermaid.css - resources/themes/v_moonlight/arrow_dropdown_disabled.svg - resources/themes/v_pure/arrow_dropdown_disabled.svg - resources/icons/clear_search.svg - resources/icons/search.svg - resources/icons/search_advanced.svg - resources/icons/search_console.svg - resources/icons/note_item.svg - resources/themes/v_native/arrow_dropdown.svg - resources/themes/v_native/arrow_dropdown_disabled.svg - resources/themes/v_native/close.svg - resources/themes/v_native/close_grey.svg - resources/themes/v_native/float.svg - resources/themes/v_native/v_native.css - resources/themes/v_native/v_native.mdhl - resources/themes/v_native/v_native.palette - resources/themes/v_native/v_native.qss - resources/themes/v_native/v_native_codeblock.css - resources/themes/v_native/v_native_mermaid.css - resources/themes/v_pure/checkbox_checked_disabled.svg - resources/themes/v_pure/checkbox_unchecked_disabled.svg - resources/themes/v_pure/radiobutton_checked_disabled.svg - resources/themes/v_pure/radiobutton_unchecked_disabled.svg - resources/themes/v_moonlight/checkbox_checked_disabled.svg - resources/themes/v_moonlight/checkbox_unchecked_disabled.svg - resources/themes/v_moonlight/radiobutton_checked_disabled.svg - resources/themes/v_moonlight/radiobutton_unchecked_disabled.svg - resources/icons/universal_entry_tb.svg - resources/mathjax_preview.js - resources/mathjax_preview_template.html - utils/dom-to-image/dom-to-image.js - utils/markdown-it/markdown-it-front-matter.js - utils/markdown-it/markdown-it-imsize.min.js - utils/markdown-it/markdown-it-emoji.min.js - resources/icons/notebook.svg - resources/icons/history.svg - resources/icons/clear_history.svg - resources/icons/pin.svg - resources/icons/view.svg - resources/icons/explorer.svg - resources/icons/star.svg - resources/icons/open_location.svg - resources/icons/unstar.svg - resources/icons/explore_root.svg - resources/icons/stay_on_top.svg - resources/themes/v_detorte/arrow_dropdown.svg - resources/themes/v_detorte/arrow_dropdown_disabled.svg - resources/themes/v_detorte/branch_closed.svg - resources/themes/v_detorte/branch_end.svg - resources/themes/v_detorte/branch_more.svg - resources/themes/v_detorte/branch_open.svg - resources/themes/v_detorte/checkbox_checked.svg - resources/themes/v_detorte/checkbox_checked_disabled.svg - resources/themes/v_detorte/checkbox_unchecked.svg - resources/themes/v_detorte/checkbox_unchecked_disabled.svg - resources/themes/v_detorte/close.svg - resources/themes/v_detorte/close_grey.svg - resources/themes/v_detorte/down.svg - resources/themes/v_detorte/down_disabled.svg - resources/themes/v_detorte/float.svg - resources/themes/v_detorte/left.svg - resources/themes/v_detorte/left_disabled.svg - resources/themes/v_detorte/line.svg - resources/themes/v_detorte/menu_checkbox.svg - resources/themes/v_detorte/menu_radiobutton.svg - resources/themes/v_detorte/radiobutton_checked.svg - resources/themes/v_detorte/radiobutton_checked_disabled.svg - resources/themes/v_detorte/radiobutton_unchecked.svg - resources/themes/v_detorte/radiobutton_unchecked_disabled.svg - resources/themes/v_detorte/right.svg - resources/themes/v_detorte/right_disabled.svg - resources/themes/v_detorte/up.svg - resources/themes/v_detorte/up_disabled.svg - resources/themes/v_detorte/v_detorte.css - resources/themes/v_detorte/v_detorte.mdhl - resources/themes/v_detorte/v_detorte.palette - resources/themes/v_detorte/v_detorte.qss - resources/themes/v_detorte/v_detorte_codeblock.css - resources/themes/v_detorte/v_detorte_mermaid.css - resources/icons/tags.svg - resources/icons/tag_explorer.svg - resources/icons/tag.svg - resources/view_image.js - resources/icons/decrease_outline_level.svg - resources/icons/increase_outline_level.svg - utils/markdown-it/markdown-it-texmath.js - resources/icons/up.svg - utils/turndown/turndown.js - utils/turndown/turndown-plugin-gfm.js - resources/common.css - resources/icons/quick_access.svg - resources/common.js - resources/export/export_template.html - resources/export/outline.css - resources/export/outline.js - resources/icons/add.svg - resources/icons/delete.svg - resources/icons/256x256/vnote.png - utils/markdown-it/markdown-it-container.min.js - resources/icons/table.svg - utils/wavedrom/wavedrom.min.js - utils/wavedrom/wavedrom-theme.js - utils/plantuml/synchro2.js - utils/plantuml/zopfli.raw.min.js - utils/clipboard.js/clipboard.min.js - resources/themes/v_simple/arrow_dropdown.svg - resources/themes/v_simple/arrow_dropdown_disabled.svg - resources/themes/v_simple/branch_closed.svg - resources/themes/v_simple/branch_end.svg - resources/themes/v_simple/branch_more.svg - resources/themes/v_simple/branch_open.svg - resources/themes/v_simple/checkbox_checked.svg - resources/themes/v_simple/checkbox_checked_disabled.svg - resources/themes/v_simple/checkbox_unchecked.svg - resources/themes/v_simple/checkbox_unchecked_disabled.svg - resources/themes/v_simple/close.svg - resources/themes/v_simple/close_grey.svg - resources/themes/v_simple/down.svg - resources/themes/v_simple/down_disabled.svg - resources/themes/v_simple/float.svg - resources/themes/v_simple/left.svg - resources/themes/v_simple/left_disabled.svg - resources/themes/v_simple/line.svg - resources/themes/v_simple/menu_checkbox.svg - resources/themes/v_simple/menu_radiobutton.svg - resources/themes/v_simple/radiobutton_checked.svg - resources/themes/v_simple/radiobutton_checked_disabled.svg - resources/themes/v_simple/radiobutton_unchecked.svg - resources/themes/v_simple/radiobutton_unchecked_disabled.svg - resources/themes/v_simple/right.svg - resources/themes/v_simple/right_disabled.svg - resources/themes/v_simple/up.svg - resources/themes/v_simple/up_disabled.svg - resources/themes/v_simple/v_simple.css - resources/themes/v_simple/v_simple.mdhl - resources/themes/v_simple/v_simple.palette - resources/themes/v_simple/v_simple.qss - resources/themes/v_simple/v_simple_codeblock.css - resources/themes/v_simple/v_simple_mermaid.css - resources/themes/v_next/arrow_dropdown.svg - resources/themes/v_next/arrow_dropdown_disabled.svg - resources/themes/v_next/branch_closed.svg - resources/themes/v_next/branch_end.svg - resources/themes/v_next/branch_more.svg - resources/themes/v_next/branch_open.svg - resources/themes/v_next/checkbox_checked.svg - resources/themes/v_next/checkbox_checked_disabled.svg - resources/themes/v_next/checkbox_unchecked.svg - resources/themes/v_next/checkbox_unchecked_disabled.svg - resources/themes/v_next/close.svg - resources/themes/v_next/close_grey.svg - resources/themes/v_next/down.svg - resources/themes/v_next/down_disabled.svg - resources/themes/v_next/float.svg - resources/themes/v_next/left.svg - resources/themes/v_next/left_disabled.svg - resources/themes/v_next/line.svg - resources/themes/v_next/menu_checkbox.svg - resources/themes/v_next/menu_radiobutton.svg - resources/themes/v_next/radiobutton_checked.svg - resources/themes/v_next/radiobutton_checked_disabled.svg - resources/themes/v_next/radiobutton_unchecked.svg - resources/themes/v_next/radiobutton_unchecked_disabled.svg - resources/themes/v_next/right.svg - resources/themes/v_next/right_disabled.svg - resources/themes/v_next/up.svg - resources/themes/v_next/up_disabled.svg - resources/themes/v_next/v_next.css - resources/themes/v_next/v_next.mdhl - resources/themes/v_next/v_next.palette - resources/themes/v_next/v_next.qss - resources/themes/v_next/v_next_codeblock.css - resources/themes/v_next/v_next_mermaid.css - utils/mermaid/mermaid.min.js - resources/docs/en/markdown_guide.md - resources/docs/en/shortcuts.md - resources/docs/en/tips_add_style.md - resources/docs/en/tips_add_theme.md - resources/docs/en/tips_custom_shortcut.md - resources/docs/en/tips_external_program.md - resources/docs/en/welcome.md - resources/docs/ja/markdown_guide.md - resources/docs/ja/shortcuts.md - resources/docs/ja/tips_add_style.md - resources/docs/ja/tips_add_theme.md - resources/docs/ja/tips_custom_shortcut.md - resources/docs/ja/tips_external_program.md - resources/docs/ja/welcome.md - resources/docs/zh_CN/markdown_guide.md - resources/docs/zh_CN/shortcuts.md - resources/docs/zh_CN/tips_add_style.md - resources/docs/zh_CN/tips_add_theme.md - resources/docs/zh_CN/tips_custom_shortcut.md - resources/docs/zh_CN/tips_external_program.md - resources/docs/zh_CN/welcome.md - - diff --git a/src/vnotebook.cpp b/src/vnotebook.cpp deleted file mode 100644 index 1caada89..00000000 --- a/src/vnotebook.cpp +++ /dev/null @@ -1,520 +0,0 @@ -#include "vnotebook.h" -#include -#include -#include -#include - -#include "vdirectory.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" -#include "vnotefile.h" - -extern VConfigManager *g_config; - -VNotebook::VNotebook(const QString &name, const QString &path, QObject *parent) - : QObject(parent), m_name(name), m_valid(false) -{ - setPath(path); - m_recycleBinFolder = g_config->getRecycleBinFolder(); - m_rootDir = new VDirectory(this, - NULL, - VUtils::directoryNameFromPath(m_path), - QDateTime::currentDateTimeUtc()); -} - -VNotebook::~VNotebook() -{ - delete m_rootDir; -} - -void VNotebook::setPath(const QString &p_path) -{ - m_pathInConfig = QDir::cleanPath(p_path); - if (QDir::isAbsolutePath(m_pathInConfig)) { - m_path = m_pathInConfig; - } else { - m_path = QDir::cleanPath(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(m_pathInConfig)); - } -} - -bool VNotebook::readConfigNotebook() -{ - QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path); - if (configJson.isEmpty()) { - qWarning() << "fail to read notebook configuration" << m_path; - m_valid = false; - return false; - } - - // [image_folder] section. - auto it = configJson.find(DirConfig::c_imageFolder); - if (it != configJson.end()) { - m_imageFolder = it.value().toString(); - } - - // [recycle_bin_folder] section. - it = configJson.find(DirConfig::c_recycleBinFolder); - if (it != configJson.end()) { - m_recycleBinFolder = it.value().toString(); - } - - // [tags] section. - QJsonArray tagsJson = configJson[DirConfig::c_tags].toArray(); - for (int i = 0; i < tagsJson.size(); ++i) { - m_tags.append(tagsJson[i].toString()); - } - - // [attachment_folder] section. - // SHOULD be processed at last. - it = configJson.find(DirConfig::c_attachmentFolder); - if (it != configJson.end()) { - m_attachmentFolder = it.value().toString(); - } - - // We do not allow empty attachment folder. - if (m_attachmentFolder.isEmpty()) { - m_attachmentFolder = g_config->getAttachmentFolder(); - Q_ASSERT(!m_attachmentFolder.isEmpty()); - writeConfigNotebook(); - } - - m_valid = true; - return true; -} - -QJsonObject VNotebook::toConfigJsonNotebook() const -{ - QJsonObject json; - - // [image_folder] section. - json[DirConfig::c_imageFolder] = m_imageFolder; - - // [attachment_folder] section. - json[DirConfig::c_attachmentFolder] = m_attachmentFolder; - - // [recycle_bin_folder] section. - json[DirConfig::c_recycleBinFolder] = m_recycleBinFolder; - - // [tags] section. - QJsonArray tags; - for (auto const & tag : m_tags) { - tags.append(tag); - } - - json[DirConfig::c_tags] = tags; - - return json; -} - -QJsonObject VNotebook::toConfigJson() const -{ - QJsonObject json = m_rootDir->toConfigJson(); - QJsonObject nbJson = toConfigJsonNotebook(); - - // Merge nbJson to json. - for (auto it = nbJson.begin(); it != nbJson.end(); ++it) { - V_ASSERT(!json.contains(it.key())); - json[it.key()] = it.value(); - } - - return json; -} - -bool VNotebook::writeToConfig() const -{ - return VConfigManager::writeDirectoryConfig(m_path, toConfigJson()); -} - -bool VNotebook::writeConfigNotebook() const -{ - QJsonObject nbJson = toConfigJsonNotebook(); - - QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path); - if (configJson.isEmpty()) { - qWarning() << "fail to read notebook configuration" << m_path; - return false; - } - - for (auto it = nbJson.begin(); it != nbJson.end(); ++it) { - configJson[it.key()] = it.value(); - } - - return VConfigManager::writeDirectoryConfig(m_path, configJson); -} - -void VNotebook::close() -{ - m_rootDir->close(); -} - -bool VNotebook::open() -{ - if (!m_valid) { - return false; - } - - QString recycleBinPath = getRecycleBinFolderPath(); - if (!QFileInfo::exists(recycleBinPath)) { - QDir dir(m_path); - if (!dir.mkpath(recycleBinPath)) { - qWarning() << "fail to create recycle bin folder" << recycleBinPath - << "for notebook" << m_name; - return false; - } - } - - return m_rootDir->open(); -} - -VNotebook *VNotebook::createNotebook(const QString &p_name, - const QString &p_path, - bool p_import, - const QString &p_imageFolder, - const QString &p_attachmentFolder, - QObject *p_parent) -{ - VNotebook *nb = new VNotebook(p_name, p_path, p_parent); - - // If @p_imageFolder is empty, it will report global configured folder as - // its image folder. - nb->setImageFolder(p_imageFolder); - - // If @p_attachmentFolder is empty, use global configured folder. - QString attachmentFolder = p_attachmentFolder; - if (attachmentFolder.isEmpty()) { - attachmentFolder = g_config->getAttachmentFolder(); - } - - nb->setAttachmentFolder(attachmentFolder); - - // Check if there alread exists a config file. - if (p_import && VConfigManager::directoryConfigExist(nb->getPath())) { - qDebug() << "import existing notebook"; - nb->readConfigNotebook(); - return nb; - } - - VUtils::makePath(nb->getPath()); - - if (!nb->writeToConfig()) { - delete nb; - return NULL; - } else { - nb->m_valid = true; - } - - return nb; -} - -bool VNotebook::deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles) -{ - bool ret = true; - - if (!p_notebook) { - return true; - } - - if (p_deleteFiles) { - if (!p_notebook->open()) { - qWarning() << "fail to open notebook" << p_notebook->getName() - << "to delete"; - ret = false; - goto exit; - } - - // Delete sub directories. - VDirectory *rootDir = p_notebook->getRootDir(); - QVector subdirs = rootDir->getSubDirs(); - for (auto dir : subdirs) { - // Skip recycle bin. - VDirectory::deleteDirectory(dir, true); - } - - // Delete the recycle bin. - QDir recycleDir(p_notebook->getRecycleBinFolderPath()); - if (!recycleDir.removeRecursively()) { - qWarning() << "fail to delete notebook recycle bin folder" - << p_notebook->getRecycleBinFolderPath(); - ret = false; - } - - // Delete the config file. - if (!VConfigManager::deleteDirectoryConfig(p_notebook->getPath())) { - ret = false; - goto exit; - } - - // If it is now an empty directory, delete it. - QDir dir(p_notebook->getPath()); - dir.cdUp(); - if (!dir.rmdir(rootDir->getName())) { - qWarning() << "fail to delete notebook root folder" << rootDir->getName(); - ret = false; - } - } - -exit: - p_notebook->close(); - delete p_notebook; - - return ret; -} - -void VNotebook::rename(const QString &p_name) -{ - if (p_name == m_name || p_name.isEmpty()) { - return; - } - - m_name = p_name; -} - -bool VNotebook::containsFile(const VFile *p_file) const -{ - return m_rootDir->containsFile(p_file); -} - -VNoteFile *VNotebook::tryLoadFile(const QString &p_path) -{ - QFileInfo fi(p_path); - Q_ASSERT(fi.isAbsolute()); - if (!fi.exists()) { - return NULL; - } - - QStringList filePath; - if (VUtils::splitPathInBasePath(m_path, p_path, filePath)) { - if (filePath.isEmpty()) { - return NULL; - } - - bool opened = isOpened(); - if (!open()) { - return NULL; - } - - VNoteFile *file = m_rootDir->tryLoadFile(filePath); - - if (!file && !opened) { - close(); - } - - return file; - } - - return NULL; -} - -VDirectory *VNotebook::tryLoadDirectory(const QString &p_path) -{ - QFileInfo fi(p_path); - Q_ASSERT(fi.isAbsolute()); - if (!fi.exists()) { - return NULL; - } - - QStringList filePath; - if (VUtils::splitPathInBasePath(m_path, p_path, filePath)) { - if (filePath.isEmpty()) { - return NULL; - } - - bool opened = isOpened(); - if (!open()) { - return NULL; - } - - VDirectory *dir = m_rootDir->tryLoadDirectory(filePath); - - if (!dir && !opened) { - close(); - } - - return dir; - } - - return NULL; -} - -const QString &VNotebook::getImageFolder() const -{ - if (m_imageFolder.isEmpty()) { - return g_config->getImageFolder(); - } else { - return m_imageFolder; - } -} - -void VNotebook::setImageFolder(const QString &p_imageFolder) -{ - m_imageFolder = p_imageFolder; -} - -const QString &VNotebook::getImageFolderConfig() const -{ - return m_imageFolder; -} - -const QString &VNotebook::getAttachmentFolder() const -{ - return m_attachmentFolder; -} - -void VNotebook::setAttachmentFolder(const QString &p_attachmentFolder) -{ - m_attachmentFolder = p_attachmentFolder; -} - -bool VNotebook::isOpened() const -{ - return m_rootDir->isOpened(); -} - -QDateTime VNotebook::getCreatedTimeUtc() -{ - if (!isOpened()) { - if (!open()) { - return QDateTime(); - } - } - - return m_rootDir->getCreatedTimeUtc(); -} - -QString VNotebook::getRecycleBinFolderPath() const -{ - QFileInfo fi(m_recycleBinFolder); - if (fi.isAbsolute()) { - return m_recycleBinFolder; - } else { - return QDir(m_path).filePath(m_recycleBinFolder); - } -} - -QList VNotebook::collectFiles() -{ - QList files; - - bool opened = isOpened(); - if (!opened && !open()) { - qWarning() << "fail to open notebook %1" << m_path; - return files; - } - - files = m_rootDir->collectFiles(); - - if (!opened) { - close(); - } - - return files; -} - -void VNotebook::updatePath(const QString &p_path) -{ - Q_ASSERT(!isOpened()); - m_valid = false; - setPath(p_path); - delete m_rootDir; - m_rootDir = new VDirectory(this, - NULL, - VUtils::directoryNameFromPath(m_path), - QDateTime::currentDateTimeUtc()); - - readConfigNotebook(); -} - -bool VNotebook::addTag(const QString &p_tag) -{ - Q_ASSERT(isOpened()); - - if (p_tag.isEmpty() || hasTag(p_tag)) { - return false; - } - - m_tags.append(p_tag); - if (!writeConfigNotebook()) { - qWarning() << "fail to update config of notebook" << m_name - << "in directory" << m_path; - m_tags.removeAll(p_tag); - return false; - } - - return true; -} - -bool VNotebook::addTags(VDirectory *p_dir) -{ - QStringList tags = p_dir->collectTags(); - - for (auto const & tag : tags) { - if (tag.isEmpty() || hasTag(tag)) { - continue; - } - - m_tags.append(tag); - } - - if (!writeConfigNotebook()) { - qWarning() << "fail to update config of notebook" << m_name - << "in directory" << m_path; - return false; - } - - return true; -} - -void VNotebook::removeTag(const QString &p_tag) -{ - if (p_tag.isEmpty() || m_tags.isEmpty()) { - return; - } - - int nr = m_tags.removeAll(p_tag); - if (nr > 0) { - if (!writeConfigNotebook()) { - qWarning() << "fail to update config of notebook" << m_name - << "in directory" << m_path; - } - } -} - -bool VNotebook::buildNotebook(const QString &p_name, - const QString &p_path, - const QString &p_imgFolder, - const QString &p_attachmentFolder, - QString *p_errMsg) -{ - VNotebook *nb = new VNotebook(p_name, p_path); - nb->setImageFolder(p_imgFolder); - - QString attachmentFolder = p_attachmentFolder; - if (p_attachmentFolder.isEmpty()) { - nb->setAttachmentFolder(g_config->getAttachmentFolder()); - } else { - nb->setAttachmentFolder(p_attachmentFolder); - } - - // Process all the folders. - QVector &subdirs = nb->getRootDir()->getSubDirs(); - QDir rootDir(p_path); - QFileInfoList dirList = rootDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot); - for (auto const & sub : dirList) { - VDirectory *dir = VDirectory::buildDirectory(sub.absoluteFilePath(), - nb->getRootDir(), - p_errMsg); - if (dir) { - subdirs.append(dir); - } - } - - if (!nb->writeToConfig()) { - delete nb; - VUtils::addErrMsg(p_errMsg, - tr("Fail to write notebook configuration file.")); - return false; - } - - delete nb; - return true; -} diff --git a/src/vnotebook.h b/src/vnotebook.h deleted file mode 100644 index 5c2ea43a..00000000 --- a/src/vnotebook.h +++ /dev/null @@ -1,206 +0,0 @@ -#ifndef VNOTEBOOK_H -#define VNOTEBOOK_H - -#include -#include -#include -#include - -class VDirectory; -class VFile; -class VNoteFile; - -class VNotebook : public QObject -{ - Q_OBJECT -public: - VNotebook(const QString &name, const QString &path, QObject *parent = 0); - - ~VNotebook(); - - // Open the root directory to load contents - bool open(); - - // Whether this notebook is opened. - bool isOpened() const; - - // Close all the directory and files of this notebook. - // Please make sure all files belonging to this notebook have been closed in the tab. - void close(); - - bool containsFile(const VFile *p_file) const; - - // Try to load the file @p_path. - // Returns the corresponding VNoteFile struct if @p_path is a note inside this notebook. - // Otherwise, returns NULL. - // If notebook is not opened currently, it will open itself and close itself - // if @p_path is not inside this notebook. - VNoteFile *tryLoadFile(const QString &p_path); - - // Try to load the directory @p_path. - // Returns the corresponding VDirectory struct if @p_path is a folder inside this notebook. - // Otherwise, returns NULL. - // If notebook is not opened currently, it will open itself and close itself - // if @p_path is not inside this notebook. - VDirectory *tryLoadDirectory(const QString &p_path); - - const QString &getName() const; - - const QString &getPath() const; - - const QString &getPathInConfig() const; - - void updatePath(const QString &p_path); - - VDirectory *getRootDir() const; - - void rename(const QString &p_name); - - const QStringList &getTags() const; - - bool addTag(const QString &p_tag); - - // Walk through @p_dir recursively to add all tags to notebook. - bool addTags(VDirectory *p_dir); - - void removeTag(const QString &p_tag); - - bool hasTag(const QString &p_tag) const; - - static VNotebook *createNotebook(const QString &p_name, - const QString &p_path, - bool p_import, - const QString &p_imageFolder, - const QString &p_attachmentFolder, - QObject *p_parent = 0); - - static bool deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles); - - // Get the image folder for this notebook to use (not exactly the same as - // m_imageFolder if it is empty). - const QString &getImageFolder() const; - - // Return m_imageFolder. - const QString &getImageFolderConfig() const; - - // Different from image folder. We could not change the attachment folder - // of a notebook once it has been created. - // Get the attachment folder for this notebook to use. - const QString &getAttachmentFolder() const; - - // Return m_recycleBinFolder. - const QString &getRecycleBinFolder() const; - - // Get the recycle folder path for this notebook to use. - QString getRecycleBinFolderPath() const; - - void setImageFolder(const QString &p_imageFolder); - - void setAttachmentFolder(const QString &p_attachmentFolder); - - // Read configurations (only notebook part) directly from root directory config file. - bool readConfigNotebook(); - - // Write configurations only related to notebook to root directory config file. - bool writeConfigNotebook() const; - - // Return only the info of notebook part in json. - QJsonObject toConfigJsonNotebook() const; - - // Need to check if this notebook has been opened. - QDateTime getCreatedTimeUtc(); - - bool isValid() const; - - QList collectFiles(); - - // Create configuration files recursively to build a notebook based on - // a external directory. - static bool buildNotebook(const QString &p_name, - const QString &p_path, - const QString &p_imgFolder, - const QString &p_attachmentFolder, - QString *p_errMsg = NULL); - -private: - // Serialize current instance to json. - QJsonObject toConfigJson() const; - - // Write current instance to config file. - bool writeToConfig() const; - - void setPath(const QString &p_path); - - QString m_name; - - QString m_path; - - // Path in vnote.ini. - // May be relative path to VNote's executable. - QString m_pathInConfig; - - // Folder name to store images. - // If not empty, VNote will store images in this folder within the same directory of the note. - // Otherwise, VNote will use the global configured folder. - QString m_imageFolder; - - // Folder name to store attachments. - // Should not be empty and changed once a notebook is created. - QString m_attachmentFolder; - - // Folder name to store deleted files. - // Could be relative or absolute. - QString m_recycleBinFolder; - - // List of all the tags of notes. - // Used for index and auto-completion. - QStringList m_tags; - - // Parent is NULL for root directory - VDirectory *m_rootDir; - - // Whether this notebook is valid. - // Will set to true after readConfigNotebook(). - bool m_valid; -}; - -inline VDirectory *VNotebook::getRootDir() const -{ - return m_rootDir; -} - -inline const QString &VNotebook::getRecycleBinFolder() const -{ - return m_recycleBinFolder; -} - -inline bool VNotebook::isValid() const -{ - return m_valid; -} - -inline const QString &VNotebook::getPath() const -{ - return m_path; -} - -inline const QString &VNotebook::getPathInConfig() const -{ - return m_pathInConfig; -} - -inline const QString &VNotebook::getName() const -{ - return m_name; -} - -inline bool VNotebook::hasTag(const QString &p_tag) const -{ - return m_tags.contains(p_tag); -} - -inline const QStringList &VNotebook::getTags() const -{ - return m_tags; -} -#endif // VNOTEBOOK_H diff --git a/src/vnotebookselector.cpp b/src/vnotebookselector.cpp deleted file mode 100644 index 41d67834..00000000 --- a/src/vnotebookselector.cpp +++ /dev/null @@ -1,748 +0,0 @@ -#include "vnotebookselector.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vnotebook.h" -#include "vconfigmanager.h" -#include "dialog/vnewnotebookdialog.h" -#include "dialog/vnotebookinfodialog.h" -#include "dialog/vdeletenotebookdialog.h" -#include "vnotebook.h" -#include "vdirectory.h" -#include "utils/vutils.h" -#include "vnote.h" -#include "veditarea.h" -#include "vnofocusitemdelegate.h" -#include "vmainwindow.h" -#include "utils/vimnavigationforwidget.h" -#include "utils/viconutils.h" -#include "dialog/vsortdialog.h" - -extern VConfigManager *g_config; - -extern VNote *g_vnote; - -extern VMainWindow *g_mainWin; - -VNotebookSelector::VNotebookSelector(QWidget *p_parent) - : QComboBox(p_parent), - VNavigationMode(), - m_notebooks(g_vnote->getNotebooks()), - m_lastValidIndex(-1), - m_muted(false), - m_naviLabel(NULL) -{ - m_listWidget = new QListWidget(this); - m_listWidget->setItemDelegate(new VNoFocusItemDelegate(this)); - m_listWidget->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_listWidget, &QListWidget::customContextMenuRequested, - this, &VNotebookSelector::popupListContextMenuRequested); - - setModel(m_listWidget->model()); - setView(m_listWidget); - - m_listWidget->viewport()->installEventFilter(this); - m_listWidget->installEventFilter(this); - - connect(this, SIGNAL(currentIndexChanged(int)), - this, SLOT(handleCurIndexChanged(int))); -} - -void VNotebookSelector::updateComboBox() -{ - m_muted = true; - - clear(); - - m_listWidget->clear(); - - insertAddNotebookItem(); - - for (int i = 0; i < m_notebooks.size(); ++i) { - addNotebookItem(m_notebooks[i]); - } - - setCurrentIndex(-1); - - m_muted = false; - - if (m_notebooks.isEmpty()) { - g_config->setCurNotebookIndex(-1); - setCurrentIndex(0); - } -} - -void VNotebookSelector::restoreCurrentNotebook() -{ - int index = g_config->getCurNotebookIndex(); - if (index < 0 || index >= m_notebooks.size()) { - index = 0; - } - - const VNotebook *nb = NULL; - if (index < m_notebooks.size()) { - nb = m_notebooks[index]; - } - - if (nb) { - setCurrentItemToNotebook(nb); - } -} - -void VNotebookSelector::setCurrentItemToNotebook(const VNotebook *p_notebook) -{ - setCurrentIndex(itemIndexOfNotebook(p_notebook)); -} - -int VNotebookSelector::itemIndexOfNotebook(const VNotebook *p_notebook) const -{ - if (!p_notebook) { - return -1; - } - - qulonglong ptr = (qulonglong)p_notebook; - int cnt = m_listWidget->count(); - for (int i = 0; i < cnt; ++i) { - QListWidgetItem *item = m_listWidget->item(i); - if (item->data(Qt::UserRole).toULongLong() == ptr) { - return i; - } - } - - return -1; -} - -void VNotebookSelector::insertAddNotebookItem() -{ - QListWidgetItem *item = new QListWidgetItem(); - item->setIcon(VIconUtils::comboBoxIcon(":/resources/icons/create_notebook.svg")); - item->setText(tr("Add Notebook")); - QFont font; - font.setItalic(true); - item->setData(Qt::FontRole, font); - item->setToolTip(tr("Create or import a notebook")); - - m_listWidget->insertItem(0, item); -} - -void VNotebookSelector::handleCurIndexChanged(int p_index) -{ - if (m_muted) { - return; - } - - QString tooltip = tr("View and edit notebooks"); - VNotebook *nb = NULL; - if (p_index > -1) { - nb = getNotebook(p_index); - if (!nb) { - // Add notebook. - setToolTip(tooltip); - - if (m_lastValidIndex != p_index && m_lastValidIndex > -1) { - setCurrentIndex(m_lastValidIndex); - } - - if (!m_notebooks.isEmpty()) { - newNotebook(); - } - - return; - } - } - - m_lastValidIndex = p_index; - - int nbIdx = -1; - if (nb) { - tooltip = nb->getName(); - - nbIdx = m_notebooks.indexOf(nb); - Q_ASSERT(nbIdx > -1); - } - - g_config->setCurNotebookIndex(nbIdx); - - setToolTip(tooltip); - - emit curNotebookChanged(nb); -} - -void VNotebookSelector::update() -{ - updateComboBox(); -} - -bool VNotebookSelector::newNotebook() -{ - QString info(tr("Please type the name of the notebook and " - "choose a folder as the Root Folder of the notebook.")); - info += "\n"; - info += tr("* The root folder should be used EXCLUSIVELY by VNote and " - "it is recommended to be EMPTY."); - info += "\n"; - info += tr("* A previously created notebook could be imported into VNote " - "by choosing its root folder."); - info += "\n"; - info += tr("* When a non-empty folder is chosen, VNote will create a notebook " - "based on the folders and files in it recursively."); - - // Use empty default name and path to let the dialog to auto generate a name - // under the default VNote notebook folder. - VNewNotebookDialog dialog(tr("Add Notebook"), - info, - "", - "", - m_notebooks, - this); - if (dialog.exec() == QDialog::Accepted) { - bool isImport = dialog.isImportExistingNotebook(); - if(dialog.isImportExternalProject()) { - QString msg; - bool ret = VNotebook::buildNotebook(dialog.getNameInput(), - dialog.getPathInput(), - dialog.getImageFolder(), - dialog.getAttachmentFolder(), - &msg); - - QList suffixes = g_config->getDocSuffixes()[(int)DocType::Markdown]; - QString sufs; - for (auto const & suf : suffixes) { - if (sufs.isEmpty()) { - sufs = "*." + suf; - } else { - sufs += ",*." + suf; - } - } - - QString info = ret ? tr("Successfully build notebook recursively (%1).").arg(sufs) - : tr("Fail to build notebook recursively."); - if (!ret || !msg.isEmpty()) { - VUtils::showMessage(ret ? QMessageBox::Information : QMessageBox::Warning, - ret ? tr("Information") : tr("Warning"), - info, - msg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - if (!ret) { - return false; - } - - isImport = true; - } - - createNotebook(dialog.getNameInput(), - dialog.getPathInput(), - isImport, - dialog.getImageFolder(), - dialog.getAttachmentFolder()); - - emit notebookCreated(dialog.getNameInput(), isImport); - return true; - } - - return false; -} - -void VNotebookSelector::createNotebook(const QString &p_name, - const QString &p_path, - bool p_import, - const QString &p_imageFolder, - const QString &p_attachmentFolder) -{ - VNotebook *nb = VNotebook::createNotebook(p_name, - p_path, - p_import, - p_imageFolder, - p_attachmentFolder, - g_vnote); - if (!nb) { - VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Fail to create notebook " - "%2 in %3.") - .arg(g_config->c_dataTextStyle).arg(p_name).arg(p_path), "", - QMessageBox::Ok, QMessageBox::Ok, this); - return; - } - - m_notebooks.append(nb); - g_config->setNotebooks(m_notebooks); - - addNotebookItem(nb); - setCurrentItemToNotebook(nb); -} - -void VNotebookSelector::deleteNotebook() -{ - QList items = m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - - VNotebook *notebook = getNotebook(items[0]); - Q_ASSERT(notebook); - - VDeleteNotebookDialog dialog(tr("Delete Notebook"), notebook, this); - if (dialog.exec() == QDialog::Accepted) { - bool deleteFiles = dialog.getDeleteFiles(); - g_mainWin->getEditArea()->closeFile(notebook, true); - deleteNotebook(notebook, deleteFiles); - } -} - -void VNotebookSelector::deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles) -{ - Q_ASSERT(p_notebook); - - m_notebooks.removeOne(p_notebook); - g_config->setNotebooks(m_notebooks); - - int idx = itemIndexOfNotebook(p_notebook); - QListWidgetItem *item = m_listWidget->takeItem(idx); - Q_ASSERT(item); - delete item; - - QString name(p_notebook->getName()); - QString path(p_notebook->getPath()); - bool ret = VNotebook::deleteNotebook(p_notebook, p_deleteFiles); - if (!ret) { - // Notebook could not be deleted completely. - int cho = VUtils::showMessage(QMessageBox::Information, - tr("Delete Notebook Folder From Disk"), - tr("Fail to delete the root folder of notebook " - "%2 from disk. You may open " - "the folder and check it manually.") - .arg(g_config->c_dataTextStyle).arg(name), - "", - QMessageBox::Open | QMessageBox::Ok, - QMessageBox::Ok, - this); - if (cho == QMessageBox::Open) { - // Open the notebook location. - QUrl url = QUrl::fromLocalFile(path); - QDesktopServices::openUrl(url); - } - } - - if (m_notebooks.isEmpty()) { - m_muted = true; - setCurrentIndex(0); - m_muted = false; - } -} - -void VNotebookSelector::editNotebookInfo() -{ - QList items = m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - - VNotebook *notebook = getNotebook(items[0]); - VNotebookInfoDialog dialog(tr("Notebook Information"), - "", - notebook, - m_notebooks, - this); - if (dialog.exec() == QDialog::Accepted) { - bool updated = false; - bool configUpdated = false; - QString name = dialog.getName(); - if (name != notebook->getName()) { - updated = true; - notebook->rename(name); - g_config->setNotebooks(m_notebooks); - } - - QString imageFolder = dialog.getImageFolder(); - if (imageFolder != notebook->getImageFolderConfig()) { - configUpdated = true; - notebook->setImageFolder(imageFolder); - } - - if (configUpdated) { - updated = true; - notebook->writeConfigNotebook(); - } - - if (updated) { - fillItem(items[0], notebook); - emit notebookUpdated(notebook); - } - } -} - -void VNotebookSelector::addNotebookItem(const VNotebook *p_notebook) -{ - QListWidgetItem *item = new QListWidgetItem(m_listWidget); - fillItem(item, p_notebook); -} - -void VNotebookSelector::fillItem(QListWidgetItem *p_item, - const VNotebook *p_notebook) const -{ - p_item->setText(p_notebook->getName()); - p_item->setToolTip(p_notebook->getName()); - p_item->setIcon(VIconUtils::comboBoxIcon(":/resources/icons/notebook_item.svg")); - p_item->setData(Qt::UserRole, (qulonglong)p_notebook); -} - - -void VNotebookSelector::popupListContextMenuRequested(QPoint p_pos) -{ - QListWidgetItem *item = m_listWidget->itemAt(p_pos); - if (!item) { - return; - } - - const VNotebook *nb = getNotebook(item); - if (!nb) { - return; - } - - m_listWidget->clearSelection(); - item->setSelected(true); - - QMenu menu(this); - menu.setToolTipsVisible(true); - - QAction *deleteNotebookAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_notebook.svg"), - tr("&Delete"), - &menu); - deleteNotebookAct->setToolTip(tr("Delete current notebook")); - connect(deleteNotebookAct, SIGNAL(triggered(bool)), - this, SLOT(deleteNotebook())); - menu.addAction(deleteNotebookAct); - - if (m_notebooks.size() > 1) { - QAction *sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - &menu); - sortAct->setToolTip(tr("Sort notebooks")); - connect(sortAct, SIGNAL(triggered(bool)), - this, SLOT(sortItems())); - menu.addAction(sortAct); - } - - if (nb->isValid()) { - menu.addSeparator(); - - QAction *recycleBinAct = new QAction(VIconUtils::menuIcon(":/resources/icons/recycle_bin.svg"), - tr("&Recycle Bin"), - &menu); - recycleBinAct->setToolTip(tr("Open the recycle bin of this notebook")); - connect(recycleBinAct, &QAction::triggered, - this, [this]() { - QList items = this->m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - VNotebook *notebook = getNotebook(items[0]); - QUrl url = QUrl::fromLocalFile(notebook->getRecycleBinFolderPath()); - QDesktopServices::openUrl(url); - }); - - menu.addAction(recycleBinAct); - - QAction *emptyRecycleBinAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/empty_recycle_bin.svg"), - tr("&Empty Recycle Bin"), - &menu); - emptyRecycleBinAct->setToolTip(tr("Empty the recycle bin of this notebook")); - connect(emptyRecycleBinAct, &QAction::triggered, - this, [this]() { - QList items = this->m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - VNotebook *notebook = getNotebook(items[0]); - QString binPath = notebook->getRecycleBinFolderPath(); - - int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Are you sure to empty recycle bin of notebook " - "%2?") - .arg(g_config->c_dataTextStyle) - .arg(notebook->getName()), - tr("WARNING: " - "VNote will delete all the files in directory " - "%3." - "
    It may be UNRECOVERABLE!") - .arg(g_config->c_warningTextStyle) - .arg(g_config->c_dataTextStyle) - .arg(binPath), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - this, - MessageBoxType::Danger); - if (ret == QMessageBox::Ok) { - QString info; - if (VUtils::emptyDirectory(notebook, binPath, true)) { - info = tr("Successfully emptied recycle bin of notebook " - "%2!") - .arg(g_config->c_dataTextStyle) - .arg(notebook->getName()); - } else { - info = tr("Fail to empty recycle bin of notebook " - "%2!") - .arg(g_config->c_dataTextStyle) - .arg(notebook->getName()); - } - - VUtils::showMessage(QMessageBox::Information, - tr("Information"), - info, - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - }); - menu.addAction(emptyRecycleBinAct); - } - - menu.addSeparator(); - - QAction *openLocationAct = new QAction(VIconUtils::menuIcon(":/resources/icons/open_location.svg"), - tr("&Open Notebook Location"), - &menu); - openLocationAct->setToolTip(tr("Explore the root folder of this notebook in operating system")); - connect(openLocationAct, &QAction::triggered, - this, [this]() { - QList items = this->m_listWidget->selectedItems(); - if (items.isEmpty()) { - return; - } - - Q_ASSERT(items.size() == 1); - VNotebook *notebook = getNotebook(items[0]); - QUrl url = QUrl::fromLocalFile(notebook->getPath()); - QDesktopServices::openUrl(url); - }); - menu.addAction(openLocationAct); - - if (nb->isValid()) { - QAction *notebookInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/notebook_info.svg"), - tr("&Info (Rename)"), - &menu); - notebookInfoAct->setToolTip(tr("View and edit current notebook's information")); - connect(notebookInfoAct, SIGNAL(triggered(bool)), - this, SLOT(editNotebookInfo())); - menu.addAction(notebookInfoAct); - } - - menu.exec(m_listWidget->mapToGlobal(p_pos)); -} - -bool VNotebookSelector::eventFilter(QObject *watched, QEvent *event) -{ - QEvent::Type type = event->type(); - if (type == QEvent::KeyPress && watched == m_listWidget) { - if (handlePopupKeyPress(static_cast(event))) { - return true; - } - } else if (type == QEvent::MouseButtonRelease) { - if (static_cast(event)->button() == Qt::RightButton) { - return true; - } - } - - return QComboBox::eventFilter(watched, event); -} - -bool VNotebookSelector::locateNotebook(const VNotebook *p_notebook) -{ - bool ret = false; - int index = itemIndexOfNotebook(p_notebook); - if (index > -1) { - setCurrentIndex(index); - ret = true; - } - - return ret; -} - -void VNotebookSelector::showPopup() -{ - if (m_notebooks.isEmpty()) { - // No normal notebook items. Just add notebook. - newNotebook(); - return; - } - - resizeListWidgetToContent(); - QComboBox::showPopup(); -} - -void VNotebookSelector::resizeListWidgetToContent() -{ - static QRect screenRect = QGuiApplication::primaryScreen()->geometry(); - static int maxMinWidth = screenRect.width() < 400 ? screenRect.width() : screenRect.width() / 2; - static int maxMinHeight = screenRect.height() < 400 ? screenRect.height() : screenRect.height() / 2; - - int minWidth = 0; - int minHeight = 0; - if (m_listWidget->count() > 0) { - // Width - minWidth = m_listWidget->sizeHintForColumn(0); - minWidth = qMin(minWidth, maxMinWidth); - - // Height - minHeight = m_listWidget->sizeHintForRow(0) * m_listWidget->count() + 10; - minHeight = qMin(minHeight, maxMinHeight); - } - - m_listWidget->setMinimumSize(minWidth, minHeight); -} - -void VNotebookSelector::registerNavigation(QChar p_majorKey) -{ - Q_ASSERT(!m_naviLabel); - m_majorKey = p_majorKey; -} - -void VNotebookSelector::showNavigation() -{ - if (!isVisible()) { - return; - } - - V_ASSERT(!m_naviLabel); - m_naviLabel = new QLabel(m_majorKey, this); - m_naviLabel->setStyleSheet(g_vnote->getNavigationLabelStyle(m_majorKey)); - m_naviLabel->show(); - m_naviLabel->move(rect().topRight() - QPoint(m_naviLabel->width() + 2, 2)); -} - -void VNotebookSelector::hideNavigation() -{ - if (m_naviLabel) { - delete m_naviLabel; - m_naviLabel = NULL; - } -} - -bool VNotebookSelector::handleKeyNavigation(int p_key, bool &p_succeed) -{ - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (keyChar == m_majorKey) { - // Hit. - p_succeed = true; - ret = true; - setFocus(); - if (m_naviLabel) { - showPopup(); - } - } - - return ret; -} - -bool VNotebookSelector::handlePopupKeyPress(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(m_listWidget, - p_event)) { - return true; - } - - return false; -} - -VNotebook *VNotebookSelector::getNotebook(int p_itemIdx) const -{ - VNotebook *nb = NULL; - QListWidgetItem *item = m_listWidget->item(p_itemIdx); - if (item) { - nb = (VNotebook *)item->data(Qt::UserRole).toULongLong(); - } - - return nb; -} - -VNotebook *VNotebookSelector::getNotebook(const QListWidgetItem *p_item) const -{ - if (p_item) { - return (VNotebook *)p_item->data(Qt::UserRole).toULongLong(); - } - - return NULL; -} - -VNotebook *VNotebookSelector::currentNotebook() const -{ - return getNotebook(currentIndex()); -} - -void VNotebookSelector::sortItems() -{ - if (m_notebooks.size() < 2) { - return; - } - - VSortDialog dialog(tr("Sort Notebooks"), - tr("Sort notebooks in the configuration file."), - this); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(1); - QStringList headers; - headers << tr("Name"); - tree->setHeaderLabels(headers); - for (int i = 0; i < m_notebooks.size(); ++i) { - QStringList cols; - cols << m_notebooks[i]->getName(); - QTreeWidgetItem *item = new QTreeWidgetItem(tree, cols); - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == m_notebooks.size()); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - // Sort m_notebooks. - auto ori = m_notebooks; - auto curNotebook = currentNotebook(); - int curNotebookIdx = -1; - for (int i = 0; i < sortedIdx.size(); ++i) { - m_notebooks[i] = ori[sortedIdx[i]]; - if (m_notebooks[i] == curNotebook) { - curNotebookIdx = i; - } - } - - Q_ASSERT(ori.size() == m_notebooks.size()); - Q_ASSERT(curNotebookIdx != -1); - - g_config->setNotebooks(m_notebooks); - g_config->setCurNotebookIndex(curNotebookIdx); - - update(); - - setCurrentItemToNotebook(m_notebooks[curNotebookIdx]); - } -} diff --git a/src/vnotebookselector.h b/src/vnotebookselector.h deleted file mode 100644 index 71998970..00000000 --- a/src/vnotebookselector.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef VNOTEBOOKSELECTOR_H -#define VNOTEBOOKSELECTOR_H - -#include -#include -#include -#include -#include "vnavigationmode.h" - -class VNotebook; -class QListWidget; -class QListWidgetItem; -class QLabel; - -class VNotebookSelector : public QComboBox, public VNavigationMode -{ - Q_OBJECT -public: - explicit VNotebookSelector(QWidget *p_parent = 0); - - // Update Combox from m_notebooks. - void update(); - - // Select notebook @p_notebook. - bool locateNotebook(const VNotebook *p_notebook); - - // Add notebook on popup if no notebooks currently. - void showPopup() Q_DECL_OVERRIDE; - - VNotebook *currentNotebook() const; - - void restoreCurrentNotebook(); - - // Implementations for VNavigationMode. - void registerNavigation(QChar p_majorKey) Q_DECL_OVERRIDE; - void showNavigation() Q_DECL_OVERRIDE; - void hideNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -signals: - void curNotebookChanged(VNotebook *p_notebook); - - // Info of current notebook was changed. - void notebookUpdated(const VNotebook *p_notebook); - - // Emit after creating a new notebook. - void notebookCreated(const QString &p_name, bool p_import); - -public slots: - // Popup a dialog to prompt user to create a notebook. - bool newNotebook(); - -protected: - bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; - -private slots: - // Act to currentIndexChanged() signal if m_muted is false. - void handleCurIndexChanged(int p_index); - - void popupListContextMenuRequested(QPoint p_pos); - - // Delete currently selected notebook. - void deleteNotebook(); - - // View and edit notebook information of selected notebook. - void editNotebookInfo(); - - // Sort notebooks. - void sortItems(); - -private: - // Update Combox from m_notebooks. - void updateComboBox(); - - // Return the item index of @p_notebook. - int itemIndexOfNotebook(const VNotebook *p_notebook) const; - - // If @p_import is true, we will use the existing config file. - // If @p_imageFolder is empty, we will use the global one. - // If @p_attachmentFolder is empty, we will use the global one. - void createNotebook(const QString &p_name, - const QString &p_path, - bool p_import, - const QString &p_imageFolder, - const QString &p_attachmentFolder); - - void deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles); - - // Add an item corresponding to @p_notebook to combo box. - void addNotebookItem(const VNotebook *p_notebook); - - void fillItem(QListWidgetItem *p_item, const VNotebook *p_notebook) const; - - // Insert "Add Notebook" item to combo box. - void insertAddNotebookItem(); - - // Set current item corresponding to @p_notebook. - void setCurrentItemToNotebook(const VNotebook *p_notebook); - - // Get VNotebook from @p_itemIdx, the index of m_listWidget. - VNotebook *getNotebook(int p_itemIdx) const; - - VNotebook *getNotebook(const QListWidgetItem *p_item) const; - - void resizeListWidgetToContent(); - - bool handlePopupKeyPress(QKeyEvent *p_event); - - QVector &m_notebooks; - - QListWidget *m_listWidget; - - // Used to restore after clicking Add Notebook item. - int m_lastValidIndex; - - // Whether it is muted from currentIndexChanged(). - bool m_muted; - - QLabel *m_naviLabel; -}; - -#endif // VNOTEBOOKSELECTOR_H diff --git a/src/vnotefile.cpp b/src/vnotefile.cpp deleted file mode 100644 index f80bf4bc..00000000 --- a/src/vnotefile.cpp +++ /dev/null @@ -1,701 +0,0 @@ -#include "vnotefile.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "vdirectory.h" - -VNoteFile::VNoteFile(VDirectory *p_directory, - const QString &p_name, - FileType p_type, - bool p_modifiable, - QDateTime p_createdTimeUtc, - QDateTime p_modifiedTimeUtc) - : VFile(p_directory, p_name, p_type, p_modifiable, p_createdTimeUtc, p_modifiedTimeUtc) -{ -} - -QString VNoteFile::fetchPath() const -{ - return QDir(getDirectory()->fetchPath()).filePath(m_name); -} - -QString VNoteFile::fetchBasePath() const -{ - return getDirectory()->fetchPath(); -} - -QString VNoteFile::fetchImageFolderPath() const -{ - return QDir(fetchBasePath()).filePath(getNotebook()->getImageFolder()); -} - -bool VNoteFile::useRelativeImageFolder() const -{ - // Always use relative image folder. - return true; -} - -QString VNoteFile::getImageFolderInLink() const -{ - return getNotebook()->getImageFolder(); -} - -void VNoteFile::setName(const QString &p_name) -{ - m_name = p_name; -} - -bool VNoteFile::rename(const QString &p_name) -{ - if (m_name == p_name) { - return true; - } - - QString oldName = m_name; - - VDirectory *dir = getDirectory(); - Q_ASSERT(dir); - - // Rename it in disk. - QDir diskDir(dir->fetchPath()); - if (!diskDir.rename(m_name, p_name)) { - qWarning() << "fail to rename file" << m_name << "to" << p_name << "in disk"; - return false; - } - - m_name = p_name; - - // Update parent directory's config file. - if (!dir->updateFileConfig(this)) { - m_name = oldName; - diskDir.rename(p_name, m_name); - return false; - } - - // Can't not change doc type. - Q_ASSERT(m_docType == DocType::Unknown - || m_docType == VUtils::docTypeFromName(m_name)); - - m_docType = VUtils::docTypeFromName(m_name); - - qDebug() << "file renamed from" << oldName << "to" << m_name; - return true; -} - -VDirectory *VNoteFile::getDirectory() -{ - Q_ASSERT(parent()); - return (VDirectory *)parent(); -} - -const VDirectory *VNoteFile::getDirectory() const -{ - Q_ASSERT(parent()); - return (const VDirectory *)parent(); -} - -VNotebook *VNoteFile::getNotebook() -{ - return getDirectory()->getNotebook(); -} - -const VNotebook *VNoteFile::getNotebook() const -{ - return getDirectory()->getNotebook(); -} - -QString VNoteFile::getNotebookName() const -{ - return getDirectory()->getNotebookName(); -} - -QString VNoteFile::fetchRelativePath() const -{ - return QDir(getDirectory()->fetchRelativePath()).filePath(m_name); -} - -VNoteFile *VNoteFile::fromJson(VDirectory *p_directory, - const QJsonObject &p_json, - FileType p_type, - bool p_modifiable) -{ - VNoteFile *file = new VNoteFile(p_directory, - p_json[DirConfig::c_name].toString(), - p_type, - p_modifiable, - QDateTime::fromString(p_json[DirConfig::c_createdTime].toString(), - Qt::ISODate), - QDateTime::fromString(p_json[DirConfig::c_modifiedTime].toString(), - Qt::ISODate)); - - // Attachment Folder. - file->m_attachmentFolder = p_json[DirConfig::c_attachmentFolder].toString(); - - // Attachments. - QJsonArray attachmentJson = p_json[DirConfig::c_attachments].toArray(); - for (int i = 0; i < attachmentJson.size(); ++i) { - QJsonObject attachmentItem = attachmentJson[i].toObject(); - file->m_attachments.push_back(VAttachment(attachmentItem[DirConfig::c_name].toString())); - } - - // Tags. - QJsonArray tagsJson = p_json[DirConfig::c_tags].toArray(); - for (int i = 0; i < tagsJson.size(); ++i) { - file->m_tags.append(tagsJson[i].toString()); - } - - return file; -} - -QJsonObject VNoteFile::toConfigJson() const -{ - QJsonObject item; - item[DirConfig::c_name] = m_name; - item[DirConfig::c_createdTime] = m_createdTimeUtc.toString(Qt::ISODate); - item[DirConfig::c_modifiedTime] = m_modifiedTimeUtc.toString(Qt::ISODate); - item[DirConfig::c_attachmentFolder] = m_attachmentFolder; - - // Attachments. - QJsonArray attachmentJson; - for (int i = 0; i < m_attachments.size(); ++i) { - const VAttachment &att = m_attachments[i]; - QJsonObject attachmentItem; - attachmentItem[DirConfig::c_name] = att.m_name; - attachmentJson.append(attachmentItem); - } - - item[DirConfig::c_attachments] = attachmentJson; - - // Tags. - QJsonArray tags; - for (auto const & tag : m_tags) { - tags.append(tag); - } - - item[DirConfig::c_tags] = tags; - - return item; -} - -bool VNoteFile::deleteFile(QString *p_errMsg) -{ - Q_ASSERT(!m_opened); - Q_ASSERT(parent()); - - bool ret = true; - - // Delete local images if it is Markdown. - if (m_docType == DocType::Markdown) { - if (!deleteInternalImages()) { - ret = false; - VUtils::addErrMsg(p_errMsg, tr("Fail to delete images of this note.")); - } - } - - // Delete attachments. - if (!deleteAttachments()) { - ret = false; - VUtils::addErrMsg(p_errMsg, tr("Fail to delete attachments of this note.")); - } - - // Delete the file. - QString filePath = fetchPath(); - if (VUtils::deleteFile(getNotebook(), filePath, false)) { - qDebug() << "deleted" << m_name << filePath; - } else { - ret = false; - VUtils::addErrMsg(p_errMsg, tr("Fail to delete the note file.")); - qWarning() << "fail to delete" << m_name << filePath; - } - - return ret; -} - -bool VNoteFile::deleteInternalImages() -{ - Q_ASSERT(parent() && m_docType == DocType::Markdown); - - QVector images = VUtils::fetchImagesFromMarkdownFile(this, - ImageLink::LocalRelativeInternal); - int deleted = 0; - for (int i = 0; i < images.size(); ++i) { - if (VUtils::deleteFile(getNotebook(), images[i].m_path, false)) { - ++deleted; - } - } - - qDebug() << "delete" << deleted << "images for" << m_name << fetchPath(); - - return deleted == images.size(); -} - -bool VNoteFile::addAttachment(const QString &p_file, QString *p_destFile) -{ - if (p_file.isEmpty() || !QFileInfo::exists(p_file)) { - return false; - } - - QString folderPath = fetchAttachmentFolderPath(); - QString name = VUtils::fileNameFromPath(p_file); - Q_ASSERT(!name.isEmpty()); - // For attachments, we do not use complete base name. - // abc.tar.gz should be abc_001.tar.gz instead of abc.tar_001.gz. - name = VUtils::getFileNameWithSequence(folderPath, name, false); - QString destPath = QDir(folderPath).filePath(name); - if (!VUtils::copyFile(p_file, destPath, false)) { - return false; - } - - m_attachments.push_back(VAttachment(name)); - - if (!getDirectory()->updateFileConfig(this)) { - qWarning() << "fail to update config of file" << m_name - << "in directory" << fetchBasePath(); - return false; - } - - if (p_destFile) { - *p_destFile = destPath; - } - - return true; -} - -QString VNoteFile::fetchAttachmentFolderPath() -{ - QString folderPath = QDir(fetchBasePath()).filePath(getNotebook()->getAttachmentFolder()); - if (m_attachmentFolder.isEmpty()) { - m_attachmentFolder = VUtils::getRandomFileName(folderPath); - } - - folderPath = QDir(folderPath).filePath(m_attachmentFolder); - if (!QFileInfo::exists(folderPath)) { - QDir dir; - if (!dir.mkpath(folderPath)) { - qWarning() << "fail to create attachment folder of notebook" << m_name << folderPath; - } - } - - return folderPath; -} - -bool VNoteFile::deleteAttachments(bool p_omitMissing) -{ - if (m_attachments.isEmpty()) { - return true; - } - - QVector attas; - for (int i = 0; i < m_attachments.size(); ++i) { - attas.push_back(m_attachments[i].m_name); - } - - return deleteAttachments(attas, p_omitMissing); -} - -bool VNoteFile::deleteAttachments(const QVector &p_names, - bool p_omitMissing) -{ - if (p_names.isEmpty()) { - return true; - } - - QDir dir(fetchAttachmentFolderPath()); - bool ret = true; - for (int i = 0; i < p_names.size(); ++i) { - int idx = findAttachment(p_names[i]); - if (idx == -1) { - ret = false; - continue; - } - - m_attachments.remove(idx); - - QString filePath = dir.filePath(p_names[i]); - if (p_omitMissing - && !QFileInfo::exists(filePath)) { - // The attachment file does not exist. We skip it to avoid error. - continue; - } - - if (!VUtils::deleteFile(getNotebook(), filePath, false)) { - ret = false; - qWarning() << "fail to delete attachment" << p_names[i] - << "for note" << m_name; - } - } - - // Delete the attachment folder if m_attachments is empty now. - if (m_attachments.isEmpty()) { - dir.cdUp(); - if (!dir.rmdir(m_attachmentFolder)) { - ret = false; - qWarning() << "fail to delete attachment folder" << m_attachmentFolder - << "for note" << m_name; - } - } - - if (!getDirectory()->updateFileConfig(this)) { - ret = false; - qWarning() << "fail to update config of file" << m_name - << "in directory" << fetchBasePath(); - } - - return ret; -} - -int VNoteFile::findAttachment(const QString &p_name, bool p_caseSensitive) -{ - const QString name = p_caseSensitive ? p_name : p_name.toLower(); - for (int i = 0; i < m_attachments.size(); ++i) { - QString attaName = p_caseSensitive ? m_attachments[i].m_name - : m_attachments[i].m_name.toLower(); - if (name == attaName) { - return i; - } - } - - return -1; -} - -int VNoteFile::findAttachmentByPath(const QString &p_file, bool p_caseSensitive) -{ - QFileInfo fi(p_file); - int idx = findAttachment(fi.fileName(), p_caseSensitive); - if (idx == -1) { - return -1; - } - - // Check path. - QString attPath = QDir(fetchAttachmentFolderPath()).filePath(m_attachments[idx].m_name); - - bool equal = false; - if (p_caseSensitive) { - equal = VUtils::equalPath(attPath, fi.absoluteFilePath()); - } else { - equal = VUtils::equalPath(attPath.toLower(), - fi.absoluteFilePath().toLower()); - } - - return equal ? idx : -1; -} - -bool VNoteFile::sortAttachments(const QVector &p_sortedIdx) -{ - V_ASSERT(m_opened); - V_ASSERT(p_sortedIdx.size() == m_attachments.size()); - - auto ori = m_attachments; - - for (int i = 0; i < p_sortedIdx.size(); ++i) { - m_attachments[i] = ori[p_sortedIdx[i]]; - } - - bool ret = true; - if (!getDirectory()->updateFileConfig(this)) { - qWarning() << "fail to reorder attachments in config" << p_sortedIdx; - m_attachments = ori; - ret = false; - } - - return ret; -} - -bool VNoteFile::renameAttachment(const QString &p_oldName, const QString &p_newName) -{ - int idx = findAttachment(p_oldName); - if (idx == -1) { - return false; - } - - QDir dir(fetchAttachmentFolderPath()); - if (!dir.rename(p_oldName, p_newName)) { - qWarning() << "fail to rename attachment file" << p_oldName << p_newName; - return false; - } - - m_attachments[idx].m_name = p_newName; - - if (!getDirectory()->updateFileConfig(this)) { - qWarning() << "fail to rename attachment in config" << p_oldName << p_newName; - - m_attachments[idx].m_name = p_oldName; - dir.rename(p_newName, p_oldName); - - return false; - } - - return true; -} - -QVector VNoteFile::checkAttachments() -{ - QVector missing; - - QDir dir(fetchAttachmentFolderPath()); - for (auto const & atta : m_attachments) { - QString file = dir.filePath(atta.m_name); - if (!QFileInfo::exists(file)) { - missing.push_back(atta.m_name); - } - } - - return missing; -} - -bool VNoteFile::deleteFile(VNoteFile *p_file, QString *p_errMsg) -{ - Q_ASSERT(!p_file->isOpened()); - - bool ret = true; - QString name = p_file->getName(); - QString path = p_file->fetchPath(); - - if (!p_file->deleteFile(p_errMsg)) { - qWarning() << "fail to delete file" << name << path; - ret = false; - } - - VDirectory *dir = p_file->getDirectory(); - Q_ASSERT(dir); - if (!dir->removeFile(p_file)) { - qWarning() << "fail to remove file from directory" << name << path; - VUtils::addErrMsg(p_errMsg, tr("Fail to remove the note from the folder configuration.")); - ret = false; - } - - delete p_file; - - return ret; -} - -bool VNoteFile::copyFile(VDirectory *p_destDir, - const QString &p_destName, - VNoteFile *p_file, - bool p_isCut, - int p_idx, - VNoteFile **p_targetFile, - QString *p_errMsg) -{ - bool ret = true; - *p_targetFile = NULL; - int nrImageCopied = 0; - bool attachmentFolderCopied = false; - - QString srcPath = QDir::cleanPath(p_file->fetchPath()); - QString destPath = QDir::cleanPath(QDir(p_destDir->fetchPath()).filePath(p_destName)); - if (VUtils::equalPath(srcPath, destPath)) { - *p_targetFile = p_file; - return false; - } - - if (!p_destDir->isOpened()) { - VUtils::addErrMsg(p_errMsg, tr("Fail to open target folder.")); - return false; - } - - QString opStr = p_isCut ? tr("cut") : tr("copy"); - VDirectory *srcDir = p_file->getDirectory(); - DocType docType = p_file->getDocType(); - - Q_ASSERT(srcDir->isOpened()); - Q_ASSERT(docType == VUtils::docTypeFromName(p_destName)); - - // Images to be copied. - QVector images; - if (docType == DocType::Markdown) { - images = VUtils::fetchImagesFromMarkdownFile(p_file, - ImageLink::LocalRelativeInternal); - } - - // Attachments to be copied. - QString attaFolder = p_file->getAttachmentFolder(); - QString attaFolderPath; - if (!attaFolder.isEmpty()) { - attaFolderPath = p_file->fetchAttachmentFolderPath(); - } - - // Copy the note file. - if (!VUtils::copyFile(srcPath, destPath, p_isCut)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to %1 the note file.").arg(opStr)); - qWarning() << "fail to" << opStr << "the note file" << srcPath << "to" << destPath; - return false; - } - - // Add file to VDirectory. - VNoteFile *destFile = NULL; - if (p_isCut) { - srcDir->removeFile(p_file); - p_file->setName(p_destName); - if (p_destDir->addFile(p_file, p_idx)) { - destFile = p_file; - } else { - destFile = NULL; - } - } else { - destFile = p_destDir->addFile(p_destName, p_idx); - // Copy tags to this file. - if (destFile) { - const QStringList &tags = p_file->getTags(); - for (auto const & tag : tags) { - destFile->addTag(tag); - destFile->getNotebook()->addTag(tag); - } - } - } - - if (!destFile) { - VUtils::addErrMsg(p_errMsg, tr("Fail to add the note to target folder's configuration.")); - return false; - } - - // Copy images. - if (!copyInternalImages(images, - destFile->fetchBasePath(), - p_isCut, - &nrImageCopied, - p_errMsg)) { - ret = false; - } - - // Copy attachment folder. - if (!attaFolderPath.isEmpty()) { - QDir dir(destFile->fetchBasePath()); - QString folderPath = dir.filePath(destFile->getNotebook()->getAttachmentFolder()); - attaFolder = VUtils::getDirNameWithSequence(folderPath, attaFolder); - folderPath = QDir(folderPath).filePath(attaFolder); - - // Copy attaFolderPath to folderPath. - if (!VUtils::copyDirectory(attaFolderPath, folderPath, p_isCut)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to %1 attachments folder %2 to %3. " - "Please manually maintain it.") - .arg(opStr).arg(attaFolderPath).arg(folderPath)); - QVector emptyAttas; - destFile->setAttachments(emptyAttas); - ret = false; - } else { - attachmentFolderCopied = true; - - destFile->setAttachmentFolder(attaFolder); - if (!p_isCut) { - destFile->setAttachments(p_file->getAttachments()); - } - } - - if (!p_destDir->updateFileConfig(destFile)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to update configuration of note %1.") - .arg(destFile->fetchPath())); - ret = false; - } - } - - qDebug() << "copyFile:" << p_file << "to" << destFile - << "copied_images:" << nrImageCopied - << "copied_attachments:" << attachmentFolderCopied; - - *p_targetFile = destFile; - return ret; -} - -bool VNoteFile::copyInternalImages(const QVector &p_images, - const QString &p_destDirPath, - bool p_isCut, - int *p_nrImageCopied, - QString *p_errMsg) -{ - bool ret = true; - QDir parentDir(p_destDirPath); - QSet processedImages; - QString opStr = p_isCut ? tr("cut") : tr("copy"); - int nrImageCopied = 0; - for (int i = 0; i < p_images.size(); ++i) { - const ImageLink &link = p_images[i]; - if (processedImages.contains(link.m_path)) { - continue; - } - - processedImages.insert(link.m_path); - - if (!QFileInfo::exists(link.m_path)) { - VUtils::addErrMsg(p_errMsg, tr("Source image %1 does not exist.") - .arg(link.m_path)); - ret = false; - continue; - } - - QString imageFolder = VUtils::directoryNameFromPath(VUtils::basePathFromPath(link.m_path)); - QString destImagePath = QDir(parentDir.filePath(imageFolder)).filePath(VUtils::fileNameFromPath(link.m_path)); - - if (VUtils::equalPath(link.m_path, destImagePath)) { - VUtils::addErrMsg(p_errMsg, tr("Skip image with the same source and target path %1.") - .arg(link.m_path)); - ret = false; - continue; - } - - if (!VUtils::copyFile(link.m_path, destImagePath, p_isCut)) { - VUtils::addErrMsg(p_errMsg, tr("Fail to %1 image %2 to %3. " - "Please manually %1 it and modify the note.") - .arg(opStr).arg(link.m_path).arg(destImagePath)); - ret = false; - } else { - ++nrImageCopied; - qDebug() << opStr << "image" << link.m_path << "to" << destImagePath; - } - } - - *p_nrImageCopied = nrImageCopied; - return ret; -} - -void VNoteFile::removeTag(const QString &p_tag) -{ - if (p_tag.isEmpty() || m_tags.isEmpty()) { - return; - } - - int nr = m_tags.removeAll(p_tag); - if (nr > 0) { - if (!getDirectory()->updateFileConfig(this)) { - qWarning() << "fail to update config of file" << m_name - << "in directory" << fetchBasePath(); - } - } -} - -bool VNoteFile::addTag(const QString &p_tag) -{ - if (p_tag.isEmpty() || hasTag(p_tag)) { - return false; - } - - m_tags.append(p_tag); - if (!getDirectory()->updateFileConfig(this)) { - qWarning() << "fail to update config of file" << m_name - << "in directory" << fetchBasePath(); - m_tags.removeAll(p_tag); - return false; - } - - return true; -} - -bool VNoteFile::save() -{ - bool ret = VFile::save(); - if (ret) { - if (!getDirectory()->updateFileConfig(this)) { - qWarning() << "fail to update config of file" << m_name - << "in directory" << fetchBasePath(); - ret = false; - } - } - - return ret; -} diff --git a/src/vnotefile.h b/src/vnotefile.h deleted file mode 100644 index 56ed9178..00000000 --- a/src/vnotefile.h +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef VNOTEFILE_H -#define VNOTEFILE_H - -#include -#include - -#include "vfile.h" -#include "utils/vutils.h" - -class VDirectory; -class VNotebook; - -// Structure for a note attachment. -struct VAttachment -{ - VAttachment() - { - } - - VAttachment(const QString &p_name) - : m_name(p_name) - { - } - - // File name of the attachment. - QString m_name; -}; - -class VNoteFile : public VFile -{ - Q_OBJECT -public: - VNoteFile(VDirectory *p_directory, - const QString &p_name, - FileType p_type, - bool p_modifiable, - QDateTime p_createdTimeUtc, - QDateTime p_modifiedTimeUtc); - - QString fetchPath() const Q_DECL_OVERRIDE; - - QString fetchBasePath() const Q_DECL_OVERRIDE; - - QString fetchImageFolderPath() const Q_DECL_OVERRIDE; - - bool useRelativeImageFolder() const Q_DECL_OVERRIDE; - - QString getImageFolderInLink() const Q_DECL_OVERRIDE; - - bool save() Q_DECL_OVERRIDE; - - // Set the name of this file. - void setName(const QString &p_name); - - // Rename the name of this file in disk and config. - bool rename(const QString &p_name); - - VDirectory *getDirectory(); - - const VDirectory *getDirectory() const; - - VNotebook *getNotebook(); - - const VNotebook *getNotebook() const; - - QString getNotebookName() const; - - // Get the relative path related to the notebook. - QString fetchRelativePath() const; - - // Create a Json object from current instance. - QJsonObject toConfigJson() const; - - const QString &getAttachmentFolder() const; - - void setAttachmentFolder(const QString &p_folder); - - const QVector &getAttachments() const; - - void setAttachments(const QVector &p_attas); - - // Add @p_file as an attachment to this note. - bool addAttachment(const QString &p_file, QString *p_destFile = NULL); - - // Fetch attachment folder path. - // Will create it if it does not exist. - QString fetchAttachmentFolderPath(); - - // Delete all the attachments. - // @p_omitMissing: omit the error if the attachment file does not exist. - bool deleteAttachments(bool p_omitMissing = false); - - // Delete attachments specified by @p_names. - // @p_omitMissing: omit the error if the attachment file does not exist. - bool deleteAttachments(const QVector &p_names, - bool p_omitMissing = false); - - // Reorder attachments in m_attachments by index. - bool sortAttachments(const QVector &p_sortedIdx); - - // Return the index of @p_name in m_attachments. - // -1 if not found. - int findAttachment(const QString &p_name, bool p_caseSensitive = true); - - int findAttachmentByPath(const QString &p_file, bool p_caseSensitive = true); - - // Rename attachment @p_oldName to @p_newName. - bool renameAttachment(const QString &p_oldName, const QString &p_newName); - - // Check if all the attachment files still exist. - // Return the missing attachments' names. - QVector checkAttachments(); - - const QStringList &getTags() const; - - void removeTag(const QString &p_tag); - - bool addTag(const QString &p_tag); - - bool hasTag(const QString &p_tag) const; - - // Create a VNoteFile from @p_json Json object. - static VNoteFile *fromJson(VDirectory *p_directory, - const QJsonObject &p_json, - FileType p_type, - bool p_modifiable); - - // Delete file @p_file including removing it from parent directory configuration - // and delete the file in disk. - // @p_file: should be a normal file with parent directory. - // @p_errMsg: if not NULL, it will contain error message if this function fails. - static bool deleteFile(VNoteFile *p_file, QString *p_errMsg = NULL); - - // Copy file @p_file to @p_destDir with new name @p_destName. - // Returns a file representing the destination file after copy/cut. - static bool copyFile(VDirectory *p_destDir, - const QString &p_destName, - VNoteFile *p_file, - bool p_isCut, - int p_idx, - VNoteFile **p_targetFile, - QString *p_errMsg = NULL); - - // Copy images @p_images of a file to @p_destDirPath. - static bool copyInternalImages(const QVector &p_images, - const QString &p_destDirPath, - bool p_isCut, - int *p_nrImageCopied, - QString *p_errMsg = NULL); - -private: - // Delete internal images of this file. - // Return true only when all internal images were deleted successfully. - bool deleteInternalImages(); - - // Delete this file in disk as well as all its images/attachments. - bool deleteFile(QString *p_msg = NULL); - - // Folder under the attachment folder of the notebook. - // Store all the attachments of current file. - QString m_attachmentFolder; - - // Attachments. - QVector m_attachments; - - // Tags of this file. - QStringList m_tags; -}; - -inline const QString &VNoteFile::getAttachmentFolder() const -{ - return m_attachmentFolder; -} - -inline void VNoteFile::setAttachmentFolder(const QString &p_folder) -{ - m_attachmentFolder = p_folder; -} - -inline const QVector &VNoteFile::getAttachments() const -{ - return m_attachments; -} - -inline void VNoteFile::setAttachments(const QVector &p_attas) -{ - m_attachments = p_attas; -} - -inline const QStringList &VNoteFile::getTags() const -{ - return m_tags; -} - -inline bool VNoteFile::hasTag(const QString &p_tag) const -{ - return m_tags.contains(p_tag); -} -#endif // VNOTEFILE_H diff --git a/src/vopenedlistmenu.cpp b/src/vopenedlistmenu.cpp deleted file mode 100644 index 1257d2c2..00000000 --- a/src/vopenedlistmenu.cpp +++ /dev/null @@ -1,271 +0,0 @@ -#include "vopenedlistmenu.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "veditwindow.h" -#include "vnotefile.h" -#include "vedittab.h" -#include "vdirectory.h" -#include "utils/vutils.h" -#include "vbuttonmenuitem.h" -#include "utils/vimnavigationforwidget.h" -#include "vpalette.h" - -extern VPalette *g_palette; - -static const int c_cmdTime = 1 * 1000; - -static bool fileComp(const VOpenedListMenu::ItemInfo &a, - const VOpenedListMenu::ItemInfo &b) -{ - QString notebooka, notebookb; - if (a.file->getType() == FileType::Note) { - notebooka = dynamic_cast(a.file)->getNotebookName().toLower(); - } else { - notebooka = "EXTERNAL_FILES"; - } - - if (b.file->getType() == FileType::Note) { - notebookb = dynamic_cast(b.file)->getNotebookName().toLower(); - } else { - notebookb = "EXTERNAL_FILES"; - } - - if (notebooka < notebookb) { - return true; - } else if (notebooka > notebookb) { - return false; - } else { - QString patha = a.file->fetchBasePath(); - QString pathb = b.file->fetchBasePath(); -#if defined(Q_OS_WIN) - patha = patha.toLower(); - pathb = pathb.toLower(); -#endif - if (patha == pathb) { - return a.index < b.index; - } else { - return patha < pathb; - } - } -} - -VOpenedListMenu::VOpenedListMenu(VEditWindow *p_editWin) - : QMenu(p_editWin), - m_editWin(p_editWin), - m_cmdNum(0), - m_accepted(false) -{ - setToolTipsVisible(true); - - m_cmdTimer = new QTimer(this); - m_cmdTimer->setSingleShot(true); - m_cmdTimer->setInterval(c_cmdTime); - connect(m_cmdTimer, &QTimer::timeout, - this, &VOpenedListMenu::cmdTimerTimeout); - - connect(this, &QMenu::aboutToShow, - this, &VOpenedListMenu::updateOpenedList); - connect(this, &QMenu::triggered, - this, &VOpenedListMenu::handleItemTriggered); -} - -void VOpenedListMenu::updateOpenedList() -{ - // Regenerate the opened list. - m_seqActionMap.clear(); - clear(); - m_accepted = false; - - int curTab = m_editWin->currentIndex(); - int nrTab = m_editWin->count(); - QVector files(nrTab); - for (int i = 0; i < nrTab; ++i) { - files[i].file = m_editWin->getTab(i)->getFile(); - files[i].index = i; - } - - Q_ASSERT(!files.isEmpty()); - - std::sort(files.begin(), files.end(), fileComp); - - QString notebook; - const VDirectory *directory = NULL; - for (int i = 0; i < nrTab; ++i) { - QPointer file = files[i].file; - int index = files[i].index; - - // Whether add separator. - QString curNotebook; - const VDirectory *curDirectory = NULL; - if (file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast((VFile *)file); - curNotebook = tmpFile->getNotebookName(); - curDirectory = tmpFile->getDirectory(); - } else { - curNotebook = "EXTERNAL_FILES"; - } - - QString separatorText; - if (curNotebook != notebook - || curDirectory != directory) { - notebook = curNotebook; - directory = curDirectory; - QString dirName; - if (directory) { - dirName = directory->getName(); - } - - if (dirName.isEmpty()) { - separatorText = QString("[%1]").arg(notebook); - } else { - separatorText = QString("[%1] %2").arg(notebook).arg(dirName); - } - - addSeparator(); - } - - // Append the separator text to the end of the first item. - QWidgetAction *wact = new QWidgetAction(this); - wact->setData(QVariant::fromValue(file)); - VButtonMenuItem *w = new VButtonMenuItem(wact, - m_editWin->tabIcon(index), - m_editWin->tabText(index), - separatorText, - g_palette->color("buttonmenuitem_decoration_text_fg"), - this); - w->setToolTip(generateDescription(file)); - wact->setDefaultWidget(w); - - if (index == curTab) { - QFont boldFont = w->font(); - boldFont.setBold(true); - w->setFont(boldFont); - - w->setFocus(); - } - - addAction(wact); - m_seqActionMap[index + c_tabSequenceBase] = wact; - } -} - -QString VOpenedListMenu::generateDescription(const VFile *p_file) const -{ - if (!p_file) { - return ""; - } - - // [Notebook]path - if (p_file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast(p_file); - return QString("[%1] %2").arg(tmpFile->getNotebookName()).arg(tmpFile->fetchPath()); - } else { - return QString("%1").arg(p_file->fetchPath()); - } -} - -void VOpenedListMenu::handleItemTriggered(QAction *p_action) -{ - if (p_action) { - QPointer file = p_action->data().value>(); - if (file) { - m_accepted = true; - emit fileTriggered(file); - } - } - - hide(); -} - -void VOpenedListMenu::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(this, - p_event)) { - m_cmdTimer->stop(); - m_cmdNum = 0; - return; - } - - int key = p_event->key(); - switch (key) { - case Qt::Key_0: - case Qt::Key_1: - case Qt::Key_2: - case Qt::Key_3: - case Qt::Key_4: - case Qt::Key_5: - case Qt::Key_6: - case Qt::Key_7: - case Qt::Key_8: - case Qt::Key_9: - { - addDigit(key - Qt::Key_0); - return; - } - - default: - m_cmdTimer->stop(); - m_cmdNum = 0; - break; - } - - QMenu::keyPressEvent(p_event); -} - -void VOpenedListMenu::cmdTimerTimeout() -{ - if (m_cmdNum > 0) { - triggerItem(m_cmdNum); - m_cmdNum = 0; - } -} - -void VOpenedListMenu::addDigit(int p_digit) -{ - V_ASSERT(p_digit >= 0 && p_digit <= 9); - m_cmdTimer->stop(); - m_cmdNum = m_cmdNum * 10 + p_digit; - - int totalItem = m_seqActionMap.size(); - // Try to trigger it ASAP. - if (m_cmdNum > 0) { - if (getNumOfDigit(m_cmdNum) == getNumOfDigit(totalItem)) { - triggerItem(m_cmdNum); - m_cmdNum = 0; - return; - } - } - - m_cmdTimer->start(); -} - -int VOpenedListMenu::getNumOfDigit(int p_num) -{ - int nrDigit = 1; - while (true) { - p_num /= 10; - if (p_num == 0) { - return nrDigit; - } else { - ++nrDigit; - } - } -} - -void VOpenedListMenu::triggerItem(int p_seq) -{ - auto it = m_seqActionMap.find(p_seq); - if (it != m_seqActionMap.end()) { - QAction *act = it.value(); - act->trigger(); - hide(); - } -} diff --git a/src/vopenedlistmenu.h b/src/vopenedlistmenu.h deleted file mode 100644 index 4084cf70..00000000 --- a/src/vopenedlistmenu.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef VOPENEDLISTMENU_H -#define VOPENEDLISTMENU_H - -#include -#include - -class VEditWindow; -class VFile; -class QAction; -class QKeyEvent; -class QTimer; - -class VOpenedListMenu : public QMenu -{ - Q_OBJECT -public: - struct ItemInfo { - VFile *file; - int index; - }; - - explicit VOpenedListMenu(VEditWindow *p_editWin); - - bool isAccepted() const; - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - -signals: - void fileTriggered(VFile *p_file); - -private slots: - void updateOpenedList(); - void handleItemTriggered(QAction *p_action); - void cmdTimerTimeout(); - -private: - QString generateDescription(const VFile *p_file) const; - void addDigit(int p_digit); - int getNumOfDigit(int p_num); - void triggerItem(int p_seq); - - VEditWindow *m_editWin; - - // The number user pressed. - int m_cmdNum; - - QTimer *m_cmdTimer; - QMap m_seqActionMap; - - // Whether the menu is accepted or rejected. - bool m_accepted; -}; - -inline bool VOpenedListMenu::isAccepted() const -{ - return m_accepted; -} -#endif // VOPENEDLISTMENU_H diff --git a/src/vorphanfile.cpp b/src/vorphanfile.cpp deleted file mode 100644 index a0cf9543..00000000 --- a/src/vorphanfile.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "vorphanfile.h" -#include -#include -#include -#include -#include "utils/vutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VOrphanFile::VOrphanFile(QObject *p_parent, - const QString &p_path, - bool p_modifiable, - bool p_systemFile) - : VFile(p_parent, - VUtils::fileNameFromPath(p_path), - FileType::Orphan, - p_modifiable, - QDateTime(), - QDateTime()), - m_path(p_path), - m_systemFile(p_systemFile) -{ -} - -QString VOrphanFile::fetchPath() const -{ - return m_path; -} - -QString VOrphanFile::fetchBasePath() const -{ - return VUtils::basePathFromPath(m_path); -} - -QString VOrphanFile::fetchImageFolderPath() const -{ - QString folder = m_imageFolder; - if (m_imageFolder.isEmpty()) { - folder = g_config->getImageFolderExt(); - } - - QFileInfo fi(folder); - if (fi.isAbsolute()) { - return folder; - } else { - return QDir(fetchBasePath()).filePath(folder); - } -} - -bool VOrphanFile::useRelativeImageFolder() const -{ - QString folder = m_imageFolder; - if (m_imageFolder.isEmpty()) { - folder = g_config->getImageFolderExt(); - } - - return !QFileInfo(folder).isAbsolute(); -} - -QString VOrphanFile::getImageFolderInLink() const -{ - QString folder = m_imageFolder; - if (m_imageFolder.isEmpty()) { - folder = g_config->getImageFolderExt(); - } - - return folder; -} - -QString VOrphanFile::fetchRecycleBinFolderPath() const -{ - QString folder = m_recycleBinFolder; - if (m_recycleBinFolder.isEmpty()) { - folder = g_config->getRecycleBinFolderExt(); - } - - QFileInfo fi(folder); - if (fi.isAbsolute()) { - return folder; - } else { - return QDir(fetchBasePath()).filePath(folder); - } -} diff --git a/src/vorphanfile.h b/src/vorphanfile.h deleted file mode 100644 index 6d4b851a..00000000 --- a/src/vorphanfile.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef VORPHANFILE_H -#define VORPHANFILE_H - -#include "vfile.h" - -// VOrphanFile is a file not belonging to any notebooks or directories. -// Such as external files, system files. -// It uses the file path to locate and identify a file. -class VOrphanFile : public VFile -{ - Q_OBJECT -public: - VOrphanFile(QObject *p_parent, - const QString &p_path, - bool p_modifiable, - bool p_systemFile = false); - - QString fetchPath() const Q_DECL_OVERRIDE; - - QString fetchBasePath() const Q_DECL_OVERRIDE; - - QString fetchImageFolderPath() const Q_DECL_OVERRIDE; - - // Whether use a relative image folder. - bool useRelativeImageFolder() const Q_DECL_OVERRIDE; - - // Return the image folder part in an image link. - QString getImageFolderInLink() const Q_DECL_OVERRIDE; - - // Return image folder config. - const QString getImageFolder() const; - - // Set the image folder config. - void setImageFolder(const QString &p_path); - - bool isSystemFile() const; - - // Get the recycle bin folder for this file. - QString fetchRecycleBinFolderPath() const; - -private: - // Full path of this file. - QString m_path; - - // Image folder path of this file. - // It could be an absolute or relative path. - // Empty to use the global default config. - // Valid only within a session. - QString m_imageFolder; - - // Recycle bin forlder. - // May be absolute or relative path. - // Empty to use the global default config. - // Valid only within a session. - QString m_recycleBinFolder; - - // Whether it is a system internal file. - bool m_systemFile; -}; - -inline const QString VOrphanFile::getImageFolder() const -{ - return m_imageFolder; -} - -inline void VOrphanFile::setImageFolder(const QString &p_path) -{ - m_imageFolder = p_path; -} - -inline bool VOrphanFile::isSystemFile() const -{ - return m_systemFile; -} - -#endif // VORPHANFILE_H diff --git a/src/voutline.cpp b/src/voutline.cpp deleted file mode 100644 index 75918b8f..00000000 --- a/src/voutline.cpp +++ /dev/null @@ -1,371 +0,0 @@ -#include "voutline.h" - -#include -#include - -#include "utils/vutils.h" -#include "vnote.h" -#include "vfile.h" -#include "vtreewidget.h" -#include "utils/viconutils.h" -#include "vconfigmanager.h" -#include "vmainwindow.h" - -extern VNote *g_vnote; - -extern VConfigManager *g_config; - -extern VMainWindow *g_mainWin; - -#define STATIC_EXPANDED_LEVEL 6 - -VOutline::VOutline(QWidget *parent) - : QWidget(parent), - VNavigationMode(), - m_muted(false) -{ - setupUI(); - - m_expandTimer = new QTimer(this); - m_expandTimer->setSingleShot(true); - m_expandTimer->setInterval(1000); - connect(m_expandTimer, &QTimer::timeout, - this, [this]() { - // Auto adjust items after current header change. - int level = g_config->getOutlineExpandedLevel(); - if (level == STATIC_EXPANDED_LEVEL) { - return; - } - - expandTree(level); - - QTreeWidgetItem *curItem = m_tree->currentItem(); - if (curItem) { - m_tree->scrollToItem(curItem); - } - }); -} - -void VOutline::setupUI() -{ - m_deLevelBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/decrease_outline_level.svg"), - "", - this); - m_deLevelBtn->setToolTip(tr("Decrease Expanded Level")); - m_deLevelBtn->setProperty("FlatBtn", true); - m_deLevelBtn->setEnabled(false); - connect(m_deLevelBtn, &QPushButton::clicked, - this, [this]() { - int level = g_config->getOutlineExpandedLevel() - 1; - if (level <= 0) { - level = 1; - } else { - g_config->setOutlineExpandedLevel(level); - expandTree(level); - } - - g_mainWin->showStatusMessage(tr("Set Outline Expanded Level to %1").arg(level)); - }); - - m_inLevelBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/increase_outline_level.svg"), - "", - this); - m_inLevelBtn->setToolTip(tr("Increase Expanded Level")); - m_inLevelBtn->setProperty("FlatBtn", true); - m_inLevelBtn->setEnabled(false); - connect(m_inLevelBtn, &QPushButton::clicked, - this, [this]() { - int level = g_config->getOutlineExpandedLevel() + 1; - if (level >= 7) { - level = 6; - } else { - g_config->setOutlineExpandedLevel(level); - expandTree(level); - } - - g_mainWin->showStatusMessage(tr("Set Outline Expanded Level to %1").arg(level)); - }); - - QHBoxLayout *btnLayout = new QHBoxLayout(); - btnLayout->addStretch(); - btnLayout->addWidget(m_deLevelBtn); - btnLayout->addWidget(m_inLevelBtn); - btnLayout->setContentsMargins(0, 0, 0, 0); - - m_tree = new VTreeWidget(this); - m_tree->setColumnCount(1); - m_tree->setHeaderHidden(true); - m_tree->setSelectionMode(QAbstractItemView::SingleSelection); - // TODO: jump to the header when user click the same item twice. - connect(m_tree, &QTreeWidget::currentItemChanged, - this, [this](QTreeWidgetItem *p_cur, QTreeWidgetItem *p_pre) { - Q_UNUSED(p_pre); - activateItem(p_cur); - }); - connect(m_tree, &QTreeWidget::itemClicked, - this, [this](QTreeWidgetItem *p_item, int p_col) { - Q_UNUSED(p_col); - // Will duplicate the signal. That's fine. - activateItem(p_item, true); - }); - - QVBoxLayout *layout = new QVBoxLayout(); - layout->addLayout(btnLayout); - layout->addWidget(m_tree); - layout->setContentsMargins(3, 0, 3, 0); - - setLayout(layout); -} - -void VOutline::updateOutline(const VTableOfContent &p_outline) -{ - if (p_outline == m_outline) { - return; - } - - // Clear current header - m_currentHeader.clear(); - - m_outline = p_outline; - - updateTreeFromOutline(m_tree, m_outline); - - updateButtonsState(); - - expandTree(g_config->getOutlineExpandedLevel()); -} - -void VOutline::updateTreeFromOutline(QTreeWidget *p_treeWidget, - const VTableOfContent &p_outline) -{ - p_treeWidget->clear(); - - if (p_outline.isEmpty()) { - p_treeWidget->update(); - return; - } - - const QVector &headers = p_outline.getTable(); - int idx = 0; - updateTreeByLevel(p_treeWidget, headers, idx, NULL, NULL, 1); -} - -void VOutline::updateTreeByLevel(QTreeWidget *p_treeWidget, - const QVector &p_headers, - int &p_index, - QTreeWidgetItem *p_parent, - QTreeWidgetItem *p_last, - int p_level) -{ - while (p_index < p_headers.size()) { - const VTableOfContentItem &header = p_headers[p_index]; - QTreeWidgetItem *item; - if (header.m_level == p_level) { - if (p_parent) { - item = new QTreeWidgetItem(p_parent); - } else { - item = new QTreeWidgetItem(p_treeWidget); - } - - fillItem(item, header); - - p_last = item; - ++p_index; - } else if (header.m_level < p_level) { - return; - } else { - updateTreeByLevel(p_treeWidget, p_headers, p_index, p_last, NULL, p_level + 1); - } - } -} - -void VOutline::fillItem(QTreeWidgetItem *p_item, const VTableOfContentItem &p_header) -{ - p_item->setData(0, Qt::UserRole, p_header.m_index); - p_item->setText(0, p_header.m_name); - p_item->setToolTip(0, p_header.m_name); - - if (p_header.isEmpty()) { - p_item->setForeground(0, QColor("grey")); - } -} - -void VOutline::expandTree(int p_expandedLevel) -{ - int topCount = m_tree->topLevelItemCount(); - if (topCount == 0) { - return; - } - - m_tree->collapseAll(); - - // Get the base level. - const VTableOfContentItem *header = getHeaderFromItem(m_tree->topLevelItem(0), m_outline); - if (!header) { - return; - } - - int baseLevel = header->m_level; - int levelToBeExpanded = p_expandedLevel - baseLevel; - - for (int i = 0; i < topCount; ++i) { - expandTreeOne(m_tree->topLevelItem(i), levelToBeExpanded); - } -} - -void VOutline::expandTreeOne(QTreeWidgetItem *p_item, int p_levelToBeExpanded) -{ - if (p_levelToBeExpanded <= 0) { - return; - } - - // Expand this item. - p_item->setExpanded(true); - - int nrChild = p_item->childCount(); - for (int i = 0; i < nrChild; ++i) { - expandTreeOne(p_item->child(i), p_levelToBeExpanded - 1); - } -} - -void VOutline::activateItem(QTreeWidgetItem *p_item, bool p_focusEditArea) -{ - if (!p_item) { - return; - } - - const VTableOfContentItem *header = getHeaderFromItem(p_item, m_outline); - Q_ASSERT(header); - m_currentHeader.update(m_outline.getFile(), header->m_index); - - if (!header->isEmpty() && !m_muted) { - emit outlineItemActivated(m_currentHeader); - if (p_focusEditArea) { - g_mainWin->focusEditArea(); - } - } -} - -void VOutline::updateCurrentHeader(const VHeaderPointer &p_header) -{ - if (p_header == m_currentHeader - || !m_outline.isMatched(p_header)) { - return; - } - - // Item change should not emit the signal. - m_muted = true; - m_currentHeader = p_header; - selectHeader(m_tree, m_outline, m_currentHeader); - m_muted = false; - - m_expandTimer->start(); -} - -void VOutline::selectHeader(QTreeWidget *p_treeWidget, - const VTableOfContent &p_outline, - const VHeaderPointer &p_header) -{ - p_treeWidget->setCurrentItem(NULL); - - if (!p_outline.getItem(p_header)) { - return; - } - - int nrTop = p_treeWidget->topLevelItemCount(); - for (int i = 0; i < nrTop; ++i) { - if (selectHeaderOne(p_treeWidget, p_treeWidget->topLevelItem(i), p_outline, p_header)) { - return; - } - } -} - -bool VOutline::selectHeaderOne(QTreeWidget *p_treeWidget, - QTreeWidgetItem *p_item, - const VTableOfContent &p_outline, - const VHeaderPointer &p_header) -{ - if (!p_item) { - return false; - } - - const VTableOfContentItem *header = getHeaderFromItem(p_item, p_outline); - if (!header) { - return false; - } - - if (header->isMatched(p_header)) { - p_treeWidget->setCurrentItem(p_item); - return true; - } - - int nrChild = p_item->childCount(); - for (int i = 0; i < nrChild; ++i) { - if (selectHeaderOne(p_treeWidget, p_item->child(i), p_outline, p_header)) { - return true; - } - } - - return false; -} - -void VOutline::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Return: - V_FALLTHROUGH; - case Qt::Key_Enter: - { - QTreeWidgetItem *item = m_tree->currentItem(); - if (item) { - item->setExpanded(!item->isExpanded()); - } - - return; - } - - default: - break; - } - - QWidget::keyPressEvent(event); -} - -void VOutline::showNavigation() -{ - VNavigationMode::showNavigation(m_tree); -} - -bool VOutline::handleKeyNavigation(int p_key, bool &p_succeed) -{ - bool ret = VNavigationMode::handleKeyNavigation(m_tree, - p_key, - p_succeed); - - if (ret && p_succeed && !m_isSecondKey) { - g_mainWin->focusEditArea(); - } - - return ret; -} - -const VTableOfContentItem *VOutline::getHeaderFromItem(QTreeWidgetItem *p_item, - const VTableOfContent &p_outline) -{ - int index = p_item->data(0, Qt::UserRole).toInt(); - return p_outline.getItem(index); -} - -void VOutline::focusInEvent(QFocusEvent *p_event) -{ - QWidget::focusInEvent(p_event); - - m_tree->setFocus(); -} - -void VOutline::updateButtonsState() -{ - bool empty = m_outline.isEmpty(); - m_deLevelBtn->setEnabled(!empty); - m_inLevelBtn->setEnabled(!empty); -} diff --git a/src/voutline.h b/src/voutline.h deleted file mode 100644 index ea134f52..00000000 --- a/src/voutline.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef VOUTLINE_H -#define VOUTLINE_H - -#include -#include -#include -#include - -#include "vtableofcontent.h" -#include "vnavigationmode.h" - -class QLabel; -class VTreeWidget; -class QPushButton; -class QTimer; - -// Display table of content as a tree and enable user to click an item to -// jump to that header. -class VOutline : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - VOutline(QWidget *parent = 0); - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - - // Update tree according to outline. - static void updateTreeFromOutline(QTreeWidget *p_treeWidget, const VTableOfContent &p_outline); - - // Set the item corresponding to @p_header as current item. - static void selectHeader(QTreeWidget *p_treeWidget, - const VTableOfContent &p_outline, - const VHeaderPointer &p_header); - - // Return NULL if no corresponding header in outline. - static const VTableOfContentItem *getHeaderFromItem(QTreeWidgetItem *p_item, - const VTableOfContent &p_outline); - -signals: - // Emit when current item changed by user and header of that item is not empty. - // Do not worry about infinite recursion. - void outlineItemActivated(const VHeaderPointer &p_header); - -public slots: - // Called to update outline and the tree. - // Just clear the tree if @p_outline is empty. - void updateOutline(const VTableOfContent &p_outline); - - // Called to update current header in the tree. - // Will not emit outlineItemActivated(). - void updateCurrentHeader(const VHeaderPointer &p_header); - -protected: - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - - void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private: - void setupUI(); - - void expandTree(int p_expandedLevel = 6); - - void expandTreeOne(QTreeWidgetItem *p_item, int p_levelToBeExpanded); - - void updateButtonsState(); - - // Do not response if m_muted is true. - void activateItem(QTreeWidgetItem *p_item, bool p_focusEditArea = false); - - // @index: the index in @headers. - static void updateTreeByLevel(QTreeWidget *p_treeWidget, - const QVector &p_headers, - int &p_index, - QTreeWidgetItem *p_parent, - QTreeWidgetItem *p_last, - int p_level); - - // Fill the info of @p_item. - static void fillItem(QTreeWidgetItem *p_item, const VTableOfContentItem &p_header); - - static bool selectHeaderOne(QTreeWidget *p_treeWidget, - QTreeWidgetItem *p_item, - const VTableOfContent &p_outline, - const VHeaderPointer &p_header); - - VTableOfContent m_outline; - - VHeaderPointer m_currentHeader; - - // When true, won't emit outlineItemActivated(). - bool m_muted; - - QTimer *m_expandTimer; - - QPushButton *m_deLevelBtn; - QPushButton *m_inLevelBtn; - VTreeWidget *m_tree; -}; - -#endif // VOUTLINE_H diff --git a/src/voutlineue.cpp b/src/voutlineue.cpp deleted file mode 100644 index 1e995341..00000000 --- a/src/voutlineue.cpp +++ /dev/null @@ -1,257 +0,0 @@ -#include "voutlineue.h" - -#include -#include - -#include "vtreewidget.h" -#include "vlistwidget.h" -#include "voutline.h" -#include "vmainwindow.h" -#include "vedittab.h" -#include "veditarea.h" -#include "vsearchconfig.h" -#include "vtableofcontent.h" - -extern VMainWindow *g_mainWin; - -VOutlineUE::VOutlineUE(QObject *p_parent) - : IUniversalEntry(p_parent), - m_listWidget(NULL), - m_treeWidget(NULL), - m_listOutline(true) -{ -} - -QString VOutlineUE::description(int p_id) const -{ - Q_UNUSED(p_id); - - return tr("List and search the outline of current note"); -} - -void VOutlineUE::init() -{ - if (m_initialized) { - return; - } - - Q_ASSERT(m_widgetParent); - - m_initialized = true; - - m_listWidget = new VListWidget(m_widgetParent); - m_listWidget->setFitContent(true); - m_listWidget->hide(); - connect(m_listWidget, SIGNAL(itemActivated(QListWidgetItem *)), - this, SLOT(activateItem(QListWidgetItem *))); - - m_treeWidget = new VTreeWidget(m_widgetParent); - m_treeWidget->setColumnCount(1); - m_treeWidget->setHeaderHidden(true); - m_treeWidget->setSelectionMode(QAbstractItemView::SingleSelection); - m_treeWidget->setExpandsOnDoubleClick(false); - m_treeWidget->setFitContent(true); - m_treeWidget->hide(); - - connect(m_treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)), - this, SLOT(activateItem(QTreeWidgetItem *, int))); - connect(m_treeWidget, &VTreeWidget::itemExpandedOrCollapsed, - this, &VOutlineUE::widgetUpdated); -} - -QWidget *VOutlineUE::widget(int p_id) -{ - Q_UNUSED(p_id); - init(); - - if (m_listOutline) { - return m_treeWidget; - } else { - return m_listWidget; - } -} - -void VOutlineUE::processCommand(int p_id, const QString &p_cmd) -{ - Q_UNUSED(p_id); - - init(); - - clear(-1); - - emit stateUpdated(State::Busy); - - VEditTab *tab = g_mainWin->getCurrentTab(); - if (p_cmd.isEmpty()) { - // List the outline. - m_listOutline = true; - - if (tab) { - const VTableOfContent &outline = tab->getOutline(); - VOutline::updateTreeFromOutline(m_treeWidget, outline); - - VTreeWidget::expandCollapseAll(m_treeWidget); - - const VHeaderPointer &header = tab->getCurrentHeader(); - if (outline.isMatched(header)) { - VOutline::selectHeader(m_treeWidget, outline, header); - } - } - } else { - // Search the outline. - m_listOutline = false; - - if (tab) { - VSearchConfig config(VSearchConfig::CurrentNote, - VSearchConfig::Content, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString()); - - const VTableOfContent &outline = tab->getOutline(); - const QVector &table = outline.getTable(); - for (auto const & it : table) { - if (it.isEmpty()) { - continue; - } - - if (!config.m_token.matched(it.m_name)) { - continue; - } - - // Add item to list. - QListWidgetItem *item = new QListWidgetItem(it.m_name, m_listWidget); - item->setData(Qt::UserRole, it.m_index); - item->setToolTip(it.m_name); - - if (!m_listWidget->currentItem()) { - m_listWidget->setCurrentItem(item); - } - } - } - } - - emit stateUpdated(State::Success); - updateWidget(); -} - -void VOutlineUE::updateWidget() -{ - QWidget *wid = m_listWidget; - if (m_listOutline) { - if (m_treeWidget->topLevelItemCount() > 0) { - m_treeWidget->resizeColumnToContents(0); - } else { - QTreeWidgetItem *item = new QTreeWidgetItem(m_treeWidget, QStringList("test")); - m_treeWidget->resizeColumnToContents(0); - delete item; - } - - wid = m_treeWidget; - } - - wid->updateGeometry(); - emit widgetUpdated(); -} - -void VOutlineUE::clear(int p_id) -{ - Q_UNUSED(p_id); - m_treeWidget->clearAll(); - m_listWidget->clearAll(); -} - -void VOutlineUE::entryHidden(int p_id) -{ - Q_UNUSED(p_id); - clear(-1); -} - -void VOutlineUE::entryShown(int p_id, const QString &p_cmd) -{ - processCommand(p_id, p_cmd); -} - -void VOutlineUE::selectNextItem(int p_id, bool p_forward) -{ - Q_UNUSED(p_id); - - if (m_listOutline) { - m_treeWidget->selectNextItem(p_forward); - } else { - m_listWidget->selectNextItem(p_forward); - } -} - -void VOutlineUE::activate(int p_id) -{ - Q_UNUSED(p_id); - if (m_listOutline) { - activateItem(m_treeWidget->currentItem(), 0); - } else { - activateItem(m_listWidget->currentItem()); - } -} - -void VOutlineUE::activateItem(QListWidgetItem *p_item) -{ - if (!p_item) { - return; - } - - int idx = p_item->data(Qt::UserRole).toInt(); - - emit requestHideUniversalEntry(); - - VHeaderPointer hp(g_mainWin->getCurrentFile(), idx); - g_mainWin->getEditArea()->scrollToHeader(hp); -} - -void VOutlineUE::activateItem(QTreeWidgetItem *p_item, int p_col) -{ - Q_UNUSED(p_col); - if (!p_item) { - return; - } - - VEditTab *tab = g_mainWin->getCurrentTab(); - Q_ASSERT(tab); - const VTableOfContent &outline = tab->getOutline(); - const VTableOfContentItem *header = VOutline::getHeaderFromItem(p_item, outline); - Q_ASSERT(header); - if (!header->isEmpty()) { - emit requestHideUniversalEntry(); - - VHeaderPointer hp(outline.getFile(), header->m_index); - g_mainWin->getEditArea()->scrollToHeader(hp); - } -} - -void VOutlineUE::selectParentItem(int p_id) -{ - Q_UNUSED(p_id); - if (m_listOutline) { - m_treeWidget->selectParentItem(); - } -} - -void VOutlineUE::toggleItemExpanded(int p_id) -{ - Q_UNUSED(p_id); - if (m_listOutline) { - QTreeWidgetItem *item = m_treeWidget->currentItem(); - if (item) { - item->setExpanded(!item->isExpanded()); - } - } -} - -void VOutlineUE::expandCollapseAll(int p_id) -{ - Q_UNUSED(p_id); - if (m_listOutline) { - VTreeWidget::expandCollapseAll(m_treeWidget); - } -} diff --git a/src/voutlineue.h b/src/voutlineue.h deleted file mode 100644 index 4f1ebe70..00000000 --- a/src/voutlineue.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef VOUTLINEUE_H -#define VOUTLINEUE_H - -#include "iuniversalentry.h" - -class VListWidget; -class QListWidgetItem; -class VTreeWidget; -class QTreeWidgetItem; - -// Universal Entry to list and search outline of current note. -class VOutlineUE : public IUniversalEntry -{ - Q_OBJECT -public: - explicit VOutlineUE(QObject *p_parent = nullptr); - - QString description(int p_id) const Q_DECL_OVERRIDE; - - QWidget *widget(int p_id) Q_DECL_OVERRIDE; - - void processCommand(int p_id, const QString &p_cmd) Q_DECL_OVERRIDE; - - void clear(int p_id) Q_DECL_OVERRIDE; - - void entryHidden(int p_id) Q_DECL_OVERRIDE; - - void entryShown(int p_id, const QString &p_cmd) Q_DECL_OVERRIDE; - - void selectNextItem(int p_id, bool p_forward) Q_DECL_OVERRIDE; - - void selectParentItem(int p_id) Q_DECL_OVERRIDE; - - void activate(int p_id) Q_DECL_OVERRIDE; - - void toggleItemExpanded(int p_id) Q_DECL_OVERRIDE; - - void expandCollapseAll(int p_id) Q_DECL_OVERRIDE; - -protected: - void init() Q_DECL_OVERRIDE; - -private slots: - void activateItem(QListWidgetItem *p_item); - - void activateItem(QTreeWidgetItem *p_item, int p_col); - -private: - void updateWidget(); - - VListWidget *m_listWidget; - - VTreeWidget *m_treeWidget; - - bool m_listOutline; -}; - -#endif // VOUTLINEUE_H diff --git a/src/vpalette.cpp b/src/vpalette.cpp deleted file mode 100644 index 49c208c7..00000000 --- a/src/vpalette.cpp +++ /dev/null @@ -1,336 +0,0 @@ -#include "vpalette.h" - -#include -#include -#include -#include -#include - -#include "utils/vutils.h" - -VPalette::VPalette(const QString &p_file) -{ - init(p_file); -} - -void VPalette::init(const QString &p_file) -{ - m_file = QFileInfo(p_file).absoluteFilePath(); - - QSettings settings(p_file, QSettings::IniFormat); - m_data = getPaletteMetaData(m_file); - initPaleteFromSettings(&settings, "phony"); - initPaleteFromSettings(&settings, "soft_defined"); - initPaleteFromSettings(&settings, "widgets"); - - qDebug() << "theme file" << m_file << m_data.toString(); -} - -void VPalette::initPaleteFromSettings(QSettings *p_settings, const QString &p_group) -{ - QRegExp reg("@(\\w+)"); - - p_settings->beginGroup(p_group); - // Used to store undefined pairs. - QHash undefined; - QStringList keys = p_settings->childKeys(); - for (auto const & key : keys) { - if (key.isEmpty()) { - continue; - } - - QString val = p_settings->value(key).toString(); - if (reg.exactMatch(val)) { - auto it = m_palette.find(reg.cap(1)); - if (it != m_palette.end()) { - val = it.value(); - } else { - undefined.insert(key, reg.cap(1)); - continue; - } - } - - m_palette.insert(key, val); - } - - // Handle definition: a=@b b=@c c=red. - int iter = 0; - while (!undefined.isEmpty()) { - if (iter >= undefined.size()) { - qWarning() << "cyclic palette definitions found" << undefined; - break; - } - - for (auto it = undefined.begin(); it != undefined.end();) { - auto pit = m_palette.find(it.value()); - if (pit != m_palette.end()) { - m_palette.insert(it.key(), pit.value()); - iter = 0; - it = undefined.erase(it); - } else { - ++iter; - ++it; - } - } - } - - p_settings->endGroup(); -} - -QString VPalette::color(const QString &p_name) const -{ - auto it = m_palette.find(p_name); - if (it != m_palette.end()) { - return it.value(); - } - - return QString(); -} - -void VPalette::fillStyle(QString &p_text) const -{ - // Cap(2) is the string to be replaced. - QRegExp reg("(\\s|:)@(\\w+)(?=\\W)"); - - int pos = 0; - while (pos < p_text.size()) { - int idx = p_text.indexOf(reg, pos); - if (idx == -1) { - break; - } - - QString name = reg.cap(2); - QString val = color(name); - - if (val.isEmpty()) { - pos = idx + reg.matchedLength(); - } else { - pos = idx + reg.matchedLength() + val.size() - name.size() - 1; - p_text.replace(idx + reg.cap(1).size(), name.size() + 1, val); - } - } -} - -QString VPalette::fetchQtStyleSheet() const -{ - QString style = VUtils::readFileFromDisk(m_data.m_qssFile); - fillStyle(style); - fillAbsoluteUrl(style); - fillFontFamily(style); - fillScaledSize(style); - - return style; -} - -void VPalette::fillAbsoluteUrl(QString &p_style) const -{ - // Cap(2) is the string to be replaced. - QRegExp reg("(\\s|:)url\\(([^\\(\\)]+)\\)(?=\\W)"); - int literalSize = QString("url(").size(); - QDir dir(VUtils::basePathFromPath(m_file)); - - int pos = 0; - while (pos < p_style.size()) { - int idx = p_style.indexOf(reg, pos); - if (idx == -1) { - break; - } - - QString url = reg.cap(2); - QString abUrl = dir.filePath(url); - pos = idx + reg.matchedLength() + abUrl.size() - url.size(); - p_style.replace(idx + reg.cap(1).size() + literalSize, url.size(), abUrl); - } -} - -QMap VPalette::editorStylesFromThemes(const QList &p_themeFiles) -{ - QMap styles; - for (auto const & theme : p_themeFiles) { - QString value = getPaletteMetaData(theme).m_mdhlFile; - if (!value.isEmpty()) { - styles.insert(themeName(theme) + "/" + QFileInfo(value).completeBaseName(), value); - } - } - - return styles; -} - -QMap VPalette::cssStylesFromThemes(const QList &p_themeFiles) -{ - QMap styles; - for (auto const & theme : p_themeFiles) { - QString value = getPaletteMetaData(theme).m_cssFile; - if (!value.isEmpty()) { - styles.insert(themeName(theme) + "/" + QFileInfo(value).completeBaseName(), value); - } - } - - return styles; -} - -QMap VPalette::codeBlockCssStylesFromThemes(const QList &p_themeFiles) -{ - QMap styles; - for (auto const & theme : p_themeFiles) { - QString value = getPaletteMetaData(theme).m_codeBlockCssFile; - if (!value.isEmpty()) { - styles.insert(themeName(theme) + "/" + QFileInfo(value).completeBaseName(), value); - } - } - - return styles; -} - -static QString translateColorValue(const QString &p_col) -{ - QString tmp = p_col.trimmed().toLower(); - if (tmp.startsWith('#')) { - QColor col(tmp); - int r, g, b; - col.getRgb(&r, &g, &b); - return QString("rgb(%1, %2, %3)").arg(r).arg(g).arg(b); - } else { - return tmp; - } -} - -VPaletteMetaData VPalette::getPaletteMetaData(const QString &p_paletteFile) -{ - VPaletteMetaData data; - - QSettings settings(p_paletteFile, QSettings::IniFormat); - QDir dir(VUtils::basePathFromPath(QFileInfo(p_paletteFile).absoluteFilePath())); - - settings.beginGroup("metadata"); - data.m_version = settings.value("version").toInt(); - - QString val = settings.value("qss_file").toString(); - if (!val.isEmpty()) { - data.m_qssFile = dir.filePath(val); - } - - val = settings.value("mdhl_file").toString(); - if (!val.isEmpty()) { - data.m_mdhlFile = dir.filePath(val); - } - - val = settings.value("css_file").toString(); - if (!val.isEmpty()) { - data.m_cssFile = dir.filePath(val); - } - - val = settings.value("codeblock_css_file").toString(); - if (!val.isEmpty()) { - data.m_codeBlockCssFile = dir.filePath(val); - } - - val = settings.value("mermaid_css_file").toString(); - if (!val.isEmpty()) { - data.m_mermaidCssFile = dir.filePath(val); - } - - QStringList mapping = settings.value("css_color_mapping").toStringList(); - if (!mapping.isEmpty()) { - for (auto const & m : mapping) { - QStringList vals = m.split(':'); - if (vals.size() != 2) { - continue; - } - - // Translate the #aabbcc into rgb(aa, bb, cc) format. - data.m_colorMapping.insert(translateColorValue(vals[0]), - translateColorValue(vals[1])); - } - } - - settings.endGroup(); - - return data; -} - -QString VPalette::themeName(const QString &p_paletteFile) -{ - return QFileInfo(p_paletteFile).completeBaseName(); -} - -QString VPalette::themeEditorStyle(const QString &p_paletteFile) -{ - VPaletteMetaData data = getPaletteMetaData(p_paletteFile); - return themeName(p_paletteFile) + "/" + QFileInfo(data.m_mdhlFile).completeBaseName(); -} - -QString VPalette::themeCssStyle(const QString &p_paletteFile) -{ - VPaletteMetaData data = getPaletteMetaData(p_paletteFile); - return themeName(p_paletteFile) + "/" + QFileInfo(data.m_cssFile).completeBaseName(); -} - -QString VPalette::themeCodeBlockCssStyle(const QString &p_paletteFile) -{ - VPaletteMetaData data = getPaletteMetaData(p_paletteFile); - return themeName(p_paletteFile) + "/" + QFileInfo(data.m_codeBlockCssFile).completeBaseName(); -} - -int VPalette::getPaletteVersion(const QString &p_paletteFile) -{ - return getPaletteMetaData(p_paletteFile).m_version; -} - -void VPalette::fillFontFamily(QString &p_text) const -{ - QRegExp reg("(\\s|^)font-family:([^;]+);"); - - int pos = 0; - while (pos < p_text.size()) { - int idx = p_text.indexOf(reg, pos); - if (idx == -1) { - break; - } - - QString familyList = reg.cap(2).trimmed(); - familyList.remove('"'); - QString family = VUtils::getAvailableFontFamily(familyList.split(',')); - if (!family.isEmpty() && family != familyList) { - if (family.contains(' ')) { - family = "\"" + family + "\""; - } - - QString str = QString("%1font-family: %2;").arg(reg.cap(1)).arg(family); - p_text.replace(idx, reg.matchedLength(), str); - - pos = idx + str.size(); - } else { - pos = idx + reg.matchedLength(); - } - } -} - -void VPalette::fillScaledSize(QString &p_text) const -{ - // Cap(2) is the sign. - // Cap(3) is the number string. - QRegExp reg("(\\s|:)\\$([+-]?)(\\d+)(?=\\D)"); - const qreal factor = VUtils::calculateScaleFactor(); - - int pos = 0; - while (pos < p_text.size()) { - int idx = p_text.indexOf(reg, pos); - if (idx == -1) { - break; - } - - QString str = reg.cap(3); - bool ok; - int val = str.toInt(&ok); - if (!ok) { - pos = idx + reg.matchedLength(); - continue; - } - - val = val * factor + 0.5; - QString newStr = QString("%1%2%3").arg(reg.cap(1)).arg(reg.cap(2)).arg(val); - p_text.replace(idx, reg.matchedLength(), newStr); - pos = idx + newStr.size(); - } -} diff --git a/src/vpalette.h b/src/vpalette.h deleted file mode 100644 index 56bc848a..00000000 --- a/src/vpalette.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef VPALETTE_H -#define VPALETTE_H - -#include -#include -#include - -class QSettings; - -struct VPaletteMetaData -{ - int m_version; - - // These are all file PATH, not name. - QString m_qssFile; - QString m_mdhlFile; - QString m_cssFile; - QString m_codeBlockCssFile; - QString m_mermaidCssFile; - - // Color mapping when copied. - // All lower-case. - QHash m_colorMapping; - - QString toString() const - { - return QString("palette metadata version=%1 qss=%2 mdhl=%3 css=%4 " - "codeBlockCss=%5 mermaidCss=%6 colorMappingSize=%7") - .arg(m_version) - .arg(m_qssFile) - .arg(m_mdhlFile) - .arg(m_cssFile) - .arg(m_codeBlockCssFile) - .arg(m_mermaidCssFile) - .arg(m_colorMapping.size()); - } -}; - - -class VPalette -{ -public: - explicit VPalette(const QString &p_file); - - QString color(const QString &p_name) const; - - // Read QSS file. - QString fetchQtStyleSheet() const; - - // Fill "@xxx" in @p_text with corresponding style. - void fillStyle(QString &p_text) const; - - // Fill "$xxx" in @p_text with scaled num. - void fillScaledSize(QString &p_text) const; - - // QSS seems not to recognize multiple font-family values. - // We will choose the first existing one. - void fillFontFamily(QString &p_text) const; - - const QHash &getColorMapping() const; - - // Read themes and return the mappings of editor styles. - static QMap editorStylesFromThemes(const QList &p_themeFiles); - - // Read themes and return the mappings of css styles. - static QMap cssStylesFromThemes(const QList &p_themeFiles); - - // Read themes and return the mappings of css styles. - static QMap codeBlockCssStylesFromThemes(const QList &p_themeFiles); - - static int getPaletteVersion(const QString &p_paletteFile); - - static VPaletteMetaData getPaletteMetaData(const QString &p_paletteFile); - - // Return the name of the theme. - static QString themeName(const QString &p_paletteFile); - - // Return the name of the editor style of the theme. - static QString themeEditorStyle(const QString &p_paletteFile); - - // Return the name of the css style of the theme. - static QString themeCssStyle(const QString &p_paletteFile); - - // Return the name of the css style of the theme. - static QString themeCodeBlockCssStyle(const QString &p_paletteFile); - -private: - void init(const QString &p_file); - - void initPaleteFromSettings(QSettings *p_settings, const QString &p_group); - - void fillAbsoluteUrl(QString &p_style) const; - - // File path of the palette file. - QString m_file; - - QHash m_palette; - - VPaletteMetaData m_data; -}; - -inline const QHash &VPalette::getColorMapping() const -{ - return m_data.m_colorMapping; -} - -#endif // VPALETTE_H diff --git a/src/vplaintextedit.cpp b/src/vplaintextedit.cpp deleted file mode 100644 index 6f6c5211..00000000 --- a/src/vplaintextedit.cpp +++ /dev/null @@ -1,601 +0,0 @@ -#include "vplaintextedit.h" - -#include -#include -#include -#include -#include -#include - -#include "vimageresourcemanager.h" - - -const int VPlainTextEdit::c_minimumImageWidth = 100; - -enum class BlockState -{ - Normal = 0, - CodeBlockStart, - CodeBlock, - CodeBlockEnd, - Comment -}; - - -VPlainTextEdit::VPlainTextEdit(QWidget *p_parent) - : QPlainTextEdit(p_parent), - m_imageMgr(NULL), - m_blockImageEnabled(false), - m_imageWidthConstrainted(false), - m_maximumImageWidth(INT_MAX) -{ - init(); -} - -VPlainTextEdit::VPlainTextEdit(const QString &p_text, QWidget *p_parent) - : QPlainTextEdit(p_text, p_parent), - m_imageMgr(NULL), - m_blockImageEnabled(false), - m_imageWidthConstrainted(false), - m_maximumImageWidth(INT_MAX) -{ - init(); -} - -VPlainTextEdit::~VPlainTextEdit() -{ - if (m_imageMgr) { - delete m_imageMgr; - } -} - -void VPlainTextEdit::init() -{ - m_lineNumberType = LineNumberType::None; - - m_imageMgr = new VImageResourceManager(); - - QTextDocument *doc = document(); - QPlainTextDocumentLayout *layout = new VPlainTextDocumentLayout(doc, - m_imageMgr, - m_blockImageEnabled); - doc->setDocumentLayout(layout); - - m_lineNumberArea = new VLineNumberArea(this, - document(), - fontMetrics().width(QLatin1Char('8')), - this); - connect(document(), &QTextDocument::blockCountChanged, - this, &VPlainTextEdit::updateLineNumberAreaMargin); - connect(this, &QPlainTextEdit::textChanged, - this, &VPlainTextEdit::updateLineNumberArea); - connect(verticalScrollBar(), &QScrollBar::valueChanged, - this, &VPlainTextEdit::updateLineNumberArea); - connect(this, &QPlainTextEdit::cursorPositionChanged, - this, &VPlainTextEdit::updateLineNumberArea); -} - -void VPlainTextEdit::updateBlockImages(const QVector &p_blocksInfo) -{ - if (m_blockImageEnabled) { - m_imageMgr->updateBlockInfos(p_blocksInfo, m_maximumImageWidth); - - update(); - } -} - -void VPlainTextEdit::clearBlockImages() -{ - m_imageMgr->clear(); -} - -bool VPlainTextEdit::containsImage(const QString &p_imageName) const -{ - return m_imageMgr->contains(p_imageName); -} - -void VPlainTextEdit::addImage(const QString &p_imageName, const QPixmap &p_image) -{ - if (m_blockImageEnabled) { - m_imageMgr->addImage(p_imageName, p_image); - } -} - -static void fillBackground(QPainter *p, - const QRectF &rect, - QBrush brush, - const QRectF &gradientRect = QRectF()) -{ - p->save(); - if (brush.style() >= Qt::LinearGradientPattern - && brush.style() <= Qt::ConicalGradientPattern) { - if (!gradientRect.isNull()) { - QTransform m = QTransform::fromTranslate(gradientRect.left(), - gradientRect.top()); - m.scale(gradientRect.width(), - gradientRect.height()); - brush.setTransform(m); - const_cast(brush.gradient())->setCoordinateMode(QGradient::LogicalMode); - } - } else { - p->setBrushOrigin(rect.topLeft()); - } - - p->fillRect(rect, brush); - p->restore(); -} - -void VPlainTextEdit::paintEvent(QPaintEvent *p_event) -{ - QPainter painter(viewport()); - QPointF offset(contentOffset()); - - QRect er = p_event->rect(); - QRect viewportRect = viewport()->rect(); - - bool editable = !isReadOnly(); - - QTextBlock block = firstVisibleBlock(); - qreal maximumWidth = document()->documentLayout()->documentSize().width(); - - // Set a brush origin so that the WaveUnderline knows where the wave started. - painter.setBrushOrigin(offset); - - // Keep right margin clean from full-width selection. - int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth) - - document()->documentMargin(); - er.setRight(qMin(er.right(), maxX)); - painter.setClipRect(er); - - QAbstractTextDocumentLayout::PaintContext context = getPaintContext(); - - while (block.isValid()) { - QRectF r = blockBoundingRect(block).translated(offset); - QTextLayout *layout = block.layout(); - - if (!block.isVisible()) { - offset.ry() += r.height(); - block = block.next(); - continue; - } - - if (r.bottom() >= er.top() && r.top() <= er.bottom()) { - QTextBlockFormat blockFormat = block.blockFormat(); - QBrush bg = blockFormat.background(); - if (bg != Qt::NoBrush) { - QRectF contentsRect = r; - contentsRect.setWidth(qMax(r.width(), maximumWidth)); - fillBackground(&painter, contentsRect, bg); - } - - QVector selections; - int blpos = block.position(); - int bllen = block.length(); - for (int i = 0; i < context.selections.size(); ++i) { - const QAbstractTextDocumentLayout::Selection &range = context.selections.at(i); - const int selStart = range.cursor.selectionStart() - blpos; - const int selEnd = range.cursor.selectionEnd() - blpos; - if (selStart < bllen - && selEnd > 0 - && selEnd > selStart) { - QTextLayout::FormatRange o; - o.start = selStart; - o.length = selEnd - selStart; - o.format = range.format; - selections.append(o); - } else if (!range.cursor.hasSelection() - && range.format.hasProperty(QTextFormat::FullWidthSelection) - && block.contains(range.cursor.position())) { - // For full width selections we don't require an actual selection, just - // a position to specify the line. That's more convenience in usage. - QTextLayout::FormatRange o; - QTextLine l = layout->lineForTextPosition(range.cursor.position() - blpos); - o.start = l.textStart(); - o.length = l.textLength(); - if (o.start + o.length == bllen - 1) { - ++o.length; // include newline - } - - o.format = range.format; - selections.append(o); - } - } - - bool drawCursor = (editable - || (textInteractionFlags() & Qt::TextSelectableByKeyboard)) - && context.cursorPosition >= blpos - && context.cursorPosition < blpos + bllen; - - bool drawCursorAsBlock = drawCursor && overwriteMode() ; - if (drawCursorAsBlock) { - if (context.cursorPosition == blpos + bllen - 1) { - drawCursorAsBlock = false; - } else { - QTextLayout::FormatRange o; - o.start = context.cursorPosition - blpos; - o.length = 1; - o.format.setForeground(palette().base()); - o.format.setBackground(palette().text()); - selections.append(o); - } - } - - if (!placeholderText().isEmpty() - && document()->isEmpty() - && layout->preeditAreaText().isEmpty()) { - QColor col = palette().text().color(); - col.setAlpha(128); - painter.setPen(col); - const int margin = int(document()->documentMargin()); - painter.drawText(r.adjusted(margin, 0, 0, 0), - Qt::AlignTop | Qt::TextWordWrap, - placeholderText()); - } else { - layout->draw(&painter, offset, selections, er); - } - - if ((drawCursor && !drawCursorAsBlock) - || (editable - && context.cursorPosition < -1 - && !layout->preeditAreaText().isEmpty())) { - int cpos = context.cursorPosition; - if (cpos < -1) { - cpos = layout->preeditAreaPosition() - (cpos + 2); - } else { - cpos -= blpos; - } - - layout->drawCursor(&painter, offset, cpos, cursorWidth()); - } - - // Draw preview image of this block if there is one. - drawImageOfBlock(block, &painter, r); - } - - offset.ry() += r.height(); - if (offset.y() > viewportRect.height()) { - break; - } - - block = block.next(); - } - - if (backgroundVisible() - && !block.isValid() - && offset.y() <= er.bottom() - && (centerOnScroll() - || verticalScrollBar()->maximum() == verticalScrollBar()->minimum())) { - painter.fillRect(QRect(QPoint((int)er.left(), - (int)offset.y()), - er.bottomRight()), - palette().background()); - } -} - -void VPlainTextEdit::drawImageOfBlock(const QTextBlock &p_block, - QPainter *p_painter, - const QRectF &p_blockRect) -{ - if (!m_blockImageEnabled) { - return; - } - - const VBlockImageInfo *info = m_imageMgr->findImageInfoByBlock(p_block.blockNumber()); - if (!info) { - return; - } - - const QPixmap *image = m_imageMgr->findImage(info->m_imageName); - if (!image) { - return; - } - - int oriHeight = originalBlockBoundingRect(p_block).height(); - bool noMargin = (info->m_margin + info->m_imageWidth > m_maximumImageWidth); - int margin = noMargin ? 0 : info->m_margin; - QRect tmpRect(p_blockRect.toRect()); - QRect targetRect(tmpRect.x() + margin, - tmpRect.y() + oriHeight, - info->m_imageWidth, - qMax(info->m_imageHeight, tmpRect.height() - oriHeight)); - - p_painter->drawPixmap(targetRect, *image); - - auto *layout = getLayout(); - emit layout->documentSizeChanged(layout->documentSize()); -} - -QRectF VPlainTextEdit::originalBlockBoundingRect(const QTextBlock &p_block) const -{ - return getLayout()->QPlainTextDocumentLayout::blockBoundingRect(p_block); -} - -void VPlainTextEdit::setBlockImageEnabled(bool p_enabled) -{ - if (m_blockImageEnabled == p_enabled) { - return; - } - - m_blockImageEnabled = p_enabled; - if (!p_enabled) { - clearBlockImages(); - } - - getLayout()->setBlockImageEnabled(m_blockImageEnabled); -} - -void VPlainTextEdit::setImageWidthConstrainted(bool p_enabled) -{ - m_imageWidthConstrainted = p_enabled; - - updateImageWidth(); - - auto *layout = getLayout(); - emit layout->documentSizeChanged(layout->documentSize()); -} - -void VPlainTextEdit::updateImageWidth() -{ - bool needUpdate = false; - if (m_imageWidthConstrainted) { - int viewWidth = viewport()->size().width(); - m_maximumImageWidth = viewWidth - 10; - if (m_maximumImageWidth < 0) { - m_maximumImageWidth = viewWidth; - } - - needUpdate = true; - } else if (m_maximumImageWidth != INT_MAX) { - needUpdate = true; - m_maximumImageWidth = INT_MAX; - } - - if (needUpdate) { - m_imageMgr->updateImageWidth(m_maximumImageWidth); - } -} - -void VPlainTextEdit::resizeEvent(QResizeEvent *p_event) -{ - updateImageWidth(); - - QPlainTextEdit::resizeEvent(p_event); - - if (m_lineNumberType != LineNumberType::None) { - QRect rect = contentsRect(); - m_lineNumberArea->setGeometry(QRect(rect.left(), - rect.top(), - m_lineNumberArea->calculateWidth(), - rect.height())); - } -} - -void VPlainTextEdit::paintLineNumberArea(QPaintEvent *p_event) -{ - if (m_lineNumberType == LineNumberType::None) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - return; - } - - QPainter painter(m_lineNumberArea); - painter.fillRect(p_event->rect(), m_lineNumberArea->getBackgroundColor()); - - QTextBlock block = firstVisibleBlock(); - if (!block.isValid()) { - return; - } - - int blockNumber = block.blockNumber(); - QRectF rect = blockBoundingGeometry(block); - int top = (int)(contentOffset().y() + rect.y()); - int bottom = top + (int)rect.height(); - int eventTop = p_event->rect().top(); - int eventBtm = p_event->rect().bottom(); - const int digitHeight = painter.fontMetrics().height(); - const int curBlockNumber = textCursor().block().blockNumber(); - painter.setPen(m_lineNumberArea->getForegroundColor()); - - // Display line number only in code block. - if (m_lineNumberType == LineNumberType::CodeBlock) { - int number = 0; - while (block.isValid() && top <= eventBtm) { - int blockState = block.userState(); - switch (blockState) { - case (int)BlockState::CodeBlockStart: - Q_ASSERT(number == 0); - number = 1; - break; - - case (int)BlockState::CodeBlockEnd: - number = 0; - break; - - case (int)BlockState::CodeBlock: - if (number == 0) { - // Need to find current line number in code block. - QTextBlock startBlock = block.previous(); - while (startBlock.isValid()) { - if (startBlock.userState() == (int)BlockState::CodeBlockStart) { - number = block.blockNumber() - startBlock.blockNumber(); - break; - } - - startBlock = startBlock.previous(); - } - } - - break; - - default: - break; - } - - if (blockState == (int)BlockState::CodeBlock) { - if (block.isVisible() && bottom >= eventTop) { - QString numberStr = QString::number(number); - painter.drawText(0, - top, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - } - - ++number; - } - - block = block.next(); - top = bottom; - bottom = top + (int)blockBoundingRect(block).height(); - } - - return; - } - - // Handle m_lineNumberType 1 and 2. - Q_ASSERT(m_lineNumberType == LineNumberType::Absolute - || m_lineNumberType == LineNumberType::Relative); - while (block.isValid() && top <= eventBtm) { - if (block.isVisible() && bottom >= eventTop) { - bool currentLine = false; - int number = blockNumber + 1; - if (m_lineNumberType == LineNumberType::Relative) { - number = blockNumber - curBlockNumber; - if (number == 0) { - currentLine = true; - number = blockNumber + 1; - } else if (number < 0) { - number = -number; - } - } else if (blockNumber == curBlockNumber) { - currentLine = true; - } - - QString numberStr = QString::number(number); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(true); - painter.setFont(font); - } - - painter.drawText(0, - top, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight, - numberStr); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(false); - painter.setFont(font); - } - } - - block = block.next(); - top = bottom; - bottom = top + (int)blockBoundingRect(block).height(); - ++blockNumber; - } - -} - -VPlainTextDocumentLayout *VPlainTextEdit::getLayout() const -{ - return qobject_cast(document()->documentLayout()); -} - -void VPlainTextEdit::updateLineNumberAreaMargin() -{ - int width = 0; - if (m_lineNumberType != LineNumberType::None) { - width = m_lineNumberArea->calculateWidth(); - } - - if (width != viewportMargins().left()) { - setViewportMargins(width, 0, 0, 0); - } -} - -void VPlainTextEdit::updateLineNumberArea() -{ - if (m_lineNumberType != LineNumberType::None) { - if (!m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->show(); - } - - m_lineNumberArea->update(); - } else if (m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - } -} - -VPlainTextDocumentLayout::VPlainTextDocumentLayout(QTextDocument *p_document, - VImageResourceManager *p_imageMgr, - bool p_blockImageEnabled) - : QPlainTextDocumentLayout(p_document), - m_imageMgr(p_imageMgr), - m_blockImageEnabled(p_blockImageEnabled), - m_maximumImageWidth(INT_MAX) -{ -} - -QRectF VPlainTextDocumentLayout::blockBoundingRect(const QTextBlock &p_block) const -{ - QRectF br = QPlainTextDocumentLayout::blockBoundingRect(p_block); - if (!m_blockImageEnabled) { - return br; - } - - const VBlockImageInfo *info = m_imageMgr->findImageInfoByBlock(p_block.blockNumber()); - if (info) { - int tmp = info->m_margin + info->m_imageWidth; - if (tmp > m_maximumImageWidth) { - Q_ASSERT(info->m_imageWidth <= m_maximumImageWidth); - tmp = info->m_imageWidth; - } - - qreal width = (qreal)(tmp); - qreal dw = width > br.width() ? width - br.width() : 0; - qreal dh = (qreal)info->m_imageHeight; - - br.adjust(0, 0, dw, dh); - } - - return br; -} - -QRectF VPlainTextDocumentLayout::frameBoundingRect(QTextFrame *p_frame) const -{ - QRectF fr = QPlainTextDocumentLayout::frameBoundingRect(p_frame); - if (!m_blockImageEnabled) { - return fr; - } - - qreal imageWidth = (qreal)m_imageMgr->getMaximumImageWidth(); - qreal dw = imageWidth - fr.width(); - if (dw > 0) { - fr.adjust(0, 0, dw, 0); - } - - return fr; -} - -QSizeF VPlainTextDocumentLayout::documentSize() const -{ - QSizeF si = QPlainTextDocumentLayout::documentSize(); - if (!m_blockImageEnabled) { - return si; - } - - qreal imageWidth = (qreal)m_imageMgr->getMaximumImageWidth(); - if (imageWidth > si.width()) { - si.setWidth(imageWidth); - } - - return si; -} diff --git a/src/vplaintextedit.h b/src/vplaintextedit.h deleted file mode 100644 index 143784a3..00000000 --- a/src/vplaintextedit.h +++ /dev/null @@ -1,191 +0,0 @@ -#ifndef VPLAINTEXTEDIT_H -#define VPLAINTEXTEDIT_H - -#include -#include -#include - -#include "vlinenumberarea.h" - -class QTextDocument; -class VImageResourceManager; -class QPaintEvent; -class QPainter; -class QResizeEvent; -class VPlainTextDocumentLayout; - - -struct VBlockImageInfo -{ -public: - VBlockImageInfo() - : m_blockNumber(-1), m_margin(0), m_imageWidth(0), m_imageHeight(0) - { - } - - VBlockImageInfo(int p_blockNumber, - const QString &p_imageName, - int p_margin = 0) - : m_blockNumber(p_blockNumber), - m_imageName(p_imageName), - m_margin(p_margin), - m_imageWidth(0), - m_imageHeight(0) - { - } - - // Block number. - int m_blockNumber; - - // The name of the image corresponding to this block. - QString m_imageName; - - // Left margin of the image. - int m_margin; - -private: - // Width and height of the image display. - int m_imageWidth; - int m_imageHeight; - - friend class VImageResourceManager; - friend class VPlainTextEdit; - friend class VPlainTextDocumentLayout; -}; - - -class VPlainTextEdit : public QPlainTextEdit, public VTextEditWithLineNumber -{ - Q_OBJECT -public: - explicit VPlainTextEdit(QWidget *p_parent = nullptr); - - explicit VPlainTextEdit(const QString &p_text, QWidget *p_parent = nullptr); - - virtual ~VPlainTextEdit(); - - // Update images of these given blocks. - // Images of blocks not given here will be clear. - void updateBlockImages(const QVector &p_blocksInfo); - - void clearBlockImages(); - - // Whether the resoruce manager contains image of name @p_imageName. - bool containsImage(const QString &p_imageName) const; - - // Add an image to the resources. - void addImage(const QString &p_imageName, const QPixmap &p_image); - - void setBlockImageEnabled(bool p_enabled); - - void setImageWidthConstrainted(bool p_enabled); - - void paintLineNumberArea(QPaintEvent *p_event) Q_DECL_OVERRIDE; - - void setLineNumberType(LineNumberType p_type); - - void setLineNumberColor(const QColor &p_foreground, const QColor &p_background); - - // The minimum width of an image in pixels. - static const int c_minimumImageWidth; - -protected: - // Most logics are copied from QPlainTextEdit. - // Differences: draw images for blocks with preview image. - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE; - - void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - // Update viewport margin to hold the line number area. - void updateLineNumberAreaMargin(); - - void updateLineNumberArea(); - -private: - void init(); - - // @p_blockRect: the content rect of @p_block. - void drawImageOfBlock(const QTextBlock &p_block, - QPainter *p_painter, - const QRectF &p_blockRect); - - QRectF originalBlockBoundingRect(const QTextBlock &p_block) const; - - VPlainTextDocumentLayout *getLayout() const; - - void updateImageWidth(); - - // Widget to display line number area. - VLineNumberArea *m_lineNumberArea; - - VImageResourceManager *m_imageMgr; - - bool m_blockImageEnabled; - - // Whether constraint the width of image to the width of the viewport. - bool m_imageWidthConstrainted; - - // Maximum width of the images. - int m_maximumImageWidth; - - LineNumberType m_lineNumberType; -}; - - -class VPlainTextDocumentLayout : public QPlainTextDocumentLayout -{ - Q_OBJECT -public: - explicit VPlainTextDocumentLayout(QTextDocument *p_document, - VImageResourceManager *p_imageMgr, - bool p_blockImageEnabled = false); - - // Will adjust the rect if there is an image for this block. - QRectF blockBoundingRect(const QTextBlock &p_block) const Q_DECL_OVERRIDE; - - QRectF frameBoundingRect(QTextFrame *p_frame) const Q_DECL_OVERRIDE; - - QSizeF documentSize() const Q_DECL_OVERRIDE; - - void setBlockImageEnabled(bool p_enabled); - - void setMaximumImageWidth(int p_width); - -private: - VImageResourceManager *m_imageMgr; - - bool m_blockImageEnabled; - - int m_maximumImageWidth; -}; - -inline void VPlainTextDocumentLayout::setBlockImageEnabled(bool p_enabled) -{ - m_blockImageEnabled = p_enabled; -} - -inline void VPlainTextDocumentLayout::setMaximumImageWidth(int p_width) -{ - m_maximumImageWidth = p_width; -} - -inline void VPlainTextEdit::setLineNumberType(LineNumberType p_type) -{ - if (p_type == m_lineNumberType) { - return; - } - - m_lineNumberType = p_type; - - updateLineNumberArea(); -} - -inline void VPlainTextEdit::setLineNumberColor(const QColor &p_foreground, - const QColor &p_background) -{ - m_lineNumberArea->setForegroundColor(p_foreground); - m_lineNumberArea->setBackgroundColor(p_background); -} - -#endif // VPLAINTEXTEDIT_H diff --git a/src/vplantumlhelper.cpp b/src/vplantumlhelper.cpp deleted file mode 100644 index 7e30ebe1..00000000 --- a/src/vplantumlhelper.cpp +++ /dev/null @@ -1,1132 +0,0 @@ -#include "vplantumlhelper.h" - -#include -#include - -#include "vconfigmanager.h" -#include "utils/vprocessutils.h" - -extern VConfigManager *g_config; - -#define TaskIdProperty "PlantUMLTaskId" -#define TaskFormatProperty "PlantUMLTaskFormat" -#define TaskTimeStampProperty "PlantUMLTaskTimeStamp" - -VPlantUMLHelper::VPlantUMLHelper(QObject *p_parent) - : QObject(p_parent) -{ - m_customCmd = g_config->getPlantUMLCmd(); - if (m_customCmd.isEmpty()) { - prepareCommand(m_program, m_args); - } -} - -VPlantUMLHelper::VPlantUMLHelper(const QString &p_jar, QObject *p_parent) - : QObject(p_parent) -{ - m_customCmd = g_config->getPlantUMLCmd(); - if (m_customCmd.isEmpty()) { - prepareCommand(m_program, m_args, p_jar); - } -} - -void VPlantUMLHelper::processAsync(int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QString &p_text) -{ - QProcess *process = new QProcess(this); - process->setProperty(TaskIdProperty, p_id); - process->setProperty(TaskTimeStampProperty, p_timeStamp); - process->setProperty(TaskFormatProperty, p_format); - connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), - this, SLOT(handleProcessFinished(int, QProcess::ExitStatus))); - - if (m_customCmd.isEmpty()) { - QStringList args(m_args); - args << ("-t" + p_format); - qDebug() << m_program << args; - process->start(m_program, refineArgsForUse(args)); - } else { - QString cmd(m_customCmd); - cmd.replace("%0", p_format); - qDebug() << cmd; - process->start(cmd); - } - - if (process->write(p_text.toUtf8()) == -1) { - qWarning() << "fail to write to QProcess:" << process->errorString(); - } - - process->closeWriteChannel(); -} - -void VPlantUMLHelper::prepareCommand(QString &p_program, - QStringList &p_args, - const QString &p_jar) const -{ -#if defined(Q_OS_WIN) - p_program = "java"; -#else - p_program = "/bin/sh"; - p_args << "-c"; - p_args << "java"; -#endif - - p_args << "-Djava.awt.headless=true -jar" << (p_jar.isEmpty() ? g_config->getPlantUMLJar() : p_jar); - p_args << "-charset" << "UTF-8"; - - /* - int nbthread = QThread::idealThreadCount(); - p_args << "-nbthread" << QString::number(nbthread > 0 ? nbthread : 1); - */ - - const QString &dot = g_config->getGraphvizDot(); - if (!dot.isEmpty()) { - p_args << "-graphvizdot"; - p_args << dot; - } - - p_args << "-pipe"; - p_args << g_config->getPlantUMLArgs(); -} - -void VPlantUMLHelper::handleProcessFinished(int p_exitCode, QProcess::ExitStatus p_exitStatus) -{ - QProcess *process = static_cast(sender()); - int id = process->property(TaskIdProperty).toInt(); - QString format = process->property(TaskFormatProperty).toString(); - TimeStamp timeStamp = process->property(TaskTimeStampProperty).toULongLong(); - qDebug() << QString("PlantUML finished: id %1 timestamp %2 format %3 exitcode %4 exitstatus %5") - .arg(id) - .arg(timeStamp) - .arg(format) - .arg(p_exitCode) - .arg(p_exitStatus); - bool failed = true; - if (p_exitStatus == QProcess::NormalExit) { - if (p_exitCode < 0) { - qWarning() << "PlantUML fail" << p_exitCode; - } else { - failed = false; - QByteArray outBa = process->readAllStandardOutput(); - if (format == "svg") { - emit resultReady(id, timeStamp, format, QString::fromLocal8Bit(outBa)); - } else { - emit resultReady(id, timeStamp, format, QString::fromLocal8Bit(outBa.toBase64())); - } - } - } else { - qWarning() << "fail to start PlantUML process" << p_exitCode << p_exitStatus; - } - - QByteArray errBa = process->readAllStandardError(); - if (!errBa.isEmpty()) { - QString errStr(QString::fromLocal8Bit(errBa)); - if (failed) { - qWarning() << "PlantUML stderr:" << errStr; - } else { - qDebug() << "PlantUML stderr:" << errStr; - } - } - - if (failed) { - emit resultReady(id, timeStamp, format, ""); - } - - process->deleteLater(); -} - -bool VPlantUMLHelper::testPlantUMLJar(const QString &p_jar, QString &p_msg) -{ - VPlantUMLHelper inst(p_jar); - QStringList args(inst.m_args); - args << "-tsvg"; - args = refineArgsForUse(args); - - QString testGraph("VNote->Markdown : hello"); - - int exitCode = -1; - QByteArray out, err; - int ret = VProcessUtils::startProcess(inst.m_program, - args, - testGraph.toUtf8(), - exitCode, - out, - err); - - p_msg = QString("Command: %1 %2\nExitCode: %3\nOutput: %4\nError: %5") - .arg(inst.m_program) - .arg(args.join(' ')) - .arg(exitCode) - .arg(QString::fromLocal8Bit(out)) - .arg(QString::fromLocal8Bit(err)); - - return ret == 0 && exitCode == 0; -} - -QByteArray VPlantUMLHelper::process(const QString &p_format, const QString &p_text) -{ - VPlantUMLHelper inst; - - int exitCode = -1; - QByteArray out, err; - int ret = -1; - if (inst.m_customCmd.isEmpty()) { - QStringList args(inst.m_args); - args << ("-t" + p_format); - args = refineArgsForUse(args); - ret = VProcessUtils::startProcess(inst.m_program, - args, - p_text.toUtf8(), - exitCode, - out, - err); - } else { - QString cmd(inst.m_customCmd); - cmd.replace("%0", p_format); - ret = VProcessUtils::startProcess(cmd, - p_text.toUtf8(), - exitCode, - out, - err); - } - - if (ret != 0 || exitCode < 0) { - qWarning() << "PlantUML fail" << ret << exitCode << QString::fromLocal8Bit(err); - } - - return out; -} - -static bool tryKeywords(QString &p_keyword, bool &p_needCreole) -{ - // start, stop, end, endif, repeat, fork, fork again, end fork, }, - // detach, end note, end box, endrnote, endhnote, - // top to bottom direction, left to right direction, - // @startuml, @enduml - // ||, --, title, end title, end legend - static QRegExp keywords("^\\s*(?:start|stop|end|endif|repeat|" - "fork(?:\\s+again)?|end\\s+fork|\\}|detach|" - "end ?(?:note|box)|endrnote|endhnote|" - "top\\s+to\\s+bottom\\s+direction|" - "left\\s+to\\s+right\\s+direction|" - "@startuml|@enduml|" - "--|\\|\\||(?:end\\s+)?title|end\\s+legend)\\s*$"); - if (keywords.indexIn(p_keyword) >= 0) { - p_keyword.clear(); - return true; - } - - // Comments. - static QRegExp comment("^\\s*'"); - if (comment.indexIn(p_keyword) >= 0) { - p_keyword.clear(); - return true; - } - - // scale 1.5 - static QRegExp scale("^\\s*scale\\s+\\w+"); - if (scale.indexIn(p_keyword) >= 0) { - p_keyword.clear(); - return true; - } - - // title - // caption - static QRegExp title("^\\s*(?:title|caption)\\s+(.+)"); - if (title.indexIn(p_keyword) >= 0) { - p_keyword = title.cap(1).trimmed(); - p_needCreole = true; - return true; - } - - // legend right - static QRegExp legend("^\\s*legend(?:\\s+(?:left|right|center))?"); - if (legend.indexIn(p_keyword) >= 0) { - p_keyword.clear(); - return true; - } - - return false; -} - -static bool tryClassDiagram(QString &p_keyword, QString &p_hints, bool &p_isRegex, bool &p_needCreole) -{ - Q_UNUSED(p_isRegex); - - // class ABC #Pink - // interface conflicts with component diagram, so it is removed from here. - static QRegExp classDef1("^\\s*(?:class|(?:abstract(?:\\s+class)?)|annotation|enum)\\s+" - "(?!class)(\\w+)"); - if (classDef1.indexIn(p_keyword) >= 0) { - p_keyword = classDef1.cap(1); - p_hints = "id"; - return true; - } - - // class "ABC DEF" as AD #Pink - static QRegExp classDef2("^\\s*(?:class|(?:abstract(?:\\s+class)?)|annotation|enum)\\s+" - "\"([^\"]+)\"\\s*(?:\\bas\\s+(\\w+))?"); - if (classDef2.indexIn(p_keyword) >= 0) { - if (classDef2.cap(2).isEmpty()) { - p_keyword = classDef2.cap(1).trimmed(); - } else { - p_keyword = classDef2.cap(2); - } - p_hints = "id"; - return true; - } - - // class01 "1" *-- "many" class02 : contains 4 > - static QRegExp relation("^\\s*(?:(\\w+)|\"([^\"]+)\")\\s*" - "(?:\"[^\"]+\"\\s*)?" - "(?:<\\||[*o<#x}+^])?" "(?:-+|\\.+)" "(?:\\|>|[*o>#x{+^])?\\s*" - "(?:\"[^\"]+\"\\s*)?" - "(?:(\\w+)|\"([^\"]+)\")\\s*" - "(?::(.+))?"); - if (relation.indexIn(p_keyword) >= 0) { - if (relation.cap(5).isEmpty()) { - QString class2 = relation.cap(3); - if (class2.isEmpty()) { - class2 = relation.cap(4).trimmed(); - } - - p_keyword = class2; - p_hints = "id"; - } else { - p_needCreole = true; - p_keyword = relation.cap(5).trimmed(); - } - - return true; - } - - // {static} field : String - bool containsModifier = false; - static QRegExp modifier("\\{(?:static|abstract|classifier)\\}"); - if (modifier.indexIn(p_keyword) >= 0) { - containsModifier = true; - p_keyword.remove(modifier); - } - - // + field - static QRegExp member("^\\s*[-#~+]\\s*(.*)"); - if (member.indexIn(p_keyword) >= 0) { - p_keyword = member.cap(1).trimmed(); - return true; - } else if (containsModifier) { - p_keyword = p_keyword.trimmed(); - return true; - } - - // note left on link #Pink : message - // note left on link - // node on link: message - // MUST before next rule "note". - static QRegExp note4("^\\s*note\\s+(?:(?:left|top|right|bottom)\\s+)?" - "on\\s+link" - "[^:]*" - "(?::(.*))?"); - if (note4.indexIn(p_keyword) >= 0) { - p_needCreole = true; - p_keyword = note4.cap(1).trimmed(); - return true; - } - - // note top of Object #Pink : message - // note top of Object - // note top: message - // hnote and rnote for sequence diagram. - // note right of (use case) - // note right of [component] - static QRegExp note("^\\s*[hr]?note\\s+(?:left|top|right|bottom)" - "(?:\\s+of\\s+(?:(\\w+)|" - "\\(([^\\)]+)\\)|" - "\\[([^\\]]+)\\]))?" - "[^:]*" - "(?::(.*))?"); - if (note.indexIn(p_keyword) >= 0) { - p_keyword = note.cap(4).trimmed(); - if (p_keyword.isEmpty()) { - QString ent = note.cap(1); - if (ent.isEmpty()) { - ent = note.cap(2).trimmed(); - if (ent.isEmpty()) { - ent = note.cap(3).trimmed(); - } - - p_keyword = ent; - p_needCreole = true; - } else { - p_keyword = ent; - p_hints = "id"; - } - } else { - p_needCreole = true; - } - - return true; - } - - // note "a floating note" as N1 #Pink - // note as N1 - static QRegExp note2("^\\s*note\\s+(?:\"([^\"]*)\"\\s+)?as\\s+\\w+"); - if (note2.indexIn(p_keyword) >= 0) { - p_keyword = note2.cap(1).trimmed(); - return true; - } - - return false; -} - -static bool tryCommonElements(QString &p_keyword, QString &p_hints, bool &p_isRegex, bool &p_needCreole) -{ - Q_UNUSED(p_isRegex); - Q_UNUSED(p_hints); - Q_UNUSED(p_needCreole); - - // Words in quotes. - // cmf("abc") - static QRegExp quote("^[^\"]*\"([^\"]+)\"[^\"]*$"); - if (quote.indexIn(p_keyword) >= 0) { - p_keyword = quote.cap(1).trimmed(); - return true; - } - - return false; -} - -static bool tryActivityDiagram(QString &p_keyword, QString &p_hints, bool &p_isRegex, bool &p_needCreole) -{ - Q_UNUSED(p_isRegex); - Q_UNUSED(p_hints); - - // Activity. (Do not support color.) - // :Hello world; - // :Across multiple lines - static QRegExp activity1("^\\s*:([^:]+)\\s*$"); - if (activity1.indexIn(p_keyword) >= 0) { - p_keyword = activity1.cap(1).trimmed(); - if (!p_keyword.isEmpty()) { - QChar ch = p_keyword[p_keyword.size() - 1]; - if (ch == ';' || ch == '|' || ch == '<' || ch == '>' - || ch == '/' || ch == ']' || ch == '}') { - p_keyword = p_keyword.left(p_keyword.size() - 1); - } - } - - p_needCreole = true; - return true; - } - - // Activity. - // multiple lines; - static QRegExp activity2("^\\s*([^\\[]+)([;|<>/\\]}])\\s*$"); - if (activity2.indexIn(p_keyword) >= 0) { - QString word = activity2.cap(1); - QChar end = activity2.cap(2)[0]; - if (end != ';' && !word.isEmpty()) { - // || << >> // ]] }} are not legal. - if (word[word.size() - 1] == end) { - return false; - } - } - - // It may conflict with note. - p_needCreole = true; - p_keyword = word.trimmed(); - return true; - } - - // Conditionals. - // if (Graphviz) then (yes) - // else if (Graphviz) then (yes) - static QRegExp conIf("^\\s*(?:else)?if\\s+\\(([^\\)]+)\\)\\s+then(?:\\s+\\([^\\)]+\\))?\\s*$"); - if (conIf.indexIn(p_keyword) >= 0) { - p_keyword = conIf.cap(1).trimmed(); - return true; - } - - // else (no) - static QRegExp conElse("^\\s*else(?:\\s+\\(([^\\)]+)\\))?\\s*$"); - if (conElse.indexIn(p_keyword) >= 0) { - p_keyword = conElse.cap(1).trimmed(); - return true; - } - - // Repeat loop. - // repeat while (more data?) - static QRegExp repeat("^\\s*repeat\\s+while\\s+\\(([^\\)]+)\\)\\s*$"); - if (repeat.indexIn(p_keyword) >= 0) { - p_keyword = repeat.cap(1).trimmed(); - return true; - } - - // while (check?) is (not empty) - static QRegExp whileLoop("^\\s*while\\s+\\(([^\\)]+)\\)(?:\\s+is\\s+\\([^\\)]+\\))?\\s*$"); - if (whileLoop.indexIn(p_keyword) >= 0) { - p_keyword = whileLoop.cap(1).trimmed(); - return true; - } - - // endwhile (empty) - static QRegExp endWhile("^\\s*endwhile(?:\\s+\\(([^\\)]+)\\))?\\s*$"); - if (endWhile.indexIn(p_keyword) >= 0) { - p_keyword = endWhile.cap(1).trimmed(); - return true; - } - - // partition Running { - static QRegExp partition("^\\s*partition\\s+(\\w+)\\s+\\{\\s*$"); - if (partition.indexIn(p_keyword) >= 0) { - p_keyword = partition.cap(1).trimmed(); - return true; - } - - // |Swimlane1| - // |#Pink|Swimlane1| - static QRegExp swimline("^\\s*(?:\\|[^\\|]+)?\\|([^|]+)\\|\\s*$"); - if (swimline.indexIn(p_keyword) >= 0) { - p_keyword = swimline.cap(1).trimmed(); - return true; - } - - return false; -} - -static bool trySequenceDiagram(QString &p_keyword, QString &p_hints, bool &p_isRegex, bool &p_needCreole) -{ - Q_UNUSED(p_isRegex); - Q_UNUSED(p_hints); - - // participant ABC #Pink - // participant "ABC DEF" as AD #Pink - static QRegExp participant1("^\\s*(?:participant|actor|boundary|control|entity|database)\\s+" - "(?:(\\w+)|\"([^\"]+)\"\\s*(?:\\bas\\s+\\w+)?)"); - if (participant1.indexIn(p_keyword) >= 0) { - p_keyword = participant1.cap(1); - if (p_keyword.isEmpty()) { - p_keyword = participant1.cap(2).trimmed(); - } - - return true; - } - - // "abc" ->> "def" : Authentication - static QRegExp message("^\\s*(?:\\w+|\"[^\"]+\")\\s+" - "[-<>x\\\\/o]+\\s+" - "(?:\\w+|\"[^\"]+\")\\s*" - ":\\s*(.+)"); - if (message.indexIn(p_keyword) >= 0) { - p_needCreole = true; - p_keyword = message.cap(1).trimmed(); - return true; - } - - // autonumber - static QRegExp autonum("^\\s*autonumber\\s+"); - if (autonum.indexIn(p_keyword) >= 0) { - p_keyword.clear(); - return true; - } - - // newpage - static QRegExp newpage("^\\s*newpage\\s+(.+)"); - if (newpage.indexIn(p_keyword) >= 0) { - p_keyword = newpage.cap(1).trimmed(); - return true; - } - - // alt, else, group, loop ABCDEFG - static QRegExp group1("^\\s*(?:alt|else|group|loop)\\s+(.*)"); - if (group1.indexIn(p_keyword) >= 0) { - p_keyword = group1.cap(1).trimmed(); - return true; - } - - // note over bob, alice #Pink: - // ref over bob, alice : init - static QRegExp noteon("^\\s*(?:[hr]?note|ref)\\s+over\\s+" - "(\\w+)[^:]*" - "(?::(.+))?"); - if (noteon.indexIn(p_keyword) >= 0) { - p_keyword = noteon.cap(2).trimmed(); - if (p_keyword.isEmpty()) { - p_keyword = noteon.cap(1); - } else { - p_needCreole = true; - } - - return true; - } - - // Divider. - // == Initialization == - static QRegExp divider("^\\s*==\\s*([^=]*)==\\s*$"); - if (divider.indexIn(p_keyword) >= 0) { - p_needCreole = true; - p_keyword = divider.cap(1).trimmed(); - return true; - } - - // Delay. - // ... 5 minutes latter ... - static QRegExp delay("^\\s*\\.\\.\\.(?:(.+)\\.\\.\\.)?\\s*$"); - if (delay.indexIn(p_keyword) >= 0) { - p_needCreole = true; - p_keyword = delay.cap(1).trimmed(); - return true; - } - - // activate A - static QRegExp activate("^\\s*(?:(?:de)?activate|destroy)\\s+" - "(?:(\\w+)|\"([^\"]+)\")"); - if (activate.indexIn(p_keyword) >= 0) { - p_keyword = activate.cap(1); - if (p_keyword.isEmpty()) { - p_keyword = activate.cap(2).trimmed(); - } - - return true; - } - - // create control ABC - static QRegExp create("^\\s*create\\s+(?:\\w+\\s+)?" - "(?:(\\w+)|\"([^\"]+)\")"); - if (create.indexIn(p_keyword) >= 0) { - p_keyword = create.cap(1); - if (p_keyword.isEmpty()) { - p_keyword = create.cap(2).trimmed(); - } - - return true; - } - - // Incoming and outgoing message. - static QRegExp incoming("^\\s*\\[[-<>ox]+\\s*" - "(?:\\w+|\"[^\"]+\")\\s*" - ":\\s*(.+)"); - if (incoming.indexIn(p_keyword) >= 0) { - p_needCreole = true; - p_keyword = incoming.cap(1).trimmed(); - return true; - } - - static QRegExp outgoing("^\\s*(?:\\w+|\"[^\"]+\")\\s*" - "[-<>ox]+\\]\\s*" - ":\\s*(.+)"); - if (outgoing.indexIn(p_keyword) >= 0) { - p_needCreole = true; - p_keyword = outgoing.cap(1).trimmed(); - return true; - } - - // box "Internal Service" #Pink - static QRegExp box("^\\s*box(?:\\s+\"([^\"]+)\")?\\s*"); - if (box.indexIn(p_keyword) >= 0) { - p_keyword = box.cap(1).trimmed(); - return true; - } - - return false; -} - -static bool tryUseCaseDiagram(QString &p_keyword, QString &p_hints, bool &p_isRegex, bool &p_needCreole) -{ - Q_UNUSED(p_isRegex); - Q_UNUSED(p_hints); - - // User -> (Start) - // User --> (Use the application) : A small label - // :Main Admin: --> (Use the application) : This is another label - // (chekckout) -- (payment) : include - static QRegExp rel("^\\s*(?:(\\w+)|:([^:]+):|\\(([^\\)]+)\\))\\s*" - "[-.<>]+\\s*" - "(?:\\(([^\\)]+)\\)|(\\w+))\\s*" - "(?::(.+))?"); - if (rel.indexIn(p_keyword) >= 0) { - QString msg(rel.cap(6).trimmed()); - if (msg.isEmpty()) { - QString ent2(rel.cap(4).trimmed()); - if (ent2.isEmpty()) { - ent2 = rel.cap(5).trimmed(); - } - - if (ent2.isEmpty()) { - QString ent1(rel.cap(3).trimmed()); - if (ent1.isEmpty()) { - ent1 = rel.cap(2).trimmed(); - if (ent1.isEmpty()) { - ent1 = rel.cap(1).trimmed(); - } - } - - p_keyword = ent1; - } else { - p_keyword = ent2; - } - } else { - p_keyword = msg; - } - - p_needCreole = true; - return true; - } - - // Usecase. - // (First usecase) as (UC2) - // usecase UC3 - // usecase (Last usecase) as UC4 - static QRegExp usecase1("^\\s*usecase\\s+""(?:(\\w+)|\\(([^\\)]+)\\)\\s+as\\s+\\w+)"); - if (usecase1.indexIn(p_keyword) >= 0) { - if (usecase1.cap(1).isEmpty()) { - p_keyword = usecase1.cap(2).trimmed(); - p_needCreole = true; - } else { - p_keyword = usecase1.cap(1); - } - - return true; - } - - // This will eat almost anything starting with (). - static QRegExp usecase2("^\\s*\\(([^\\)]+)\\)"); - if (usecase2.indexIn(p_keyword) >= 0) { - p_keyword = usecase2.cap(1).trimmed(); - p_needCreole = true; - return true; - } - - // Actor. - // :Another\nactor: as men2 - // actor :Last actor: as men4 - static QRegExp actor1("^\\s*(?:actor\\s+)?:([^:]+):(?:\\s+as\\s+\\w+)?[^:]*$"); - if (actor1.indexIn(p_keyword) >= 0) { - p_keyword = actor1.cap(1).trimmed(); - p_needCreole = true; - return true; - } - - // actor men1 - static QRegExp actor2("^\\s*actor\\s+(\\w+)"); - if (actor2.indexIn(p_keyword) >= 0) { - p_keyword = actor2.cap(1).trimmed(); - p_needCreole = true; - return true; - } - - // rectangle checkout { - static QRegExp rect("^\\s*rectangle\\s+(?:(\\w+)|\"([^\"]+)\")"); - if (rect.indexIn(p_keyword) >= 0) { - p_keyword = rect.cap(1).trimmed(); - if (p_keyword.isEmpty()) { - p_keyword = rect.cap(2).trimmed(); - } - - p_needCreole = true; - return true; - } - - // Grouping. - // package "ABC DEF" { - static QRegExp group("^\\s*(?:package|node|folder|frame|cloud|database)\\s+" - "(?:(\\w+)|\"([^\"]+)\")"); - if (group.indexIn(p_keyword) >= 0) { - if (group.cap(1).isEmpty()) { - p_keyword = group.cap(2).trimmed(); - p_needCreole = true; - } else { - p_keyword = group.cap(1); - } - - return true; - } - - return false; -} - -static bool tryComponentDiagram(QString &p_keyword, QString &p_hints, bool &p_isRegex, bool &p_needCreole) -{ - Q_UNUSED(p_isRegex); - Q_UNUSED(p_hints); - - // DataAccess - [First Component] - // [First Component] ..> HTTP : use - static QRegExp rel("^\\s*(?:(\\w+)|\\[([^\\]]+)\\])\\s*" - "[-.<>]+\\s*" - "(?:(\\w+)|\\[([^\\]]+)\\])\\s*" - "(?::(.+))?"); - if (rel.indexIn(p_keyword) >= 0) { - QString msg(rel.cap(5).trimmed()); - if (msg.isEmpty()) { - QString ent1(rel.cap(3)); - if (ent1.isEmpty()) { - ent1 = rel.cap(4).trimmed(); - if (ent1 == "*") { - // State diagram. - ent1 = rel.cap(1); - if (ent1.isEmpty()) { - ent1 = rel.cap(2).trimmed(); - p_needCreole = true; - } - } else { - p_needCreole = true; - } - } - - p_keyword = ent1; - } else { - p_needCreole = true; - p_keyword = msg; - } - - return true; - } - - // Components. - // [First component] - // [Another component] as Comp2 - // component comp3 - // component [last\ncomponent] as Comp4 - static QRegExp comp1("^\\s*component\\s+(?:(\\w+)|\\[([^\\]]+)\\]\\s+as\\s+\\w+)"); - if (comp1.indexIn(p_keyword) >= 0) { - if (comp1.cap(1).isEmpty()) { - p_keyword = comp1.cap(2).trimmed(); - p_needCreole = true; - } else { - p_keyword = comp1.cap(1); - } - - return true; - } - - // This will eat almost anything starting with []. - static QRegExp comp2("^\\s*\\[([^\\]]+)\\]"); - if (comp2.indexIn(p_keyword) >= 0) { - p_keyword = comp2.cap(1).trimmed(); - p_needCreole = true; - return true; - } - - // Interface. - // interface Int1 - // interface "last interface" as Int2 - static QRegExp int1("^\\s*interface\\s+(?:(\\w+)|\"([^\"]+)\"\\s+as\\s+\\w+)"); - if (int1.indexIn(p_keyword) >= 0) { - if (int1.cap(1).isEmpty()) { - p_keyword = int1.cap(2).trimmed(); - p_needCreole = true; - } else { - p_keyword = int1.cap(1); - } - - return true; - } - - - // () "First Interface" as Inter2 - static QRegExp int2("^\\s*\\(\\)\\s+\"([^\"]+)\""); - if (int2.indexIn(p_keyword) >= 0) { - p_keyword = int2.cap(1).trimmed(); - p_needCreole = true; - - return true; - } - - return false; -} - -static bool tryStateDiagram(QString &p_keyword, QString &p_hints, bool &p_isRegex, bool &p_needCreole) -{ - Q_UNUSED(p_isRegex); - Q_UNUSED(p_hints); - - // state State3 { - static QRegExp state("^\\s*state\\s+" - "(?:(\\w+)|\"([^\"]+)\")"); - if (state.indexIn(p_keyword) >= 0) { - p_keyword = state.cap(1); - if (p_keyword.isEmpty()) { - p_keyword = state.cap(2).trimmed(); - p_needCreole = true; - } - - return true; - } - - // state1 : this is a string - static QRegExp state2("^\\s*\\w+\\s*:(.+)"); - if (state2.indexIn(p_keyword) >= 0) { - p_keyword = state2.cap(1).trimmed(); - p_needCreole = true; - return true; - } - - return false; -} - -static bool tryObjectDiagram(QString &p_keyword, QString &p_hints, bool &p_isRegex, bool &p_needCreole) -{ - Q_UNUSED(p_isRegex); - Q_UNUSED(p_hints); - - // object obj { - static QRegExp object("^\\s*object\\s+" - "(?:(\\w+)|\"([^\"]+)\")"); - if (object.indexIn(p_keyword) >= 0) { - p_keyword = object.cap(1); - if (p_keyword.isEmpty()) { - p_keyword = object.cap(2).trimmed(); - p_needCreole = true; - } - - return true; - } - - return false; -} - -static bool tryMultipleLineText(QString &p_keyword) -{ - static QRegExp mulline("\\\\n"); - - QString maxPart; - bool found = false; - int pos = 0; - while (pos < p_keyword.size()) { - int idx = mulline.indexIn(p_keyword, pos); - if (idx == -1) { - if (found) { - if (p_keyword.size() - pos > maxPart.size()) { - maxPart = p_keyword.mid(pos); - } - } - - break; - } - - found = true; - - // [pos, idx) is part of the plain text. - if (idx - pos > maxPart.size()) { - maxPart = p_keyword.mid(pos, idx - pos); - } - - pos = idx + mulline.matchedLength(); - } - - if (found) { - p_keyword = maxPart.trimmed(); - return true; - } else { - return false; - } -} - -static bool tryEmphasizedText(QString &p_keyword) -{ - static QRegExp emph("(--|\\*\\*|//|\"\"|__|~~)" - "([^-*/\"_~]+)" - "\\1"); - QString maxPart; - bool found = false; - int pos = 0; - while (pos < p_keyword.size()) { - int idx = emph.indexIn(p_keyword, pos); - if (idx == -1) { - if (found) { - if (p_keyword.size() - pos > maxPart.size()) { - maxPart = p_keyword.mid(pos); - } - } - - break; - } - - found = true; - - // [pos, idx) is part of the plain text. - if (idx - pos > maxPart.size()) { - maxPart = p_keyword.mid(pos, idx - pos); - } - - if (emph.cap(2).size() > maxPart.size()) { - maxPart = emph.cap(2); - } - - pos = idx + emph.matchedLength(); - } - - if (found) { - p_keyword = maxPart.trimmed(); - return true; - } else { - return false; - } -} - -static bool tryCreole(QString &p_keyword) -{ - if (p_keyword.isEmpty()) { - return false; - } - - bool ret = false; - - // List. - // ** list - // # list - static QRegExp listMark("^\\s*(?:\\*+|#+)\\s+(.+)$"); - if (listMark.indexIn(p_keyword) >= 0) { - p_keyword = listMark.cap(1).trimmed(); - ret = true; - } - - // Heading. - // ### head - static QRegExp headMark("^\\s*=+\\s+(.+)"); - if (headMark.indexIn(p_keyword) >= 0) { - p_keyword = headMark.cap(1).trimmed(); - ret = true; - } - - // \n - if (tryMultipleLineText(p_keyword)) { - ret = true; - } - - // Emphasized text. - if (tryEmphasizedText(p_keyword)) { - ret = true; - } - - return ret; -} - -QString VPlantUMLHelper::keywordForSmartLivePreview(const QString &p_text, - QString &p_hints, - bool &p_isRegex) -{ - QString kw = p_text.trimmed(); - if (kw.isEmpty()) { - return kw; - } - - p_isRegex = false; - bool needCreole = false; - - qDebug() << "tryKeywords" << kw; - - if (tryKeywords(kw, needCreole)) { - if (needCreole) { - goto creole; - } - - return kw; - } - - qDebug() << "tryClassDiagram" << kw; - - if (tryClassDiagram(kw, p_hints, p_isRegex, needCreole)) { - if (needCreole) { - goto creole; - } - - return kw; - } - - qDebug() << "tryActivityDiagram" << kw; - - if (tryActivityDiagram(kw, p_hints, p_isRegex, needCreole)) { - if (needCreole) { - goto creole; - } - - return kw; - } - - qDebug() << "trySequenceDiagram" << kw; - - if (trySequenceDiagram(kw, p_hints, p_isRegex, needCreole)) { - if (needCreole) { - goto creole; - } - - return kw; - } - - qDebug() << "tryUseCaseDiagram" << kw; - - if (tryUseCaseDiagram(kw, p_hints, p_isRegex, needCreole)) { - if (needCreole) { - goto creole; - } - - return kw; - } - - qDebug() << "tryComponentDiagram" << kw; - - if (tryComponentDiagram(kw, p_hints, p_isRegex, needCreole)) { - if (needCreole) { - goto creole; - } - - return kw; - } - - qDebug() << "tryStateDiagram" << kw; - - if (tryStateDiagram(kw, p_hints, p_isRegex, needCreole)) { - if (needCreole) { - goto creole; - } - - return kw; - } - - qDebug() << "tryObjectDiagram" << kw; - - if (tryObjectDiagram(kw, p_hints, p_isRegex, needCreole)) { - if (needCreole) { - goto creole; - } - - return kw; - } - - qDebug() << "tryCommonElements" << kw; - - if (tryCommonElements(kw, p_hints, p_isRegex, needCreole)) { - if (needCreole) { - goto creole; - } - - return kw; - } - -creole: - tryCreole(kw); - return kw; -} - -QStringList VPlantUMLHelper::refineArgsForUse(const QStringList &p_args) -{ - if (p_args.isEmpty()) { - return QStringList(); - } - - if (p_args[0] == "-c") { - QStringList args; - args << p_args[0]; - QString subCmd; - for (int i = 1; i < p_args.size(); ++i) { - subCmd += " " + p_args[i]; - } - args << subCmd; - return args; - } else { - return p_args; - } -} diff --git a/src/vplantumlhelper.h b/src/vplantumlhelper.h deleted file mode 100644 index 663efcd9..00000000 --- a/src/vplantumlhelper.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef VPLANTUMLHELPER_H -#define VPLANTUMLHELPER_H - -#include - -#include -#include - -#include "vconstants.h" - -class VPlantUMLHelper : public QObject -{ - Q_OBJECT -public: - explicit VPlantUMLHelper(QObject *p_parent = nullptr); - - void processAsync(int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QString &p_text); - - static bool testPlantUMLJar(const QString &p_jar, QString &p_msg); - - static QByteArray process(const QString &p_format, const QString &p_text); - - static QString keywordForSmartLivePreview(const QString &p_text, - QString &p_hints, - bool &p_isRegex); - -signals: - void resultReady(int p_id, - TimeStamp p_timeStamp, - const QString &p_format, - const QString &p_result); - -private slots: - void handleProcessFinished(int p_exitCode, QProcess::ExitStatus p_exitStatus); - -private: - VPlantUMLHelper(const QString &p_jar, QObject *p_parent = nullptr); - - void prepareCommand(QString &p_cmd, QStringList &p_args, const QString &p_jar= QString()) const; - - static QStringList refineArgsForUse(const QStringList &p_args); - - QString m_program; - - QStringList m_args; - - // When not empty, @m_program and @m_args will be ignored. - QString m_customCmd; -}; - -#endif // VPLANTUMLHELPER_H diff --git a/src/vpreviewmanager.cpp b/src/vpreviewmanager.cpp deleted file mode 100644 index 4f4d37ea..00000000 --- a/src/vpreviewmanager.cpp +++ /dev/null @@ -1,571 +0,0 @@ -#include "vpreviewmanager.h" - -#include -#include -#include -#include -#include - -#include "vconfigmanager.h" -#include "utils/vutils.h" -#include "vdownloader.h" -#include "pegmarkdownhighlighter.h" - -extern VConfigManager *g_config; - -VPreviewManager::VPreviewManager(VMdEditor *p_editor, PegMarkdownHighlighter *p_highlighter) - : QObject(p_editor), - m_editor(p_editor), - m_document(p_editor->document()), - m_highlighter(p_highlighter), - m_previewEnabled(false) -{ - for (int i = 0; i < (int)PreviewSource::MaxNumberOfSources; ++i) { - m_timeStamps[i] = 0; - } - - m_downloader = new VDownloader(this); - connect(m_downloader, &VDownloader::downloadFinished, - this, &VPreviewManager::imageDownloaded); -} - -void VPreviewManager::updateImageLinks(const QVector &p_imageRegions) -{ - if (!m_previewEnabled) { - return; - } - - TS ts = ++timeStamp(PreviewSource::ImageLink); - previewImages(ts, p_imageRegions); -} - -static QPixmap scalePreviewImage(const QPixmap &p_img, int p_width, int p_height) -{ - const Qt::TransformationMode tMode = Qt::SmoothTransformation; - qreal sf = VUtils::calculateScaleFactor(); - if (p_width > 0) { - if (p_height > 0) { - return p_img.scaled(p_width * sf, - p_height * sf, - Qt::IgnoreAspectRatio, - tMode); - } else { - return p_img.scaledToWidth(p_width * sf, tMode); - } - } else if (p_height > 0) { - return p_img.scaledToHeight(p_height * sf, tMode); - } else { - if (sf < 1.1) { - return p_img; - } else { - return p_img.scaledToWidth(p_img.width() * sf, tMode); - } - } -} - -void VPreviewManager::imageDownloaded(const QByteArray &p_data, const QString &p_url) -{ - if (!m_previewEnabled) { - return; - } - - auto it = m_urlMap.find(p_url); - if (it == m_urlMap.end()) { - return; - } - - QSharedPointer info = it.value(); - m_urlMap.erase(it); - - if (m_editor->containsImage(info->m_name) || info->m_name.isEmpty()) { - return; - } - - QPixmap image; - image.loadFromData(p_data); - if (!image.isNull()) { - m_editor->addImage(info->m_name, - scalePreviewImage(image, info->m_width, info->m_height)); - emit requestUpdateImageLinks(); - } -} - -void VPreviewManager::setPreviewEnabled(bool p_enabled) -{ - if (m_previewEnabled != p_enabled) { - m_previewEnabled = p_enabled; - - emit previewEnabledChanged(p_enabled); - - if (!m_previewEnabled) { - clearPreview(); - } else { - requestUpdateImageLinks(); - } - } -} - -void VPreviewManager::clearPreview() -{ - OrderedIntSet affectedBlocks; - for (int i = 0; i < (int)PreviewSource::MaxNumberOfSources; ++i) { - TS ts = ++timeStamp(static_cast(i)); - clearBlockObsoletePreviewInfo(ts, static_cast(i), affectedBlocks); - clearObsoleteImages(ts, static_cast(i)); - } - - relayout(affectedBlocks); -} - -void VPreviewManager::previewImages(TS p_timeStamp, const QVector &p_imageRegions) -{ - QVector imageLinks; - fetchImageLinksFromRegions(p_imageRegions, imageLinks); - - OrderedIntSet affectedBlocks; - - updateBlockPreviewInfo(p_timeStamp, imageLinks, affectedBlocks); - - clearBlockObsoletePreviewInfo(p_timeStamp, PreviewSource::ImageLink, affectedBlocks); - - clearObsoleteImages(p_timeStamp, PreviewSource::ImageLink); - - relayout(affectedBlocks); -} - -// Returns true if p_text[p_start, p_end) is all spaces. -static bool isAllSpaces(const QString &p_text, int p_start, int p_end) -{ - int len = qMin(p_text.size(), p_end); - for (int i = p_start; i < len; ++i) { - if (!p_text[i].isSpace()) { - return false; - } - } - - return true; -} - -void VPreviewManager::fetchImageLinksFromRegions(QVector p_imageRegions, - QVector &p_imageLinks) -{ - p_imageLinks.clear(); - - if (p_imageRegions.isEmpty()) { - return; - } - - p_imageLinks.reserve(p_imageRegions.size()); - - QTextDocument *doc = m_editor->document(); - - for (int i = 0; i < p_imageRegions.size(); ++i) { - const VElementRegion ® = p_imageRegions[i]; - QTextBlock firstBlock = doc->findBlock(reg.m_startPos); - if (!firstBlock.isValid()) { - continue; - } - - // Image link may cross multiple regions. - QTextBlock lastBlock = doc->findBlock(reg.m_endPos - 1); - if (!lastBlock.isValid()) { - continue; - } - - int firstBlockStart = firstBlock.position(); - int lastBlockStart = lastBlock.position(); - int lastBlockEnd = lastBlockStart + lastBlock.length() - 1; - - QString text; - if (firstBlock.blockNumber() == lastBlock.blockNumber()) { - text = firstBlock.text().mid(reg.m_startPos - firstBlockStart, - reg.m_endPos - reg.m_startPos); - } else { - text = firstBlock.text().mid(reg.m_startPos - firstBlockStart); - - QTextBlock block = firstBlock.next(); - while (block.isValid() && block.blockNumber() < lastBlock.blockNumber()) { - text += "\n" + block.text(); - block = block.next(); - } - - text += "\n" + lastBlock.text().left(reg.m_endPos - lastBlockStart); - } - - // Preview the image at the last block. - ImageLinkInfo info(qMax(reg.m_startPos, lastBlockStart), - reg.m_endPos, - lastBlockStart, - lastBlock.blockNumber(), - calculateBlockMargin(firstBlock, m_editor->tabStopWidthW())); - if ((reg.m_startPos == firstBlockStart - || isAllSpaces(firstBlock.text(), 0, reg.m_startPos - firstBlockStart)) - && (reg.m_endPos == lastBlockEnd - || isAllSpaces(lastBlock.text(), - reg.m_endPos - lastBlockStart, - lastBlockEnd - lastBlockStart))) { - // Image block. - info.m_isBlock = true; - } else { - // Inline image. - info.m_isBlock = false; - } - - fetchImageInfoToPreview(text, info); - - if (info.m_linkUrl.isEmpty() || info.m_linkShortUrl.isEmpty()) { - continue; - } - - p_imageLinks.append(info); - } -} - -void VPreviewManager::fetchImageInfoToPreview(const QString &p_text, ImageLinkInfo &p_info) -{ - QString surl = VUtils::fetchImageLinkUrlToPreview(p_text, p_info.m_width, p_info.m_height); - p_info.m_linkShortUrl = surl; - if (surl.isEmpty()) { - p_info.m_linkUrl = surl; - return; - } - - const VFile *file = m_editor->getFile(); - p_info.m_linkUrl = VUtils::linkUrlToPath(file->fetchBasePath(), surl); -} - -QString VPreviewManager::imageResourceName(const ImageLinkInfo &p_link) -{ - // Add size info to the name. - QString name = QString("%1_%2_%3").arg(p_link.m_linkShortUrl) - .arg(p_link.m_width) - .arg(p_link.m_height); - if (m_editor->containsImage(name)) { - return name; - } - - // Add it to the resource. - QPixmap image; - QString imgPath = p_link.m_linkUrl; - if (QFileInfo::exists(imgPath)) { - // Local file. - image = VUtils::pixmapFromFile(imgPath); - if (image.isNull()) { - return QString(); - } - } else { - // URL. Try to download it. - // qrc:// files will touch this path. - m_downloader->download(imgPath); - - QSharedPointer info(new UrlImageInfo(name, - p_link.m_width, - p_link.m_height)); - m_urlMap.insert(imgPath, info); - - return QString(); - } - - m_editor->addImage(name, - scalePreviewImage(image, p_link.m_width, p_link.m_height)); - return name; -} - -QString VPreviewManager::imageResourceNameForSource(PreviewSource p_source, - const QSharedPointer &p_image) -{ - QString name = QString::number((int)p_source) + "_" + p_image->m_name; - if (m_editor->containsImage(name)) { - return name; - } - - // Add it to the resource. - if (p_image->m_image.isNull()) { - return QString(); - } - - m_editor->addImage(name, p_image->m_image); - return name; -} - -int VPreviewManager::calculateBlockMargin(const QTextBlock &p_block, int p_tabStopWidth) -{ - static QHash spaceWidthOfFonts; - - if (!p_block.isValid()) { - return 0; - } - - QString text = p_block.text(); - int nrSpaces = 0; - for (int i = 0; i < text.size(); ++i) { - if (!text[i].isSpace()) { - break; - } else if (text[i] == ' ') { - ++nrSpaces; - } else if (text[i] == '\t') { - nrSpaces += p_tabStopWidth; - } - } - - if (nrSpaces == 0) { - return 0; - } - - int spaceWidth = 0; - QFont font; - QVector fmts = p_block.layout()->formats(); - if (fmts.isEmpty()) { - font = p_block.charFormat().font(); - } else { - font = fmts.first().format.font(); - } - - QString fontName = font.toString(); - auto it = spaceWidthOfFonts.find(fontName); - if (it != spaceWidthOfFonts.end()) { - spaceWidth = it.value(); - } else { - spaceWidth = QFontMetrics(font).width(' '); - spaceWidthOfFonts.insert(fontName, spaceWidth); - } - - return spaceWidth * nrSpaces; -} - -void VPreviewManager::updateBlockPreviewInfo(TS p_timeStamp, - const QVector &p_imageLinks, - OrderedIntSet &p_affectedBlocks) -{ - for (auto const & link : p_imageLinks) { - QTextBlock block = m_document->findBlockByNumber(link.m_blockNumber); - if (!block.isValid()) { - continue; - } - - QString name = imageResourceName(link); - if (name.isEmpty()) { - continue; - } - - VTextBlockData *blockData = static_cast(block.userData()); - if (!blockData) { - continue; - } - - VPreviewInfo *info = new VPreviewInfo(PreviewSource::ImageLink, - p_timeStamp, - link.m_startPos - link.m_blockPos, - link.m_endPos - link.m_blockPos, - link.m_padding, - !link.m_isBlock, - name, - m_editor->imageSize(name), - QString()); - bool tsUpdated = blockData->insertPreviewInfo(info); - imageCache(PreviewSource::ImageLink).insert(name, p_timeStamp); - if (!tsUpdated) { - // No need to relayout the block if only timestamp is updated. - p_affectedBlocks.insert(link.m_blockNumber, QMapDummyValue()); - m_highlighter->addPossiblePreviewBlock(link.m_blockNumber); - } - } -} - -void VPreviewManager::updateBlockPreviewInfo(TS p_timeStamp, - PreviewSource p_source, - const QVector > &p_images, - OrderedIntSet &p_affectedBlocks) -{ - for (auto const & img : p_images) { - if (img.isNull()) { - continue; - } - - QTextBlock block = m_document->findBlockByNumber(img->m_blockNumber); - if (!block.isValid()) { - continue; - } - - QString name = imageResourceNameForSource(p_source, img); - if (name.isEmpty()) { - continue; - } - - VTextBlockData *blockData = static_cast(block.userData()); - if (!blockData) { - continue; - } - - VPreviewInfo *info = new VPreviewInfo(p_source, - p_timeStamp, - img->m_startPos - img->m_blockPos, - img->m_endPos - img->m_blockPos, - img->m_padding, - !img->m_isBlock, - name, - m_editor->imageSize(name), - img->m_background); - bool tsUpdated = blockData->insertPreviewInfo(info); - imageCache(p_source).insert(name, p_timeStamp); - if (!tsUpdated) { - // No need to relayout the block if only timestamp is updated. - p_affectedBlocks.insert(img->m_blockNumber, QMapDummyValue()); - m_highlighter->addPossiblePreviewBlock(img->m_blockNumber); - } - } -} - -void VPreviewManager::clearObsoleteImages(long long p_timeStamp, PreviewSource p_source) -{ - QHash &cache = imageCache(p_source); - - for (auto it = cache.begin(); it != cache.end();) { - if (it.value() < p_timeStamp) { - m_editor->removeImage(it.key()); - it = cache.erase(it); - } else { - ++it; - } - } -} - -void VPreviewManager::clearBlockObsoletePreviewInfo(long long p_timeStamp, - PreviewSource p_source, - OrderedIntSet &p_affectedBlocks) -{ - QVector obsoleteBlocks; - const QSet &blocks = m_highlighter->getPossiblePreviewBlocks(); - for (auto i : blocks) { - QTextBlock block = m_document->findBlockByNumber(i); - if (!block.isValid()) { - obsoleteBlocks.append(i); - continue; - } - - VTextBlockData *blockData = static_cast(block.userData()); - if (!blockData) { - continue; - } - - if (blockData->clearObsoletePreview(p_timeStamp, p_source)) { - p_affectedBlocks.insert(i, QMapDummyValue()); - } - - if (blockData->getPreviews().isEmpty()) { - obsoleteBlocks.append(i); - } - } - - m_highlighter->clearPossiblePreviewBlocks(obsoleteBlocks); -} - -void VPreviewManager::refreshPreview() -{ - if (!m_previewEnabled) { - return; - } - - clearPreview(); - - // No need to request updating code blocks since this will also update them. - requestUpdateImageLinks(); -} - -void VPreviewManager::updateCodeBlocks(const QVector > &p_images) -{ - if (!m_previewEnabled) { - return; - } - - TS ts = ++timeStamp(PreviewSource::CodeBlock); - - OrderedIntSet affectedBlocks; - - updateBlockPreviewInfo(ts, PreviewSource::CodeBlock, p_images, affectedBlocks); - - clearBlockObsoletePreviewInfo(ts, PreviewSource::CodeBlock, affectedBlocks); - - clearObsoleteImages(ts, PreviewSource::CodeBlock); - - relayout(affectedBlocks); -} - -void VPreviewManager::updateMathjaxBlocks(const QVector > &p_images) -{ - if (!m_previewEnabled) { - return; - } - - TS ts = ++timeStamp(PreviewSource::MathjaxBlock); - - OrderedIntSet affectedBlocks; - - updateBlockPreviewInfo(ts, PreviewSource::MathjaxBlock, p_images, affectedBlocks); - - clearBlockObsoletePreviewInfo(ts, PreviewSource::MathjaxBlock, affectedBlocks); - - clearObsoleteImages(ts, PreviewSource::MathjaxBlock); - - relayout(affectedBlocks); -} - -void VPreviewManager::checkBlocksForObsoletePreview(const QList &p_blocks) -{ - if (p_blocks.isEmpty()) { - return; - } - - OrderedIntSet affectedBlocks; - for (auto blockNum : p_blocks) { - QTextBlock block = m_document->findBlockByNumber(blockNum); - if (!block.isValid()) { - continue; - } - - VTextBlockData *blockData = static_cast(block.userData()); - if (!blockData) { - continue; - } - - if (blockData->getPreviews().isEmpty()) { - continue; - } - - for (int i = 0; i < (int)PreviewSource::MaxNumberOfSources; ++i) { - if (blockData->getPreviews().isEmpty()) { - break; - } - - PreviewSource ps = static_cast(i); - if (blockData->clearObsoletePreview(timeStamp(ps), ps)) { - affectedBlocks.insert(blockNum, QMapDummyValue()); - } - } - } - - relayout(affectedBlocks); -} - -void VPreviewManager::relayoutEditor(const OrderedIntSet &p_blocks) -{ - OrderedIntSet bs(p_blocks); - int first, last; - m_editor->visibleBlockRange(first, last); - for (int i = first; i <= last; ++i) { - bs.insert(i, QMapDummyValue()); - } - - m_editor->relayout(bs); - - // We may get the wrong visible block range before relayout() updating the document size. - OrderedIntSet after; - int afterFirst = m_editor->firstVisibleBlockNumber(); - for (int i = afterFirst; i < first; ++i) { - if (!bs.contains(i)) { - after.insert(i, QMapDummyValue()); - } - } - - m_editor->relayout(after); -} diff --git a/src/vpreviewmanager.h b/src/vpreviewmanager.h deleted file mode 100644 index 33d7284b..00000000 --- a/src/vpreviewmanager.h +++ /dev/null @@ -1,272 +0,0 @@ -#ifndef VPREVIEWMANAGER_H -#define VPREVIEWMANAGER_H - -#include -#include -#include -#include -#include -#include - -#include "markdownhighlighterdata.h" -#include "vmdeditor.h" -#include "vtextblockdata.h" - -class VDownloader; - -typedef long long TS; - -// Info about image to preview. -struct VImageToPreview -{ - void clear() - { - m_startPos = m_endPos = m_blockPos = m_blockNumber = -1; - m_padding = 0; - m_image = QPixmap(); - m_name.clear(); - m_background.clear(); - m_isBlock = true; - }; - - int m_startPos; - - int m_endPos; - - // Position of this block. - int m_blockPos; - - int m_blockNumber; - - // Left padding of this block in pixels. - int m_padding; - - QPixmap m_image; - - // If @m_name are the same, then they are the same imges. - QString m_name; - - // If not empty, we should draw a background before drawing this image. - QString m_background; - - // Whether it is an image block. - bool m_isBlock; -}; - - -// Manage inplace preview. -class VPreviewManager : public QObject -{ - Q_OBJECT -public: - VPreviewManager(VMdEditor *p_editor, PegMarkdownHighlighter *p_highlighter); - - void setPreviewEnabled(bool p_enabled); - - // Clear all the preview. - void clearPreview(); - - // Refresh all the preview. - void refreshPreview(); - - bool isPreviewEnabled() const; - - // Check @p_blocks to see if there is any obsolete preview and clear them - // if there is any. - void checkBlocksForObsoletePreview(const QList &p_blocks); - - // Calculate the block margin (prefix spaces) in pixels. - static int calculateBlockMargin(const QTextBlock &p_block, int p_tabStopWidth); - -public slots: - // Image links were updated from the highlighter. - void updateImageLinks(const QVector &p_imageRegions); - - void updateCodeBlocks(const QVector > &p_images); - - void updateMathjaxBlocks(const QVector > &p_images); - -signals: - // Request highlighter to update image links. - void requestUpdateImageLinks(); - - void previewEnabledChanged(bool p_enabled); - -private slots: - // Non-local image downloaded for preview. - void imageDownloaded(const QByteArray &p_data, const QString &p_url); - -private: - struct ImageLinkInfo - { - ImageLinkInfo() - : m_startPos(-1), - m_endPos(-1), - m_blockPos(-1), - m_blockNumber(-1), - m_padding(0), - m_isBlock(false), - m_width(-1), - m_height(-1) - { - } - - ImageLinkInfo(int p_startPos, - int p_endPos, - int p_blockPos, - int p_blockNumber, - int p_padding) - : m_startPos(p_startPos), - m_endPos(p_endPos), - m_blockPos(p_blockPos), - m_blockNumber(p_blockNumber), - m_padding(p_padding), - m_isBlock(false), - m_width(-1), - m_height(-1) - { - } - - QString toString() const - { - return QString("ImageLinkInfo [%1,%2) block(%3,%4) padding %5 " - "short %6 url %7 isBlock %8 width %9 height %10") - .arg(m_startPos) - .arg(m_endPos) - .arg(m_blockNumber) - .arg(m_blockPos) - .arg(m_padding) - .arg(m_linkShortUrl) - .arg(m_linkUrl) - .arg(m_isBlock) - .arg(m_width) - .arg(m_height); - } - - int m_startPos; - - int m_endPos; - - // Position of this block. - int m_blockPos; - - int m_blockNumber; - - // Left padding of this block in pixels. - int m_padding; - - // Short URL within the () of ![](). - // Used as the ID of the image. - QString m_linkShortUrl; - - // Full URL of the link. - QString m_linkUrl; - - // Whether it is an image block. - bool m_isBlock; - - // Image width, -1 for not specified. - int m_width; - - // Image height, -1 for not specified. - int m_height; - }; - - struct UrlImageInfo { - UrlImageInfo(const QString &p_name, int p_width, int p_height) - : m_name(p_name), - m_width(p_width), - m_height(p_height) - { - } - - QString m_name; - int m_width; - int m_height; - }; - - // Start to preview images according to image links. - void previewImages(TS p_timeStamp, const QVector &p_imageRegions); - - // According to p_imageRegions, fetch the image link Url. - // @p_imageRegions: output. - void fetchImageLinksFromRegions(QVector p_imageRegions, - QVector &p_imageLinks); - - // Fetch the image's full path and size. - void fetchImageInfoToPreview(const QString &p_text, ImageLinkInfo &p_info); - - // Update the preview info of related blocks according to @p_imageLinks. - void updateBlockPreviewInfo(TS p_timeStamp, - const QVector &p_imageLinks, - OrderedIntSet &p_affectedBlocks); - - // Update the preview info of related blocks according to @p_images. - void updateBlockPreviewInfo(TS p_timeStamp, - PreviewSource p_source, - const QVector > &p_images, - OrderedIntSet &p_affectedBlocks); - - // Get the name of the image in the resource manager. - // Will add the image to the resource manager if not exists. - // Returns empty if fail to add the image to the resource manager. - QString imageResourceName(const ImageLinkInfo &p_link); - - QString imageResourceNameForSource(PreviewSource p_source, const QSharedPointer &p_image); - - QHash &imageCache(PreviewSource p_source); - - void clearObsoleteImages(long long p_timeStamp, PreviewSource p_source); - - void clearBlockObsoletePreviewInfo(long long p_timeStamp, - PreviewSource p_source, - OrderedIntSet &p_affectedBlocks); - - TS &timeStamp(PreviewSource p_source); - - void relayoutEditor(const OrderedIntSet &p_blocks); - - void relayout(const OrderedIntSet &p_blocks); - - VMdEditor *m_editor; - - QTextDocument *m_document; - - PegMarkdownHighlighter *m_highlighter; - - VDownloader *m_downloader; - - // Whether preview is enabled. - bool m_previewEnabled; - - // Map from URL to name in the resource manager. - // Used for downloading images. - QHash> m_urlMap; - - // Timestamp per each preview source. - TS m_timeStamps[(int)PreviewSource::MaxNumberOfSources]; - - // Used to discard obsolete images. One per each preview source. - QHash m_imageCaches[(int)PreviewSource::MaxNumberOfSources]; -}; - -inline QHash &VPreviewManager::imageCache(PreviewSource p_source) -{ - return m_imageCaches[(int)p_source]; -} - -inline TS &VPreviewManager::timeStamp(PreviewSource p_source) -{ - return m_timeStamps[(int)p_source]; -} - -inline bool VPreviewManager::isPreviewEnabled() const -{ - return m_previewEnabled; -} - -inline void VPreviewManager::relayout(const OrderedIntSet &p_blocks) -{ - m_editor->relayout(p_blocks); -} -#endif // VPREVIEWMANAGER_H diff --git a/src/vpreviewpage.cpp b/src/vpreviewpage.cpp deleted file mode 100644 index 81e67ede..00000000 --- a/src/vpreviewpage.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "vpreviewpage.h" - -#include - -#include "vmainwindow.h" - -extern VMainWindow *g_mainWin; - -VPreviewPage::VPreviewPage(QWidget *parent) : QWebEnginePage(parent) -{ - -} - -bool VPreviewPage::acceptNavigationRequest(const QUrl &p_url, - QWebEnginePage::NavigationType p_type, - bool p_isMainFrame) -{ - Q_UNUSED(p_type); - - if (p_url.isLocalFile()) { - QString filePath = p_url.toLocalFile(); - if (g_mainWin->tryOpenInternalFile(filePath)) { - return false; - } - } else if (!p_isMainFrame) { - return true; - } else if (p_url.scheme() == "data") { - // Qt 5.12 will trigger this when calling QWebEngineView.setHtml(). - return true; - } - - QDesktopServices::openUrl(p_url); - return false; -} diff --git a/src/vpreviewpage.h b/src/vpreviewpage.h deleted file mode 100644 index eca8a25c..00000000 --- a/src/vpreviewpage.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef VPREVIEWPAGE_H -#define VPREVIEWPAGE_H - -#include - -class VPreviewPage : public QWebEnginePage -{ - Q_OBJECT -public: - explicit VPreviewPage(QWidget *parent = 0); - -protected: - bool acceptNavigationRequest(const QUrl &p_url, - NavigationType p_type, - bool p_isMainFrame); -}; - -#endif // VPREVIEWPAGE_H diff --git a/src/vsearch.cpp b/src/vsearch.cpp deleted file mode 100644 index 08f841c8..00000000 --- a/src/vsearch.cpp +++ /dev/null @@ -1,687 +0,0 @@ -#include "vsearch.h" - -#include "utils/vutils.h" -#include "vnotefile.h" -#include "vdirectory.h" -#include "vnotebook.h" -#include "veditarea.h" -#include "vmainwindow.h" -#include "vtableofcontent.h" -#include "vsearchengine.h" - -extern VMainWindow *g_mainWin; - -VSearch::VSearch(QObject *p_parent) - : QObject(p_parent), - m_askedToStop(false), - m_engine(NULL) -{ - m_slashReg = QRegExp("[\\/]"); -} - -QSharedPointer VSearch::search(const QVector &p_files) -{ - Q_ASSERT(!askedToStop()); - - QSharedPointer result(new VSearchResult(this)); - - if (p_files.isEmpty() || m_config->isEmpty()) { - result->m_state = VSearchState::Success; - return result; - } - - if (!testTarget(VSearchConfig::Note)) { - qDebug() << "search is not applicable for note"; - result->m_state = VSearchState::Success; - return result; - } - - result->m_state = VSearchState::Busy; - - for (auto const & it : p_files) { - if (!it) { - continue; - } - - searchFirstPhase(it, result, true); - - if (askedToStop()) { - qDebug() << "asked to cancel the search"; - result->m_state = VSearchState::Cancelled; - break; - } - } - - if (result->m_state == VSearchState::Busy) { - result->m_state = VSearchState::Success; - } - - return result; -} - -QSharedPointer VSearch::search(VDirectory *p_directory) -{ - Q_ASSERT(!askedToStop()); - - QSharedPointer result(new VSearchResult(this)); - - if (!p_directory || m_config->isEmpty()) { - result->m_state = VSearchState::Success; - return result; - } - - if ((!testTarget(VSearchConfig::Note) - && !testTarget(VSearchConfig::Folder)) - || testObject(VSearchConfig::Outline)) { - qDebug() << "search is not applicable for folder"; - result->m_state = VSearchState::Success; - return result; - } - - result->m_state = VSearchState::Busy; - - searchFirstPhase(p_directory, result); - - if (result->hasSecondPhaseItems()) { - searchSecondPhase(result); - } else if (result->m_state == VSearchState::Busy) { - result->m_state = VSearchState::Success; - } - - return result; -} - -QSharedPointer VSearch::search(const QVector &p_notebooks) -{ - Q_ASSERT(!askedToStop()); - - QSharedPointer result(new VSearchResult(this)); - - if (p_notebooks.isEmpty() || m_config->isEmpty()) { - result->m_state = VSearchState::Success; - return result; - } - - if (testObject(VSearchConfig::Outline)) { - qDebug() << "search is not applicable for notebook"; - result->m_state = VSearchState::Success; - return result; - } - - result->m_state = VSearchState::Busy; - - for (auto const & nb : p_notebooks) { - if (!nb) { - continue; - } - - searchFirstPhase(nb, result); - - if (askedToStop()) { - qDebug() << "asked to cancel the search"; - result->m_state = VSearchState::Cancelled; - break; - } - } - - if (result->hasSecondPhaseItems()) { - searchSecondPhase(result); - } else if (result->m_state == VSearchState::Busy) { - result->m_state = VSearchState::Success; - } - - return result; -} - -QSharedPointer VSearch::search(const QString &p_directoryPath) -{ - Q_ASSERT(!askedToStop()); - - QSharedPointer result(new VSearchResult(this)); - - if (p_directoryPath.isEmpty() || m_config->isEmpty()) { - result->m_state = VSearchState::Success; - return result; - } - - if ((!testTarget(VSearchConfig::Note) - && !testTarget(VSearchConfig::Folder)) - || testObject(VSearchConfig::Outline) - || testObject(VSearchConfig::Tag)) { - qDebug() << "search is not applicable for directory"; - result->m_state = VSearchState::Success; - return result; - } - - result->m_state = VSearchState::Busy; - - searchFirstPhase(p_directoryPath, p_directoryPath, result); - - if (result->hasSecondPhaseItems()) { - searchSecondPhase(result); - } else if (result->m_state == VSearchState::Busy) { - result->m_state = VSearchState::Success; - } - - return result; -} - -void VSearch::searchFirstPhase(VFile *p_file, - const QSharedPointer &p_result, - bool p_searchContent) -{ - Q_ASSERT(testTarget(VSearchConfig::Note)); - - QString name = p_file->getName(); - if (!matchPattern(name)) { - return; - } - - QString filePath = p_file->fetchPath(); - if (testObject(VSearchConfig::Name)) { - if (matchNonContent(name)) { - VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - name, - filePath); - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - - if (testObject(VSearchConfig::Path)) { - QString normFilePath; - if (p_file->getType() == FileType::Note) { - normFilePath = static_cast(p_file)->fetchRelativePath(); - } else { - normFilePath = filePath; - } - - removeSlashFromPath(normFilePath); - if (matchNonContent(normFilePath)) { - VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - name, - filePath); - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - - if (testObject(VSearchConfig::Outline)) { - VSearchResultItem *item = searchForOutline(p_file); - if (item) { - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - - if (testObject(VSearchConfig::Tag)) { - VSearchResultItem *item = searchForTag(p_file); - if (item) { - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - - if (testObject(VSearchConfig::Content)) { - // Search content in first phase. - if (p_searchContent) { - VSearchResultItem *item = searchForContent(p_file); - if (item) { - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } else { - // Add an item for second phase process. - p_result->addSecondPhaseItem(filePath); - } - } -} - -void VSearch::searchFirstPhase(VDirectory *p_directory, - const QSharedPointer &p_result) -{ - Q_ASSERT(testTarget(VSearchConfig::Note) || testTarget(VSearchConfig::Folder)); - - bool opened = p_directory->isOpened(); - if (!opened && !p_directory->open()) { - p_result->logError(QString("Fail to open folder %1.").arg(p_directory->fetchRelativePath())); - p_result->m_state = VSearchState::Fail; - return; - } - - if (testTarget(VSearchConfig::Folder)) { - QString name = p_directory->getName(); - QString dirPath = p_directory->fetchPath(); - if (testObject(VSearchConfig::Name)) { - if (matchNonContent(name)) { - VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Folder, - VSearchResultItem::LineNumber, - name, - dirPath); - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - - if (testObject(VSearchConfig::Path)) { - QString normPath(p_directory->fetchRelativePath()); - removeSlashFromPath(normPath); - if (matchNonContent(normPath)) { - VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Folder, - VSearchResultItem::LineNumber, - name, - dirPath); - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - } - - // Search files. - if (testTarget(VSearchConfig::Note)) { - for (auto const & file : p_directory->getFiles()) { - if (askedToStop()) { - qDebug() << "asked to cancel the search"; - p_result->m_state = VSearchState::Cancelled; - goto exit; - } - - searchFirstPhase(file, p_result); - } - } - - // Search subfolders. - for (auto const & dir : p_directory->getSubDirs()) { - if (askedToStop()) { - qDebug() << "asked to cancel the search"; - p_result->m_state = VSearchState::Cancelled; - goto exit; - } - - searchFirstPhase(dir, p_result); - } - -exit: - if (!opened) { - p_directory->close(); - } -} - -void VSearch::searchFirstPhase(VNotebook *p_notebook, - const QSharedPointer &p_result) -{ - bool opened = p_notebook->isOpened(); - if (!opened && !p_notebook->open()) { - p_result->logError(QString("Fail to open notebook %1.").arg(p_notebook->getName())); - p_result->m_state = VSearchState::Fail; - return; - } - - if (testTarget(VSearchConfig::Notebook) - && testObject(VSearchConfig::Name)) { - QString text = p_notebook->getName(); - if (matchNonContent(text)) { - VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Notebook, - VSearchResultItem::LineNumber, - text, - p_notebook->getPath()); - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - - if (!testTarget(VSearchConfig::Note) - && !testTarget(VSearchConfig::Folder)) { - goto exit; - } - - // Search for subfolders. - for (auto const & dir : p_notebook->getRootDir()->getSubDirs()) { - if (askedToStop()) { - qDebug() << "asked to cancel the search"; - p_result->m_state = VSearchState::Cancelled; - goto exit; - } - - searchFirstPhase(dir, p_result); - } - -exit: - if (!opened) { - p_notebook->close(); - } -} - -void VSearch::searchFirstPhase(const QString &p_basePath, - const QString &p_directoryPath, - const QSharedPointer &p_result) -{ - Q_ASSERT(testTarget(VSearchConfig::Note) || testTarget(VSearchConfig::Folder)); - Q_ASSERT(!p_directoryPath.isEmpty()); - - QDir dir(p_directoryPath); - if (!dir.exists()) { - p_result->logError(QString("Directory %1 does not exist.").arg(p_directoryPath)); - p_result->m_state = VSearchState::Fail; - return; - } - - Q_ASSERT(dir.isAbsolute()); - - if (testTarget(VSearchConfig::Folder)) { - QString name = dir.dirName(); - if (testObject(VSearchConfig::Name)) { - if (matchNonContent(name)) { - VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Folder, - VSearchResultItem::LineNumber, - name, - p_directoryPath); - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - - if (testObject(VSearchConfig::Path)) { - QString normPath(QDir(p_basePath).relativeFilePath(p_directoryPath)); - removeSlashFromPath(normPath); - if (matchNonContent(normPath)) { - VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Folder, - VSearchResultItem::LineNumber, - name, - p_directoryPath); - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - } - - if (testTarget(VSearchConfig::Note)) { - QStringList files = dir.entryList(QDir::Files); - for (auto const & file : files) { - if (askedToStop()) { - qDebug() << "asked to cancel the search"; - p_result->m_state = VSearchState::Cancelled; - return; - } - - searchFirstPhaseFile(p_basePath, dir.absoluteFilePath(file), p_result); - } - } - - // Search subfolders. - QStringList subdirs = dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); - for (auto const & sub : subdirs) { - if (askedToStop()) { - qDebug() << "asked to cancel the search"; - p_result->m_state = VSearchState::Cancelled; - return; - } - - searchFirstPhase(p_basePath, dir.absoluteFilePath(sub), p_result); - } -} - -void VSearch::searchFirstPhaseFile(const QString &p_basePath, - const QString &p_filePath, - const QSharedPointer &p_result) -{ - Q_ASSERT(testTarget(VSearchConfig::Note)); - - QString name = VUtils::fileNameFromPath(p_filePath); - if (!matchPattern(name)) { - return; - } - - if (testObject(VSearchConfig::Name)) { - if (matchNonContent(name)) { - VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - name, - p_filePath); - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - - if (testObject(VSearchConfig::Path)) { - QString normFilePath(QDir(p_basePath).relativeFilePath(p_filePath)); - removeSlashFromPath(normFilePath); - if (matchNonContent(normFilePath)) { - VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - name, - p_filePath); - QSharedPointer pitem(item); - emit resultItemAdded(pitem); - } - } - - if (testObject(VSearchConfig::Content)) { - // Add an item for second phase process. - p_result->addSecondPhaseItem(p_filePath); - } -} - -VSearchResultItem *VSearch::searchForOutline(const VFile *p_file) const -{ - VEditTab *tab = g_mainWin->getEditArea()->getTab(p_file); - if (!tab) { - return NULL; - } - - const VTableOfContent &toc = tab->getOutline(); - const QVector &table = toc.getTable(); - VSearchResultItem *item = NULL; - for (auto const & it: table) { - if (it.isEmpty()) { - continue; - } - - if (!matchNonContent(it.m_name)) { - continue; - } - - if (!item) { - item = new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::OutlineIndex, - p_file->getName(), - p_file->fetchPath(), - m_config); - } - - VSearchResultSubItem sitem(it.m_index, it.m_name); - item->m_matches.append(sitem); - } - - return item; -} - -VSearchResultItem *VSearch::searchForTag(const VFile *p_file) const -{ - if (p_file->getType() != FileType::Note) { - return NULL; - } - - const VNoteFile *file = static_cast(p_file); - const QStringList &tags = file->getTags(); - - VSearchToken &contentToken = m_config->m_contentToken; - bool singleToken = contentToken.tokenSize() == 1; - if (!singleToken) { - contentToken.startBatchMode(); - } - - VSearchResultItem *item = NULL; - bool allMatched = false; - - for (int i = 0; i < tags.size(); ++i) { - const QString &tag = tags[i]; - if (tag.isEmpty()) { - continue; - } - - bool matched = false; - if (singleToken) { - matched = contentToken.matched(tag); - } else { - matched = contentToken.matchBatchMode(tag); - } - - if (matched) { - if (!item) { - item = new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - file->getName(), - file->fetchPath()); - } - - VSearchResultSubItem sitem(i, tag); - item->m_matches.append(sitem); - } - - if (!singleToken && contentToken.readyToEndBatchMode(allMatched)) { - break; - } - } - - if (!singleToken) { - contentToken.readyToEndBatchMode(allMatched); - contentToken.endBatchMode(); - - if (!allMatched && item) { - // This file does not meet all the tokens. - delete item; - item = NULL; - } - } - - return item; -} - -VSearchResultItem *VSearch::searchForContent(const VFile *p_file) const -{ - Q_ASSERT(p_file->isOpened()); - const QString &content = p_file->getContent(); - if (content.isEmpty()) { - return NULL; - } - - VSearchResultItem *item = NULL; - int lineNum = 1; - int pos = 0; - int size = content.size(); - QRegExp newLineReg = QRegExp("\\n|\\r\\n|\\r"); - VSearchToken &contentToken = m_config->m_contentToken; - bool singleToken = contentToken.tokenSize() == 1; - if (!singleToken) { - contentToken.startBatchMode(); - } - - bool allMatched = false; - - while (pos < size) { - int idx = content.indexOf(newLineReg, pos); - if (idx == -1) { - idx = size; - } - - if (idx > pos) { - QString lineText = content.mid(pos, idx - pos); - bool matched = false; - if (singleToken) { - matched = contentToken.matched(lineText); - } else { - matched = contentToken.matchBatchMode(lineText); - } - - if (matched) { - if (!item) { - item = new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - p_file->getName(), - p_file->fetchPath(), - m_config); - } - - VSearchResultSubItem sitem(lineNum, lineText); - item->m_matches.append(sitem); - } - } - - if (idx == size) { - break; - } - - if (!singleToken && contentToken.readyToEndBatchMode(allMatched)) { - break; - } - - pos = idx + newLineReg.matchedLength(); - ++lineNum; - } - - if (!singleToken) { - contentToken.readyToEndBatchMode(allMatched); - contentToken.endBatchMode(); - - if (!allMatched && item) { - // This file does not meet all the tokens. - delete item; - item = NULL; - } - } - - return item; -} - -void VSearch::searchSecondPhase(const QSharedPointer &p_result) -{ - delete m_engine; - m_engine = NULL; - - switch (m_config->m_engine) { - case VSearchConfig::Internal: - { - m_engine = new VSearchEngine(this); - m_engine->search(m_config, p_result); - break; - } - - default: - p_result->m_state = VSearchState::Success; - break; - } - - if (m_engine) { - connect(m_engine, &ISearchEngine::finished, - this, &VSearch::finished); - connect(m_engine, &ISearchEngine::resultItemsAdded, - this, &VSearch::resultItemsAdded); - } -} - -void VSearch::clear() -{ - m_config.clear(); - - if (m_engine) { - m_engine->clear(); - - delete m_engine; - m_engine = NULL; - } - - m_askedToStop = false; -} - -void VSearch::stop() -{ - qDebug() << "VSearch asked to stop"; - m_askedToStop = true; - - if (m_engine) { - m_engine->stop(); - } -} diff --git a/src/vsearch.h b/src/vsearch.h deleted file mode 100644 index 09d9ffd0..00000000 --- a/src/vsearch.h +++ /dev/null @@ -1,157 +0,0 @@ -#ifndef VSEARCH_H -#define VSEARCH_H - -#include -#include -#include -#include -#include - -#include "vsearchconfig.h" - -class VFile; -class VDirectory; -class VNotebook; -class ISearchEngine; - - -class VSearch : public QObject -{ - Q_OBJECT -public: - explicit VSearch(QObject *p_parent = nullptr); - - void setConfig(QSharedPointer p_config); - - // Search list of files for CurrentNote and OpenedNotes. - QSharedPointer search(const QVector &p_files); - - // Search folder for CurrentFolder. - QSharedPointer search(VDirectory *p_directory); - - // Search folder for CurrentNotebook and AllNotebooks. - QSharedPointer search(const QVector &p_notebooks); - - // Search directory path for ExplorerDirectory. - QSharedPointer search(const QString &p_directoryPath); - - // Clear resources after a search completed. - void clear(); - - void stop(); - -signals: - // Emitted when a new item added as result. - void resultItemAdded(const QSharedPointer &p_item); - - void resultItemsAdded(const QList > &p_items); - - // Emitted when async task finished. - void finished(const QSharedPointer &p_result); - -private: - bool askedToStop() const; - - // @p_searchContent: whether search content in first phase. - void searchFirstPhase(VFile *p_file, - const QSharedPointer &p_result, - bool p_searchContent = false); - - void searchFirstPhase(VDirectory *p_directory, - const QSharedPointer &p_result); - - void searchFirstPhase(VNotebook *p_notebook, - const QSharedPointer &p_result); - - void searchFirstPhase(const QString &p_basePath, - const QString &p_directoryPath, - const QSharedPointer &p_result); - - void searchFirstPhaseFile(const QString &p_basePath, - const QString &p_filePath, - const QSharedPointer &p_result); - - bool testTarget(VSearchConfig::Target p_target) const; - - bool testObject(VSearchConfig::Object p_object) const; - - bool testOption(VSearchConfig::Option p_option) const; - - bool matchNonContent(const QString &p_text) const; - - bool matchPattern(const QString &p_name) const; - - VSearchResultItem *searchForOutline(const VFile *p_file) const; - - VSearchResultItem *searchForTag(const VFile *p_file) const; - - VSearchResultItem *searchForContent(const VFile *p_file) const; - - void searchSecondPhase(const QSharedPointer &p_result); - - void removeSlashFromPath(QString &p_path); - - bool m_askedToStop; - - QSharedPointer m_config; - - ISearchEngine *m_engine; - - // Wildcard reg to for file name pattern. - QRegExp m_patternReg; - - // Remove slashes. - QRegExp m_slashReg; -}; - -inline bool VSearch::askedToStop() const -{ - QCoreApplication::processEvents(); - return m_askedToStop; -} - -inline void VSearch::setConfig(QSharedPointer p_config) -{ - m_config = p_config; - - if (m_config->m_pattern.isEmpty()) { - m_patternReg = QRegExp(); - } else { - m_patternReg = QRegExp(m_config->m_pattern, Qt::CaseInsensitive, QRegExp::Wildcard); - } -} - -inline bool VSearch::testTarget(VSearchConfig::Target p_target) const -{ - return p_target & m_config->m_target; -} - -inline bool VSearch::testObject(VSearchConfig::Object p_object) const -{ - return p_object & m_config->m_object; -} - -inline bool VSearch::testOption(VSearchConfig::Option p_option) const -{ - return p_option & m_config->m_option; -} - -inline bool VSearch::matchNonContent(const QString &p_text) const -{ - return m_config->m_token.matched(p_text); -} - -inline bool VSearch::matchPattern(const QString &p_name) const -{ - if (m_patternReg.isEmpty()) { - return true; - } - - return p_name.contains(m_patternReg); -} - -inline void VSearch::removeSlashFromPath(QString &p_path) -{ - p_path.remove(m_slashReg); -} -#endif // VSEARCH_H diff --git a/src/vsearchconfig.h b/src/vsearchconfig.h deleted file mode 100644 index 25668218..00000000 --- a/src/vsearchconfig.h +++ /dev/null @@ -1,614 +0,0 @@ -#ifndef VSEARCHCONFIG_H -#define VSEARCHCONFIG_H - -#include -#include -#include -#include -#include - -#include "utils/vutils.h" - - -struct VSearchToken -{ - enum Type - { - RawString = 0, - RegularExpression - }; - - enum Operator - { - And = 0, - Or - }; - - VSearchToken() - : m_type(Type::RawString), - m_op(Operator::And), - m_caseSensitivity(Qt::CaseSensitive) - { - } - - void clear() - { - m_keywords.clear(); - m_regs.clear(); - } - - void append(const QString &p_rawStr) - { - m_keywords.append(p_rawStr); - } - - void append(const QRegExp &p_reg) - { - m_regs.append(p_reg); - } - - QString toString() const - { - return QString("token %1 %2 %3 %4 %5").arg(m_type) - .arg(m_op) - .arg(m_caseSensitivity) - .arg(m_keywords.size()) - .arg(m_regs.size()); - } - - // Whether @p_text match all the constraint. - bool matched(const QString &p_text) const - { - int size = m_keywords.size(); - if (m_type == Type::RegularExpression) { - size = m_regs.size(); - } - - if (size == 0) { - return false; - } - - bool ret = m_op == Operator::And ? true : false; - for (int i = 0; i < size; ++i) { - bool tmp = false; - if (m_type == Type::RawString) { - tmp = p_text.contains(m_keywords[i], m_caseSensitivity); - } else { - tmp = p_text.contains(m_regs[i]); - } - - if (tmp) { - if (m_op == Operator::Or) { - ret = true; - break; - } - } else { - if (m_op == Operator::And) { - ret = false; - break; - } - } - } - - return ret; - } - - void startBatchMode() - { - int size = m_type == Type::RawString ? m_keywords.size() : m_regs.size(); - m_matchesInBatch.resize(size); - m_matchesInBatch.fill(false); - m_numOfMatches = 0; - } - - // Match one string in batch mode. - // Returns true if @p_text matches one. - bool matchBatchMode(const QString &p_text) - { - bool ret = false; - int size = m_matchesInBatch.size(); - for (int i = 0; i < size; ++i) { - if (m_matchesInBatch[i]) { - continue; - } - - bool tmp = false; - if (m_type == Type::RawString) { - tmp = p_text.contains(m_keywords[i], m_caseSensitivity); - } else { - tmp = p_text.contains(m_regs[i]); - } - - if (tmp) { - m_matchesInBatch[i] = true; - ++m_numOfMatches; - ret = true; - } - } - - return ret; - } - - // Whether it is OK to finished batch mode. - // @p_matched: the overall match result. - bool readyToEndBatchMode(bool &p_matched) const - { - if (m_op == VSearchToken::And) { - // We need all the tokens matched. - if (m_numOfMatches == m_matchesInBatch.size()) { - p_matched = true; - return true; - } else { - p_matched = false; - return false; - } - } else { - // We only need one match. - if (m_numOfMatches > 0) { - p_matched = true; - return true; - } else { - p_matched = false; - return false; - } - } - } - - void endBatchMode() - { - m_matchesInBatch.clear(); - m_numOfMatches = 0; - } - - int tokenSize() const - { - return m_type == Type::RawString ? m_keywords.size() : m_regs.size(); - } - - bool isEmpty() const - { - return tokenSize() == 0; - } - - bool operator==(const VSearchToken &p_other) const - { - if (m_type != p_other.m_type - || m_op != p_other.m_op - || m_caseSensitivity != p_other.m_caseSensitivity - || m_keywords.size() != p_other.m_keywords.size() - || m_numOfMatches != p_other.m_numOfMatches - || m_regs.size() != p_other.m_regs.size()) { - return false; - } - - return m_keywords == p_other.m_keywords - && m_regs == p_other.m_regs; - } - - VSearchToken::Type m_type; - - VSearchToken::Operator m_op; - - Qt::CaseSensitivity m_caseSensitivity; - - // Valid at RawString. - QVector m_keywords; - - // Valid at RegularExpression. - QVector m_regs; - - // Bitmap for batch mode. - // True if m_regs[i] or m_keywords[i] has been matched. - QVector m_matchesInBatch; - - int m_numOfMatches; -}; - - -struct VSearchConfig -{ - enum Scope - { - NoneScope = 0, - CurrentNote, - OpenedNotes, - CurrentFolder, - CurrentNotebook, - AllNotebooks, - ExplorerDirectory - }; - - enum Object - { - NoneObject = 0, - Name = 0x1UL, - Content = 0x2UL, - Outline = 0x4UL, - Tag = 0x8UL, - Path = 0x10UL - }; - - enum Target - { - NoneTarget = 0, - Note = 0x1UL, - Folder = 0x2UL, - Notebook = 0x4UL - }; - - enum Engine - { - Internal = 0 - }; - - enum Option - { - NoneOption = 0, - CaseSensitive = 0x1UL, - WholeWordOnly = 0x2UL, - Fuzzy = 0x4UL, - RegularExpression = 0x8UL - }; - - - VSearchConfig() - : VSearchConfig(Scope::NoneScope, - Object::NoneObject, - Target::NoneTarget, - Engine::Internal, - Option::NoneOption, - "", - "") - { - } - - - VSearchConfig(int p_scope, - int p_object, - int p_target, - int p_engine, - int p_option, - const QString &p_keyword, - const QString &p_pattern) - : m_scope(p_scope), - m_object(p_object), - m_target(p_target), - m_engine(p_engine), - m_option(p_option), - m_pattern(p_pattern) - { - compileToken(p_keyword); - } - - // We support some magic switch in the keyword which will suppress the specified - // options: - // \c: Case insensitive; - // \C: Case sensitive; - // \r: Turn off regular expression; - // \R: Turn on regular expression; - // \f: Turn off fuzzy search; - // \F: Turn on fuzzy search (invalid when searching content); - // \w: Turn off whole word only; - // \W: Turn on whole word only; - void compileToken(const QString &p_keyword) - { - m_token.clear(); - m_contentToken.clear(); - if (p_keyword.isEmpty()) { - return; - } - - // """ to input a "; - // && for AND, || for OR; - QStringList args = VUtils::parseCombinedArgString(p_keyword); - - Qt::CaseSensitivity cs = m_option & VSearchConfig::CaseSensitive - ? Qt::CaseSensitive : Qt::CaseInsensitive; - bool useReg = m_option & VSearchConfig::RegularExpression; - bool wwo = m_option & VSearchConfig::WholeWordOnly; - bool fuzzy = m_option & VSearchConfig::Fuzzy; - - // Read magic switch from keyword. - for (int i = 0; i < args.size();) { - const QString &arg = args[i]; - if (arg.size() != 2 || arg[0] != '\\') { - ++i; - continue; - } - - if (arg == "\\c") { - cs = Qt::CaseInsensitive; - } else if (arg == "\\C") { - cs = Qt::CaseSensitive; - } else if (arg == "\\r") { - useReg = false; - } else if (arg == "\\R") { - useReg = true; - } else if (arg == "\\f") { - fuzzy = false; - } else if (arg == "\\F") { - fuzzy = true; - } else if (arg == "\\w") { - wwo = false; - } else if (arg == "\\W") { - wwo = true; - } else { - ++i; - continue; - } - - args.removeAt(i); - } - - if (args.isEmpty()) { - return; - } - - m_token.m_caseSensitivity = cs; - m_contentToken.m_caseSensitivity = cs; - - if (useReg) { - m_token.m_type = VSearchToken::RegularExpression; - m_contentToken.m_type = VSearchToken::RegularExpression; - } else { - if (fuzzy) { - m_token.m_type = VSearchToken::RegularExpression; - m_contentToken.m_type = VSearchToken::RawString; - } else if (wwo) { - m_token.m_type = VSearchToken::RegularExpression; - m_contentToken.m_type = VSearchToken::RegularExpression; - } else { - m_token.m_type = VSearchToken::RawString; - m_contentToken.m_type = VSearchToken::RawString; - } - } - - VSearchToken::Operator op = VSearchToken::And; - for (auto const & arg : args) { - if (arg == QStringLiteral("&&")) { - op = VSearchToken::And; - continue; - } else if (arg == QStringLiteral("||")) { - op = VSearchToken::Or; - continue; - } - - if (useReg) { - QRegExp reg(arg, cs); - m_token.append(reg); - m_contentToken.append(reg); - } else { - if (fuzzy) { - QString wildcardText(arg.size() * 2 + 1, '*'); - for (int i = 0, j = 1; i < arg.size(); ++i, j += 2) { - wildcardText[j] = arg[i]; - } - - QRegExp reg(wildcardText, cs, QRegExp::Wildcard); - m_token.append(reg); - m_contentToken.append(arg); - } else if (wwo) { - QString pattern = QRegExp::escape(arg); - pattern = "\\b" + pattern + "\\b"; - - QRegExp reg(pattern, cs); - m_token.append(reg); - m_contentToken.append(reg); - } else { - m_token.append(arg); - m_contentToken.append(arg); - } - } - } - - m_token.m_op = op; - m_contentToken.m_op = op; - } - - bool isEmpty() const - { - return m_token.tokenSize() == 0; - } - - QStringList toConfig() const - { - QStringList str; - str << QString::number(m_scope); - str << QString::number(m_object); - str << QString::number(m_target); - str << QString::number(m_engine); - str << QString::number(m_option); - str << m_pattern; - - return str; - } - - static VSearchConfig fromConfig(const QStringList &p_str) - { - VSearchConfig config; - if (p_str.size() != 6) { - return config; - } - - config.m_scope = p_str[0].toInt(); - config.m_object = p_str[1].toInt(); - config.m_target = p_str[2].toInt(); - config.m_engine = p_str[3].toInt(); - config.m_option = p_str[4].toInt(); - config.m_pattern = p_str[5]; - - return config; - } - - int m_scope; - int m_object; - int m_target; - int m_engine; - int m_option; - - // Wildcard pattern to filter file. - QString m_pattern; - - // Token for name, outline. - VSearchToken m_token; - - // Token for content and tag. - VSearchToken m_contentToken; -}; - - -struct VSearchResultSubItem -{ - VSearchResultSubItem() - : m_lineNumber(-1) - { - } - - VSearchResultSubItem(int p_lineNumber, - const QString &p_text) - : m_lineNumber(p_lineNumber), - m_text(p_text) - { - } - - int m_lineNumber; - - QString m_text; -}; - - -struct VSearchResultItem -{ - enum ItemType - { - None = 0, - Note, - Folder, - Notebook - }; - - - enum MatchType - { - LineNumber = 0, - OutlineIndex - }; - - - VSearchResultItem() - : m_type(ItemType::None), - m_matchType(MatchType::LineNumber) - { - } - - VSearchResultItem(VSearchResultItem::ItemType p_type, - VSearchResultItem::MatchType p_matchType, - const QString &p_text, - const QString &p_path, - const QSharedPointer &p_config = nullptr) - : m_type(p_type), - m_matchType(p_matchType), - m_text(p_text), - m_path(p_path), - m_config(p_config) - { - } - - bool isEmpty() const - { - return m_type == ItemType::None; - } - - QString toString() const - { - return QString("item text: [%1] path: [%2] subitems: %3") - .arg(m_text) - .arg(m_path) - .arg(m_matches.size()); - } - - - ItemType m_type; - - MatchType m_matchType; - - // Text to displayed. If empty, use @m_path instead. - QString m_text; - - // Path of the target. - QString m_path; - - // Matched places within this item. - QList m_matches; - - // Search config to search for this item. - QSharedPointer m_config; -}; - - -class VSearch; - - -enum class VSearchState -{ - Idle = 0, - Busy, - Success, - Fail, - Cancelled -}; - - -struct VSearchResult -{ - friend class VSearch; - - explicit VSearchResult(VSearch *p_search) - : m_state(VSearchState::Idle), - m_search(p_search) - { - } - - bool hasError() const - { - return !m_errMsg.isEmpty(); - } - - void logError(const QString &p_err) - { - if (m_errMsg.isEmpty()) { - m_errMsg = p_err; - } else { - m_errMsg = "\n" + p_err; - } - } - - void addSecondPhaseItem(const QString &p_item) - { - m_secondPhaseItems.append(p_item); - } - - QString toString() const - { - QString str = QString("search result: state %1 err %2") - .arg((int)m_state) - .arg(!m_errMsg.isEmpty()); - return str; - } - - bool hasSecondPhaseItems() const - { - return !m_secondPhaseItems.isEmpty(); - } - - VSearchState m_state; - - QString m_errMsg; - - QStringList m_secondPhaseItems; - -private: - VSearch *m_search; -}; - -#endif // VSEARCHCONFIG_H diff --git a/src/vsearchengine.cpp b/src/vsearchengine.cpp deleted file mode 100644 index 07994c13..00000000 --- a/src/vsearchengine.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include "vsearchengine.h" - -#include -#include -#include - -#include "utils/vutils.h" - -VSearchEngineWorker::VSearchEngineWorker(QObject *p_parent) - : QThread(p_parent), - m_stop(0), - m_state(VSearchState::Idle) -{ -} - -void VSearchEngineWorker::setData(const QStringList &p_files, - const VSearchToken &p_token, - const QSharedPointer &p_config) -{ - m_files = p_files; - m_token = p_token; - m_config = p_config; -} - -void VSearchEngineWorker::stop() -{ - m_stop.store(1); -} - -void VSearchEngineWorker::run() -{ - qDebug() << "worker" << QThread::currentThreadId() << m_files.size(); - - QMimeDatabase mimeDatabase; - m_state = VSearchState::Busy; - - m_results.clear(); - int nr = 0; - for (auto const & fileName : m_files) { - if (m_stop.load() == 1) { - m_state = VSearchState::Cancelled; - qDebug() << "worker" << QThread::currentThreadId() << "is asked to stop"; - break; - } - - const QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileName); - if (mimeType.isValid() && !mimeType.inherits(QStringLiteral("text/plain"))) { - appendError(tr("Skip binary file %1.").arg(fileName)); - continue; - } - - VSearchResultItem *item = searchFile(fileName); - if (item) { - m_results.append(QSharedPointer(item)); - } - - if (++nr >= BATCH_ITEM_SIZE) { - nr = 0; - postAndClearResults(); - } - } - - postAndClearResults(); - - if (m_state == VSearchState::Busy) { - m_state = VSearchState::Success; - } -} - -VSearchResultItem *VSearchEngineWorker::searchFile(const QString &p_fileName) -{ - QFile file(p_fileName); - if (!file.open(QIODevice::ReadOnly)) { - return NULL; - } - - int lineNum = 1; - VSearchResultItem *item = NULL; - QString line; - QTextStream in(&file); - - bool singleToken = m_token.tokenSize() == 1; - if (!singleToken) { - m_token.startBatchMode(); - } - - bool allMatched = false; - - while (!in.atEnd()) { - if (m_stop.load() == 1) { - m_state = VSearchState::Cancelled; - qDebug() << "worker" << QThread::currentThreadId() << "is asked to stop"; - break; - } - - line = in.readLine(); - bool matched = false; - if (singleToken) { - matched = m_token.matched(line); - } else { - matched = m_token.matchBatchMode(line); - } - - if (matched) { - if (!item) { - item = new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - VUtils::fileNameFromPath(p_fileName), - p_fileName, - m_config); - } - - VSearchResultSubItem sitem(lineNum, line); - item->m_matches.append(sitem); - } - - if (!singleToken && m_token.readyToEndBatchMode(allMatched)) { - break; - } - - ++lineNum; - } - - if (!singleToken) { - m_token.readyToEndBatchMode(allMatched); - m_token.endBatchMode(); - - if (!allMatched && item) { - delete item; - item = NULL; - } - } - - return item; -} - -void VSearchEngineWorker::postAndClearResults() -{ - if (!m_results.isEmpty()) { - emit resultItemsReady(m_results); - m_results.clear(); - } -} - - -VSearchEngine::VSearchEngine(QObject *p_parent) - : ISearchEngine(p_parent), - m_finishedWorkers(0) -{ -} - -VSearchEngine::~VSearchEngine() -{ - // stop() - for (auto const & th : m_workers) { - th->stop(); - } - - // clear() - clearAllWorkers(); - - m_finishedWorkers = 0; - - m_result.clear(); -} - -void VSearchEngine::search(const QSharedPointer &p_config, - const QSharedPointer &p_result) -{ - int numThread = QThread::idealThreadCount(); - if (numThread < 1) { - numThread = 1; - } - - const QStringList items = p_result->m_secondPhaseItems; - Q_ASSERT(!items.isEmpty()); - if (items.size() < numThread) { - numThread = items.size(); - } - - m_result = p_result; - - clearAllWorkers(); - m_workers.reserve(numThread); - m_finishedWorkers = 0; - int totalSize = m_result->m_secondPhaseItems.size(); - int step = totalSize / numThread; - int remain = totalSize % numThread; - int start = 0; - for (int i = 0; i < numThread && start < totalSize; ++i) { - int len = step; - if (remain) { - ++len; - --remain; - } - - if (start + len > totalSize) { - len = totalSize - start; - } - - VSearchEngineWorker *th = new VSearchEngineWorker(this); - th->setData(m_result->m_secondPhaseItems.mid(start, len), - p_config->m_contentToken, - p_config); - connect(th, &VSearchEngineWorker::finished, - this, &VSearchEngine::handleWorkerFinished); - connect(th, &VSearchEngineWorker::resultItemsReady, - this, [this](const QList > &p_items) { - emit resultItemsAdded(p_items); - }); - - m_workers.append(th); - th->start(); - - start += len; - } - - qDebug() << "schedule tasks to threads" << m_workers.size() << totalSize << step; -} - -void VSearchEngine::stop() -{ - qDebug() << "VSearchEngine asked to stop"; - for (auto const & th : m_workers) { - th->stop(); - } -} - -void VSearchEngine::handleWorkerFinished() -{ - ++m_finishedWorkers; - - qDebug() << m_finishedWorkers << "workers finished"; - if (m_finishedWorkers == m_workers.size()) { - VSearchState state = VSearchState::Success; - - for (auto const & th : m_workers) { - if (th->m_state == VSearchState::Fail) { - if (state != VSearchState::Cancelled) { - state = VSearchState::Fail; - } - } else if (th->m_state == VSearchState::Cancelled) { - state = VSearchState::Cancelled; - } - - if (!th->m_error.isEmpty()) { - m_result->logError(th->m_error); - } - - Q_ASSERT(th->isFinished()); - th->deleteLater(); - } - - m_workers.clear(); - m_finishedWorkers = 0; - - m_result->m_state = state; - qDebug() << "SearchEngine finished" << (int)state; - emit finished(m_result); - } -} - -void VSearchEngine::clear() -{ - clearAllWorkers(); - - m_finishedWorkers = 0; - - m_result.clear(); -} - -void VSearchEngine::clearAllWorkers() -{ - for (auto const & th : m_workers) { - th->quit(); - th->wait(); - - delete th; - } - - m_workers.clear(); -} diff --git a/src/vsearchengine.h b/src/vsearchengine.h deleted file mode 100644 index f34eff01..00000000 --- a/src/vsearchengine.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef VSEARCHENGINE_H -#define VSEARCHENGINE_H - -#include "isearchengine.h" - -#include -#include -#include -#include - -#include "vsearchconfig.h" - -#define BATCH_ITEM_SIZE 100 - -class VSearchEngineWorker : public QThread -{ - Q_OBJECT - - friend class VSearchEngine; - -public: - explicit VSearchEngineWorker(QObject *p_parent = nullptr); - - void setData(const QStringList &p_files, - const VSearchToken &p_token, - const QSharedPointer &p_config); - -public slots: - void stop(); - -signals: - void resultItemsReady(const QList > &p_items); - -protected: - void run() Q_DECL_OVERRIDE; - -private: - void appendError(const QString &p_err); - - VSearchResultItem *searchFile(const QString &p_fileName); - - void postAndClearResults(); - - QAtomicInt m_stop; - - QStringList m_files; - - VSearchToken m_token; - - QSharedPointer m_config; - - VSearchState m_state; - - QString m_error; - - QList > m_results; -}; - -inline void VSearchEngineWorker::appendError(const QString &p_err) -{ - if (m_error.isEmpty()) { - m_error = p_err; - } else { - m_error = "\n" + p_err; - } -} - - -class VSearchEngine : public ISearchEngine -{ - Q_OBJECT -public: - explicit VSearchEngine(QObject *p_parent = nullptr); - - ~VSearchEngine(); - - void search(const QSharedPointer &p_config, - const QSharedPointer &p_result) Q_DECL_OVERRIDE; - - void stop() Q_DECL_OVERRIDE; - - void clear() Q_DECL_OVERRIDE; - -private slots: - void handleWorkerFinished(); - -private: - void clearAllWorkers(); - - int m_finishedWorkers; - - QVector m_workers; -}; - -#endif // VSEARCHENGINE_H diff --git a/src/vsearcher.cpp b/src/vsearcher.cpp deleted file mode 100644 index 3fa5891b..00000000 --- a/src/vsearcher.cpp +++ /dev/null @@ -1,627 +0,0 @@ -#include "vsearcher.h" - -#include -#include - -#include "vlineedit.h" -#include "utils/vutils.h" -#include "utils/viconutils.h" -#include "vsearch.h" -#include "vsearchresulttree.h" -#include "vmainwindow.h" -#include "veditarea.h" -#include "vdirectorytree.h" -#include "vdirectory.h" -#include "vnotebookselector.h" -#include "vnotebook.h" -#include "vnote.h" -#include "vconfigmanager.h" -#include "vexplorer.h" -#include "vconstants.h" - -extern VMainWindow *g_mainWin; - -extern VNote *g_vnote; - -extern VConfigManager *g_config; - -VSearcher::VSearcher(QWidget *p_parent) - : QWidget(p_parent), - m_initialized(false), - m_uiInitialized(false), - m_inSearch(false), - m_askedToStop(false), - m_search(this) -{ - qRegisterMetaType>>("QList>"); -} - -void VSearcher::setupUI() -{ - if (m_uiInitialized) { - return; - } - - m_uiInitialized = true; - - // Search button. - m_searchBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/search.svg"), "", this); - m_searchBtn->setToolTip(tr("Search")); - m_searchBtn->setProperty("FlatBtn", true); - connect(m_searchBtn, &QPushButton::clicked, - this, &VSearcher::startSearch); - - // Clear button. - m_clearBtn = new QPushButton(VIconUtils::buttonDangerIcon(":/resources/icons/clear_search.svg"), "", this); - m_clearBtn->setToolTip(tr("Clear Results")); - m_clearBtn->setProperty("FlatBtn", true); - connect(m_clearBtn, &QPushButton::clicked, - this, [this]() { - m_results->clearResults(); - }); - - // Advanced button. - m_advBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/search_advanced.svg"), - "", - this); - m_advBtn->setToolTip(tr("Advanced Settings")); - m_advBtn->setProperty("FlatBtn", true); - m_advBtn->setCheckable(true); - connect(m_advBtn, &QPushButton::toggled, - this, [this](bool p_checked) { - m_advWidget->setVisible(p_checked); - }); - - // Console button. - m_consoleBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/search_console.svg"), - "", - this); - m_consoleBtn->setToolTip(tr("Console")); - m_consoleBtn->setProperty("FlatBtn", true); - m_consoleBtn->setCheckable(true); - connect(m_consoleBtn, &QPushButton::toggled, - this, [this](bool p_checked) { - m_consoleEdit->setVisible(p_checked); - }); - - m_numLabel = new QLabel(this); - - QHBoxLayout *btnLayout = new QHBoxLayout(); - btnLayout->addWidget(m_searchBtn); - btnLayout->addWidget(m_clearBtn); - btnLayout->addWidget(m_advBtn); - btnLayout->addWidget(m_consoleBtn); - btnLayout->addStretch(); - btnLayout->addWidget(m_numLabel); - btnLayout->setContentsMargins(0, 0, 0, 0); - - // Keyword. - m_keywordCB = VUtils::getComboBox(this); - m_keywordCB->setEditable(true); - m_keywordCB->setLineEdit(new VLineEdit(this)); - m_keywordCB->setToolTip(tr("Keywords to search for")); - m_keywordCB->lineEdit()->setPlaceholderText(tr("Supports space, &&, and ||")); - m_keywordCB->lineEdit()->setProperty("EmbeddedEdit", true); - connect(m_keywordCB, &QComboBox::currentTextChanged, - this, &VSearcher::handleInputChanged); - connect(m_keywordCB->lineEdit(), &QLineEdit::returnPressed, - this, &VSearcher::animateSearchClick); - m_keywordCB->completer()->setCaseSensitivity(Qt::CaseSensitive); - - // Scope. - m_searchScopeCB = VUtils::getComboBox(this); - m_searchScopeCB->setToolTip(tr("Scope to search")); - connect(m_searchScopeCB, static_cast(&QComboBox::currentIndexChanged), - this, &VSearcher::handleInputChanged); - - // Object. - m_searchObjectCB = VUtils::getComboBox(this); - m_searchObjectCB->setToolTip(tr("Object to search")); - connect(m_searchObjectCB, static_cast(&QComboBox::currentIndexChanged), - this, &VSearcher::handleInputChanged); - - // Target. - m_searchTargetCB = VUtils::getComboBox(this); - m_searchTargetCB->setToolTip(tr("Target to search")); - connect(m_searchTargetCB, static_cast(&QComboBox::currentIndexChanged), - this, &VSearcher::handleInputChanged); - - // Pattern. - m_filePatternCB = VUtils::getComboBox(this); - m_filePatternCB->setEditable(true); - m_filePatternCB->setLineEdit(new VLineEdit(this)); - m_filePatternCB->setToolTip(tr("Wildcard pattern to filter the files to be searched")); - m_filePatternCB->lineEdit()->setProperty("EmbeddedEdit", true); - m_filePatternCB->completer()->setCaseSensitivity(Qt::CaseSensitive); - - // Engine. - m_searchEngineCB = VUtils::getComboBox(this); - m_searchEngineCB->setToolTip(tr("Engine to execute the search")); - - // Case sensitive. - m_caseSensitiveCB = new QCheckBox(tr("&Case sensitive"), this); - - // Whole word only. - m_wholeWordOnlyCB = new QCheckBox(tr("&Whole word only"), this); - - // Fuzzy search. - m_fuzzyCB = new QCheckBox(tr("&Fuzzy search"), this); - m_fuzzyCB->setToolTip(tr("Not available for content search")); - connect(m_fuzzyCB, &QCheckBox::stateChanged, - this, [this](int p_state) { - bool checked = p_state == Qt::Checked; - m_wholeWordOnlyCB->setEnabled(!checked); - }); - - // Regular expression. - m_regularExpressionCB = new QCheckBox(tr("Re&gular expression"), this); - connect(m_regularExpressionCB, &QCheckBox::stateChanged, - this, [this](int p_state) { - bool checked = p_state == Qt::Checked; - m_wholeWordOnlyCB->setEnabled(!checked); - m_fuzzyCB->setEnabled(!checked); - }); - - QFormLayout *advLayout = VUtils::getFormLayout(); - advLayout->addRow(tr("File pattern:"), m_filePatternCB); - advLayout->addRow(tr("Engine:"), m_searchEngineCB); - advLayout->addRow(m_caseSensitiveCB); - advLayout->addRow(m_wholeWordOnlyCB); - advLayout->addRow(m_fuzzyCB); - advLayout->addRow(m_regularExpressionCB); - advLayout->setContentsMargins(0, 0, 0, 0); - - m_advWidget = new QWidget(this); - m_advWidget->setLayout(advLayout); - m_advWidget->hide(); - - // Progress bar. - m_proBar = new QProgressBar(this); - m_proBar->setRange(0, 0); - - // Cancel button. - m_cancelBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/close.svg"), - "", - this); - m_cancelBtn->setToolTip(tr("Cancel")); - m_cancelBtn->setProperty("FlatBtn", true); - connect(m_cancelBtn, &QPushButton::clicked, - this, [this]() { - if (m_inSearch) { - appendLogLine(tr("Cancelling the search...")); - m_askedToStop = true; - m_search.stop(); - } - }); - - QHBoxLayout *proLayout = new QHBoxLayout(); - proLayout->addWidget(m_proBar); - proLayout->addWidget(m_cancelBtn); - proLayout->setContentsMargins(0, 0, 0, 0); - - // Console. - m_consoleEdit = new QPlainTextEdit(this); - m_consoleEdit->setReadOnly(true); - m_consoleEdit->setLineWrapMode(QPlainTextEdit::WidgetWidth); - m_consoleEdit->setProperty("LineEdit", true); - m_consoleEdit->setPlaceholderText(tr("Output logs will be shown here")); - m_consoleEdit->setMaximumHeight(m_searchScopeCB->height() * 2); - m_consoleEdit->hide(); - - // List. - m_results = new VSearchResultTree(this); - m_results->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - connect(m_results, &VSearchResultTree::countChanged, - this, [this](int p_count) { - m_clearBtn->setEnabled(p_count > 0); - updateNumLabel(p_count); - }); - - QShortcut *expandShortcut = new QShortcut(QKeySequence(Shortcut::c_expand), this); - expandShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(expandShortcut, &QShortcut::activated, - m_results, &VSearchResultTree::expandCollapseAll); - - QFormLayout *formLayout = VUtils::getFormLayout(); - formLayout->addRow(tr("Keywords:"), m_keywordCB); - formLayout->addRow(tr("Scope:"), m_searchScopeCB); - formLayout->addRow(tr("Object:"), m_searchObjectCB); - formLayout->addRow(tr("Target:"), m_searchTargetCB); - formLayout->setContentsMargins(0, 0, 0, 0); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(btnLayout); - mainLayout->addLayout(formLayout); - mainLayout->addWidget(m_advWidget); - mainLayout->addLayout(proLayout); - mainLayout->addWidget(m_consoleEdit); - mainLayout->addWidget(m_results); - mainLayout->setContentsMargins(3, 0, 3, 0); - - setLayout(mainLayout); -} - -void VSearcher::initUIFields() -{ - VSearchConfig config = VSearchConfig::fromConfig(g_config->getSearchOptions()); - - // Scope. - m_searchScopeCB->addItem(tr("Opened Notes"), VSearchConfig::OpenedNotes); - m_searchScopeCB->addItem(tr("Current Folder"), VSearchConfig::CurrentFolder); - m_searchScopeCB->addItem(tr("Current Notebook"), VSearchConfig::CurrentNotebook); - m_searchScopeCB->addItem(tr("All Notebooks"), VSearchConfig::AllNotebooks); - m_searchScopeCB->addItem(tr("Explorer Directory"), VSearchConfig::ExplorerDirectory); - m_searchScopeCB->setCurrentIndex(m_searchScopeCB->findData(config.m_scope)); - - // Object. - m_searchObjectCB->addItem(tr("Name"), VSearchConfig::Name); - m_searchObjectCB->addItem(tr("Content"), VSearchConfig::Content); - m_searchObjectCB->addItem(tr("Tag"), VSearchConfig::Tag); - m_searchObjectCB->addItem(tr("Path"), VSearchConfig::Path); - m_searchObjectCB->setCurrentIndex(m_searchObjectCB->findData(config.m_object)); - - // Target. - m_searchTargetCB->addItem(tr("Note"), VSearchConfig::Note); - m_searchTargetCB->addItem(tr("Folder"), VSearchConfig::Folder); - m_searchTargetCB->addItem(tr("Notebook"), VSearchConfig::Notebook); - m_searchTargetCB->addItem(tr("Note/Folder/Notebook"), - VSearchConfig::Note - | VSearchConfig:: Folder - | VSearchConfig::Notebook); - m_searchTargetCB->setCurrentIndex(m_searchTargetCB->findData(config.m_target)); - - // Engine. - m_searchEngineCB->addItem(tr("Internal"), VSearchConfig::Internal); - m_searchEngineCB->setCurrentIndex(m_searchEngineCB->findData(config.m_engine)); - - // Pattern. - m_filePatternCB->setCurrentText(config.m_pattern); - - m_caseSensitiveCB->setChecked(config.m_option & VSearchConfig::CaseSensitive); - m_wholeWordOnlyCB->setChecked(config.m_option & VSearchConfig::WholeWordOnly); - m_fuzzyCB->setChecked(config.m_option & VSearchConfig::Fuzzy); - m_regularExpressionCB->setChecked(config.m_option & VSearchConfig::RegularExpression); - - setProgressVisible(false); - - m_clearBtn->setEnabled(false); -} - -void VSearcher::updateItemToComboBox(QComboBox *p_comboBox) -{ - QString text = p_comboBox->currentText(); - if (!text.isEmpty() && p_comboBox->findText(text) == -1) { - p_comboBox->addItem(text); - } -} - -void VSearcher::setProgressVisible(bool p_visible) -{ - m_proBar->setVisible(p_visible); - m_cancelBtn->setVisible(p_visible); -} - -void VSearcher::appendLogLine(const QString &p_text) -{ - m_consoleEdit->appendPlainText(">>> " + p_text); - m_consoleEdit->ensureCursorVisible(); - QCoreApplication::sendPostedEvents(); -} - -void VSearcher::showMessage(const QString &p_text) const -{ - g_mainWin->showStatusMessage(p_text); - QCoreApplication::sendPostedEvents(); -} - -void VSearcher::handleInputChanged() -{ - bool readyToSearch = true; - - // Keyword. - QString keyword = m_keywordCB->currentText(); - readyToSearch = !keyword.isEmpty(); - - if (readyToSearch) { - int obj = m_searchObjectCB->currentData().toInt(); - int target = m_searchTargetCB->currentData().toInt(); - int scope = m_searchScopeCB->currentData().toInt(); - - // Other targets are only available for Name and Path. - if (!(obj & VSearchConfig::Name) - && !(obj & VSearchConfig::Path) - && !(target & VSearchConfig::Note)) { - readyToSearch = false; - } - - if (readyToSearch - && obj == VSearchConfig::Outline - && scope != VSearchConfig::CurrentNotebook - && scope != VSearchConfig::OpenedNotes) { - // Outline is available only for CurrentNote and OpenedNotes. - readyToSearch = false; - } - - if (readyToSearch && scope == VSearchConfig::ExplorerDirectory) { - if (!(obj & VSearchConfig::Name) - && !(obj & VSearchConfig::Path) - && !(obj & VSearchConfig::Content)) { - readyToSearch = false; - } else if (!(target & VSearchConfig::Note) - && !(target & VSearchConfig::Folder)) { - readyToSearch = false; - } - } - } - - m_searchBtn->setEnabled(readyToSearch); -} - -void VSearcher::startSearch() -{ - if (m_inSearch) { - return; - } - - m_searchBtn->setEnabled(false); - setProgressVisible(true); - m_results->clearResults(); - m_askedToStop = false; - m_inSearch = true; - m_consoleEdit->clear(); - appendLogLine(tr("Search started.")); - - updateItemToComboBox(m_keywordCB); - updateItemToComboBox(m_filePatternCB); - - m_search.clear(); - - QSharedPointer config(new VSearchConfig(m_searchScopeCB->currentData().toInt(), - m_searchObjectCB->currentData().toInt(), - m_searchTargetCB->currentData().toInt(), - m_searchEngineCB->currentData().toInt(), - getSearchOption(), - m_keywordCB->currentText(), - m_filePatternCB->currentText())); - m_search.setConfig(config); - - g_config->setSearchOptions(config->toConfig()); - - QSharedPointer result; - switch (config->m_scope) { - case VSearchConfig::CurrentNote: - { - QVector files; - files.append(g_mainWin->getCurrentFile()); - if (files[0]) { - QString msg(tr("Search current note %1.").arg(files[0]->getName())); - appendLogLine(msg); - showMessage(msg); - } - - result = m_search.search(files); - break; - } - - case VSearchConfig::OpenedNotes: - { - QVector tabs = g_mainWin->getEditArea()->getAllTabsInfo(); - QVector files; - files.reserve(tabs.size()); - for (auto const & ta : tabs) { - files.append(ta.m_editTab->getFile()); - } - - result = m_search.search(files); - break; - } - - case VSearchConfig::CurrentFolder: - { - VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory(); - if (dir) { - QString msg(tr("Search current folder %1.").arg(dir->getName())); - appendLogLine(msg); - showMessage(msg); - } - - result = m_search.search(dir); - break; - } - - case VSearchConfig::CurrentNotebook: - { - QVector notebooks; - notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook()); - if (notebooks[0]) { - QString msg(tr("Search current notebook %1.").arg(notebooks[0]->getName())); - appendLogLine(msg); - showMessage(msg); - } - - result = m_search.search(notebooks); - break; - } - - case VSearchConfig::AllNotebooks: - { - const QVector ¬ebooks = g_vnote->getNotebooks(); - result = m_search.search(notebooks); - break; - } - - case VSearchConfig::ExplorerDirectory: - { - QString rootDirectory = g_mainWin->getExplorer()->getRootDirectory(); - if (!rootDirectory.isEmpty()) { - QString msg(tr("Search Explorer directory %1.").arg(rootDirectory)); - appendLogLine(msg); - showMessage(msg); - } - - result = m_search.search(rootDirectory); - break; - } - - default: - break; - } - - handleSearchFinished(result); -} - -void VSearcher::handleSearchFinished(const QSharedPointer &p_result) -{ - Q_ASSERT(m_inSearch); - Q_ASSERT(p_result->m_state != VSearchState::Idle); - - qDebug() << "handleSearchFinished" << (int)p_result->m_state; - - QString msg; - switch (p_result->m_state) { - case VSearchState::Busy: - msg = tr("Search is on going."); - appendLogLine(msg); - return; - - case VSearchState::Success: - msg = tr("Search succeeded."); - appendLogLine(msg); - showMessage(msg); - break; - - case VSearchState::Fail: - msg = tr("Search failed."); - appendLogLine(msg); - showMessage(msg); - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Search failed."), - p_result->m_errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - break; - - case VSearchState::Cancelled: - Q_ASSERT(m_askedToStop); - msg = tr("User cancelled the search. Aborted!"); - appendLogLine(msg); - showMessage(msg); - m_askedToStop = false; - break; - - default: - break; - } - - if (p_result->m_state != VSearchState::Fail - && p_result->hasError()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Errors found during search."), - p_result->m_errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - m_search.clear(); - - m_inSearch = false; - m_searchBtn->setEnabled(true); - setProgressVisible(false); -} - -void VSearcher::animateSearchClick() -{ - m_searchBtn->animateClick(); -} - -int VSearcher::getSearchOption() const -{ - int ret = VSearchConfig::NoneOption; - - if (m_caseSensitiveCB->isChecked()) { - ret |= VSearchConfig::CaseSensitive; - } - - if (m_wholeWordOnlyCB->isChecked()) { - ret |= VSearchConfig::WholeWordOnly; - } - - if (m_fuzzyCB->isChecked()) { - ret |= VSearchConfig::Fuzzy; - } - - if (m_regularExpressionCB->isChecked()) { - ret |= VSearchConfig::RegularExpression; - } - - return ret; -} - -void VSearcher::updateNumLabel(int p_count) -{ - m_numLabel->setText(tr("%1 Items").arg(p_count)); -} - -void VSearcher::focusToSearch() -{ - init(); - - m_keywordCB->setFocus(Qt::OtherFocusReason); -} - -void VSearcher::showNavigation() -{ - setupUI(); - - VNavigationMode::showNavigation(m_results); -} - -bool VSearcher::handleKeyNavigation(int p_key, bool &p_succeed) -{ - setupUI(); - - return VNavigationMode::handleKeyNavigation(m_results, - p_key, - p_succeed); -} - -void VSearcher::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - setupUI(); - - initUIFields(); - - handleInputChanged(); - - connect(&m_search, &VSearch::resultItemAdded, - this, [this](const QSharedPointer &p_item) { - // Not sure if it works. - QCoreApplication::sendPostedEvents(NULL, QEvent::MouseButtonRelease); - m_results->addResultItem(p_item); - }); - connect(&m_search, &VSearch::resultItemsAdded, - this, [this](const QList > &p_items) { - // Not sure if it works. - QCoreApplication::sendPostedEvents(NULL, QEvent::MouseButtonRelease); - m_results->addResultItems(p_items); - }); - connect(&m_search, &VSearch::finished, - this, &VSearcher::handleSearchFinished); -} - -void VSearcher::showEvent(QShowEvent *p_event) -{ - init(); - - QWidget::showEvent(p_event); -} diff --git a/src/vsearcher.h b/src/vsearcher.h deleted file mode 100644 index a7d7c999..00000000 --- a/src/vsearcher.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef VSEARCHER_H -#define VSEARCHER_H - -#include -#include - -#include "vsearch.h" - -#include "vnavigationmode.h" - -class QComboBox; -class QCheckBox; -class QPushButton; -class QLabel; -class VSearchResultTree; -class QProgressBar; -class QPlainTextEdit; -class QShowEvent; - -class VSearcher : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VSearcher(QWidget *p_parent = nullptr); - - void focusToSearch(); - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void handleSearchFinished(const QSharedPointer &p_result); - -private: - void startSearch(); - - void setupUI(); - - void init(); - - void initUIFields(); - - void setProgressVisible(bool p_visible); - - void appendLogLine(const QString &p_text); - - void handleInputChanged(); - - void animateSearchClick(); - - void updateItemToComboBox(QComboBox *p_comboBox); - - // Get the OR of the search options. - int getSearchOption() const; - - void updateNumLabel(int p_count); - - void showMessage(const QString &p_text) const; - - QComboBox *m_keywordCB; - - // All notebooks, current notebook, and so on. - QComboBox *m_searchScopeCB; - - // Name, content, tag. - QComboBox *m_searchObjectCB; - - // Notebook, folder, note. - QComboBox *m_searchTargetCB; - - QComboBox *m_filePatternCB; - - QComboBox *m_searchEngineCB; - - QCheckBox *m_caseSensitiveCB; - - QCheckBox *m_wholeWordOnlyCB; - - QCheckBox *m_fuzzyCB; - - QCheckBox *m_regularExpressionCB; - - QPushButton *m_searchBtn; - - QPushButton *m_clearBtn; - - QPushButton *m_advBtn; - - QPushButton *m_consoleBtn; - - QLabel *m_numLabel; - - QWidget *m_advWidget; - - VSearchResultTree *m_results; - - QProgressBar *m_proBar; - - QPushButton *m_cancelBtn; - - QPlainTextEdit *m_consoleEdit; - - bool m_initialized; - - bool m_uiInitialized; - - bool m_inSearch; - - bool m_askedToStop; - - VSearch m_search; -}; - -#endif // VSEARCHER_H diff --git a/src/vsearchresulttree.cpp b/src/vsearchresulttree.cpp deleted file mode 100644 index 3083695b..00000000 --- a/src/vsearchresulttree.cpp +++ /dev/null @@ -1,287 +0,0 @@ -#include "vsearchresulttree.h" - -#include -#include - -#include "utils/vutils.h" -#include "utils/viconutils.h" -#include "vnote.h" -#include "vmainwindow.h" -#include "vnotefile.h" -#include "vcart.h" -#include "vhistorylist.h" -#include "vexplorer.h" -#include "vuniversalentry.h" -#include "vsearchue.h" -#include "vconstants.h" - -extern VNote *g_vnote; - -extern VMainWindow *g_mainWin; - -VSearchResultTree::VSearchResultTree(QWidget *p_parent) - : VTreeWidget(p_parent) -{ - setColumnCount(1); - setHeaderHidden(true); - setExpandsOnDoubleClick(false); - setContextMenuPolicy(Qt::CustomContextMenu); - setSelectionMode(QAbstractItemView::ExtendedSelection); - - setSimpleSearchMatchFlags(getSimpleSearchMatchFlags() & ~Qt::MatchRecursive); - - m_noteIcon = VIconUtils::treeViewIcon(":/resources/icons/note_item.svg"); - m_folderIcon = VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg"); - m_notebookIcon = VIconUtils::treeViewIcon(":/resources/icons/notebook_item.svg"); - - connect(this, &VTreeWidget::itemActivated, - this, &VSearchResultTree::activateItem); - connect(this, &VTreeWidget::customContextMenuRequested, - this, &VSearchResultTree::handleContextMenuRequested); -} - -void VSearchResultTree::updateResults(const QList > &p_items) -{ - clearResults(); - - for (auto const & it : p_items) { - appendItem(it); - } - - emit countChanged(topLevelItemCount()); -} - -void VSearchResultTree::addResultItem(const QSharedPointer &p_item) -{ - appendItem(p_item); - - emit countChanged(topLevelItemCount()); -} - -void VSearchResultTree::addResultItems(const QList > &p_items) -{ - for (auto const & it : p_items) { - appendItem(it); - } - - emit countChanged(topLevelItemCount()); -} - -void VSearchResultTree::clearResults() -{ - clearAll(); - - m_data.clear(); - - emit countChanged(topLevelItemCount()); -} - -void VSearchResultTree::appendItem(const QSharedPointer &p_item) -{ - m_data.append(p_item); - - QTreeWidgetItem *item = new QTreeWidgetItem(this); - item->setData(0, Qt::UserRole, m_data.size() - 1); - QString text; - if (p_item->m_text.isEmpty()) { - text = p_item->m_path; - } else if (p_item->m_type != VSearchResultItem::Notebook) { - text = VUniversalEntry::fileNameWithDir(p_item->m_text, p_item->m_path); - } else { - text = p_item->m_text; - } - item->setText(0, text); - item->setToolTip(0, p_item->m_path); - - switch (p_item->m_type) { - case VSearchResultItem::Note: - item->setIcon(0, m_noteIcon); - break; - - case VSearchResultItem::Folder: - item->setIcon(0, m_folderIcon); - break; - - case VSearchResultItem::Notebook: - item->setIcon(0, m_notebookIcon); - break; - - default: - break; - } - - for (auto const & it: p_item->m_matches) { - QTreeWidgetItem *subItem = new QTreeWidgetItem(item); - QString text; - if (it.m_lineNumber > -1) { - text = QString("[%1] %2").arg(it.m_lineNumber).arg(it.m_text); - } else { - text = it.m_text; - } - - subItem->setText(0, text); - subItem->setToolTip(0, it.m_text); - } -} - -void VSearchResultTree::handleContextMenuRequested(QPoint p_pos) -{ - QMenu menu(this); - menu.setToolTipsVisible(true); - - QTreeWidgetItem *item = itemAt(p_pos); - if (!item) { - goto global; - } - - { - QList items = selectedItems(); - - bool hasNote = false; - for (auto const & it : items) { - if (itemResultType(it) == VSearchResultItem::Note) { - hasNote = true; - break; - } - } - - if (items.size() == 1) { - QAction *openAct = new QAction(tr("&Open"), &menu); - openAct->setToolTip(tr("Open selected notes")); - connect(openAct, &QAction::triggered, - this, [this]() { - activateItem(currentItem()); - }); - menu.addAction(openAct); - - if (hasNote) { - QAction *locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"), - tr("&Locate To Folder"), - &menu); - locateAct->setToolTip(tr("Locate the folder of current note")); - connect(locateAct, &QAction::triggered, - this, &VSearchResultTree::locateCurrentItem); - menu.addAction(locateAct); - } - } - - if (hasNote) { - QAction *addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"), - tr("Add To Cart"), - &menu); - addToCartAct->setToolTip(tr("Add selected notes to Cart for further processing")); - connect(addToCartAct, &QAction::triggered, - this, &VSearchResultTree::addSelectedItemsToCart); - menu.addAction(addToCartAct); - - QAction *pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"), - tr("Pin To History"), - &menu); - pinToHistoryAct->setToolTip(tr("Pin selected notes to History")); - connect(pinToHistoryAct, &QAction::triggered, - this, &VSearchResultTree::pinSelectedItemsToHistory); - menu.addAction(pinToHistoryAct); - } - } - -global: - if (topLevelItemCount() > 0) { - if (item) { - menu.addSeparator(); - } - - QString shortcutText = VUtils::getShortcutText(Shortcut::c_expand); - QAction *expandAct = new QAction(tr("Expand/Collapse All\t%1").arg(shortcutText), - &menu); - connect(expandAct, &QAction::triggered, - this, &VSearchResultTree::expandCollapseAll); - menu.addAction(expandAct); - - menu.exec(mapToGlobal(p_pos)); - } -} - -void VSearchResultTree::locateCurrentItem() -{ - auto item = currentItem(); - if (!item) { - return; - } - - const QSharedPointer &resItem = itemResultData(item); - if (resItem->m_type == VSearchResultItem::Note) { - VFile *file = g_vnote->getInternalFile(resItem->m_path); - if (file) { - g_mainWin->locateFile(file); - } - } -} - -void VSearchResultTree::addSelectedItemsToCart() -{ - QList items = selectedItems(); - VCart *cart = g_mainWin->getCart(); - - int nrAdded = 0; - for (int i = 0; i < items.size(); ++i) { - const QSharedPointer &resItem = itemResultData(items[i]); - if (resItem->m_type == VSearchResultItem::Note) { - cart->addFile(resItem->m_path); - ++nrAdded; - } - } - - if (nrAdded) { - g_mainWin->showStatusMessage(tr("%1 %2 added to Cart") - .arg(nrAdded) - .arg(nrAdded > 1 ? tr("notes") : tr("note"))); - } -} - -void VSearchResultTree::pinSelectedItemsToHistory() -{ - QList items = selectedItems(); - QStringList files; - for (int i = 0; i < items.size(); ++i) { - const QSharedPointer &resItem = itemResultData(items[i]); - if (resItem->m_type == VSearchResultItem::Note) { - files << resItem->m_path; - } - } - - if (!files.isEmpty()) { - g_mainWin->getHistoryList()->pinFiles(files); - g_mainWin->showStatusMessage(tr("%1 %2 pinned to History") - .arg(files.size()) - .arg(files.size() > 1 ? tr("notes") : tr("note"))); - } -} - -VSearchResultItem::ItemType VSearchResultTree::itemResultType(const QTreeWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - return itemResultData(p_item)->m_type; -} - -const QSharedPointer &VSearchResultTree::itemResultData(const QTreeWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - const QTreeWidgetItem *topItem = VTreeWidget::topLevelTreeItem(p_item); - int idx = topItem->data(0, Qt::UserRole).toInt(); - Q_ASSERT(idx >= 0 && idx < m_data.size()); - return m_data[idx]; -} - -void VSearchResultTree::activateItem(const QTreeWidgetItem *p_item) const -{ - if (!p_item) { - return; - } - - VSearchUE::activateItem(itemResultData(p_item), VTreeWidget::childIndexOfTreeItem(p_item)); -} - -void VSearchResultTree::expandCollapseAll() -{ - VTreeWidget::expandCollapseAll(this); -} diff --git a/src/vsearchresulttree.h b/src/vsearchresulttree.h deleted file mode 100644 index 41c46952..00000000 --- a/src/vsearchresulttree.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef VSEARCHRESULTTREE_H -#define VSEARCHRESULTTREE_H - -#include - -#include "vtreewidget.h" -#include "vsearch.h" - - -class VSearchResultTree : public VTreeWidget -{ - Q_OBJECT -public: - explicit VSearchResultTree(QWidget *p_parent = nullptr); - - void updateResults(const QList > &p_items); - - void clearResults(); - -public slots: - void addResultItem(const QSharedPointer &p_item); - - void addResultItems(const QList > &p_items); - - void handleContextMenuRequested(QPoint p_pos); - - void expandCollapseAll(); - -signals: - void countChanged(int p_count); - -private slots: - void locateCurrentItem(); - - void addSelectedItemsToCart(); - - void pinSelectedItemsToHistory(); - -private: - void appendItem(const QSharedPointer &p_item); - - VSearchResultItem::ItemType itemResultType(const QTreeWidgetItem *p_item) const; - - void activateItem(const QTreeWidgetItem *p_item) const; - - const QSharedPointer &itemResultData(const QTreeWidgetItem *p_item) const; - - QVector > m_data; - - QIcon m_noteIcon; - QIcon m_folderIcon; - QIcon m_notebookIcon; -}; - -#endif // VSEARCHRESULTTREE_H diff --git a/src/vsearchue.cpp b/src/vsearchue.cpp deleted file mode 100644 index 79a613f7..00000000 --- a/src/vsearchue.cpp +++ /dev/null @@ -1,1257 +0,0 @@ -#include "vsearchue.h" - -#include -#include - -#include "vlistwidgetdoublerows.h" -#include "vtreewidget.h" -#include "vnotebook.h" -#include "vnote.h" -#include "vsearch.h" -#include "utils/viconutils.h" -#include "utils/vutils.h" -#include "vmainwindow.h" -#include "vnotebookselector.h" -#include "vnotefile.h" -#include "vdirectory.h" -#include "vdirectorytree.h" -#include "veditarea.h" -#include "vexplorer.h" -#include "vuniversalentry.h" -#include "vconfigmanager.h" - -extern VNote *g_vnote; - -extern VMainWindow *g_mainWin; - -extern VConfigManager *g_config; - -#define ITEM_NUM_TO_UPDATE_WIDGET 20 - -VSearchUE::VSearchUE(QObject *p_parent) - : IUniversalEntry(p_parent), - m_search(NULL), - m_inSearch(false), - m_id(ID::Name_Notebook_AllNotebook), - m_listWidget(NULL), - m_treeWidget(NULL) -{ -} - -QString VSearchUE::description(int p_id) const -{ - switch (p_id) { - case ID::Name_Notebook_AllNotebook: - return tr("List and search all the notebooks"); - - case ID::Name_FolderNote_AllNotebook: - return tr("Search the name of folders/notes in all the notebooks"); - - case ID::Content_Note_AllNotebook: - return tr("Search the content of notes in all the notebooks"); - - case ID::Tag_Note_AllNotebook: - return tr("Search the tags of notes in all the notebooks"); - - case ID::Name_FolderNote_CurrentNotebook: - return tr("Search the name of folders/notes in current notebook"); - - case ID::Content_Note_CurrentNotebook: - return tr("Search the content of notes in current notebook"); - - case ID::Tag_Note_CurrentNotebook: - return tr("Search the tags of notes in current notebook"); - - case ID::Name_FolderNote_CurrentFolder: - return tr("Search the name of folders/notes in current folder"); - - case ID::Content_Note_CurrentFolder: - return tr("Search the content of notes in current folder"); - - case ID::Tag_Note_CurrentFolder: - return tr("Search the tags of notes in current folder"); - - case ID::Name_Note_Buffer: - return tr("List and search the name of opened notes in buffer"); - - case ID::Content_Note_Buffer: - return tr("Search the content of opened notes in buffer"); - - case ID::Outline_Note_Buffer: - return tr("Search the outline of opened notes in buffer"); - - case ID::Path_FolderNote_AllNotebook: - return tr("Search the path of folders/notes in all the notebooks"); - - case ID::Path_FolderNote_CurrentNotebook: - return tr("Search the path of folders/notes in current notebook"); - - case ID::Content_Note_ExplorerDirectory: - return tr("Search the content of notes in Explorer root directory"); - - default: - Q_ASSERT(false); - return tr("Invalid ID %1").arg(p_id); - } -} - -void VSearchUE::init() -{ - if (m_initialized) { - return; - } - - Q_ASSERT(m_widgetParent); - - m_initialized = true; - - m_search = new VSearch(this); - connect(m_search, &VSearch::resultItemAdded, - this, &VSearchUE::handleSearchItemAdded); - connect(m_search, &VSearch::resultItemsAdded, - this, &VSearchUE::handleSearchItemsAdded); - connect(m_search, &VSearch::finished, - this, &VSearchUE::handleSearchFinished); - - m_noteIcon = VIconUtils::treeViewIcon(":/resources/icons/note_item.svg"); - m_folderIcon = VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg"); - m_notebookIcon = VIconUtils::treeViewIcon(":/resources/icons/notebook_item.svg"); - - m_listWidget = new VListWidgetDoubleRows(m_widgetParent); - m_listWidget->setFitContent(true); - m_listWidget->hide(); - connect(m_listWidget, SIGNAL(itemActivated(QListWidgetItem *)), - this, SLOT(activateItem(QListWidgetItem *))); - - m_treeWidget = new VTreeWidget(m_widgetParent); - m_treeWidget->setColumnCount(1); - m_treeWidget->setHeaderHidden(true); - m_treeWidget->setExpandsOnDoubleClick(false); - m_treeWidget->setFitContent(true); - m_treeWidget->hide(); - connect(m_treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)), - this, SLOT(activateItem(QTreeWidgetItem *, int))); - connect(m_treeWidget, &VTreeWidget::itemExpandedOrCollapsed, - this, &VSearchUE::widgetUpdated); -} - -QWidget *VSearchUE::widget(int p_id) -{ - init(); - - switch (p_id) { - case ID::Name_Notebook_AllNotebook: - case ID::Tag_Note_AllNotebook: - case ID::Name_FolderNote_AllNotebook: - case ID::Name_FolderNote_CurrentNotebook: - case ID::Tag_Note_CurrentNotebook: - case ID::Name_FolderNote_CurrentFolder: - case ID::Tag_Note_CurrentFolder: - case ID::Name_Note_Buffer: - case ID::Path_FolderNote_AllNotebook: - case ID::Path_FolderNote_CurrentNotebook: - return m_listWidget; - - case ID::Content_Note_AllNotebook: - case ID::Content_Note_CurrentNotebook: - case ID::Content_Note_CurrentFolder: - case ID::Content_Note_ExplorerDirectory: - case ID::Content_Note_Buffer: - case ID::Outline_Note_Buffer: - return m_treeWidget; - - default: - Q_ASSERT(false); - return NULL; - } -} - -void VSearchUE::processCommand(int p_id, const QString &p_cmd) -{ - qDebug() << "processCommand" << p_id << p_cmd; - - init(); - - clear(-1); - - m_inSearch = true; - m_id = p_id; - emit stateUpdated(State::Busy); - switch (p_id) { - case ID::Name_Notebook_AllNotebook: - searchNameOfAllNotebooks(p_cmd); - break; - - case ID::Name_FolderNote_AllNotebook: - searchNameOfFolderNoteInAllNotebooks(p_cmd); - break; - - case ID::Tag_Note_AllNotebook: - searchTagOfNoteInAllNotebooks(p_cmd); - break; - - case ID::Content_Note_AllNotebook: - searchContentOfNoteInAllNotebooks(p_cmd); - break; - - case ID::Name_FolderNote_CurrentNotebook: - searchNameOfFolderNoteInCurrentNotebook(p_cmd); - break; - - case ID::Content_Note_CurrentNotebook: - searchContentOfNoteInCurrentNotebook(p_cmd); - break; - - case ID::Tag_Note_CurrentNotebook: - searchTagOfNoteInCurrentNotebook(p_cmd); - break; - - case ID::Name_FolderNote_CurrentFolder: - searchNameOfFolderNoteInCurrentFolder(p_cmd); - break; - - case ID::Content_Note_CurrentFolder: - searchContentOfNoteInCurrentFolder(p_cmd); - break; - - case ID::Content_Note_ExplorerDirectory: - searchContentOfNoteInExplorerDirectory(p_cmd); - break; - - case ID::Tag_Note_CurrentFolder: - searchTagOfNoteInCurrentFolder(p_cmd); - break; - - case ID::Name_Note_Buffer: - searchNameOfBuffer(p_cmd); - break; - - case ID::Content_Note_Buffer: - searchContentOfBuffer(p_cmd); - break; - - case ID::Outline_Note_Buffer: - searchOutlineOfBuffer(p_cmd); - break; - - case ID::Path_FolderNote_AllNotebook: - searchPathOfFolderNoteInAllNotebooks(p_cmd); - break; - - case ID::Path_FolderNote_CurrentNotebook: - searchPathOfFolderNoteInCurrentNotebook(p_cmd); - break; - - default: - Q_ASSERT(false); - break; - } - - updateWidget(); -} - -void VSearchUE::updateWidget() -{ - QWidget *wid = widget(m_id); - if (wid == m_treeWidget) { - if (m_treeWidget->topLevelItemCount() > 0) { - m_treeWidget->resizeColumnToContents(0); - } else { - QTreeWidgetItem *item = new QTreeWidgetItem(m_treeWidget, QStringList("test")); - m_treeWidget->resizeColumnToContents(0); - delete item; - } - } - - wid->updateGeometry(); - emit widgetUpdated(); -} - -void VSearchUE::searchNameOfAllNotebooks(const QString &p_cmd) -{ - const QVector ¬ebooks = g_vnote->getNotebooks(); - if (p_cmd.isEmpty()) { - // List all the notebooks. - for (auto const & nb : notebooks) { - QSharedPointer item(new VSearchResultItem(VSearchResultItem::Notebook, - VSearchResultItem::LineNumber, - nb->getName(), - nb->getPath())); - handleSearchItemAdded(item); - } - - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - // Do a fuzzy search against the name of the notebooks. - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::AllNotebooks, - VSearchConfig::Name, - VSearchConfig::Notebook, - VSearchConfig::Internal, - VSearchConfig::Fuzzy, - p_cmd, - QString())); - m_search->setConfig(config); - - QSharedPointer result = m_search->search(notebooks); - handleSearchFinished(result); - } -} - -void VSearchUE::searchNameOfFolderNoteInAllNotebooks(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::AllNotebooks, - VSearchConfig::Name, - VSearchConfig::Folder | VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(g_vnote->getNotebooks()); - handleSearchFinished(result); - } -} - -void VSearchUE::searchTagOfNoteInAllNotebooks(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::AllNotebooks, - VSearchConfig::Tag, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(g_vnote->getNotebooks()); - handleSearchFinished(result); - } -} - -void VSearchUE::searchTagOfNoteInCurrentNotebook(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - QVector notebooks; - notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook()); - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::CurrentNotebook, - VSearchConfig::Tag, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(notebooks); - handleSearchFinished(result); - } -} - -void VSearchUE::searchTagOfNoteInCurrentFolder(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory(); - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::CurrentFolder, - VSearchConfig::Tag, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(dir); - handleSearchFinished(result); - } -} - -void VSearchUE::searchContentOfNoteInAllNotebooks(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::AllNotebooks, - VSearchConfig::Content, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(g_vnote->getNotebooks()); - handleSearchFinished(result); - } -} - -void VSearchUE::searchNameOfFolderNoteInCurrentNotebook(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - QVector notebooks; - notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook()); - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::CurrentNotebook, - VSearchConfig::Name, - VSearchConfig::Folder | VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(notebooks); - handleSearchFinished(result); - } -} - -void VSearchUE::searchContentOfNoteInCurrentNotebook(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - QVector notebooks; - notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook()); - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::CurrentNotebook, - VSearchConfig::Content, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(notebooks); - handleSearchFinished(result); - } -} - -void VSearchUE::searchNameOfFolderNoteInCurrentFolder(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory(); - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::CurrentFolder, - VSearchConfig::Name, - VSearchConfig::Folder | VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(dir); - handleSearchFinished(result); - } -} - -void VSearchUE::searchContentOfNoteInCurrentFolder(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory(); - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::CurrentFolder, - VSearchConfig::Content, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(dir); - handleSearchFinished(result); - } -} - -void VSearchUE::searchContentOfNoteInExplorerDirectory(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - QString rootDirectory = g_mainWin->getExplorer()->getRootDirectory(); - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::ExplorerDirectory, - VSearchConfig::Content, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(rootDirectory); - handleSearchFinished(result); - } -} - -QVector getFilesInBuffer() -{ - QVector tabs = g_mainWin->getEditArea()->getAllTabsInfo(); - QVector files; - files.reserve(tabs.size()); - for (auto const & ta : tabs) { - files.append(ta.m_editTab->getFile()); - } - - return files; -} - -void VSearchUE::searchNameOfBuffer(const QString &p_cmd) -{ - QVector files = getFilesInBuffer(); - if (p_cmd.isEmpty()) { - // List all the notes. - for (auto const & fi : files) { - QSharedPointer item(new VSearchResultItem(VSearchResultItem::Note, - VSearchResultItem::LineNumber, - fi->getName(), - fi->fetchPath())); - handleSearchItemAdded(item); - } - - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::OpenedNotes, - VSearchConfig::Name, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(files); - handleSearchFinished(result); - } -} - -void VSearchUE::searchContentOfBuffer(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::OpenedNotes, - VSearchConfig::Content, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(getFilesInBuffer()); - handleSearchFinished(result); - } -} - -void VSearchUE::searchOutlineOfBuffer(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::OpenedNotes, - VSearchConfig::Outline, - VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(getFilesInBuffer()); - handleSearchFinished(result); - } -} - -void VSearchUE::searchPathOfFolderNoteInAllNotebooks(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::AllNotebooks, - VSearchConfig::Path, - VSearchConfig::Folder | VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(g_vnote->getNotebooks()); - handleSearchFinished(result); - } -} - -void VSearchUE::searchPathOfFolderNoteInCurrentNotebook(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - m_inSearch = false; - emit stateUpdated(State::Success); - } else { - QVector notebooks; - notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook()); - m_search->clear(); - QSharedPointer config(new VSearchConfig(VSearchConfig::CurrentNotebook, - VSearchConfig::Path, - VSearchConfig::Folder | VSearchConfig::Note, - VSearchConfig::Internal, - VSearchConfig::NoneOption, - p_cmd, - QString())); - m_search->setConfig(config); - QSharedPointer result = m_search->search(notebooks); - handleSearchFinished(result); - } -} - -void VSearchUE::clear(int p_id) -{ - Q_UNUSED(p_id); - stopSearch(); - - m_data.clear(); - m_listWidget->clearAll(); - m_treeWidget->clearAll(); -} - -void VSearchUE::handleSearchItemAdded(const QSharedPointer &p_item) -{ - static int itemAdded = 0; - ++itemAdded; - - QCoreApplication::sendPostedEvents(NULL, QEvent::KeyPress); - - switch (m_id) { - case ID::Name_Notebook_AllNotebook: - case ID::Name_FolderNote_AllNotebook: - case ID::Tag_Note_AllNotebook: - case ID::Name_FolderNote_CurrentNotebook: - case ID::Tag_Note_CurrentNotebook: - case ID::Name_FolderNote_CurrentFolder: - case ID::Tag_Note_CurrentFolder: - case ID::Name_Note_Buffer: - case ID::Path_FolderNote_AllNotebook: - case ID::Path_FolderNote_CurrentNotebook: - appendItemToList(p_item); - if (itemAdded > 50) { - itemAdded = 0; - m_listWidget->updateGeometry(); - emit widgetUpdated(); - } - - break; - - case ID::Content_Note_AllNotebook: - case ID::Content_Note_CurrentNotebook: - case ID::Content_Note_CurrentFolder: - case ID::Content_Note_ExplorerDirectory: - case ID::Content_Note_Buffer: - case ID::Outline_Note_Buffer: - appendItemToTree(p_item); - if (itemAdded > 50) { - itemAdded = 0; - m_treeWidget->resizeColumnToContents(0); - m_treeWidget->updateGeometry(); - emit widgetUpdated(); - } - - break; - - default: - break; - } -} - -void VSearchUE::handleSearchItemsAdded(const QList > &p_items) -{ - QCoreApplication::sendPostedEvents(NULL, QEvent::KeyPress); - - switch (m_id) { - case ID::Name_Notebook_AllNotebook: - case ID::Name_FolderNote_AllNotebook: - case ID::Tag_Note_AllNotebook: - case ID::Name_FolderNote_CurrentNotebook: - case ID::Tag_Note_CurrentNotebook: - case ID::Name_FolderNote_CurrentFolder: - case ID::Tag_Note_CurrentFolder: - case ID::Name_Note_Buffer: - case ID::Path_FolderNote_AllNotebook: - case ID::Path_FolderNote_CurrentNotebook: - { - for (auto const & it : p_items) { - appendItemToList(it); - } - - m_listWidget->updateGeometry(); - emit widgetUpdated(); - break; - } - - case ID::Content_Note_AllNotebook: - case ID::Content_Note_CurrentNotebook: - case ID::Content_Note_CurrentFolder: - case ID::Content_Note_ExplorerDirectory: - case ID::Content_Note_Buffer: - case ID::Outline_Note_Buffer: - { - for (auto const & it : p_items) { - appendItemToTree(it); - } - - m_treeWidget->resizeColumnToContents(0); - m_treeWidget->updateGeometry(); - emit widgetUpdated(); - break; - } - - default: - break; - } -} - -void VSearchUE::appendItemToList(const QSharedPointer &p_item) -{ - m_data.append(p_item); - - QString first, second; - if (p_item->m_text.isEmpty()) { - first = p_item->m_path; - } else { - if (p_item->m_type != VSearchResultItem::Notebook) { - first = VUniversalEntry::fileNameWithDir(p_item->m_text, p_item->m_path); - } else { - first = p_item->m_text; - } - second = p_item->m_path; - } - - QIcon *icon = NULL; - // We put notebook and folder before note. - int row = 0; - switch (p_item->m_type) { - case VSearchResultItem::Note: - row = m_listWidget->count(); - icon = &m_noteIcon; - break; - - case VSearchResultItem::Folder: - icon = &m_folderIcon; - break; - - case VSearchResultItem::Notebook: - icon = &m_notebookIcon; - break; - - default: - break; - } - - QListWidgetItem *item = m_listWidget->insertDoubleRowsItem(row, *icon, first, second); - item->setData(Qt::UserRole, m_data.size() - 1); - item->setToolTip(p_item->m_path); - - if (row == 0) { - m_listWidget->setCurrentRow(0); - } -} - -void VSearchUE::appendItemToTree(const QSharedPointer &p_item) -{ - m_data.append(p_item); - - QTreeWidgetItem *item = new QTreeWidgetItem(m_treeWidget); - item->setData(0, Qt::UserRole, m_data.size() - 1); - QString text; - if (p_item->m_text.isEmpty()) { - text = p_item->m_path; - } else if (p_item->m_type != VSearchResultItem::Notebook) { - text = VUniversalEntry::fileNameWithDir(p_item->m_text, p_item->m_path); - } else { - text = p_item->m_text; - } - item->setText(0, text); - item->setToolTip(0, p_item->m_path); - - switch (p_item->m_type) { - case VSearchResultItem::Note: - item->setIcon(0, m_noteIcon); - break; - - case VSearchResultItem::Folder: - item->setIcon(0, m_folderIcon); - break; - - case VSearchResultItem::Notebook: - item->setIcon(0, m_notebookIcon); - break; - - default: - break; - } - - for (auto const & it: p_item->m_matches) { - QTreeWidgetItem *subItem = new QTreeWidgetItem(item); - QString text; - if (it.m_lineNumber > -1) { - text = QString("[%1] %2").arg(it.m_lineNumber).arg(it.m_text); - } else { - text = it.m_text; - } - - subItem->setText(0, text); - subItem->setToolTip(0, it.m_text); - } - - if (!m_treeWidget->currentItem()) { - m_treeWidget->setCurrentItem(item); - } -} - -void VSearchUE::handleSearchFinished(const QSharedPointer &p_result) -{ - Q_ASSERT(m_inSearch); - Q_ASSERT(p_result->m_state != VSearchState::Idle); - - qDebug() << "handleSearchFinished" << (int)p_result->m_state; - - IUniversalEntry::State state = State::Idle; - - bool finished = true; - switch (p_result->m_state) { - case VSearchState::Busy: - qDebug() << "search is ongoing"; - state = State::Busy; - finished = false; - break; - - case VSearchState::Success: - qDebug() << "search succeeded"; - state = State::Success; - break; - - case VSearchState::Fail: - qDebug() << "search failed"; - state = State::Fail; - break; - - case VSearchState::Cancelled: - qDebug() << "search cancelled"; - state = State::Cancelled; - break; - - default: - break; - } - - if (finished) { - m_search->clear(); - m_inSearch = false; - } - - updateWidget(); - - emit stateUpdated(state); -} - -void VSearchUE::stopSearch() -{ - if (m_inSearch) { - m_search->stop(); - - while (m_inSearch) { - VUtils::sleepWait(100); - qDebug() << "sleep wait for search to stop"; - } - } -} - -const QSharedPointer &VSearchUE::itemResultData(const QListWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - int idx = p_item->data(Qt::UserRole).toInt(); - Q_ASSERT(idx >= 0 && idx < m_data.size()); - return m_data[idx]; -} - -const QSharedPointer &VSearchUE::itemResultData(const QTreeWidgetItem *p_item) const -{ - Q_ASSERT(p_item); - const QTreeWidgetItem *topItem = VTreeWidget::topLevelTreeItem(p_item); - int idx = topItem->data(0, Qt::UserRole).toInt(); - Q_ASSERT(idx >= 0 && idx < m_data.size()); - return m_data[idx]; -} - -void VSearchUE::activateItem(const QSharedPointer &p_item, int p_matchIndex) -{ - switch (p_item->m_type) { - case VSearchResultItem::Note: - { - bool highlightPage = false; - bool jumpTitle = false; - if (!p_item->m_matches.isEmpty() && p_item->m_config) { - if (p_item->m_config->m_object == VSearchConfig::Content) { - highlightPage = g_config->getHighlightMatchesInPage(); - } else if (p_item->m_config->m_object == VSearchConfig::Outline) { - jumpTitle = true; - } - } - - QStringList files(p_item->m_path); - OpenFileMode mode = highlightPage ? OpenFileMode::Edit : OpenFileMode::Read; - bool forceMode = highlightPage; - QVector openedFiles = g_mainWin->openFiles(files, - false, - mode, - forceMode); - if (openedFiles.size() == 1) { - VEditTab *tab = g_mainWin->getCurrentTab(); - if (tab->getFile() != openedFiles.first()) { - break; - } - - if (highlightPage) { - tab->findText(p_item->m_config->m_contentToken, true, true); - } else if (jumpTitle) { - if (p_matchIndex >= p_item->m_matches.size()) { - p_matchIndex = p_item->m_matches.size() - 1; - } - - VHeaderPointer header(tab->getFile(), - p_item->m_matches[p_matchIndex].m_lineNumber); - tab->scrollToHeader(header); - } - } - - break; - } - - case VSearchResultItem::Folder: - { - VDirectory *dir = g_vnote->getInternalDirectory(p_item->m_path); - if (dir) { - g_mainWin->locateDirectory(dir); - } else { - // External directory. - g_mainWin->showExplorerPanel(true); - g_mainWin->getExplorer()->setRootDirectory(p_item->m_path); - } - - break; - } - - case VSearchResultItem::Notebook: - { - VNotebook *nb = g_vnote->getNotebook(p_item->m_path); - if (nb) { - g_mainWin->locateNotebook(nb); - } - - break; - } - - default: - break; - } -} - -void VSearchUE::activateItem(QListWidgetItem *p_item) -{ - if (!p_item) { - return; - } - - emit requestHideUniversalEntry(); - activateItem(itemResultData(p_item)); -} - -void VSearchUE::activateItem(QTreeWidgetItem *p_item, int p_col) -{ - Q_UNUSED(p_col); - if (!p_item) { - return; - } - - emit requestHideUniversalEntry(); - activateItem(itemResultData(p_item), VTreeWidget::childIndexOfTreeItem(p_item)); -} - -void VSearchUE::selectNextItem(int p_id, bool p_forward) -{ - switch (p_id) { - case ID::Name_Notebook_AllNotebook: - case ID::Name_FolderNote_AllNotebook: - case ID::Tag_Note_AllNotebook: - case ID::Name_FolderNote_CurrentNotebook: - case ID::Tag_Note_CurrentNotebook: - case ID::Name_FolderNote_CurrentFolder: - case ID::Tag_Note_CurrentFolder: - case ID::Name_Note_Buffer: - case ID::Path_FolderNote_AllNotebook: - case ID::Path_FolderNote_CurrentNotebook: - { - // Could not use postEvent method here which will induce infinite recursion. - m_listWidget->selectNextItem(p_forward); - break; - } - - case ID::Content_Note_AllNotebook: - case ID::Content_Note_CurrentNotebook: - case ID::Content_Note_CurrentFolder: - case ID::Content_Note_ExplorerDirectory: - case ID::Content_Note_Buffer: - case ID::Outline_Note_Buffer: - { - m_treeWidget->selectNextItem(p_forward); - break; - } - - default: - Q_ASSERT(false); - } -} - -void VSearchUE::activate(int p_id) -{ - switch (p_id) { - case ID::Name_Notebook_AllNotebook: - case ID::Name_FolderNote_AllNotebook: - case ID::Tag_Note_AllNotebook: - case ID::Name_FolderNote_CurrentNotebook: - case ID::Tag_Note_CurrentNotebook: - case ID::Name_FolderNote_CurrentFolder: - case ID::Tag_Note_CurrentFolder: - case ID::Name_Note_Buffer: - case ID::Path_FolderNote_AllNotebook: - case ID::Path_FolderNote_CurrentNotebook: - { - activateItem(m_listWidget->currentItem()); - break; - } - - case ID::Content_Note_AllNotebook: - case ID::Content_Note_CurrentNotebook: - case ID::Content_Note_CurrentFolder: - case ID::Content_Note_ExplorerDirectory: - case ID::Content_Note_Buffer: - case ID::Outline_Note_Buffer: - { - activateItem(m_treeWidget->currentItem(), 0); - break; - } - - default: - Q_ASSERT(false); - } -} - -void VSearchUE::askToStop(int p_id) -{ - Q_UNUSED(p_id); - if (m_inSearch) { - m_search->stop(); - } -} - -void VSearchUE::selectParentItem(int p_id) -{ - switch (p_id) { - case ID::Content_Note_AllNotebook: - case ID::Content_Note_CurrentNotebook: - case ID::Content_Note_CurrentFolder: - case ID::Content_Note_ExplorerDirectory: - case ID::Content_Note_Buffer: - case ID::Outline_Note_Buffer: - m_treeWidget->selectParentItem(); - break; - - default: - break; - } -} - -void VSearchUE::toggleItemExpanded(int p_id) -{ - switch (p_id) { - case ID::Content_Note_AllNotebook: - case ID::Content_Note_CurrentNotebook: - case ID::Content_Note_CurrentFolder: - case ID::Content_Note_ExplorerDirectory: - case ID::Content_Note_Buffer: - case ID::Outline_Note_Buffer: - { - QTreeWidgetItem *item = m_treeWidget->currentItem(); - if (item) { - item->setExpanded(!item->isExpanded()); - } - - break; - } - - default: - break; - } -} - -void VSearchUE::expandCollapseAll(int p_id) -{ - switch (p_id) { - case ID::Content_Note_AllNotebook: - case ID::Content_Note_CurrentNotebook: - case ID::Content_Note_CurrentFolder: - case ID::Content_Note_ExplorerDirectory: - case ID::Content_Note_Buffer: - case ID::Outline_Note_Buffer: - { - VTreeWidget::expandCollapseAll(m_treeWidget); - break; - } - - default: - break; - } -} - -void VSearchUE::sort(int p_id) -{ - static bool noteFirst = false; - - switch (p_id) { - case ID::Name_Notebook_AllNotebook: - case ID::Name_FolderNote_AllNotebook: - case ID::Tag_Note_AllNotebook: - case ID::Name_FolderNote_CurrentNotebook: - case ID::Tag_Note_CurrentNotebook: - case ID::Name_FolderNote_CurrentFolder: - case ID::Tag_Note_CurrentFolder: - case ID::Name_Note_Buffer: - case ID::Path_FolderNote_AllNotebook: - case ID::Path_FolderNote_CurrentNotebook: - { - int cnt = m_listWidget->count(); - if (noteFirst) { - int idx = cnt - 1; - while (true) { - if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) { - // Move it to the first row. - m_listWidget->moveItem(idx, 0); - } else { - break; - } - } - } else { - int idx = 0; - while (true) { - if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) { - // Move it to the last row. - m_listWidget->moveItem(idx, cnt - 1); - } else { - break; - } - } - } - - if (cnt) { - m_listWidget->setCurrentRow(0); - } - - noteFirst = !noteFirst; - break; - } - - default: - break; - } -} - -QString VSearchUE::currentItemFolder(int p_id) -{ - QString folder; - QSharedPointer resItem; - - switch (p_id) { - case ID::Name_Notebook_AllNotebook: - case ID::Name_FolderNote_AllNotebook: - case ID::Tag_Note_AllNotebook: - case ID::Name_FolderNote_CurrentNotebook: - case ID::Tag_Note_CurrentNotebook: - case ID::Name_FolderNote_CurrentFolder: - case ID::Tag_Note_CurrentFolder: - case ID::Name_Note_Buffer: - case ID::Path_FolderNote_AllNotebook: - case ID::Path_FolderNote_CurrentNotebook: - { - QListWidgetItem *item = m_listWidget->currentItem(); - if (item) { - resItem = itemResultData(item); - } - - break; - } - - case ID::Content_Note_AllNotebook: - case ID::Content_Note_CurrentNotebook: - case ID::Content_Note_CurrentFolder: - case ID::Content_Note_ExplorerDirectory: - case ID::Content_Note_Buffer: - case ID::Outline_Note_Buffer: - { - QTreeWidgetItem *item = m_treeWidget->currentItem(); - if (item) { - resItem = itemResultData(item); - } - - break; - } - - default: - Q_ASSERT(false); - } - - if (!resItem.isNull()) { - switch (resItem->m_type) { - case VSearchResultItem::Note: - folder = VUtils::basePathFromPath(resItem->m_path); - break; - - case VSearchResultItem::Folder: - case VSearchResultItem::Notebook: - folder = resItem->m_path; - break; - - default: - break; - } - } - - return folder; -} diff --git a/src/vsearchue.h b/src/vsearchue.h deleted file mode 100644 index f3c5ed97..00000000 --- a/src/vsearchue.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef VSEARCHUE_H -#define VSEARCHUE_H - -#include "iuniversalentry.h" - -#include - -#include "vsearchconfig.h" - -class VListWidgetDoubleRows; -class QListWidgetItem; -class VTreeWidget; -class QTreeWidgetItem; - - -// Universal Entry using VSearch. -class VSearchUE : public IUniversalEntry -{ - Q_OBJECT -public: - enum ID - { - // List and search the name of all notebooks. - Name_Notebook_AllNotebook = 0, - - // Search the name of the folder/note in all the notebooks. - Name_FolderNote_AllNotebook, - - // Search content of the note in all the notebooks. - Content_Note_AllNotebook, - - // Search tag of the note in all the notebooks. - Tag_Note_AllNotebook, - - // Search the name of the folder/note in current notebook. - Name_FolderNote_CurrentNotebook, - - // Search content of the note in current notebook. - Content_Note_CurrentNotebook, - - // Search tag of the note in current notebook. - Tag_Note_CurrentNotebook, - - // Search the name of the folder/note in current folder. - Name_FolderNote_CurrentFolder, - - // Search content of the note in current folder. - Content_Note_CurrentFolder, - - // Search the tag of the note in current folder. - Tag_Note_CurrentFolder, - - // List and search the name of opened notes in buffer. - Name_Note_Buffer, - - // Search content of opened notes in buffer. - Content_Note_Buffer, - - // Search outline of opened notes in buffer. - Outline_Note_Buffer, - - // Search path of folder/note in all the notebooks. - Path_FolderNote_AllNotebook, - - // Search path of folder/note in current notebook. - Path_FolderNote_CurrentNotebook, - - // Search content of the note in Explorer root directory. - Content_Note_ExplorerDirectory - }; - - explicit VSearchUE(QObject *p_parent = nullptr); - - QString description(int p_id) const Q_DECL_OVERRIDE; - - QWidget *widget(int p_id) Q_DECL_OVERRIDE; - - void processCommand(int p_id, const QString &p_cmd) Q_DECL_OVERRIDE; - - void clear(int p_id) Q_DECL_OVERRIDE; - - void selectNextItem(int p_id, bool p_forward) Q_DECL_OVERRIDE; - - void selectParentItem(int p_id) Q_DECL_OVERRIDE; - - void activate(int p_id) Q_DECL_OVERRIDE; - - void askToStop(int p_id) Q_DECL_OVERRIDE; - - void toggleItemExpanded(int p_id) Q_DECL_OVERRIDE; - - void sort(int p_id) Q_DECL_OVERRIDE; - - QString currentItemFolder(int p_id) Q_DECL_OVERRIDE; - - static void activateItem(const QSharedPointer &p_item, int p_matchIndex = 0); - - void expandCollapseAll(int p_id) Q_DECL_OVERRIDE; - -protected: - void init() Q_DECL_OVERRIDE; - -private slots: - void handleSearchItemAdded(const QSharedPointer &p_item); - - void handleSearchItemsAdded(const QList > &p_items); - - void handleSearchFinished(const QSharedPointer &p_result); - - void activateItem(QListWidgetItem *p_item); - - void activateItem(QTreeWidgetItem *p_item, int p_col); - -private: - void searchNameOfAllNotebooks(const QString &p_cmd); - - void searchNameOfFolderNoteInAllNotebooks(const QString &p_cmd); - - void searchTagOfNoteInAllNotebooks(const QString &p_cmd); - - void searchTagOfNoteInCurrentNotebook(const QString &p_cmd); - - void searchTagOfNoteInCurrentFolder(const QString &p_cmd); - - void searchNameOfFolderNoteInCurrentNotebook(const QString &p_cmd); - - void searchNameOfFolderNoteInCurrentFolder(const QString &p_cmd); - - void searchContentOfNoteInAllNotebooks(const QString &p_cmd); - - void searchContentOfNoteInCurrentNotebook(const QString &p_cmd); - - void searchContentOfNoteInCurrentFolder(const QString &p_cmd); - - void searchContentOfNoteInExplorerDirectory(const QString &p_cmd); - - void searchNameOfBuffer(const QString &p_cmd); - - void searchContentOfBuffer(const QString &p_cmd); - - void searchOutlineOfBuffer(const QString &p_cmd); - - void searchPathOfFolderNoteInAllNotebooks(const QString &p_cmd); - - void searchPathOfFolderNoteInCurrentNotebook(const QString &p_cmd); - - // Stop the search synchronously. - void stopSearch(); - - void appendItemToList(const QSharedPointer &p_item); - - void appendItemToTree(const QSharedPointer &p_item); - - const QSharedPointer &itemResultData(const QListWidgetItem *p_item) const; - - const QSharedPointer &itemResultData(const QTreeWidgetItem *p_item) const; - - // Update geometry of widget. - void updateWidget(); - - VSearch *m_search; - - bool m_inSearch; - - // Current instance ID. - int m_id; - - QVector > m_data; - - QIcon m_noteIcon; - QIcon m_folderIcon; - QIcon m_notebookIcon; - - VListWidgetDoubleRows *m_listWidget; - - VTreeWidget *m_treeWidget; -}; - -#endif // VSEARCHUE_H diff --git a/src/vsimplesearchinput.cpp b/src/vsimplesearchinput.cpp deleted file mode 100644 index 2a09e0f1..00000000 --- a/src/vsimplesearchinput.cpp +++ /dev/null @@ -1,237 +0,0 @@ -#include "vsimplesearchinput.h" - -#include -#include -#include -#include -#include -#include - -#include "vlineedit.h" -#include "utils/vutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VSimpleSearchInput::VSimpleSearchInput(ISimpleSearch *p_obj, QWidget *p_parent) - : QWidget(p_parent), - m_obj(p_obj), - m_inSearchMode(false), - m_currentIdx(-1), - m_wildCardEnabled(g_config->getEnableWildCardInSimpleSearch()), - m_navigationKeyEnabled(false) -{ - if (m_wildCardEnabled) { - m_matchFlags = Qt::MatchWildcard | Qt::MatchWrap | Qt::MatchRecursive; - } else { - m_matchFlags = Qt::MatchContains | Qt::MatchWrap | Qt::MatchRecursive; - } - - m_searchEdit = new VLineEdit(); - m_searchEdit->setPlaceholderText(tr("Type to search")); - m_searchEdit->setCtrlKEnabled(false); - connect(m_searchEdit, &QLineEdit::textChanged, - this, &VSimpleSearchInput::handleEditTextChanged); - - QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), - m_searchEdit); - m_searchEdit->setValidator(validator); - m_searchEdit->installEventFilter(this); - - m_infoLabel = new QLabel(); - - QLayout *layout = new QHBoxLayout(); - layout->addWidget(m_searchEdit); - layout->addWidget(m_infoLabel); - layout->setContentsMargins(0, 0, 0, 0); - - setLayout(layout); -} - -void VSimpleSearchInput::clear() -{ - m_inSearchMode = false; - clearSearch(); -} - -// If it is the / leader key to trigger search mode. -static bool isLeaderKey(int p_key, int p_modifiers) -{ - return p_key == Qt::Key_Slash && p_modifiers == Qt::NoModifier; -} - -static bool isCharKey(int p_key, int p_modifiers) -{ - return p_key >= Qt::Key_A - && p_key <= Qt::Key_Z - && (p_modifiers == Qt::NoModifier || p_modifiers == Qt::ShiftModifier); -} - -static bool isDigitKey(int p_key, int p_modifiers) -{ - return p_key >= Qt::Key_0 - && p_key <= Qt::Key_9 - && (p_modifiers == Qt::NoModifier || p_modifiers == Qt::KeypadModifier); -} - -static QChar keyToChar(int p_key, int p_modifiers) -{ - if (isCharKey(p_key, p_modifiers)) { - char ch = p_modifiers == Qt::ShiftModifier ? 'A' : 'a'; - return QChar(ch + (p_key - Qt::Key_A)); - } else if (isDigitKey(p_key, p_modifiers)) { - return QChar('0' + (p_key - Qt::Key_0)); - } - - return QChar(); -} - -bool VSimpleSearchInput::tryHandleKeyPressEvent(QKeyEvent *p_event) -{ - int key = p_event->key(); - Qt::KeyboardModifiers modifiers = p_event->modifiers(); - - if (!m_inSearchMode) { - // Try to trigger search mode. - QChar ch; - if (isCharKey(key, modifiers) - || isDigitKey(key, modifiers)) { - m_inSearchMode = true; - ch = keyToChar(key, modifiers); - } else if (isLeaderKey(key, modifiers)) { - m_inSearchMode = true; - } - - if (m_inSearchMode) { - emit triggered(m_inSearchMode, false); - - clearSearch(); - m_searchEdit->setFocus(); - - if (!ch.isNull()) { - m_searchEdit->setText(ch); - } - - return true; - } - } else { - // Try to exit search mode. - if (key == Qt::Key_Escape - || (key == Qt::Key_BracketLeft - && VUtils::isControlModifierForVim(modifiers))) { - m_inSearchMode = false; - emit triggered(m_inSearchMode, true); - return true; - } - } - - // Ctrl+N/P to activate next hit item. - if (VUtils::isControlModifierForVim(modifiers) - && (key == Qt::Key_N || key == Qt::Key_P)) { - int delta = key == Qt::Key_N ? 1 : -1; - - if (!m_inSearchMode) { - m_inSearchMode = true; - emit triggered(m_inSearchMode, false); - m_searchEdit->setFocus(); - - m_obj->highlightHitItems(m_hitItems); - } - - if (!m_hitItems.isEmpty()) { - m_currentIdx += delta; - if (m_currentIdx < 0) { - m_currentIdx = m_hitItems.size() - 1; - } else if (m_currentIdx >= m_hitItems.size()) { - m_currentIdx = 0; - } - - m_obj->selectHitItem(currentItem()); - } - - return true; - } - - // Up/Down Ctrl+K/J to navigate to next item. - // QTreeWidget may not response to the key event if it does not have the focus. - if (m_inSearchMode && m_navigationKeyEnabled) { - if (key == Qt::Key_Down - || key == Qt::Key_Up - || (VUtils::isControlModifierForVim(modifiers) - && (key == Qt::Key_J || key == Qt::Key_K))) { - bool forward = true; - if (key == Qt::Key_Up || key == Qt::Key_K) { - forward = false; - } - - m_obj->selectNextItem(forward); - return true; - } - } - - return false; -} - -void VSimpleSearchInput::clearSearch() -{ - m_searchEdit->clear(); - m_hitItems.clear(); - m_currentIdx = -1; - m_obj->clearItemsHighlight(); - - updateInfoLabel(0, m_obj->totalNumberOfItems()); -} - -bool VSimpleSearchInput::eventFilter(QObject *p_watched, QEvent *p_event) -{ - Q_UNUSED(p_watched); - if (p_event->type() == QEvent::FocusOut) { - QFocusEvent *eve = static_cast(p_event); - if (eve->reason() != Qt::ActiveWindowFocusReason) { - m_inSearchMode = false; - emit triggered(m_inSearchMode, false); - } - } - - return QWidget::eventFilter(p_watched, p_event); -} - -void VSimpleSearchInput::handleEditTextChanged(const QString &p_text) -{ - if (!m_inSearchMode) { - goto exit; - } - - if (p_text.isEmpty()) { - clearSearch(); - m_obj->selectHitItem(NULL); - goto exit; - } - - if (m_wildCardEnabled) { - QString wildcardText(p_text.size() * 2 + 1, '*'); - for (int i = 0, j = 1; i < p_text.size(); ++i, j += 2) { - wildcardText[j] = p_text[i]; - } - - m_hitItems = m_obj->searchItems(wildcardText, m_matchFlags); - } else { - m_hitItems = m_obj->searchItems(p_text, m_matchFlags); - } - - updateInfoLabel(m_hitItems.size(), m_obj->totalNumberOfItems()); - - m_obj->highlightHitItems(m_hitItems); - - m_currentIdx = m_hitItems.isEmpty() ? -1 : 0; - - m_obj->selectHitItem(currentItem()); - -exit: - emit inputTextChanged(p_text); -} - -void VSimpleSearchInput::updateInfoLabel(int p_nrHit, int p_total) -{ - m_infoLabel->setText(tr("%1/%2").arg(p_nrHit).arg(p_total)); -} diff --git a/src/vsimplesearchinput.h b/src/vsimplesearchinput.h deleted file mode 100644 index 3d19b695..00000000 --- a/src/vsimplesearchinput.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef VSIMPLESEARCHINPUT_H -#define VSIMPLESEARCHINPUT_H - -#include -#include - -class VLineEdit; -class QLabel; - -class ISimpleSearch -{ -public: - // Return items matching the search. - virtual QList searchItems(const QString &p_text, - Qt::MatchFlags p_flags) const = 0; - - // Highlight hit items to denote the search result. - virtual void highlightHitItems(const QList &p_items) = 0; - - // Clear the highlight. - virtual void clearItemsHighlight() = 0; - - // Select @p_item. - // @p_item sets to NULL to clear selection. - virtual void selectHitItem(void *p_item) = 0; - - // Get the total number of all the items. - virtual int totalNumberOfItems() = 0; - - // Select next item. - virtual void selectNextItem(bool p_forward) = 0; -}; - - -class VSimpleSearchInput : public QWidget -{ - Q_OBJECT -public: - explicit VSimpleSearchInput(ISimpleSearch *p_obj, QWidget *p_parent = nullptr); - - // Clear input. - void clear(); - - // Try to handle key press event from outside widget. - // Return true if @p_event is consumed and do not need further process. - bool tryHandleKeyPressEvent(QKeyEvent *p_event); - - void setNavigationKeyEnabled(bool p_enabled); - - void setMatchFlags(Qt::MatchFlags p_flags); - - Qt::MatchFlags getMatchFlags() const; - -signals: - // Search mode is triggered. - // @p_focus: whether the widget containing this input should get focus. - void triggered(bool p_inSearchMode, bool p_focus); - - void inputTextChanged(const QString &p_text); - -protected: - bool eventFilter(QObject *p_watched, QEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - // Text in the input changed. - void handleEditTextChanged(const QString &p_text); - -private: - // Clear last search. - void clearSearch(); - - void *currentItem() const; - - void updateInfoLabel(int p_nrHit, int p_total); - - ISimpleSearch *m_obj; - - VLineEdit *m_searchEdit; - - QLabel *m_infoLabel; - - bool m_inSearchMode; - - QList m_hitItems; - - int m_currentIdx; - - Qt::MatchFlags m_matchFlags; - - bool m_wildCardEnabled; - - // Down/Up/Ctrl+J/Ctrl+K to navigate. - bool m_navigationKeyEnabled; -}; - -inline void *VSimpleSearchInput::currentItem() const -{ - if (m_currentIdx >= 0 && m_currentIdx < m_hitItems.size()) { - return m_hitItems[m_currentIdx]; - } - - return NULL; -} - -inline void VSimpleSearchInput::setNavigationKeyEnabled(bool p_enabled) -{ - m_navigationKeyEnabled = p_enabled; -} - -inline void VSimpleSearchInput::setMatchFlags(Qt::MatchFlags p_flags) -{ - m_matchFlags = p_flags; -} - -inline Qt::MatchFlags VSimpleSearchInput::getMatchFlags() const -{ - return m_matchFlags; -} -#endif // VSIMPLESEARCHINPUT_H diff --git a/src/vsingleinstanceguard.cpp b/src/vsingleinstanceguard.cpp deleted file mode 100644 index 2ddacfcc..00000000 --- a/src/vsingleinstanceguard.cpp +++ /dev/null @@ -1,192 +0,0 @@ -#include "vsingleinstanceguard.h" -#include - -#include "utils/vutils.h" - -const QString VSingleInstanceGuard::c_memKey = "vnote_shared_memory"; -const int VSingleInstanceGuard::c_magic = 19910906; - -VSingleInstanceGuard::VSingleInstanceGuard() - : m_online(false), - m_sharedMemory(c_memKey) -{ -} - -bool VSingleInstanceGuard::tryRun() -{ - m_online = false; - - // If we can attach to the sharedmemory, there is another instance running. - // In Linux, crashes may cause the shared memory segment remains. In this case, - // this will attach to the old segment, then exit, freeing the old segment. - if (m_sharedMemory.attach()) { - qDebug() << "another instance is running"; - return false; - } - - // Try to create it. - bool ret = m_sharedMemory.create(sizeof(SharedStruct)); - if (ret) { - // We created it. - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - str->m_magic = c_magic; - str->m_filesBufIdx = 0; - str->m_askedToShow = false; - m_sharedMemory.unlock(); - - m_online = true; - return true; - } else { - qWarning() << "fail to create shared memory segment " - "(keep in mind that do not run multiple instances of VNote)"; - // On macOS, this happens a lot. Just let it go. - return true; - } -} - -void VSingleInstanceGuard::openExternalFiles(const QStringList &p_files) -{ - if (p_files.isEmpty()) { - return; - } - - if (!m_sharedMemory.isAttached()) { - if (!m_sharedMemory.attach()) { - qDebug() << "fail to attach to the shared memory segment" - << (m_sharedMemory.error() ? m_sharedMemory.errorString() : ""); - return; - } - } - - qDebug() << "try to request another instance to open files" << p_files; - - int idx = 0; - int tryCount = 100; - while (tryCount--) { - qDebug() << "set shared memory one round" << idx << "of" << p_files.size(); - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - V_ASSERT(str->m_magic == c_magic); - for (; idx < p_files.size(); ++idx) { - if (p_files[idx].size() + 1 > FilesBufCount) { - qDebug() << "skip file since its long name" << p_files[idx]; - // Skip this long long name file. - continue; - } - - if (!appendFileToBuffer(str, p_files[idx])) { - break; - } - } - - m_sharedMemory.unlock(); - - if (idx < p_files.size()) { - VUtils::sleepWait(500); - } else { - break; - } - } -} - -bool VSingleInstanceGuard::appendFileToBuffer(SharedStruct *p_str, const QString &p_file) -{ - if (p_file.isEmpty()) { - return true; - } - - int strSize = p_file.size(); - if (strSize + 1 > FilesBufCount - p_str->m_filesBufIdx) { - qDebug() << "no enough space for" << p_file; - return false; - } - - // Put the size first. - p_str->m_filesBuf[p_str->m_filesBufIdx++] = (ushort)strSize; - const QChar *data = p_file.constData(); - for (int i = 0; i < strSize; ++i) { - p_str->m_filesBuf[p_str->m_filesBufIdx++] = data[i].unicode(); - } - - qDebug() << "after appended one file" << p_str->m_filesBufIdx << p_file; - return true; -} - -QStringList VSingleInstanceGuard::fetchFilesToOpen() -{ - QStringList files; - - if (!m_online) { - return files; - } - - Q_ASSERT(m_sharedMemory.isAttached()); - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - Q_ASSERT(str->m_magic == c_magic); - Q_ASSERT(str->m_filesBufIdx <= FilesBufCount); - int idx = 0; - while (idx < str->m_filesBufIdx) { - int strSize = str->m_filesBuf[idx++]; - Q_ASSERT(strSize <= str->m_filesBufIdx - idx); - QString file; - for (int i = 0; i < strSize; ++i) { - file.append(QChar(str->m_filesBuf[idx++])); - } - - files.append(file); - } - - str->m_filesBufIdx = 0; - m_sharedMemory.unlock(); - - return files; -} - -void VSingleInstanceGuard::showInstance() -{ - if (!m_sharedMemory.isAttached()) { - if (!m_sharedMemory.attach()) { - qDebug() << "fail to attach to the shared memory segment" - << (m_sharedMemory.error() ? m_sharedMemory.errorString() : ""); - return; - } - } - - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - V_ASSERT(str->m_magic == c_magic); - str->m_askedToShow = true; - m_sharedMemory.unlock(); - - qDebug() << "try to request another instance to show up"; -} - -bool VSingleInstanceGuard::fetchAskedToShow() -{ - if (!m_online) { - return false; - } - - Q_ASSERT(m_sharedMemory.isAttached()); - m_sharedMemory.lock(); - SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); - Q_ASSERT(str->m_magic == c_magic); - bool ret = str->m_askedToShow; - str->m_askedToShow = false; - m_sharedMemory.unlock(); - - return ret; -} - -void VSingleInstanceGuard::exit() -{ - if (!m_online) { - return; - } - - Q_ASSERT(m_sharedMemory.isAttached()); - m_sharedMemory.detach(); - m_online = false; -} diff --git a/src/vsingleinstanceguard.h b/src/vsingleinstanceguard.h deleted file mode 100644 index f212aeaf..00000000 --- a/src/vsingleinstanceguard.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef VSINGLEINSTANCEGUARD_H -#define VSINGLEINSTANCEGUARD_H - -#include -#include -#include - -class VSingleInstanceGuard -{ -public: - VSingleInstanceGuard(); - - // Return ture if this is the only instance of VNote. - bool tryRun(); - - // There is already another instance running. - // Call this to ask that instance to open external files passed in - // via command line arguments. - void openExternalFiles(const QStringList &p_files); - - // Ask another instance to show itself. - void showInstance(); - - // Fetch files from shared memory to open. - // Will clear the shared memory. - QStringList fetchFilesToOpen(); - - // Whether this instance is asked to show itself. - bool fetchAskedToShow(); - - // A running instance requests to exit. - void exit(); - -private: - // The count of the entries in the buffer to hold the path of the files to open. - enum { FilesBufCount = 1024 }; - - struct SharedStruct { - // A magic number to identify if this struct is initialized - int m_magic; - - // Next empty entry in m_filesBuf. - int m_filesBufIdx; - - // File paths to be opened. - // Encoded in this way with 2 bytes for each size part. - // [size of file1][file1][size of file2][file 2] - // Unicode representation of QString. - ushort m_filesBuf[FilesBufCount]; - - // Whether other instances ask to show the legal instance. - bool m_askedToShow; - }; - - // Append @p_file to the shared struct files buffer. - // Returns true if succeeds or false if there is no enough space. - bool appendFileToBuffer(SharedStruct *p_str, const QString &p_file); - - bool m_online; - - QSharedMemory m_sharedMemory; - - static const QString c_memKey; - static const int c_magic; -}; - -#endif // VSINGLEINSTANCEGUARD_H diff --git a/src/vsnippet.cpp b/src/vsnippet.cpp deleted file mode 100644 index 17e0676f..00000000 --- a/src/vsnippet.cpp +++ /dev/null @@ -1,253 +0,0 @@ -#include "vsnippet.h" - -#include -#include - -#include "vconstants.h" -#include "utils/vutils.h" -#include "utils/veditutils.h" -#include "utils/vmetawordmanager.h" - -extern VMetaWordManager *g_mwMgr; - -const QString VSnippet::c_defaultCursorMark = "@@"; - -const QString VSnippet::c_defaultSelectionMark = "$$"; - -QVector VSnippet::s_allShortcuts; - -VSnippet::VSnippet() - : m_type(Type::PlainText), - m_cursorMark(c_defaultCursorMark), - m_autoIndent(false) -{ -} - -VSnippet::VSnippet(const QString &p_name, - Type p_type, - const QString &p_content, - const QString &p_cursorMark, - const QString &p_selectionMark, - QChar p_shortcut, - bool p_autoIndent) - : m_name(p_name), - m_type(p_type), - m_content(p_content), - m_cursorMark(p_cursorMark), - m_selectionMark(p_selectionMark), - m_shortcut(p_shortcut), - m_autoIndent(p_autoIndent) -{ - Q_ASSERT(m_selectionMark != m_cursorMark); -} - -bool VSnippet::update(const QString &p_name, - Type p_type, - const QString &p_content, - const QString &p_cursorMark, - const QString &p_selectionMark, - QChar p_shortcut, - bool p_autoIndent) -{ - bool updated = false; - if (m_name != p_name) { - m_name = p_name; - updated = true; - } - - if (m_type != p_type) { - m_type = p_type; - updated = true; - } - - if (m_content != p_content) { - m_content = p_content; - updated = true; - } - - if (m_cursorMark != p_cursorMark) { - m_cursorMark = p_cursorMark; - updated = true; - } - - if (m_selectionMark != p_selectionMark) { - m_selectionMark = p_selectionMark; - updated = true; - } - - if (m_shortcut != p_shortcut) { - m_shortcut = p_shortcut; - updated = true; - } - - if (m_autoIndent != p_autoIndent) { - m_autoIndent = p_autoIndent; - updated = true; - } - - qDebug() << "snippet" << m_name << "updated" << updated; - - return updated; -} - -QString VSnippet::typeStr(VSnippet::Type p_type) -{ - switch (p_type) { - case Type::PlainText: - return QObject::tr("PlainText"); - - case Type::Html: - return QObject::tr("Html"); - - default: - return QObject::tr("Invalid"); - } -} - -QJsonObject VSnippet::toJson() const -{ - QJsonObject snip; - snip[SnippetConfig::c_name] = m_name; - snip[SnippetConfig::c_type] = (int)m_type; - snip[SnippetConfig::c_cursorMark] = m_cursorMark; - snip[SnippetConfig::c_selectionMark] = m_selectionMark; - snip[SnippetConfig::c_shortcut] = m_shortcut.isNull() ? "" : QString(m_shortcut); - snip[SnippetConfig::c_autoIndent] = m_autoIndent; - - return snip; -} - -VSnippet VSnippet::fromJson(const QJsonObject &p_json) -{ - QChar shortcut; - QString shortcutStr = p_json[SnippetConfig::c_shortcut].toString(); - if (!shortcutStr.isEmpty() && isValidShortcut(shortcutStr[0])) { - shortcut = shortcutStr[0]; - } - - VSnippet snip(p_json[SnippetConfig::c_name].toString(), - static_cast(p_json[SnippetConfig::c_type].toInt()), - "", - p_json[SnippetConfig::c_cursorMark].toString(), - p_json[SnippetConfig::c_selectionMark].toString(), - shortcut, - p_json[SnippetConfig::c_autoIndent].toBool()); - - return snip; -} - -const QVector &VSnippet::getAllShortcuts() -{ - if (s_allShortcuts.isEmpty()) { - // Init. - char ch = 'a'; - while (true) { - s_allShortcuts.append(ch); - if (ch == 'z') { - break; - } - - ch++; - } - } - - return s_allShortcuts; -} - -bool VSnippet::isValidShortcut(QChar p_char) -{ - if (p_char >= 'a' && p_char <= 'z') { - return true; - } - - return false; -} - -bool VSnippet::apply(QTextCursor &p_cursor) const -{ - p_cursor.beginEditBlock(); - // Delete selected text. - QString selection = VEditUtils::selectedText(p_cursor); - p_cursor.removeSelectedText(); - - // Evaluate the content. - QString content = g_mwMgr->evaluate(m_content); - - if (content.isEmpty()) { - p_cursor.endEditBlock(); - return true; - } - - // Find the cursor mark and break the content. - QString secondPart; - if (!m_cursorMark.isEmpty()) { - QStringList parts = content.split(m_cursorMark); - Q_ASSERT(parts.size() < 3 && parts.size() > 0); - - content = parts[0]; - if (parts.size() == 2) { - secondPart = parts[1]; - } - } - - // Replace the selection mark. - // Content may be empty. - if (!m_selectionMark.isEmpty() && !content.isEmpty()) { - content.replace(m_selectionMark, selection); - } - - int pos = p_cursor.position() + content.size(); - - if (!m_selectionMark.isEmpty() && !secondPart.isEmpty()) { - secondPart.replace(m_selectionMark, selection); - } - - content += secondPart; - - // Auto indent. - QTextBlock startBlock = p_cursor.block(); - QTextBlock endBlock; - QString indentation = VEditUtils::fetchIndentSpaces(startBlock); - - // Insert it. - switch (m_type) { - case Type::Html: - p_cursor.insertHtml(content); - break; - - case Type::PlainText: - V_FALLTHROUGH; - - default: - p_cursor.insertText(content); - break; - } - - endBlock = p_cursor.block(); - - if (m_autoIndent - && startBlock != endBlock - && !indentation.isEmpty()) { - // Indent (startBlock, endBlock]. - startBlock = startBlock.next(); - while (startBlock.isValid()) { - int tmpPos = startBlock.position(); - p_cursor.setPosition(tmpPos); - VEditUtils::indentBlock(p_cursor, indentation, false); - if (tmpPos <= pos) { - pos += indentation.size(); - } - - if (startBlock == endBlock) { - break; - } - - startBlock = startBlock.next(); - } - } - - p_cursor.setPosition(pos); - - p_cursor.endEditBlock(); - return true; -} diff --git a/src/vsnippet.h b/src/vsnippet.h deleted file mode 100644 index 084389df..00000000 --- a/src/vsnippet.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef VSNIPPET_H -#define VSNIPPET_H - -#include -#include -#include - - -class VSnippet -{ -public: - enum Type - { - PlainText = 0, - Html, - Invalid - }; - - VSnippet(); - - VSnippet(const QString &p_name, - Type p_type = Type::PlainText, - const QString &p_content = QString(), - const QString &p_cursorMark = c_defaultCursorMark, - const QString &p_selectionMark = c_defaultSelectionMark, - QChar p_shortcut = QChar(), - bool p_autoIndent = false); - - // Return true if there is any update. - bool update(const QString &p_name, - Type p_type, - const QString &p_content, - const QString &p_cursorMark, - const QString &p_selectionMark, - QChar p_shortcut, - bool p_autoIndent); - - const QString &getName() const - { - return m_name; - } - - VSnippet::Type getType() const - { - return m_type; - } - - const QString &getCursorMark() const - { - return m_cursorMark; - } - - const QString &getSelectionMark() const - { - return m_selectionMark; - } - - const QString &getContent() const - { - return m_content; - } - - QChar getShortcut() const - { - return m_shortcut; - } - - bool getAutoIndent() const - { - return m_autoIndent; - } - - void setContent(const QString &p_content) - { - m_content = p_content; - } - - // Not including m_content. - QJsonObject toJson() const; - - // Apply this snippet via @p_cursor. - bool apply(QTextCursor &p_cursor) const; - - // Not including m_content. - static VSnippet fromJson(const QJsonObject &p_json); - - static QString typeStr(VSnippet::Type p_type); - - static const QVector &getAllShortcuts(); - - static bool isValidShortcut(QChar p_char); - -private: - // File name in the snippet folder. - QString m_name; - - Type m_type; - - // Support magic word. - QString m_content; - - // String in the content that mark the position of the cursor after insertion. - // If there is no such mark in the content, the cursor should be put at the - // end of the insertion. - QString m_cursorMark; - - // Selection marks in the content will be replaced by selected text. - QString m_selectionMark; - - // Shortcut to apply this snippet. - QChar m_shortcut; - - // Auto indent with the first line. - bool m_autoIndent; - - static const QString c_defaultCursorMark; - - static const QString c_defaultSelectionMark; - - static QVector s_allShortcuts; -}; - -#endif // VSNIPPET_H diff --git a/src/vsnippetlist.cpp b/src/vsnippetlist.cpp deleted file mode 100644 index 1db6a11a..00000000 --- a/src/vsnippetlist.cpp +++ /dev/null @@ -1,653 +0,0 @@ -#include "vsnippetlist.h" - -#include - -#include "vconfigmanager.h" -#include "dialog/veditsnippetdialog.h" -#include "utils/vutils.h" -#include "utils/vimnavigationforwidget.h" -#include "dialog/vsortdialog.h" -#include "dialog/vconfirmdeletiondialog.h" -#include "vmainwindow.h" -#include "utils/viconutils.h" -#include "vlistwidget.h" - -extern VConfigManager *g_config; - -extern VMainWindow *g_mainWin; - -const QString VSnippetList::c_infoShortcutSequence = "F2"; - -VSnippetList::VSnippetList(QWidget *p_parent) - : QWidget(p_parent), - m_initialized(false), - m_uiInitialized(false) -{ - initShortcuts(); -} - -void VSnippetList::setupUI() -{ - if (m_uiInitialized) { - return; - } - - m_uiInitialized = true; - - m_addBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/add_snippet.svg"), ""); - m_addBtn->setToolTip(tr("New Snippet")); - m_addBtn->setProperty("FlatBtn", true); - connect(m_addBtn, &QPushButton::clicked, - this, &VSnippetList::newSnippet); - - m_locateBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/locate_snippet.svg"), ""); - m_locateBtn->setToolTip(tr("Open Folder")); - m_locateBtn->setProperty("FlatBtn", true); - connect(m_locateBtn, &QPushButton::clicked, - this, [this]() { - makeSureFolderExist(); - QUrl url = QUrl::fromLocalFile(g_config->getSnippetConfigFolder()); - QDesktopServices::openUrl(url); - }); - - m_numLabel = new QLabel(); - - QHBoxLayout *btnLayout = new QHBoxLayout; - btnLayout->addWidget(m_addBtn); - btnLayout->addWidget(m_locateBtn); - btnLayout->addStretch(); - btnLayout->addWidget(m_numLabel); - btnLayout->setContentsMargins(0, 0, 0, 0); - - m_snippetList = new VListWidget(); - m_snippetList->setAttribute(Qt::WA_MacShowFocusRect, false); - m_snippetList->setContextMenuPolicy(Qt::CustomContextMenu); - m_snippetList->setSelectionMode(QAbstractItemView::ExtendedSelection); - connect(m_snippetList, &QListWidget::customContextMenuRequested, - this, &VSnippetList::handleContextMenuRequested); - connect(m_snippetList, &QListWidget::itemActivated, - this, &VSnippetList::handleItemActivated); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(btnLayout); - mainLayout->addWidget(m_snippetList); - mainLayout->setContentsMargins(3, 0, 3, 0); - - setLayout(mainLayout); -} - -void VSnippetList::initShortcuts() -{ - QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this); - infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); - connect(infoShortcut, &QShortcut::activated, - this, &VSnippetList::snippetInfo); -} - -void VSnippetList::newSnippet() -{ - QString defaultName = VUtils::getFileNameWithSequence(g_config->getSnippetConfigFolder(), - "snippet"); - - VSnippet tmpSnippet(defaultName); - QString info = tr("Magic words are supported in the content of the snippet."); - VEditSnippetDialog dialog(tr("Create Snippet"), - info, - m_snippets, - tmpSnippet, - this); - if (dialog.exec() == QDialog::Accepted) { - makeSureFolderExist(); - VSnippet snippet(dialog.getNameInput(), - dialog.getTypeInput(), - dialog.getContentInput(), - dialog.getCursorMarkInput(), - dialog.getSelectionMarkInput(), - dialog.getShortcutInput(), - dialog.getAutoIndentInput()); - - QString errMsg; - if (!addSnippet(snippet, &errMsg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to create snippet %2.") - .arg(g_config->c_dataTextStyle) - .arg(snippet.getName()), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - - updateContent(); - } - } -} - -void VSnippetList::handleContextMenuRequested(QPoint p_pos) -{ - QListWidgetItem *item = m_snippetList->itemAt(p_pos); - QMenu menu(this); - menu.setToolTipsVisible(true); - - if (item) { - int itemCount = m_snippetList->selectedItems().size(); - if (itemCount == 1) { - QAction *applyAct = new QAction(VIconUtils::menuIcon(":/resources/icons/apply_snippet.svg"), - tr("&Apply"), - &menu); - applyAct->setToolTip(tr("Insert this snippet in editor")); - connect(applyAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = m_snippetList->currentItem(); - handleItemActivated(item); - }); - menu.addAction(applyAct); - - QAction *infoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/snippet_info.svg"), - tr("&Info (Rename)\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)), - &menu); - infoAct->setToolTip(tr("View and edit snippet's information")); - connect(infoAct, &QAction::triggered, - this, &VSnippetList::snippetInfo); - menu.addAction(infoAct); - } - - QAction *deleteAct = new QAction(VIconUtils::menuDangerIcon(":/resources/icons/delete_snippet.svg"), - tr("&Delete"), - &menu); - deleteAct->setToolTip(tr("Delete selected snippets")); - connect(deleteAct, &QAction::triggered, - this, &VSnippetList::deleteSelectedItems); - menu.addAction(deleteAct); - } - - m_snippetList->update(); - - if (m_snippets.size() > 1) { - if (!menu.actions().isEmpty()) { - menu.addSeparator(); - } - - QAction *sortAct = new QAction(VIconUtils::menuIcon(":/resources/icons/sort.svg"), - tr("&Sort"), - &menu); - sortAct->setToolTip(tr("Sort snippets manually")); - connect(sortAct, &QAction::triggered, - this, &VSnippetList::sortItems); - menu.addAction(sortAct); - } - - if (!menu.actions().isEmpty()) { - menu.exec(m_snippetList->mapToGlobal(p_pos)); - } -} - -void VSnippetList::handleItemActivated(QListWidgetItem *p_item) -{ - const VSnippet *snip = getSnippet(p_item); - if (snip) { - VEditTab *tab = g_mainWin->getCurrentTab(); - if (tab) { - tab->applySnippet(snip); - } - } -} - -void VSnippetList::deleteSelectedItems() -{ - QVector items; - const QList selectedItems = m_snippetList->selectedItems(); - - if (selectedItems.isEmpty()) { - return; - } - - for (auto const & item : selectedItems) { - QString name = item->data(Qt::UserRole).toString(); - items.push_back(ConfirmItemInfo(name, - name, - "", - NULL)); - } - - QString text = tr("Are you sure to delete these snippets?"); - QString info = tr("Click \"Cancel\" to leave them untouched."); - VConfirmDeletionDialog dialog(tr("Confirm Deleting Snippets"), - text, - info, - items, - false, - false, - false, - this); - if (dialog.exec()) { - items = dialog.getConfirmedItems(); - - QList names; - for (auto const & item : items) { - names.append(item.m_name); - } - - QString errMsg; - if (!deleteSnippets(names, &errMsg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to delete snippets."), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateContent(); - } -} - -void VSnippetList::sortItems() -{ - if (m_snippets.size() < 2) { - return; - } - - VSortDialog dialog(tr("Sort Snippets"), - tr("Sort snippets in the configuration file."), - this); - QTreeWidget *tree = dialog.getTreeWidget(); - tree->clear(); - tree->setColumnCount(1); - QStringList headers; - headers << tr("Name"); - tree->setHeaderLabels(headers); - - for (int i = 0; i < m_snippets.size(); ++i) { - QTreeWidgetItem *item = new QTreeWidgetItem(tree, QStringList(m_snippets[i].getName())); - - item->setData(0, Qt::UserRole, i); - } - - dialog.treeUpdated(); - - if (dialog.exec()) { - QVector data = dialog.getSortedData(); - Q_ASSERT(data.size() == m_snippets.size()); - QVector sortedIdx(data.size(), -1); - for (int i = 0; i < data.size(); ++i) { - sortedIdx[i] = data[i].toInt(); - } - - QString errMsg; - if (!sortSnippets(sortedIdx, &errMsg)) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to sort snippets."), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateContent(); - } -} - -void VSnippetList::snippetInfo() -{ - if (m_snippetList->selectedItems().size() != 1) { - return; - } - - QListWidgetItem *item = m_snippetList->currentItem(); - VSnippet *snip = getSnippet(item); - if (!snip) { - return; - } - - QString info = tr("Magic words are supported in the content of the snippet."); - VEditSnippetDialog dialog(tr("Snippet Information"), - info, - m_snippets, - *snip, - this); - if (dialog.exec() == QDialog::Accepted) { - QString errMsg; - bool ret = true; - if (snip->getName() != dialog.getNameInput()) { - // Delete the original snippet file. - if (!deleteSnippetFile(*snip, &errMsg)) { - ret = false; - } - } - - if (snip->update(dialog.getNameInput(), - dialog.getTypeInput(), - dialog.getContentInput(), - dialog.getCursorMarkInput(), - dialog.getSelectionMarkInput(), - dialog.getShortcutInput(), - dialog.getAutoIndentInput())) { - if (!writeSnippetFile(*snip, &errMsg)) { - ret = false; - } - - if (!writeSnippetsToConfig()) { - VUtils::addErrMsg(&errMsg, - tr("Fail to write snippets configuration file.")); - ret = false; - } - - updateContent(); - } - - if (!ret) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to update information of snippet %2.") - .arg(g_config->c_dataTextStyle) - .arg(snip->getName()), - errMsg, - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - } -} - -void VSnippetList::makeSureFolderExist() const -{ - QString path = g_config->getSnippetConfigFolder(); - if (!QFileInfo::exists(path)) { - QDir dir; - dir.mkpath(path); - } -} - -void VSnippetList::updateContent() -{ - m_snippetList->clearAll(); - - for (int i = 0; i < m_snippets.size(); ++i) { - const VSnippet &snip = m_snippets[i]; - QString text = QString("%1%2").arg(snip.getName()) - .arg(snip.getShortcut().isNull() - ? "" : QString(" [%1]").arg(snip.getShortcut())); - QListWidgetItem *item = new QListWidgetItem(text); - item->setToolTip(snip.getName()); - item->setData(Qt::UserRole, snip.getName()); - - m_snippetList->addItem(item); - } - - int cnt = m_snippetList->count(); - if (cnt > 0) { - m_snippetList->setFocus(); - } else { - m_addBtn->setFocus(); - } - - updateNumberLabel(); -} - -bool VSnippetList::addSnippet(const VSnippet &p_snippet, QString *p_errMsg) -{ - if (!writeSnippetFile(p_snippet, p_errMsg)) { - return false; - } - - m_snippets.push_back(p_snippet); - - bool ret = true; - if (!writeSnippetsToConfig()) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to write snippets configuration file.")); - m_snippets.pop_back(); - ret = false; - } - - updateContent(); - - return ret; -} - -bool VSnippetList::writeSnippetsToConfig() const -{ - makeSureFolderExist(); - - QJsonObject snippetJson; - snippetJson[SnippetConfig::c_version] = "1"; - - QJsonArray snippetArray; - for (int i = 0; i < m_snippets.size(); ++i) { - snippetArray.append(m_snippets[i].toJson()); - } - - snippetJson[SnippetConfig::c_snippets] = snippetArray; - - return VUtils::writeJsonToDisk(g_config->getSnippetConfigFilePath(), - snippetJson); -} - -bool VSnippetList::readSnippetsFromConfig() -{ - m_snippets.clear(); - - if (!QFileInfo::exists(g_config->getSnippetConfigFilePath())) { - return true; - } - - QJsonObject snippets = VUtils::readJsonFromDisk(g_config->getSnippetConfigFilePath()); - if (snippets.isEmpty()) { - qWarning() << "invalid snippets configuration file" << g_config->getSnippetConfigFilePath(); - return false; - } - - // [snippets] section. - bool ret = true; - QJsonArray snippetArray = snippets[SnippetConfig::c_snippets].toArray(); - for (int i = 0; i < snippetArray.size(); ++i) { - VSnippet snip = VSnippet::fromJson(snippetArray[i].toObject()); - - // Read the content. - QString filePath(QDir(g_config->getSnippetConfigFolder()).filePath(snip.getName())); - QString content = VUtils::readFileFromDisk(filePath); - if (content.isNull()) { - qWarning() << "fail to read snippet" << snip.getName(); - ret = false; - continue; - } - - snip.setContent(content); - m_snippets.push_back(snip); - } - - return ret; -} - -void VSnippetList::keyPressEvent(QKeyEvent *p_event) -{ - if (VimNavigationForWidget::injectKeyPressEventForVim(m_snippetList, - p_event)) { - return; - } - - QWidget::keyPressEvent(p_event); -} - -void VSnippetList::showNavigation() -{ - setupUI(); - - VNavigationMode::showNavigation(m_snippetList); -} - -bool VSnippetList::handleKeyNavigation(int p_key, bool &p_succeed) -{ - setupUI(); - - return VNavigationMode::handleKeyNavigation(m_snippetList, - p_key, - p_succeed); -} - -int VSnippetList::getSnippetIndex(QListWidgetItem *p_item) const -{ - if (!p_item) { - return -1; - } - - QString name = p_item->data(Qt::UserRole).toString(); - for (int i = 0; i < m_snippets.size(); ++i) { - if (m_snippets[i].getName() == name) { - return i; - } - } - - Q_ASSERT(false); - return -1; -} - -VSnippet *VSnippetList::getSnippet(QListWidgetItem *p_item) -{ - int idx = getSnippetIndex(p_item); - if (idx == -1) { - return NULL; - } else { - return &m_snippets[idx]; - } -} - -bool VSnippetList::writeSnippetFile(const VSnippet &p_snippet, QString *p_errMsg) -{ - // Create and write to the snippet file. - QString filePath = getSnippetFilePath(p_snippet); - if (!VUtils::writeFileToDisk(filePath, p_snippet.getContent())) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to add write the snippet file %1.") - .arg(filePath)); - return false; - } - - return true; -} - -QString VSnippetList::getSnippetFilePath(const VSnippet &p_snippet) const -{ - return QDir(g_config->getSnippetConfigFolder()).filePath(p_snippet.getName()); -} - -bool VSnippetList::sortSnippets(const QVector &p_sortedIdx, QString *p_errMsg) -{ - V_ASSERT(p_sortedIdx.size() == m_snippets.size()); - - auto ori = m_snippets; - - for (int i = 0; i < p_sortedIdx.size(); ++i) { - m_snippets[i] = ori[p_sortedIdx[i]]; - } - - bool ret = true; - if (!writeSnippetsToConfig()) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to write snippets configuration file.")); - m_snippets = ori; - ret = false; - } - - return ret; -} - -bool VSnippetList::deleteSnippets(const QList &p_snippets, - QString *p_errMsg) -{ - if (p_snippets.isEmpty()) { - return true; - } - - bool ret = true; - QSet targets = QSet::fromList(p_snippets); - for (auto it = m_snippets.begin(); it != m_snippets.end();) { - if (targets.contains(it->getName())) { - // Remove it. - if (!deleteSnippetFile(*it, p_errMsg)) { - ret = false; - } - - it = m_snippets.erase(it); - } else { - ++it; - } - } - - if (!writeSnippetsToConfig()) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to write snippets configuration file.")); - ret = false; - } - - return ret; -} - -bool VSnippetList::deleteSnippetFile(const VSnippet &p_snippet, QString *p_errMsg) -{ - QString filePath = getSnippetFilePath(p_snippet); - if (!VUtils::deleteFile(filePath)) { - VUtils::addErrMsg(p_errMsg, - tr("Fail to remove snippet file %1.") - .arg(filePath)); - return false; - } - - return true; -} - -void VSnippetList::focusInEvent(QFocusEvent *p_event) -{ - init(); - - QWidget::focusInEvent(p_event); - - if (m_snippets.isEmpty()) { - m_addBtn->setFocus(); - } else { - m_snippetList->setFocus(); - } -} - -void VSnippetList::updateNumberLabel() const -{ - int cnt = m_snippetList->count(); - m_numLabel->setText(tr("%1 %2").arg(cnt) - .arg(cnt > 1 ? tr("Items") : tr("Item"))); -} - -void VSnippetList::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - setupUI(); - - if (!readSnippetsFromConfig()) { - VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Fail to read snippets from %2.") - .arg(g_config->c_dataTextStyle) - .arg(g_config->getSnippetConfigFolder()), - "", - QMessageBox::Ok, - QMessageBox::Ok, - this); - } - - updateContent(); -} - -void VSnippetList::showEvent(QShowEvent *p_event) -{ - init(); - - QWidget::showEvent(p_event); -} - diff --git a/src/vsnippetlist.h b/src/vsnippetlist.h deleted file mode 100644 index a079bddd..00000000 --- a/src/vsnippetlist.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef VSNIPPETLIST_H -#define VSNIPPETLIST_H - -#include -#include -#include - -#include "vsnippet.h" -#include "vnavigationmode.h" - -class QPushButton; -class VListWidget; -class QListWidgetItem; -class QLabel; -class QKeyEvent; -class QFocusEvent; - - -class VSnippetList : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VSnippetList(QWidget *p_parent = nullptr); - - const QVector &getSnippets() const; - - const VSnippet *getSnippet(const QString &p_name) const; - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void newSnippet(); - - void handleContextMenuRequested(QPoint p_pos); - - void handleItemActivated(QListWidgetItem *p_item); - - void snippetInfo(); - - void deleteSelectedItems(); - - void sortItems(); - -private: - void setupUI(); - - void init(); - - void initShortcuts(); - - void makeSureFolderExist() const; - - // Update list of snippets according to m_snippets. - void updateContent(); - - // Add @p_snippet. - bool addSnippet(const VSnippet &p_snippet, QString *p_errMsg = nullptr); - - // Write m_snippets to config file. - bool writeSnippetsToConfig() const; - - // Read from config file to m_snippets. - bool readSnippetsFromConfig(); - - // Get the snippet index in m_snippets of @p_item. - int getSnippetIndex(QListWidgetItem *p_item) const; - - VSnippet *getSnippet(QListWidgetItem *p_item); - - // Write the content of @p_snippet to file. - bool writeSnippetFile(const VSnippet &p_snippet, QString *p_errMsg = nullptr); - - QString getSnippetFilePath(const VSnippet &p_snippet) const; - - // Sort m_snippets according to @p_sortedIdx. - bool sortSnippets(const QVector &p_sortedIdx, QString *p_errMsg = nullptr); - - bool deleteSnippets(const QList &p_snippets, QString *p_errMsg = nullptr); - - bool deleteSnippetFile(const VSnippet &p_snippet, QString *p_errMsg = nullptr); - - void updateNumberLabel() const; - - bool m_initialized; - - bool m_uiInitialized; - - QPushButton *m_addBtn; - QPushButton *m_locateBtn; - QLabel *m_numLabel; - VListWidget *m_snippetList; - - QVector m_snippets; - - static const QString c_infoShortcutSequence; -}; - -inline const QVector &VSnippetList::getSnippets() const -{ - const_cast(this)->init(); - - return m_snippets; -} - -inline const VSnippet *VSnippetList::getSnippet(const QString &p_name) const -{ - const_cast(this)->init(); - - for (auto const & snip : m_snippets) { - if (snip.getName() == p_name) { - return &snip; - } - } - - return NULL; -} -#endif // VSNIPPETLIST_H diff --git a/src/vstyleditemdelegate.cpp b/src/vstyleditemdelegate.cpp deleted file mode 100644 index 8cf3d172..00000000 --- a/src/vstyleditemdelegate.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "vstyleditemdelegate.h" - -#include -#include -#include -#include - -#include "vpalette.h" -#include "vtreewidget.h" - -extern VPalette *g_palette; - -VStyledItemDelegate::VStyledItemDelegate(QListWidget *p_list, VTreeWidget *p_tree) - : QStyledItemDelegate(p_list ? (QObject *)p_list : (QObject *)p_tree), - m_list(p_list), - m_tree(p_tree) -{ - Q_ASSERT(!(m_list && m_tree)); - m_itemHitBg = QBrush(QColor(g_palette->color("search_hit_item_bg"))); - m_itemHitFg = QBrush(QColor(g_palette->color("search_hit_item_fg"))); - m_itemSeparatorBg = QBrush(QColor(g_palette->color("item_separator_bg"))); - m_itemSeparatorFg = QBrush(QColor(g_palette->color("item_separator_fg"))); -} - -void VStyledItemDelegate::paint(QPainter *p_painter, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const -{ - if (isHit(p_index)) { - QStyleOptionViewItem option(p_option); - p_painter->fillRect(option.rect, m_itemHitBg); - // Does not work anyway. - // option.palette.setBrush(QPalette::Base, m_itemHitBg); - option.palette.setBrush(QPalette::Text, m_itemHitFg); - QStyledItemDelegate::paint(p_painter, option, p_index); - } else if (itemType(p_index) == ItemTypeSeparator) { - QStyleOptionViewItem option(p_option); - p_painter->fillRect(option.rect, m_itemSeparatorBg); - option.palette.setBrush(QPalette::Text, m_itemSeparatorFg); - QStyledItemDelegate::paint(p_painter, option, p_index); - } else { - QStyledItemDelegate::paint(p_painter, p_option, p_index); - } -} - -int VStyledItemDelegate::itemType(const QModelIndex &p_index) const -{ - int type = 0; - if (m_list) { - QListWidgetItem *item = m_list->item(p_index.row()); - if (item) { - type = item->type(); - } - } else if (m_tree) { - QTreeWidgetItem *item = m_tree->getItemFromIndex(p_index); - if (item) { - type = item->type(); - } - } - - return type; -} diff --git a/src/vstyleditemdelegate.h b/src/vstyleditemdelegate.h deleted file mode 100644 index e3b86c5c..00000000 --- a/src/vstyleditemdelegate.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef VSTYLEDITEMDELEGATE_H -#define VSTYLEDITEMDELEGATE_H - -#include -#include -#include - -class QListWidget; -class VTreeWidget; - -// Should be larger then QListWidgetItem::UserType and QTreeWidgetItem::UserType. -#define ItemTypeSeparator 2000 - -class VStyledItemDelegate : public QStyledItemDelegate -{ -public: - explicit VStyledItemDelegate(QListWidget *p_list = nullptr, VTreeWidget *p_tree = nullptr); - - virtual void paint(QPainter *p_painter, - const QStyleOptionViewItem &p_option, - const QModelIndex &p_index) const Q_DECL_OVERRIDE; - - void setHitItems(const QSet &p_hitItems); - - void clearHitItems(); - -private: - bool isHit(const QModelIndex &p_index) const; - - int itemType(const QModelIndex &p_index) const; - - QBrush m_itemHitBg; - QBrush m_itemHitFg; - - QBrush m_itemSeparatorBg; - QBrush m_itemSeparatorFg; - - QSet m_hitItems; - - // m_list OR m_tree (but not both) could be not NULL. - const QListWidget *m_list; - const VTreeWidget *m_tree; -}; - -inline void VStyledItemDelegate::setHitItems(const QSet &p_hitItems) -{ - m_hitItems = p_hitItems; -} - -inline void VStyledItemDelegate::clearHitItems() -{ - m_hitItems.clear(); -} - -inline bool VStyledItemDelegate::isHit(const QModelIndex &p_index) const -{ - if (m_hitItems.isEmpty()) { - return false; - } - - return m_hitItems.contains(p_index); -} -#endif // VSTYLEDITEMDELEGATE_H diff --git a/src/vstyleparser.cpp b/src/vstyleparser.cpp deleted file mode 100644 index 969b721d..00000000 --- a/src/vstyleparser.cpp +++ /dev/null @@ -1,325 +0,0 @@ -#include "vstyleparser.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils/vutils.h" - -VStyleParser::VStyleParser() -{ - markdownStyles = NULL; -} - -VStyleParser::~VStyleParser() -{ - if (markdownStyles) { - pmh_free_style_collection(markdownStyles); - } -} - -QColor VStyleParser::QColorFromPmhAttr(pmh_attr_argb_color *attr) const -{ - return QColor(attr->red, attr->green, attr->blue, attr->alpha); -} - -QBrush VStyleParser::QBrushFromPmhAttr(pmh_attr_argb_color *attr) const -{ - return QBrush(QColorFromPmhAttr(attr)); -} - -void markdownStyleErrorCB(char *errMsg, int lineNr, void *context) -{ - (void)context; - qWarning() << "parser error:" << errMsg << lineNr; -} - -QTextCharFormat VStyleParser::QTextCharFormatFromAttrs(pmh_style_attribute *attrs, - const QFont &baseFont) const -{ - QTextCharFormat format; - while (attrs) { - switch (attrs->type) { - case pmh_attr_type_foreground_color: - format.setForeground(QBrushFromPmhAttr(attrs->value->argb_color)); - break; - - case pmh_attr_type_background_color: - format.setBackground(QBrushFromPmhAttr(attrs->value->argb_color)); - break; - - case pmh_attr_type_font_size_pt: - { - pmh_attr_font_size *fontSize = attrs->value->font_size; - int ptSize = fontSize->size_pt; - if (fontSize->is_relative) { - int basePtSize = baseFont.pointSize(); - if (basePtSize == -1) { - // In pixel. Use default font configuration. - basePtSize = 11; - } - ptSize += basePtSize; - } - if (ptSize > 0) { - format.setFontPointSize(ptSize); - } - break; - } - - case pmh_attr_type_font_family: - { - QString familyList(attrs->value->font_family); - QString finalFamily = VUtils::getAvailableFontFamily(familyList.split(',')); - if (!finalFamily.isEmpty()) { - format.setFontFamily(finalFamily); - } - break; - } - - case pmh_attr_type_font_style: - { - pmh_attr_font_styles *fontStyle = attrs->value->font_styles; - if (fontStyle->italic) { - format.setFontItalic(true); - } - - if (fontStyle->bold) { - format.setFontWeight(QFont::Bold); - } - - if (fontStyle->underlined) { - format.setFontUnderline(true); - } - - if (fontStyle->strikeout) { - format.setFontStrikeOut(true); - } - - break; - } - - default: - qWarning() << "unimplemented format attr type:" << attrs->type; - break; - } - attrs = attrs->next; - } - return format; -} - -void VStyleParser::parseMarkdownStyle(const QString &styleStr) -{ - if (markdownStyles) { - pmh_free_style_collection(markdownStyles); - } - - // markdownStyles is not indexed by element type. - markdownStyles = pmh_parse_styles(styleStr.toLocal8Bit().data(), - &markdownStyleErrorCB, this); -} - -QVector VStyleParser::fetchMarkdownStyles(const QFont &baseFont) const -{ - QVector styles; - - for (int i = 0; i < pmh_NUM_LANG_TYPES; ++i) { - pmh_style_attribute *attr = markdownStyles->element_styles[i]; - if (!attr) { - continue; - } - - HighlightingStyle style; - style.type = attr->lang_element_type; - style.format = QTextCharFormatFromAttrs(attr, baseFont); - styles.append(style); - } - return styles; -} - -QHash VStyleParser::fetchCodeBlockStyles(const QFont & p_baseFont) const -{ - QHash styles; - - pmh_style_attribute *attrs = NULL; - for (int i = 0; i < pmh_NUM_LANG_TYPES; ++i) { - pmh_style_attribute *tmp = markdownStyles->element_styles[i]; - if (!tmp) { - continue; - } - - if (tmp->lang_element_type == pmh_FENCEDCODEBLOCK) { - attrs = tmp; - break; - } - } - - // First set up the base format. - QTextCharFormat baseFormat = QTextCharFormatFromAttrs(attrs, p_baseFont); - - while (attrs) { - switch (attrs->type) { - case pmh_attr_type_other: - { - QString attrName(attrs->name); - QString attrValue(attrs->value->string); - QTextCharFormat format = baseFormat; - - QStringList items = attrValue.split(',', QString::SkipEmptyParts); - for (auto const &item : items) { - QString val = item.trimmed().toLower(); - if (val == "bold") { - format.setFontWeight(QFont::Bold); - } else if (val == "italic") { - format.setFontItalic(true); - } else if (val == "underlined") { - format.setFontUnderline(true); - } else if (val == "strikeout") { - format.setFontStrikeOut(true); - } else { - // Treat it as the color RGB value string without '#'. - QColor color("#" + val); - if (color.isValid()) { - format.setForeground(QBrush(color)); - } - } - } - - if (format.isValid()) { - styles[attrName] = format; - } - break; - } - - default: - // We just only handle custom attribute here. - break; - } - attrs = attrs->next; - } - - return styles; -} - -void VStyleParser::fetchMarkdownEditorStyles(QPalette &palette, QFont &font, - QMap> &styles) const -{ - QString ruleKey; - - int basePointSize = font.pointSize(); - if (basePointSize == -1) { - // The size is specified in pixel. Use 11 pt by default. - basePointSize = 11; - } - - // editor - pmh_style_attribute *editorStyles = markdownStyles->editor_styles; - ruleKey = "editor"; - while (editorStyles) { - switch (editorStyles->type) { - case pmh_attr_type_foreground_color: - palette.setColor(QPalette::Text, - QColorFromPmhAttr(editorStyles->value->argb_color)); - break; - - case pmh_attr_type_background_color: - palette.setColor(QPalette::Base, - QColorFromPmhAttr(editorStyles->value->argb_color)); - break; - - case pmh_attr_type_font_family: - { - QString familyList(editorStyles->value->font_family); - QString finalFamily = VUtils::getAvailableFontFamily(familyList.split(',')); - if (!finalFamily.isEmpty()) { - font.setFamily(finalFamily); - } - break; - } - - case pmh_attr_type_font_size_pt: - { - pmh_attr_font_size *fontSize = editorStyles->value->font_size; - int ptSize = fontSize->size_pt; - if (fontSize->is_relative) { - ptSize += basePointSize; - } - - if (ptSize > 0) { - font.setPointSize(ptSize); - } - - break; - } - - // Get custom styles: - // trailing-space, line-number-background, line-number-foreground, - // color-column-background, color-column-foreground - case pmh_attr_type_other: - { - QString attrName(editorStyles->name); - QString value(editorStyles->value->string); - styles[ruleKey][attrName] = value; - break; - } - - default: - qWarning() << "unimplemented editor attr type:" << editorStyles->type; - } - editorStyles = editorStyles->next; - } - - // editor-current-line - pmh_style_attribute *curLineStyles = markdownStyles->editor_current_line_styles; - ruleKey = "editor-current-line"; - while (curLineStyles) { - switch (curLineStyles->type) { - case pmh_attr_type_background_color: - { - QString attrName(curLineStyles->name); - QString value = QColorFromPmhAttr(curLineStyles->value->argb_color).name(); - styles[ruleKey][attrName] = value; - break; - } - - // Get custom styles: - // vim-background. - case pmh_attr_type_other: - { - QString attrName(curLineStyles->name); - QString value(curLineStyles->value->string); - styles[ruleKey][attrName] = value; - break; - } - - default: - qWarning() << "unimplemented current line attr type:" << curLineStyles->type; - } - curLineStyles = curLineStyles->next; - } - - // editor-selection - pmh_style_attribute *selStyles = markdownStyles->editor_selection_styles; - while (selStyles) { - switch (selStyles->type) { - case pmh_attr_type_foreground_color: - palette.setColor(QPalette::HighlightedText, - QColorFromPmhAttr(selStyles->value->argb_color)); - break; - - case pmh_attr_type_background_color: - palette.setColor(QPalette::Highlight, - QColorFromPmhAttr(selStyles->value->argb_color)); - break; - - default: - qWarning() << "unimplemented selection attr type:" << selStyles->type; - } - selStyles = selStyles->next; - } -} diff --git a/src/vstyleparser.h b/src/vstyleparser.h deleted file mode 100644 index ef41fca7..00000000 --- a/src/vstyleparser.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef VSTYLEPARSER_H -#define VSTYLEPARSER_H - -#include -#include -#include -#include -#include "pegmarkdownhighlighter.h" - -extern "C" { -#include -#include -} - -class QColor; -class QBrush; - -class VStyleParser -{ -public: - VStyleParser(); - ~VStyleParser(); - - void parseMarkdownStyle(const QString &styleStr); - QVector fetchMarkdownStyles(const QFont &baseFont) const; - - // Fetch style sections: editor, editor-selection, editor-current-line. - // @styles: [rule] -> ([attr] -> value). - void fetchMarkdownEditorStyles(QPalette &palette, QFont &font, - QMap> &styles) const; - - QHash fetchCodeBlockStyles(const QFont &p_baseFont) const; - -private: - QColor QColorFromPmhAttr(pmh_attr_argb_color *attr) const; - QBrush QBrushFromPmhAttr(pmh_attr_argb_color *attr) const; - QTextCharFormat QTextCharFormatFromAttrs(pmh_style_attribute *attrs, - const QFont &baseFont) const; - pmh_style_collection *markdownStyles; -}; - -#endif // VSTYLEPARSER_H diff --git a/src/vtabindicator.cpp b/src/vtabindicator.cpp deleted file mode 100644 index 1a186ff7..00000000 --- a/src/vtabindicator.cpp +++ /dev/null @@ -1,300 +0,0 @@ -#include "vtabindicator.h" - -#include - -#include "vedittab.h" -#include "vorphanfile.h" -#include "vbuttonwithwidget.h" -#include "vwordcountinfo.h" -#include "utils/vutils.h" -#include "vtagpanel.h" -#include "vnotefile.h" -#include "vmainwindow.h" -#include "vcaptain.h" - -extern VMainWindow *g_mainWin; - -VWordCountPanel::VWordCountPanel(QWidget *p_parent) - : QWidget(p_parent) -{ - m_wordLabel = new QLabel(); - m_wordLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_charWithoutSpacesLabel = new QLabel(); - m_charWithoutSpacesLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_charWithSpacesLabel = new QLabel(); - m_charWithSpacesLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - - QFormLayout *readLayout = new QFormLayout(); - readLayout->addRow(tr("Words"), m_wordLabel); - readLayout->addRow(tr("Characters (no spaces)"), m_charWithoutSpacesLabel); - readLayout->addRow(tr("Characters (with spaces)"), m_charWithSpacesLabel); - m_readBox = new QGroupBox(tr("Read")); - m_readBox->setLayout(readLayout); - - m_wordEditLabel = new QLabel(); - m_wordEditLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_charWithoutSpacesEditLabel = new QLabel(); - m_charWithoutSpacesEditLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - m_charWithSpacesEditLabel = new QLabel(); - m_charWithSpacesEditLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - - QLabel *cwsLabel = new QLabel(tr("Characters (with spaces)")); - cwsLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); - - QFormLayout *editLayout = new QFormLayout(); - editLayout->addRow(tr("Words"), m_wordEditLabel); - editLayout->addRow(tr("Characters (no spaces)"), m_charWithoutSpacesEditLabel); - editLayout->addRow(cwsLabel, m_charWithSpacesEditLabel); - m_editBox = new QGroupBox(tr("Edit")); - m_editBox->setLayout(editLayout); - - QLabel *titleLabel = new QLabel(tr("Word Count")); - titleLabel->setProperty("TitleLabel", true); - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(titleLabel); - mainLayout->addWidget(m_readBox); - mainLayout->addWidget(m_editBox); - - setLayout(mainLayout); -} - -void VWordCountPanel::updateReadInfo(const VWordCountInfo &p_readInfo) -{ - if (p_readInfo.isNull()) { - m_wordLabel->clear(); - m_charWithoutSpacesLabel->clear(); - m_charWithSpacesLabel->clear(); - } else { - m_wordLabel->setText(QString::number(p_readInfo.m_wordCount)); - m_charWithoutSpacesLabel->setText(QString::number(p_readInfo.m_charWithoutSpacesCount)); - m_charWithSpacesLabel->setText(QString::number(p_readInfo.m_charWithSpacesCount)); - } -} - -void VWordCountPanel::updateEditInfo(const VWordCountInfo &p_editInfo) -{ - if (p_editInfo.isNull()) { - m_wordEditLabel->clear(); - m_charWithoutSpacesEditLabel->clear(); - m_charWithSpacesEditLabel->clear(); - } else { - m_wordEditLabel->setText(QString::number(p_editInfo.m_wordCount)); - m_charWithoutSpacesEditLabel->setText(QString::number(p_editInfo.m_charWithoutSpacesCount)); - m_charWithSpacesEditLabel->setText(QString::number(p_editInfo.m_charWithSpacesCount)); - } -} - -void VWordCountPanel::clear() -{ - m_wordLabel->clear(); - m_charWithoutSpacesLabel->clear(); - m_charWithSpacesLabel->clear(); - - m_wordEditLabel->clear(); - m_charWithoutSpacesEditLabel->clear(); - m_charWithSpacesEditLabel->clear(); -} - - -VTabIndicator::VTabIndicator(QWidget *p_parent) - : QWidget(p_parent), - m_editTab(NULL) -{ - setupUI(); -} - -void VTabIndicator::registerNavigationTarget() -{ - g_mainWin->getCaptain()->registerNavigationTarget(m_tagPanel); -} - -void VTabIndicator::setupUI() -{ - m_tagPanel = new VTagPanel(this); - - m_docTypeLabel = new QLabel(this); - m_docTypeLabel->setToolTip(tr("The type of the file")); - m_docTypeLabel->setProperty("ColorGreyLabel", true); - - m_readonlyLabel = new QLabel(tr("ReadOnly"), this); - m_readonlyLabel->setToolTip(tr("This file is read-only")); - m_readonlyLabel->setProperty("ColorRedLabel", true); - - m_externalLabel = new QLabel(tr("Standalone"), this); - m_externalLabel->setToolTip(tr("This file is not managed by any notebook or folder")); - m_externalLabel->setProperty("ColorTealLabel", true); - - m_systemLabel = new QLabel(tr("System"), this); - m_systemLabel->setToolTip(tr("This file is a system file")); - m_systemLabel->setProperty("ColorGreenLabel", true); - - m_cursorLabel = new QLabel(this); - m_cursorLabel->setProperty("TabIndicatorLabel", true); - - m_wordCountPanel = new VWordCountPanel(this); - m_wordCountPanel->setMinimumWidth(300 * VUtils::calculateScaleFactor()); - - m_wordCountBtn = new VButtonWithWidget(tr("[W]"), m_wordCountPanel, this); - m_wordCountBtn->setToolTip(tr("Word Count Information")); - m_wordCountBtn->setProperty("StatusBtn", true); - m_wordCountBtn->setFocusPolicy(Qt::NoFocus); - connect(m_wordCountBtn, &VButtonWithWidget::popupWidgetAboutToShow, - this, &VTabIndicator::updateWordCountInfo); - - QHBoxLayout *mainLayout = new QHBoxLayout(this); - mainLayout->addWidget(m_tagPanel); - mainLayout->addWidget(m_cursorLabel); - mainLayout->addWidget(m_wordCountBtn); - mainLayout->addWidget(m_externalLabel); - mainLayout->addWidget(m_systemLabel); - mainLayout->addWidget(m_readonlyLabel); - mainLayout->addWidget(m_docTypeLabel); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -static QString docTypeToString(DocType p_type) -{ - QString str; - - switch (p_type) { - case DocType::Html: - str = "HTML"; - break; - - case DocType::Markdown: - str = "Markdown"; - break; - - case DocType::List: - str = "List"; - break; - - case DocType::Container: - str = "Container"; - break; - - default: - str = "Unknown"; - break; - } - - return str; -} - -void VTabIndicator::update(const VEditTabInfo &p_info) -{ - VFile *file = NULL; - DocType docType = DocType::Html; - bool readonly = false; - bool external = false; - bool system = false; - QString cursorStr; - - m_editTab = p_info.m_editTab; - - if (m_editTab) - { - file = m_editTab->getFile(); - docType = file->getDocType(); - readonly = !file->isModifiable(); - external = file->getType() == FileType::Orphan; - system = external && dynamic_cast(file)->isSystemFile(); - - if (m_editTab->isEditMode()) { - int line = p_info.m_cursorBlockNumber + 1; - int col = p_info.m_cursorPositionInBlock; - if (col < 0) { - col = 0; - } - - int lineCount = p_info.m_blockCount < 1 ? 1 : p_info.m_blockCount; - - QString cursorText = tr("Line: %1 - %2(%3%) Col: %4") - .arg(line) - .arg(lineCount) - .arg((int)(line * 1.0 / lineCount * 100), 2) - .arg(col, -3); - m_cursorLabel->setText(cursorText); - m_cursorLabel->show(); - } else { - m_cursorLabel->hide(); - } - } - - m_tagPanel->setVisible(!external); - if (external) { - m_tagPanel->updateTags(NULL); - } else { - m_tagPanel->updateTags(dynamic_cast(file)); - } - - updateWordCountBtn(p_info); - - if (p_info.m_wordCountInfo.m_mode == VWordCountInfo::Read) { - m_wordCountPanel->updateReadInfo(p_info.m_wordCountInfo); - } - - m_docTypeLabel->setText(docTypeToString(docType)); - m_readonlyLabel->setVisible(readonly); - m_externalLabel->setVisible(external); - m_systemLabel->setVisible(system); -} - -void VTabIndicator::updateWordCountInfo(QWidget *p_widget) -{ - VWordCountPanel *wcp = dynamic_cast(p_widget); - - if (!m_editTab) { - wcp->clear(); - return; - } - - wcp->updateReadInfo(m_editTab->fetchWordCountInfo(false)); - wcp->updateEditInfo(m_editTab->fetchWordCountInfo(true)); -} - -void VTabIndicator::updateWordCountBtn(const VEditTabInfo &p_info) -{ - const VEditTab *editTab = p_info.m_editTab; - if (!editTab) { - m_wordCountBtn->setText(tr("[W]")); - return; - } - - const VWordCountInfo &wci = p_info.m_wordCountInfo; - bool editMode = editTab->isEditMode(); - int wc = -1; - bool needUpdate = false; - switch (wci.m_mode) { - case VWordCountInfo::Read: - if (!editMode) { - wc = wci.m_wordCount; - needUpdate = true; - } - - break; - - case VWordCountInfo::Edit: - if (editMode) { - wc = wci.m_charWithSpacesCount; - needUpdate = true; - } - - break; - - case VWordCountInfo::Invalid: - needUpdate = true; - break; - - default: - break; - } - - if (needUpdate) { - QString text = tr("[%1]%2").arg(editMode ? tr("C") : tr("W")) - .arg(wc > -1 ? QString::number(wc) : ""); - m_wordCountBtn->setText(text); - } -} diff --git a/src/vtabindicator.h b/src/vtabindicator.h deleted file mode 100644 index 1c8ac381..00000000 --- a/src/vtabindicator.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef VTABINDICATOR_H -#define VTABINDICATOR_H - -#include -#include "vedittabinfo.h" - -class QLabel; -class VButtonWithWidget; -class VEditTab; -class VWordCountPanel; -class QGroupBox; -class VTagPanel; - -class VWordCountPanel : public QWidget -{ - Q_OBJECT -public: - VWordCountPanel(QWidget *p_parent = nullptr); - - void updateReadInfo(const VWordCountInfo &p_readInfo); - - void updateEditInfo(const VWordCountInfo &p_editInfo); - - void clear(); - -private: - QLabel *m_wordLabel; - QLabel *m_charWithoutSpacesLabel; - QLabel *m_charWithSpacesLabel; - - QLabel *m_wordEditLabel; - QLabel *m_charWithoutSpacesEditLabel; - QLabel *m_charWithSpacesEditLabel; - - QGroupBox *m_readBox; - QGroupBox *m_editBox; -}; - - -class VTabIndicator : public QWidget -{ - Q_OBJECT - -public: - explicit VTabIndicator(QWidget *p_parent = 0); - - // Update indicator. - void update(const VEditTabInfo &p_info); - - void registerNavigationTarget(); - -private slots: - void updateWordCountInfo(QWidget *p_widget); - -private: - void setupUI(); - - void updateWordCountBtn(const VEditTabInfo &p_info); - - // Tag panel. - VTagPanel *m_tagPanel; - - // Indicate the doc type. - QLabel *m_docTypeLabel; - - // Indicate the readonly property. - QLabel *m_readonlyLabel; - - // Indicate whether it is a normal note or an external file. - QLabel *m_externalLabel; - - // Indicate whether it is a system file. - QLabel *m_systemLabel; - - // Indicate the position of current cursor. - QLabel *m_cursorLabel; - - // Indicate the word count. - VButtonWithWidget *m_wordCountBtn; - - VEditTab *m_editTab; - - VWordCountPanel *m_wordCountPanel; -}; - -#endif // VTABINDICATOR_H diff --git a/src/vtable.cpp b/src/vtable.cpp deleted file mode 100644 index 2704e841..00000000 --- a/src/vtable.cpp +++ /dev/null @@ -1,713 +0,0 @@ -#include "vtable.h" - -#include -#include -#include - -#include "veditor.h" - -const QString VTable::c_defaultDelimiter = "---"; - -const QChar VTable::c_borderChar = '|'; - -enum { HeaderRowIndex = 0, DelimiterRowIndex = 1 }; - -VTable::VTable(VEditor *p_editor, const VTableBlock &p_block) - : m_editor(p_editor), - m_exist(true), - m_spaceWidth(10), - m_minusWidth(10), - m_colonWidth(10), - m_defaultDelimiterWidth(10) -{ - parseFromTableBlock(p_block); -} - -VTable::VTable(VEditor *p_editor, int p_nrBodyRow, int p_nrCol, VTable::Alignment p_alignment) - : m_editor(p_editor), - m_exist(false), - m_spaceWidth(10), - m_minusWidth(10), - m_colonWidth(10), - m_defaultDelimiterWidth(10) -{ - Q_ASSERT(p_nrBodyRow >= 0 && p_nrCol > 0); - m_rows.resize(p_nrBodyRow + 2); - - // PreText for each row. - QString preText; - QTextCursor cursor = m_editor->textCursorW(); - Q_ASSERT(cursor.atBlockEnd()); - if (!cursor.atBlockStart()) { - preText = cursor.block().text(); - } - - QString core(c_defaultDelimiter); - switch (p_alignment) { - case Alignment::Left: - core[0] = ':'; - break; - - case Alignment::Center: - core[0] = ':'; - core[core.size() - 1] = ':'; - break; - - case Alignment::Right: - core[core.size() - 1] = ':'; - break; - - default: - break; - } - const QString delimiterCell = generateFormattedText(core, 0); - const QString contentCell = generateFormattedText(QString(c_defaultDelimiter.size(), ' '), 0); - - for (int rowIdx = 0; rowIdx < m_rows.size(); ++rowIdx) { - auto & row = m_rows[rowIdx]; - row.m_preText = preText; - row.m_cells.resize(p_nrCol); - - const QString &content = isDelimiterRow(rowIdx) ? delimiterCell : contentCell; - for (auto & cell : row.m_cells) { - cell.m_text = content; - } - } -} - -bool VTable::isValid() const -{ - return header() && header()->isValid() - && delimiter() && delimiter()->isValid(); -} - -void VTable::parseFromTableBlock(const VTableBlock &p_block) -{ - clear(); - - QTextDocument *doc = m_editor->documentW(); - - QTextBlock block = doc->findBlock(p_block.m_startPos); - if (!block.isValid()) { - return; - } - - int lastBlockNumber = doc->findBlock(p_block.m_endPos - 1).blockNumber(); - if (lastBlockNumber == -1) { - return; - } - - const QVector &borders = p_block.m_borders; - if (borders.isEmpty()) { - return; - } - - int numRows = lastBlockNumber - block.blockNumber() + 1; - if (numRows <= DelimiterRowIndex) { - return; - } - - calculateBasicWidths(block, borders[0]); - - int borderIdx = 0; - m_rows.reserve(numRows); - for (int i = 0; i < numRows; ++i) { - m_rows.append(Row()); - if (!parseOneRow(block, borders, borderIdx, m_rows.last())) { - clear(); - return; - } - - block = block.next(); - } -} - -bool VTable::parseOneRow(const QTextBlock &p_block, - const QVector &p_borders, - int &p_borderIdx, - Row &p_row) const -{ - if (!p_block.isValid() || p_borderIdx >= p_borders.size()) { - return false; - } - - p_row.m_block = p_block; - - QString text = p_block.text(); - int startPos = p_block.position(); - int endPos = startPos + text.length(); - - if (p_borders[p_borderIdx] < startPos - || p_borders[p_borderIdx] >= endPos) { - return false; - } - - // Get pre text. - int firstCellOffset = p_borders[p_borderIdx] - startPos; - if (text[firstCellOffset] != c_borderChar) { - return false; - } - p_row.m_preText = text.left(firstCellOffset); - - for (; p_borderIdx < p_borders.size(); ++p_borderIdx) { - int border = p_borders[p_borderIdx]; - if (border >= endPos) { - break; - } - - int offset = border - startPos; - if (text[offset] != c_borderChar) { - return false; - } - - int nextIdx = p_borderIdx + 1; - if (nextIdx >= p_borders.size() || p_borders[nextIdx] >= endPos) { - // The last border of this row. - ++p_borderIdx; - break; - } - - int nextOffset = p_borders[nextIdx] - startPos; - if (text[nextOffset] != c_borderChar) { - return false; - } - - // Got one cell. - Cell cell; - cell.m_offset = offset; - cell.m_length = nextOffset - offset; - cell.m_text = text.mid(cell.m_offset, cell.m_length); - - p_row.m_cells.append(cell); - } - - return true; -} - -void VTable::clear() -{ - m_rows.clear(); - m_spaceWidth = 0; - m_minusWidth = 0; - m_colonWidth = 0; - m_defaultDelimiterWidth = 0; -} - -void VTable::format() -{ - if (!isValid()) { - return; - } - - QTextCursor cursor = m_editor->textCursorW(); - int curRowIdx = cursor.blockNumber() - m_rows[0].m_block.blockNumber(); - int curPib = -1; - if (curRowIdx < 0 || curRowIdx >= m_rows.size()) { - curRowIdx = -1; - } else { - curPib = cursor.positionInBlock(); - } - - int nrCols = calculateColumnCount(); - pruneColumns(nrCols); - - for (int i = 0; i < nrCols; ++i) { - formatOneColumn(i, curRowIdx, curPib); - } -} - -int VTable::calculateColumnCount() const -{ - // We use the width of the header as the width of the table. - // With this, we could add or remove one column by just changing the header row. - return header()->m_cells.size(); -} - -VTable::Row *VTable::header() const -{ - if (m_rows.size() <= HeaderRowIndex) { - return NULL; - } - - return const_cast(&m_rows[HeaderRowIndex]); -} - -VTable::Row *VTable::delimiter() const -{ - if (m_rows.size() <= DelimiterRowIndex) { - return NULL; - } - - return const_cast(&m_rows[DelimiterRowIndex]); -} - -void VTable::formatOneColumn(int p_idx, int p_cursorRowIdx, int p_cursorPib) -{ - QVector cells; - int targetWidth = 0; - fetchCellInfoOfColumn(p_idx, cells, targetWidth); - - // Get the alignment of this column. - const Alignment align = getColumnAlignment(p_idx); - - // Calculate the formatted text of each cell. - for (int rowIdx = 0; rowIdx < cells.size(); ++rowIdx) { - auto & info = cells[rowIdx]; - auto & row = m_rows[rowIdx]; - if (row.m_cells.size() <= p_idx) { - row.m_cells.resize(p_idx + 1); - } - auto & cell = row.m_cells[p_idx]; - Q_ASSERT(cell.m_formattedText.isEmpty()); - Q_ASSERT(cell.m_cursorCoreOffset == -1); - - // Record the cursor position. - if (rowIdx == p_cursorRowIdx) { - if (cell.m_offset <= p_cursorPib && cell.m_offset + cell.m_length > p_cursorPib) { - // Cursor in this cell. - int offset = p_cursorPib - cell.m_offset; - offset = offset - info.m_coreOffset; - if (offset > info.m_coreLength) { - offset = info.m_coreLength; - } else if (offset < 0) { - offset = 0; - } - - cell.m_cursorCoreOffset = offset; - } - } - - if (isDelimiterRow(rowIdx)) { - if (!isDelimiterCellWellFormatted(cell, info, targetWidth)) { - QString core; - // Round to 1 when above 0.5 approximately. - int delta = m_minusWidth / 2; - switch (align) { - case Alignment::None: - core = QString((targetWidth + delta) / m_minusWidth, '-'); - break; - - case Alignment::Left: - core = ":"; - core += QString((targetWidth - m_colonWidth + delta) / m_minusWidth, '-'); - break; - - case Alignment::Center: - core = ":"; - core += QString((targetWidth - 2 * m_colonWidth + delta) / m_minusWidth, '-'); - core += ":"; - break; - - case Alignment::Right: - core = QString((targetWidth - m_colonWidth + delta) / m_minusWidth, '-'); - core += ":"; - break; - - default: - Q_ASSERT(false); - break; - } - - cell.m_formattedText = generateFormattedText(core, 0); - } - } else { - Alignment fakeAlign = align; - if (fakeAlign == Alignment::None) { - // For Alignment::None, we make the header align center while - // content cells align left. - if (isHeaderRow(rowIdx)) { - fakeAlign = Alignment::Center; - } else { - fakeAlign = Alignment::Left; - } - } - - if (!isCellWellFormatted(row, cell, info, targetWidth, fakeAlign)) { - QString core = cell.m_text.mid(info.m_coreOffset, info.m_coreLength); - int nr = (targetWidth - info.m_coreWidth + m_spaceWidth / 2) / m_spaceWidth; - cell.m_formattedText = generateFormattedText(core, nr, fakeAlign); - - // For cells crossing lines and having spaces at the end of one line, - // Qt will collapse those spaces, which make it not well formatted. - if (cell.m_text == cell.m_formattedText) { - cell.m_formattedText.clear(); - } - } - } - } -} - -void VTable::fetchCellInfoOfColumn(int p_idx, - QVector &p_cellsInfo, - int &p_targetWidth) const -{ - p_targetWidth = m_defaultDelimiterWidth; - p_cellsInfo.resize(m_rows.size()); - - // Fetch the trimmed core content and its width. - for (int i = 0; i < m_rows.size(); ++i) { - auto & row = m_rows[i]; - auto & info = p_cellsInfo[i]; - - if (row.m_cells.size() <= p_idx) { - // Need to add a new cell later. - continue; - } - - // Get the info of this cell. - const auto & cell = row.m_cells[p_idx]; - int first = 1, last = cell.m_length - 1; - for (; first <= last; ++first) { - if (cell.m_text[first] != ' ') { - // Found the core content. - info.m_coreOffset = first; - break; - } - } - - if (first > last) { - // Empty cell. - continue; - } - - for (; last >= first; --last) { - if (cell.m_text[last] != ' ') { - // Found the last of core content. - info.m_coreLength = last - first + 1; - break; - } - } - - // Calculate the core width. - info.m_coreWidth = calculateTextWidth(row.m_block, - cell.m_offset + info.m_coreOffset, - info.m_coreLength); - // Delimiter row's width should not be considered. - if (info.m_coreWidth > p_targetWidth && !isDelimiterRow(i)) { - p_targetWidth = info.m_coreWidth; - } - } -} - -void VTable::calculateBasicWidths(const QTextBlock &p_block, int p_borderPos) -{ - QFont font; - - int pib = p_borderPos - p_block.position(); - QVector fmts = p_block.layout()->formats(); - for (const auto & fmt : fmts) { - if (fmt.start <= pib && fmt.start + fmt.length > pib) { - // Hit. - if (!fmt.format.fontFamily().isEmpty()) { - font = fmt.format.font(); - break; - } - } - } - - QFontMetrics fm(font); - m_spaceWidth = fm.width(' '); - m_minusWidth = fm.width('-'); - m_colonWidth = fm.width(':'); - m_defaultDelimiterWidth = fm.width(c_defaultDelimiter); -} - -int VTable::calculateTextWidth(const QTextBlock &p_block, int p_pib, int p_length) const -{ - // The block may cross multiple lines. - int width = 0; - QTextLayout *layout = p_block.layout(); - QTextLine line = layout->lineForTextPosition(p_pib); - while (line.isValid()) { - int lineEnd = line.textStart() + line.textLength(); - if (lineEnd >= p_pib + p_length) { - // The last line. - width += line.cursorToX(p_pib + p_length) - line.cursorToX(p_pib); - break; - } else { - // Cross lines. - width += line.cursorToX(lineEnd) - line.cursorToX(p_pib); - - // Move to next line. - p_length = p_length - (lineEnd - p_pib); - p_pib = lineEnd; - line = layout->lineForTextPosition(p_pib + 1); - } - } - - return width > 0 ? width : -1; -} - -bool VTable::isHeaderRow(int p_idx) const -{ - return p_idx == HeaderRowIndex; -} - -bool VTable::isDelimiterRow(int p_idx) const -{ - return p_idx == DelimiterRowIndex; -} - -QString VTable::generateFormattedText(const QString &p_core, - int p_nrSpaces, - Alignment p_align) const -{ - Q_ASSERT(p_align != Alignment::None); - - // Align left. - int leftSpaces = 0; - int rightSpaces = p_nrSpaces; - - if (p_align == Alignment::Center) { - leftSpaces = p_nrSpaces / 2; - rightSpaces = p_nrSpaces - leftSpaces; - } else if (p_align == Alignment::Right) { - leftSpaces = p_nrSpaces; - rightSpaces = 0; - } - - return QString("%1 %2%3%4 ").arg(c_borderChar, - QString(leftSpaces, ' '), - p_core, - QString(rightSpaces, ' ')); -} - -VTable::Alignment VTable::getColumnAlignment(int p_idx) const -{ - Row *row = delimiter(); - if (row->m_cells.size() <= p_idx) { - return Alignment::None; - } - - QString core = row->m_cells[p_idx].m_text.mid(1).trimmed(); - Q_ASSERT(!core.isEmpty()); - bool leftColon = core[0] == ':'; - bool rightColon = core[core.size() - 1] == ':'; - if (leftColon) { - if (rightColon) { - return Alignment::Center; - } else { - return Alignment::Left; - } - } else { - if (rightColon) { - return Alignment::Right; - } else { - return Alignment::None; - } - } -} - -static inline bool equalWidth(int p_a, int p_b, int p_margin = 5) -{ - return qAbs(p_a - p_b) < p_margin; -} - -bool VTable::isDelimiterCellWellFormatted(const Cell &p_cell, - const CellInfo &p_info, - int p_targetWidth) const -{ - // We could use core width here for delimiter cell. - if (!equalWidth(p_info.m_coreWidth, p_targetWidth, m_minusWidth)) { - return false; - } - - const QString &text = p_cell.m_text; - if (text.size() < 4) { - return false; - } - - if (text[1] != ' ' || text[text.size() - 1] != ' ') { - return false; - } - - if (text[2] == ' ' || text[text.size() - 2] == ' ') { - return false; - } - - return true; -} - -bool VTable::isCellWellFormatted(const Row &p_row, - const Cell &p_cell, - const CellInfo &p_info, - int p_targetWidth, - Alignment p_align) const -{ - Q_ASSERT(p_align != Alignment::None); - - const QString &text = p_cell.m_text; - if (text.size() < 4) { - return false; - } - - if (text[1] != ' ' || text[text.size() - 1] != ' ') { - return false; - } - - // Skip alignment check of empty cell. - if (p_info.m_coreOffset > 0) { - int leftSpaces = p_info.m_coreOffset - 2; - int rightSpaces = text.size() - p_info.m_coreOffset - p_info.m_coreLength - 1; - switch (p_align) { - case Alignment::Left: - if (leftSpaces > 0) { - return false; - } - - break; - - case Alignment::Center: - if (qAbs(leftSpaces - rightSpaces) > 1) { - return false; - } - - break; - - case Alignment::Right: - if (rightSpaces > 0) { - return false; - } - - break; - - default: - Q_ASSERT(false); - break; - } - } - - // Calculate the width of the text without two spaces around. - int cellWidth = calculateTextWidth(p_row.m_block, - p_cell.m_offset + 2, - p_cell.m_length - 3); - if (!equalWidth(cellWidth, p_targetWidth, m_spaceWidth)) { - return false; - } - - return true; -} - -void VTable::write() -{ - if (m_exist) { - writeExist(); - } else { - writeNonExist(); - } -} - -void VTable::writeExist() -{ - bool changed = false; - QTextCursor cursor = m_editor->textCursorW(); - int cursorBlock = -1, cursorPib = -1; - - // Write the table row by row. - for (auto & row : m_rows) { - bool needChange = false; - for (const auto & cell : row.m_cells) { - if (!cell.m_formattedText.isEmpty() || cell.m_deleted) { - needChange = true; - break; - } - } - - if (!needChange) { - continue; - } - - if (!changed) { - changed = true; - cursorBlock = cursor.blockNumber(); - cursorPib = cursor.positionInBlock(); - - cursor.beginEditBlock(); - } - - // Construct the block text. - QString newBlockText(row.m_preText); - for (auto & cell : row.m_cells) { - if (cell.m_deleted) { - continue; - } - - int pos = newBlockText.size(); - if (cell.m_formattedText.isEmpty()) { - newBlockText += cell.m_text; - } else { - newBlockText += cell.m_formattedText; - } - - if (cell.m_cursorCoreOffset > -1) { - // Cursor in this cell. - cursorPib = pos + cell.m_cursorCoreOffset + 2; - if (cursorPib >= newBlockText.size()) { - cursorPib = newBlockText.size() - 1; - } - } - } - - newBlockText += c_borderChar; - - // Replace the whole block. - cursor.setPosition(row.m_block.position()); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - cursor.insertText(newBlockText); - } - - if (changed) { - qDebug() << "write formatted table with cursor block" << cursorBlock; - cursor.endEditBlock(); - m_editor->setTextCursorW(cursor); - - // Restore the cursor. - QTextBlock block = m_editor->documentW()->findBlockByNumber(cursorBlock); - if (block.isValid()) { - int pos = block.position() + cursorPib; - QTextCursor cur = m_editor->textCursorW(); - cur.setPosition(pos); - m_editor->setTextCursorW(cur); - } - } -} - -void VTable::writeNonExist() -{ - // Generate the text of the whole table. - QString tableText; - for (int rowIdx = 0; rowIdx < m_rows.size(); ++rowIdx) { - const auto & row = m_rows[rowIdx]; - tableText += row.m_preText; - for (auto & cell : row.m_cells) { - if (cell.m_deleted) { - continue; - } - - tableText += cell.m_text; - } - - tableText += c_borderChar; - - if (rowIdx < m_rows.size() - 1) { - tableText += '\n'; - } - } - - QTextCursor cursor = m_editor->textCursorW(); - int pos = cursor.position() + 2; - cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - cursor.insertText(tableText); - cursor.setPosition(pos); - m_editor->setTextCursorW(cursor); -} - -void VTable::pruneColumns(int p_nrCols) -{ - for (auto & row : m_rows) { - for (int i = p_nrCols; i < row.m_cells.size(); ++i) { - row.m_cells[i].m_deleted = true; - } - } -} diff --git a/src/vtable.h b/src/vtable.h deleted file mode 100644 index c32bc54c..00000000 --- a/src/vtable.h +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef VTABLE_H -#define VTABLE_H - -#include - -#include "markdownhighlighterdata.h" - -class VEditor; - -class VTable -{ -public: - enum Alignment { - None, - Left, - Center, - Right - }; - - VTable(VEditor *p_editor, const VTableBlock &p_block); - - VTable(VEditor *p_editor, int p_nrBodyRow, int p_nrCol, VTable::Alignment p_alignment); - - bool isValid() const; - - void format(); - - // Write a formatted table. - void write(); - -private: - struct Cell - { - Cell() - : m_offset(-1), - m_length(0), - m_cursorCoreOffset(-1), - m_deleted(false) - { - } - - void clear() - { - m_offset = -1; - m_length = 0; - m_text.clear(); - m_formattedText.clear(); - m_cursorCoreOffset = -1; - m_deleted = false; - } - - // Start offset within block, including the starting border |. - int m_offset; - - // Length of this cell, till next border |. - int m_length; - - // Text like "| vnote ". - QString m_text; - - // Formatted text, such as "| vnote ". - // It is empty if it does not need formatted. - QString m_formattedText; - - // If cursor is within this cell, this will not be -1. - int m_cursorCoreOffset; - - // Whether this cell need to be deleted. - bool m_deleted; - }; - - struct Row - { - Row() - { - } - - bool isValid() const - { - return !m_cells.isEmpty(); - } - - void clear() - { - m_block = QTextBlock(); - m_preText.clear(); - m_cells.clear(); - } - - QString toString() const - { - QString cells; - for (auto & cell : m_cells) { - cells += QString(" (%1, %2 [%3])").arg(cell.m_offset) - .arg(cell.m_length) - .arg(cell.m_text); - } - - return QString("row %1 %2").arg(m_block.blockNumber()).arg(cells); - } - - QTextBlock m_block; - // Text before table row. - QString m_preText; - QVector m_cells; - }; - - // Used to hold info about a cell when formatting a column. - struct CellInfo - { - CellInfo() - : m_coreOffset(0), - m_coreLength(0), - m_coreWidth(0) - { - } - - // The offset of the core content within the cell. - // Will be 0 if it is an empty cell. - int m_coreOffset; - - // The length of the core content. - // Will be 0 if it is an empty cell. - int m_coreLength; - - // Pixel width of the core content. - int m_coreWidth; - }; - - void parseFromTableBlock(const VTableBlock &p_block); - - void clear(); - - bool parseOneRow(const QTextBlock &p_block, - const QVector &p_borders, - int &p_borderIdx, - Row &p_row) const; - - int calculateColumnCount() const; - - // When called with i, the (i - 1) column must have been formatted. - void formatOneColumn(int p_idx, int p_cursorRowIdx, int p_cursorPib); - - void fetchCellInfoOfColumn(int p_idx, - QVector &p_cellsInfo, - int &p_targetWidth) const; - - void calculateBasicWidths(const QTextBlock &p_block, int p_borderPos); - - int calculateTextWidth(const QTextBlock &p_block, int p_pib, int p_length) const; - - bool isHeaderRow(int p_idx) const; - - bool isDelimiterRow(int p_idx) const; - - // @p_nrSpaces: number of spaces to fill core content. - QString generateFormattedText(const QString &p_core, - int p_nrSpaces = 0, - Alignment p_align = Alignment::Left) const; - - VTable::Alignment getColumnAlignment(int p_idx) const; - - bool isDelimiterCellWellFormatted(const Cell &p_cell, - const CellInfo &p_info, - int p_targetWidth) const; - - bool isCellWellFormatted(const Row &p_row, - const Cell &p_cell, - const CellInfo &p_info, - int p_targetWidth, - Alignment p_align) const; - - void writeExist(); - - void writeNonExist(); - - // Prune unwanted columns beyond the header row. - void pruneColumns(int p_nrCols); - - VTable::Row *header() const; - - VTable::Row *delimiter() const; - - VEditor *m_editor; - - // Whether this table exist already. - bool m_exist; - - // Header, delimiter, and body. - QVector m_rows; - - int m_spaceWidth; - int m_minusWidth; - int m_colonWidth; - int m_defaultDelimiterWidth; - - static const QString c_defaultDelimiter; - - static const QChar c_borderChar; -}; - -#endif // VTABLE_H diff --git a/src/vtablehelper.cpp b/src/vtablehelper.cpp deleted file mode 100644 index 0b104a7b..00000000 --- a/src/vtablehelper.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "vtablehelper.h" - -#include - -#include "veditor.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VTableHelper::VTableHelper(VEditor *p_editor, QObject *p_parent) - : QObject(p_parent), - m_editor(p_editor) -{ - m_timer = new QTimer(this); - m_timer->setSingleShot(true); - m_timer->setInterval(g_config->getTableFormatInterval()); - connect(m_timer, &QTimer::timeout, - this, &VTableHelper::formatTables); -} - -void VTableHelper::updateTableBlocks(const QVector &p_blocks) -{ - m_timer->stop(); - - if (m_editor->isReadOnlyW() || - !m_editor->isModified() || - !g_config->getEnableSmartTable()) { - return; - } - - int idx = currentCursorTableBlock(p_blocks); - if (idx == -1) { - return; - } - - m_block = p_blocks[idx]; - m_timer->start(); -} - -int VTableHelper::currentCursorTableBlock(const QVector &p_blocks) const -{ - // Binary search. - int curPos = m_editor->textCursorW().position(); - - int first = 0, last = p_blocks.size() - 1; - while (first <= last) { - int mid = (first + last) / 2; - const VTableBlock &block = p_blocks[mid]; - if (block.m_startPos <= curPos && block.m_endPos >= curPos) { - return mid; - } - - if (block.m_startPos > curPos) { - last = mid - 1; - } else { - first = mid + 1; - } - } - - return -1; -} - -void VTableHelper::insertTable(int p_nrRow, int p_nrCol, VTable::Alignment p_alignment) -{ - VTable table(m_editor, p_nrRow, p_nrCol, p_alignment); - if (!table.isValid()) { - return; - } - - table.write(); -} - -void VTableHelper::formatTables() -{ - if (!m_block.isValid()) { - return; - } - - VTable table(m_editor, m_block); - if (!table.isValid()) { - return; - } - - table.format(); - - table.write(); -} diff --git a/src/vtablehelper.h b/src/vtablehelper.h deleted file mode 100644 index 3e3e3959..00000000 --- a/src/vtablehelper.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef VTABLEHELPER_H -#define VTABLEHELPER_H - -#include -#include - -#include "markdownhighlighterdata.h" -#include "vtable.h" - -class VEditor; - -class VTableHelper : public QObject -{ - Q_OBJECT -public: - explicit VTableHelper(VEditor *p_editor, QObject *p_parent = nullptr); - - // Insert table right at current cursor. - void insertTable(int p_nrRow, int p_nrCol, VTable::Alignment p_alignment); - -public slots: - void updateTableBlocks(const QVector &p_blocks); - -private: - // Return the block index which contains the cursor. - int currentCursorTableBlock(const QVector &p_blocks) const; - - void formatTables(); - - VEditor *m_editor; - - QTimer *m_timer; - - VTableBlock m_block; -}; - -#endif // VTABLEHELPER_H diff --git a/src/vtableofcontent.cpp b/src/vtableofcontent.cpp deleted file mode 100644 index 396b54ff..00000000 --- a/src/vtableofcontent.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "vtableofcontent.h" -#include "vconstants.h" - -#include -#include - - -VTableOfContent::VTableOfContent() - : m_file(NULL), m_type(VTableOfContentType::Anchor) -{ -} - -VTableOfContent::VTableOfContent(const VFile *p_file) - : m_file(p_file), m_type(VTableOfContentType::Anchor) -{ -} - -void VTableOfContent::update(const VFile *p_file, - const QVector &p_table, - VTableOfContentType p_type) -{ - m_file = p_file; - m_table = p_table; - m_type = p_type; -} - -static bool parseTocUl(QXmlStreamReader &p_xml, - QVector &p_table, - int p_level); - -static bool parseTocLi(QXmlStreamReader &p_xml, - QVector &p_table, - int p_level) -{ - Q_ASSERT(p_xml.isStartElement() && p_xml.name() == "li"); - - if (p_xml.readNextStartElement()) { - if (p_xml.name() == "a") { - QString anchor = p_xml.attributes().value("href").toString().mid(1); - QString name; - // Read till . - int nrStart = 1; - while (p_xml.readNext()) { - if (p_xml.tokenString() == "Characters") { - name += p_xml.text().toString(); - } else if (p_xml.isEndElement()) { - --nrStart; - if (nrStart < 0) { - qWarning() << "end elements more than start elements in " << anchor << p_xml.name(); - return false; - } - - if (p_xml.name() == "a") { - break; - } - } else if (p_xml.isStartElement()) { - ++nrStart; - } - } - - if (p_xml.hasError()) { - // Error - qWarning() << "fail to parse an entire element" << anchor << name; - return false; - } - - VTableOfContentItem header(name, p_level, anchor, p_table.size()); - p_table.append(header); - } else if (p_xml.name() == "ul") { - // Such as header 3 under header 1 directly - VTableOfContentItem header(c_emptyHeaderName, p_level, "", p_table.size()); - p_table.append(header); - parseTocUl(p_xml, p_table, p_level + 1); - } else { - qWarning() << "TOC HTML
  • should contain or
      " << p_xml.name(); - return false; - } - } - - while (p_xml.readNext()) { - if (p_xml.isEndElement()) { - if (p_xml.name() == "li") { - return true; - } - - continue; - } - - if (p_xml.name() == "ul") { - // Nested unordered list - if (!parseTocUl(p_xml, p_table, p_level + 1)) { - return false; - } - } else { - return false; - } - } - - return true; -} - -static bool parseTocUl(QXmlStreamReader &p_xml, - QVector &p_table, - int p_level) -{ - bool ret = true; - Q_ASSERT(p_xml.isStartElement() && p_xml.name() == "ul"); - - while (p_xml.readNextStartElement()) { - if (p_xml.name() == "li") { - if (!parseTocLi(p_xml, p_table, p_level)) { - ret = false; - break; - } - } else { - qWarning() << "TOC HTML
        should contain
      • " << p_xml.name(); - ret = false; - break; - } - } - - return ret; -} - -bool VTableOfContent::parseTableFromHtml(const QString &p_html) -{ - bool ret = true; - m_table.clear(); - - if (!p_html.isEmpty()) { - QXmlStreamReader xml(p_html); - if (xml.readNextStartElement()) { - if (xml.name() == "ul") { - ret = parseTocUl(xml, m_table, 1); - } else { - qWarning() << "TOC HTML does not start with
          " << p_html; - ret = false; - } - } - - if (xml.hasError()) { - qWarning() << "fail to parse TOC in HTML" << p_html; - ret = false; - } - } - - return ret; -} - -int VTableOfContent::indexOfItemByAnchor(const QString &p_anchor) const -{ - if (p_anchor.isEmpty() - || isEmpty() - || m_type != VTableOfContentType::Anchor) { - return -1; - } - - for (int i = 0; i < m_table.size(); ++i) { - if (m_table[i].m_anchor == p_anchor) { - return i; - } - } - - return -1; -} - -int VTableOfContent::indexOfItemByBlockNumber(int p_blockNumber) const -{ - if (p_blockNumber == -1 - || isEmpty() - || m_type != VTableOfContentType::BlockNumber) { - return -1; - } - - for (int i = m_table.size() - 1; i >= 0; --i) { - if (!m_table[i].isEmpty() - && m_table[i].m_blockNumber <= p_blockNumber) { - return i; - } - } - - return -1; -} - -bool VTableOfContent::operator==(const VTableOfContent &p_outline) const -{ - return m_file == p_outline.getFile() - && m_type == p_outline.getType() - && m_table == p_outline.getTable(); -} diff --git a/src/vtableofcontent.h b/src/vtableofcontent.h deleted file mode 100644 index 5f589e75..00000000 --- a/src/vtableofcontent.h +++ /dev/null @@ -1,286 +0,0 @@ -#ifndef VTABLEOFCONTENT_H -#define VTABLEOFCONTENT_H - -#include -#include - -class VFile; - - -struct VHeaderPointer -{ - VHeaderPointer() - : m_file(NULL), m_index(-1) - { - } - - VHeaderPointer(const VFile *p_file, int p_index) - : m_file(p_file), m_index(p_index) - { - } - - bool operator==(const VHeaderPointer &p_header) const - { - return m_file == p_header.m_file - && m_index == p_header.m_index; - } - - void reset() - { - m_index = -1; - } - - void clear() - { - m_file = NULL; - reset(); - } - - void update(const VFile *p_file, int p_index) - { - m_file = p_file; - m_index = p_index; - } - - bool isValid() const - { - return m_index > -1; - } - - QString toString() const - { - return QString("VHeaderPointer file: %1 index: %2") - .arg((long long)m_file) - .arg(m_index); - } - - // The corresponding file. - const VFile *m_file; - - // Index of the header item in VTableOfContent which this instance points to. - int m_index; -}; - - -struct VTableOfContentItem -{ - VTableOfContentItem() - : m_level(1), m_blockNumber(-1), m_index(-1) - { - } - - VTableOfContentItem(const QString &p_name, - int p_level, - const QString &p_anchor, - int p_index) - : m_name(p_name), - m_level(p_level), - m_anchor(p_anchor), - m_blockNumber(-1), - m_index(p_index) - { - } - - VTableOfContentItem(const QString &p_name, - int p_level, - int p_blockNumber, - int p_index) - : m_name(p_name), - m_level(p_level), - m_blockNumber(p_blockNumber), - m_index(p_index) - { - } - - // Whether it is an empty item. - // An empty item points to nothing. - bool isEmpty() const - { - if (m_anchor.isEmpty()) { - return m_blockNumber == -1; - } - - return false; - } - - bool isMatched(const VHeaderPointer &p_header) const - { - return m_index == p_header.m_index; - } - - bool operator==(const VTableOfContentItem &p_item) const - { - return m_name == p_item.m_name - && m_level == p_item.m_level - && m_anchor == p_item.m_anchor - && m_blockNumber == p_item.m_blockNumber - && m_index == p_item.m_index; - } - - // Name of the item to display. - QString m_name; - - // Level of this item, based on 1. - int m_level; - - // Use an anchor to identify the position of this item. - QString m_anchor; - - // Use block number to identify the position of this item. - // -1 to indicate invalid. - int m_blockNumber; - - // Index in VTableOfContent, based on 0. - // -1 for invalid value. - int m_index; -}; - - -enum class VTableOfContentType -{ - Anchor = 0, - BlockNumber -}; - - -class VTableOfContent -{ -public: - VTableOfContent(); - - VTableOfContent(const VFile *p_file); - - void update(const VFile *p_file, - const QVector &p_table, - VTableOfContentType p_type); - - // Parse m_table from html. - bool parseTableFromHtml(const QString &p_html); - - const VFile *getFile() const; - - void setFile(const VFile *p_file); - - VTableOfContentType getType() const; - - void setType(VTableOfContentType p_type); - - void clearTable(); - - const QVector &getTable() const; - - void setTable(const QVector &p_table); - - void clear(); - - // Return the index in @m_table of @p_anchor. - int indexOfItemByAnchor(const QString &p_anchor) const; - - // Return the last index in @m_table which has smaller block number than @p_blockNumber. - int indexOfItemByBlockNumber(int p_blockNumber) const; - - const VTableOfContentItem *getItem(int p_idx) const; - - const VTableOfContentItem *getItem(const VHeaderPointer &p_header) const; - - bool isEmpty() const; - - // Whether @p_header is pointing to this outline. - bool isMatched(const VHeaderPointer &p_header) const; - - bool operator==(const VTableOfContent &p_outline) const; - - QString toString() const; - -private: - // Corresponding file. - const VFile *m_file; - - // Table of content. - QVector m_table; - - // Type of the table of content: by anchor or by block number. - VTableOfContentType m_type; -}; - -inline VTableOfContentType VTableOfContent::getType() const -{ - return m_type; -} - -inline void VTableOfContent::setType(VTableOfContentType p_type) -{ - m_type = p_type; -} - -inline void VTableOfContent::clearTable() -{ - m_table.clear(); -} - -inline const QVector &VTableOfContent::getTable() const -{ - return m_table; -} - -inline void VTableOfContent::setTable(const QVector &p_table) -{ - m_table = p_table; -} - -inline void VTableOfContent::clear() -{ - m_file = NULL; - m_table.clear(); - m_type = VTableOfContentType::Anchor; -} - -inline void VTableOfContent::setFile(const VFile *p_file) -{ - m_file = p_file; -} - -inline const VFile *VTableOfContent::getFile() const -{ - return m_file; -} - -inline const VTableOfContentItem *VTableOfContent::getItem(int p_idx) const -{ - if (!m_file - || p_idx < 0 - || p_idx >= m_table.size()) { - return NULL; - } - - return &m_table[p_idx]; -} - -inline const VTableOfContentItem *VTableOfContent::getItem(const VHeaderPointer &p_header) const -{ - if (p_header.m_file != m_file) { - return NULL; - } - - return getItem(p_header.m_index); -} - -inline bool VTableOfContent::isEmpty() const -{ - return !m_file || m_table.isEmpty(); -} - -inline bool VTableOfContent::isMatched(const VHeaderPointer &p_header) const -{ - return m_file && m_file == p_header.m_file; -} - -inline QString VTableOfContent::toString() const -{ - return QString("VTableOfContent file: %1 isAnchor: %2 tableSize: %3") - .arg((long long)m_file) - .arg(m_type == VTableOfContentType::Anchor) - .arg(m_table.size()); -} - -#endif // VTABLEOFCONTENT_H diff --git a/src/vtagexplorer.cpp b/src/vtagexplorer.cpp deleted file mode 100644 index 9b463e9e..00000000 --- a/src/vtagexplorer.cpp +++ /dev/null @@ -1,555 +0,0 @@ -#include "vtagexplorer.h" - -#include - -#include "utils/viconutils.h" -#include "vmainwindow.h" -#include "vlistwidget.h" -#include "vnotebook.h" -#include "vconfigmanager.h" -#include "vsearch.h" -#include "vnote.h" -#include "vcart.h" -#include "vhistorylist.h" -#include "vnotefile.h" -#include "utils/vutils.h" -#include "vnavigationmode.h" -#include "vcaptain.h" - -extern VMainWindow *g_mainWin; - -extern VConfigManager *g_config; - -extern VNote *g_vnote; - -#define MAX_DISPLAY_LENGTH 10 - -VTagExplorer::VTagExplorer(QWidget *p_parent) - : QWidget(p_parent), - m_uiInitialized(false), - m_notebook(NULL), - m_notebookChanged(true), - m_search(NULL) -{ -} - -void VTagExplorer::setupUI() -{ - if (m_uiInitialized) { - return; - } - - m_uiInitialized = true; - - m_notebookLabel = new QLabel(tr("Tags"), this); - m_notebookLabel->setProperty("TitleLabel", true); - - m_tagList = new VListWidget(this); - m_tagList->setAttribute(Qt::WA_MacShowFocusRect, false); - connect(m_tagList, &QListWidget::itemActivated, - this, [this](const QListWidgetItem *p_item) { - QString tag; - if (p_item) { - tag = p_item->text(); - } - - bool ret = activateTag(tag); - if (ret && !tag.isEmpty() && m_fileList->count() == 0) { - promptToRemoveEmptyTag(tag); - } - }); - - QVBoxLayout *tagLayout = new QVBoxLayout(); - tagLayout->addWidget(m_notebookLabel); - tagLayout->addWidget(m_tagList); - tagLayout->setContentsMargins(0, 0, 0, 0); - - QWidget *tagWidget = new QWidget(this); - tagWidget->setLayout(tagLayout); - - m_tagLabel = new QLabel(tr("Notes"), this); - m_tagLabel->setProperty("TitleLabel", true); - - m_splitBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/split_window.svg"), - "", - this); - m_splitBtn->setToolTip(tr("Split")); - m_splitBtn->setCheckable(true); - m_splitBtn->setProperty("CornerBtn", true); - m_splitBtn->setFocusPolicy(Qt::NoFocus); - connect(m_splitBtn, &QPushButton::clicked, - this, [this](bool p_checked) { - g_config->setEnableSplitTagFileList(p_checked); - setupFileListSplitOut(p_checked); - saveStateAndGeometry(); - }); - - QHBoxLayout *titleLayout = new QHBoxLayout(); - titleLayout->addWidget(m_tagLabel); - titleLayout->addWidget(m_splitBtn); - titleLayout->addStretch(); - titleLayout->setContentsMargins(0, 0, 0, 0); - - m_fileList = new VListWidget(this); - m_fileList->setAttribute(Qt::WA_MacShowFocusRect, false); - m_fileList->setContextMenuPolicy(Qt::CustomContextMenu); - m_fileList->setSelectionMode(QAbstractItemView::ExtendedSelection); - connect(m_fileList, &QListWidget::itemActivated, - this, &VTagExplorer::openFileItem); - connect(m_fileList, &QListWidget::customContextMenuRequested, - this, &VTagExplorer::handleFileListContextMenuRequested); - - QVBoxLayout *fileLayout = new QVBoxLayout(); - fileLayout->addLayout(titleLayout); - fileLayout->addWidget(m_fileList); - fileLayout->setContentsMargins(0, 0, 0, 0); - - QWidget *fileWidget = new QWidget(this); - fileWidget->setLayout(fileLayout); - - m_splitter = new QSplitter(this); - m_splitter->setObjectName("TagExplorerSplitter"); - m_splitter->addWidget(tagWidget); - m_splitter->addWidget(fileWidget); - - setupFileListSplitOut(g_config->getEnableSplitTagFileList()); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_splitter); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); - - restoreStateAndGeometry(); -} - -void VTagExplorer::showEvent(QShowEvent *p_event) -{ - setupUI(); - QWidget::showEvent(p_event); - - updateContent(); -} - -void VTagExplorer::focusInEvent(QFocusEvent *p_event) -{ - setupUI(); - QWidget::focusInEvent(p_event); - m_tagList->setFocus(); -} - -void VTagExplorer::setNotebook(VNotebook *p_notebook) -{ - if (p_notebook == m_notebook) { - return; - } - - setupUI(); - - m_notebook = p_notebook; - m_notebookChanged = true; - - if (!isVisible()) { - return; - } - - updateContent(); -} - -void VTagExplorer::updateContent() -{ - if (m_notebook) { - updateNotebookLabel(); - const QStringList &tags = m_notebook->getTags(); - if (m_notebookChanged || tagListObsolete(tags)) { - updateTagList(tags); - } - } else { - clear(); - } - - m_notebookChanged = false; -} - -void VTagExplorer::clear() -{ - setupUI(); - - m_fileList->clearAll(); - m_tagList->clearAll(); - updateTagLabel(""); - updateNotebookLabel(); -} - -void VTagExplorer::updateNotebookLabel() -{ - QString text = tr("Tags"); - QString tooltip; - if (m_notebook) { - QString name = m_notebook->getName(); - tooltip = name; - - if (name.size() > MAX_DISPLAY_LENGTH) { - name = name.left(MAX_DISPLAY_LENGTH) + QStringLiteral("..."); - } - - text = tr("Tags (%1)").arg(name); - } - - m_notebookLabel->setText(text); - m_notebookLabel->setToolTip(tooltip); -} - -bool VTagExplorer::tagListObsolete(const QStringList &p_tags) const -{ - if (m_tagList->count() != p_tags.size()) { - return true; - } - - for (int i = 0; i < p_tags.size(); ++i) { - if (p_tags[i] != m_tagList->item(i)->text()) { - return true; - } - } - - return false; -} - -void VTagExplorer::updateTagLabel(const QString &p_tag) -{ - QString text = tr("Notes"); - QString tooltip; - if (!p_tag.isEmpty()) { - QString name = p_tag; - tooltip = name; - - if (name.size() > MAX_DISPLAY_LENGTH) { - name = name.left(MAX_DISPLAY_LENGTH) + QStringLiteral("..."); - } - - text = tr("Notes (%1)").arg(name); - } - - m_tagLabel->setText(text); - m_tagLabel->setToolTip(tooltip); -} - -bool VTagExplorer::activateTag(const QString &p_tag) -{ - updateTagLabel(p_tag); - - m_fileList->clearAll(); - - if (p_tag.isEmpty()) { - return false; - } - - // Search this tag within current notebook. - g_mainWin->showStatusMessage(tr("Searching for tag \"%1\"").arg(p_tag)); - - QVector notebooks; - notebooks.append(m_notebook); - getVSearch()->clear(); - // We could not use WholeWordOnly here, since "c#" won't match a word. - int opts = VSearchConfig::CaseSensitive | VSearchConfig::RegularExpression; - QString pattern = QRegExp::escape(p_tag); - pattern = "^" + pattern + "$"; - QSharedPointer config(new VSearchConfig(VSearchConfig::CurrentNotebook, - VSearchConfig::Tag, - VSearchConfig::Note, - VSearchConfig::Internal, - opts, - pattern, - QString())); - getVSearch()->setConfig(config); - QSharedPointer result = getVSearch()->search(notebooks); - - bool ret = result->m_state == VSearchState::Success; - handleSearchFinished(result); - - return ret; -} - -void VTagExplorer::updateTagList(const QStringList &p_tags) -{ - // Clear. - m_tagList->clearAll(); - activateTag(""); - - for (auto const & tag : p_tags) { - addTagItem(tag); - } - - if (m_tagList->count() > 0) { - m_tagList->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); - } -} - -void VTagExplorer::addTagItem(const QString &p_tag) -{ - QListWidgetItem *item = new QListWidgetItem(VIconUtils::treeViewIcon(":/resources/icons/tag.svg"), - p_tag); - item->setToolTip(p_tag); - - m_tagList->addItem(item); -} - -void VTagExplorer::saveStateAndGeometry() -{ - if (!m_uiInitialized) { - return; - } - - g_config->setTagExplorerSplitterState(m_splitter->saveState()); -} - -void VTagExplorer::restoreStateAndGeometry() -{ - const QByteArray state = g_config->getTagExplorerSplitterState(); - if (!state.isEmpty()) { - m_splitter->restoreState(state); - } -} - -void VTagExplorer::initVSearch() -{ - m_search = new VSearch(this); - connect(m_search, &VSearch::resultItemAdded, - this, &VTagExplorer::handleSearchItemAdded); - connect(m_search, &VSearch::resultItemsAdded, - this, &VTagExplorer::handleSearchItemsAdded); - connect(m_search, &VSearch::finished, - this, &VTagExplorer::handleSearchFinished); - - m_noteIcon = VIconUtils::treeViewIcon(":/resources/icons/note_item.svg"); -} - -void VTagExplorer::handleSearchItemAdded(const QSharedPointer &p_item) -{ - appendItemToFileList(p_item); -} - -void VTagExplorer::appendItemToFileList(const QSharedPointer &p_item) -{ - Q_ASSERT(p_item->m_type == VSearchResultItem::Note); - - QListWidgetItem *item = new QListWidgetItem(m_noteIcon, - p_item->m_text.isEmpty() ? p_item->m_path : p_item->m_text); - item->setData(Qt::UserRole, p_item->m_path); - item->setToolTip(p_item->m_path); - m_fileList->addItem(item); -} - -void VTagExplorer::handleSearchItemsAdded(const QList > &p_items) -{ - for (auto const & it : p_items) { - appendItemToFileList(it); - } -} - -void VTagExplorer::handleSearchFinished(const QSharedPointer &p_result) -{ - Q_ASSERT(p_result->m_state != VSearchState::Idle); - QString msg; - switch (p_result->m_state) { - case VSearchState::Busy: - // Only synchronized search. - Q_ASSERT(false); - msg = tr("Invalid busy state when searching for tag"); - break; - - case VSearchState::Success: - qDebug() << "search succeeded"; - msg = tr("Search for tag succeeded"); - break; - - case VSearchState::Fail: - qDebug() << "search failed"; - msg = tr("Search for tag failed"); - break; - - case VSearchState::Cancelled: - qDebug() << "search cancelled"; - msg = tr("Search for tag calcelled"); - break; - - default: - break; - } - - m_search->clear(); - - if (!msg.isEmpty()) { - g_mainWin->showStatusMessage(msg); - } -} - -void VTagExplorer::openFileItem(QListWidgetItem *p_item) const -{ - if (!p_item) { - return; - } - - QStringList files; - files << getFilePath(p_item); - g_mainWin->openFiles(files); -} - -void VTagExplorer::openSelectedFileItems() const -{ - QStringList files; - QList selectedItems = m_fileList->selectedItems(); - for (auto it : selectedItems) { - files << getFilePath(it); - } - - if (!files.isEmpty()) { - g_mainWin->openFiles(files); - } -} - -QString VTagExplorer::getFilePath(const QListWidgetItem *p_item) const -{ - return p_item->data(Qt::UserRole).toString(); -} - -void VTagExplorer::handleFileListContextMenuRequested(QPoint p_pos) -{ - QListWidgetItem *item = m_fileList->itemAt(p_pos); - if (!item) { - return; - } - - QMenu menu(this); - menu.setToolTipsVisible(true); - - QAction *openAct = new QAction(tr("&Open"), &menu); - openAct->setToolTip(tr("Open selected notes")); - connect(openAct, &QAction::triggered, - this, &VTagExplorer::openSelectedFileItems); - menu.addAction(openAct); - - QList selectedItems = m_fileList->selectedItems(); - if (selectedItems.size() == 1) { - QAction *locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"), - tr("&Locate To Folder"), - &menu); - locateAct->setToolTip(tr("Locate the folder of current note")); - connect(locateAct, &QAction::triggered, - this, &VTagExplorer::locateCurrentFileItem); - menu.addAction(locateAct); - } - - menu.addSeparator(); - - QAction *addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"), - tr("Add To Cart"), - &menu); - addToCartAct->setToolTip(tr("Add selected notes to Cart for further processing")); - connect(addToCartAct, &QAction::triggered, - this, &VTagExplorer::addFileToCart); - menu.addAction(addToCartAct); - - QAction *pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"), - tr("Pin To History"), - &menu); - pinToHistoryAct->setToolTip(tr("Pin selected notes to History")); - connect(pinToHistoryAct, &QAction::triggered, - this, &VTagExplorer::pinFileToHistory); - menu.addAction(pinToHistoryAct); - - menu.exec(m_fileList->mapToGlobal(p_pos)); -} - -void VTagExplorer::locateCurrentFileItem() const -{ - auto item = m_fileList->currentItem(); - if (!item) { - return; - } - - VFile *file = g_vnote->getInternalFile(getFilePath(item)); - if (file) { - g_mainWin->locateFile(file); - } -} - -void VTagExplorer::addFileToCart() const -{ - QList items = m_fileList->selectedItems(); - VCart *cart = g_mainWin->getCart(); - - for (int i = 0; i < items.size(); ++i) { - cart->addFile(getFilePath(items[i])); - } - - g_mainWin->showStatusMessage(tr("%1 %2 added to Cart") - .arg(items.size()) - .arg(items.size() > 1 ? tr("notes") : tr("note"))); -} - -void VTagExplorer::pinFileToHistory() const -{ - QList items = m_fileList->selectedItems(); - - QStringList files; - for (int i = 0; i < items.size(); ++i) { - files << getFilePath(items[i]); - } - - g_mainWin->getHistoryList()->pinFiles(files); - - g_mainWin->showStatusMessage(tr("%1 %2 pinned to History") - .arg(items.size()) - .arg(items.size() > 1 ? tr("notes") : tr("note"))); -} - -void VTagExplorer::promptToRemoveEmptyTag(const QString &p_tag) -{ - Q_ASSERT(!p_tag.isEmpty()); - - int ret = VUtils::showMessage(QMessageBox::Warning, - tr("Warning"), - tr("Empty tag detected! Do you want to remove it?"), - tr("The tag %2 seems not to " - "be assigned to any note currently.") - .arg(g_config->c_dataTextStyle) - .arg(p_tag), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Cancel, - this, - MessageBoxType::Danger); - - if (ret == QMessageBox::Cancel) { - return; - } - - // Remove the tag from m_notebook. - m_notebook->removeTag(p_tag); - updateContent(); -} - -void VTagExplorer::registerNavigationTarget() -{ - setupUI(); - - VNavigationModeListWidgetWrapper *tagWrapper = new VNavigationModeListWidgetWrapper(m_tagList, this); - g_mainWin->getCaptain()->registerNavigationTarget(tagWrapper); - - VNavigationModeListWidgetWrapper *fileWrapper = new VNavigationModeListWidgetWrapper(m_fileList, this); - g_mainWin->getCaptain()->registerNavigationTarget(fileWrapper); -} - -void VTagExplorer::setupFileListSplitOut(bool p_enabled) -{ - m_splitBtn->setChecked(p_enabled); - if (p_enabled) { - m_splitter->setOrientation(Qt::Horizontal); - m_splitter->setStretchFactor(0, 0); - m_splitter->setStretchFactor(1, 1); - } else { - m_splitter->setOrientation(Qt::Vertical); - m_splitter->setStretchFactor(0, 1); - m_splitter->setStretchFactor(1, 2); - } -} diff --git a/src/vtagexplorer.h b/src/vtagexplorer.h deleted file mode 100644 index ad65808b..00000000 --- a/src/vtagexplorer.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef VTAGEXPLORER_H -#define VTAGEXPLORER_H - -#include -#include - -#include "vsearchconfig.h" - -class QLabel; -class VListWidget; -class QListWidgetItem; -class QSplitter; -class VNotebook; -class VSearch; - -class VTagExplorer : public QWidget -{ - Q_OBJECT -public: - explicit VTagExplorer(QWidget *p_parent = nullptr); - - void clear(); - - void setNotebook(VNotebook *p_notebook); - - void saveStateAndGeometry(); - - void registerNavigationTarget(); - -protected: - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void handleSearchItemAdded(const QSharedPointer &p_item); - - void handleSearchItemsAdded(const QList > &p_items); - - void handleSearchFinished(const QSharedPointer &p_result); - - void openFileItem(QListWidgetItem *p_item) const; - - void openSelectedFileItems() const; - - void locateCurrentFileItem() const; - - void addFileToCart() const; - - void pinFileToHistory() const; - - void handleFileListContextMenuRequested(QPoint p_pos); - -private: - void setupUI(); - - void updateNotebookLabel(); - - void updateTagLabel(const QString &p_tag); - - bool tagListObsolete(const QStringList &p_tags) const; - - void updateTagList(const QStringList &p_tags); - - void updateContent(); - - // Return ture if succeeded. - bool activateTag(const QString &p_tag); - - void addTagItem(const QString &p_tag); - - void restoreStateAndGeometry(); - - VSearch *getVSearch() const; - - void initVSearch(); - - void appendItemToFileList(const QSharedPointer &p_item); - - QString getFilePath(const QListWidgetItem *p_item) const; - - void promptToRemoveEmptyTag(const QString &p_tag); - - void setupFileListSplitOut(bool p_enabled); - - bool m_uiInitialized; - - QLabel *m_notebookLabel; - - QLabel *m_tagLabel; - - QPushButton *m_splitBtn; - - VListWidget *m_tagList; - - VListWidget *m_fileList; - - QSplitter *m_splitter; - - VNotebook *m_notebook; - - bool m_notebookChanged; - - QIcon m_noteIcon; - - VSearch *m_search; -}; - -inline VSearch *VTagExplorer::getVSearch() const -{ - if (m_search) { - return m_search; - } - - const_cast(this)->initVSearch(); - return m_search; -} - -#endif // VTAGEXPLORER_H diff --git a/src/vtaglabel.cpp b/src/vtaglabel.cpp deleted file mode 100644 index 44afa631..00000000 --- a/src/vtaglabel.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "vtaglabel.h" - -#include - -#include "utils/viconutils.h" -#include "vconfigmanager.h" - -extern VConfigManager *g_config; - -VTagLabel::VTagLabel(const QString &p_text, - bool p_useFullText, - QWidget *p_parent) - : QWidget(p_parent), - m_text(p_text), - m_useFullText(p_useFullText) -{ - setupUI(); -} - -VTagLabel::VTagLabel(QWidget *p_parent) - : QWidget(p_parent), - m_useFullText(false) -{ - setupUI(); -} - -void VTagLabel::setupUI() -{ - m_label = new QLabel(this); - m_label->setProperty("TagLabel", true); - - updateLabel(); - - m_closeBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/close.svg"), "", this); - m_closeBtn->setProperty("StatusBtn", true); - m_closeBtn->setToolTip(tr("Remove")); - m_closeBtn->setFocusPolicy(Qt::NoFocus); - m_closeBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); - m_closeBtn->hide(); - connect(m_closeBtn, &QPushButton::clicked, - this, [this]() { - emit removalRequested(m_text); - }); - - QHBoxLayout *layout = new QHBoxLayout(); - layout->addWidget(m_label); - layout->addWidget(m_closeBtn); - - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - - setLayout(layout); -} - -void VTagLabel::updateLabel() -{ - QString tag(m_text); - - if (!m_useFullText) { - int ml = g_config->getMaxTagLabelLength(); - if (ml > 0 && tag.size() > ml) { - tag.resize(ml); - tag += QStringLiteral("..."); - } - } - - m_label->setText(tag); - m_label->setToolTip(m_text); -} - -void VTagLabel::clear() -{ - m_label->clear(); -} - -void VTagLabel::setText(const QString &p_text) -{ - m_text = p_text; - updateLabel(); -} - -bool VTagLabel::event(QEvent *p_event) -{ - switch (p_event->type()) { - case QEvent::Enter: - m_closeBtn->show(); - break; - - case QEvent::Leave: - m_closeBtn->hide(); - break; - - default: - break; - } - - return QWidget::event(p_event); -} diff --git a/src/vtaglabel.h b/src/vtaglabel.h deleted file mode 100644 index aad5ffa5..00000000 --- a/src/vtaglabel.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef VTAGLABEL_H -#define VTAGLABEL_H - -#include - -class QLabel; -class QPushButton; - -class VTagLabel : public QWidget -{ - Q_OBJECT -public: - explicit VTagLabel(const QString &p_text, - bool p_useFullText, - QWidget *p_parent = nullptr); - - explicit VTagLabel(QWidget *p_parent = nullptr); - - void clear(); - - void setText(const QString &p_text); - - const QString &text() const; - -signals: - void removalRequested(const QString &p_text); - -protected: - virtual bool event(QEvent *p_event) Q_DECL_OVERRIDE; - -private: - void setupUI(); - - void updateLabel(); - - QString m_text; - - bool m_useFullText; - - QLabel *m_label; - QPushButton *m_closeBtn; -}; - -inline const QString &VTagLabel::text() const -{ - return m_text; -} - -#endif // VTAGLABEL_H diff --git a/src/vtagpanel.cpp b/src/vtagpanel.cpp deleted file mode 100644 index 55c045d4..00000000 --- a/src/vtagpanel.cpp +++ /dev/null @@ -1,294 +0,0 @@ -#include "vtagpanel.h" - -#include - -#include "vbuttonwithwidget.h" -#include "utils/viconutils.h" -#include "vnotefile.h" -#include "valltagspanel.h" -#include "vtaglabel.h" -#include "vlineedit.h" -#include "vmainwindow.h" -#include "vnote.h" -#include "vconfigmanager.h" - -extern VPalette *g_palette; - -extern VMainWindow *g_mainWin; - -extern VNote *g_vnote; - -extern VConfigManager *g_config; - -VTagPanel::VTagPanel(QWidget *parent) - : QWidget(parent), - m_file(NULL), - m_notebookOfCompleter(NULL) -{ - setupUI(); -} - -void VTagPanel::setupUI() -{ - const int maxNum = g_config->getMaxNumOfTagLabels(); - for (int i = 0; i < maxNum; ++i) { - VTagLabel *label = new VTagLabel(this); - connect(label, &VTagLabel::removalRequested, - this, [this](const QString &p_text) { - removeTag(p_text); - updateTags(); - }); - - m_labels.append(label); - } - - m_tagsPanel = new VAllTagsPanel(this); - connect(m_tagsPanel, &VAllTagsPanel::tagRemoved, - this, [this](const QString &p_text) { - removeTag(p_text); - - if (m_file->getTags().size() <= g_config->getMaxNumOfTagLabels()) { - // Hide the more panel. - m_btn->hidePopupWidget(); - m_btn->hide(); - } - }); - - m_btn = new VButtonWithWidget(VIconUtils::icon(":/resources/icons/tags.svg", - g_palette->color("tab_indicator_tag_label_bg")), - "", - m_tagsPanel, - this); - m_btn->setToolTip(tr("View and edit tags of current note")); - m_btn->setProperty("StatusBtn", true); - m_btn->setFocusPolicy(Qt::NoFocus); - connect(m_btn, &VButtonWithWidget::popupWidgetAboutToShow, - this, &VTagPanel::updateAllTagsPanel); - - m_tagEdit = new VLineEdit(this); - m_tagEdit->setToolTip(tr("Press Enter to add a tag")); - m_tagEdit->setPlaceholderText(tr("Add a tag")); - m_tagEdit->setProperty("EmbeddedEdit", true); - m_tagEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); - connect(m_tagEdit, &QLineEdit::returnPressed, - this, [this]() { - Q_ASSERT(m_file); - QString text = m_tagEdit->text(); - if (addTag(text)) { - if (m_file->getNotebook()->addTag(text)) { - updateCompleter(); - } - - updateTags(); - - g_mainWin->showStatusMessage(tr("Tag \"%1\" added").arg(text)); - } - - // Clear after a wait since it may be triggered by the completion. - // The activated() of completion will add text to the edit. - QTimer::singleShot(100, m_tagEdit, SLOT(clear())); - }); - - QValidator *validator = new QRegExpValidator(QRegExp("[^,]+"), m_tagEdit); - m_tagEdit->setValidator(validator); - - // Completer. - m_tagsModel = new QStringListModel(this); - QCompleter *completer = new QCompleter(m_tagsModel, this); - completer->setCaseSensitivity(Qt::CaseSensitive); - completer->popup()->setItemDelegate(new QStyledItemDelegate(this)); - m_tagEdit->setCompleter(completer); - m_tagEdit->installEventFilter(this); - - QHBoxLayout *mainLayout = new QHBoxLayout(); - for (auto label : m_labels) { - mainLayout->addWidget(label); - label->hide(); - } - - mainLayout->addWidget(m_btn); - mainLayout->addWidget(m_tagEdit); - - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -void VTagPanel::clearLabels() -{ - for (auto label : m_labels) { - label->clear(); - label->hide(); - } - - m_tagsPanel->clear(); -} - -void VTagPanel::updateTags(VNoteFile *p_file) -{ - if (m_file == p_file) { - return; - } - - m_file = p_file; - - updateTags(); -} - -void VTagPanel::updateTags() -{ - clearLabels(); - - if (!m_file) { - m_btn->setVisible(false); - return; - } - - const QStringList &tags = m_file->getTags(); - int idx = 0; - for (; idx < tags.size() && idx < m_labels.size(); ++idx) { - m_labels[idx]->setText(tags[idx]); - m_labels[idx]->show(); - } - - m_btn->setVisible(idx < tags.size()); -} - -void VTagPanel::updateAllTagsPanel() -{ - Q_ASSERT(m_file); - m_tagsPanel->clear(); - - const QStringList &tags = m_file->getTags(); - for (int idx = g_config->getMaxNumOfTagLabels(); idx < tags.size(); ++idx) { - m_tagsPanel->addTag(tags[idx]); - } -} - -void VTagPanel::removeTag(const QString &p_text) -{ - if (!m_file) { - return; - } - - m_file->removeTag(p_text); - g_mainWin->showStatusMessage(tr("Tag \"%1\" removed").arg(p_text)); -} - -bool VTagPanel::addTag(const QString &p_text) -{ - if (!m_file) { - return false; - } - - bool ret = m_file->addTag(p_text); - return ret; -} - -bool VTagPanel::eventFilter(QObject *p_obj, QEvent *p_event) -{ - Q_ASSERT(p_obj == m_tagEdit); - - if (p_event->type() == QEvent::FocusIn) { - QFocusEvent *eve = static_cast(p_event); - if (eve->gotFocus()) { - // Just check completer. - updateCompleter(m_file); - } - } - - return QWidget::eventFilter(p_obj, p_event); -} - -void VTagPanel::updateCompleter(const VNoteFile *p_file) -{ - const VNotebook *nb = p_file ? p_file->getNotebook() : NULL; - if (nb == m_notebookOfCompleter) { - // No need to update. - return; - } - - m_notebookOfCompleter = nb; - updateCompleter(); -} - -void VTagPanel::updateCompleter() -{ - m_tagsModel->setStringList(m_notebookOfCompleter ? m_notebookOfCompleter->getTags() - : QStringList()); -} - -void VTagPanel::showNavigation() -{ - if (!isVisible() || !m_file) { - return; - } - - // View all tags. - if (isAllTagsPanelAvailable()) { - QChar key('a'); - m_keyMap[key] = m_btn; - - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, this); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str, true)); - label->move(m_btn->geometry().topLeft()); - label->show(); - m_naviLabels.append(label); - } - - // Add tag edit. - { - QChar key('b'); - m_keyMap[key] = m_tagEdit; - - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, this); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str, true)); - label->move(m_tagEdit->geometry().topLeft()); - label->show(); - m_naviLabels.append(label); - } -} - -bool VTagPanel::handleKeyNavigation(int p_key, bool &p_succeed) -{ - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (m_isSecondKey && !keyChar.isNull()) { - m_isSecondKey = false; - p_succeed = true; - auto it = m_keyMap.find(keyChar); - if (it != m_keyMap.end()) { - ret = true; - - if (*it == m_btn) { - // Show all tags panel. - // To avoid focus in VCaptain after hiding the menu. - g_mainWin->focusEditArea(); - // Use timer to hide the label first. - QTimer::singleShot(50, m_btn, SLOT(showPopupWidget())); - } else { - m_tagEdit->setFocus(); - } - } - } else if (keyChar == m_majorKey) { - // Major key pressed. - // Need second key if m_keyMap is not empty. - if (m_keyMap.isEmpty()) { - p_succeed = true; - } else { - m_isSecondKey = true; - } - - ret = true; - } - - return ret; -} - -bool VTagPanel::isAllTagsPanelAvailable() const -{ - return m_btn->isVisible(); -} diff --git a/src/vtagpanel.h b/src/vtagpanel.h deleted file mode 100644 index 12d530b8..00000000 --- a/src/vtagpanel.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef VTAGPANEL_H -#define VTAGPANEL_H - -#include -#include "vnavigationmode.h" - -#include - -class VTagLabel; -class VButtonWithWidget; -class VNoteFile; -class VAllTagsPanel; -class VLineEdit; -class QStringListModel; -class VNotebook; - -class VTagPanel : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VTagPanel(QWidget *parent = nullptr); - - void updateTags(VNoteFile *p_file); - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -protected: - bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - void updateAllTagsPanel(); - - void removeTag(const QString &p_text); - -private: - void setupUI(); - - void clearLabels(); - - void updateTags(); - - bool addTag(const QString &p_text); - - void updateCompleter(const VNoteFile *p_file); - - void updateCompleter(); - - bool isAllTagsPanelAvailable() const; - - QVector m_labels; - - VButtonWithWidget *m_btn; - - VAllTagsPanel *m_tagsPanel; - - VLineEdit *m_tagEdit; - - // Used for auto completion. - QStringListModel *m_tagsModel; - - VNoteFile *m_file; - - const VNotebook *m_notebookOfCompleter; -}; -#endif // VTAGPANEL_H diff --git a/src/vtextblockdata.cpp b/src/vtextblockdata.cpp deleted file mode 100644 index ad52af75..00000000 --- a/src/vtextblockdata.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "vtextblockdata.h" - -VTextBlockData::VTextBlockData() - : QTextBlockUserData(), - m_timeStamp(0), - m_codeBlockTimeStamp(0), - m_cacheValid(false), - m_codeBlockIndentation(-1) -{ -} - -VTextBlockData::~VTextBlockData() -{ - for (auto it : m_previews) { - delete it; - } - - m_previews.clear(); -} - -bool VTextBlockData::insertPreviewInfo(VPreviewInfo *p_info) -{ - bool tsUpdated = false; - bool inserted = false; - for (auto it = m_previews.begin(); it != m_previews.end();) { - VPreviewInfo *ele = *it; - - if (p_info->m_imageInfo < ele->m_imageInfo) { - // Insert p_info here. - m_previews.insert(it, p_info); - inserted = true; - break; - } else if (p_info->m_imageInfo == ele->m_imageInfo) { - // Update the timestamp. - delete ele; - *it = p_info; - inserted = true; - tsUpdated = true; - break; - } else if (p_info->m_imageInfo.intersect(ele->m_imageInfo)) { - // Two preview intersect. - delete ele; - it = m_previews.erase(it); - } else { - ++it; - } - } - - if (!inserted) { - // Append it. - m_previews.append(p_info); - } - - Q_ASSERT(checkOrder()); - - return tsUpdated; -} - -QString VTextBlockData::toString() const -{ - QString ret; - for (int i = 0; i < m_previews.size(); ++i) { - ret += QString("preview %1: source %2 ts %3 image %4\n") - .arg(i) - .arg((int)m_previews[i]->m_source) - .arg(m_previews[i]->m_timeStamp) - .arg(m_previews[i]->m_imageInfo.toString()); - } - - return ret; -} - -bool VTextBlockData::checkOrder() const -{ - for (int i = 1; i < m_previews.size(); ++i) { - if (!(m_previews[i - 1]->m_imageInfo < m_previews[i]->m_imageInfo)) { - return false; - } - } - - return true; -} - -bool VTextBlockData::clearObsoletePreview(long long p_timeStamp, PreviewSource p_source) -{ - bool deleted = false; - for (auto it = m_previews.begin(); it != m_previews.end();) { - VPreviewInfo *ele = *it; - if (ele->m_source == p_source - && ele->m_timeStamp != p_timeStamp) { - // Remove it. - delete ele; - it = m_previews.erase(it); - deleted = true; - } else { - ++it; - } - } - - return deleted; -} diff --git a/src/vtextblockdata.h b/src/vtextblockdata.h deleted file mode 100644 index 34bc86e1..00000000 --- a/src/vtextblockdata.h +++ /dev/null @@ -1,357 +0,0 @@ -#ifndef VTEXTBLOCKDATA_H -#define VTEXTBLOCKDATA_H - -#include -#include -#include - -#include "vconstants.h" -#include "markdownhighlighterdata.h" -#include "vtextdocumentlayoutdata.h" - -// Sources of the preview. -enum class PreviewSource -{ - ImageLink = 0, - CodeBlock, - MathjaxBlock, - MaxNumberOfSources -}; - - -// Info about a previewed image. -struct VPreviewedImageInfo -{ - VPreviewedImageInfo() - : m_startPos(-1), - m_endPos(-1), - m_padding(0), - m_inline(false) - { - } - - VPreviewedImageInfo(int p_startPos, - int p_endPos, - int p_padding, - bool p_inline, - const QString &p_imageName, - const QSize &p_imageSize, - const QString &p_background) - : m_startPos(p_startPos), - m_endPos(p_endPos), - m_padding(p_padding), - m_inline(p_inline), - m_imageName(p_imageName), - m_imageSize(p_imageSize), - m_background(p_background) - { - } - - bool operator<(const VPreviewedImageInfo &a) const - { - return m_endPos <= a.m_startPos; - } - - bool operator==(const VPreviewedImageInfo &a) const - { - return m_startPos == a.m_startPos - && m_endPos == a.m_endPos - && m_padding == a.m_padding - && m_inline == a.m_inline - && m_imageName == a.m_imageName - && m_imageSize == a.m_imageSize - && m_background == a.m_background; - } - - bool intersect(const VPreviewedImageInfo &a) const - { - return !(m_endPos <= a.m_startPos || m_startPos >= a.m_endPos); - } - - bool contains(int p_positionInBlock) const - { - return p_positionInBlock >= m_startPos && p_positionInBlock < m_endPos; - } - - QString toString() const - { - return QString("previewed image (%1): [%2, %3) padding %4 inline %5 (%6,%7) bg(%8)") - .arg(m_imageName) - .arg(m_startPos) - .arg(m_endPos) - .arg(m_padding) - .arg(m_inline) - .arg(m_imageSize.width()) - .arg(m_imageSize.height()) - .arg(m_background); - } - - // Start position of text corresponding to the image within block. - int m_startPos; - - // End position of text corresponding to the image within block. - int m_endPos; - - // Padding of the image. Only valid for block image. - int m_padding; - - // Whether it is inline image or block image. - bool m_inline; - - // Image name in the resource manager. - QString m_imageName; - - // Image size of the image. Cache for performance. - QSize m_imageSize; - - // Forced background before drawing this image. - QString m_background; -}; - - -struct VPreviewInfo -{ - VPreviewInfo() - : m_source(PreviewSource::ImageLink), - m_timeStamp(0) - { - } - - VPreviewInfo(PreviewSource p_source, - long long p_timeStamp, - int p_startPos, - int p_endPos, - int p_padding, - bool p_inline, - const QString &p_imageName, - const QSize &p_imageSize, - const QString &p_background) - : m_source(p_source), - m_timeStamp(p_timeStamp), - m_imageInfo(p_startPos, - p_endPos, - p_padding, - p_inline, - p_imageName, - p_imageSize, - p_background) - { - } - - // Source of this preview. - PreviewSource m_source; - - // Timestamp for this preview. - long long m_timeStamp; - - // Image info of this preview. - VPreviewedImageInfo m_imageInfo; -}; - - -// User data for each block. -class VTextBlockData : public QTextBlockUserData -{ -public: - VTextBlockData(); - - ~VTextBlockData(); - - // Insert @p_info into m_previews, preserving the order. - // Returns true if only timestamp is updated. - bool insertPreviewInfo(VPreviewInfo *p_info); - - // For degub only. - QString toString() const; - - const QVector &getPreviews() const; - - // Return true if there have obsolete preview being deleted. - bool clearObsoletePreview(long long p_timeStamp, PreviewSource p_source); - - int getCodeBlockIndentation() const; - - void setCodeBlockIndentation(int p_indent); - - TimeStamp getTimeStamp() const; - - void setTimeStamp(TimeStamp p_ts); - - TimeStamp getCodeBlockTimeStamp() const; - - void setCodeBlockTimeStamp(TimeStamp p_ts); - - bool isBlockHighlightCacheMatched(const QVector &p_highlight) const; - - QVector &getBlockHighlightCache(); - - void setBlockHighlightCache(const QVector &p_highlight); - - bool isCodeBlockHighlightCacheMatched(const QVector &p_highlight) const; - - QVector &getCodeBlockHighlightCache(); - - void setCodeBlockHighlightCache(const QVector &p_highlight); - - bool isCacheValid() const; - - void setCacheValid(bool p_valid); - - static VTextBlockData *blockData(const QTextBlock &p_block); - - static BlockLayoutInfo *layoutInfo(const QTextBlock &p_block); - -private: - // Check the order of elements. - bool checkOrder() const; - - // TimeStamp of the highlight result which has been applied to this block. - TimeStamp m_timeStamp; - - // TimeStamp of the code block highlight result which has been applied to this block. - TimeStamp m_codeBlockTimeStamp; - - // Block highlight cache. - QVector m_blockHighlightCache; - - // Code block highlight cache. - // This cache is always valid. - QVector m_codeBlockHighlightCache; - - // Whether the highlight cache is valid. - bool m_cacheValid; - - // Sorted by m_imageInfo.m_startPos, with no two element's position intersected. - QVector m_previews; - - // Indentation of the this code block if this block is a fenced code block. - int m_codeBlockIndentation; - - BlockLayoutInfo m_layoutInfo; -}; - -inline const QVector &VTextBlockData::getPreviews() const -{ - return m_previews; -} - -inline int VTextBlockData::getCodeBlockIndentation() const -{ - return m_codeBlockIndentation; -} - -inline void VTextBlockData::setCodeBlockIndentation(int p_indent) -{ - m_codeBlockIndentation = p_indent; -} - -inline TimeStamp VTextBlockData::getTimeStamp() const -{ - return m_timeStamp; -} - -inline void VTextBlockData::setTimeStamp(TimeStamp p_ts) -{ - m_timeStamp = p_ts; -} - -inline TimeStamp VTextBlockData::getCodeBlockTimeStamp() const -{ - return m_codeBlockTimeStamp; -} - -inline void VTextBlockData::setCodeBlockTimeStamp(TimeStamp p_ts) -{ - m_codeBlockTimeStamp = p_ts; -} - -inline bool VTextBlockData::isBlockHighlightCacheMatched(const QVector &p_highlight) const -{ - if (!m_cacheValid - || p_highlight.size() != m_blockHighlightCache.size()) { - return false; - } - - int sz = p_highlight.size(); - for (int i = 0; i < sz; ++i) - { - if (!(p_highlight[i] == m_blockHighlightCache[i])) { - return false; - } - } - - return true; -} - -inline QVector &VTextBlockData::getBlockHighlightCache() -{ - return m_blockHighlightCache; -} - -inline void VTextBlockData::setBlockHighlightCache(const QVector &p_highlight) -{ - m_blockHighlightCache = p_highlight; -} - -inline bool VTextBlockData::isCodeBlockHighlightCacheMatched(const QVector &p_highlight) const -{ - if (p_highlight.size() != m_codeBlockHighlightCache.size()) { - return false; - } - - int sz = p_highlight.size(); - for (int i = 0; i < sz; ++i) - { - if (!(p_highlight[i] == m_codeBlockHighlightCache[i])) { - return false; - } - } - - return true; -} - -inline QVector &VTextBlockData::getCodeBlockHighlightCache() -{ - return m_codeBlockHighlightCache; -} - -inline void VTextBlockData::setCodeBlockHighlightCache(const QVector &p_highlight) -{ - m_codeBlockHighlightCache = p_highlight; -} - -inline bool VTextBlockData::isCacheValid() const -{ - return m_cacheValid; -} - -inline void VTextBlockData::setCacheValid(bool p_valid) -{ - m_cacheValid = p_valid; -} - -inline VTextBlockData *VTextBlockData::blockData(const QTextBlock &p_block) -{ - if (!p_block.isValid()) { - return NULL; - } - - VTextBlockData *data = static_cast(p_block.userData()); - if (!data) { - data = new VTextBlockData(); - const_cast(p_block).setUserData(data); - } - - return data; -} - -inline BlockLayoutInfo *VTextBlockData::layoutInfo(const QTextBlock &p_block) -{ - VTextBlockData *data = blockData(p_block); - if (data) { - return &data->m_layoutInfo; - } else { - return NULL; - } -} -#endif // VTEXTBLOCKDATA_H diff --git a/src/vtextdocumentlayout.cpp b/src/vtextdocumentlayout.cpp deleted file mode 100644 index eebdf6e4..00000000 --- a/src/vtextdocumentlayout.cpp +++ /dev/null @@ -1,1208 +0,0 @@ -#include "vtextdocumentlayout.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vimageresourcemanager2.h" -#include "vtextedit.h" -#include "vtextblockdata.h" - -#define MARKER_THICKNESS 2 -#define MAX_INLINE_IMAGE_HEIGHT 400 - -inline static bool realEqual(qreal p_a, qreal p_b) -{ - return qAbs(p_a - p_b) < 1e-8; -} - -VTextDocumentLayout::VTextDocumentLayout(QTextDocument *p_doc, - VImageResourceManager2 *p_imageMgr) - : QAbstractTextDocumentLayout(p_doc), - m_margin(p_doc->documentMargin()), - m_width(0), - m_maximumWidthBlockNumber(-1), - m_height(0), - m_lineLeading(0), - m_blockCount(0), - m_cursorWidth(1), - m_cursorMargin(4), - m_imageMgr(p_imageMgr), - m_blockImageEnabled(false), - m_imageWidthConstrainted(false), - m_imageLineColor("#9575CD"), - m_cursorBlockMode(CursorBlock::None), - m_virtualCursorBlockWidth(8), - m_lastCursorBlockWidth(-1), - m_highlightCursorLineBlock(false), - m_cursorLineBlockBg("#C0C0C0"), - m_cursorLineBlockNumber(-1), - m_extraBufferHeight(0) -{ -} - -static void fillBackground(QPainter *p_painter, - const QRectF &p_rect, - QBrush p_brush, - QRectF p_gradientRect = QRectF()) -{ - p_painter->save(); - if (p_brush.style() >= Qt::LinearGradientPattern - && p_brush.style() <= Qt::ConicalGradientPattern) { - if (!p_gradientRect.isNull()) { - QTransform m = QTransform::fromTranslate(p_gradientRect.left(), - p_gradientRect.top()); - m.scale(p_gradientRect.width(), p_gradientRect.height()); - p_brush.setTransform(m); - const_cast(p_brush.gradient())->setCoordinateMode(QGradient::LogicalMode); - } - } else { - p_painter->setBrushOrigin(p_rect.topLeft()); - } - - p_painter->fillRect(p_rect, p_brush); - p_painter->restore(); -} - -void VTextDocumentLayout::blockRangeFromRect(const QRectF &p_rect, - int &p_first, - int &p_last) const -{ - if (p_rect.isNull()) { - p_first = 0; - p_last = document()->blockCount() - 1; - return; - } - - p_first = -1; - p_last = document()->blockCount() - 1; - int y = p_rect.y(); - QTextBlock block = document()->firstBlock(); - while (block.isValid()) { - const BlockLayoutInfo *info = VTextBlockData::layoutInfo(block); - V_ASSERT(info->hasOffset()); - - if (info->top() == y - || (info->top() < y && info->bottom() >= y)) { - p_first = block.blockNumber(); - break; - } - - block = block.next(); - } - - if (p_first == -1) { - p_last = -1; - return; - } - - y += p_rect.height(); - while (block.isValid()) { - const BlockLayoutInfo *info = VTextBlockData::layoutInfo(block); - V_ASSERT(info->hasOffset()); - - if (info->bottom() > y) { - p_last = block.blockNumber(); - break; - } - - block = block.next(); - } -} - -void VTextDocumentLayout::blockRangeFromRectBS(const QRectF &p_rect, - int &p_first, - int &p_last) const -{ - if (p_rect.isNull()) { - p_first = 0; - p_last = document()->blockCount() - 1; - return; - } - - p_first = findBlockByPosition(p_rect.topLeft()); - if (p_first == -1) { - p_last = -1; - return; - } - - int y = p_rect.bottom(); - QTextBlock block = document()->findBlockByNumber(p_first); - const BlockLayoutInfo *info = VTextBlockData::layoutInfo(block); - if (realEqual(info->top(), p_rect.top()) && p_first > 0) { - --p_first; - } - - p_last = document()->blockCount() - 1; - while (block.isValid()) { - const BlockLayoutInfo *tinfo = VTextBlockData::layoutInfo(block); - if (!tinfo->hasOffset()) { - qWarning() << "block without offset" - << block.blockNumber() << tinfo->m_offset - << tinfo->m_rect << tinfo->m_rect.isNull(); - } - - V_ASSERT(tinfo->hasOffset()); - - if (tinfo->bottom() > y) { - p_last = block.blockNumber(); - break; - } - - block = block.next(); - } -} - -int VTextDocumentLayout::findBlockByPosition(const QPointF &p_point) const -{ - QTextDocument *doc = document(); - int first = 0, last = doc->blockCount() - 1; - int y = p_point.y(); - while (first <= last) { - int mid = (first + last) / 2; - QTextBlock blk = doc->findBlockByNumber(mid); - const BlockLayoutInfo *info = VTextBlockData::layoutInfo(blk); - if (!info) { - return -1; - } - - V_ASSERT(info->hasOffset()); - if (info->top() <= y && info->bottom() > y) { - // Found it. - return mid; - } else if (info->top() > y) { - last = mid - 1; - } else { - first = mid + 1; - } - } - - QTextBlock blk = doc->lastBlock(); - const BlockLayoutInfo *info = VTextBlockData::layoutInfo(blk); - if (y >= info->bottom()) { - return blk.blockNumber(); - } - - return 0; -} - -void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_context) -{ - // Find out the blocks. - int first, last; - blockRangeFromRectBS(p_context.clip, first, last); - if (first == -1) { - return; - } - - QTextDocument *doc = document(); - QTextBlock block = doc->findBlockByNumber(first); - QPointF offset(m_margin, VTextBlockData::layoutInfo(block)->top()); - QTextBlock lastBlock = doc->findBlockByNumber(last); - - QPen oldPen = p_painter->pen(); - p_painter->setPen(p_context.palette.color(QPalette::Text)); - - while (block.isValid()) { - const BlockLayoutInfo *info = VTextBlockData::layoutInfo(block); - V_ASSERT(info->hasOffset()); - - const QRectF &rect = info->m_rect; - QTextLayout *layout = block.layout(); - if (!block.isVisible()) { - offset.ry() += rect.height(); - if (block == lastBlock) { - break; - } - - block = block.next(); - continue; - } - - QTextBlockFormat blockFormat = block.blockFormat(); - QBrush bg = blockFormat.background(); - if (bg != Qt::NoBrush) { - int x = offset.x(); - int y = offset.y(); - fillBackground(p_painter, - rect.adjusted(x, y, x, y), - bg); - } - - // Draw block background for HRULE. - if (block.userState() == HighlightBlockState::HRule) { - QVector fmts = layout->formats(); - if (fmts.size() == 1) { - int x = offset.x(); - int y = offset.y(); - fillBackground(p_painter, - rect.adjusted(x, y, x, y), - fmts[0].format.background()); - } - } - - auto selections = formatRangeFromSelection(block, p_context.selections); - - // Draw the cursor. - int blpos = block.position(); - int bllen = block.length(); - bool drawCursor = p_context.cursorPosition >= blpos - && p_context.cursorPosition < blpos + bllen; - int cursorWidth = m_cursorWidth; - int cursorPosition = p_context.cursorPosition - blpos; - if (drawCursor && m_cursorBlockMode != CursorBlock::None) { - auto direction = layout->textOption().textDirection(); - bool needUpdateWidthViaSelection = true; - int deltaPosition = direction == Qt::RightToLeft ? -1 : 1; - // FIXME: the rect to update is error in RTL case. - if (m_cursorBlockMode == CursorBlock::LeftSide) { - if (direction == Qt::RightToLeft) { - if (cursorPosition == 0) { - cursorWidth = 1; - needUpdateWidthViaSelection = false; - } - } else { - if (cursorPosition > 0) { - --cursorPosition; - } else { - cursorWidth = 1; - needUpdateWidthViaSelection = false; - } - } - } else if (m_cursorBlockMode == CursorBlock::RightSide) { - if (direction == Qt::RightToLeft) { - if (cursorPosition < bllen - 1) { - ++cursorPosition; - } else { - cursorWidth = 1; - needUpdateWidthViaSelection = false; - } - } else { - if (cursorPosition == bllen - 1) { - cursorWidth = m_virtualCursorBlockWidth; - needUpdateWidthViaSelection = false; - } - } - } - - if (needUpdateWidthViaSelection) { - // Get the width of the selection to update cursor width. - cursorWidth = getTextWidthWithinTextLine(layout, cursorPosition, deltaPosition); - if (cursorWidth < m_cursorWidth) { - cursorWidth = m_cursorWidth; - } - } - - if (cursorWidth != m_lastCursorBlockWidth) { - m_lastCursorBlockWidth = cursorWidth; - emit cursorBlockWidthUpdated(m_lastCursorBlockWidth); - } - - Q_ASSERT(cursorWidth > 0); - } - - // Draw cursor line block. - if (m_highlightCursorLineBlock - && m_cursorLineBlockNumber == block.blockNumber()) { - int x = offset.x(); - int y = offset.y(); - fillBackground(p_painter, - rect.adjusted(x, y, x, y), - m_cursorLineBlockBg); - } - - layout->draw(p_painter, - offset, - selections, - p_context.clip.isValid() ? p_context.clip : QRectF()); - - drawImages(p_painter, block, offset); - - drawMarkers(p_painter, block, offset); - - if (drawCursor - || (p_context.cursorPosition < -1 - && !layout->preeditAreaText().isEmpty())) { - if (p_context.cursorPosition < -1) { - cursorPosition = layout->preeditAreaPosition() - - (p_context.cursorPosition + 2); - } - - layout->drawCursor(p_painter, - offset, - cursorPosition, - cursorWidth); - } - - offset.ry() += rect.height(); - if (block == lastBlock) { - break; - } - - block = block.next(); - } - - p_painter->setPen(oldPen); -} - -QVector VTextDocumentLayout::formatRangeFromSelection(const QTextBlock &p_block, - const QVector &p_selections) const -{ - QVector ret; - - int blpos = p_block.position(); - int bllen = p_block.length(); - for (int i = 0; i < p_selections.size(); ++i) { - const QAbstractTextDocumentLayout::Selection &range = p_selections.at(i); - const int selStart = range.cursor.selectionStart() - blpos; - const int selEnd = range.cursor.selectionEnd() - blpos; - if (selStart < bllen - && selEnd > 0 - && selEnd > selStart) { - QTextLayout::FormatRange o; - o.start = selStart; - o.length = selEnd - selStart; - o.format = range.format; - ret.append(o); - } else if (!range.cursor.hasSelection() - && range.format.hasProperty(QTextFormat::FullWidthSelection) - && p_block.contains(range.cursor.position())) { - // For full width selections we don't require an actual selection, just - // a position to specify the line. that's more convenience in usage. - QTextLayout::FormatRange o; - QTextLine l = p_block.layout()->lineForTextPosition(range.cursor.position() - blpos); - V_ASSERT(l.isValid()); - o.start = l.textStart(); - o.length = l.textLength(); - if (o.start + o.length == bllen - 1) { - ++o.length; // include newline - } - - o.format = range.format; - ret.append(o); - } - } - - return ret; -} - -int VTextDocumentLayout::hitTest(const QPointF &p_point, Qt::HitTestAccuracy p_accuracy) const -{ - Q_UNUSED(p_accuracy); - int bn = findBlockByPosition(p_point); - if (bn == -1) { - return -1; - } - - QTextBlock block = document()->findBlockByNumber(bn); - V_ASSERT(block.isValid()); - QTextLayout *layout = block.layout(); - int off = 0; - QPointF pos = p_point - QPointF(m_margin, VTextBlockData::layoutInfo(block)->top()); - for (int i = 0; i < layout->lineCount(); ++i) { - QTextLine line = layout->lineAt(i); - const QRectF lr = line.naturalTextRect(); - if (lr.top() > pos.y()) { - off = qMin(off, line.textStart()); - } else if (lr.bottom() <= pos.y()) { - off = qMax(off, line.textStart() + line.textLength()); - } else { - off = line.xToCursor(pos.x(), QTextLine::CursorBetweenCharacters); - break; - } - } - - return block.position() + off; -} - -int VTextDocumentLayout::pageCount() const -{ - return 1; -} - -QSizeF VTextDocumentLayout::documentSize() const -{ - return QSizeF(m_width, m_height + m_extraBufferHeight); -} - -QRectF VTextDocumentLayout::frameBoundingRect(QTextFrame *p_frame) const -{ - Q_UNUSED(p_frame); - return QRectF(0, 0, - qMax(document()->pageSize().width(), m_width), qreal(INT_MAX)); -} - -// Sometimes blockBoundingRect() may be called before documentChanged(). -QRectF VTextDocumentLayout::blockBoundingRect(const QTextBlock &p_block) const -{ - if (!p_block.isValid()) { - return QRectF(); - } - - const BlockLayoutInfo *info = VTextBlockData::layoutInfo(p_block); - if (!info->hasOffset()) { - if (info->isNull()) { - const_cast(this)->layoutBlockAndUpdateOffset(p_block); - } else { - const_cast(this)->updateOffset(p_block); - } - } - - QRectF geo = info->m_rect.adjusted(0, info->m_offset, 0, info->m_offset); - return geo; -} - -void VTextDocumentLayout::documentChanged(int p_from, int p_charsRemoved, int p_charsAdded) -{ - QTextDocument *doc = document(); - int newBlockCount = doc->blockCount(); - - // Update the margin. - m_margin = doc->documentMargin(); - - int charsChanged = p_charsRemoved + p_charsAdded; - - QTextBlock changeStartBlock = doc->findBlock(p_from); - // May be an invalid block. - QTextBlock changeEndBlock; - if (p_charsRemoved == p_charsAdded - && newBlockCount == m_blockCount - && changeStartBlock.position() == p_from - && changeStartBlock.length() == p_charsAdded) { - // TODO: we may need one more next block. - changeEndBlock = changeStartBlock; - } else { - changeEndBlock = doc->findBlock(p_from + charsChanged); - } - - /* - qDebug() << "documentChanged" << p_from << p_charsRemoved << p_charsAdded - << m_blockCount << newBlockCount - << changeStartBlock.blockNumber() << changeEndBlock.blockNumber(); - */ - - bool needRelayout = true; - if (changeStartBlock == changeEndBlock - && newBlockCount == m_blockCount) { - // Change single block internal only. - QTextBlock block = changeStartBlock; - if (block.isValid() && block.length()) { - needRelayout = false; - QRectF oldBr = blockBoundingRect(block); - clearBlockLayout(block); - layoutBlockAndUpdateOffset(block); - QRectF newBr = blockBoundingRect(block); - // Only one block is affected. - if (newBr.height() == oldBr.height()) { - // Update document size. - updateDocumentSizeWithOneBlockChanged(block); - - emit updateBlock(block); - return; - } - } - } - - if (needRelayout) { - QTextBlock block = changeStartBlock; - do { - clearBlockLayout(block); - layoutBlock(block); - if (block == changeEndBlock) { - break; - } - - block = block.next(); - } while(block.isValid()); - - updateOffset(changeStartBlock); - } - - m_blockCount = newBlockCount; - - updateDocumentSize(); - - // TODO: Update the view of all the blocks after changeStartBlock. - qreal offset = VTextBlockData::layoutInfo(changeStartBlock)->m_offset; - emit update(QRectF(0., offset, 1000000000., 1000000000.)); -} - -// MUST layout out the block after clearBlockLayout(). -// TODO: Do we need to clear all the offset after @p_block? -void VTextDocumentLayout::clearBlockLayout(QTextBlock &p_block) -{ - p_block.clearLayout(); - BlockLayoutInfo *info = VTextBlockData::layoutInfo(p_block); - info->reset(); -} - -// From Qt's qguiapplication_p.h. -static Qt::Alignment visualAlignment(Qt::LayoutDirection p_direction, - Qt::Alignment p_alignment) -{ - if (!(p_alignment & Qt::AlignHorizontal_Mask)) { - p_alignment |= Qt::AlignLeft; - } - - if (!(p_alignment & Qt::AlignAbsolute) - && (p_alignment & (Qt::AlignLeft | Qt::AlignRight))) { - if (p_direction == Qt::RightToLeft) { - p_alignment ^= (Qt::AlignLeft | Qt::AlignRight); - } - - p_alignment |= Qt::AlignAbsolute; - } - - return p_alignment; -} - -void VTextDocumentLayout::layoutBlock(const QTextBlock &p_block) -{ - QTextDocument *doc = document(); - V_ASSERT(m_margin == doc->documentMargin()); - - QTextLayout *tl = p_block.layout(); - QTextOption option = doc->defaultTextOption(); - - { - auto direction = p_block.textDirection(); - option.setTextDirection(direction); - - auto alignment = option.alignment(); - QTextBlockFormat blockFormat = p_block.blockFormat(); - if (blockFormat.hasProperty(QTextFormat::BlockAlignment)) { - alignment = blockFormat.alignment(); - } - - // For paragraph that are RTL, alignment is auto-reversed. - option.setAlignment(visualAlignment(direction, alignment)); - } - - tl->setTextOption(option); - - int extraMargin = 0; - if (option.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) { - QFontMetrics fm(p_block.charFormat().font()); - extraMargin += fm.width(QChar(0x21B5)); - } - - qreal availableWidth = doc->pageSize().width(); - if (availableWidth <= 0) { - availableWidth = qreal(INT_MAX); - } - - availableWidth -= (2 * m_margin + extraMargin + m_cursorMargin + m_cursorWidth); - - QVector markers; - QVector images; - - layoutLines(p_block, tl, markers, images, availableWidth, 0); - - // Set this block's line count to its layout's line count. - // That is one block may occupy multiple visual lines. - const_cast(p_block).setLineCount(p_block.isVisible() ? tl->lineCount() : 0); - - // Update the info about this block. - finishBlockLayout(p_block, markers, images); -} - -void VTextDocumentLayout::updateOffsetBefore(const QTextBlock &p_block) -{ - BlockLayoutInfo *info = VTextBlockData::layoutInfo(p_block); - V_ASSERT(!info->isNull()); - - const int blockNum = p_block.blockNumber(); - if (blockNum == 0) { - info->m_offset = 0; - } else { - QTextBlock blk = p_block.previous(); - while (blk.isValid()) { - BlockLayoutInfo *pinfo = VTextBlockData::layoutInfo(blk); - if (!pinfo->hasOffset()) { - int num = blk.blockNumber(); - if (pinfo->isNull()) { - layoutBlock(blk); - } - - if (num == 0) { - pinfo->m_offset = 0; - } else { - blk = blk.previous(); - continue; - } - } - - // Now we reach a block with offset. - qreal offset = pinfo->bottom(); - blk = blk.next(); - while (blk.isValid() && blk.blockNumber() <= blockNum) { - BlockLayoutInfo *ninfo = VTextBlockData::layoutInfo(blk); - V_ASSERT(!ninfo->isNull()); - ninfo->m_offset = offset; - offset = ninfo->bottom(); - blk = blk.next(); - } - - break; - } - - V_ASSERT(info->hasOffset()); - } -} - -// NOTICE: It will skip non-layouted or offset-non-changed blocks. -// So if you relayout separated blocks, you need to updateOffsetAfter() for each of them. -void VTextDocumentLayout::updateOffsetAfter(const QTextBlock &p_block) -{ - BlockLayoutInfo *info = VTextBlockData::layoutInfo(p_block); - V_ASSERT(info->hasOffset()); - qreal offset = info->bottom(); - QTextBlock blk = p_block.next(); - while (blk.isValid()) { - BlockLayoutInfo *ninfo = VTextBlockData::layoutInfo(blk); - if (ninfo->isNull()) { - break; - } - - if (realEqual(ninfo->m_offset, offset)) { - break; - } - - ninfo->m_offset = offset; - offset = ninfo->bottom(); - blk = blk.next(); - } -} - -qreal VTextDocumentLayout::layoutLines(const QTextBlock &p_block, - QTextLayout *p_tl, - QVector &p_markers, - QVector &p_images, - qreal p_availableWidth, - qreal p_height) -{ - V_ASSERT(p_block.isValid()); - - // Handle block inline image. - bool hasInlineImages = false; - const QVector *info = NULL; - if (m_blockImageEnabled) { - VTextBlockData *blockData = VTextBlockData::blockData(p_block); - info = &(blockData->getPreviews()); - if (!info->isEmpty() - && info->first()->m_imageInfo.m_inline) { - hasInlineImages = true; - } - } - - p_tl->beginLayout(); - - int imgIdx = 0; - - while (true) { - QTextLine line = p_tl->createLine(); - if (!line.isValid()) { - break; - } - - // Will introduce extra space on macOS. - // line.setLeadingIncluded(true); - line.setLineWidth(p_availableWidth); - p_height += m_lineLeading; - - if (hasInlineImages) { - QVector images; - QVector> imageRange; - qreal imgHeight = fetchInlineImagesForOneLine(*info, - &line, - m_margin, - imgIdx, - images, - imageRange); - - for (int i = 0; i < images.size(); ++i) { - layoutInlineImage(images[i], - p_height, - imgHeight, - imageRange[i].first, - imageRange[i].second, - p_markers, - p_images); - } - - if (!images.isEmpty()) { - p_height += imgHeight + MARKER_THICKNESS + MARKER_THICKNESS; - } - } - - line.setPosition(QPointF(m_margin, p_height)); - p_height += line.height(); - } - - p_tl->endLayout(); - - return p_height; -} - -void VTextDocumentLayout::layoutInlineImage(const VPreviewedImageInfo *p_info, - qreal p_heightInBlock, - qreal p_imageSpaceHeight, - qreal p_xStart, - qreal p_xEnd, - QVector &p_markers, - QVector &p_images) -{ - Marker mk; - qreal mky = p_imageSpaceHeight + p_heightInBlock + MARKER_THICKNESS; - mk.m_start = QPointF(p_xStart, mky); - mk.m_end = QPointF(p_xEnd, mky); - p_markers.append(mk); - - if (p_info) { - QSize size = p_info->m_imageSize; - scaleSize(size, p_xEnd - p_xStart, p_imageSpaceHeight); - - ImagePaintInfo ipi; - ipi.m_name = p_info->m_imageName; - ipi.m_rect = QRectF(QPointF(p_xStart, - p_heightInBlock + p_imageSpaceHeight - size.height()), - size); - if (!p_info->m_background.isEmpty()) { - ipi.m_background = QColor(p_info->m_background); - } - - p_images.append(ipi); - } -} - -void VTextDocumentLayout::finishBlockLayout(const QTextBlock &p_block, - const QVector &p_markers, - const QVector &p_images) -{ - V_ASSERT(p_block.isValid()); - ImagePaintInfo ipi; - BlockLayoutInfo *info = VTextBlockData::layoutInfo(p_block); - V_ASSERT(info->isNull()); - info->reset(); - info->m_rect = blockRectFromTextLayout(p_block, &ipi); - V_ASSERT(!info->m_rect.isNull()); - - bool hasImage = false; - if (ipi.isValid()) { - V_ASSERT(p_markers.isEmpty()); - V_ASSERT(p_images.isEmpty()); - info->m_images.append(ipi); - hasImage = true; - } else if (!p_markers.isEmpty()) { - info->m_markers = p_markers; - info->m_images = p_images; - hasImage = true; - } - - // Add vertical marker. - if (hasImage) { - // Fill the marker. - // Will be adjusted using offset. - Marker mk; - mk.m_start = QPointF(-1, 0); - mk.m_end = QPointF(-1, info->m_rect.height()); - - info->m_markers.append(mk); - } -} - -void VTextDocumentLayout::updateDocumentSize() -{ - QTextBlock block = document()->lastBlock(); - const BlockLayoutInfo *info = VTextBlockData::layoutInfo(block); - if (!info->hasOffset()) { - if (info->isNull()) { - layoutBlock(block); - } - - updateOffsetBefore(block); - } - - int oldHeight = m_height; - int oldWidth = m_width; - - m_height = info->bottom(); - - m_width = 0; - QTextBlock blk = document()->firstBlock(); - while (blk.isValid()) { - const BlockLayoutInfo *ninfo = VTextBlockData::layoutInfo(blk); - V_ASSERT(ninfo->hasOffset()); - if (m_width < ninfo->m_rect.width()) { - m_width = ninfo->m_rect.width(); - m_maximumWidthBlockNumber = blk.blockNumber(); - } - - blk = blk.next(); - } - - if (oldHeight != m_height - || oldWidth != m_width) { - emit documentSizeChanged(documentSize()); - } -} - -QRectF VTextDocumentLayout::blockRectFromTextLayout(const QTextBlock &p_block, - ImagePaintInfo *p_image) -{ - if (p_image) { - *p_image = ImagePaintInfo(); - } - - QTextLayout *tl = p_block.layout(); - if (tl->lineCount() < 1) { - return QRectF(); - } - - QRectF tlRect = tl->boundingRect(); - QRectF br(QPointF(0, 0), tlRect.bottomRight()); - - // Do not know why. Copied from QPlainTextDocumentLayout. - if (tl->lineCount() == 1) { - br.setWidth(qMax(br.width(), tl->lineAt(0).naturalTextWidth())); - } - - // Handle block non-inline image. - if (m_blockImageEnabled) { - VTextBlockData *blockData = VTextBlockData::blockData(p_block); - V_ASSERT(blockData); - const QVector &info = blockData->getPreviews(); - if (info.size() == 1) { - const VPreviewedImageInfo& img = info.first()->m_imageInfo; - if (!img.m_inline) { - int maximumWidth = tlRect.width(); - int padding; - QSize size; - adjustImagePaddingAndSize(&img, maximumWidth, padding, size); - - if (p_image) { - p_image->m_name = img.m_imageName; - p_image->m_rect = QRectF(padding + m_margin, - br.height() + m_lineLeading, - size.width(), - size.height()); - if (!img.m_background.isEmpty()) { - p_image->m_background = QColor(img.m_background); - } - } - - int dw = padding + size.width() + m_margin - br.width(); - int dh = size.height() + m_lineLeading; - br.adjust(0, 0, dw > 0 ? dw : 0, dh); - } - } - } - - br.adjust(0, 0, m_margin + m_cursorWidth, 0); - - // Add bottom margin. - if (!p_block.next().isValid()) { - br.adjust(0, 0, 0, m_margin); - } - - return br; -} - -void VTextDocumentLayout::updateDocumentSizeWithOneBlockChanged(const QTextBlock &p_block) -{ - const BlockLayoutInfo *info = VTextBlockData::layoutInfo(p_block); - qreal width = info->m_rect.width(); - if (width > m_width) { - m_width = width; - m_maximumWidthBlockNumber = p_block.blockNumber(); - emit documentSizeChanged(documentSize()); - } else if (width < m_width && p_block.blockNumber() == m_maximumWidthBlockNumber) { - // Shrink the longest block. - updateDocumentSize(); - } -} - -void VTextDocumentLayout::setLineLeading(qreal p_leading) -{ - if (p_leading >= 0) { - m_lineLeading = p_leading; - } -} - -void VTextDocumentLayout::setImageWidthConstrainted(bool p_enabled) -{ - if (m_imageWidthConstrainted == p_enabled) { - return; - } - - m_imageWidthConstrainted = p_enabled; - relayout(); -} - -void VTextDocumentLayout::setBlockImageEnabled(bool p_enabled) -{ - if (m_blockImageEnabled == p_enabled) { - return; - } - - m_blockImageEnabled = p_enabled; - relayout(); -} - -void VTextDocumentLayout::adjustImagePaddingAndSize(const VPreviewedImageInfo *p_info, - int p_maximumWidth, - int &p_padding, - QSize &p_size) const -{ - const int minimumImageWidth = 400; - - p_padding = p_info->m_padding; - p_size = p_info->m_imageSize; - - if (!m_imageWidthConstrainted) { - return; - } - - int availableWidth = p_maximumWidth - p_info->m_padding; - if (availableWidth < p_info->m_imageSize.width()) { - // Need to resize the width. - if (availableWidth >= minimumImageWidth) { - p_size.scale(availableWidth, p_size.height(), Qt::KeepAspectRatio); - } else { - // Omit the padding. - p_padding = 0; - p_size.scale(p_maximumWidth, p_size.height(), Qt::KeepAspectRatio); - } - } -} - -void VTextDocumentLayout::drawImages(QPainter *p_painter, - const QTextBlock &p_block, - const QPointF &p_offset) -{ - const QVector &images = VTextBlockData::layoutInfo(p_block)->m_images; - if (images.isEmpty()) { - return; - } - - for (auto const & img : images) { - const QPixmap *image = m_imageMgr->findImage(img.m_name); - if (!image) { - continue; - } - - QRect targetRect = img.m_rect.adjusted(p_offset.x(), - p_offset.y(), - p_offset.x(), - p_offset.y()).toRect(); - - // Qt do not render the background of some SVGs. - // We add a forced background mechanism to complement this. - if (img.hasForcedBackground()) { - p_painter->fillRect(targetRect, img.m_background); - } - - p_painter->drawPixmap(targetRect, *image); - } -} - - -void VTextDocumentLayout::drawMarkers(QPainter *p_painter, - const QTextBlock &p_block, - const QPointF &p_offset) -{ - const QVector &markers = VTextBlockData::layoutInfo(p_block)->m_markers; - if (markers.isEmpty()) { - return; - } - - QPen oldPen = p_painter->pen(); - QPen newPen(m_imageLineColor, MARKER_THICKNESS, Qt::DashLine); - p_painter->setPen(newPen); - - for (auto const & mk : markers) { - p_painter->drawLine(mk.m_start + p_offset, mk.m_end + p_offset); - } - - p_painter->setPen(oldPen); -} - -void VTextDocumentLayout::relayout() -{ - QTextDocument *doc = document(); - - // Update the margin. - m_margin = doc->documentMargin(); - - QTextBlock block = doc->firstBlock(); - while (block.isValid()) { - clearBlockLayout(block); - layoutBlock(block); - - block = block.next(); - } - - updateOffset(doc->firstBlock()); - - updateDocumentSize(); - - emit update(QRectF(0., 0., 1000000000., 1000000000.)); -} - -void VTextDocumentLayout::relayout(const OrderedIntSet &p_blocks) -{ - if (p_blocks.isEmpty()) { - return; - } - - QTextDocument *doc = document(); - - // Need to relayout and update blocks in ascending order. - QVector blocks; - blocks.reserve(p_blocks.size()); - for (auto bn = p_blocks.keyBegin(); bn != p_blocks.keyEnd(); ++bn) { - QTextBlock block = doc->findBlockByNumber(*bn); - if (block.isValid()) { - blocks.append(block); - clearBlockLayout(block); - layoutBlock(block); - } - } - - if (blocks.isEmpty()) { - return; - } - - // Need to update offset for each of these discontinuous blocks, because - // the offset of the non-touched blocks may be the same but there are still - // touched blocks after them. - for (auto & blk : blocks) { - updateOffset(blk); - } - - updateDocumentSize(); - - qreal offset = VTextBlockData::layoutInfo(blocks.first())->m_offset; - emit update(QRectF(0., offset, 1000000000., 1000000000.)); -} - -qreal VTextDocumentLayout::fetchInlineImagesForOneLine(const QVector &p_info, - const QTextLine *p_line, - qreal p_margin, - int &p_index, - QVector &p_images, - QVector> &p_imageRange) -{ - qreal maxHeight = 0; - int start = p_line->textStart(); - int end = p_line->textLength() + start; - - for (int i = 0; i < p_info.size(); ++i) { - const VPreviewedImageInfo &img = p_info[i]->m_imageInfo; - V_ASSERT(img.m_inline); - - if (img.m_startPos >= start && img.m_startPos < end) { - // Start of a new image. - qreal startX = p_line->cursorToX(img.m_startPos) + p_margin; - qreal endX; - if (img.m_endPos <= end) { - // End an image. - endX = p_line->cursorToX(img.m_endPos) + p_margin; - p_images.append(&img); - p_imageRange.append(QPair(startX, endX)); - - QSize size = img.m_imageSize; - scaleSize(size, endX - startX, MAX_INLINE_IMAGE_HEIGHT); - if (size.height() > maxHeight) { - maxHeight = size.height(); - } - - // Image i has been drawn. - p_index = i + 1; - } else { - // This image cross the line. - endX = p_line->x() + p_line->width() + p_margin; - if (end - img.m_startPos >= ((img.m_endPos - img.m_startPos) >> 1)) { - // Put image at this side. - p_images.append(&img); - p_imageRange.append(QPair(startX, endX)); - - QSize size = img.m_imageSize; - scaleSize(size, endX - startX, MAX_INLINE_IMAGE_HEIGHT); - if (size.height() > maxHeight) { - maxHeight = size.height(); - } - - // Image i has been drawn. - p_index = i + 1; - } else { - // Just put a marker here. - p_images.append(NULL); - p_imageRange.append(QPair(startX, endX)); - } - - break; - } - } else if (img.m_endPos > start && img.m_startPos < start) { - qreal startX = p_line->x() + p_margin; - qreal endX = img.m_endPos > end ? p_line->x() + p_line->width() - : p_line->cursorToX(img.m_endPos); - if (p_index <= i) { - // Image i has not been drawn. Draw it here. - p_images.append(&img); - p_imageRange.append(QPair(startX, endX)); - - QSize size = img.m_imageSize; - scaleSize(size, endX - startX, MAX_INLINE_IMAGE_HEIGHT); - if (size.height() > maxHeight) { - maxHeight = size.height(); - } - - // Image i has been drawn. - p_index = i + 1; - } else { - // Image i has been drawn. Just put a marker here. - p_images.append(NULL); - p_imageRange.append(QPair(startX, endX)); - } - - if (img.m_endPos >= end) { - break; - } - } else if (img.m_endPos <= start) { - continue; - } else { - break; - } - } - - return maxHeight; -} - -int VTextDocumentLayout::getTextWidthWithinTextLine(const QTextLayout *p_layout, - int p_pos, - int p_length) -{ - QTextLine line = p_layout->lineForTextPosition(p_pos); - V_ASSERT(line.isValid()); - V_ASSERT(p_pos + p_length <= line.textStart() + line.textLength()); - V_ASSERT(p_pos + p_length >= 0); - return qAbs(line.cursorToX(p_pos + p_length) - line.cursorToX(p_pos)); -} - -void VTextDocumentLayout::updateBlockByNumber(int p_blockNumber) -{ - if (p_blockNumber == -1) { - return; - } - - QTextBlock block = document()->findBlockByNumber(p_blockNumber); - if (block.isValid()) { - emit updateBlock(block); - } -} diff --git a/src/vtextdocumentlayout.h b/src/vtextdocumentlayout.h deleted file mode 100644 index f84055b9..00000000 --- a/src/vtextdocumentlayout.h +++ /dev/null @@ -1,343 +0,0 @@ -#ifndef VTEXTDOCUMENTLAYOUT_H -#define VTEXTDOCUMENTLAYOUT_H - -#include -#include -#include -#include - -#include "vconstants.h" -#include "vtextdocumentlayoutdata.h" - -class VImageResourceManager2; -struct VPreviewedImageInfo; -struct VPreviewInfo; - -struct QMapDummyValue -{ -}; - -typedef QMap OrderedIntSet; - -class VTextDocumentLayout : public QAbstractTextDocumentLayout -{ - Q_OBJECT -public: - VTextDocumentLayout(QTextDocument *p_doc, - VImageResourceManager2 *p_imageMgr); - - void draw(QPainter *p_painter, const PaintContext &p_context) Q_DECL_OVERRIDE; - - int hitTest(const QPointF &p_point, Qt::HitTestAccuracy p_accuracy) const Q_DECL_OVERRIDE; - - int pageCount() const Q_DECL_OVERRIDE; - - QSizeF documentSize() const Q_DECL_OVERRIDE; - - QRectF frameBoundingRect(QTextFrame *p_frame) const Q_DECL_OVERRIDE; - - QRectF blockBoundingRect(const QTextBlock &p_block) const Q_DECL_OVERRIDE; - - void setCursorWidth(int p_width); - - int cursorWidth() const; - - void setLineLeading(qreal p_leading); - - qreal getLineLeading() const; - - // Return the block number which contains point @p_point. - // If @p_point is at the border, returns the block below. - int findBlockByPosition(const QPointF &p_point) const; - - void setImageWidthConstrainted(bool p_enabled); - - void setBlockImageEnabled(bool p_enabled); - - // Relayout all the blocks. - void relayout(); - - // Relayout @p_blocks. - void relayout(const OrderedIntSet &p_blocks); - - void setImageLineColor(const QColor &p_color); - - void setCursorBlockMode(CursorBlock p_mode); - - void setVirtualCursorBlockWidth(int p_width); - - void clearLastCursorBlockWidth(); - - void setHighlightCursorLineBlockEnabled(bool p_enabled); - - void setCursorLineBlockBg(const QColor &p_bg); - - void setCursorLineBlockNumber(int p_blockNumber); - - // Request update block by block number. - void updateBlockByNumber(int p_blockNumber); - - void setExtraBufferHeight(int p_height); - -signals: - // Emit to update current cursor block width if m_cursorBlockMode is enabled. - void cursorBlockWidthUpdated(int p_width); - -protected: - void documentChanged(int p_from, int p_charsRemoved, int p_charsAdded) Q_DECL_OVERRIDE; - -private: - // Layout one block. - // Only update the rect of the block. Offset is not updated yet. - void layoutBlock(const QTextBlock &p_block); - - // Update the offset of @p_block. - // @p_block has a valid layout. - // After the call, all block before @p_block will have the correct layout and offset. - void updateOffsetBefore(const QTextBlock &p_block); - - // Update the offset of blocks after @p_block if they are layouted. - void updateOffsetAfter(const QTextBlock &p_block); - - void updateOffset(const QTextBlock &p_block); - - void layoutBlockAndUpdateOffset(const QTextBlock &p_block); - - // Returns the total height of this block after layouting lines and inline - // images. - qreal layoutLines(const QTextBlock &p_block, - QTextLayout *p_tl, - QVector &p_markers, - QVector &p_images, - qreal p_availableWidth, - qreal p_height); - - // Layout inline image in a line. - // @p_info: if NULL, means just layout a marker. - // Returns the image height. - void layoutInlineImage(const VPreviewedImageInfo *p_info, - qreal p_heightInBlock, - qreal p_imageSpaceHeight, - qreal p_xStart, - qreal p_xEnd, - QVector &p_markers, - QVector &p_images); - - // Get inline images belonging to @p_line from @p_info. - // @p_index: image [0, p_index) has been drawn. - // @p_images: contains all images and markers (NULL element indicates it - // is just a placeholder for the marker. - // Returns the maximum height of the images. - qreal fetchInlineImagesForOneLine(const QVector &p_info, - const QTextLine *p_line, - qreal p_margin, - int &p_index, - QVector &p_images, - QVector> &p_imageRange); - - // Clear the layout of @p_block. - // Also clear all the offset behind this block. - void clearBlockLayout(QTextBlock &p_block); - - // Update rect of a block. - void finishBlockLayout(const QTextBlock &p_block, - const QVector &p_markers, - const QVector &p_images); - - void updateDocumentSize(); - - QVector formatRangeFromSelection(const QTextBlock &p_block, - const QVector &p_selections) const; - - // Get the block range [first, last] by rect @p_rect. - // @p_rect: a clip region in document coordinates. If null, returns all the blocks. - // Return [-1, -1] if no valid block range found. - void blockRangeFromRect(const QRectF &p_rect, int &p_first, int &p_last) const; - - // Binary search to get the block range [first, last] by @p_rect. - void blockRangeFromRectBS(const QRectF &p_rect, int &p_first, int &p_last) const; - - // Return a rect from the layout. - // If @p_imageRect is not NULL and there is block image for this block, it will - // be set to the rect of that image. - // Return a null rect if @p_block has not been layouted. - QRectF blockRectFromTextLayout(const QTextBlock &p_block, - ImagePaintInfo *p_image = NULL); - - // Update document size when only @p_block is changed and the height - // remains the same. - void updateDocumentSizeWithOneBlockChanged(const QTextBlock &p_block); - - void adjustImagePaddingAndSize(const VPreviewedImageInfo *p_info, - int p_maximumWidth, - int &p_padding, - QSize &p_size) const; - - // Draw images of block @p_block. - // @p_offset: the offset for the drawing of the block. - void drawImages(QPainter *p_painter, - const QTextBlock &p_block, - const QPointF &p_offset); - - void drawMarkers(QPainter *p_painter, - const QTextBlock &p_block, - const QPointF &p_offset); - - void scaleSize(QSize &p_size, int p_width, int p_height); - - // Get text length in pixel. - // @p_pos: position within the layout. - int getTextWidthWithinTextLine(const QTextLayout *p_layout, int p_pos, int p_length); - - // Document margin on left/right/bottom. - qreal m_margin; - - // Maximum width of the contents. - qreal m_width; - - // The block number of the block which contains the m_width. - int m_maximumWidthBlockNumber; - - // Height of all the document (all the blocks, excluding m_extraBufferHeight). - qreal m_height; - - // Set the leading space of a line. - qreal m_lineLeading; - - // Block count of the document. - int m_blockCount; - - // Width of the cursor. - int m_cursorWidth; - - // Right margin for cursor. - qreal m_cursorMargin; - - VImageResourceManager2 *m_imageMgr; - - bool m_blockImageEnabled; - - // Whether constraint the width of image to the width of the page. - bool m_imageWidthConstrainted; - - // Color of the image line. - QColor m_imageLineColor; - - // Draw cursor as block. - CursorBlock m_cursorBlockMode; - - // Virtual cursor block: cursor block on no character. - int m_virtualCursorBlockWidth; - - int m_lastCursorBlockWidth; - - // Whether highlight the block containing the cursor line. - bool m_highlightCursorLineBlock; - - // The cursor line's block background color. - QColor m_cursorLineBlockBg; - - // The block containing the cursor. - int m_cursorLineBlockNumber; - - // Extra buffer height in document size. - int m_extraBufferHeight; -}; - -inline qreal VTextDocumentLayout::getLineLeading() const -{ - return m_lineLeading; -} - -inline void VTextDocumentLayout::setImageLineColor(const QColor &p_color) -{ - m_imageLineColor = p_color; -} - -inline void VTextDocumentLayout::scaleSize(QSize &p_size, int p_width, int p_height) -{ - if (p_size.width() > p_width || p_size.height() > p_height) { - p_size.scale(p_width, p_height, Qt::KeepAspectRatio); - } -} - -inline void VTextDocumentLayout::setCursorBlockMode(CursorBlock p_mode) -{ - m_cursorBlockMode = p_mode; -} - -inline void VTextDocumentLayout::setVirtualCursorBlockWidth(int p_width) -{ - m_virtualCursorBlockWidth = p_width; -} - -inline void VTextDocumentLayout::clearLastCursorBlockWidth() -{ - m_lastCursorBlockWidth = -1; -} - -inline void VTextDocumentLayout::setHighlightCursorLineBlockEnabled(bool p_enabled) -{ - if (m_highlightCursorLineBlock != p_enabled) { - m_highlightCursorLineBlock = p_enabled; - if (!m_highlightCursorLineBlock) { - int pre = m_cursorLineBlockNumber; - m_cursorLineBlockNumber = -1; - updateBlockByNumber(pre); - } - } -} - -inline void VTextDocumentLayout::setCursorLineBlockBg(const QColor &p_bg) -{ - if (p_bg != m_cursorLineBlockBg) { - m_cursorLineBlockBg = p_bg; - updateBlockByNumber(m_cursorLineBlockNumber); - } -} - -inline void VTextDocumentLayout::setCursorLineBlockNumber(int p_blockNumber) -{ - if (p_blockNumber != m_cursorLineBlockNumber) { - int pre = m_cursorLineBlockNumber; - m_cursorLineBlockNumber = p_blockNumber; - - if (m_highlightCursorLineBlock) { - updateBlockByNumber(pre); - updateBlockByNumber(m_cursorLineBlockNumber); - } - } -} - -inline void VTextDocumentLayout::setCursorWidth(int p_width) -{ - m_cursorWidth = p_width; -} - -inline int VTextDocumentLayout::cursorWidth() const -{ - return m_cursorWidth; -} - -inline void VTextDocumentLayout::layoutBlockAndUpdateOffset(const QTextBlock &p_block) -{ - layoutBlock(p_block); - updateOffset(p_block); -} - -inline void VTextDocumentLayout::updateOffset(const QTextBlock &p_block) -{ - updateOffsetBefore(p_block); - updateOffsetAfter(p_block); -} - -inline void VTextDocumentLayout::setExtraBufferHeight(int p_height) -{ - if (m_extraBufferHeight == p_height) { - return; - } - - m_extraBufferHeight = p_height; - emit documentSizeChanged(documentSize()); -} -#endif // VTEXTDOCUMENTLAYOUT_H diff --git a/src/vtextdocumentlayoutdata.h b/src/vtextdocumentlayoutdata.h deleted file mode 100644 index 71b7e4ec..00000000 --- a/src/vtextdocumentlayoutdata.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef VTEXTDOCUMENTLAYOUTDATA_H -#define VTEXTDOCUMENTLAYOUTDATA_H - -#include "utils/vutils.h" - -// Denote the start and end position of a marker line. -struct Marker -{ - QPointF m_start; - QPointF m_end; -}; - -struct ImagePaintInfo -{ - // The rect to draw the image. - QRectF m_rect; - - // Name of the image. - QString m_name; - - // Forced background. - QColor m_background; - - bool isValid() const - { - return !m_name.isEmpty(); - } - - bool hasForcedBackground() const - { - return m_background.isValid(); - } -}; - -struct BlockLayoutInfo -{ - BlockLayoutInfo() - : m_offset(-1) - { - } - - void reset() - { - m_offset = -1; - m_rect = QRectF(); - m_markers.clear(); - m_images.clear(); - } - - bool isNull() const - { - return m_rect.isNull(); - } - - bool hasOffset() const - { - return m_offset > -1 && !m_rect.isNull(); - } - - qreal top() const - { - V_ASSERT(hasOffset()); - return m_offset; - } - - qreal bottom() const - { - V_ASSERT(hasOffset()); - return m_offset + m_rect.height(); - } - - // Y offset of this block. - // -1 for invalid. - qreal m_offset; - - // The bounding rect of this block, including the margins. - // Null for invalid. - QRectF m_rect; - - // Markers to draw for this block. - // Y is the offset within this block. - QVector m_markers; - - // Images to draw for this block. - // Y is the offset within this block. - QVector m_images; -}; -#endif // VTEXTDOCUMENTLAYOUTDATA_H diff --git a/src/vtextedit.cpp b/src/vtextedit.cpp deleted file mode 100644 index 175f7989..00000000 --- a/src/vtextedit.cpp +++ /dev/null @@ -1,481 +0,0 @@ -#include "vtextedit.h" - -#include -#include -#include -#include - -#include "vimageresourcemanager2.h" - -#define VIRTUAL_CURSOR_BLOCK_WIDTH 8 - -enum class BlockState -{ - Normal = 0, - CodeBlockStart, - CodeBlock, - CodeBlockEnd, - Comment -}; - - -VTextEdit::VTextEdit(QWidget *p_parent) - : QTextEdit(p_parent), - m_imageMgr(nullptr) -{ - init(); -} - -VTextEdit::VTextEdit(const QString &p_text, QWidget *p_parent) - : QTextEdit(p_text, p_parent), - m_imageMgr(nullptr) -{ - init(); -} - -VTextEdit::~VTextEdit() -{ - delete m_imageMgr; -} - -void VTextEdit::init() -{ - setAcceptRichText(false); - - m_defaultCursorWidth = 1; - - m_lineNumberType = LineNumberType::None; - - m_blockImageEnabled = false; - - m_cursorBlockMode = CursorBlock::None; - - m_highlightCursorLineBlock = false; - - m_enableExtraBuffer = false; - - m_imageMgr = new VImageResourceManager2(); - - QTextDocument *doc = document(); - VTextDocumentLayout *docLayout = new VTextDocumentLayout(doc, m_imageMgr); - docLayout->setBlockImageEnabled(m_blockImageEnabled); - doc->setDocumentLayout(docLayout); - - docLayout->setVirtualCursorBlockWidth(VIRTUAL_CURSOR_BLOCK_WIDTH); - - docLayout->setCursorWidth(m_defaultCursorWidth); - - connect(docLayout, &VTextDocumentLayout::cursorBlockWidthUpdated, - this, [this](int p_width) { - if (p_width != cursorWidth() - && p_width > VIRTUAL_CURSOR_BLOCK_WIDTH) { - setCursorWidth(p_width); - } - }); - - m_lineNumberArea = new VLineNumberArea(this, - document(), - fontMetrics().width(QLatin1Char('8')), - this); - connect(doc, &QTextDocument::blockCountChanged, - this, &VTextEdit::updateLineNumberAreaMargin); - connect(this, &QTextEdit::textChanged, - this, &VTextEdit::updateLineNumberArea); - connect(verticalScrollBar(), &QScrollBar::valueChanged, - this, &VTextEdit::updateLineNumberArea); - connect(this, &QTextEdit::cursorPositionChanged, - this, [this]() { - if (m_highlightCursorLineBlock) { - QTextCursor cursor = textCursor(); - getLayout()->setCursorLineBlockNumber(cursor.block().blockNumber()); - } - - updateLineNumberArea(); - }); -} - -VTextDocumentLayout *VTextEdit::getLayout() const -{ - return qobject_cast(document()->documentLayout()); -} - -void VTextEdit::setLineLeading(qreal p_leading) -{ - getLayout()->setLineLeading(p_leading); -} - -void VTextEdit::resizeEvent(QResizeEvent *p_event) -{ - QTextEdit::resizeEvent(p_event); - - QRect rect = contentsRect(); - if (m_lineNumberType != LineNumberType::None) { - m_lineNumberArea->setGeometry(QRect(rect.left(), - rect.top(), - m_lineNumberArea->calculateWidth(), - rect.height())); - } - - if (m_enableExtraBuffer) { - getLayout()->setExtraBufferHeight(rect.height() / 2); - } -} - -void VTextEdit::paintLineNumberArea(QPaintEvent *p_event) -{ - if (m_lineNumberType == LineNumberType::None) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - return; - } - - QPainter painter(m_lineNumberArea); - painter.fillRect(p_event->rect(), m_lineNumberArea->getBackgroundColor()); - - QTextBlock block = firstVisibleBlock(); - if (!block.isValid()) { - return; - } - - VTextDocumentLayout *layout = getLayout(); - Q_ASSERT(layout); - - int blockNumber = block.blockNumber(); - QRectF rect = layout->blockBoundingRect(block); - int top = contentOffsetY() + (int)rect.y(); - int bottom = top + (int)rect.height(); - int eventTop = p_event->rect().top(); - int eventBtm = p_event->rect().bottom(); - const int digitHeight = painter.fontMetrics().height(); - const int curBlockNumber = textCursor().block().blockNumber(); - painter.setPen(m_lineNumberArea->getForegroundColor()); - const int leading = (int)layout->getLineLeading(); - - // Display line number only in code block. - if (m_lineNumberType == LineNumberType::CodeBlock) { - int number = 0; - while (block.isValid() && top <= eventBtm) { - int blockState = block.userState(); - switch (blockState) { - case (int)BlockState::CodeBlockStart: - Q_ASSERT(number == 0); - number = 1; - break; - - case (int)BlockState::CodeBlockEnd: - number = 0; - break; - - case (int)BlockState::CodeBlock: - if (number == 0) { - // Need to find current line number in code block. - QTextBlock startBlock = block.previous(); - while (startBlock.isValid()) { - if (startBlock.userState() == (int)BlockState::CodeBlockStart) { - number = block.blockNumber() - startBlock.blockNumber(); - break; - } - - startBlock = startBlock.previous(); - } - } - - break; - - default: - break; - } - - if (blockState == (int)BlockState::CodeBlock) { - if (block.isVisible() && bottom >= eventTop) { - QString numberStr = QString::number(number); - painter.drawText(0, - top + leading, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight | Qt::AlignTop, - numberStr); - } - - ++number; - } - - block = block.next(); - top = bottom; - bottom = top + (int)layout->blockBoundingRect(block).height(); - } - - return; - } - - // Handle m_lineNumberType 1 and 2. - Q_ASSERT(m_lineNumberType == LineNumberType::Absolute - || m_lineNumberType == LineNumberType::Relative); - while (block.isValid() && top <= eventBtm) { - if (block.isVisible() && bottom >= eventTop) { - bool currentLine = false; - int number = blockNumber + 1; - if (m_lineNumberType == LineNumberType::Relative) { - number = blockNumber - curBlockNumber; - if (number == 0) { - currentLine = true; - number = blockNumber + 1; - } else if (number < 0) { - number = -number; - } - } else if (blockNumber == curBlockNumber) { - currentLine = true; - } - - QString numberStr = QString::number(number); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(true); - painter.setFont(font); - } - - painter.drawText(0, - top + leading, - m_lineNumberArea->width(), - digitHeight, - Qt::AlignRight | Qt::AlignTop, - numberStr); - - if (currentLine) { - QFont font = painter.font(); - font.setBold(false); - painter.setFont(font); - } - } - - block = block.next(); - top = bottom; - bottom = top + (int)layout->blockBoundingRect(block).height(); - ++blockNumber; - } -} - -void VTextEdit::updateLineNumberAreaMargin() -{ - int width = 0; - if (m_lineNumberType != LineNumberType::None) { - width = m_lineNumberArea->calculateWidth(); - } - - if (width != viewportMargins().left()) { - setViewportMargins(width, 0, 0, 0); - } -} - -void VTextEdit::updateLineNumberArea() -{ - if (m_lineNumberType != LineNumberType::None) { - if (!m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->show(); - } - - m_lineNumberArea->update(); - } else if (m_lineNumberArea->isVisible()) { - updateLineNumberAreaMargin(); - m_lineNumberArea->hide(); - } -} - -int VTextEdit::firstVisibleBlockNumber() const -{ - VTextDocumentLayout *layout = getLayout(); - Q_ASSERT(layout); - return layout->findBlockByPosition(QPointF(0, -contentOffsetY())); -} - -QTextBlock VTextEdit::firstVisibleBlock() const -{ - VTextDocumentLayout *layout = getLayout(); - Q_ASSERT(layout); - int blockNumber = layout->findBlockByPosition(QPointF(0, -contentOffsetY())); - return document()->findBlockByNumber(blockNumber); -} - -QTextBlock VTextEdit::lastVisibleBlock() const -{ - VTextDocumentLayout *layout = getLayout(); - Q_ASSERT(layout); - int blockNumber = layout->findBlockByPosition(QPointF(0, -contentOffsetY() + contentsRect().height())); - return document()->findBlockByNumber(blockNumber); -} - -void VTextEdit::visibleBlockRange(int &p_first, int &p_last) const -{ - VTextDocumentLayout *layout = getLayout(); - Q_ASSERT(layout); - p_first = layout->findBlockByPosition(QPointF(0, -contentOffsetY())); - p_last = layout->findBlockByPosition(QPointF(0, -contentOffsetY() + contentsRect().height())); -} - -int VTextEdit::contentOffsetY() const -{ - QScrollBar *sb = verticalScrollBar(); - return -(sb->value()); -} - -void VTextEdit::clearBlockImages() -{ - m_imageMgr->clear(); - - getLayout()->relayout(); -} - -void VTextEdit::relayout(const OrderedIntSet &p_blocks) -{ - if (p_blocks.isEmpty()) { - return; - } - - getLayout()->relayout(p_blocks); - - updateLineNumberArea(); -} - -void VTextEdit::relayoutVisibleBlocks() -{ - int first, last; - visibleBlockRange(first, last); - OrderedIntSet blocks; - - for (int i = first; i <= last; ++i) { - blocks.insert(i, QMapDummyValue()); - } - - getLayout()->relayout(blocks); - - updateLineNumberArea(); -} - -bool VTextEdit::containsImage(const QString &p_imageName) const -{ - return m_imageMgr->contains(p_imageName); -} - -QSize VTextEdit::imageSize(const QString &p_imageName) const -{ - const QPixmap *img = m_imageMgr->findImage(p_imageName); - if (img) { - return img->size(); - } - - return QSize(); -} - -const QPixmap *VTextEdit::findImage(const QString &p_name) const -{ - return m_imageMgr->findImage(p_name); -} - -void VTextEdit::addImage(const QString &p_imageName, const QPixmap &p_image) -{ - if (m_blockImageEnabled) { - m_imageMgr->addImage(p_imageName, p_image); - } -} - -void VTextEdit::removeImage(const QString &p_imageName) -{ - m_imageMgr->removeImage(p_imageName); -} - -void VTextEdit::setBlockImageEnabled(bool p_enabled) -{ - if (m_blockImageEnabled == p_enabled) { - return; - } - - m_blockImageEnabled = p_enabled; - - getLayout()->setBlockImageEnabled(m_blockImageEnabled); - - if (!m_blockImageEnabled) { - clearBlockImages(); - } -} - -void VTextEdit::setImageWidthConstrainted(bool p_enabled) -{ - getLayout()->setImageWidthConstrainted(p_enabled); -} - -void VTextEdit::setImageLineColor(const QColor &p_color) -{ - getLayout()->setImageLineColor(p_color); -} - -void VTextEdit::setCursorBlockMode(CursorBlock p_mode) -{ - VTextDocumentLayout *layout = getLayout(); - - if (p_mode != m_cursorBlockMode) { - m_cursorBlockMode = p_mode; - layout->setCursorBlockMode(m_cursorBlockMode); - layout->clearLastCursorBlockWidth(); - setCursorWidth(m_cursorBlockMode != CursorBlock::None ? VIRTUAL_CURSOR_BLOCK_WIDTH - : m_defaultCursorWidth); - layout->updateBlockByNumber(textCursor().blockNumber()); - } -} - -void VTextEdit::setHighlightCursorLineBlockEnabled(bool p_enabled) -{ - if (m_highlightCursorLineBlock != p_enabled) { - auto layout = getLayout(); - m_highlightCursorLineBlock = p_enabled; - layout->setHighlightCursorLineBlockEnabled(p_enabled); - if (m_highlightCursorLineBlock) { - QTextCursor cursor = textCursor(); - layout->setCursorLineBlockNumber(cursor.block().blockNumber()); - } - } -} - -void VTextEdit::setCursorLineBlockBg(const QColor &p_bg) -{ - getLayout()->setCursorLineBlockBg(p_bg); -} - -void VTextEdit::relayout() -{ - getLayout()->relayout(); - - updateLineNumberArea(); -} - -void VTextEdit::setDisplayScaleFactor(qreal p_factor) -{ - m_defaultCursorWidth = p_factor + 0.5; - - setCursorWidth(m_cursorBlockMode != CursorBlock::None ? VIRTUAL_CURSOR_BLOCK_WIDTH - : m_defaultCursorWidth); - getLayout()->setCursorWidth(m_defaultCursorWidth); -} - -void VTextEdit::updateLineNumberAreaWidth(const QFontMetrics &p_metrics) -{ - m_lineNumberArea->setDigitWidth(p_metrics.width(QLatin1Char('8'))); - updateLineNumberAreaMargin(); -} - -void VTextEdit::dragMoveEvent(QDragMoveEvent *p_event) -{ - QTextEdit::dragMoveEvent(p_event); - - // We need to update the cursor rect to show the cursor while dragging text. - // This is a work-around. We do not know why VTextEdit won't update the cursor - // rect to show the cursor. - // TODO: find out the rect of current cursor to update that rect only. - update(); -} - -int VTextEdit::lineNumberAreaWidth() const -{ - return m_lineNumberArea->width(); -} diff --git a/src/vtextedit.h b/src/vtextedit.h deleted file mode 100644 index 13d04d76..00000000 --- a/src/vtextedit.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef VTEXTEDIT_H -#define VTEXTEDIT_H - -#include -#include - -#include "vlinenumberarea.h" -#include "vtextdocumentlayout.h" - -class VTextDocumentLayout; -class QPainter; -class QResizeEvent; -class VImageResourceManager2; - - -class VTextEdit : public QTextEdit, public VTextEditWithLineNumber -{ - Q_OBJECT -public: - explicit VTextEdit(QWidget *p_parent = nullptr); - - explicit VTextEdit(const QString &p_text, QWidget *p_parent = nullptr); - - virtual ~VTextEdit(); - - void init(); - - void setLineLeading(qreal p_leading); - - void paintLineNumberArea(QPaintEvent *p_event) Q_DECL_OVERRIDE; - - void setLineNumberType(LineNumberType p_type); - - void setLineNumberColor(const QColor &p_foreground, const QColor &p_background); - - int firstVisibleBlockNumber() const; - - QTextBlock firstVisibleBlock() const; - - QTextBlock lastVisibleBlock() const; - - void visibleBlockRange(int &p_first, int &p_last) const; - - void clearBlockImages(); - - // Whether the resoruce manager contains image of name @p_imageName. - bool containsImage(const QString &p_imageName) const; - - // Get the image size from the resource manager. - QSize imageSize(const QString &p_imageName) const; - - // Get the image from the resource manager. - const QPixmap *findImage(const QString &p_name) const; - - // Add an image to the resources. - void addImage(const QString &p_imageName, const QPixmap &p_image); - - // Remove an image from the resources. - void removeImage(const QString &p_imageName); - - void setBlockImageEnabled(bool p_enabled); - - void setImageWidthConstrainted(bool p_enabled); - - void setImageLineColor(const QColor &p_color); - - void relayout(const OrderedIntSet &p_blocks); - - void setCursorBlockMode(CursorBlock p_mode); - - void setHighlightCursorLineBlockEnabled(bool p_enabled); - - void setCursorLineBlockBg(const QColor &p_bg); - - void relayout(); - - void relayoutVisibleBlocks(); - - void setDisplayScaleFactor(qreal p_factor); - - void setEnableExtraBuffer(bool p_enable); - -protected: - void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - - // Return the Y offset of the content via the scrollbar. - int contentOffsetY() const; - - int lineNumberAreaWidth() const; - - void updateLineNumberAreaWidth(const QFontMetrics &p_metrics); - - void dragMoveEvent(QDragMoveEvent *p_event) Q_DECL_OVERRIDE; - -private slots: - // Update viewport margin to hold the line number area. - void updateLineNumberAreaMargin(); - - void updateLineNumberArea(); - -private: - VTextDocumentLayout *getLayout() const; - - VLineNumberArea *m_lineNumberArea; - - LineNumberType m_lineNumberType; - - VImageResourceManager2 *m_imageMgr; - - bool m_blockImageEnabled; - - CursorBlock m_cursorBlockMode; - - bool m_highlightCursorLineBlock; - - int m_defaultCursorWidth; - - bool m_enableExtraBuffer; -}; - -inline void VTextEdit::setLineNumberType(LineNumberType p_type) -{ - if (p_type == m_lineNumberType) { - return; - } - - m_lineNumberType = p_type; - - updateLineNumberArea(); -} - -inline void VTextEdit::setLineNumberColor(const QColor &p_foreground, - const QColor &p_background) -{ - m_lineNumberArea->setForegroundColor(p_foreground); - m_lineNumberArea->setBackgroundColor(p_background); -} - -inline void VTextEdit::setEnableExtraBuffer(bool p_enable) -{ - if (m_enableExtraBuffer == p_enable) { - return; - } - - m_enableExtraBuffer = p_enable; - getLayout()->setExtraBufferHeight(m_enableExtraBuffer ? contentsRect().height() / 2 - : 0); -} -#endif // VTEXTEDIT_H diff --git a/src/vtexteditcompleter.cpp b/src/vtexteditcompleter.cpp deleted file mode 100644 index 89ccba91..00000000 --- a/src/vtexteditcompleter.cpp +++ /dev/null @@ -1,321 +0,0 @@ -#include "vtexteditcompleter.h" - -#include -#include -#include -#include -#include -#include - -#include "utils/vutils.h" -#include "veditor.h" -#include "vmainwindow.h" - -extern VMainWindow *g_mainWin; - -VTextEditCompleter::VTextEditCompleter(QObject *p_parent) - : QCompleter(p_parent), - m_initialized(false) -{ -} - -void VTextEditCompleter::performCompletion(const QStringList &p_words, - const QString &p_prefix, - Qt::CaseSensitivity p_cs, - bool p_reversed, - const QRect &p_rect, - VEditor *p_editor) -{ - init(); - - m_editor = p_editor; - - setWidget(m_editor->getEditor()); - - m_model->setStringList(p_words); - setCaseSensitivity(p_cs); - setCompletionPrefix(p_prefix); - - int cnt = completionCount(); - if (cnt == 0) { - finishCompletion(); - return; - } - - selectRow(p_reversed ? cnt - 1 : 0); - - if (cnt == 1 && currentCompletion() == p_prefix) { - finishCompletion(); - return; - } - - g_mainWin->setCaptainModeEnabled(false); - - m_insertedCompletion = p_prefix; - insertCurrentCompletion(); - - auto pu = popup(); - QRect rt(p_rect); - rt.setWidth(pu->sizeHintForColumn(0) + pu->verticalScrollBar()->sizeHint().width()); - complete(rt); -} - -void VTextEditCompleter::init() -{ - if (m_initialized) { - return; - } - - m_initialized = true; - - m_model = new QStringListModel(this); - setModel(m_model); - - popup()->setProperty("TextEdit", true); - popup()->setItemDelegate(new QStyledItemDelegate(this)); - - connect(this, static_cast(&QCompleter::activated), - this, [this](const QString &p_text) { - insertCompletion(p_text); - finishCompletion(); - }); -} - -void VTextEditCompleter::selectNextCompletion(bool p_reversed) -{ - QModelIndex curIndex = popup()->currentIndex(); - if (p_reversed) { - if (curIndex.isValid()) { - int row = curIndex.row(); - if (row == 0) { - setCurrentIndex(QModelIndex()); - } else { - selectRow(row - 1); - } - } else { - selectRow(completionCount() - 1); - } - } else { - if (curIndex.isValid()) { - int row = curIndex.row(); - if (!selectRow(row + 1)) { - setCurrentIndex(QModelIndex()); - } - } else { - selectRow(0); - } - } -} - -bool VTextEditCompleter::selectRow(int p_row) -{ - if (setCurrentRow(p_row)) { - setCurrentIndex(currentIndex()); - return true; - } - - return false; -} - -void VTextEditCompleter::setCurrentIndex(QModelIndex p_index, bool p_select) -{ - auto pu = popup(); - if (!pu) { - return; - } - - if (!p_select) { - pu->selectionModel()->setCurrentIndex(p_index, QItemSelectionModel::NoUpdate); - } else { - if (!p_index.isValid()) { - pu->selectionModel()->clear(); - } else { - pu->selectionModel()->setCurrentIndex(p_index, QItemSelectionModel::ClearAndSelect); - } - } - - p_index = pu->selectionModel()->currentIndex(); - if (!p_index.isValid()) { - pu->scrollToTop(); - } else { - pu->scrollTo(p_index); - } -} - -bool VTextEditCompleter::eventFilter(QObject *p_obj, QEvent *p_eve) -{ - switch (p_eve->type()) { - case QEvent::KeyPress: - { - if (p_obj != popup() || !m_editor) { - break; - } - - bool exited = false; - - QKeyEvent *ke = static_cast(p_eve); - const int key = ke->key(); - const int modifiers = ke->modifiers(); - switch (key) { - case Qt::Key_N: - V_FALLTHROUGH; - case Qt::Key_P: - if (VUtils::isControlModifierForVim(modifiers)) { - selectNextCompletion(key == Qt::Key_P); - insertCurrentCompletion(); - return true; - } - break; - - case Qt::Key_J: - V_FALLTHROUGH; - case Qt::Key_K: - if (VUtils::isControlModifierForVim(modifiers)) { - selectNextCompletion(key == Qt::Key_K); - return true; - } - break; - - case Qt::Key_BracketLeft: - if (!VUtils::isControlModifierForVim(modifiers)) { - break; - } - V_FALLTHROUGH; - case Qt::Key_Escape: - exited = true; - // Propogate this event to the editor widget for Vim mode. - if (!m_editor->getVim()) { - finishCompletion(); - return true; - } - break; - - case Qt::Key_E: - if (VUtils::isControlModifierForVim(modifiers)) { - cancelCompletion(); - return true; - } - break; - - case Qt::Key_Enter: - case Qt::Key_Return: - { - if (m_insertedCompletion != currentCompletion()) { - insertCurrentCompletion(); - finishCompletion(); - return true; - } else { - exited = true; - } - break; - } - - default: - break; - } - - int cursorPos = -1; - if (!exited) { - cursorPos = m_editor->textCursorW().position(); - } - - bool ret = QCompleter::eventFilter(p_obj, p_eve); - if (!exited) { - // Detect if cursor position changed after key press. - int pos = m_editor->textCursorW().position(); - if (pos == cursorPos - 1) { - // Deleted one char. - if (m_insertedCompletion.size() > 1) { - updatePrefix(m_editor->fetchCompletionPrefix()); - } else { - exited = true; - } - } else if (pos == cursorPos + 1) { - // Added one char. - QString prefix = m_editor->fetchCompletionPrefix(); - if (prefix.size() == m_insertedCompletion.size() + 1 - && prefix.startsWith(m_insertedCompletion)) { - updatePrefix(prefix); - } else { - exited = true; - } - } else if (pos != cursorPos) { - exited = true; - } - } - - if (exited) { - // finishCompletion() will do clean up. Must be called after QCompleter::eventFilter(). - finishCompletion(); - } - - return ret; - } - - case QEvent::Hide: - { - // Completion exited. - cleanUp(); - break; - } - - default: - break; - } - - return QCompleter::eventFilter(p_obj, p_eve); -} - -void VTextEditCompleter::insertCurrentCompletion() -{ - QString completion; - QModelIndex curIndex = popup()->currentIndex(); - if (curIndex.isValid()) { - completion = currentCompletion(); - } else { - completion = completionPrefix(); - } - - insertCompletion(completion); -} - -void VTextEditCompleter::insertCompletion(const QString &p_completion) -{ - if (m_insertedCompletion == p_completion) { - return; - } - - m_editor->insertCompletion(m_insertedCompletion, p_completion); - m_insertedCompletion = p_completion; -} - -void VTextEditCompleter::cancelCompletion() -{ - insertCompletion(completionPrefix()); - - finishCompletion(); -} - -void VTextEditCompleter::cleanUp() -{ - // Do not clean up m_editor and m_insertedCompletion, since activated() - // signal is after the HideEvent. - setWidget(NULL); - g_mainWin->setCaptainModeEnabled(true); -} - -void VTextEditCompleter::updatePrefix(const QString &p_prefix) -{ - m_insertedCompletion = p_prefix; - setCompletionPrefix(p_prefix); - - int cnt = completionCount(); - if (cnt == 0) { - finishCompletion(); - } else if (cnt == 1) { - setCurrentRow(0); - if (currentCompletion() == p_prefix) { - finishCompletion(); - } - } -} diff --git a/src/vtexteditcompleter.h b/src/vtexteditcompleter.h deleted file mode 100644 index 2f815f6f..00000000 --- a/src/vtexteditcompleter.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef VTEXTEDITCOMPLETER_H -#define VTEXTEDITCOMPLETER_H - -#include -#include - -class QStringListModel; -class VEditor; - -class VTextEditCompleter : public QCompleter -{ - Q_OBJECT -public: - explicit VTextEditCompleter(QObject *p_parent = nullptr); - - bool isPopupVisible() const; - - void performCompletion(const QStringList &p_words, - const QString &p_prefix, - Qt::CaseSensitivity p_cs, - bool p_reversed, - const QRect &p_rect, - VEditor *p_editor); - -protected: - bool eventFilter(QObject *p_obj, QEvent *p_eve) Q_DECL_OVERRIDE; - -private: - void init(); - - bool selectRow(int p_row); - - void setCurrentIndex(QModelIndex p_index, bool p_select = true); - - void selectNextCompletion(bool p_reversed); - - void insertCurrentCompletion(); - - void insertCompletion(const QString &p_completion); - - void finishCompletion(); - - // Revert inserted completion to prefix and finish completion. - void cancelCompletion(); - - void cleanUp(); - - void updatePrefix(const QString &p_prefix); - - bool m_initialized; - - QStringListModel *m_model; - - VEditor *m_editor; - - QString m_insertedCompletion; -}; - -inline bool VTextEditCompleter::isPopupVisible() const -{ - return popup()->isVisible(); -} - -inline void VTextEditCompleter::finishCompletion() -{ - popup()->hide(); -} -#endif // VTEXTEDITCOMPLETER_H diff --git a/src/vtoolbox.cpp b/src/vtoolbox.cpp deleted file mode 100644 index 8e5b699e..00000000 --- a/src/vtoolbox.cpp +++ /dev/null @@ -1,198 +0,0 @@ -#include "vtoolbox.h" - -#include -#include -#include -#include -#include -#include - -#include "vnote.h" -#include "utils/vutils.h" -#include "utils/viconutils.h" - -extern VNote *g_vnote; - -VToolBox::VToolBox(QWidget *p_parent) - : QWidget(p_parent), - m_currentIndex(-1) -{ - setupUI(); -} - -void VToolBox::setupUI() -{ - m_btnLayout = new QHBoxLayout(); - m_btnLayout->addStretch(); - m_btnLayout->setContentsMargins(0, 0, 0, 2); - m_btnLayout->setSpacing(0); - QWidget *wid = new QWidget(); - wid->setProperty("ToolBoxTitle", true); - wid->setLayout(m_btnLayout); - - m_widgetLayout = new QStackedLayout(); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(wid); - mainLayout->addLayout(m_widgetLayout); - mainLayout->setContentsMargins(3, 0, 3, 0); - - setLayout(mainLayout); -} - -int VToolBox::addItem(QWidget *p_widget, - const QString &p_iconFile, - const QString &p_text, - QWidget *p_focusWidget) -{ - int idx = m_items.size(); - - // New a button. - QIcon icon = VIconUtils::toolBoxIcon(p_iconFile); - QPushButton *btn = new QPushButton(icon, ""); - btn->setToolTip(p_text); - btn->setProperty("FlatBtn", true); - btn->setProperty("ToolBoxTitleBtn", true); - connect(btn, &QPushButton::clicked, - this, [this]() { - QObject *btn = sender(); - for (int i = 0; i < m_items.size(); ++i) { - if (m_items[i].m_btn == btn) { - setCurrentIndex(i); - break; - } - } - }); - - m_btnLayout->insertWidget(idx, btn); - - // Insert widget to layout. - m_widgetLayout->insertWidget(idx, p_widget); - - m_items.push_back(ItemInfo(p_widget, - p_focusWidget, - p_text, - btn, - icon, - VIconUtils::toolBoxActiveIcon(p_iconFile))); - - if (m_items.size() == 1) { - setCurrentIndex(0); - } - - return idx; -} - -void VToolBox::setCurrentIndex(int p_idx, bool p_focus) -{ - if (p_idx < 0 || p_idx >= m_items.size()) { - if (m_items.isEmpty()) { - m_currentIndex = -1; - } else { - m_currentIndex = 0; - } - } else { - m_currentIndex = p_idx; - } - - setCurrentButtonIndex(m_currentIndex); - - m_widgetLayout->setCurrentIndex(m_currentIndex); - - QWidget *widget = m_widgetLayout->widget(m_currentIndex); - if (widget && p_focus) { - if (m_items[m_currentIndex].m_focusWidget) { - m_items[m_currentIndex].m_focusWidget->setFocus(); - } else { - widget->setFocus(); - } - } -} - -void VToolBox::setCurrentWidget(QWidget *p_widget, bool p_focus) -{ - int idx = -1; - for (int i = 0; i < m_items.size(); ++i) { - if (m_items[i].m_widget == p_widget) { - idx = i; - break; - } - } - - setCurrentIndex(idx, p_focus); -} - -void VToolBox::setCurrentButtonIndex(int p_idx) -{ - // Remove the text of all button. - for (int i = 0; i < m_items.size(); ++i) { - QPushButton *btn = m_items[i].m_btn; - btn->setText(""); - btn->setIcon(m_items[i].m_icon); - btn->clearFocus(); - VUtils::setDynamicProperty(btn, "ToolBoxActiveBtn", false); - } - - if (p_idx < 0 || p_idx >= m_items.size()) { - return; - } - - QPushButton *curBtn = m_items[p_idx].m_btn; - curBtn->setText(m_items[p_idx].m_text); - curBtn->setIcon(m_items[p_idx].m_activeIcon); - VUtils::setDynamicProperty(curBtn, "ToolBoxActiveBtn", true); -} - -void VToolBox::showNavigation() -{ - clearNavigation(); - - if (!isVisible()) { - return; - } - - for (int i = 0; i < 26 && i < m_items.size(); ++i) { - const ItemInfo &item = m_items[i]; - - QChar key('a' + i); - m_keyMap[key] = item.m_widget; - - QString str = QString(m_majorKey) + key; - QLabel *label = new QLabel(str, this); - label->setStyleSheet(g_vnote->getNavigationLabelStyle(str)); - label->show(); - QRect rect = item.m_btn->geometry(); - // Display the label at the end to show the file name. - label->move(rect.x(), rect.y() + rect.height() / 2); - m_naviLabels.append(label); - } -} - -bool VToolBox::handleKeyNavigation(int p_key, bool &p_succeed) -{ - bool ret = false; - p_succeed = false; - QChar keyChar = VUtils::keyToChar(p_key); - if (m_isSecondKey && !keyChar.isNull()) { - m_isSecondKey = false; - p_succeed = true; - auto it = m_keyMap.find(keyChar); - if (it != m_keyMap.end()) { - ret = true; - QWidget *widget = static_cast(it.value()); - setCurrentWidget(widget); - } - } else if (keyChar == m_majorKey) { - // Major key pressed. - // Need second key if m_keyMap is not empty. - if (m_keyMap.isEmpty()) { - p_succeed = true; - } else { - m_isSecondKey = true; - } - - ret = true; - } - - return ret; -} diff --git a/src/vtoolbox.h b/src/vtoolbox.h deleted file mode 100644 index 65d13119..00000000 --- a/src/vtoolbox.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef VTOOLBOX_H -#define VTOOLBOX_H - -#include -#include -#include -#include - -#include "vnavigationmode.h" - -class QPushButton; -class QStackedLayout; -class QBoxLayout; - -class VToolBox : public QWidget, public VNavigationMode -{ - Q_OBJECT -public: - explicit VToolBox(QWidget *p_parent = nullptr); - - int addItem(QWidget *p_widget, - const QString &p_iconFile, - const QString &p_text, - QWidget *p_focusWidget = nullptr); - - void setCurrentIndex(int p_idx, bool p_focus = true); - - void setCurrentWidget(QWidget *p_widget, bool p_focus = true); - - int currentIndex() const; - - // Implementations for VNavigationMode. - void showNavigation() Q_DECL_OVERRIDE; - bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; - -private: - struct ItemInfo - { - ItemInfo() - : m_widget(nullptr), - m_focusWidget(nullptr), - m_btn(nullptr) - { - } - - ItemInfo(QWidget *p_widget, - QWidget *p_focusWidget, - const QString &p_text, - QPushButton *p_btn, - const QIcon &p_icon, - const QIcon &p_activeIcon) - : m_widget(p_widget), - m_focusWidget(p_focusWidget), - m_text(p_text), - m_btn(p_btn), - m_icon(p_icon), - m_activeIcon(p_activeIcon) - { - } - - QWidget *m_widget; - QWidget *m_focusWidget; - QString m_text; - - QPushButton *m_btn; - QIcon m_icon; - QIcon m_activeIcon; - }; - - void setupUI(); - - void setCurrentButtonIndex(int p_idx); - - QBoxLayout *m_btnLayout; - - QStackedLayout *m_widgetLayout; - - int m_currentIndex; - - QVector m_items; -}; - -inline int VToolBox::currentIndex() const -{ - return m_currentIndex; -} - -#endif // VTOOLBOX_H diff --git a/src/vtreewidget.cpp b/src/vtreewidget.cpp deleted file mode 100644 index 1f77164b..00000000 --- a/src/vtreewidget.cpp +++ /dev/null @@ -1,440 +0,0 @@ -#include "vtreewidget.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "utils/vutils.h" -#include "utils/vimnavigationforwidget.h" -#include "vstyleditemdelegate.h" - -#define SEARCH_INPUT_NORMAL_OPACITY 0.8 - -#define SEARCH_INPUT_IDLE_OPACITY 0.2 - -VTreeWidget::VTreeWidget(QWidget *p_parent) - : QTreeWidget(p_parent), - ISimpleSearch(), - m_fitContent(false) -{ - setAttribute(Qt::WA_MacShowFocusRect, false); - - m_searchInput = new VSimpleSearchInput(this, this); - connect(m_searchInput, &VSimpleSearchInput::triggered, - this, &VTreeWidget::handleSearchModeTriggered); - connect(m_searchInput, &VSimpleSearchInput::inputTextChanged, - this, &VTreeWidget::handleSearchInputTextChanged); - - QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect(m_searchInput); - effect->setOpacity(SEARCH_INPUT_NORMAL_OPACITY); - m_searchInput->setGraphicsEffect(effect); - m_searchInput->hide(); - - m_searchColdTimer = new QTimer(this); - m_searchColdTimer->setSingleShot(true); - m_searchColdTimer->setInterval(1000); - connect(m_searchColdTimer, &QTimer::timeout, - this, [this]() { - QGraphicsOpacityEffect *effect = getSearchInputEffect(); - Q_ASSERT(effect); - effect->setOpacity(SEARCH_INPUT_IDLE_OPACITY); - }); - - m_delegate = new VStyledItemDelegate(NULL, this); - setItemDelegate(m_delegate); - - m_expandTimer = new QTimer(this); - m_expandTimer->setSingleShot(true); - m_expandTimer->setInterval(100); - connect(m_expandTimer, &QTimer::timeout, - this, [this]() { - if (m_fitContent) { - resizeColumnToContents(0); - } - - emit itemExpandedOrCollapsed(); - }); - - connect(this, &VTreeWidget::itemExpanded, - m_expandTimer, static_cast(&QTimer::start)); - connect(this, &VTreeWidget::itemCollapsed, - m_expandTimer, static_cast(&QTimer::start)); -} - -void VTreeWidget::keyPressEvent(QKeyEvent *p_event) -{ - if (m_searchInput->tryHandleKeyPressEvent(p_event)) { - return; - } - - if (VimNavigationForWidget::injectKeyPressEventForVim(this, p_event)) { - return; - } - - QTreeWidget::keyPressEvent(p_event); -} - -void VTreeWidget::clearAll() -{ - m_searchInput->clear(); - setSearchInputVisible(false); - - VTreeWidget::clear(); -} - -void VTreeWidget::setSearchInputVisible(bool p_visible) -{ - m_searchInput->setVisible(p_visible); - // setViewportMargins() and setContentsMargins() do not work for QTreeWidget. - // setStyleSheet(QString("padding-bottom: %1px").arg(bottomMargin)); - QGraphicsOpacityEffect *effect = getSearchInputEffect(); - Q_ASSERT(effect); - effect->setOpacity(SEARCH_INPUT_NORMAL_OPACITY); -} - -void VTreeWidget::resizeEvent(QResizeEvent *p_event) -{ - QTreeWidget::resizeEvent(p_event); - - QRect contentRect = contentsRect(); - int width = contentRect.width(); - QScrollBar *vbar = verticalScrollBar(); - if (vbar && (vbar->minimum() != vbar->maximum())) { - width -= vbar->width(); - } - - int y = height() - m_searchInput->height(); - QScrollBar *hbar = horizontalScrollBar(); - if (hbar && (hbar->minimum() != hbar->maximum())) { - y -= hbar->height(); - } - - m_searchInput->setGeometry(QRect(contentRect.left(), - y, - width, - m_searchInput->height())); -} - -void VTreeWidget::handleSearchModeTriggered(bool p_inSearchMode, bool p_focus) -{ - setSearchInputVisible(p_inSearchMode); - if (!p_inSearchMode) { - clearItemsHighlight(); - } - - if (p_focus) { - setFocus(); - } -} - -void VTreeWidget::dropEvent(QDropEvent *p_event) -{ - QList dragItems = selectedItems(); - - int first = -1, last = -1; - QTreeWidgetItem *firstItem = NULL; - for (int i = 0; i < dragItems.size(); ++i) { - int row = indexFromItem(dragItems[i]).row(); - if (row > last) { - last = row; - } - - if (first == -1 || row < first) { - first = row; - firstItem = dragItems[i]; - } - } - - Q_ASSERT(firstItem); - - QTreeWidget::dropEvent(p_event); - - int target = indexFromItem(firstItem).row(); - emit rowsMoved(first, last, target); -} - -QList VTreeWidget::searchItems(const QString &p_text, - Qt::MatchFlags p_flags) const -{ - QList items = findItems(p_text, p_flags); - - QList res; - res.reserve(items.size()); - for (int i = 0; i < items.size(); ++i) { - if (items[i]->type() == ItemTypeSeparator) { - continue; - } - - res.append(items[i]); - } - - return res; -} - -void VTreeWidget::highlightHitItems(const QList &p_items) -{ - clearItemsHighlight(); - - QSet hitIndexes; - for (auto it : p_items) { - QModelIndex index = indexFromItem(static_cast(it)); - if (index.isValid()) { - hitIndexes.insert(index); - } - } - - if (!hitIndexes.isEmpty()) { - m_delegate->setHitItems(hitIndexes); - update(); - } -} - -void VTreeWidget::clearItemsHighlight() -{ - m_delegate->clearHitItems(); - update(); -} - -void VTreeWidget::selectHitItem(void *p_item) -{ - setCurrentItem(static_cast(p_item), 0, QItemSelectionModel::ClearAndSelect); -} - -// Count the total number of tree @p_item. -static int treeItemCount(QTreeWidgetItem *p_item) -{ - if (!p_item) { - return 0; - } - - int child = p_item->childCount(); - int total = 1; - for (int i = 0; i < child; ++i) { - total += treeItemCount(p_item->child(i)); - } - - return total; -} - -int VTreeWidget::totalNumberOfItems() -{ - int total = 0; - int cn = topLevelItemCount(); - for (int i = 0; i < cn; ++i) { - total += treeItemCount(topLevelItem(i)); - } - - return total; -} - -void VTreeWidget::handleSearchInputTextChanged(const QString &p_text) -{ - m_searchColdTimer->stop(); - m_searchColdTimer->start(); - - Q_UNUSED(p_text); - QGraphicsOpacityEffect *effect = getSearchInputEffect(); - Q_ASSERT(effect); - effect->setOpacity(0.8); -} - -QGraphicsOpacityEffect *VTreeWidget::getSearchInputEffect() const -{ - return static_cast(m_searchInput->graphicsEffect()); -} - -static QTreeWidgetItem *lastItemOfTree(QTreeWidgetItem *p_item) -{ - if (p_item->isExpanded() && p_item->childCount() > 0) { - return p_item->child(p_item->childCount() - 1); - } else { - return p_item; - } -} - -QTreeWidgetItem *VTreeWidget::nextSibling(const QTreeWidget *p_tree, - QTreeWidgetItem *p_item, - bool p_forward) -{ - if (!p_item) { - return NULL; - } - - QTreeWidgetItem *pa = p_item->parent(); - if (pa) { - int idx = pa->indexOfChild(p_item); - if (p_forward) { - ++idx; - if (idx >= pa->childCount()) { - return NULL; - } - } else { - --idx; - if (idx < 0) { - return NULL; - } - } - - return pa->child(idx); - } else { - // Top level item. - int idx = p_tree->indexOfTopLevelItem(p_item); - if (p_forward) { - ++idx; - if (idx >= p_tree->topLevelItemCount()) { - return NULL; - } - } else { - --idx; - if (idx < 0) { - return NULL; - } - } - - return p_tree->topLevelItem(idx); - } -} - -void VTreeWidget::selectNextItem(bool p_forward) -{ - if (topLevelItemCount() == 0) { - return; - } - - QTreeWidgetItem *item = currentItem(); - if (!item) { - setCurrentItem(topLevelItem(0), 0, QItemSelectionModel::ClearAndSelect); - return; - } - - QTreeWidgetItem *nItem = nextItem(this, item, p_forward); - if (nItem) { - setCurrentItem(nItem, 0, QItemSelectionModel::ClearAndSelect); - } -} - -QTreeWidgetItem *VTreeWidget::nextItem(const QTreeWidget *p_tree, - QTreeWidgetItem *p_item, - bool p_forward) -{ - QTreeWidgetItem *nItem = NULL; - if (p_forward) { - if (p_item->isExpanded() && p_item->childCount() > 0) { - nItem = p_item->child(0); - } else { - while (!nItem && p_item) { - nItem = nextSibling(p_tree, p_item, true); - p_item = p_item->parent(); - } - } - } else { - nItem = nextSibling(p_tree, p_item, false); - if (!nItem) { - nItem = p_item->parent(); - } else { - nItem = lastItemOfTree(nItem); - } - } - - return nItem; -} - -void VTreeWidget::selectParentItem() -{ - QTreeWidgetItem *item = currentItem(); - if (item) { - QTreeWidgetItem *pitem = item->parent(); - if (pitem) { - setCurrentItem(pitem, 0, QItemSelectionModel::ClearAndSelect); - } - } -} - -static bool isItemTreeExpanded(const QTreeWidgetItem *p_item) -{ - if (!p_item) { - return true; - } - - if (p_item->isHidden() || !p_item->isExpanded()) { - return false; - } - - int cnt = p_item->childCount(); - for (int i = 0; i < cnt; ++i) { - if (!isItemTreeExpanded(p_item->child(i))) { - return false; - } - } - - return true; -} - -bool VTreeWidget::isTreeExpanded(const QTreeWidget *p_tree) -{ - int cnt = p_tree->topLevelItemCount(); - for (int i = 0; i < cnt; ++i) { - if (!isItemTreeExpanded(p_tree->topLevelItem(i))) { - return false; - } - } - - return true; -} - -void VTreeWidget::expandCollapseAll(QTreeWidget *p_tree) -{ - QTreeWidgetItem *topLevelItem = NULL; - QTreeWidgetItem *item = p_tree->currentItem(); - if (item) { - topLevelItem = const_cast(topLevelTreeItem(item)); - } - - bool expanded = isTreeExpanded(p_tree); - if (expanded) { - p_tree->collapseAll(); - } else { - p_tree->expandAll(); - - } - - VTreeWidget *vtree = dynamic_cast(p_tree); - if (vtree) { - if (vtree->m_fitContent) { - vtree->resizeColumnToContents(0); - } - - emit vtree->itemExpandedOrCollapsed(); - } - - if (topLevelItem) { - p_tree->setCurrentItem(topLevelItem, 0, QItemSelectionModel::ClearAndSelect); - p_tree->scrollToItem(topLevelItem); - } -} - -const QTreeWidgetItem *VTreeWidget::topLevelTreeItem(const QTreeWidgetItem *p_item) -{ - if (!p_item) { - return NULL; - } - - if (p_item->parent()) { - return topLevelTreeItem(p_item->parent()); - } else { - return p_item; - } -} - -int VTreeWidget::childIndexOfTreeItem(const QTreeWidgetItem *p_item) -{ - if (p_item->parent()) { - return p_item->parent()->indexOfChild(const_cast(p_item)); - } else { - return 0; - } -} diff --git a/src/vtreewidget.h b/src/vtreewidget.h deleted file mode 100644 index 7007771f..00000000 --- a/src/vtreewidget.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef VTREEWIDGET_H -#define VTREEWIDGET_H - -#include - -#include "vsimplesearchinput.h" - -class QDropEvent; -class VStyledItemDelegate; -class QTimer; -class QGraphicsOpacityEffect; - -// QTreeWidget won't emit the rowsMoved() signal after drag-and-drop. -// VTreeWidget will emit rowsMoved() signal. -class VTreeWidget : public QTreeWidget, public ISimpleSearch -{ - Q_OBJECT -public: - explicit VTreeWidget(QWidget *p_parent = nullptr); - - // Clear tree widget as well as other data. - void clearAll(); - - void setSimpleSearchMatchFlags(Qt::MatchFlags p_flags); - - Qt::MatchFlags getSimpleSearchMatchFlags() const; - - // Implement ISimpleSearch. - virtual QList searchItems(const QString &p_text, - Qt::MatchFlags p_flags) const Q_DECL_OVERRIDE; - - virtual void highlightHitItems(const QList &p_items) Q_DECL_OVERRIDE; - - virtual void clearItemsHighlight() Q_DECL_OVERRIDE; - - virtual void selectHitItem(void *p_item) Q_DECL_OVERRIDE; - - virtual int totalNumberOfItems() Q_DECL_OVERRIDE; - - virtual void selectNextItem(bool p_forward) Q_DECL_OVERRIDE; - - virtual void selectParentItem(); - - void setFitContent(bool p_enabled); - - QTreeWidgetItem *getItemFromIndex(const QModelIndex &p_index) const; - - // Next visible item. - static QTreeWidgetItem *nextItem(const QTreeWidget* p_tree, - QTreeWidgetItem *p_item, - bool p_forward); - - // Whether @p_tree is expanded. - static bool isTreeExpanded(const QTreeWidget *p_tree); - - static void expandCollapseAll(QTreeWidget *p_tree); - - static const QTreeWidgetItem *topLevelTreeItem(const QTreeWidgetItem *p_item); - - static int childIndexOfTreeItem(const QTreeWidgetItem *p_item); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; - - void dropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE; - -signals: - // Rows [@p_first, @p_last] were moved to @p_row. - void rowsMoved(int p_first, int p_last, int p_row); - - void itemExpandedOrCollapsed(); - -private slots: - void handleSearchModeTriggered(bool p_inSearchMode, bool p_focus); - - void handleSearchInputTextChanged(const QString &p_text); - -private: - // Show or hide search input. - void setSearchInputVisible(bool p_visible); - - QGraphicsOpacityEffect *getSearchInputEffect() const; - - static QTreeWidgetItem *nextSibling(const QTreeWidget *p_widget, - QTreeWidgetItem *p_item, - bool p_forward); - - VSimpleSearchInput *m_searchInput; - - VStyledItemDelegate *m_delegate; - - QTimer *m_searchColdTimer; - QTimer *m_expandTimer; - - bool m_fitContent; -}; - -inline void VTreeWidget::setSimpleSearchMatchFlags(Qt::MatchFlags p_flags) -{ - m_searchInput->setMatchFlags(p_flags); -} - -inline Qt::MatchFlags VTreeWidget::getSimpleSearchMatchFlags() const -{ - return m_searchInput->getMatchFlags(); -} - -inline void VTreeWidget::setFitContent(bool p_enabled) -{ - m_fitContent = p_enabled; - setSizeAdjustPolicy(m_fitContent ? QAbstractScrollArea::AdjustToContents - : QAbstractScrollArea::AdjustIgnored); -} - -inline QTreeWidgetItem *VTreeWidget::getItemFromIndex(const QModelIndex &p_index) const -{ - return itemFromIndex(p_index); -} -#endif // VTREEWIDGET_H diff --git a/src/vuetitlecontentpanel.cpp b/src/vuetitlecontentpanel.cpp deleted file mode 100644 index c19a3e9d..00000000 --- a/src/vuetitlecontentpanel.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "vuetitlecontentpanel.h" - -#include -#include -#include -#include - -VUETitleContentPanel::VUETitleContentPanel(QWidget *p_contentWidget, - QWidget *p_parent) - : QWidget(p_parent) -{ - m_titleLabel = new QLabel(this); - m_titleLabel->setProperty("TitleLabel", true); - - p_contentWidget->setParent(this); - - QVBoxLayout *layout = new QVBoxLayout(); - layout->addWidget(m_titleLabel); - layout->addWidget(p_contentWidget); - - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - - setLayout(layout); -} - -void VUETitleContentPanel::setTitle(const QString &p_title) -{ - m_titleLabel->setText(p_title); -} - -void VUETitleContentPanel::clearTitle() -{ - m_titleLabel->clear(); -} diff --git a/src/vuetitlecontentpanel.h b/src/vuetitlecontentpanel.h deleted file mode 100644 index 21e5b367..00000000 --- a/src/vuetitlecontentpanel.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef VUETITLECONTENTPANEL_H -#define VUETITLECONTENTPANEL_H - -#include - -class QLabel; - -class VUETitleContentPanel : public QWidget -{ - Q_OBJECT -public: - explicit VUETitleContentPanel(QWidget *p_contentWidget, - QWidget *p_parent = nullptr); - - void setTitle(const QString &p_title); - - void clearTitle(); - -private: - QLabel *m_titleLabel; -}; - -#endif // VUETITLECONTENTPANEL_H diff --git a/src/vuniversalentry.cpp b/src/vuniversalentry.cpp deleted file mode 100644 index dcd2e20b..00000000 --- a/src/vuniversalentry.cpp +++ /dev/null @@ -1,472 +0,0 @@ -#include "vuniversalentry.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vmetawordlineedit.h" -#include "vlistwidget.h" -#include "vpalette.h" -#include "vlistfolderue.h" - -#define MINIMUM_WIDTH 200 - -#define CMD_EDIT_INTERVAL 500 -#define CMD_EDIT_IDLE_INTERVAL 100 - -extern VPalette *g_palette; - -VUniversalEntryContainer::VUniversalEntryContainer(QWidget *p_parent) - : QWidget(p_parent), - m_widget(NULL) -{ - m_layout = new QVBoxLayout(); - m_layout->setContentsMargins(0, 0, 0, 0); - - setLayout(m_layout); -} - -void VUniversalEntryContainer::clear() -{ - if (m_widget) { - m_layout->removeWidget(m_widget); - m_widget->hide(); - m_widget = NULL; - } - - adjustSizeByWidget(); -} - -void VUniversalEntryContainer::setWidget(QWidget *p_widget) -{ - if (m_widget != p_widget) { - clear(); - m_widget = p_widget; - m_layout->addWidget(m_widget); - m_widget->show(); - } - - adjustSizeByWidget(); -} - -void VUniversalEntryContainer::adjustSizeByWidget() -{ - updateGeometry(); -} - -QSize VUniversalEntryContainer::sizeHint() const -{ - if (m_widget) { - return m_widget->sizeHint(); - } else { - return QWidget::sizeHint(); - } -} - - -VUniversalEntry::VUniversalEntry(QWidget *p_parent) - : QWidget(p_parent), - m_availableRect(0, 0, MINIMUM_WIDTH, MINIMUM_WIDTH), - m_lastEntry(NULL), - m_inQueue(0), - m_pendingCommand(false) -{ - m_minimumWidth = MINIMUM_WIDTH * VUtils::calculateScaleFactor() + 0.5; - - m_cmdTimer = new QTimer(this); - m_cmdTimer->setSingleShot(true); - m_cmdTimer->setInterval(CMD_EDIT_INTERVAL); - connect(m_cmdTimer, &QTimer::timeout, - this, [this]() { - processCommand(); - }); - - setupUI(); - - m_infoWidget = new VListWidget(this); - m_infoWidget->setFitContent(true); - m_container->setWidget(m_infoWidget); - - m_cmdStyleSheet = m_cmdEdit->styleSheet(); -} - -void VUniversalEntry::setupUI() -{ - m_cmdEdit = new VMetaWordLineEdit(this); - m_cmdEdit->setPlaceholderText(tr("Universal Entry, reach anything by typing")); - m_cmdEdit->setCtrlKEnabled(false); - m_cmdEdit->setCtrlEEnabled(false); - connect(m_cmdEdit, &VMetaWordLineEdit::textEdited, - this, [this](const QString &p_text) { - m_cmdTimer->stop(); - if (p_text.size() <= 1) { - m_cmdTimer->start(CMD_EDIT_IDLE_INTERVAL); - } else { - m_cmdTimer->start(CMD_EDIT_INTERVAL); - } - }); - - m_container = new VUniversalEntryContainer(this); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(m_cmdEdit); - mainLayout->addWidget(m_container); - - mainLayout->setContentsMargins(1, 1, 1, 1); - mainLayout->setSpacing(0); - - setLayout(mainLayout); - - setMinimumWidth(m_minimumWidth); -} - -void VUniversalEntry::hideEvent(QHideEvent *p_event) -{ - QWidget::hideEvent(p_event); - if (m_lastEntry) { - m_lastEntry->m_entry->entryHidden(m_lastEntry->m_id); - } - - emit exited(); -} - -void VUniversalEntry::showEvent(QShowEvent *p_event) -{ - QWidget::showEvent(p_event); - - // Fix Chinese input method issue. - activateWindow(); - - m_cmdEdit->setFocus(); - m_cmdEdit->selectAll(); - - if (m_lastEntry) { - m_lastEntry->m_entry->entryShown(m_lastEntry->m_id, getCommandFromEdit()); - } -} - -void VUniversalEntry::setAvailableRect(const QRect &p_rect) -{ - m_availableRect = p_rect; - - if (m_availableRect.width() < m_minimumWidth) { - m_availableRect.setWidth(m_minimumWidth); - } - - setMaximumSize(m_availableRect.size()); -} - -void VUniversalEntry::registerEntry(QChar p_key, IUniversalEntry *p_entry, int p_id) -{ - Q_ASSERT(!m_entries.contains(p_key)); - - p_entry->setParent(this); - p_entry->setWidgetParent(this); - connect(p_entry, &IUniversalEntry::widgetUpdated, - this, [this]() { - if (m_lastEntry) { - m_container->setWidget(m_lastEntry->m_entry->widget(m_lastEntry->m_id)); - } else { - m_container->adjustSizeByWidget(); - } - - adjustSize(); - }); - connect(p_entry, &IUniversalEntry::stateUpdated, - this, &VUniversalEntry::updateState); - connect(p_entry, &IUniversalEntry::requestHideUniversalEntry, - this, &VUniversalEntry::hide); - - m_entries.insert(p_key, Entry(p_entry, p_id)); - m_infoWidget->addItem(QString("%1: %2").arg(p_key) - .arg(p_entry->description(p_id))); - m_infoWidget->updateGeometry(); - - if (m_listEntryKey.isNull()) { - if (dynamic_cast(p_entry)) { - m_listEntryKey = p_key; - } - } -} - -void VUniversalEntry::processCommand() -{ - if (!m_inQueue.testAndSetRelaxed(0, 1)) { - // There is already a job in queue. - qDebug() << "already a job in queue, pend a new job and ask to stop"; - m_pendingCommand = true; - if (m_lastEntry) { - m_lastEntry->m_entry->askToStop(m_lastEntry->m_id); - } - - return; - } - -redo: - QString cmd = m_cmdEdit->getEvaluatedText(); - processCommand(cmd); - if (m_pendingCommand && cmd != m_cmdEdit->getEvaluatedText()) { - // Handle pending job. - qDebug() << "handle pending job" << cmd; - m_pendingCommand = false; - goto redo; - } - - m_inQueue.store(0); -} - -void VUniversalEntry::processCommand(const QString &p_cmd) -{ - if (p_cmd.isEmpty()) { - clear(); - return; - } - - auto it = m_entries.find(p_cmd[0]); - if (it == m_entries.end()) { - clear(); - return; - } - - const Entry &entry = it.value(); - if (m_lastEntry && m_lastEntry != &entry) { - m_lastEntry->m_entry->clear(m_lastEntry->m_id); - } - - m_lastEntry = &entry; - m_container->setWidget(entry.m_entry->widget(entry.m_id)); - adjustSize(); - entry.m_entry->processCommand(entry.m_id, p_cmd.mid(1)); -} - -void VUniversalEntry::clear() -{ - if (m_lastEntry) { - m_lastEntry->m_entry->clear(m_lastEntry->m_id); - m_lastEntry = NULL; - } - - m_container->setWidget(m_infoWidget); - adjustSize(); -} - -void VUniversalEntry::keyPressEvent(QKeyEvent *p_event) -{ - int modifiers = p_event->modifiers(); - bool forward = true; - switch (p_event->key()) { - case Qt::Key_BracketLeft: - if (VUtils::isControlModifierForVim(modifiers)) { - // Hide. - hide(); - return; - } - - break; - - case Qt::Key_Escape: - hide(); - return; - - // Up/Down Ctrl+K/J to navigate to next item. - case Qt::Key_Up: - forward = false; - V_FALLTHROUGH; - case Qt::Key_Down: - if (m_lastEntry) { - m_lastEntry->m_entry->selectNextItem(m_lastEntry->m_id, forward); - return; - } - - break; - - case Qt::Key_K: - forward = false; - V_FALLTHROUGH; - case Qt::Key_J: - if (m_lastEntry && VUtils::isControlModifierForVim(modifiers)) { - m_lastEntry->m_entry->selectNextItem(m_lastEntry->m_id, forward); - return; - } - - break; - - case Qt::Key_Enter: - // Fall through. - V_FALLTHROUGH; - case Qt::Key_Return: - { - if (m_lastEntry) { - m_lastEntry->m_entry->activate(m_lastEntry->m_id); - return; - } - - break; - } - - case Qt::Key_E: - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+E to eliminate input except the command key. - QString cmd = m_cmdEdit->getEvaluatedText(); - if (!cmd.isEmpty()) { - m_cmdTimer->stop(); - m_cmdEdit->setText(cmd.left(1)); - processCommand(); - } - - return; - } - - break; - - case Qt::Key_F: - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+F to select the command key. - QString cmd = m_cmdEdit->getEvaluatedText(); - if (!cmd.isEmpty()) { - m_cmdTimer->stop(); - m_cmdEdit->setSelection(0, 1); - } - - return; - } - - break; - - case Qt::Key_D: - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+D to cancel current command. - m_pendingCommand = false; - if (m_lastEntry) { - m_lastEntry->m_entry->askToStop(m_lastEntry->m_id); - } - - return; - } - - break; - - case Qt::Key_L: - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+L to go up a level. - if (m_lastEntry) { - m_lastEntry->m_entry->selectParentItem(m_lastEntry->m_id); - } - - return; - } - - break; - - case Qt::Key_I: - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+I to expand or collapse an item. - if (m_lastEntry) { - m_lastEntry->m_entry->toggleItemExpanded(m_lastEntry->m_id); - } - - return; - } - - break; - - case Qt::Key_S: - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+S to sort the items. - // UE could just alternate among all the sort modes. - if (m_lastEntry) { - m_lastEntry->m_entry->sort(m_lastEntry->m_id); - } - - return; - } - - break; - - case Qt::Key_M: - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+M to browse current item folder or the folder containing current - // item. - if (m_lastEntry && !m_listEntryKey.isNull()) { - QString folderPath = m_lastEntry->m_entry->currentItemFolder(m_lastEntry->m_id); - if (!folderPath.isEmpty()) { - m_cmdTimer->stop(); - Q_ASSERT(m_entries.contains(m_listEntryKey)); - const Entry &entry = m_entries[m_listEntryKey]; - static_cast(entry.m_entry)->setFolderPath(folderPath); - m_cmdEdit->setText(m_listEntryKey); - processCommand(); - } - } - - return; - } - - break; - - case Qt::Key_B: - if (VUtils::isControlModifierForVim(modifiers)) { - // Ctrl+B to expand/collapse all the items. - if (m_lastEntry) { - m_lastEntry->m_entry->expandCollapseAll(m_lastEntry->m_id); - } - - return; - } - - break; - - default: - break; - } - - QWidget::keyPressEvent(p_event); -} - -void VUniversalEntry::paintEvent(QPaintEvent *p_event) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - - QWidget::paintEvent(p_event); -} - -void VUniversalEntry::updateState(IUniversalEntry::State p_state) -{ - QString fg; - switch (p_state) { - case IUniversalEntry::Busy: - fg = g_palette->color("ue_cmd_busy_border"); - break; - - case IUniversalEntry::Fail: - fg = g_palette->color("ue_cmd_fail_border"); - break; - - default: - break; - } - - if (fg.isEmpty()) { - m_cmdEdit->setStyleSheet(m_cmdStyleSheet); - } else { - m_cmdEdit->setStyleSheet(QString("border-color: %1;").arg(fg)); - } -} - -QString VUniversalEntry::getCommandFromEdit() const -{ - QString cmd = m_cmdEdit->getEvaluatedText(); - return cmd.mid(1); -} diff --git a/src/vuniversalentry.h b/src/vuniversalentry.h deleted file mode 100644 index 113ef816..00000000 --- a/src/vuniversalentry.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef VUNIVERSALENTRY_H -#define VUNIVERSALENTRY_H - -#include -#include -#include -#include - -#include "iuniversalentry.h" -#include "utils/vutils.h" - -class VMetaWordLineEdit; -class QVBoxLayout; -class QHideEvent; -class QShowEvent; -class QPaintEvent; -class QKeyEvent; -class QTimer; -class VListWidget; - -class VUniversalEntryContainer : public QWidget -{ - Q_OBJECT -public: - VUniversalEntryContainer(QWidget *p_parent = nullptr); - - void clear(); - - void setWidget(QWidget *p_widget); - - void adjustSizeByWidget(); - -protected: - QSize sizeHint() const Q_DECL_OVERRIDE; - -private: - QWidget *m_widget; - - QVBoxLayout *m_layout; -}; - - -class VUniversalEntry : public QWidget -{ - Q_OBJECT -public: - explicit VUniversalEntry(QWidget *p_parent = nullptr); - - // Set the availabel width and height. - void setAvailableRect(const QRect &p_rect); - - // Register an entry at @p_key. - // Different entries may use the same @p_entry, in which case they can use - // @p_id to distinguish. - void registerEntry(QChar p_key, IUniversalEntry *p_entry, int p_id = 0); - - static QString fileNameWithDir(const QString &p_name, const QString &p_path); - -signals: - // Exit Universal Entry. - void exited(); - -protected: - void hideEvent(QHideEvent *p_event) Q_DECL_OVERRIDE; - - void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; - - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE; - -private: - struct Entry - { - Entry() - : m_entry(NULL), m_id(-1) - { - } - - Entry(IUniversalEntry *p_entry, int p_id) - : m_entry(p_entry), m_id(p_id) - { - } - - IUniversalEntry *m_entry; - int m_id; - }; - - void setupUI(); - - void clear(); - - void processCommand(); - - void processCommand(const QString &p_cmd); - - void updateState(IUniversalEntry::State p_state); - - QString getCommandFromEdit() const; - - VMetaWordLineEdit *m_cmdEdit; - - VUniversalEntryContainer *m_container; - - // Rect availabel for the UE to use. - QRect m_availableRect; - - int m_minimumWidth; - - QHash m_entries; - - // Widget to list all entries. - VListWidget *m_infoWidget; - - QTimer *m_cmdTimer; - - // Last used Entry. - const Entry *m_lastEntry; - - // Entry to list folder content. - QChar m_listEntryKey; - - // The CMD edit's original style sheet. - QString m_cmdStyleSheet; - - QAtomicInt m_inQueue; - - bool m_pendingCommand; -}; - -inline QString VUniversalEntry::fileNameWithDir(const QString &p_name, const QString &p_path) -{ - return VUtils::parentDirName(p_path) + " / " + p_name; -} -#endif // VUNIVERSALENTRY_H diff --git a/src/vvimcmdlineedit.cpp b/src/vvimcmdlineedit.cpp deleted file mode 100644 index 8bda06ec..00000000 --- a/src/vvimcmdlineedit.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include "vvimcmdlineedit.h" - -#include -#include -#include - -#include "vpalette.h" - -extern VPalette *g_palette; - -VVimCmdLineEdit::VVimCmdLineEdit(QWidget *p_parent) - : VLineEdit(p_parent), m_type(VVim::CommandLineType::Invalid), - m_registerPending(false), m_enableInputMethod(true) -{ - // When user delete all the text, cancel command input. - connect(this, &VVimCmdLineEdit::textChanged, - this, [this](const QString &p_text){ - if (p_text.isEmpty()) { - emit commandCancelled(); - } else { - emit commandChanged(m_type, p_text.right(p_text.size() - 1)); - } - }); - - connect(this, &VVimCmdLineEdit::textEdited, - this, [this](const QString &p_text){ - if (p_text.size() < 2) { - m_userLastInput.clear(); - } else { - m_userLastInput = p_text.right(p_text.size() - 1); - } - }); - - m_originStyleSheet = styleSheet(); -} - -QString VVimCmdLineEdit::getCommand() const -{ - QString tx = text(); - if (tx.size() < 2) { - return ""; - } else { - return tx.right(tx.size() - 1); - } -} - -QString VVimCmdLineEdit::commandLineTypeLeader(VVim::CommandLineType p_type) -{ - QString leader; - switch (p_type) { - case VVim::CommandLineType::Command: - leader = ":"; - break; - - case VVim::CommandLineType::SearchForward: - leader = "/"; - break; - - case VVim::CommandLineType::SearchBackward: - leader = "?"; - break; - - case VVim::CommandLineType::Invalid: - leader.clear(); - break; - - default: - Q_ASSERT(false); - break; - } - - return leader; -} - -void VVimCmdLineEdit::reset(VVim::CommandLineType p_type) -{ - m_type = p_type; - m_userLastInput.clear(); - setCommand(""); - show(); - setFocus(); - setInputMethodEnabled(p_type != VVim::CommandLineType::Command); -} - -void VVimCmdLineEdit::setInputMethodEnabled(bool p_enabled) -{ - if (m_enableInputMethod != p_enabled) { - m_enableInputMethod = p_enabled; - - QInputMethod *im = QGuiApplication::inputMethod(); - im->reset(); - // Ask input method to query current state, which will call inputMethodQuery(). - im->update(Qt::ImEnabled); - } -} - -QVariant VVimCmdLineEdit::inputMethodQuery(Qt::InputMethodQuery p_query) const -{ - if (p_query == Qt::ImEnabled) { - return m_enableInputMethod; - } - - return VLineEdit::inputMethodQuery(p_query); -} - -// See if @p_modifiers is Control which is different on macOs and Windows. -static bool isControlModifier(int p_modifiers) -{ -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) - return p_modifiers == Qt::MetaModifier; -#else - return p_modifiers == Qt::ControlModifier; -#endif -} - -void VVimCmdLineEdit::keyPressEvent(QKeyEvent *p_event) -{ - int key = p_event->key(); - int modifiers = p_event->modifiers(); - - if (m_registerPending) { - // Ctrl and Shift may be sent out first. - if (key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Meta) { - goto exit; - } - - // Expecting a register name. - emit requestRegister(key, modifiers); - - p_event->accept(); - setRegisterPending(false); - return; - } - - if ((key == Qt::Key_Return && modifiers == Qt::NoModifier) - || (key == Qt::Key_Enter && modifiers == Qt::KeypadModifier)) { - // Enter, complete the command line input. - p_event->accept(); - emit commandFinished(m_type, getCommand()); - return; - } else if (key == Qt::Key_Escape - || (key == Qt::Key_BracketLeft && isControlModifier(modifiers))) { - // Exit command line input. - setText(commandLineTypeLeader(m_type)); - p_event->accept(); - emit commandCancelled(); - return; - } - - switch (key) { - case Qt::Key_U: - if (isControlModifier(modifiers)) { - // Ctrl+U, delete all user input. - setText(commandLineTypeLeader(m_type)); - p_event->accept(); - return; - } - - break; - - case Qt::Key_N: - if (!isControlModifier(modifiers)) { - break; - } - // Ctrl+N, request next command. - // Fall through. - case Qt::Key_Down: - { - emit requestNextCommand(m_type, getCommand()); - p_event->accept(); - return; - } - - case Qt::Key_P: - if (!isControlModifier(modifiers)) { - break; - } - // Ctrl+P, request previous command. - // Fall through. - case Qt::Key_Up: - { - emit requestPreviousCommand(m_type, getCommand()); - p_event->accept(); - return; - } - - case Qt::Key_R: - { - if (isControlModifier(modifiers)) { - // Ctrl+R, insert the content of a register. - setRegisterPending(true); - p_event->accept(); - return; - } - } - - default: - break; - } - -exit: - VLineEdit::keyPressEvent(p_event); -} - -void VVimCmdLineEdit::focusOutEvent(QFocusEvent *p_event) -{ - if (p_event->reason() != Qt::ActiveWindowFocusReason) { - emit commandCancelled(); - } - - VLineEdit::focusOutEvent(p_event); -} - -void VVimCmdLineEdit::setCommand(const QString &p_cmd) -{ - setText(commandLineTypeLeader(m_type) + p_cmd); -} - -void VVimCmdLineEdit::restoreUserLastInput() -{ - setCommand(m_userLastInput); -} - -void VVimCmdLineEdit::setRegisterPending(bool p_pending) -{ - if (p_pending && !m_registerPending) { - // Going to pending. - setStyleSheet(QString("background: %1;").arg(g_palette->color("vim_indicator_cmd_edit_pending_bg"))); - } else if (!p_pending && m_registerPending) { - // Leaving pending. - setStyleSheet(m_originStyleSheet); - } - - m_registerPending = p_pending; -} diff --git a/src/vvimcmdlineedit.h b/src/vvimcmdlineedit.h deleted file mode 100644 index 5181f02d..00000000 --- a/src/vvimcmdlineedit.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef VVIMCMDLINEEDIT_H -#define VVIMCMDLINEEDIT_H - -#include "vlineedit.h" -#include "utils/vvim.h" - -class QKeyEvent; -class QFocusEvent; - -class VVimCmdLineEdit : public VLineEdit -{ - Q_OBJECT - -public: - explicit VVimCmdLineEdit(QWidget *p_parent = 0); - - void reset(VVim::CommandLineType p_type); - - // Set the command to @p_cmd with leader unchanged. - void setCommand(const QString &p_cmd); - - // Get the command. - QString getCommand() const; - - void restoreUserLastInput(); - - QVariant inputMethodQuery(Qt::InputMethodQuery p_query) const Q_DECL_OVERRIDE; - -signals: - // User has finished the input and the command is ready to execute. - void commandFinished(VVim::CommandLineType p_type, const QString &p_cmd); - - // User cancelled the input. - void commandCancelled(); - - // User request the next command in the history. - void requestNextCommand(VVim::CommandLineType p_type, const QString &p_cmd); - - // User request the previous command in the history. - void requestPreviousCommand(VVim::CommandLineType p_type, const QString &p_cmd); - - // Emit when the input text changed. - void commandChanged(VVim::CommandLineType p_type, const QString &p_cmd); - - // Emit when expecting to read a register. - void requestRegister(int p_key, int p_modifiers); - -protected: - void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; - - void focusOutEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; - -private: - // Return the leader of @p_type. - QString commandLineTypeLeader(VVim::CommandLineType p_type); - - void setRegisterPending(bool p_pending); - - void setInputMethodEnabled(bool p_enabled); - - VVim::CommandLineType m_type; - - // The latest command user input. - QString m_userLastInput; - - // Whether we are expecting a register name to read. - bool m_registerPending; - - QString m_originStyleSheet; - - // Whether enable input method. - bool m_enableInputMethod; -}; -#endif // VVIMCMDLINEEDIT_H diff --git a/src/vvimindicator.cpp b/src/vvimindicator.cpp deleted file mode 100644 index 866e6939..00000000 --- a/src/vvimindicator.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include "vvimindicator.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vconfigmanager.h" -#include "vbuttonwithwidget.h" -#include "vpalette.h" - -extern VConfigManager *g_config; - -VVimIndicator::VVimIndicator(QWidget *p_parent) - : QWidget(p_parent), m_vim(NULL) -{ - setupUI(); -} - -void VVimIndicator::setupUI() -{ - m_modeLabel = new QLabel(this); - m_modeLabel->setProperty("VimIndicatorModeLabel", true); - - QTreeWidget *regTree = new QTreeWidget(this); - regTree->setProperty("ItemBorder", true); - regTree->setRootIsDecorated(false); - regTree->setColumnCount(2); - regTree->header()->setStretchLastSection(true); - QStringList headers; - headers << tr("Register") << tr("Value"); - regTree->setHeaderLabels(headers); - - m_regBtn = new VButtonWithWidget("\"", - regTree, - this); - m_regBtn->setToolTip(tr("Registers")); - m_regBtn->setProperty("StatusBtn", true); - m_regBtn->setFocusPolicy(Qt::NoFocus); - connect(m_regBtn, &VButtonWithWidget::popupWidgetAboutToShow, - this, &VVimIndicator::updateRegistersTree); - - QTreeWidget *markTree = new QTreeWidget(this); - markTree->setProperty("ItemBorder", true); - markTree->setRootIsDecorated(false); - markTree->setColumnCount(4); - markTree->header()->setStretchLastSection(true); - headers.clear(); - headers << tr("Mark") << tr("Line") << tr("Column") << tr("Text"); - markTree->setHeaderLabels(headers); - - m_markBtn = new VButtonWithWidget("[]", - markTree, - this); - m_markBtn->setToolTip(tr("Marks")); - m_markBtn->setProperty("StatusBtn", true); - m_markBtn->setFocusPolicy(Qt::NoFocus); - connect(m_markBtn, &VButtonWithWidget::popupWidgetAboutToShow, - this, &VVimIndicator::updateMarksTree); - - m_keyLabel = new QLabel(this); - m_keyLabel->setProperty("VimIndicatorKeyLabel", true); - QFontMetrics metric(font()); - m_keyLabel->setMinimumWidth(metric.width('A') * 5); - - QHBoxLayout *mainLayout = new QHBoxLayout(this); - mainLayout->addWidget(m_modeLabel); - mainLayout->addWidget(m_regBtn); - mainLayout->addWidget(m_markBtn); - mainLayout->addWidget(m_keyLabel); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -QString VVimIndicator::modeToString(VimMode p_mode) const -{ - QString str; - - switch (p_mode) { - case VimMode::Normal: - str = tr("Normal"); - break; - - case VimMode::Insert: - str = tr("Insert"); - break; - - case VimMode::Visual: - str = tr("Visual"); - break; - - case VimMode::VisualLine: - str = tr("VisualLine"); - break; - - case VimMode::Replace: - str = tr("Replace"); - break; - - default: - str = tr("Unknown"); - break; - } - - return str; -} - -static QString modeBackgroundColor(VimMode p_mode) -{ - QString color; - - switch (p_mode) { - case VimMode::Normal: - color = g_config->getEditorVimNormalBg(); - break; - - case VimMode::Insert: - color = g_config->getEditorVimInsertBg(); - break; - - case VimMode::Visual: - color = g_config->getEditorVimVisualBg(); - break; - - case VimMode::VisualLine: - color = g_config->getEditorVimVisualBg(); - break; - - case VimMode::Replace: - color = g_config->getEditorVimReplaceBg(); - break; - - default: - color = "red"; - break; - } - - return color; -} - -static void fillTreeItemsWithRegisters(QTreeWidget *p_tree, - const QMap &p_regs) -{ - p_tree->clear(); - for (auto const ® : p_regs) { - if (reg.m_value.isEmpty()) { - continue; - } - - QStringList itemStr; - itemStr << reg.m_name << reg.m_value; - QTreeWidgetItem *item = new QTreeWidgetItem(p_tree, itemStr); - item->setFlags(item->flags() | Qt::ItemIsSelectable | Qt::ItemIsEditable); - } - - p_tree->resizeColumnToContents(0); - p_tree->resizeColumnToContents(1); -} - -void VVimIndicator::update(const VVim *p_vim) -{ - m_vim = const_cast(p_vim); - if (!m_vim) { - return; - } - - VimMode mode = VimMode::Normal; - QChar curRegName(' '); - QChar lastUsedMark; - QString pendingKeys; - if (p_vim) { - mode = p_vim->getMode(); - curRegName = p_vim->getCurrentRegisterName(); - lastUsedMark = p_vim->getMarks().getLastUsedMark(); - pendingKeys = p_vim->getPendingKeys(); - } - - m_modeLabel->setStyleSheet(QString("background: %1;").arg(modeBackgroundColor(mode))); - m_modeLabel->setText(modeToString(mode)); - - m_regBtn->setText(curRegName); - - QString markText = QString("[%1]") - .arg(lastUsedMark.isNull() ? QChar(' ') : lastUsedMark); - m_markBtn->setText(markText); - - m_keyLabel->setText(pendingKeys); -} - -void VVimIndicator::updateRegistersTree(QWidget *p_widget) -{ - QTreeWidget *regTree = dynamic_cast(p_widget); - if (!m_vim) { - regTree->clear(); - return; - } - - const QMap ®s = m_vim->getRegisters(); - fillTreeItemsWithRegisters(regTree, regs); -} - -static void fillTreeItemsWithMarks(QTreeWidget *p_tree, - const QMap &p_marks) -{ - p_tree->clear(); - for (auto const &mark : p_marks) { - if (!mark.m_location.isValid()) { - continue; - } - - QStringList itemStr; - itemStr << mark.m_name << QString::number(mark.m_location.m_blockNumber + 1) - << QString::number(mark.m_location.m_positionInBlock) << mark.m_text; - QTreeWidgetItem *item = new QTreeWidgetItem(p_tree, itemStr); - item->setFlags(item->flags() | Qt::ItemIsSelectable | Qt::ItemIsEditable); - } - - p_tree->resizeColumnToContents(0); - p_tree->resizeColumnToContents(1); - p_tree->resizeColumnToContents(2); - p_tree->resizeColumnToContents(3); -} - -void VVimIndicator::updateMarksTree(QWidget *p_widget) -{ - QTreeWidget *markTree = dynamic_cast(p_widget); - if (!m_vim) { - markTree->clear(); - return; - } - - const QMap &marks = m_vim->getMarks().getMarks(); - fillTreeItemsWithMarks(markTree, marks); -} diff --git a/src/vvimindicator.h b/src/vvimindicator.h deleted file mode 100644 index 169db519..00000000 --- a/src/vvimindicator.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef VVIMINDICATOR_H -#define VVIMINDICATOR_H - -#include -#include -#include "utils/vvim.h" - -class QLabel; -class VButtonWithWidget; -class QKeyEvent; -class QFocusEvent; - -class VVimIndicator : public QWidget -{ - Q_OBJECT - -public: - explicit VVimIndicator(QWidget *p_parent = 0); - - // Update indicator according to @p_vim. - void update(const VVim *p_vim); - -private slots: - void updateRegistersTree(QWidget *p_widget); - - void updateMarksTree(QWidget *p_widget); - -private: - void setupUI(); - - QString modeToString(VimMode p_mode) const; - - // Indicate the mode. - QLabel *m_modeLabel; - - // Indicate the registers. - VButtonWithWidget *m_regBtn; - - // Indicate the marks. - VButtonWithWidget *m_markBtn; - - // Indicate the pending keys. - QLabel *m_keyLabel; - - QPointer m_vim; -}; - -#endif // VVIMINDICATOR_H diff --git a/src/vwaitingwidget.cpp b/src/vwaitingwidget.cpp deleted file mode 100644 index 1efd4e64..00000000 --- a/src/vwaitingwidget.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "vwaitingwidget.h" - -#include -#include -#include -#include - -VWaitingWidget::VWaitingWidget(QWidget *p_parent) - : QWidget(p_parent) -{ - setupUI(); -} - -void VWaitingWidget::setupUI() -{ - QSize imgSize(64, 64); - QLabel *logoLabel = new QLabel(); - logoLabel->setPixmap(QPixmap(":/resources/icons/vnote.svg").scaled(imgSize, Qt::KeepAspectRatio)); - - QHBoxLayout *layout = new QHBoxLayout(); - layout->addStretch(); - layout->addWidget(logoLabel); - layout->addStretch(); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addStretch(); - mainLayout->addLayout(layout); - mainLayout->addStretch(); - - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} diff --git a/src/vwaitingwidget.h b/src/vwaitingwidget.h deleted file mode 100644 index b81fc433..00000000 --- a/src/vwaitingwidget.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef VWAITINGWIDGET_H -#define VWAITINGWIDGET_H - -#include - -class QLabel; - - -class VWaitingWidget : public QWidget -{ - Q_OBJECT -public: - explicit VWaitingWidget(QWidget *p_parent = nullptr); - -private: - void setupUI(); -}; - -#endif // VWAITINGWIDGET_H diff --git a/src/vwebview.cpp b/src/vwebview.cpp deleted file mode 100644 index 2524ba1e..00000000 --- a/src/vwebview.cpp +++ /dev/null @@ -1,483 +0,0 @@ -#include "vwebview.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vfile.h" -#include "utils/vclipboardutils.h" -#include "utils/viconutils.h" -#include "vconfigmanager.h" -#include "utils/vwebutils.h" -#include "utils/vutils.h" - -extern VConfigManager *g_config; - -extern VWebUtils *g_webUtils; - -// We set the property of the clipboard to mark that the URL copied in the -// clipboard has been altered. -static const QString c_ClipboardPropertyMark = "CopiedImageURLAltered"; - -VWebView::VWebView(VFile *p_file, QWidget *p_parent) - : QWebEngineView(p_parent), - m_file(p_file), - m_copyImageUrlActionHooked(false), - m_afterCopyImage(false), - m_inPreview(false) -{ - setAcceptDrops(false); - - connect(QApplication::clipboard(), &QClipboard::changed, - this, &VWebView::handleClipboardChanged); -} - -void VWebView::contextMenuEvent(QContextMenuEvent *p_event) -{ - QMenu *menu = page()->createStandardContextMenu(); - menu->setToolTipsVisible(true); - - const QList actions = menu->actions(); - QAction *firstAction = actions.isEmpty() ? NULL : actions[0]; - - bool selection = hasSelection(); - -#if defined(Q_OS_WIN) - if (!m_copyImageUrlActionHooked) { - // "Copy Image URL" action will put the encoded URL to the clipboard as text - // and the URL as URLs. If the URL contains Chinese, OneNote or Word could not - // recognize it. - // We need to change it to only-space-encoded text. - QAction *copyImageUrlAct = pageAction(QWebEnginePage::CopyImageUrlToClipboard); - if (actions.contains(copyImageUrlAct)) { - connect(copyImageUrlAct, &QAction::triggered, - this, &VWebView::handleCopyImageUrlAction); - - m_copyImageUrlActionHooked = true; - - qDebug() << "hooked CopyImageUrl action" << copyImageUrlAct; - } - } -#endif - - if (!selection) { - if (m_inPreview) { - QAction *expandAct = new QAction(tr("Expand/Restore Preview Area"), menu); - VUtils::fixTextWithCaptainShortcut(expandAct, "ExpandLivePreview"); - connect(expandAct, &QAction::triggered, - this, &VWebView::requestExpandRestorePreviewArea); - menu->insertAction(firstAction, expandAct); - - initPreviewTunnelMenu(firstAction, menu); - - if (firstAction) { - menu->insertSeparator(firstAction); - } - } else { - if (m_file && m_file->isModifiable()) { - QAction *editAct= new QAction(VIconUtils::menuIcon(":/resources/icons/edit_note.svg"), - tr("&Edit"), - menu); - editAct->setToolTip(tr("Edit current note")); - connect(editAct, &QAction::triggered, - this, &VWebView::handleEditAction); - menu->insertAction(firstAction, editAct); - if (firstAction) { - menu->insertSeparator(firstAction); - } - } - - QAction *savePageAct = new QAction(QWebEnginePage::tr("Save &Page"), menu); - connect(savePageAct, &QAction::triggered, - this, &VWebView::requestSavePage); - menu->addAction(savePageAct); - } - } - - // Add Copy As menu. - { - QAction *copyAct = pageAction(QWebEnginePage::Copy); - if (actions.contains(copyAct) && !m_inPreview) { - initCopyAsMenu(copyAct, menu); - } - } - - // We need to replace the "Copy Image" action: - // - the default one use the fully-encoded URL to fetch the image while - // Windows seems to not recognize it. - // - We need to remove the html to let it be recognized by some web pages. - QAction *defaultCopyImageAct = pageAction(QWebEnginePage::CopyImageToClipboard); - if (actions.contains(defaultCopyImageAct)) { - QAction *copyImageAct = new QAction(defaultCopyImageAct->text(), menu); - copyImageAct->setToolTip(defaultCopyImageAct->toolTip()); - connect(copyImageAct, &QAction::triggered, - this, &VWebView::copyImage); - menu->insertAction(defaultCopyImageAct, copyImageAct); - defaultCopyImageAct->setVisible(false); - } - - // Add Copy All As menu. - if (!m_inPreview) { - initCopyAllAsMenu(menu); - } - - hideUnusedActions(menu); - - p_event->accept(); - - bool valid = false; - for (auto act : menu->actions()) { - if (act->isVisible()) { - valid = true; - break; - } - } - - if (valid) { - menu->exec(p_event->globalPos()); - } - - delete menu; -} - -void VWebView::handleEditAction() -{ - emit editNote(); -} - -void VWebView::copyImage() -{ -#if defined(Q_OS_WIN) - Q_ASSERT(m_copyImageUrlActionHooked); - // triggerPageAction(QWebEnginePage::CopyImageUrlToClipboard) will not really - // trigger the corresponding action. It just do the stuff directly. - QAction *copyImageUrlAct = pageAction(QWebEnginePage::CopyImageUrlToClipboard); - copyImageUrlAct->trigger(); - - QCoreApplication::processEvents(); - - QClipboard *clipboard = QApplication::clipboard(); - if (clipboard->property(c_ClipboardPropertyMark.toLatin1()).toBool()) { - const QMimeData *mimeData = clipboard->mimeData(); - QString imgPath; - if (mimeData->hasUrls()) { - QList urls = mimeData->urls(); - if (!urls.isEmpty() && urls[0].isLocalFile()) { - imgPath = urls[0].toLocalFile(); - } - } - - if (!imgPath.isEmpty()) { - QImage img = VUtils::imageFromFile(imgPath); - if (!img.isNull()) { - m_afterCopyImage = false; - VClipboardUtils::setImageToClipboard(clipboard, img, QClipboard::Clipboard); - qDebug() << "clipboard copy image via URL" << imgPath; - return; - } - } - } -#endif - - m_afterCopyImage = true; - - // Fall back. - triggerPageAction(QWebEnginePage::CopyImageToClipboard); -} - -void VWebView::handleCopyImageUrlAction() -{ - // To avoid failure of setting clipboard mime data. - QCoreApplication::processEvents(); - - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - clipboard->setProperty(c_ClipboardPropertyMark.toLatin1(), false); - if (clipboard->ownsClipboard() - && mimeData->hasText() - && mimeData->hasUrls()) { - QString text = mimeData->text(); - QList urls = mimeData->urls(); - if (urls.size() == 1 - && urls[0].isLocalFile() - && urls[0].toEncoded() == text) { - QString spaceOnlyText = urls[0].toString(QUrl::EncodeSpaces); - if (spaceOnlyText != text) { - // Set new mime data. - QMimeData *data = new QMimeData(); - data->setUrls(urls); - data->setText(spaceOnlyText); - VClipboardUtils::setMimeDataToClipboard(clipboard, data, QClipboard::Clipboard); - - clipboard->setProperty(c_ClipboardPropertyMark.toLatin1(), true); - qDebug() << "clipboard copy image URL altered" << spaceOnlyText; - } - } - } -} - -void VWebView::hideUnusedActions(QMenu *p_menu) -{ - QList unusedActions; - - // QWebEnginePage uses different actions of Back/Forward/Reload. - // [Woboq](https://code.woboq.org/qt5/qtwebengine/src/webenginewidgets/api/qwebenginepage.cpp.html#1652) - // We tell these three actions by name. - const QStringList actionNames({QWebEnginePage::tr("&Back"), - QWebEnginePage::tr("&Forward"), - QWebEnginePage::tr("&Reload")}); - - const QList actions = p_menu->actions(); - for (auto it : actions) { - if (actionNames.contains(it->text())) { - unusedActions.append(it); - } - } - - // ViewSource. - QAction *act = pageAction(QWebEnginePage::ViewSource); - unusedActions.append(act); - - // DownloadImageToDisk. - act = pageAction(QWebEnginePage::DownloadImageToDisk); - unusedActions.append(act); - - // DownloadLinkToDisk. - act = pageAction(QWebEnginePage::DownloadLinkToDisk); - unusedActions.append(act); - - for (auto it : unusedActions) { - if (it) { - it->setVisible(false); - } - } -} - -bool VWebView::removeStyles(QString &p_html) -{ - bool changed = false; - - const QStringList &styles = g_config->getStylesToRemoveWhenCopied(); - if (styles.isEmpty()) { - return changed; - } - - QRegExp tagReg("(<[^>]+\\sstyle=[^>]*>)"); - - int pos = 0; - while (pos < p_html.size()) { - int idx = p_html.indexOf(tagReg, pos); - if (idx == -1) { - break; - } - - QString styleStr = tagReg.cap(1); - QString alteredStyleStr = styleStr; - - QString regPatt("(\\s|\")%1:[^;]+;"); - for (auto const & sty : styles) { - QRegExp reg(regPatt.arg(sty)); - alteredStyleStr.replace(reg, "\\1"); - } - - pos = idx + tagReg.matchedLength(); - if (styleStr != alteredStyleStr) { - pos = pos + alteredStyleStr.size() - styleStr.size(); - p_html.replace(idx, tagReg.matchedLength(), alteredStyleStr); - changed = true; - } - } - - return changed; -} - -void VWebView::handleClipboardChanged(QClipboard::Mode p_mode) -{ - if (!hasFocus() - || p_mode != QClipboard::Clipboard) { - return; - } - - QClipboard *clipboard = QApplication::clipboard(); - if (!clipboard->ownsClipboard()) { - return; - } - - const QMimeData *mimeData = clipboard->mimeData(); - - QString copyTarget = m_copyTarget; - m_copyTarget.clear(); - - if (m_afterCopyImage) { - m_afterCopyImage = false; - removeHtmlFromImageData(clipboard, mimeData); - } else { - alterHtmlMimeData(clipboard, mimeData, copyTarget); - } -} - -void VWebView::alterHtmlMimeData(QClipboard *p_clipboard, - const QMimeData *p_mimeData, - const QString &p_copyTarget) -{ - if (!p_mimeData->hasHtml() - || p_mimeData->hasImage() - || p_copyTarget.isEmpty()) { - return; - } - - QString html = p_mimeData->html(); - if (!g_webUtils->alterHtmlAsTarget(url(), html, p_copyTarget)) { - return; - } - - // Set new mime data. - QMimeData *data = VClipboardUtils::cloneMimeData(p_mimeData); - data->setHtml(html); - - VClipboardUtils::setMimeDataToClipboard(p_clipboard, data, QClipboard::Clipboard); - qDebug() << "altered clipboard's Html"; -} - -void VWebView::removeHtmlFromImageData(QClipboard *p_clipboard, - const QMimeData *p_mimeData) -{ - if (!p_mimeData->hasImage()) { - return; - } - - if (p_mimeData->hasHtml()) { - qDebug() << "remove html from image data" << p_mimeData->html(); - QMimeData *data = new QMimeData(); - data->setImageData(p_mimeData->imageData()); - VClipboardUtils::setMimeDataToClipboard(p_clipboard, data, QClipboard::Clipboard); - } -} - -void VWebView::initCopyAsMenu(QAction *p_after, QMenu *p_menu) -{ - QStringList targets = g_webUtils->getCopyTargetsName(); - if (targets.isEmpty()) { - return; - } - - QMenu *subMenu = new QMenu(tr("Copy As"), p_menu); - subMenu->setToolTipsVisible(true); - for (auto const & target : targets) { - QAction *act = new QAction(target, subMenu); - act->setData(target); - act->setToolTip(tr("Copy selected content using rules specified by target %1").arg(target)); - - subMenu->addAction(act); - } - - connect(subMenu, &QMenu::triggered, - this, &VWebView::handleCopyAsAction); - - QAction *menuAct = p_menu->insertMenu(p_after, subMenu); - p_menu->removeAction(p_after); - p_menu->insertAction(menuAct, p_after); -} - -void VWebView::handleCopyAsAction(QAction *p_act) -{ - if (!p_act) { - return; - } - - m_copyTarget = p_act->data().toString(); - - triggerPageAction(QWebEnginePage::Copy); -} - -void VWebView::initCopyAllAsMenu(QMenu *p_menu) -{ - QStringList targets = g_webUtils->getCopyTargetsName(); - if (targets.isEmpty()) { - return; - } - - QMenu *subMenu = new QMenu(tr("Copy All As"), p_menu); - subMenu->setToolTipsVisible(true); - for (auto const & target : targets) { - QAction *act = new QAction(target, subMenu); - act->setData(target); - act->setToolTip(tr("Copy all content using rules specified by target %1").arg(target)); - - subMenu->addAction(act); - } - - connect(subMenu, &QMenu::triggered, - this, &VWebView::handleCopyAllAsAction); - - p_menu->addSeparator(); - p_menu->addMenu(subMenu); -} - -void VWebView::handleCopyAllAsAction(QAction *p_act) -{ - if (!p_act) { - return; - } - - triggerPageAction(QWebEnginePage::SelectAll); - - m_copyTarget = p_act->data().toString(); - - triggerPageAction(QWebEnginePage::Copy); - - triggerPageAction(QWebEnginePage::Unselect); -} - -void VWebView::initPreviewTunnelMenu(QAction *p_before, QMenu *p_menu) -{ - QMenu *subMenu = new QMenu(tr("Live Preview Tunnel"), p_menu); - - int config = g_config->getSmartLivePreview(); - - QActionGroup *ag = new QActionGroup(subMenu); - QAction *act = ag->addAction(tr("Disabled")); - act->setData(SmartLivePreview::Disabled); - act->setCheckable(true); - if (act->data().toInt() == config) { - act->setChecked(true); - } - - act = ag->addAction(tr("Editor -> Preview")); - act->setData(SmartLivePreview::EditorToWeb); - act->setCheckable(true); - if (act->data().toInt() == config) { - act->setChecked(true); - } - - act = ag->addAction(tr("Preview -> Editor")); - act->setData(SmartLivePreview::WebToEditor); - act->setCheckable(true); - if (act->data().toInt() == config) { - act->setChecked(true); - } - - act = ag->addAction(tr("Bidirectional")); - act->setData(SmartLivePreview::EditorToWeb | SmartLivePreview::WebToEditor); - act->setCheckable(true); - if (act->data().toInt() == config) { - act->setChecked(true); - } - - connect(ag, &QActionGroup::triggered, - this, [](QAction *p_act) { - int data = p_act->data().toInt(); - g_config->setSmartLivePreview(data); - }); - - subMenu->addActions(ag->actions()); - - p_menu->insertMenu(p_before, subMenu); -} diff --git a/src/vwebview.h b/src/vwebview.h deleted file mode 100644 index 08988bc6..00000000 --- a/src/vwebview.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef VWEBVIEW_H -#define VWEBVIEW_H - -#include -#include -#include - -class VFile; -class QMenu; - -class VWebView : public QWebEngineView -{ - Q_OBJECT -public: - // @p_file could be NULL. - explicit VWebView(VFile *p_file, QWidget *p_parent = Q_NULLPTR); - - void setInPreview(bool p_preview); - -signals: - void editNote(); - - void requestSavePage(); - - void requestExpandRestorePreviewArea(); - -protected: - void contextMenuEvent(QContextMenuEvent *p_event); - -private slots: - void handleEditAction(); - - void handleCopyImageUrlAction(); - - void handleCopyAsAction(QAction *p_act); - - void handleCopyAllAsAction(QAction *p_act); - - // Copy the clicked image. - // Used to replace the default CopyImageToClipboard action. - void copyImage(); - - void handleClipboardChanged(QClipboard::Mode p_mode); - -private: - void hideUnusedActions(QMenu *p_menu); - - void alterHtmlMimeData(QClipboard *p_clipboard, - const QMimeData *p_mimeData, - const QString &p_copyTarget); - - void removeHtmlFromImageData(QClipboard *p_clipboard, - const QMimeData *p_mimeData); - - bool removeStyles(QString &p_html); - - void initCopyAsMenu(QAction *p_after, QMenu *p_menu); - - void initCopyAllAsMenu(QMenu *p_menu); - - void initPreviewTunnelMenu(QAction *p_before, QMenu *p_menu); - - VFile *m_file; - - // Whether this view has hooked the Copy Image Url action. - bool m_copyImageUrlActionHooked; - - // Whether it is after copy image action. - bool m_afterCopyImage; - - // Target of Copy As. - QString m_copyTarget; - - // Whether in preview mode. - bool m_inPreview; -}; - -inline void VWebView::setInPreview(bool p_preview) -{ - m_inPreview = p_preview; -} -#endif // VWEBVIEW_H diff --git a/src/vwordcountinfo.h b/src/vwordcountinfo.h deleted file mode 100644 index 693b0e84..00000000 --- a/src/vwordcountinfo.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef VWORDCOUNTINFO_H -#define VWORDCOUNTINFO_H - -#include -#include - - -struct VWordCountInfo -{ - enum Mode - { - Read = 0, - Edit, - Invalid - }; - - VWordCountInfo() - : m_mode(Mode::Invalid), - m_wordCount(-1), - m_charWithoutSpacesCount(-1), - m_charWithSpacesCount(-1) - { - } - - bool isNull() const - { - return m_mode == Mode::Invalid; - } - - void clear() - { - m_mode = Mode::Invalid; - m_wordCount = -1; - m_charWithoutSpacesCount = -1; - m_charWithSpacesCount = -1; - } - - QString toString() const - { - return QString("VWordCountInfo mode %1 WC %2 CNSC %3 CSC %4") - .arg(m_mode) - .arg(m_wordCount) - .arg(m_charWithoutSpacesCount) - .arg(m_charWithSpacesCount); - } - - Mode m_mode; - int m_wordCount; - int m_charWithoutSpacesCount; - int m_charWithSpacesCount; -}; - -#endif // VWORDCOUNTINFO_H diff --git a/src/widgets/vcombobox.cpp b/src/widgets/vcombobox.cpp deleted file mode 100644 index f36cbea8..00000000 --- a/src/widgets/vcombobox.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "vcombobox.h" - -#include -#include - -VComboBox::VComboBox(QWidget *p_parent) - : QComboBox(p_parent) -{ -} - -void VComboBox::showPopup() -{ - QComboBox::showPopup(); - -#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) || defined(Q_OS_LINUX) - auto *vw = view(); - if (count() > 0) { - int cnt = qMin(count(), maxVisibleItems()); - int height = 20 + cnt * vw->visualRect(vw->model()->index(0, 0)).height(); - if (height > vw->height()) { - vw->setMinimumHeight(height); - } - } -#endif -} diff --git a/src/widgets/vcombobox.h b/src/widgets/vcombobox.h deleted file mode 100644 index 3a0c5f7d..00000000 --- a/src/widgets/vcombobox.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef VCOMBOBOX_H -#define VCOMBOBOX_H - -#include - - -class VComboBox : public QComboBox -{ - Q_OBJECT -public: - explicit VComboBox(QWidget *p_parent = nullptr); - - void showPopup() Q_DECL_OVERRIDE; -}; - -#endif // VCOMBOBOX_H