diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index f825dd2..69a11d2 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -32,6 +32,7 @@ jobs:
         run: go test -v -coverprofile='coverage.txt' -covermode=atomic ./...
 
       - name: Upload Coverage report
-        uses: codecov/codecov-action@v3
+        uses: codecov/codecov-action@v4
         with:
           file: ./coverage.txt
+          token: ${{ secrets.CODECOV_TOKEN }}
diff --git a/go.mod b/go.mod
index 305da48..94f353d 100644
--- a/go.mod
+++ b/go.mod
@@ -1,17 +1,17 @@
 module github.com/issue9/webfilter
 
-go 1.22
+go 1.22.0
 
 require (
 	github.com/google/uuid v1.6.0
 	github.com/issue9/assert/v4 v4.1.1
 	github.com/issue9/version v1.0.8
-	github.com/issue9/web v0.88.0
+	github.com/issue9/web v0.89.0
 )
 
 require (
 	github.com/andybalholm/brotli v1.1.0 // indirect
-	github.com/issue9/cache v0.10.0 // indirect
+	github.com/issue9/cache v0.12.0 // indirect
 	github.com/issue9/config v0.6.2 // indirect
 	github.com/issue9/conv v1.3.5 // indirect
 	github.com/issue9/errwrap v0.3.2 // indirect
@@ -19,7 +19,7 @@ require (
 	github.com/issue9/logs/v7 v7.5.1 // indirect
 	github.com/issue9/mux/v7 v7.4.2 // indirect
 	github.com/issue9/query/v3 v3.1.3 // indirect
-	github.com/issue9/scheduled v0.19.3 // indirect
+	github.com/issue9/scheduled v0.19.4 // indirect
 	github.com/issue9/sliceutil v0.16.0 // indirect
 	github.com/issue9/source v0.8.3 // indirect
 	github.com/issue9/term/v3 v3.2.7 // indirect
diff --git a/go.sum b/go.sum
index 8ba7e89..b4f86d3 100644
--- a/go.sum
+++ b/go.sum
@@ -6,8 +6,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/issue9/assert/v4 v4.1.1 h1:OhPE8SB8n/qZCNGLQa+6MQtr/B3oON0JAVj68k8jJlc=
 github.com/issue9/assert/v4 v4.1.1/go.mod h1:v7qDRXi7AsaZZNh8eAK2rkLJg5/clztqQGA1DRv9Lv4=
-github.com/issue9/cache v0.10.0 h1:pgw4kbAFUeUu9pOKcNSdc+BhhXwdRFzjwAvWAX2BWHc=
-github.com/issue9/cache v0.10.0/go.mod h1:0s9j7qiKv4uWYqz0D2N2H7bIBvmtD+903h5GqnxW6i4=
+github.com/issue9/cache v0.12.0 h1:NiDBuN9x22H4UJsOMDoEuIFA8r3qNqPqO9vyzzcvzoY=
+github.com/issue9/cache v0.12.0/go.mod h1:0s9j7qiKv4uWYqz0D2N2H7bIBvmtD+903h5GqnxW6i4=
 github.com/issue9/config v0.6.2 h1:znXvsk6gh0wm+fTEn0zUjjramKuOLY8Jt0ZTxp4GIkc=
 github.com/issue9/config v0.6.2/go.mod h1:S97FVtZim4rPB+M49EoOuBajaqY4ULQbqltZmZ99+Dc=
 github.com/issue9/conv v1.3.5 h1:UWeA+Zqp5vjNDLrmhLhaXPjS1hL8gh4quX6Shk5njKQ=
@@ -22,22 +22,22 @@ github.com/issue9/mux/v7 v7.4.2 h1:BIuHX7g3RctaVlu4dCf6drrTT6GzToo0T3/d7dGCcOs=
 github.com/issue9/mux/v7 v7.4.2/go.mod h1:NQ5vH/HD3QDil227u5DGT9PN9IP7j/Dx7+cSSEBgvhM=
 github.com/issue9/query/v3 v3.1.3 h1:Y6ETEYXxaKqhpM4lXPKCffhJ72VuKQbrAwgwHlacu0Y=
 github.com/issue9/query/v3 v3.1.3/go.mod h1:a/W/+7iel9K+5rRT4AFAKR8+OJeV5axeF6tK9My4lNA=
-github.com/issue9/rands/v2 v2.0.1 h1:Bg6ASFymqrEYb1MPEKUihFLoRJ7i5TfczbLS9Zw8/gs=
-github.com/issue9/rands/v2 v2.0.1/go.mod h1:xSSN8bmW5Vuo7C/oRz+xvUxinYgloHkVu92DzgyylIk=
-github.com/issue9/scheduled v0.19.3 h1:hI/8gh1SMH62inPVsrZazRBxc91RQT/YbnWr1S9se08=
-github.com/issue9/scheduled v0.19.3/go.mod h1:4OTuwC3QMRJLGRV8ImmRS2bqX58bDjKi2OAuzHcgJuQ=
+github.com/issue9/rands/v3 v3.0.1 h1:EnX9WNushGgHCzoL/R5eBPaLfvjLO/c7CGHNgLK0JhY=
+github.com/issue9/rands/v3 v3.0.1/go.mod h1:n4mM2ts7NCpuxHwS9zorPITJBWEUGksXg6cTOH6yqS0=
+github.com/issue9/scheduled v0.19.4 h1:Wg9S7rOmMpn2O0F1OVb51o8FYGibdMjPkElgjEKcYK4=
+github.com/issue9/scheduled v0.19.4/go.mod h1:S63DdPErP0aXsEnUzc27F+v0koMf+2V4V+CpY7tvr8o=
 github.com/issue9/sliceutil v0.16.0 h1:+gyumWF126mprQLiUi14s6SAeucMg1vuyPEh66VTtC8=
 github.com/issue9/sliceutil v0.16.0/go.mod h1:ldun6sT4/bOJxuMtOXhtc6P7GCwE7L+avV86HNks7qk=
 github.com/issue9/source v0.8.3 h1:MH883uljg0fupE/qkqJm3RqA5/l40KR+HsR7Mp3zjYY=
 github.com/issue9/source v0.8.3/go.mod h1:H0Joo5go08sIMODLvQXpWwiWpGrH2MiTMFhKBZhVbH8=
 github.com/issue9/term/v3 v3.2.7 h1:esfhoinbQ65P3oFscXhticrDFOgZJQqUwL/IC70HiWc=
 github.com/issue9/term/v3 v3.2.7/go.mod h1:DvA/fPiKzX11P/ZoVWJG5QMVpI0ia+uqiU31iZV2jHE=
-github.com/issue9/unique/v2 v2.0.1 h1:Tdbq7hWZd7rvnf3ckUqzvEftOBWl1Z3S60Jk/zbPvyM=
-github.com/issue9/unique/v2 v2.0.1/go.mod h1:oYIXt0BXX4tekc9+77oBu/ROsm7tr5kmD78XEqFoWwk=
+github.com/issue9/unique/v2 v2.1.0 h1:lE9hstenrbBgDM/Iulv7d75qAYpgoDV8rSRoLmEBHOk=
+github.com/issue9/unique/v2 v2.1.0/go.mod h1:qZoDKnfu+7Q0yxhifVseRKD2Wea9Tc9zdXwALnFc54A=
 github.com/issue9/version v1.0.8 h1:IsNdDYdV8UGDGwwgp8H4RszJE0Ko26HjWg9pZzyOivs=
 github.com/issue9/version v1.0.8/go.mod h1:w8bQwODBOG5+iaS3qIJbElxxpp3Uo4x5F39qKBqwpdc=
-github.com/issue9/web v0.88.0 h1:BUSBbUfKTZre3n3YDBFQU02eUlru8fRhmlaeECyRUVQ=
-github.com/issue9/web v0.88.0/go.mod h1:XlxxlnmthHpWnuK1OXMQhK55/I7tNui9a6lzZMmCbj0=
+github.com/issue9/web v0.89.0 h1:hfyhMWqJv8dumZZkT2kXcV3sDwkM1GjjcTjMGuk53IM=
+github.com/issue9/web v0.89.0/go.mod h1:CnDJ05ITcOTVVdAnc3tLBpV7aYqUW6j5FOEiJtA5GdU=
 github.com/jellydator/ttlcache/v3 v3.2.0 h1:6lqVJ8X3ZaUwvzENqPAobDsXNExfUJd61u++uW8a3LE=
 github.com/jellydator/ttlcache/v3 v3.2.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4=
 github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=