diff --git a/go.mod b/go.mod
index f302ca6ab4f48c1b0d9c115e8e969e9a7ae9fb69..580c31d0000f2b8c1baebed814c6a9522be31cc6 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
 	github.com/PuerkitoBio/goquery v1.7.1
 	github.com/PuerkitoBio/purell v0.1.0
 	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
-	github.com/google/go-cmp v0.5.6
+	github.com/google/go-cmp v0.5.9
 	github.com/google/uuid v1.1.1 // indirect
 	github.com/pborman/uuid v1.2.1
 	github.com/syndtr/goleveldb v0.0.0-20190923125748-758128399b1d
diff --git a/go.sum b/go.sum
index b977e7259b9c323c68db509c2cad1e58a8a4b8b4..daa075decc30af7562d112b7a78bf3b4901ec093 100644
--- a/go.sum
+++ b/go.sum
@@ -22,6 +22,8 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go
index 86d0903b8b542e1ab579943426b3355916702738..087320da7f0f515a54f0bbef192284b14d69e80d 100644
--- a/vendor/github.com/google/go-cmp/cmp/compare.go
+++ b/vendor/github.com/google/go-cmp/cmp/compare.go
@@ -13,21 +13,21 @@
 //
 // The primary features of cmp are:
 //
-// • When the default behavior of equality does not suit the needs of the test,
-// custom equality functions can override the equality operation.
-// For example, an equality function may report floats as equal so long as they
-// are within some tolerance of each other.
+//   - When the default behavior of equality does not suit the test's needs,
+//     custom equality functions can override the equality operation.
+//     For example, an equality function may report floats as equal so long as
+//     they are within some tolerance of each other.
 //
-// • Types that have an Equal method may use that method to determine equality.
-// This allows package authors to determine the equality operation for the types
-// that they define.
+//   - Types with an Equal method may use that method to determine equality.
+//     This allows package authors to determine the equality operation
+//     for the types that they define.
 //
-// • If no custom equality functions are used and no Equal method is defined,
-// equality is determined by recursively comparing the primitive kinds on both
-// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported
-// fields are not compared by default; they result in panics unless suppressed
-// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly
-// compared using the Exporter option.
+//   - If no custom equality functions are used and no Equal method is defined,
+//     equality is determined by recursively comparing the primitive kinds on
+//     both values, much like reflect.DeepEqual. Unlike reflect.DeepEqual,
+//     unexported fields are not compared by default; they result in panics
+//     unless suppressed by using an Ignore option (see cmpopts.IgnoreUnexported)
+//     or explicitly compared using the Exporter option.
 package cmp
 
 import (
@@ -36,33 +36,34 @@ import (
 	"strings"
 
 	"github.com/google/go-cmp/cmp/internal/diff"
-	"github.com/google/go-cmp/cmp/internal/flags"
 	"github.com/google/go-cmp/cmp/internal/function"
 	"github.com/google/go-cmp/cmp/internal/value"
 )
 
+// TODO(≥go1.18): Use any instead of interface{}.
+
 // Equal reports whether x and y are equal by recursively applying the
 // following rules in the given order to x and y and all of their sub-values:
 //
-// • Let S be the set of all Ignore, Transformer, and Comparer options that
-// remain after applying all path filters, value filters, and type filters.
-// If at least one Ignore exists in S, then the comparison is ignored.
-// If the number of Transformer and Comparer options in S is greater than one,
-// then Equal panics because it is ambiguous which option to use.
-// If S contains a single Transformer, then use that to transform the current
-// values and recursively call Equal on the output values.
-// If S contains a single Comparer, then use that to compare the current values.
-// Otherwise, evaluation proceeds to the next rule.
+//   - Let S be the set of all Ignore, Transformer, and Comparer options that
+//     remain after applying all path filters, value filters, and type filters.
+//     If at least one Ignore exists in S, then the comparison is ignored.
+//     If the number of Transformer and Comparer options in S is non-zero,
+//     then Equal panics because it is ambiguous which option to use.
+//     If S contains a single Transformer, then use that to transform
+//     the current values and recursively call Equal on the output values.
+//     If S contains a single Comparer, then use that to compare the current values.
+//     Otherwise, evaluation proceeds to the next rule.
 //
-// • If the values have an Equal method of the form "(T) Equal(T) bool" or
-// "(T) Equal(I) bool" where T is assignable to I, then use the result of
-// x.Equal(y) even if x or y is nil. Otherwise, no such method exists and
-// evaluation proceeds to the next rule.
+//   - If the values have an Equal method of the form "(T) Equal(T) bool" or
+//     "(T) Equal(I) bool" where T is assignable to I, then use the result of
+//     x.Equal(y) even if x or y is nil. Otherwise, no such method exists and
+//     evaluation proceeds to the next rule.
 //
-// • Lastly, try to compare x and y based on their basic kinds.
-// Simple kinds like booleans, integers, floats, complex numbers, strings, and
-// channels are compared using the equivalent of the == operator in Go.
-// Functions are only equal if they are both nil, otherwise they are unequal.
+//   - Lastly, try to compare x and y based on their basic kinds.
+//     Simple kinds like booleans, integers, floats, complex numbers, strings,
+//     and channels are compared using the equivalent of the == operator in Go.
+//     Functions are only equal if they are both nil, otherwise they are unequal.
 //
 // Structs are equal if recursively calling Equal on all fields report equal.
 // If a struct contains unexported fields, Equal panics unless an Ignore option
@@ -143,7 +144,7 @@ func rootStep(x, y interface{}) PathStep {
 	// so that they have the same parent type.
 	var t reflect.Type
 	if !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() {
-		t = reflect.TypeOf((*interface{})(nil)).Elem()
+		t = anyType
 		if vx.IsValid() {
 			vvx := reflect.New(t).Elem()
 			vvx.Set(vx)
@@ -319,7 +320,6 @@ func (s *state) tryMethod(t reflect.Type, vx, vy reflect.Value) bool {
 }
 
 func (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value {
-	v = sanitizeValue(v, f.Type().In(0))
 	if !s.dynChecker.Next() {
 		return f.Call([]reflect.Value{v})[0]
 	}
@@ -343,8 +343,6 @@ func (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value {
 }
 
 func (s *state) callTTBFunc(f, x, y reflect.Value) bool {
-	x = sanitizeValue(x, f.Type().In(0))
-	y = sanitizeValue(y, f.Type().In(1))
 	if !s.dynChecker.Next() {
 		return f.Call([]reflect.Value{x, y})[0].Bool()
 	}
@@ -372,19 +370,6 @@ func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) {
 	ret = f.Call(vs)[0]
 }
 
-// sanitizeValue converts nil interfaces of type T to those of type R,
-// assuming that T is assignable to R.
-// Otherwise, it returns the input value as is.
-func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value {
-	// TODO(≥go1.10): Workaround for reflect bug (https://golang.org/issue/22143).
-	if !flags.AtLeastGo110 {
-		if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t {
-			return reflect.New(t).Elem()
-		}
-	}
-	return v
-}
-
 func (s *state) compareStruct(t reflect.Type, vx, vy reflect.Value) {
 	var addr bool
 	var vax, vay reflect.Value // Addressable versions of vx and vy
@@ -654,7 +639,9 @@ type dynChecker struct{ curr, next int }
 // Next increments the state and reports whether a check should be performed.
 //
 // Checks occur every Nth function call, where N is a triangular number:
+//
 //	0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ...
+//
 // See https://en.wikipedia.org/wiki/Triangular_number
 //
 // This sequence ensures that the cost of checks drops significantly as
diff --git a/vendor/github.com/google/go-cmp/cmp/export_panic.go b/vendor/github.com/google/go-cmp/cmp/export_panic.go
index 5ff0b4218c6de5ed3e8e73cdb3e9cf256589b1c2..ae851fe53f29ac999392fad6465c5dccf2ba702d 100644
--- a/vendor/github.com/google/go-cmp/cmp/export_panic.go
+++ b/vendor/github.com/google/go-cmp/cmp/export_panic.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build purego
 // +build purego
 
 package cmp
diff --git a/vendor/github.com/google/go-cmp/cmp/export_unsafe.go b/vendor/github.com/google/go-cmp/cmp/export_unsafe.go
index 21eb54858e034405b22b59fa8f55931a59b48d16..e2c0f74e8393e12353d447342b574bd40584f415 100644
--- a/vendor/github.com/google/go-cmp/cmp/export_unsafe.go
+++ b/vendor/github.com/google/go-cmp/cmp/export_unsafe.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !purego
 // +build !purego
 
 package cmp
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
index 1daaaacc5ee61def5ad03d73a148325a61c88757..36062a604ca3e5fb76ea9f0f297ebf1fe06f0c83 100644
--- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
+++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !cmp_debug
 // +build !cmp_debug
 
 package diff
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
index 4b91dbcacaef2058b3b20a6207507637d899ec37..a3b97a1ad57188171a2bc9439372d740da0b65e4 100644
--- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
+++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cmp_debug
 // +build cmp_debug
 
 package diff
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
index bc196b16cfaadc883ef553badca5f1f16f55dce1..a248e5436d98e0ae489e9b017e92a5875e3c4020 100644
--- a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
+++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
@@ -127,9 +127,9 @@ var randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0
 // This function returns an edit-script, which is a sequence of operations
 // needed to convert one list into the other. The following invariants for
 // the edit-script are maintained:
-//	• eq == (es.Dist()==0)
-//	• nx == es.LenX()
-//	• ny == es.LenY()
+//   - eq == (es.Dist()==0)
+//   - nx == es.LenX()
+//   - ny == es.LenY()
 //
 // This algorithm is not guaranteed to be an optimal solution (i.e., one that
 // produces an edit-script with a minimal Levenshtein distance). This algorithm
@@ -169,12 +169,13 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) {
 	// A diagonal edge is equivalent to a matching symbol between both X and Y.
 
 	// Invariants:
-	//	• 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx
-	//	• 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny
+	//   - 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx
+	//   - 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny
 	//
 	// In general:
-	//	• fwdFrontier.X < revFrontier.X
-	//	• fwdFrontier.Y < revFrontier.Y
+	//   - fwdFrontier.X < revFrontier.X
+	//   - fwdFrontier.Y < revFrontier.Y
+	//
 	// Unless, it is time for the algorithm to terminate.
 	fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)}
 	revPath := path{-1, point{nx, ny}, make(EditScript, 0)}
@@ -195,19 +196,21 @@ func Difference(nx, ny int, f EqualFunc) (es EditScript) {
 	// computing sub-optimal edit-scripts between two lists.
 	//
 	// The algorithm is approximately as follows:
-	//	• Searching for differences switches back-and-forth between
-	//	a search that starts at the beginning (the top-left corner), and
-	//	a search that starts at the end (the bottom-right corner). The goal of
-	//	the search is connect with the search from the opposite corner.
-	//	• As we search, we build a path in a greedy manner, where the first
-	//	match seen is added to the path (this is sub-optimal, but provides a
-	//	decent result in practice). When matches are found, we try the next pair
-	//	of symbols in the lists and follow all matches as far as possible.
-	//	• When searching for matches, we search along a diagonal going through
-	//	through the "frontier" point. If no matches are found, we advance the
-	//	frontier towards the opposite corner.
-	//	• This algorithm terminates when either the X coordinates or the
-	//	Y coordinates of the forward and reverse frontier points ever intersect.
+	//   - Searching for differences switches back-and-forth between
+	//     a search that starts at the beginning (the top-left corner), and
+	//     a search that starts at the end (the bottom-right corner).
+	//     The goal of the search is connect with the search
+	//     from the opposite corner.
+	//   - As we search, we build a path in a greedy manner,
+	//     where the first match seen is added to the path (this is sub-optimal,
+	//     but provides a decent result in practice). When matches are found,
+	//     we try the next pair of symbols in the lists and follow all matches
+	//     as far as possible.
+	//   - When searching for matches, we search along a diagonal going through
+	//     through the "frontier" point. If no matches are found,
+	//     we advance the frontier towards the opposite corner.
+	//   - This algorithm terminates when either the X coordinates or the
+	//     Y coordinates of the forward and reverse frontier points ever intersect.
 
 	// This algorithm is correct even if searching only in the forward direction
 	// or in the reverse direction. We do both because it is commonly observed
@@ -389,6 +392,7 @@ type point struct{ X, Y int }
 func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy }
 
 // zigzag maps a consecutive sequence of integers to a zig-zag sequence.
+//
 //	[0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...]
 func zigzag(x int) int {
 	if x&1 != 0 {
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go
deleted file mode 100644
index 82d1d7fbf8a28b5090d8ac819236cb4d8a73dd4e..0000000000000000000000000000000000000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2019, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.10
-
-package flags
-
-// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10.
-const AtLeastGo110 = false
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go
deleted file mode 100644
index 8646f05293439689aa406db0cbdcea887466dd9c..0000000000000000000000000000000000000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2019, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.10
-
-package flags
-
-// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10.
-const AtLeastGo110 = true
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/name.go b/vendor/github.com/google/go-cmp/cmp/internal/value/name.go
index b6c12cefb47e67ec457a1b4beabd4a26d0d929dd..7b498bb2cb95cd4277a79e58131712c09aa65bd0 100644
--- a/vendor/github.com/google/go-cmp/cmp/internal/value/name.go
+++ b/vendor/github.com/google/go-cmp/cmp/internal/value/name.go
@@ -9,6 +9,8 @@ import (
 	"strconv"
 )
 
+var anyType = reflect.TypeOf((*interface{})(nil)).Elem()
+
 // TypeString is nearly identical to reflect.Type.String,
 // but has an additional option to specify that full type names be used.
 func TypeString(t reflect.Type, qualified bool) string {
@@ -20,6 +22,11 @@ func appendTypeName(b []byte, t reflect.Type, qualified, elideFunc bool) []byte
 	// of the same name and within the same package,
 	// but declared within the namespace of different functions.
 
+	// Use the "any" alias instead of "interface{}" for better readability.
+	if t == anyType {
+		return append(b, "any"...)
+	}
+
 	// Named type.
 	if t.Name() != "" {
 		if qualified && t.PkgPath() != "" {
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
index 44f4a5afddcb7c11cd0b211b096174615e03294f..1a71bfcbd39b11f1e8890befb4e47a3bb3b395ee 100644
--- a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
+++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build purego
 // +build purego
 
 package value
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
index a605953d46660d8759543eee4cecda0b78c06b94..16e6860af6e1a46ce381a2aec400dcfce3b8e442 100644
--- a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
+++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !purego
 // +build !purego
 
 package value
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go b/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
deleted file mode 100644
index 9147a29973110e125cb5f6b4d3c28971ef0d12c3..0000000000000000000000000000000000000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/value/zero.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package value
-
-import (
-	"math"
-	"reflect"
-)
-
-// IsZero reports whether v is the zero value.
-// This does not rely on Interface and so can be used on unexported fields.
-func IsZero(v reflect.Value) bool {
-	switch v.Kind() {
-	case reflect.Bool:
-		return v.Bool() == false
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return v.Int() == 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return v.Uint() == 0
-	case reflect.Float32, reflect.Float64:
-		return math.Float64bits(v.Float()) == 0
-	case reflect.Complex64, reflect.Complex128:
-		return math.Float64bits(real(v.Complex())) == 0 && math.Float64bits(imag(v.Complex())) == 0
-	case reflect.String:
-		return v.String() == ""
-	case reflect.UnsafePointer:
-		return v.Pointer() == 0
-	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
-		return v.IsNil()
-	case reflect.Array:
-		for i := 0; i < v.Len(); i++ {
-			if !IsZero(v.Index(i)) {
-				return false
-			}
-		}
-		return true
-	case reflect.Struct:
-		for i := 0; i < v.NumField(); i++ {
-			if !IsZero(v.Field(i)) {
-				return false
-			}
-		}
-		return true
-	}
-	return false
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go
index e57b9eb5392d22f0230e4c3e48a44f9efff73e48..1f9ca9c4892b5258beea5e70ddc1d40c78baa122 100644
--- a/vendor/github.com/google/go-cmp/cmp/options.go
+++ b/vendor/github.com/google/go-cmp/cmp/options.go
@@ -33,6 +33,7 @@ type Option interface {
 }
 
 // applicableOption represents the following types:
+//
 //	Fundamental: ignore | validator | *comparer | *transformer
 //	Grouping:    Options
 type applicableOption interface {
@@ -43,6 +44,7 @@ type applicableOption interface {
 }
 
 // coreOption represents the following types:
+//
 //	Fundamental: ignore | validator | *comparer | *transformer
 //	Filters:     *pathFilter | *valuesFilter
 type coreOption interface {
@@ -336,9 +338,9 @@ func (tr transformer) String() string {
 // both implement T.
 //
 // The equality function must be:
-//	• Symmetric: equal(x, y) == equal(y, x)
-//	• Deterministic: equal(x, y) == equal(x, y)
-//	• Pure: equal(x, y) does not modify x or y
+//   - Symmetric: equal(x, y) == equal(y, x)
+//   - Deterministic: equal(x, y) == equal(x, y)
+//   - Pure: equal(x, y) does not modify x or y
 func Comparer(f interface{}) Option {
 	v := reflect.ValueOf(f)
 	if !function.IsType(v.Type(), function.Equal) || v.IsNil() {
@@ -430,7 +432,7 @@ func AllowUnexported(types ...interface{}) Option {
 }
 
 // Result represents the comparison result for a single node and
-// is provided by cmp when calling Result (see Reporter).
+// is provided by cmp when calling Report (see Reporter).
 type Result struct {
 	_     [0]func() // Make Result incomparable
 	flags resultFlags
diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go
index f01eff318c561e7e1ca880d33f0c60ca87d228c4..a0a588502ed67f5b4e5d489013fcb835da58ee4f 100644
--- a/vendor/github.com/google/go-cmp/cmp/path.go
+++ b/vendor/github.com/google/go-cmp/cmp/path.go
@@ -41,13 +41,13 @@ type PathStep interface {
 	// The type of each valid value is guaranteed to be identical to Type.
 	//
 	// In some cases, one or both may be invalid or have restrictions:
-	//	• For StructField, both are not interface-able if the current field
-	//	is unexported and the struct type is not explicitly permitted by
-	//	an Exporter to traverse unexported fields.
-	//	• For SliceIndex, one may be invalid if an element is missing from
-	//	either the x or y slice.
-	//	• For MapIndex, one may be invalid if an entry is missing from
-	//	either the x or y map.
+	//   - For StructField, both are not interface-able if the current field
+	//     is unexported and the struct type is not explicitly permitted by
+	//     an Exporter to traverse unexported fields.
+	//   - For SliceIndex, one may be invalid if an element is missing from
+	//     either the x or y slice.
+	//   - For MapIndex, one may be invalid if an entry is missing from
+	//     either the x or y map.
 	//
 	// The provided values must not be mutated.
 	Values() (vx, vy reflect.Value)
@@ -94,6 +94,7 @@ func (pa Path) Index(i int) PathStep {
 // The simplified path only contains struct field accesses.
 //
 // For example:
+//
 //	MyMap.MySlices.MyField
 func (pa Path) String() string {
 	var ss []string
@@ -108,6 +109,7 @@ func (pa Path) String() string {
 // GoString returns the path to a specific node using Go syntax.
 //
 // For example:
+//
 //	(*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField
 func (pa Path) GoString() string {
 	var ssPre, ssPost []string
@@ -159,7 +161,7 @@ func (ps pathStep) String() string {
 	if ps.typ == nil {
 		return "<nil>"
 	}
-	s := ps.typ.String()
+	s := value.TypeString(ps.typ, false)
 	if s == "" || strings.ContainsAny(s, "{}\n") {
 		return "root" // Type too simple or complex to print
 	}
@@ -178,7 +180,7 @@ type structField struct {
 	unexported bool
 	mayForce   bool                // Forcibly allow visibility
 	paddr      bool                // Was parent addressable?
-	pvx, pvy   reflect.Value       // Parent values (always addressible)
+	pvx, pvy   reflect.Value       // Parent values (always addressable)
 	field      reflect.StructField // Field information
 }
 
@@ -282,7 +284,7 @@ type typeAssertion struct {
 
 func (ta TypeAssertion) Type() reflect.Type             { return ta.typ }
 func (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy }
-func (ta TypeAssertion) String() string                 { return fmt.Sprintf(".(%v)", ta.typ) }
+func (ta TypeAssertion) String() string                 { return fmt.Sprintf(".(%v)", value.TypeString(ta.typ, false)) }
 
 // Transform is a transformation from the parent type to the current type.
 type Transform struct{ *transform }
diff --git a/vendor/github.com/google/go-cmp/cmp/report_compare.go b/vendor/github.com/google/go-cmp/cmp/report_compare.go
index 104bb30538bcdfed15dcb979a457580c0a532f7c..2050bf6b46b79740f83f580856498f0b48aa5e89 100644
--- a/vendor/github.com/google/go-cmp/cmp/report_compare.go
+++ b/vendor/github.com/google/go-cmp/cmp/report_compare.go
@@ -7,8 +7,6 @@ package cmp
 import (
 	"fmt"
 	"reflect"
-
-	"github.com/google/go-cmp/cmp/internal/value"
 )
 
 // numContextRecords is the number of surrounding equal records to print.
@@ -116,7 +114,10 @@ func (opts formatOptions) FormatDiff(v *valueNode, ptrs *pointerReferences) (out
 	}
 
 	// For leaf nodes, format the value based on the reflect.Values alone.
-	if v.MaxDepth == 0 {
+	// As a special case, treat equal []byte as a leaf nodes.
+	isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == byteType
+	isEqualBytes := isBytes && v.NumDiff+v.NumIgnored+v.NumTransformed == 0
+	if v.MaxDepth == 0 || isEqualBytes {
 		switch opts.DiffMode {
 		case diffUnknown, diffIdentical:
 			// Format Equal.
@@ -245,11 +246,11 @@ func (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind, pt
 				var isZero bool
 				switch opts.DiffMode {
 				case diffIdentical:
-					isZero = value.IsZero(r.Value.ValueX) || value.IsZero(r.Value.ValueY)
+					isZero = r.Value.ValueX.IsZero() || r.Value.ValueY.IsZero()
 				case diffRemoved:
-					isZero = value.IsZero(r.Value.ValueX)
+					isZero = r.Value.ValueX.IsZero()
 				case diffInserted:
-					isZero = value.IsZero(r.Value.ValueY)
+					isZero = r.Value.ValueY.IsZero()
 				}
 				if isZero {
 					continue
diff --git a/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/vendor/github.com/google/go-cmp/cmp/report_reflect.go
index 33f03577f98fbe517a6a6c12bb23796d383d39e0..2ab41fad3fb550c4f9a462e4c42886db4e097869 100644
--- a/vendor/github.com/google/go-cmp/cmp/report_reflect.go
+++ b/vendor/github.com/google/go-cmp/cmp/report_reflect.go
@@ -16,6 +16,13 @@ import (
 	"github.com/google/go-cmp/cmp/internal/value"
 )
 
+var (
+	anyType    = reflect.TypeOf((*interface{})(nil)).Elem()
+	stringType = reflect.TypeOf((*string)(nil)).Elem()
+	bytesType  = reflect.TypeOf((*[]byte)(nil)).Elem()
+	byteType   = reflect.TypeOf((*byte)(nil)).Elem()
+)
+
 type formatValueOptions struct {
 	// AvoidStringer controls whether to avoid calling custom stringer
 	// methods like error.Error or fmt.Stringer.String.
@@ -184,7 +191,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind,
 		}
 		for i := 0; i < v.NumField(); i++ {
 			vv := v.Field(i)
-			if value.IsZero(vv) {
+			if vv.IsZero() {
 				continue // Elide fields with zero values
 			}
 			if len(list) == maxLen {
@@ -205,12 +212,13 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind,
 		}
 
 		// Check whether this is a []byte of text data.
-		if t.Elem() == reflect.TypeOf(byte(0)) {
+		if t.Elem() == byteType {
 			b := v.Bytes()
-			isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) && unicode.IsSpace(r) }
+			isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) }
 			if len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 {
 				out = opts.formatString("", string(b))
-				return opts.WithTypeMode(emitType).FormatType(t, out)
+				skipType = true
+				return opts.FormatType(t, out)
 			}
 		}
 
@@ -281,7 +289,12 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind,
 		}
 		defer ptrs.Pop()
 
-		skipType = true // Let the underlying value print the type instead
+		// Skip the name only if this is an unnamed pointer type.
+		// Otherwise taking the address of a value does not reproduce
+		// the named pointer type.
+		if v.Type().Name() == "" {
+			skipType = true // Let the underlying value print the type instead
+		}
 		out = opts.FormatValue(v.Elem(), t.Kind(), ptrs)
 		out = wrapTrunkReference(ptrRef, opts.PrintAddresses, out)
 		out = &textWrap{Prefix: "&", Value: out}
@@ -292,7 +305,6 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind,
 		}
 		// Interfaces accept different concrete types,
 		// so configure the underlying value to explicitly print the type.
-		skipType = true // Print the concrete type instead
 		return opts.WithTypeMode(emitType).FormatValue(v.Elem(), t.Kind(), ptrs)
 	default:
 		panic(fmt.Sprintf("%v kind not handled", v.Kind()))
diff --git a/vendor/github.com/google/go-cmp/cmp/report_slices.go b/vendor/github.com/google/go-cmp/cmp/report_slices.go
index 2ad3bc85ba82361de8dc08785c61927b765d2d07..23e444f62f364099a1faf35c9f4fab61fd7ce277 100644
--- a/vendor/github.com/google/go-cmp/cmp/report_slices.go
+++ b/vendor/github.com/google/go-cmp/cmp/report_slices.go
@@ -80,7 +80,7 @@ func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {
 	}
 
 	// Use specialized string diffing for longer slices or strings.
-	const minLength = 64
+	const minLength = 32
 	return vx.Len() >= minLength && vy.Len() >= minLength
 }
 
@@ -104,7 +104,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
 	case t.Kind() == reflect.String:
 		sx, sy = vx.String(), vy.String()
 		isString = true
-	case t.Kind() == reflect.Slice && t.Elem() == reflect.TypeOf(byte(0)):
+	case t.Kind() == reflect.Slice && t.Elem() == byteType:
 		sx, sy = string(vx.Bytes()), string(vy.Bytes())
 		isString = true
 	case t.Kind() == reflect.Array:
@@ -147,7 +147,10 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
 			})
 			efficiencyLines := float64(esLines.Dist()) / float64(len(esLines))
 			efficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes))
-			isPureLinedText = efficiencyLines < 4*efficiencyBytes
+			quotedLength := len(strconv.Quote(sx + sy))
+			unquotedLength := len(sx) + len(sy)
+			escapeExpansionRatio := float64(quotedLength) / float64(unquotedLength)
+			isPureLinedText = efficiencyLines < 4*efficiencyBytes || escapeExpansionRatio > 1.1
 		}
 	}
 
@@ -171,12 +174,13 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
 		// differences in a string literal. This format is more readable,
 		// but has edge-cases where differences are visually indistinguishable.
 		// This format is avoided under the following conditions:
-		//	• A line starts with `"""`
-		//	• A line starts with "..."
-		//	• A line contains non-printable characters
-		//	• Adjacent different lines differ only by whitespace
+		//   - A line starts with `"""`
+		//   - A line starts with "..."
+		//   - A line contains non-printable characters
+		//   - Adjacent different lines differ only by whitespace
 		//
 		// For example:
+		//
 		//		"""
 		//		... // 3 identical lines
 		//		foo
@@ -231,7 +235,7 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
 			var out textNode = &textWrap{Prefix: "(", Value: list2, Suffix: ")"}
 			switch t.Kind() {
 			case reflect.String:
-				if t != reflect.TypeOf(string("")) {
+				if t != stringType {
 					out = opts.FormatType(t, out)
 				}
 			case reflect.Slice:
@@ -326,12 +330,12 @@ func (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {
 	switch t.Kind() {
 	case reflect.String:
 		out = &textWrap{Prefix: "strings.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)}
-		if t != reflect.TypeOf(string("")) {
+		if t != stringType {
 			out = opts.FormatType(t, out)
 		}
 	case reflect.Slice:
 		out = &textWrap{Prefix: "bytes.Join(", Value: out, Suffix: fmt.Sprintf(", %q)", delim)}
-		if t != reflect.TypeOf([]byte(nil)) {
+		if t != bytesType {
 			out = opts.FormatType(t, out)
 		}
 	}
@@ -446,7 +450,6 @@ func (opts formatOptions) formatDiffSlice(
 //		{NumIdentical: 3},
 //		{NumInserted: 1},
 //	]
-//
 func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) {
 	var prevMode byte
 	lastStats := func(mode byte) *diffStats {
@@ -503,7 +506,6 @@ func coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats)
 //		{NumIdentical: 8, NumRemoved: 12, NumInserted: 3},
 //		{NumIdentical: 63},
 //	]
-//
 func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats {
 	groups, groupsOrig := groups[:0], groups
 	for i, ds := range groupsOrig {
@@ -548,7 +550,6 @@ func coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStat
 //		{NumRemoved: 9},
 //		{NumIdentical: 64}, // incremented by 10
 //	]
-//
 func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats {
 	var ix, iy int // indexes into sequence x and y
 	for i, ds := range groups {
@@ -563,10 +564,10 @@ func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []d
 		nx := ds.NumIdentical + ds.NumRemoved + ds.NumModified
 		ny := ds.NumIdentical + ds.NumInserted + ds.NumModified
 		var numLeadingIdentical, numTrailingIdentical int
-		for i := 0; i < nx && i < ny && eq(ix+i, iy+i); i++ {
+		for j := 0; j < nx && j < ny && eq(ix+j, iy+j); j++ {
 			numLeadingIdentical++
 		}
-		for i := 0; i < nx && i < ny && eq(ix+nx-1-i, iy+ny-1-i); i++ {
+		for j := 0; j < nx && j < ny && eq(ix+nx-1-j, iy+ny-1-j); j++ {
 			numTrailingIdentical++
 		}
 		if numIdentical := numLeadingIdentical + numTrailingIdentical; numIdentical > 0 {
diff --git a/vendor/github.com/google/go-cmp/cmp/report_text.go b/vendor/github.com/google/go-cmp/cmp/report_text.go
index 0fd46d7ffb6e71312f17f464eb57935fa438671f..388fcf571208541ed9b87ee926f502338d8bf030 100644
--- a/vendor/github.com/google/go-cmp/cmp/report_text.go
+++ b/vendor/github.com/google/go-cmp/cmp/report_text.go
@@ -393,6 +393,7 @@ func (s diffStats) Append(ds diffStats) diffStats {
 // String prints a humanly-readable summary of coalesced records.
 //
 // Example:
+//
 //	diffStats{Name: "Field", NumIgnored: 5}.String() => "5 ignored fields"
 func (s diffStats) String() string {
 	var ss []string
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 1d2f65d959c5e6ab9366434b068613fa89ec512d..a18e62a21f4ce2c4d9134f259498701f7ec76480 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -10,7 +10,7 @@ github.com/PuerkitoBio/purell
 github.com/andybalholm/cascadia
 # github.com/golang/snappy v0.0.1
 github.com/golang/snappy
-# github.com/google/go-cmp v0.5.6
+# github.com/google/go-cmp v0.5.9
 ## explicit
 github.com/google/go-cmp/cmp
 github.com/google/go-cmp/cmp/internal/diff