From c9c53a46a1b510dc6eceb2bd9b1fe1a97bb91cc2 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Thu, 4 May 2023 16:57:45 +0800
Subject: [PATCH 01/15] version

---
 CHANGELOG.md      | 15 +++++++++++++++
 gradle.properties |  2 +-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa91270..618b406 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,21 @@
 [![捐赠][badge:donate-zh]][shuzijun-donate]
 [![内推][badge:referrals]][shuzijun-referrals]
 
+## 8.8.0
+
+### Added
+
+### Changed
+
+### Deprecated
+
+### Fixed
+- fix [#636](https://github.com/shuzijun/leetcode-editor/issues/636)
+- fix [#638](https://github.com/shuzijun/leetcode-editor/issues/638)
+
+### Removed
+
+
 ## 8.7.0
 
 ### Added
diff --git a/gradle.properties b/gradle.properties
index e13f162..0a9f8a8 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
 pluginGroup = com.shuzijun.leetcode
 pluginName = leetcode-editor
-pluginVersion = 8.7
+pluginVersion = 8.8
 
 pluginSinceBuild = 203.0
 pluginUntilBuild =

From 85da93f82fad5020bb9d358c6f9118876926dcc1 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Thu, 4 May 2023 17:52:26 +0800
Subject: [PATCH 02/15] fix cookie

---
 .../com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java     | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java
index e34b6d9..6405235 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java
@@ -113,6 +113,7 @@ public static void setCookie(List<HttpCookie> cookieList) {
 
         cookieManager.getCookieStore().removeAll();
         for (HttpCookie cookie : cookieList) {
+            cookie.setVersion(0);
             cookieManager.getCookieStore().add(null, cookie);
         }
     }

From 6c4329d1a1a5202997a43e7942a8457c1093f484 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Thu, 7 Dec 2023 21:17:59 +0800
Subject: [PATCH 03/15] fix #682

---
 build.gradle                                  |   2 +-
 gradle/wrapper/gradle-wrapper.jar             | Bin 59536 -> 61574 bytes
 gradle/wrapper/gradle-wrapper.properties      |   3 +-
 gradlew                                       | 269 +++++++++++-------
 gradlew.bat                                   | 181 ++++++------
 .../plugin/actions/AbstractAction.java        |   7 +-
 .../plugin/actions/editor/TestcaseAction.java |   2 +-
 .../plugin/actions/toolbar/LoginAction.java   |   2 +-
 .../plugin/actions/tree/TestcaseAction.java   |   2 +-
 .../leetcode/plugin/editor/LCVPanel.java      |   2 +-
 .../editor/SplitTextEditorProvider.java       |   5 +-
 .../plugin/manager/ArticleManager.java        |   2 +-
 .../leetcode/plugin/manager/CodeManager.java  |   2 +-
 .../plugin/manager/CodeTopManager.java        |   2 +-
 .../leetcode/plugin/manager/FindManager.java  |   2 +-
 .../plugin/manager/QuestionManager.java       |   2 +-
 .../plugin/manager/SubmissionManager.java     |   2 +-
 .../leetcode/plugin/model/PageInfo.java       |   2 +-
 .../leetcode/plugin/model/QuestionView.java   |   2 +-
 .../leetcode/plugin/setting/SettingUI.java    |   2 +-
 .../leetcode/plugin/utils/FileUtils.java      |   2 +-
 .../plugin/utils/HttpClientUtils.java         |   2 +-
 .../leetcode/plugin/utils/MessageUtils.java   |   2 +-
 .../leetcode/plugin/utils/URLUtils.java       |   2 +-
 .../leetcode/plugin/utils/VelocityUtils.java  |   2 +-
 .../leetcode/plugin/window/WindowFactory.java |   2 +-
 .../plugin/window/login/HttpLogin.java        |   2 +-
 .../plugin/window/login/LoginPanel.java       |   2 +-
 28 files changed, 286 insertions(+), 223 deletions(-)
 mode change 100644 => 100755 gradlew

diff --git a/build.gradle b/build.gradle
index b649045..e471c69 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
 plugins {
     id 'java-library'
-    id 'org.jetbrains.intellij' version '1.7.0'
+    id 'org.jetbrains.intellij' version '1.13.0'
     id 'org.jetbrains.changelog' version "1.3.1"
     id "de.undercouch.download" version "4.0.2"
 }
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..943f0cbfa754578e88a3dae77fce6e3dea56edbf 100644
GIT binary patch
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 69a9715..f398c33 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
+networkTimeout=10000
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
old mode 100644
new mode 100755
index 744e882..65dcd68
--- a/gradlew
+++ b/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
 
 #
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -17,67 +17,101 @@
 #
 
 ##############################################################################
-##
-##  Gradle start up script for UN*X
-##
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
 ##############################################################################
 
 # Attempt to set APP_HOME
+
 # Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
 done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
 
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
 
 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
 
 warn () {
     echo "$*"
-}
+} >&2
 
 die () {
     echo
     echo "$*"
     echo
     exit 1
-}
+} >&2
 
 # OS specific support (must be 'true' or 'false').
 cygwin=false
 msys=false
 darwin=false
 nonstop=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MSYS* | MINGW* )
-    msys=true
-    ;;
-  NONSTOP* )
-    nonstop=true
-    ;;
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
 esac
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 if [ -n "$JAVA_HOME" ] ; then
     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
         # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
+        JAVACMD=$JAVA_HOME/jre/sh/java
     else
-        JAVACMD="$JAVA_HOME/bin/java"
+        JAVACMD=$JAVA_HOME/bin/java
     fi
     if [ ! -x "$JAVACMD" ] ; then
         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
     fi
 else
-    JAVACMD="java"
+    JAVACMD=java
     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 
 Please set the JAVA_HOME variable in your environment to match the
@@ -106,80 +140,105 @@ location of your Java installation."
 fi
 
 # Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC3045 
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC3045 
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
 fi
 
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
 
 # For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
-    JAVACMD=`cygpath --unix "$JAVACMD"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
     # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
         fi
-        i=`expr $i + 1`
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
     done
-    case $i in
-        0) set -- ;;
-        1) set -- "$args0" ;;
-        2) set -- "$args0" "$args1" ;;
-        3) set -- "$args0" "$args1" "$args2" ;;
-        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
-    esac
 fi
 
-# Escape application args
-save () {
-    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
-    echo " "
-}
-APP_ARGS=`save "$@"`
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
 
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
 
 exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 107acd3..6689b85 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -1,89 +1,92 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem      https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem  Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Resolve any "." and ".." in APP_HOME to make it shorter.
-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/AbstractAction.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/AbstractAction.java
index 737a2aa..d3402b7 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/AbstractAction.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/AbstractAction.java
@@ -9,8 +9,11 @@
 import com.shuzijun.leetcode.plugin.model.Config;
 import com.shuzijun.leetcode.plugin.model.PluginConstant;
 import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
-import com.shuzijun.leetcode.plugin.utils.*;
-import org.apache.commons.lang.StringUtils;
+import com.shuzijun.leetcode.plugin.utils.MTAUtils;
+import com.shuzijun.leetcode.plugin.utils.MessageUtils;
+import com.shuzijun.leetcode.plugin.utils.PropertiesUtils;
+import com.shuzijun.leetcode.plugin.utils.UpdateUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.jetbrains.annotations.NotNull;
 
 /**
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/editor/TestcaseAction.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/editor/TestcaseAction.java
index c4a210f..5dc6131 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/editor/TestcaseAction.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/editor/TestcaseAction.java
@@ -8,7 +8,7 @@
 import com.shuzijun.leetcode.plugin.utils.MessageUtils;
 import com.shuzijun.leetcode.plugin.utils.PropertiesUtils;
 import com.shuzijun.leetcode.plugin.window.dialog.TestcasePanel;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.concurrent.atomic.AtomicReference;
 
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/LoginAction.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/LoginAction.java
index 129e0ef..9b53189 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/LoginAction.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/LoginAction.java
@@ -14,7 +14,7 @@
 import com.shuzijun.leetcode.plugin.window.WindowFactory;
 import com.shuzijun.leetcode.plugin.window.login.HttpLogin;
 import com.shuzijun.leetcode.plugin.window.login.LoginPanel;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.net.HttpCookie;
 import java.util.List;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/TestcaseAction.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/TestcaseAction.java
index 4ef59f0..5415963 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/TestcaseAction.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/TestcaseAction.java
@@ -8,7 +8,7 @@
 import com.shuzijun.leetcode.plugin.utils.MessageUtils;
 import com.shuzijun.leetcode.plugin.utils.PropertiesUtils;
 import com.shuzijun.leetcode.plugin.window.dialog.TestcasePanel;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.concurrent.atomic.AtomicReference;
 
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/editor/LCVPanel.java b/src/main/java/com/shuzijun/leetcode/plugin/editor/LCVPanel.java
index c431975..754d57b 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/editor/LCVPanel.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/editor/LCVPanel.java
@@ -30,7 +30,7 @@
 import com.shuzijun.leetcode.plugin.utils.FileUtils;
 import com.shuzijun.leetcode.plugin.utils.PropertiesUtils;
 import io.netty.handler.codec.http.HttpHeaderNames;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.cef.browser.CefBrowser;
 import org.cef.browser.CefFrame;
 import org.cef.handler.*;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/editor/SplitTextEditorProvider.java b/src/main/java/com/shuzijun/leetcode/plugin/editor/SplitTextEditorProvider.java
index 1e5a22f..8eff520 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/editor/SplitTextEditorProvider.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/editor/SplitTextEditorProvider.java
@@ -125,15 +125,12 @@ public FileEditorPolicy getPolicy() {
     public static Builder getBuilderFromEditorProvider(@NotNull final FileEditorProvider provider,
                                                        @NotNull final Project project,
                                                        @NotNull final VirtualFile file) {
-        if (provider instanceof AsyncFileEditorProvider) {
-            return ((AsyncFileEditorProvider) provider).createEditorAsync(project, file);
-        } else {
             return new Builder() {
                 @Override
                 public FileEditor build() {
                     return provider.createEditor(project, file);
                 }
             };
-        }
+
     }
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/manager/ArticleManager.java b/src/main/java/com/shuzijun/leetcode/plugin/manager/ArticleManager.java
index c36dcca..a0e7eb9 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/manager/ArticleManager.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/manager/ArticleManager.java
@@ -10,7 +10,7 @@
 import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
 import com.shuzijun.leetcode.plugin.utils.*;
 import com.shuzijun.leetcode.plugin.utils.doc.CleanMarkdown;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.io.File;
 import java.util.ArrayList;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeManager.java b/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeManager.java
index 9dad3f2..f7fe159 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeManager.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeManager.java
@@ -12,7 +12,7 @@
 import com.shuzijun.leetcode.plugin.model.*;
 import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
 import com.shuzijun.leetcode.plugin.utils.*;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.jetbrains.annotations.NotNull;
 
 import java.io.File;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeTopManager.java b/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeTopManager.java
index ec2d9ee..4f104f7 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeTopManager.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeTopManager.java
@@ -6,7 +6,7 @@
 import com.intellij.openapi.project.Project;
 import com.shuzijun.leetcode.plugin.model.*;
 import com.shuzijun.leetcode.plugin.utils.*;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/manager/FindManager.java b/src/main/java/com/shuzijun/leetcode/plugin/manager/FindManager.java
index 6a183d0..1756877 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/manager/FindManager.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/manager/FindManager.java
@@ -9,7 +9,7 @@
 import com.shuzijun.leetcode.plugin.model.Tag;
 import com.shuzijun.leetcode.plugin.utils.*;
 import com.shuzijun.leetcode.plugin.window.WindowFactory;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/manager/QuestionManager.java b/src/main/java/com/shuzijun/leetcode/plugin/manager/QuestionManager.java
index f2cdf27..af67d65 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/manager/QuestionManager.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/manager/QuestionManager.java
@@ -12,7 +12,7 @@
 import com.shuzijun.leetcode.plugin.utils.*;
 import com.shuzijun.leetcode.plugin.utils.doc.CleanMarkdown;
 import com.shuzijun.leetcode.plugin.window.WindowFactory;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.text.SimpleDateFormat;
 import java.util.*;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/manager/SubmissionManager.java b/src/main/java/com/shuzijun/leetcode/plugin/manager/SubmissionManager.java
index 99dac6b..2e5920e 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/manager/SubmissionManager.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/manager/SubmissionManager.java
@@ -6,7 +6,7 @@
 import com.shuzijun.leetcode.plugin.model.*;
 import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
 import com.shuzijun.leetcode.plugin.utils.*;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.io.File;
 import java.util.ArrayList;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/model/PageInfo.java b/src/main/java/com/shuzijun/leetcode/plugin/model/PageInfo.java
index c5902cb..1eac394 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/model/PageInfo.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/model/PageInfo.java
@@ -2,7 +2,7 @@
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.annotation.JSONField;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/model/QuestionView.java b/src/main/java/com/shuzijun/leetcode/plugin/model/QuestionView.java
index c736443..98ea00e 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/model/QuestionView.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/model/QuestionView.java
@@ -1,6 +1,6 @@
 package com.shuzijun.leetcode.plugin.model;
 
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.HashMap;
 import java.util.Map;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/setting/SettingUI.java b/src/main/java/com/shuzijun/leetcode/plugin/setting/SettingUI.java
index 51b4a39..da81353 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/setting/SettingUI.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/setting/SettingUI.java
@@ -27,7 +27,7 @@
 import com.shuzijun.leetcode.plugin.utils.MTAUtils;
 import com.shuzijun.leetcode.plugin.utils.PropertiesUtils;
 import com.shuzijun.leetcode.plugin.utils.URLUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/FileUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/FileUtils.java
index 1099840..623c798 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/FileUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/FileUtils.java
@@ -14,7 +14,7 @@
 import com.shuzijun.leetcode.plugin.model.LeetcodeEditor;
 import com.shuzijun.leetcode.plugin.model.Question;
 import com.shuzijun.leetcode.plugin.setting.ProjectConfig;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.io.*;
 import java.util.ArrayList;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpClientUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpClientUtils.java
index afa7b9d..24ce22e 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpClientUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpClientUtils.java
@@ -3,7 +3,7 @@
 //import com.intellij.util.proxy.CommonProxy;
 //import com.shuzijun.leetcode.plugin.model.Config;
 //import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
-//import org.apache.commons.lang.StringUtils;
+//import org.apache.commons.lang3.StringUtils;
 //import org.apache.http.Header;
 //import org.apache.http.HttpHeaders;
 //import org.apache.http.client.config.AuthSchemes;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/MessageUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/MessageUtils.java
index 2d5de59..49fb513 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/MessageUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/MessageUtils.java
@@ -20,8 +20,8 @@
 import com.intellij.ui.awt.RelativePoint;
 import com.shuzijun.leetcode.plugin.model.PluginConstant;
 import com.shuzijun.leetcode.plugin.window.ConsoleWindowFactory;
-import org.apache.commons.lang.time.DateFormatUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/URLUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/URLUtils.java
index 3bc19f0..8fe1220 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/URLUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/URLUtils.java
@@ -2,7 +2,7 @@
 
 import com.shuzijun.leetcode.plugin.model.Config;
 import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * @author shuzijun
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/VelocityUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/VelocityUtils.java
index e10bdc6..f31bf6c 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/VelocityUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/VelocityUtils.java
@@ -21,7 +21,7 @@ public class VelocityUtils {
         engine = new VelocityEngine();
         engine.setProperty(RuntimeConstants.PARSER_POOL_SIZE, 20);
         engine.setProperty(RuntimeConstants.INPUT_ENCODING, "UTF-8");
-        engine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8");
+        //engine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8");
 
         Properties props = new Properties();
         props.put("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.SimpleLog4JLogSystem");
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/WindowFactory.java b/src/main/java/com/shuzijun/leetcode/plugin/window/WindowFactory.java
index 2318bc6..49ba055 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/window/WindowFactory.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/WindowFactory.java
@@ -14,7 +14,7 @@
 import com.shuzijun.leetcode.plugin.model.PluginConstant;
 import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
 import icons.LeetCodeEditorIcons;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/login/HttpLogin.java b/src/main/java/com/shuzijun/leetcode/plugin/window/login/HttpLogin.java
index 0261a89..e76519a 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/window/login/HttpLogin.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/login/HttpLogin.java
@@ -17,7 +17,7 @@
 import com.shuzijun.leetcode.plugin.utils.*;
 import com.shuzijun.leetcode.plugin.window.NavigatorTabsPanel;
 import com.shuzijun.leetcode.plugin.window.WindowFactory;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.jetbrains.annotations.NotNull;
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/login/LoginPanel.java b/src/main/java/com/shuzijun/leetcode/plugin/window/login/LoginPanel.java
index 2b8a6bc..445735b 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/window/login/LoginPanel.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/login/LoginPanel.java
@@ -15,7 +15,7 @@
 import com.intellij.util.ui.components.BorderLayoutPanel;
 import com.shuzijun.leetcode.plugin.model.PluginConstant;
 import com.shuzijun.leetcode.plugin.utils.*;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.cef.browser.CefBrowser;
 import org.cef.browser.CefFrame;
 import org.cef.callback.CefCookieVisitor;

From 83746ecc609cb99ec23716e4439d5ec0d3fd1849 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Thu, 7 Dec 2023 21:20:16 +0800
Subject: [PATCH 04/15] version

---
 CHANGELOG.md      | 14 ++++++++++++++
 gradle.properties |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 618b406..0a44909 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,20 @@
 [![捐赠][badge:donate-zh]][shuzijun-donate]
 [![内推][badge:referrals]][shuzijun-referrals]
 
+## 8.9.0
+
+### Added
+
+### Changed
+
+### Deprecated
+
+### Fixed
+- fix [#682](https://github.com/shuzijun/leetcode-editor/issues/682)
+
+### Removed
+
+
 ## 8.8.0
 
 ### Added
diff --git a/gradle.properties b/gradle.properties
index 0a9f8a8..e476cf3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
 pluginGroup = com.shuzijun.leetcode
 pluginName = leetcode-editor
-pluginVersion = 8.8
+pluginVersion = 8.9
 
 pluginSinceBuild = 203.0
 pluginUntilBuild =

From cd458795da6c01352d2af94a62782730a1559930 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Thu, 7 Dec 2023 21:50:09 +0800
Subject: [PATCH 05/15] version

---
 build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.gradle b/build.gradle
index e471c69..655d293 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
 plugins {
     id 'java-library'
-    id 'org.jetbrains.intellij' version '1.13.0'
+    id 'org.jetbrains.intellij' version '1.14.2'
     id 'org.jetbrains.changelog' version "1.3.1"
     id "de.undercouch.download" version "4.0.2"
 }

From 6ae19d01a344325f7eca6d09b714c6c5fe3825b5 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Thu, 7 Dec 2023 21:57:57 +0800
Subject: [PATCH 06/15] fix publishPlugin FAILED

---
 src/main/resources/META-INF/plugin.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index 118ffd2..a6144b6 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -36,7 +36,7 @@
                         serviceImplementation="com.shuzijun.leetcode.plugin.setting.StatisticsData"/>
         <applicationConfigurable groupId="tools" displayName="LeetCode Plugin" id="leetcode.id"
                                  instance="com.shuzijun.leetcode.plugin.setting.SettingConfigurable"/>
-        <statusBarWidgetFactory implementation="com.shuzijun.leetcode.plugin.timer.TimerStatusBarWidgetProvider"/>
+        <statusBarWidgetFactory id="leetcode-editor-TimerStatusBar" implementation="com.shuzijun.leetcode.plugin.timer.TimerStatusBarWidgetProvider"/>
         <lang.foldingBuilder language="JAVA" implementationClass="com.shuzijun.leetcode.plugin.language.ScopeFoldingBuilder"/>
         <lang.foldingBuilder language="Python" implementationClass="com.shuzijun.leetcode.plugin.language.ScopeFoldingBuilder"/>
         <lang.foldingBuilder language="ObjectiveC" implementationClass="com.shuzijun.leetcode.plugin.language.ScopeFoldingBuilder"/>

From e637e3ff7bb410e4b02bef14ca4158eb4d0d4a18 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Fri, 8 Mar 2024 11:20:19 +0800
Subject: [PATCH 07/15] fix #697

---
 CHANGELOG.md                                  |  14 ++
 build.gradle                                  |   3 +
 gradle.properties                             |   2 +-
 .../plugin/manager/CodeTopManager.java        |   4 +-
 .../plugin/utils/HttpRequestUtils.java        | 200 ++++++++----------
 .../leetcode/plugin/utils/URLUtils.java       |   2 +-
 .../window/navigator/AllNavigatorTable.java   |   3 +
 7 files changed, 118 insertions(+), 110 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0a44909..94c87c6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,20 @@
 [![捐赠][badge:donate-zh]][shuzijun-donate]
 [![内推][badge:referrals]][shuzijun-referrals]
 
+## 8.10.0
+
+### Added
+
+### Changed
+
+### Deprecated
+
+### Fixed
+- fix [#697](https://github.com/shuzijun/leetcode-editor/issues/697)
+
+### Removed
+
+
 ## 8.9.0
 
 ### Added
diff --git a/build.gradle b/build.gradle
index 655d293..b05e3f6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -15,10 +15,13 @@ targetCompatibility = 11
 
 
 repositories {
+    mavenLocal()
+    maven { url 'https://jitpack.io' }
     mavenCentral()
 }
 
 dependencies {
+    api 'com.shuzijun:lc-sdk:0.0.2'
     api 'com.alibaba:fastjson:1.2.47'
     api 'org.jsoup:jsoup:1.11.3'
     api('io.sentry:sentry:1.7.9') {
diff --git a/gradle.properties b/gradle.properties
index e476cf3..0d7b2a6 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
 pluginGroup = com.shuzijun.leetcode
 pluginName = leetcode-editor
-pluginVersion = 8.9
+pluginVersion = 8.10
 
 pluginSinceBuild = 203.0
 pluginUntilBuild =
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeTopManager.java b/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeTopManager.java
index 4f104f7..82f5d6f 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeTopManager.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/manager/CodeTopManager.java
@@ -40,7 +40,7 @@ private static List<Tag> getCompany() {
         List<Tag> tags = new ArrayList<>();
 
         HttpResponse response = HttpRequest.builderGet(CodeTopURLUtils.getCompanies()).request();
-        if (response != null && response.getStatusCode() == 200) {
+        if (response.getStatusCode() == 200) {
             try {
                 String body = response.getBody();
                 if (StringUtils.isNotBlank(body)) {
@@ -150,7 +150,7 @@ private static PageInfo<CodeTopQuestionView> getQuestionService(Project project,
             pageInfo.setRowTotal(pageObject.getInteger("count"));
             pageInfo.setRows(questionList);
         } else {
-            LogUtils.LOG.error("Request question list failed, status:" + response == null ? "" : response.getStatusCode());
+            LogUtils.LOG.error("Request question list failed, status:" + response.getStatusCode());
             throw new RuntimeException("Request question list failed");
         }
 
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java
index 6405235..fdb5f09 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java
@@ -3,16 +3,26 @@
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.intellij.openapi.project.Project;
-import com.intellij.util.io.HttpRequests;
+import com.intellij.util.net.HttpConfigurable;
+import com.intellij.util.net.IdeaWideAuthenticator;
+import com.intellij.util.net.IdeaWideProxySelector;
+import com.shuzijun.lc.LcClient;
+import com.shuzijun.lc.errors.LcException;
+import com.shuzijun.lc.http.DefaultExecutoHttp;
+import com.shuzijun.lc.http.HttpClient;
 import com.shuzijun.leetcode.plugin.model.HttpRequest;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.http.HttpHeaders;
+import okhttp3.Credentials;
+import okhttp3.OkHttpClient;
 import org.jetbrains.annotations.NotNull;
 
-import java.io.IOException;
-import java.net.*;
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.HttpCookie;
+import java.net.PasswordAuthentication;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -22,6 +32,9 @@ public class HttpRequestUtils {
 
     private static final Cache<String, HttpResponse> httpResponseCache = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS).build();
 
+    private static MyExecutorHttp executorHttp = new MyExecutorHttp();
+    private static LcClient enLcClient = LcClient.builder(HttpClient.SiteEnum.EN).executorHttp(executorHttp).build();
+    private static LcClient cnLcClient = LcClient.builder(HttpClient.SiteEnum.CN).executorHttp(executorHttp).build();
     private static final CookieManager cookieManager = new CookieManager(null, (uri, cookie) -> {
         if (uri == null || cookie == null || uri.getHost().equals("hm.baidu.com")) {
             return false;
@@ -33,18 +46,36 @@ public class HttpRequestUtils {
         CookieHandler.setDefault(cookieManager);
     }
 
+    private static HttpResponse buildResp(com.shuzijun.lc.http.HttpResponse response, HttpResponse httpResponse) {
+        httpResponse.setUrl(response.getHttpRequest().getUrl());
+        httpResponse.setStatusCode(response.getStatusCode());
+        httpResponse.setBody(response.getBody());
+        return httpResponse;
+    }
+
+    private static Map<String, String> getHeader(String url) {
+        if (url.contains(HttpClient.SiteEnum.EN.defaultEndpoint)){
+            return enLcClient.getClient().getHeader();
+        } else {
+            return cnLcClient.getClient().getHeader();
+        }
+    }
+
     @NotNull
     public static HttpResponse executeGet(HttpRequest httpRequest) {
 
         return CacheProcessor.processor(httpRequest, request -> {
+
             HttpResponse httpResponse = new HttpResponse();
             try {
-                HttpRequests.request(request.getUrl()).
-                        throwStatusCodeException(false).
-                        tuner(new HttpRequestTuner(request)).
-                        connect(new HttpResponseProcessor(request, httpResponse));
+                com.shuzijun.lc.http.HttpRequest.HttpRequestBuilder builder = com.shuzijun.lc.http.HttpRequest.
+                        builderGet(request.getUrl()).body(request.getBody()).addHeader(getHeader(request.getUrl()));
+                if (request.getHeader() != null) {
+                    builder.addHeader(request.getHeader());
+                }
+                return buildResp(executorHttp.executeGet(builder.build()), httpResponse);
 
-            } catch (IOException e) {
+            } catch (LcException e) {
                 LogUtils.LOG.error("HttpRequestUtils request error:", e);
                 httpResponse.setStatusCode(-1);
             }
@@ -59,11 +90,13 @@ public static HttpResponse executePost(HttpRequest httpRequest) {
         return CacheProcessor.processor(httpRequest, request -> {
             HttpResponse httpResponse = new HttpResponse();
             try {
-                HttpRequests.post(request.getUrl(), request.getContentType())
-                        .throwStatusCodeException(false)
-                        .tuner(new HttpRequestTuner(request))
-                        .connect(new HttpResponseProcessor(request, httpResponse));
-            } catch (IOException e) {
+                com.shuzijun.lc.http.HttpRequest.HttpRequestBuilder builder = com.shuzijun.lc.http.HttpRequest.
+                        builderPost(request.getUrl(), request.getContentType()).body(request.getBody()).addHeader(getHeader(request.getUrl()));
+                if (request.getHeader() != null) {
+                    builder.addHeader(request.getHeader());
+                }
+                return buildResp(executorHttp.executePost(builder.build()), httpResponse);
+            } catch (LcException e) {
                 LogUtils.LOG.error("HttpRequestUtils request error:", e);
                 httpResponse.setStatusCode(-1);
             }
@@ -75,11 +108,13 @@ public static HttpResponse executePut(HttpRequest httpRequest) {
         return CacheProcessor.processor(httpRequest, request -> {
             HttpResponse httpResponse = new HttpResponse();
             try {
-                HttpRequests.put(request.getUrl(), request.getContentType())
-                        .throwStatusCodeException(false)
-                        .tuner(new HttpRequestTuner(request))
-                        .connect(new HttpResponseProcessor(request, httpResponse));
-            } catch (IOException e) {
+                com.shuzijun.lc.http.HttpRequest.HttpRequestBuilder builder = com.shuzijun.lc.http.HttpRequest.
+                        builderPut(request.getUrl(), request.getContentType()).body(request.getBody()).addHeader(getHeader(request.getUrl()));
+                if (request.getHeader() != null) {
+                    builder.addHeader(request.getHeader());
+                }
+                return buildResp(executorHttp.executePut(builder.build()), httpResponse);
+            } catch (LcException e) {
                 LogUtils.LOG.error("HttpRequestUtils request error:", e);
                 httpResponse.setStatusCode(-1);
             }
@@ -88,17 +123,8 @@ public static HttpResponse executePut(HttpRequest httpRequest) {
     }
 
     public static String getToken() {
-        if (cookieManager.getCookieStore().getCookies() == null) {
-            return null;
-        }
-        for (HttpCookie cookie : cookieManager.getCookieStore().getCookies()) {
-            if (StringUtils.isNotBlank(cookie.getDomain()) &&
-                    cookie.getDomain().toLowerCase().contains(URLUtils.getLeetcodeHost()) && "csrftoken".equals(cookie.getName())) {
-                return cookie.getValue();
-            }
-
-        }
-        return null;
+        Map<String,String> headerMap = getHeader(URLUtils.getLeetcodeHost());
+        return headerMap.get("x-csrftoken");
     }
 
     public static boolean isLogin(Project project) {
@@ -110,87 +136,15 @@ public static boolean isLogin(Project project) {
     }
 
     public static void setCookie(List<HttpCookie> cookieList) {
-
-        cookieManager.getCookieStore().removeAll();
-        for (HttpCookie cookie : cookieList) {
-            cookie.setVersion(0);
-            cookieManager.getCookieStore().add(null, cookie);
-        }
+        enLcClient.getClient().cookieStore().clearCookie(URLUtils.getLeetcodeHost());
+        enLcClient.getClient().cookieStore().addCookie(URLUtils.getLeetcodeHost(),cookieList);
     }
 
     public static void resetHttpclient() {
-        cookieManager.getCookieStore().removeAll();
-    }
-
-
-    private static void defaultHeader(HttpRequest httpRequest) {
-        Map<String, String> header = httpRequest.getHeader();
-        header.putIfAbsent(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36");
-        header.putIfAbsent(HttpHeaders.ACCEPT, "*/*");
-        //header.putIfAbsent(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate, br");
-        header.putIfAbsent(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN,zh;q=0.9");
-        header.putIfAbsent("origin", URLUtils.getLeetcodeUrl());
-        //header.putIfAbsent(":authority", URLUtils.getLeetcodeHost());
-        //header.putIfAbsent(":scheme", "https");
-    }
-
-    private static class HttpRequestTuner implements HttpRequests.ConnectionTuner {
-
-        private final HttpRequest httpRequest;
-
-        public HttpRequestTuner(HttpRequest httpRequest) {
-            this.httpRequest = httpRequest;
-        }
-
-        @Override
-        public void tune(@NotNull URLConnection urlConnection) throws IOException {
-
-            if (StringUtils.isNotBlank(getToken()) && (urlConnection.getURL().toString().contains(URLUtils.leetcode) || urlConnection.getURL().toString().contains(URLUtils.leetcodecn))) {
-                urlConnection.addRequestProperty("x-csrftoken", getToken());
-            }
-            urlConnection.addRequestProperty("referer", urlConnection.getURL().toString());
-            //urlConnection.addRequestProperty(":path", urlConnection.getURL().getPath());
-
-            defaultHeader(httpRequest);
-            httpRequest.getHeader().forEach(urlConnection::addRequestProperty);
-        }
+        enLcClient.getClient().cookieStore().clearCookie(URLUtils.getLeetcodeHost());
     }
 
 
-    private static class HttpResponseProcessor implements HttpRequests.RequestProcessor<HttpResponse> {
-
-        private final HttpRequest httpRequest;
-        private final HttpResponse httpResponse;
-
-        public HttpResponseProcessor(HttpRequest httpRequest, HttpResponse httpResponse) {
-            this.httpRequest = httpRequest;
-            this.httpResponse = httpResponse;
-        }
-
-        @Override
-        public HttpResponse process(@NotNull HttpRequests.Request request) throws IOException {
-
-            if (StringUtils.isNoneBlank(httpRequest.getBody())) {
-                request.write(httpRequest.getBody());
-            }
-
-            URLConnection urlConnection = request.getConnection();
-
-            if (!(urlConnection instanceof HttpURLConnection)) {
-                httpResponse.setStatusCode(-1);
-                return httpResponse;
-            } else {
-                httpResponse.setStatusCode(((HttpURLConnection) urlConnection).getResponseCode());
-            }
-            httpResponse.setUrl(urlConnection.getURL().toString());
-            try {
-                httpResponse.setBody(request.readString());
-            } catch (IOException ignore) {
-            }
-            return httpResponse;
-        }
-    }
-
     private static class CacheProcessor {
         public static HttpResponse processor(HttpRequest httpRequest, HttpRequestUtils.Callable<HttpResponse> callable) {
 
@@ -222,4 +176,38 @@ private interface Callable<V> {
         V call(HttpRequest request);
     }
 
+
+    private static class MyExecutorHttp extends DefaultExecutoHttp {
+        @Override
+        public OkHttpClient getRequestClient() {
+            final HttpConfigurable httpConfigurable = HttpConfigurable.getInstance();
+            if (!httpConfigurable.USE_HTTP_PROXY &&  !httpConfigurable.USE_PROXY_PAC) {
+                return super.getRequestClient();
+            }
+            final IdeaWideProxySelector ideaWideProxySelector = new IdeaWideProxySelector(httpConfigurable);
+            OkHttpClient.Builder builder = super.getRequestClient().newBuilder().proxySelector(ideaWideProxySelector);
+            if (httpConfigurable.PROXY_AUTHENTICATION) {
+                final IdeaWideAuthenticator ideaWideAuthenticator = new IdeaWideAuthenticator(httpConfigurable);
+                final okhttp3.Authenticator proxyAuthenticator = getProxyAuthenticator(ideaWideAuthenticator);
+                builder.proxyAuthenticator(proxyAuthenticator);
+            }
+            return builder.build();
+        }
+
+        private okhttp3.Authenticator getProxyAuthenticator(IdeaWideAuthenticator ideaWideAuthenticator) {
+            okhttp3.Authenticator proxyAuthenticator = null;
+
+            if (Objects.nonNull(ideaWideAuthenticator)) {
+                proxyAuthenticator = (route, response) -> {
+                    final PasswordAuthentication authentication = ideaWideAuthenticator.getPasswordAuthentication();
+                    final String credential = Credentials.basic(authentication.getUserName(), Arrays.toString(authentication.getPassword()));
+                    return response.request().newBuilder()
+                            .header("Proxy-Authorization", credential)
+                            .build();
+                };
+            }
+            return proxyAuthenticator;
+        }
+    }
 }
+
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/URLUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/URLUtils.java
index 8fe1220..f494775 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/URLUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/URLUtils.java
@@ -23,7 +23,7 @@ public class URLUtils {
     private static String leetcodeSubmissions = "/submissions/detail/";
     private static String leetcodeTags = "/problems/api/tags/";
     private static String leetcodeFavorites = "/problems/api/favorites/";
-    private static String leetcodeVerify = "/problemset/all/";
+    private static String leetcodeVerify = "/problemset/";
     private static String leetcodeProgress = "/api/progress/all/";
     private static String leetcodeSession = "/session/";
     private static String leetcodeCardInfo = "/problems/api/card-info/";
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/AllNavigatorTable.java b/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/AllNavigatorTable.java
index a190931..c3748f7 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/AllNavigatorTable.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/AllNavigatorTable.java
@@ -133,6 +133,9 @@ public Object getValue(QuestionView question, int columnIndex) {
 
                 if (columnIndex == 2) {
                     Integer level = question.getLevel();
+                    if (level == null) {
+                        return null;
+                    }
                     if (level == 1) {
                         return "Easy";
                     } else if (level == 2) {

From f95faf422e9d2d47bf501a701f4587b43b9b28ef Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Mon, 11 Mar 2024 20:46:31 +0800
Subject: [PATCH 08/15] fix #701; fix #702

---
 CHANGELOG.md      | 15 +++++++++++++++
 build.gradle      |  2 +-
 gradle.properties |  2 +-
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 94c87c6..9639396 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,21 @@
 [![捐赠][badge:donate-zh]][shuzijun-donate]
 [![内推][badge:referrals]][shuzijun-referrals]
 
+## 8.11.0
+
+### Added
+
+### Changed
+
+### Deprecated
+
+### Fixed
+- fix [#701](https://github.com/shuzijun/leetcode-editor/issues/701)
+
+### Removed
+
+
+
 ## 8.10.0
 
 ### Added
diff --git a/build.gradle b/build.gradle
index b05e3f6..4f30ee4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -21,7 +21,7 @@ repositories {
 }
 
 dependencies {
-    api 'com.shuzijun:lc-sdk:0.0.2'
+    api 'com.shuzijun:lc-sdk:0.0.3'
     api 'com.alibaba:fastjson:1.2.47'
     api 'org.jsoup:jsoup:1.11.3'
     api('io.sentry:sentry:1.7.9') {
diff --git a/gradle.properties b/gradle.properties
index 0d7b2a6..8bd85fd 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
 pluginGroup = com.shuzijun.leetcode
 pluginName = leetcode-editor
-pluginVersion = 8.10
+pluginVersion = 8.11
 
 pluginSinceBuild = 203.0
 pluginUntilBuild =

From 8cf7b35eacbcf2f640da953b839bee74578f2c94 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Tue, 2 Apr 2024 16:03:14 +0800
Subject: [PATCH 09/15] close #709

---
 .../com/shuzijun/leetcode/plugin/model/CodeTypeEnum.java  | 8 +++++++-
 .../com/shuzijun/leetcode/plugin/utils/CommentUtils.java  | 7 ++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/main/java/com/shuzijun/leetcode/plugin/model/CodeTypeEnum.java b/src/main/java/com/shuzijun/leetcode/plugin/model/CodeTypeEnum.java
index 0f0a258..3541014 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/model/CodeTypeEnum.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/model/CodeTypeEnum.java
@@ -21,11 +21,17 @@ public enum CodeTypeEnum {
     KOTLIN("Kotlin", "kotlin", ".kt", "//", "/**\n%s\n*/"),
     RUST("Rust", "rust", ".rs", "//", "/**\n%s\n*/"),
     PHP("PHP", "php", ".php", "//", "/**\n%s\n*/"),
+    TypeScript("TypeScript", "typescript", ".ts", "//", "/**\n%s\n*/"),
+    Dart("Dart", "dart", ".dart", "//", "/**\n%s\n*/"),
+    Racket("Racket", "racket", ".rkt", ";", "#|\n%s\n|#"),
+    Erlang("Erlang", "erlang", ".erl", "%", ""),
+    Elixir("Elixir", "elixir", ".ex", "#", ""),
     BASH("Bash", "bash", ".sh", "#",": '\n%s\n'"),
     MYSQL("MySQL", "mysql", ".sql", "#", "/**\n%s\n*/"),
     ORACLE("Oracle", "oraclesql", ".sql", "#", "/**\n%s\n*/"),
     MSSQLSERVER("MS SQL Server", "mssql", ".sql", "#", "/**\n%s\n*/"),
-    TypeScript("TypeScript", "typescript", ".ts", "//", "/**\n%s\n*/"),
+    Pandas("Pandas", "pythondata", ".py", "#", "\"\"\"\n%s\n\"\"\""),
+    PostgreSQL("PostgreSQL", "postgresql", ".sql", "--", "/**\n%s\n*/"),
     ;
 
 
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/CommentUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/CommentUtils.java
index 2c82cd3..7f029ec 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/CommentUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/CommentUtils.java
@@ -16,9 +16,10 @@ public class CommentUtils {
     private static final Pattern subPattern = Pattern.compile("<sup>(<span.*>?)?([0-9abcdeghijklmnoprstuvwxyz\\+\\-\\*=\\(\\)\\.\\/]+)(</span>)?</sup>?");
 
     public static String createComment(String html, CodeTypeEnum codeTypeEnum, Config config) {
+        boolean isSupportMultilineComment =  config.getMultilineComment() && StringUtils.isNotBlank(codeTypeEnum.getMultiLineComment());
         html = html.replaceAll("(\\r\\n|\\r|\\n|\\n\\r)", "\\\\n").replaceAll(" "," ");
         if(config.getHtmlContent()) {
-            if(config.getMultilineComment()){
+            if(isSupportMultilineComment){
                 return String.format(codeTypeEnum.getMultiLineComment(),html.replaceAll("\\\\n", "\n"));
             }else {
                return codeTypeEnum.getComment() + html.replaceAll("\\\\n", "\n" + codeTypeEnum.getComment());
@@ -29,7 +30,7 @@ public static String createComment(String html, CodeTypeEnum codeTypeEnum, Confi
             String subStr = SuperscriptUtils.getSup(subMatcher.group(2));
             html = html.replace(subMatcher.group(), "<sup>" + subStr + "</sup>");
         }
-        String comment = config.getMultilineComment()?"":codeTypeEnum.getComment();
+        String comment = isSupportMultilineComment?"":codeTypeEnum.getComment();
         String body = comment + Jsoup.parse(html).text().replaceAll("\\\\n", "\n" + comment);
         String[] lines = body.split("\n");
         StringBuilder sb = new StringBuilder();
@@ -52,7 +53,7 @@ public static String createComment(String html, CodeTypeEnum codeTypeEnum, Confi
                 sb.append(lineBuilder).append("\n");
             }
         }
-        return config.getMultilineComment()?String.format(codeTypeEnum.getMultiLineComment(),sb):sb.toString();
+        return isSupportMultilineComment?String.format(codeTypeEnum.getMultiLineComment(),sb):sb.toString();
     }
 
     public static String createSubmissions(String html) {

From 6f950d4d1ec0fad1e74c06542f9fed87dc8c91b7 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Wed, 15 May 2024 19:55:40 +0800
Subject: [PATCH 10/15] fix #708, fix #712, close #713

---
 build.gradle                                  |   1 +
 gradle.properties                             |   2 +-
 .../plugin/actions/AbstractAction.java        |   6 +
 .../actions/editor/EditorMenuActionGroup.java |   7 ++
 .../plugin/actions/toolbar/FindAction.java    |   6 +
 .../actions/toolbar/FindActionGroup.java      |   7 ++
 .../plugin/actions/toolbar/FindTagAction.java |   6 +
 .../plugin/actions/tree/FavoriteAction.java   |   6 +
 .../actions/tree/FavoriteActionGroup.java     |   7 ++
 .../RegisterPluginInstallerStateListener.java |  60 ----------
 .../plugin/setting/PersistentConfig.java      |   2 +-
 .../plugin/utils/HttpRequestUtils.java        | 108 ++++++++++++++++--
 .../window/navigator/AllNavigatorPanel.java   |   8 ++
 .../window/navigator/NavigatorPanel.java      |   8 ++
 .../RegisterPluginInstallerStateListener.kt   |  50 ++++++++
 src/main/resources/META-INF/plugin.xml        |   2 +-
 .../java/com/shuzijun/leetcode/HttpTest.java  |  53 +++++++++
 17 files changed, 264 insertions(+), 75 deletions(-)
 delete mode 100644 src/main/java/com/shuzijun/leetcode/plugin/listener/RegisterPluginInstallerStateListener.java
 create mode 100644 src/main/kotlin/com/shuzijun/leetcode/plugin/listener/RegisterPluginInstallerStateListener.kt
 create mode 100644 src/test/java/com/shuzijun/leetcode/HttpTest.java

diff --git a/build.gradle b/build.gradle
index 4f30ee4..8d6310d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,7 @@
 plugins {
     id 'java-library'
     id 'org.jetbrains.intellij' version '1.14.2'
+    id("org.jetbrains.kotlin.jvm") version "1.9.23"
     id 'org.jetbrains.changelog' version "1.3.1"
     id "de.undercouch.download" version "4.0.2"
 }
diff --git a/gradle.properties b/gradle.properties
index 8bd85fd..0a3d74a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -7,7 +7,7 @@ pluginUntilBuild =
 pluginDescription = doc/description.html
 
 platformType = IU
-platformVersion = 2022.1
+platformVersion = 2022.2
 
 # ,-Dide.browser.jcef.log.level=verbose,-Duser.language=en-US
 runIdeJvmArgs = -Dfile.encoding=utf-8
\ No newline at end of file
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/AbstractAction.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/AbstractAction.java
index d3402b7..c7f60e9 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/AbstractAction.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/AbstractAction.java
@@ -1,5 +1,6 @@
 package com.shuzijun.leetcode.plugin.actions;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.options.ShowSettingsUtil;
@@ -47,5 +48,10 @@ public void run(@NotNull ProgressIndicator progressIndicator) {
 
     }
 
+    @Override
+    public @NotNull ActionUpdateThread getActionUpdateThread() {
+        return  ActionUpdateThread.BGT;
+    }
+
     public abstract void actionPerformed(AnActionEvent anActionEvent, Config config);
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/editor/EditorMenuActionGroup.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/editor/EditorMenuActionGroup.java
index 41f584b..9ac3f1d 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/editor/EditorMenuActionGroup.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/editor/EditorMenuActionGroup.java
@@ -1,11 +1,13 @@
 package com.shuzijun.leetcode.plugin.actions.editor;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.shuzijun.leetcode.plugin.model.LeetcodeEditor;
 import com.shuzijun.leetcode.plugin.setting.ProjectConfig;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author shuzijun
@@ -24,4 +26,9 @@ public void update(AnActionEvent e) {
         }
         e.getPresentation().setEnabledAndVisible(menuAllowed);
     }
+
+    @Override
+    public @NotNull ActionUpdateThread getActionUpdateThread() {
+        return  ActionUpdateThread.BGT;
+    }
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindAction.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindAction.java
index 8143580..8f7f6a1 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindAction.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindAction.java
@@ -1,11 +1,13 @@
 package com.shuzijun.leetcode.plugin.actions.toolbar;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.ToggleAction;
 import com.intellij.openapi.project.DumbAware;
 import com.shuzijun.leetcode.plugin.manager.NavigatorAction;
 import com.shuzijun.leetcode.plugin.utils.DataKeys;
 import com.shuzijun.leetcode.plugin.window.WindowFactory;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 
@@ -46,4 +48,8 @@ public void setSelected(AnActionEvent anActionEvent, boolean b) {
         panel.setVisible(b);
     }
 
+    @Override
+    public @NotNull ActionUpdateThread getActionUpdateThread() {
+        return  ActionUpdateThread.BGT;
+    }
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindActionGroup.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindActionGroup.java
index 34c04e5..5e74b13 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindActionGroup.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindActionGroup.java
@@ -2,6 +2,7 @@
 
 import com.google.common.collect.Lists;
 import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.DumbAware;
@@ -13,6 +14,7 @@
 import com.shuzijun.leetcode.plugin.utils.DataKeys;
 import com.shuzijun.leetcode.plugin.window.WindowFactory;
 import icons.LeetCodeEditorIcons;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
@@ -97,4 +99,9 @@ private String getFilterKey(String id) {
     private String getKey(String id) {
         return id.replace(PluginConstant.LEETCODE_FIND_PREFIX, "").replace(PluginConstant.LEETCODE_ALL_FIND_PREFIX, "").replace(PluginConstant.LEETCODE_CODETOP_FIND_PREFIX, "");
     }
+
+    @Override
+    public @NotNull ActionUpdateThread getActionUpdateThread() {
+        return  ActionUpdateThread.BGT;
+    }
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindTagAction.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindTagAction.java
index 7050c31..38fbad2 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindTagAction.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/toolbar/FindTagAction.java
@@ -1,5 +1,6 @@
 package com.shuzijun.leetcode.plugin.actions.toolbar;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.ToggleAction;
 import com.intellij.openapi.progress.ProgressIndicator;
@@ -61,5 +62,10 @@ public void run(@NotNull ProgressIndicator progressIndicator) {
         });
     }
 
+    @Override
+    public @NotNull ActionUpdateThread getActionUpdateThread() {
+        return  ActionUpdateThread.BGT;
+    }
+
 
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/FavoriteAction.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/FavoriteAction.java
index 531b855..210ec92 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/FavoriteAction.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/FavoriteAction.java
@@ -1,5 +1,6 @@
 package com.shuzijun.leetcode.plugin.actions.tree;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.ToggleAction;
 import com.intellij.openapi.progress.ProgressIndicator;
@@ -65,4 +66,9 @@ public void run(@NotNull ProgressIndicator progressIndicator) {
         });
 
     }
+
+    @Override
+    public @NotNull ActionUpdateThread getActionUpdateThread() {
+        return  ActionUpdateThread.BGT;
+    }
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/FavoriteActionGroup.java b/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/FavoriteActionGroup.java
index 8c610c3..0c551c4 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/FavoriteActionGroup.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/actions/tree/FavoriteActionGroup.java
@@ -2,6 +2,7 @@
 
 import com.google.common.collect.Lists;
 import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.DumbAware;
@@ -10,6 +11,7 @@
 import com.shuzijun.leetcode.plugin.model.Tag;
 import com.shuzijun.leetcode.plugin.utils.DataKeys;
 import com.shuzijun.leetcode.plugin.window.WindowFactory;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
@@ -39,4 +41,9 @@ public AnAction[] getChildren(AnActionEvent anActionEvent) {
 
     }
 
+    @Override
+    public @NotNull ActionUpdateThread getActionUpdateThread() {
+        return  ActionUpdateThread.BGT;
+    }
+
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/listener/RegisterPluginInstallerStateListener.java b/src/main/java/com/shuzijun/leetcode/plugin/listener/RegisterPluginInstallerStateListener.java
deleted file mode 100644
index 2836c4b..0000000
--- a/src/main/java/com/shuzijun/leetcode/plugin/listener/RegisterPluginInstallerStateListener.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.shuzijun.leetcode.plugin.listener;
-
-import com.intellij.ide.plugins.PluginManagerCore;
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.extensions.PluginId;
-import com.intellij.openapi.fileEditor.impl.HTMLEditorProvider;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.startup.StartupActivity;
-import com.shuzijun.leetcode.plugin.model.Config;
-import com.shuzijun.leetcode.plugin.model.PluginConstant;
-import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author shuzijun
- */
-public class RegisterPluginInstallerStateListener implements StartupActivity {
-
-    private final static String ShowNewHTMLEditorKey = PluginConstant.PLUGIN_ID + "ShowNewHTMLEditor";
-
-    private final static String CHANGELOGURL = "https://github.com/shuzijun/leetcode-editor/blob/master/CHANGELOG.md";
-
-    @Override
-    public void runActivity(@NotNull Project project) {
-        String newVersion = PluginManagerCore.getPlugin(PluginId.getId(PluginConstant.PLUGIN_ID)).getVersion();
-        Config config = PersistentConfig.getInstance().getInitConfig();
-        String oldVersion;
-        if (config == null) {
-            oldVersion = PropertiesComponent.getInstance().getValue(ShowNewHTMLEditorKey);
-            PropertiesComponent.getInstance().setValue(ShowNewHTMLEditorKey, newVersion);
-        } else {
-            oldVersion = config.getPluginVersion();
-            config.setPluginVersion(newVersion);
-        }
-
-        if (!newVersion.equals(oldVersion)) {
-            HTMLEditorProvider.openEditor(project,
-                    "What's New in " + PluginConstant.PLUGIN_ID,
-                    CHANGELOGURL,
-                    "'<div style='text-align: center;padding-top: 3rem'>" +
-                            "<div style='padding-top: 1rem; margin-bottom: 0.8rem;'>Failed to load!</div>" +
-                            "'<div><a href='" + CHANGELOGURL + "' target='_blank'" +
-                            "style='font-size: 2rem'>Open in browser</a></div>" +
-                            "</div>"
-            );
-        }
-
-
-       /* PluginInstaller.addStateListener(new PluginStateListener() {
-            @Override
-            public void install(@NotNull IdeaPluginDescriptor ideaPluginDescriptor) {
-            }
-
-            @Override
-            public void uninstall(@NotNull IdeaPluginDescriptor ideaPluginDescriptor) {
-                System.out.println("uninstall");
-            }
-        });*/
-    }
-}
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/setting/PersistentConfig.java b/src/main/java/com/shuzijun/leetcode/plugin/setting/PersistentConfig.java
index 97a4e7a..204edb6 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/setting/PersistentConfig.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/setting/PersistentConfig.java
@@ -94,7 +94,7 @@ public void savePassword(String password, String username) {
         if (username == null || password == null) {
             return;
         }
-        PasswordSafe.getInstance().set(new CredentialAttributes(PluginConstant.PLUGIN_ID, username, this.getClass()), new Credentials(username, password == null ? "" : password));
+        PasswordSafe.getInstance().set(new CredentialAttributes(PluginConstant.PLUGIN_ID, username, this.getClass()), new Credentials(username, password));
     }
 
     public String getPassword(String username) {
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java
index fdb5f09..b5ab6b2 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/HttpRequestUtils.java
@@ -2,24 +2,30 @@
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.util.net.HttpConfigurable;
-import com.intellij.util.net.IdeaWideAuthenticator;
 import com.intellij.util.net.IdeaWideProxySelector;
+import com.intellij.util.proxy.NonStaticAuthenticator;
 import com.shuzijun.lc.LcClient;
 import com.shuzijun.lc.errors.LcException;
 import com.shuzijun.lc.http.DefaultExecutoHttp;
 import com.shuzijun.lc.http.HttpClient;
 import com.shuzijun.leetcode.plugin.model.HttpRequest;
+import com.shuzijun.leetcode.plugin.model.PluginConstant;
+import okhttp3.Challenge;
 import okhttp3.Credentials;
 import okhttp3.OkHttpClient;
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 
 import java.net.CookieHandler;
 import java.net.CookieManager;
 import java.net.HttpCookie;
 import java.net.PasswordAuthentication;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -54,7 +60,7 @@ private static HttpResponse buildResp(com.shuzijun.lc.http.HttpResponse response
     }
 
     private static Map<String, String> getHeader(String url) {
-        if (url.contains(HttpClient.SiteEnum.EN.defaultEndpoint)){
+        if (url.contains(HttpClient.SiteEnum.EN.defaultEndpoint)) {
             return enLcClient.getClient().getHeader();
         } else {
             return cnLcClient.getClient().getHeader();
@@ -123,7 +129,7 @@ public static HttpResponse executePut(HttpRequest httpRequest) {
     }
 
     public static String getToken() {
-        Map<String,String> headerMap = getHeader(URLUtils.getLeetcodeHost());
+        Map<String, String> headerMap = getHeader(URLUtils.getLeetcodeHost());
         return headerMap.get("x-csrftoken");
     }
 
@@ -137,7 +143,7 @@ public static boolean isLogin(Project project) {
 
     public static void setCookie(List<HttpCookie> cookieList) {
         enLcClient.getClient().cookieStore().clearCookie(URLUtils.getLeetcodeHost());
-        enLcClient.getClient().cookieStore().addCookie(URLUtils.getLeetcodeHost(),cookieList);
+        enLcClient.getClient().cookieStore().addCookie(URLUtils.getLeetcodeHost(), cookieList);
     }
 
     public static void resetHttpclient() {
@@ -181,33 +187,111 @@ private static class MyExecutorHttp extends DefaultExecutoHttp {
         @Override
         public OkHttpClient getRequestClient() {
             final HttpConfigurable httpConfigurable = HttpConfigurable.getInstance();
-            if (!httpConfigurable.USE_HTTP_PROXY &&  !httpConfigurable.USE_PROXY_PAC) {
+            if (!httpConfigurable.USE_HTTP_PROXY && !httpConfigurable.USE_PROXY_PAC) {
                 return super.getRequestClient();
             }
             final IdeaWideProxySelector ideaWideProxySelector = new IdeaWideProxySelector(httpConfigurable);
             OkHttpClient.Builder builder = super.getRequestClient().newBuilder().proxySelector(ideaWideProxySelector);
             if (httpConfigurable.PROXY_AUTHENTICATION) {
-                final IdeaWideAuthenticator ideaWideAuthenticator = new IdeaWideAuthenticator(httpConfigurable);
+                final MyAuthenticator ideaWideAuthenticator = new MyAuthenticator(httpConfigurable);
                 final okhttp3.Authenticator proxyAuthenticator = getProxyAuthenticator(ideaWideAuthenticator);
                 builder.proxyAuthenticator(proxyAuthenticator);
             }
             return builder.build();
         }
 
-        private okhttp3.Authenticator getProxyAuthenticator(IdeaWideAuthenticator ideaWideAuthenticator) {
+        private okhttp3.Authenticator getProxyAuthenticator(MyAuthenticator ideaWideAuthenticator) {
             okhttp3.Authenticator proxyAuthenticator = null;
 
             if (Objects.nonNull(ideaWideAuthenticator)) {
                 proxyAuthenticator = (route, response) -> {
+                    ideaWideAuthenticator.SetResponse(response);
                     final PasswordAuthentication authentication = ideaWideAuthenticator.getPasswordAuthentication();
-                    final String credential = Credentials.basic(authentication.getUserName(), Arrays.toString(authentication.getPassword()));
-                    return response.request().newBuilder()
-                            .header("Proxy-Authorization", credential)
-                            .build();
+                    final String credential = Credentials.basic(authentication.getUserName(), new String(authentication.getPassword()));
+
+                    for (Challenge challenge : response.challenges()) {
+                        if (challenge.scheme().equalsIgnoreCase("OkHttp-Preemptive")) {
+                            return response.request().newBuilder()
+                                    .header("Proxy-Authorization", credential)
+                                    .build();
+                        }
+                    }
+                    return null;
                 };
             }
             return proxyAuthenticator;
         }
     }
+
+    private static class MyAuthenticator extends NonStaticAuthenticator {
+        private static final Logger LOG = Logger.getInstance(com.intellij.util.net.IdeaWideAuthenticator.class);
+        private final HttpConfigurable myHttpConfigurable;
+
+        private okhttp3.Response response;
+
+        public MyAuthenticator(@NotNull HttpConfigurable configurable) {
+            super();
+            this.myHttpConfigurable = configurable;
+        }
+
+
+        public void SetResponse(okhttp3.Response response) {
+            this.response = response;
+        }
+
+        public PasswordAuthentication getPasswordAuthentication() {
+            okhttp3.HttpUrl url = response.request().url();
+            Application application = ApplicationManager.getApplication();
+
+            if (StringUtils.isNoneBlank(myHttpConfigurable.getPlainProxyPassword()) && StringUtils.isNoneBlank(myHttpConfigurable.getProxyLogin())) {
+                return new PasswordAuthentication(myHttpConfigurable.getProxyLogin(), myHttpConfigurable.getPlainProxyPassword().toCharArray());
+            }
+
+            if (this.myHttpConfigurable.USE_HTTP_PROXY) {
+                LOG.debug("CommonAuthenticator.getPasswordAuthentication will return common defined proxy");
+                return this.myHttpConfigurable.getPromptedAuthentication(url.host() + ":" + url.port(), this.getRequestingPrompt());
+            }
+
+            if (this.myHttpConfigurable.USE_PROXY_PAC) {
+                LOG.debug("CommonAuthenticator.getPasswordAuthentication will return autodetected proxy");
+                if (this.myHttpConfigurable.isGenericPasswordCanceled(this.getRequestingHost(), this.getRequestingPort())) {
+                    return null;
+                }
+
+                PasswordAuthentication password = this.myHttpConfigurable.getGenericPassword(this.getRequestingHost(), this.getRequestingPort());
+                if (password != null) {
+                    return password;
+                }
+
+                if (application != null && !application.isDisposed()) {
+                    return this.myHttpConfigurable.getGenericPromptedAuthentication(PluginConstant.PLUGIN_ID, this.getRequestingHost(), this.getRequestingPrompt(), this.getRequestingPort(), true);
+                }
+
+                return null;
+            }
+
+            if (application != null && !application.isDisposed()) {
+                LOG.debug("CommonAuthenticator.getPasswordAuthentication generic authentication will be asked");
+                return null;
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        protected String getRequestingHost() {
+            return response.request().url().host();
+        }
+
+        @Override
+        protected int getRequestingPort() {
+            return response.request().url().port();
+        }
+
+        @Override
+        protected @Nls String getRequestingPrompt() {
+            return PluginConstant.PLUGIN_ID;
+        }
+    }
 }
 
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/AllNavigatorPanel.java b/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/AllNavigatorPanel.java
index 3363a44..7ca00c7 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/AllNavigatorPanel.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/AllNavigatorPanel.java
@@ -31,6 +31,8 @@
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
 import java.util.Map;
 
 /**
@@ -71,6 +73,12 @@ public AllNavigatorPanel(ToolWindow toolWindow, Project project) {
         queryField.setToolTipText("Enter Search");
         queryField.addKeyListener(new QueryKeyListener(queryField, myNavigatorAction, project));
         queryPanel.add(queryField);
+        queryPanel.addFocusListener(new FocusAdapter() {
+            @Override
+            public void focusGained(FocusEvent e) {
+                queryField.requestFocusInWindow();
+            }
+        });
 
         findToolbar = actionManager.createActionToolbar(PluginConstant.LEETCODE_ALL_FIND_TOOLBAR, (DefaultActionGroup) actionManager.getAction(PluginConstant.LEETCODE_ALL_FIND_TOOLBAR), true);
         findToolbar.setTargetComponent(navigatorTable);
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/NavigatorPanel.java b/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/NavigatorPanel.java
index 2a30729..6d9a95c 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/NavigatorPanel.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/navigator/NavigatorPanel.java
@@ -31,6 +31,8 @@
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
 import java.util.Map;
 
 /**
@@ -71,6 +73,12 @@ public NavigatorPanel(ToolWindow toolWindow, Project project) {
         queryField.setToolTipText("Enter Search");
         queryField.addKeyListener(new QueryKeyListener(queryField, myNavigatorAction, project));
         queryPanel.add(queryField);
+        queryPanel.addFocusListener(new FocusAdapter() {
+            @Override
+            public void focusGained(FocusEvent e) {
+                queryField.requestFocusInWindow();
+            }
+        });
 
         findToolbar = actionManager.createActionToolbar(PluginConstant.LEETCODE_FIND_TOOLBAR, (DefaultActionGroup) actionManager.getAction(PluginConstant.LEETCODE_FIND_TOOLBAR), true);
         findToolbar.setTargetComponent(navigatorTable);
diff --git a/src/main/kotlin/com/shuzijun/leetcode/plugin/listener/RegisterPluginInstallerStateListener.kt b/src/main/kotlin/com/shuzijun/leetcode/plugin/listener/RegisterPluginInstallerStateListener.kt
new file mode 100644
index 0000000..07f60c8
--- /dev/null
+++ b/src/main/kotlin/com/shuzijun/leetcode/plugin/listener/RegisterPluginInstallerStateListener.kt
@@ -0,0 +1,50 @@
+package com.shuzijun.leetcode.plugin.listener
+
+import com.intellij.ide.plugins.PluginManagerCore.getPlugin
+import com.intellij.ide.util.PropertiesComponent
+import com.intellij.openapi.extensions.PluginId
+import com.intellij.openapi.fileEditor.impl.HTMLEditorProvider
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.startup.StartupActivity
+import com.shuzijun.leetcode.plugin.model.PluginConstant
+import com.shuzijun.leetcode.plugin.setting.PersistentConfig
+
+/**
+ * @author shuzijun
+ */
+class RegisterPluginInstallerStateListener : StartupActivity {
+    override fun runActivity(project: Project) {
+        val newVersion = getPlugin(PluginId.getId(PluginConstant.PLUGIN_ID))!!.version
+        val config = PersistentConfig.getInstance().initConfig
+        val oldVersion: String?
+        if (config == null) {
+            oldVersion = PropertiesComponent.getInstance()
+                .getValue(ShowNewHTMLEditorKey)
+            PropertiesComponent.getInstance()
+                .setValue(ShowNewHTMLEditorKey, newVersion)
+        } else {
+            oldVersion = config.pluginVersion
+            config.pluginVersion = newVersion
+        }
+
+        if (newVersion != oldVersion) {
+            HTMLEditorProvider.openEditor(
+                project,
+                "What's New in " + PluginConstant.PLUGIN_ID,
+                CHANGELOGURL,
+                "'<div style='text-align: center;padding-top: 3rem'>" +
+                        "<div style='padding-top: 1rem; margin-bottom: 0.8rem;'>Failed to load!</div>" +
+                        "'<div><a href='" + CHANGELOGURL + "' target='_blank'" +
+                        "style='font-size: 2rem'>Open in browser</a></div>" +
+                        "</div>"
+            )
+        }
+    }
+
+    companion object {
+        private const val ShowNewHTMLEditorKey = PluginConstant.PLUGIN_ID + "ShowNewHTMLEditor"
+
+        private const val CHANGELOGURL = "https://github.com/shuzijun/leetcode-editor/blob/master/CHANGELOG.md"
+    }
+
+}
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index a6144b6..f87ed3e 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -22,7 +22,7 @@
     </application-components>
 
     <extensions defaultExtensionNs="com.intellij">
-        <postStartupActivity  implementation = "com.shuzijun.leetcode.plugin.listener.RegisterPluginInstallerStateListener"></postStartupActivity>
+        <postStartupActivity  implementation = "com.shuzijun.leetcode.plugin.listener.RegisterPluginInstallerStateListener"/>
         <errorHandler implementation="com.shuzijun.leetcode.plugin.listener.ErrorReportHandler"/>
         <toolWindow id="Leetcode" secondary="false" icon="LeetCodeEditorIcons.LEETCODE_TOOL_WINDOW" anchor="left"
                     factoryClass="com.shuzijun.leetcode.plugin.window.WindowFactory" />
diff --git a/src/test/java/com/shuzijun/leetcode/HttpTest.java b/src/test/java/com/shuzijun/leetcode/HttpTest.java
new file mode 100644
index 0000000..a69ea22
--- /dev/null
+++ b/src/test/java/com/shuzijun/leetcode/HttpTest.java
@@ -0,0 +1,53 @@
+package com.shuzijun.leetcode;
+
+import com.shuzijun.lc.errors.LcException;
+import com.shuzijun.lc.http.DefaultExecutoHttp;
+import okhttp3.Authenticator;
+import okhttp3.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.*;
+import java.util.Collections;
+import java.util.List;
+
+public class HttpTest {
+
+    @Test
+    public void testVerify() throws LcException, IOException {
+
+        DefaultExecutoHttp defaultExecutoHttp = new DefaultExecutoHttp();
+        OkHttpClient httpClient = defaultExecutoHttp.getRequestClient().newBuilder().proxySelector(new ProxySelector() {
+            @Override
+            public List<Proxy> select(URI uri) {
+                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888));
+                return Collections.singletonList(proxy);
+            }
+
+            @Override
+            public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+
+            }
+        }).proxyAuthenticator(new Authenticator() {
+            @Nullable
+            @Override
+            public Request authenticate(@Nullable Route route, @NotNull Response response) throws IOException {
+                PasswordAuthentication authentication =new PasswordAuthentication("test", "test12345".toCharArray());
+                final String credential = Credentials.basic(authentication.getUserName(),new String(authentication.getPassword()));
+
+                for (Challenge challenge : response.challenges()) {
+                    if (challenge.scheme().equalsIgnoreCase("OkHttp-Preemptive")) {
+                        return response.request().newBuilder()
+                                .header("Proxy-Authorization", credential)
+                                .build();
+                    }
+                }
+                return null;
+            }
+        }).build();
+        Response response = httpClient.newCall( (new Request.Builder()).url("https://www.baidu.com").method("get",null).build()).execute();
+        System.out.println(response.body());
+    }
+}

From c58ebf1c2fa6e4e3e791f7f2f56cf43b3ab295f9 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Wed, 15 May 2024 20:15:21 +0800
Subject: [PATCH 11/15] version

---
 CHANGELOG.md      | 16 ++++++++++++++++
 gradle.properties |  2 +-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9639396..6e0c0f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,22 @@
 [![捐赠][badge:donate-zh]][shuzijun-donate]
 [![内推][badge:referrals]][shuzijun-referrals]
 
+## 8.12.0
+
+### Added
+- Code Type: Pandas & PostgreSQL enhancement [#709](https://github.com/shuzijun/leetcode-editor/issues/709)
+- 希望点击搜索按钮时可以自动聚焦到搜索框 [#713](https://github.com/shuzijun/leetcode-editor/issues/713)
+### Changed
+
+### Deprecated
+
+### Fixed
+- fix [#708](https://github.com/shuzijun/leetcode-editor/issues/708)
+- fix [#712](https://github.com/shuzijun/leetcode-editor/issues/712)
+- 
+### Removed
+
+
 ## 8.11.0
 
 ### Added
diff --git a/gradle.properties b/gradle.properties
index 0a3d74a..1bd8bce 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
 pluginGroup = com.shuzijun.leetcode
 pluginName = leetcode-editor
-pluginVersion = 8.11
+pluginVersion = 8.12
 
 pluginSinceBuild = 203.0
 pluginUntilBuild =

From a2bafd92a6bf7c76b586629c60daa9d1a82aeb49 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Mon, 20 May 2024 14:42:07 +0800
Subject: [PATCH 12/15] fix #719

---
 .../leetcode/plugin/window/WindowFactory.java        | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/shuzijun/leetcode/plugin/window/WindowFactory.java b/src/main/java/com/shuzijun/leetcode/plugin/window/WindowFactory.java
index 49ba055..19dd6e5 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/window/WindowFactory.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/window/WindowFactory.java
@@ -11,6 +11,7 @@
 import com.intellij.openapi.wm.ToolWindowManager;
 import com.intellij.ui.content.Content;
 import com.intellij.ui.content.ContentFactory;
+import com.intellij.ui.content.ContentManager;
 import com.shuzijun.leetcode.plugin.model.PluginConstant;
 import com.shuzijun.leetcode.plugin.setting.PersistentConfig;
 import icons.LeetCodeEditorIcons;
@@ -52,8 +53,15 @@ public static DataContext getDataContext(@NotNull Project project) {
         if (leetcodeToolWindows == null) {
             return DataContext.EMPTY_CONTEXT;
         }
-
-        JComponent navigatorPanel =  leetcodeToolWindows.getContentManager().getContent(0).getComponent();
+        ContentManager navigatorContentManager = leetcodeToolWindows.getContentManagerIfCreated();
+        if (navigatorContentManager == null) {
+            return DataContext.EMPTY_CONTEXT;
+        }
+        Content navigatorContent= navigatorContentManager.getContent(0);
+        if (navigatorContent == null) {
+            return DataContext.EMPTY_CONTEXT;
+        }
+        JComponent navigatorPanel =  navigatorContent.getComponent();
         if (navigatorPanel instanceof DataProvider){
             return new MyDataContext((DataProvider) navigatorPanel);
         }

From 99466b69a934df0f5fc2ecc5b025446aa766a97f Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Mon, 20 May 2024 14:44:13 +0800
Subject: [PATCH 13/15] version

---
 CHANGELOG.md      | 14 ++++++++++++++
 gradle.properties |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6e0c0f8..4454033 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,20 @@
 [![捐赠][badge:donate-zh]][shuzijun-donate]
 [![内推][badge:referrals]][shuzijun-referrals]
 
+## 8.13.0
+
+### Added
+
+### Changed
+
+### Deprecated
+
+### Fixed
+- fix [#719](https://github.com/shuzijun/leetcode-editor/issues/719)
+- 
+### Removed
+
+
 ## 8.12.0
 
 ### Added
diff --git a/gradle.properties b/gradle.properties
index 1bd8bce..864e8d4 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
 pluginGroup = com.shuzijun.leetcode
 pluginName = leetcode-editor
-pluginVersion = 8.12
+pluginVersion = 8.13
 
 pluginSinceBuild = 203.0
 pluginUntilBuild =

From 1196129503dec4444060ebf0f294f73208875ed2 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Mon, 12 Aug 2024 20:53:43 +0800
Subject: [PATCH 14/15] fix #726

---
 .../editor/QuestionEditorWithPreview.java     |  7 +++++-
 .../editor/converge/ContentProvider.java      |  8 ++++++-
 .../leetcode/plugin/utils/FileUtils.java      | 24 ++++++++++---------
 3 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/src/main/java/com/shuzijun/leetcode/plugin/editor/QuestionEditorWithPreview.java b/src/main/java/com/shuzijun/leetcode/plugin/editor/QuestionEditorWithPreview.java
index 64743a3..796fa34 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/editor/QuestionEditorWithPreview.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/editor/QuestionEditorWithPreview.java
@@ -5,6 +5,7 @@
 import com.intellij.openapi.actionSystem.ActionGroup;
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.FileEditorLocation;
 import com.intellij.openapi.fileEditor.TextEditor;
@@ -98,7 +99,11 @@ public TextEditor getTextEditor() {
 
     }
 
-    public FileEditor getPreviewEditor() {
+    public @NotNull FileEditor getPreviewEditor() {
         return myPreview == getTextEditor() ? myEditor : myPreview;
     }
+
+    public @NotNull Editor getEditor() {
+        return getTextEditor().getEditor();
+    }
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/editor/converge/ContentProvider.java b/src/main/java/com/shuzijun/leetcode/plugin/editor/converge/ContentProvider.java
index 9bc28eb..9efcbf2 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/editor/converge/ContentProvider.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/editor/converge/ContentProvider.java
@@ -1,5 +1,6 @@
 package com.shuzijun.leetcode.plugin.editor.converge;
 
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.LocalFileSystem;
@@ -24,8 +25,13 @@ public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {
     @Override
     public @NotNull FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) {
         LeetcodeEditor leetcodeEditor = ProjectConfig.getInstance(project).getEditor(file.getPath());
-        VirtualFile contentVf = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(leetcodeEditor.getContentPath()));
 
+        VirtualFile contentVf;
+        try {
+            contentVf = ApplicationManager.getApplication().executeOnPooledThread(() -> LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(leetcodeEditor.getContentPath()))).get();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
         return super.createEditor(project, contentVf);
     }
 }
diff --git a/src/main/java/com/shuzijun/leetcode/plugin/utils/FileUtils.java b/src/main/java/com/shuzijun/leetcode/plugin/utils/FileUtils.java
index 623c798..e67f836 100644
--- a/src/main/java/com/shuzijun/leetcode/plugin/utils/FileUtils.java
+++ b/src/main/java/com/shuzijun/leetcode/plugin/utils/FileUtils.java
@@ -225,19 +225,21 @@ public static void openFileEditor(File file, Project project) {
 
 
     public static void openFileEditorAndSaveState(File file, Project project, Question question, BiConsumer<LeetcodeEditor,String> consumer,boolean isOpen) {
-        ApplicationManager.getApplication().invokeLater(() -> {
-            VirtualFile vf = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
-            LeetcodeEditor leetcodeEditor = ProjectConfig.getInstance(project).getDefEditor(URLUtils.getLeetcodeHost()+question.getFrontendQuestionId());
-            leetcodeEditor.setFrontendQuestionId(URLUtils.getLeetcodeHost()+question.getFrontendQuestionId());
-            leetcodeEditor.setTitleSlug(question.getTitleSlug());
-            leetcodeEditor.setHost(URLUtils.getLeetcodeHost());
-            consumer.accept(leetcodeEditor,vf.getPath());
-            ProjectConfig.getInstance(project).addLeetcodeEditor(leetcodeEditor);
-            if(isOpen) {
+        VirtualFile vf = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+        LeetcodeEditor leetcodeEditor = ProjectConfig.getInstance(project).getDefEditor(URLUtils.getLeetcodeHost()+question.getFrontendQuestionId());
+        leetcodeEditor.setFrontendQuestionId(URLUtils.getLeetcodeHost()+question.getFrontendQuestionId());
+        leetcodeEditor.setTitleSlug(question.getTitleSlug());
+        leetcodeEditor.setHost(URLUtils.getLeetcodeHost());
+        consumer.accept(leetcodeEditor,vf.getPath());
+        ProjectConfig.getInstance(project).addLeetcodeEditor(leetcodeEditor);
+
+        if(isOpen) {
+            ApplicationManager.getApplication().invokeLater(() -> {
                 OpenFileDescriptor descriptor = new OpenFileDescriptor(project, vf);
                 FileEditorManager.getInstance(project).openTextEditor(descriptor, false);
-            }
-        });
+            });
+        }
+
     }
 
     public static void saveEditDocument(VirtualFile file){

From 653345c110f6867e5824cbb28f63328894e80142 Mon Sep 17 00:00:00 2001
From: shuzijun <shuzijun0109@gmail.com>
Date: Mon, 12 Aug 2024 20:55:40 +0800
Subject: [PATCH 15/15] version

---
 CHANGELOG.md      | 14 ++++++++++++++
 build.gradle      |  2 +-
 gradle.properties |  2 +-
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4454033..cfe333b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,20 @@
 [![捐赠][badge:donate-zh]][shuzijun-donate]
 [![内推][badge:referrals]][shuzijun-referrals]
 
+## 8.14.0
+
+### Added
+
+### Changed
+
+### Deprecated
+
+### Fixed
+- fix [#726](https://github.com/shuzijun/leetcode-editor/issues/726)
+-
+### Removed
+
+
 ## 8.13.0
 
 ### Added
diff --git a/build.gradle b/build.gradle
index 8d6310d..ff765c0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
 plugins {
     id 'java-library'
-    id 'org.jetbrains.intellij' version '1.14.2'
+    id 'org.jetbrains.intellij' version '1.17.4'
     id("org.jetbrains.kotlin.jvm") version "1.9.23"
     id 'org.jetbrains.changelog' version "1.3.1"
     id "de.undercouch.download" version "4.0.2"
diff --git a/gradle.properties b/gradle.properties
index 864e8d4..9a63fc0 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,6 +1,6 @@
 pluginGroup = com.shuzijun.leetcode
 pluginName = leetcode-editor
-pluginVersion = 8.13
+pluginVersion = 8.14
 
 pluginSinceBuild = 203.0
 pluginUntilBuild =
