Repository: exadel-inc/esl
Pull request #1093 (2022-07-06 15:34:33)

refactor(esl-utils): rework public api for SyntheticEventTarget
In the scope of this PR I reworked public API for SyntheticEventTarget so future changes to the class won't be affecting other components

ala-n: Basically, I need to ask, @exadel-inc/esl-core-team, 
As you see in the current PR we going to share an ability to get a whole list of observers from EventTarget instance,
but the native implementation deprecates any possibility to access listeners outside debug.
And honestly, I partially see it's reasonable to have subscriptions be encapsulated and hidden from the outside world. 
Just an option we can think about the method to access just the whole state of Target instance, something like
```ts
   this.hasListeners('change'); // or similar short name
```

fshovchko: > Basically, I need to ask, @exadel-inc/esl-core-team, As you see in the current PR we going to share an ability to get a whole list of observers from EventTarget instance, but the native implementation deprecates any possibility to access listeners outside debug. And honestly, I partially see it's reasonable to have subscriptions be encapsulated and hidden from the outside world.
> 
> Just an option we can think about the method to access just the whole state of Target instance, something like
> 
> ```ts
>    this.hasListeners('change'); // or similar short name
> ```
> 
> From the usage point of view as you can see from the occurrence in the current PR it's more than enough to cover needs of `SyntheticEventTarget`
> 
> So, in case you prefer to enclose observers and go with the conservative `has` method instead of `get` mark this comment with the like +1emojy

this.hasListeners won't brake any of the code that is using SyntheticEventTarget api so I agree to change the method
ala-n: > > Basically, I need to ask, @exadel-inc/esl-core-team, As you see in the current PR we going to share an ability to get a whole list of observers from EventTarget instance, but the native implementation deprecates any possibility to access listeners outside debug. And honestly, I partially see it's reasonable to have subscriptions be encapsulated and hidden from the outside world.
> > Just an option we can think about the method to access just the whole state of Target instance, something like
> > ```ts
> >    this.hasListeners('change'); // or similar short name
> > ```

> >   
> > From the usage point of view as you can see from the occurrence in the current PR it's more than enough to cover needs of `SyntheticEventTarget`
> > So, in case you prefer to enclose observers and go with the conservative `has` method instead of `get` mark this comment with the like +1emojy
> 
> this.hasListeners won't brake any of the code that is using SyntheticEventTarget api so I agree to change the method

According to the discussion results
We don't gonna share inner observers, but just let users know if they are presented.
So yea, @fshovchko, let's do this update

Patch:
diff --git a/.husky/pre-commit b/.husky/pre-commit
index 4b93ecddb..20d0d06e5 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,4 +1,4 @@
 #!/bin/sh
 . "$(dirname "$0")/_/husky.sh"
 
-npx lint-staged --verbose --quiet
+npm run lint
diff --git a/.lintstagedrc.yml b/.lintstagedrc.yml
deleted file mode 100644
index f3fa13fe4..000000000
--- a/.lintstagedrc.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-"*.ts":
-  - "eslint --max-warnings 3"
-  - "jest --silent --noStackTrace --bail --findRelatedTests"
-"*.less":
-  - "stylelint"
-"*":
-  - "lintspaces -n -t -d spaces"
diff --git a/package-lock.json b/package-lock.json
index 016585f5b..7a786f5e1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,7 @@
         "@semantic-release/changelog": "^6.0.1",
         "@semantic-release/commit-analyzer": "^9.0.2",
         "@semantic-release/git": "^10.0.1",
-        "@semantic-release/github": "^8.0.5",
+        "@semantic-release/github": "^8.0.4",
         "@semantic-release/npm": "^9.0.1",
         "@semantic-release/release-notes-generator": "^10.0.3",
         "@types/jest": "^28.1.4",
@@ -48,7 +48,6 @@
         "js-yaml": "^4.1.0",
         "kleur": "^4.1.5",
         "less": "^4.1.3",
-        "lint-staged": "^13.0.3",
         "lintspaces-cli": "^0.7.1",
         "postcss": "^8.4.14",
         "postcss-less": "^6.0.0",
@@ -1734,47 +1733,38 @@
       }
     },
     "node_modules/@octokit/auth-token": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.0.tgz",
-      "integrity": "sha512-MDNFUBcJIptB9At7HiV7VCvU3NcL4GnfCQaP8C5lrxWrRPMJBnemYtehaKSOlaM7AYxeRyj9etenu8LVpSpVaQ==",
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
+      "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
       "dev": true,
       "dependencies": {
         "@octokit/types": "^6.0.3"
-      },
-      "engines": {
-        "node": ">= 14"
       }
     },
     "node_modules/@octokit/core": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.0.2.tgz",
-      "integrity": "sha512-vgVtE02EF9kXFsjmFoKFCwH1wDspPfDgopRbAlavkGuBJPWF+u5n0xgwP4obmdKNvLM+bB7MI7W31c2E13zgDQ==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
+      "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
       "dev": true,
       "dependencies": {
-        "@octokit/auth-token": "^3.0.0",
+        "@octokit/auth-token": "^2.4.4",
         "@octokit/graphql": "^4.5.8",
-        "@octokit/request": "^6.0.0",
+        "@octokit/request": "^5.6.3",
         "@octokit/request-error": "^2.0.5",
         "@octokit/types": "^6.0.3",
         "before-after-hook": "^2.2.0",
         "universal-user-agent": "^6.0.0"
-      },
-      "engines": {
-        "node": ">= 14"
       }
     },
     "node_modules/@octokit/endpoint": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.0.tgz",
-      "integrity": "sha512-Kz/mIkOTjs9rV50hf/JK9pIDl4aGwAtT8pry6Rpy+hVXkAPhXanNQRxMoq6AeRgDCZR6t/A1zKniY2V1YhrzlQ==",
+      "version": "6.0.12",
+      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
+      "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
       "dev": true,
       "dependencies": {
         "@octokit/types": "^6.0.3",
         "is-plain-object": "^5.0.0",
         "universal-user-agent": "^6.0.0"
-      },
-      "engines": {
-        "node": ">= 14"
       }
     },
     "node_modules/@octokit/graphql": {
@@ -1788,44 +1778,19 @@
         "universal-user-agent": "^6.0.0"
       }
     },
-    "node_modules/@octokit/graphql/node_modules/@octokit/endpoint": {
-      "version": "6.0.12",
-      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
-      "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
-      "dev": true,
-      "dependencies": {
-        "@octokit/types": "^6.0.3",
-        "is-plain-object": "^5.0.0",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
-    "node_modules/@octokit/graphql/node_modules/@octokit/request": {
-      "version": "5.6.3",
-      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
-      "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
-      "dev": true,
-      "dependencies": {
-        "@octokit/endpoint": "^6.0.1",
-        "@octokit/request-error": "^2.1.0",
-        "@octokit/types": "^6.16.1",
-        "is-plain-object": "^5.0.0",
-        "node-fetch": "^2.6.7",
-        "universal-user-agent": "^6.0.0"
-      }
-    },
     "node_modules/@octokit/openapi-types": {
-      "version": "12.8.0",
-      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.8.0.tgz",
-      "integrity": "sha512-ydcKLs2KKcxlhpdWLzJxEBDEk/U5MUeqtqkXlrtAUXXFPs6vLl1PEGghFC/BbpleosB7iXs0Z4P2DGe7ZT5ZNg==",
+      "version": "11.2.0",
+      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz",
+      "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==",
       "dev": true
     },
     "node_modules/@octokit/plugin-paginate-rest": {
-      "version": "2.21.1",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.1.tgz",
-      "integrity": "sha512-NVNTK63yoTFp07GqISWK+uDfGH1CAPhQXS7LzsJBvaK5W+UlvG549pLZC55FK0FqANVl6q/9ra3SR5c97xF/sw==",
+      "version": "2.17.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz",
+      "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==",
       "dev": true,
       "dependencies": {
-        "@octokit/types": "^6.38.2"
+        "@octokit/types": "^6.34.0"
       },
       "peerDependencies": {
         "@octokit/core": ">=2"
@@ -1841,12 +1806,12 @@
       }
     },
     "node_modules/@octokit/plugin-rest-endpoint-methods": {
-      "version": "5.16.2",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
-      "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
+      "version": "5.13.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz",
+      "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==",
       "dev": true,
       "dependencies": {
-        "@octokit/types": "^6.39.0",
+        "@octokit/types": "^6.34.0",
         "deprecation": "^2.3.1"
       },
       "peerDependencies": {
@@ -1854,20 +1819,17 @@
       }
     },
     "node_modules/@octokit/request": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.0.1.tgz",
-      "integrity": "sha512-9DSQ7fKBeSMU5aD6JfWA/1XFwP44X32d9fSYdQzxSsROjOginPYtW4Xwwt3Qs7wZtBmFOWV/td3gxOHmz9hfig==",
+      "version": "5.6.3",
+      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
+      "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
       "dev": true,
       "dependencies": {
-        "@octokit/endpoint": "^7.0.0",
+        "@octokit/endpoint": "^6.0.1",
         "@octokit/request-error": "^2.1.0",
         "@octokit/types": "^6.16.1",
         "is-plain-object": "^5.0.0",
         "node-fetch": "^2.6.7",
         "universal-user-agent": "^6.0.0"
-      },
-      "engines": {
-        "node": ">= 14"
       }
     },
     "node_modules/@octokit/request-error": {
@@ -1882,27 +1844,24 @@
       }
     },
     "node_modules/@octokit/rest": {
-      "version": "19.0.1",
-      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.1.tgz",
-      "integrity": "sha512-gZUhimQN9aKF0eBLlWFmZlKO8ksFgm6+9dy1Nu/2soS9dljlH/CmjPIGH1/hZiFoKckGAoLmMIHVjDWIhC2myw==",
+      "version": "18.12.0",
+      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
+      "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
       "dev": true,
       "dependencies": {
-        "@octokit/core": "^4.0.0",
+        "@octokit/core": "^3.5.1",
         "@octokit/plugin-paginate-rest": "^2.16.8",
         "@octokit/plugin-request-log": "^1.0.4",
         "@octokit/plugin-rest-endpoint-methods": "^5.12.0"
-      },
-      "engines": {
-        "node": ">= 14"
       }
     },
     "node_modules/@octokit/types": {
-      "version": "6.39.0",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.39.0.tgz",
-      "integrity": "sha512-Mq4N9sOAYCitTsBtDdRVrBE80lIrMBhL9Jbrw0d+j96BAzlq4V+GLHFJbHokEsVvO/9tQupQdoFdgVYhD2C8UQ==",
+      "version": "6.34.0",
+      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz",
+      "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==",
       "dev": true,
       "dependencies": {
-        "@octokit/openapi-types": "^12.7.0"
+        "@octokit/openapi-types": "^11.2.0"
       }
     },
     "node_modules/@polka/url": {
@@ -1997,12 +1956,12 @@
       }
     },
     "node_modules/@semantic-release/github": {
-      "version": "8.0.5",
-      "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.0.5.tgz",
-      "integrity": "sha512-9pGxRM3gv1hgoZ/muyd4pWnykdIUVfCiev6MXE9lOyGQof4FQy95GFE26nDcifs9ZG7bBzV8ue87bo/y1zVf0g==",
+      "version": "8.0.4",
+      "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.0.4.tgz",
+      "integrity": "sha512-But4e8oqqP3anZI5tjzZssZc2J6eoUdeeE0s7LVKKwyiAXJiQDWNNvtPOpgG2DsIz4+Exuse7cEQgjGMxwtLmg==",
       "dev": true,
       "dependencies": {
-        "@octokit/rest": "^19.0.0",
+        "@octokit/rest": "^18.0.0",
         "@semantic-release/error": "^2.2.0",
         "aggregate-error": "^3.0.0",
         "bottleneck": "^2.18.1",
@@ -5076,12 +5035,6 @@
         "readable-stream": "^2.0.2"
       }
     },
-    "node_modules/eastasianwidth": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
-      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
-      "dev": true
-    },
     "node_modules/easy-extender": {
       "version": "2.3.4",
       "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz",
@@ -8893,15 +8846,6 @@
         "node": ">= 0.8.0"
       }
     },
-    "node_modules/lilconfig": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz",
-      "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/limiter": {
       "version": "1.1.5",
       "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz",
@@ -8923,270 +8867,6 @@
         "uc.micro": "^1.0.1"
       }
     },
-    "node_modules/lint-staged": {
-      "version": "13.0.3",
-      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.0.3.tgz",
-      "integrity": "sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug==",
-      "dev": true,
-      "dependencies": {
-        "cli-truncate": "^3.1.0",
-        "colorette": "^2.0.17",
-        "commander": "^9.3.0",
-        "debug": "^4.3.4",
-        "execa": "^6.1.0",
-        "lilconfig": "2.0.5",
-        "listr2": "^4.0.5",
-        "micromatch": "^4.0.5",
-        "normalize-path": "^3.0.0",
-        "object-inspect": "^1.12.2",
-        "pidtree": "^0.6.0",
-        "string-argv": "^0.3.1",
-        "yaml": "^2.1.1"
-      },
-      "bin": {
-        "lint-staged": "bin/lint-staged.js"
-      },
-      "engines": {
-        "node": "^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/lint-staged"
-      }
-    },
-    "node_modules/lint-staged/node_modules/ansi-regex": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
-      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
-      }
-    },
-    "node_modules/lint-staged/node_modules/ansi-styles": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz",
-      "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/lint-staged/node_modules/cli-truncate": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz",
-      "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==",
-      "dev": true,
-      "dependencies": {
-        "slice-ansi": "^5.0.0",
-        "string-width": "^5.0.0"
-      },
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lint-staged/node_modules/commander": {
-      "version": "9.3.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz",
-      "integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==",
-      "dev": true,
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/lint-staged/node_modules/emoji-regex": {
-      "version": "9.2.2",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
-      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
-      "dev": true
-    },
-    "node_modules/lint-staged/node_modules/execa": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz",
-      "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.1",
-        "human-signals": "^3.0.1",
-        "is-stream": "^3.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^5.1.0",
-        "onetime": "^6.0.0",
-        "signal-exit": "^3.0.7",
-        "strip-final-newline": "^3.0.0"
-      },
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
-      }
-    },
-    "node_modules/lint-staged/node_modules/human-signals": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz",
-      "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=12.20.0"
-      }
-    },
-    "node_modules/lint-staged/node_modules/is-fullwidth-code-point": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
-      "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lint-staged/node_modules/is-stream": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
-      "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
-      "dev": true,
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lint-staged/node_modules/mimic-fn": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
-      "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lint-staged/node_modules/npm-run-path": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
-      "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^4.0.0"
-      },
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lint-staged/node_modules/onetime": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
-      "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
-      "dev": true,
-      "dependencies": {
-        "mimic-fn": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lint-staged/node_modules/path-key": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
-      "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lint-staged/node_modules/slice-ansi": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
-      "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^6.0.0",
-        "is-fullwidth-code-point": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
-      }
-    },
-    "node_modules/lint-staged/node_modules/string-width": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
-      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
-      "dev": true,
-      "dependencies": {
-        "eastasianwidth": "^0.2.0",
-        "emoji-regex": "^9.2.2",
-        "strip-ansi": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lint-staged/node_modules/strip-ansi": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
-      "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
-      }
-    },
-    "node_modules/lint-staged/node_modules/strip-final-newline": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
-      "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/lint-staged/node_modules/yaml": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz",
-      "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==",
-      "dev": true,
-      "engines": {
-        "node": ">= 14"
-      }
-    },
     "node_modules/lintspaces": {
       "version": "0.6.4",
       "resolved": "https://registry.npmjs.org/lintspaces/-/lintspaces-0.6.4.tgz",
@@ -9217,214 +8897,30 @@
         "lintspaces": "bin/lintspaces-cli.js"
       },
       "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/lintspaces-cli/node_modules/commander": {
-      "version": "2.19.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
-      "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
-      "dev": true
-    },
-    "node_modules/liquidjs": {
-      "version": "9.37.0",
-      "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-9.37.0.tgz",
-      "integrity": "sha512-qDj9iiNdB+QNZTR4iKjiQzoHQma7V8Itx5oZG/ZCP7xjebh1LI+s5IG2ZYUbs1ALO6hBzmW36Ptd8RR4eohuDA==",
-      "dev": true,
-      "bin": {
-        "liquid": "bin/liquid.js",
-        "liquidjs": "bin/liquid.js"
-      },
-      "engines": {
-        "node": ">=4.8.7"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/liquidjs"
-      }
-    },
-    "node_modules/listr2": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz",
-      "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==",
-      "dev": true,
-      "dependencies": {
-        "cli-truncate": "^2.1.0",
-        "colorette": "^2.0.16",
-        "log-update": "^4.0.0",
-        "p-map": "^4.0.0",
-        "rfdc": "^1.3.0",
-        "rxjs": "^7.5.5",
-        "through": "^2.3.8",
-        "wrap-ansi": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "peerDependencies": {
-        "enquirer": ">= 2.3.0 < 3"
-      },
-      "peerDependenciesMeta": {
-        "enquirer": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/listr2/node_modules/cli-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
-      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
-      "dev": true,
-      "dependencies": {
-        "restore-cursor": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/listr2/node_modules/cli-truncate": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
-      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
-      "dev": true,
-      "dependencies": {
-        "slice-ansi": "^3.0.0",
-        "string-width": "^4.2.0"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/listr2/node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true
-    },
-    "node_modules/listr2/node_modules/is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/listr2/node_modules/log-update": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
-      "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
-      "dev": true,
-      "dependencies": {
-        "ansi-escapes": "^4.3.0",
-        "cli-cursor": "^3.1.0",
-        "slice-ansi": "^4.0.0",
-        "wrap-ansi": "^6.2.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/listr2/node_modules/log-update/node_modules/slice-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
-      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "astral-regex": "^2.0.0",
-        "is-fullwidth-code-point": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
-      }
-    },
-    "node_modules/listr2/node_modules/log-update/node_modules/wrap-ansi": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
-      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/listr2/node_modules/p-map": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
-      "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
-      "dev": true,
-      "dependencies": {
-        "aggregate-error": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/listr2/node_modules/restore-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
-      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
-      "dev": true,
-      "dependencies": {
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/listr2/node_modules/rxjs": {
-      "version": "7.5.5",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
-      "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
-      "dev": true,
-      "dependencies": {
-        "tslib": "^2.1.0"
-      }
-    },
-    "node_modules/listr2/node_modules/slice-ansi": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
-      "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "astral-regex": "^2.0.0",
-        "is-fullwidth-code-point": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
+        "node": ">=6"
       }
     },
-    "node_modules/listr2/node_modules/string-width": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+    "node_modules/lintspaces-cli/node_modules/commander": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
+      "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
+      "dev": true
+    },
+    "node_modules/liquidjs": {
+      "version": "9.37.0",
+      "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-9.37.0.tgz",
+      "integrity": "sha512-qDj9iiNdB+QNZTR4iKjiQzoHQma7V8Itx5oZG/ZCP7xjebh1LI+s5IG2ZYUbs1ALO6hBzmW36Ptd8RR4eohuDA==",
       "dev": true,
-      "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
+      "bin": {
+        "liquid": "bin/liquid.js",
+        "liquidjs": "bin/liquid.js"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=4.8.7"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/liquidjs"
       }
     },
     "node_modules/load-json-file": {
@@ -10334,19 +9830,19 @@
     "node_modules/node-fetch/node_modules/tr46": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+      "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
       "dev": true
     },
     "node_modules/node-fetch/node_modules/webidl-conversions": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+      "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
       "dev": true
     },
     "node_modules/node-fetch/node_modules/whatwg-url": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+      "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
       "dev": true,
       "dependencies": {
         "tr46": "~0.0.3",
@@ -13425,18 +12921,6 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
-    "node_modules/pidtree": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
-      "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
-      "dev": true,
-      "bin": {
-        "pidtree": "bin/pidtree.js"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
     "node_modules/pify": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@@ -14556,12 +14040,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/rfdc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
-      "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
-      "dev": true
-    },
     "node_modules/rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -15551,15 +15029,6 @@
         "safe-buffer": "~5.1.0"
       }
     },
-    "node_modules/string-argv": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
-      "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.6.19"
-      }
-    },
     "node_modules/string-length": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -18676,23 +18145,23 @@
       }
     },
     "@octokit/auth-token": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.0.tgz",
-      "integrity": "sha512-MDNFUBcJIptB9At7HiV7VCvU3NcL4GnfCQaP8C5lrxWrRPMJBnemYtehaKSOlaM7AYxeRyj9etenu8LVpSpVaQ==",
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
+      "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
       "dev": true,
       "requires": {
         "@octokit/types": "^6.0.3"
       }
     },
     "@octokit/core": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.0.2.tgz",
-      "integrity": "sha512-vgVtE02EF9kXFsjmFoKFCwH1wDspPfDgopRbAlavkGuBJPWF+u5n0xgwP4obmdKNvLM+bB7MI7W31c2E13zgDQ==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
+      "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
       "dev": true,
       "requires": {
-        "@octokit/auth-token": "^3.0.0",
+        "@octokit/auth-token": "^2.4.4",
         "@octokit/graphql": "^4.5.8",
-        "@octokit/request": "^6.0.0",
+        "@octokit/request": "^5.6.3",
         "@octokit/request-error": "^2.0.5",
         "@octokit/types": "^6.0.3",
         "before-after-hook": "^2.2.0",
@@ -18700,9 +18169,9 @@
       }
     },
     "@octokit/endpoint": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.0.tgz",
-      "integrity": "sha512-Kz/mIkOTjs9rV50hf/JK9pIDl4aGwAtT8pry6Rpy+hVXkAPhXanNQRxMoq6AeRgDCZR6t/A1zKniY2V1YhrzlQ==",
+      "version": "6.0.12",
+      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
+      "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
       "dev": true,
       "requires": {
         "@octokit/types": "^6.0.3",
@@ -18719,48 +18188,21 @@
         "@octokit/request": "^5.6.0",
         "@octokit/types": "^6.0.3",
         "universal-user-agent": "^6.0.0"
-      },
-      "dependencies": {
-        "@octokit/endpoint": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
-          "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
-          "dev": true,
-          "requires": {
-            "@octokit/types": "^6.0.3",
-            "is-plain-object": "^5.0.0",
-            "universal-user-agent": "^6.0.0"
-          }
-        },
-        "@octokit/request": {
-          "version": "5.6.3",
-          "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
-          "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
-          "dev": true,
-          "requires": {
-            "@octokit/endpoint": "^6.0.1",
-            "@octokit/request-error": "^2.1.0",
-            "@octokit/types": "^6.16.1",
-            "is-plain-object": "^5.0.0",
-            "node-fetch": "^2.6.7",
-            "universal-user-agent": "^6.0.0"
-          }
-        }
       }
     },
     "@octokit/openapi-types": {
-      "version": "12.8.0",
-      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.8.0.tgz",
-      "integrity": "sha512-ydcKLs2KKcxlhpdWLzJxEBDEk/U5MUeqtqkXlrtAUXXFPs6vLl1PEGghFC/BbpleosB7iXs0Z4P2DGe7ZT5ZNg==",
+      "version": "11.2.0",
+      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz",
+      "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==",
       "dev": true
     },
     "@octokit/plugin-paginate-rest": {
-      "version": "2.21.1",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.1.tgz",
-      "integrity": "sha512-NVNTK63yoTFp07GqISWK+uDfGH1CAPhQXS7LzsJBvaK5W+UlvG549pLZC55FK0FqANVl6q/9ra3SR5c97xF/sw==",
+      "version": "2.17.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz",
+      "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==",
       "dev": true,
       "requires": {
-        "@octokit/types": "^6.38.2"
+        "@octokit/types": "^6.34.0"
       }
     },
     "@octokit/plugin-request-log": {
@@ -18771,22 +18213,22 @@
       "requires": {}
     },
     "@octokit/plugin-rest-endpoint-methods": {
-      "version": "5.16.2",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
-      "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
+      "version": "5.13.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz",
+      "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==",
       "dev": true,
       "requires": {
-        "@octokit/types": "^6.39.0",
+        "@octokit/types": "^6.34.0",
         "deprecation": "^2.3.1"
       }
     },
     "@octokit/request": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.0.1.tgz",
-      "integrity": "sha512-9DSQ7fKBeSMU5aD6JfWA/1XFwP44X32d9fSYdQzxSsROjOginPYtW4Xwwt3Qs7wZtBmFOWV/td3gxOHmz9hfig==",
+      "version": "5.6.3",
+      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
+      "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
       "dev": true,
       "requires": {
-        "@octokit/endpoint": "^7.0.0",
+        "@octokit/endpoint": "^6.0.1",
         "@octokit/request-error": "^2.1.0",
         "@octokit/types": "^6.16.1",
         "is-plain-object": "^5.0.0",
@@ -18806,24 +18248,24 @@
       }
     },
     "@octokit/rest": {
-      "version": "19.0.1",
-      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.1.tgz",
-      "integrity": "sha512-gZUhimQN9aKF0eBLlWFmZlKO8ksFgm6+9dy1Nu/2soS9dljlH/CmjPIGH1/hZiFoKckGAoLmMIHVjDWIhC2myw==",
+      "version": "18.12.0",
+      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
+      "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
       "dev": true,
       "requires": {
-        "@octokit/core": "^4.0.0",
+        "@octokit/core": "^3.5.1",
         "@octokit/plugin-paginate-rest": "^2.16.8",
         "@octokit/plugin-request-log": "^1.0.4",
         "@octokit/plugin-rest-endpoint-methods": "^5.12.0"
       }
     },
     "@octokit/types": {
-      "version": "6.39.0",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.39.0.tgz",
-      "integrity": "sha512-Mq4N9sOAYCitTsBtDdRVrBE80lIrMBhL9Jbrw0d+j96BAzlq4V+GLHFJbHokEsVvO/9tQupQdoFdgVYhD2C8UQ==",
+      "version": "6.34.0",
+      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz",
+      "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==",
       "dev": true,
       "requires": {
-        "@octokit/openapi-types": "^12.7.0"
+        "@octokit/openapi-types": "^11.2.0"
       }
     },
     "@polka/url": {
@@ -18896,12 +18338,12 @@
       }
     },
     "@semantic-release/github": {
-      "version": "8.0.5",
-      "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.0.5.tgz",
-      "integrity": "sha512-9pGxRM3gv1hgoZ/muyd4pWnykdIUVfCiev6MXE9lOyGQof4FQy95GFE26nDcifs9ZG7bBzV8ue87bo/y1zVf0g==",
+      "version": "8.0.4",
+      "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-8.0.4.tgz",
+      "integrity": "sha512-But4e8oqqP3anZI5tjzZssZc2J6eoUdeeE0s7LVKKwyiAXJiQDWNNvtPOpgG2DsIz4+Exuse7cEQgjGMxwtLmg==",
       "dev": true,
       "requires": {
-        "@octokit/rest": "^19.0.0",
+        "@octokit/rest": "^18.0.0",
         "@semantic-release/error": "^2.2.0",
         "aggregate-error": "^3.0.0",
         "bottleneck": "^2.18.1",
@@ -21346,12 +20788,6 @@
         "readable-stream": "^2.0.2"
       }
     },
-    "eastasianwidth": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
-      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
-      "dev": true
-    },
     "easy-extender": {
       "version": "2.3.4",
       "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz",
@@ -24217,12 +23653,6 @@
         "type-check": "~0.4.0"
       }
     },
-    "lilconfig": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz",
-      "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==",
-      "dev": true
-    },
     "limiter": {
       "version": "1.1.5",
       "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz",
@@ -24244,170 +23674,6 @@
         "uc.micro": "^1.0.1"
       }
     },
-    "lint-staged": {
-      "version": "13.0.3",
-      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.0.3.tgz",
-      "integrity": "sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug==",
-      "dev": true,
-      "requires": {
-        "cli-truncate": "^3.1.0",
-        "colorette": "^2.0.17",
-        "commander": "^9.3.0",
-        "debug": "^4.3.4",
-        "execa": "^6.1.0",
-        "lilconfig": "2.0.5",
-        "listr2": "^4.0.5",
-        "micromatch": "^4.0.5",
-        "normalize-path": "^3.0.0",
-        "object-inspect": "^1.12.2",
-        "pidtree": "^0.6.0",
-        "string-argv": "^0.3.1",
-        "yaml": "^2.1.1"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
-          "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "6.1.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz",
-          "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==",
-          "dev": true
-        },
-        "cli-truncate": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz",
-          "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==",
-          "dev": true,
-          "requires": {
-            "slice-ansi": "^5.0.0",
-            "string-width": "^5.0.0"
-          }
-        },
-        "commander": {
-          "version": "9.3.0",
-          "resolved": "https://registry.npmjs.org/commander/-/commander-9.3.0.tgz",
-          "integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==",
-          "dev": true
-        },
-        "emoji-regex": {
-          "version": "9.2.2",
-          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
-          "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
-          "dev": true
-        },
-        "execa": {
-          "version": "6.1.0",
-          "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz",
-          "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==",
-          "dev": true,
-          "requires": {
-            "cross-spawn": "^7.0.3",
-            "get-stream": "^6.0.1",
-            "human-signals": "^3.0.1",
-            "is-stream": "^3.0.0",
-            "merge-stream": "^2.0.0",
-            "npm-run-path": "^5.1.0",
-            "onetime": "^6.0.0",
-            "signal-exit": "^3.0.7",
-            "strip-final-newline": "^3.0.0"
-          }
-        },
-        "human-signals": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz",
-          "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==",
-          "dev": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
-          "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
-          "dev": true
-        },
-        "is-stream": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
-          "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
-          "dev": true
-        },
-        "mimic-fn": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
-          "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
-          "dev": true
-        },
-        "npm-run-path": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
-          "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==",
-          "dev": true,
-          "requires": {
-            "path-key": "^4.0.0"
-          }
-        },
-        "onetime": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
-          "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
-          "dev": true,
-          "requires": {
-            "mimic-fn": "^4.0.0"
-          }
-        },
-        "path-key": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
-          "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
-          "dev": true
-        },
-        "slice-ansi": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
-          "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^6.0.0",
-            "is-fullwidth-code-point": "^4.0.0"
-          }
-        },
-        "string-width": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
-          "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
-          "dev": true,
-          "requires": {
-            "eastasianwidth": "^0.2.0",
-            "emoji-regex": "^9.2.2",
-            "strip-ansi": "^7.0.1"
-          }
-        },
-        "strip-ansi": {
-          "version": "7.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
-          "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^6.0.1"
-          }
-        },
-        "strip-final-newline": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
-          "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
-          "dev": true
-        },
-        "yaml": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz",
-          "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==",
-          "dev": true
-        }
-      }
-    },
     "lintspaces": {
       "version": "0.6.4",
       "resolved": "https://registry.npmjs.org/lintspaces/-/lintspaces-0.6.4.tgz",
@@ -24446,141 +23712,6 @@
       "integrity": "sha512-qDj9iiNdB+QNZTR4iKjiQzoHQma7V8Itx5oZG/ZCP7xjebh1LI+s5IG2ZYUbs1ALO6hBzmW36Ptd8RR4eohuDA==",
       "dev": true
     },
-    "listr2": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz",
-      "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==",
-      "dev": true,
-      "requires": {
-        "cli-truncate": "^2.1.0",
-        "colorette": "^2.0.16",
-        "log-update": "^4.0.0",
-        "p-map": "^4.0.0",
-        "rfdc": "^1.3.0",
-        "rxjs": "^7.5.5",
-        "through": "^2.3.8",
-        "wrap-ansi": "^7.0.0"
-      },
-      "dependencies": {
-        "cli-cursor": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
-          "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
-          "dev": true,
-          "requires": {
-            "restore-cursor": "^3.1.0"
-          }
-        },
-        "cli-truncate": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
-          "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
-          "dev": true,
-          "requires": {
-            "slice-ansi": "^3.0.0",
-            "string-width": "^4.2.0"
-          }
-        },
-        "emoji-regex": {
-          "version": "8.0.0",
-          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-          "dev": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-          "dev": true
-        },
-        "log-update": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
-          "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
-          "dev": true,
-          "requires": {
-            "ansi-escapes": "^4.3.0",
-            "cli-cursor": "^3.1.0",
-            "slice-ansi": "^4.0.0",
-            "wrap-ansi": "^6.2.0"
-          },
-          "dependencies": {
-            "slice-ansi": {
-              "version": "4.0.0",
-              "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
-              "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "^4.0.0",
-                "astral-regex": "^2.0.0",
-                "is-fullwidth-code-point": "^3.0.0"
-              }
-            },
-            "wrap-ansi": {
-              "version": "6.2.0",
-              "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
-              "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "^4.0.0",
-                "string-width": "^4.1.0",
-                "strip-ansi": "^6.0.0"
-              }
-            }
-          }
-        },
-        "p-map": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
-          "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
-          "dev": true,
-          "requires": {
-            "aggregate-error": "^3.0.0"
-          }
-        },
-        "restore-cursor": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
-          "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
-          "dev": true,
-          "requires": {
-            "onetime": "^5.1.0",
-            "signal-exit": "^3.0.2"
-          }
-        },
-        "rxjs": {
-          "version": "7.5.5",
-          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
-          "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
-          "dev": true,
-          "requires": {
-            "tslib": "^2.1.0"
-          }
-        },
-        "slice-ansi": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
-          "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "astral-regex": "^2.0.0",
-            "is-fullwidth-code-point": "^3.0.0"
-          }
-        },
-        "string-width": {
-          "version": "4.2.3",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-          "dev": true,
-          "requires": {
-            "emoji-regex": "^8.0.0",
-            "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.1"
-          }
-        }
-      }
-    },
     "load-json-file": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
@@ -25281,19 +24412,19 @@
         "tr46": {
           "version": "0.0.3",
           "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-          "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+          "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
           "dev": true
         },
         "webidl-conversions": {
           "version": "3.0.1",
           "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-          "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+          "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
           "dev": true
         },
         "whatwg-url": {
           "version": "5.0.0",
           "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-          "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+          "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
           "dev": true,
           "requires": {
             "tr46": "~0.0.3",
@@ -27470,12 +26601,6 @@
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
       "dev": true
     },
-    "pidtree": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
-      "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
-      "dev": true
-    },
     "pify": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@@ -28362,12 +27487,6 @@
       "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
       "dev": true
     },
-    "rfdc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
-      "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
-      "dev": true
-    },
     "rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -29179,12 +28298,6 @@
         "safe-buffer": "~5.1.0"
       }
     },
-    "string-argv": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
-      "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
-      "dev": true
-    },
     "string-length": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
diff --git a/package.json b/package.json
index 32ccba0d8..2611b7fd9 100644
--- a/package.json
+++ b/package.json
@@ -89,7 +89,7 @@
     "@semantic-release/changelog": "^6.0.1",
     "@semantic-release/commit-analyzer": "^9.0.2",
     "@semantic-release/git": "^10.0.1",
-    "@semantic-release/github": "^8.0.5",
+    "@semantic-release/github": "^8.0.4",
     "@semantic-release/npm": "^9.0.1",
     "@semantic-release/release-notes-generator": "^10.0.3",
     "@types/jest": "^28.1.4",
@@ -116,7 +116,6 @@
     "js-yaml": "^4.1.0",
     "kleur": "^4.1.5",
     "less": "^4.1.3",
-    "lint-staged": "^13.0.3",
     "lintspaces-cli": "^0.7.1",
     "postcss": "^8.4.14",
     "postcss-less": "^6.0.0",
diff --git a/src/modules/esl-forms/esl-select/core/esl-select.ts b/src/modules/esl-forms/esl-select/core/esl-select.ts
index b0d32dd23..56d72f0d5 100644
--- a/src/modules/esl-forms/esl-select/core/esl-select.ts
+++ b/src/modules/esl-forms/esl-select/core/esl-select.ts
@@ -19,7 +19,7 @@ import {ESLSelectDropdown} from './esl-select-dropdown';
 @ExportNs('Select')
 export class ESLSelect extends ESLSelectWrapper {
   public static readonly is = 'esl-select';
-  public static observedAttributes = ['disabled', 'dropdown-class'];
+  public static observedAttributes = ['disabled'];
 
   public static register(): void {
     ESLSelectDropdown.register();
@@ -61,12 +61,8 @@ export class ESLSelect extends ESLSelectWrapper {
     this.$dropdown = document.createElement(ESLSelectDropdown.is);
   }
 
-  protected attributeChangedCallback(attrName: string, oldVal: string, newVal: string): void {
+  protected attributeChangedCallback(attrName: string): void {
     if (attrName === 'disabled') this._updateDisabled();
-    if (attrName === 'dropdown-class') {
-      this.$dropdown.$$cls(oldVal, false);
-      this.$dropdown.$$cls(newVal, true);
-    }
   }
 
   protected connectedCallback(): void {
diff --git a/src/modules/esl-media-query/core/conditions/media-query-condition.ts b/src/modules/esl-media-query/core/conditions/media-query-condition.ts
index 8cf99796e..cd83dfc10 100644
--- a/src/modules/esl-media-query/core/conditions/media-query-condition.ts
+++ b/src/modules/esl-media-query/core/conditions/media-query-condition.ts
@@ -28,7 +28,7 @@ export class MediaQueryCondition extends SyntheticEventTarget implements IMediaQ
   public addEventListener(type: 'change', callback: EventListener): void;
   public addEventListener(type: any, callback: EventListener = type): void {
     super.addEventListener(type, callback);
-    if (this._listeners.size > 1) return;
+    if (this.hasEventListener(1)) return;
     if (typeof this._mq.addEventListener === 'function') {
       this._mq.addEventListener('change', this._onChange);
     } else {
@@ -40,7 +40,7 @@ export class MediaQueryCondition extends SyntheticEventTarget implements IMediaQ
   public removeEventListener(type: 'change', callback: EventListener): void;
   public removeEventListener(type: any, callback: EventListener = type): void {
     super.removeEventListener(type, callback);
-    if (this._listeners.size) return;
+    if (this.hasEventListener()) return;
     if (typeof this._mq.removeEventListener === 'function') {
       this._mq.removeEventListener('change', this._onChange);
     } else {
diff --git a/src/modules/esl-media-query/core/conditions/media-query-containers.ts b/src/modules/esl-media-query/core/conditions/media-query-containers.ts
index 2289d8704..173bbd378 100644
--- a/src/modules/esl-media-query/core/conditions/media-query-containers.ts
+++ b/src/modules/esl-media-query/core/conditions/media-query-containers.ts
@@ -23,7 +23,7 @@ abstract class MediaQueryContainer extends SyntheticEventTarget implements IMedi
   public addEventListener(type: 'change', callback: EventListener): void;
   public addEventListener(type: any, callback: EventListener = type): void {
     super.addEventListener(type, callback);
-    if (this._listeners.size > 1) return;
+    if (this.hasEventListener(1)) return;
     this.items.forEach((item) => item.addEventListener('change', this._onChange));
   }
 
@@ -31,7 +31,7 @@ abstract class MediaQueryContainer extends SyntheticEventTarget implements IMedi
   public removeEventListener(type: 'change', callback: EventListener): void;
   public removeEventListener(type: any, callback: EventListener = type): void {
     super.removeEventListener(type, callback);
-    if (this._listeners.size) return;
+    if (this.hasEventListener()) return;
     this.items.forEach((item) => item.removeEventListener('change', this._onChange));
   }
 
diff --git a/src/modules/esl-media-query/core/esl-media-rule-list.ts b/src/modules/esl-media-query/core/esl-media-rule-list.ts
index 297c833d4..c86bc66dc 100644
--- a/src/modules/esl-media-query/core/esl-media-rule-list.ts
+++ b/src/modules/esl-media-query/core/esl-media-rule-list.ts
@@ -151,7 +151,7 @@ export class ESLMediaRuleList<T = any> extends SyntheticEventTarget {
   public addEventListener(type: 'change', callback: EventListener): void;
   public addEventListener(type: any, callback: EventListener = type): void {
     super.addEventListener(type, callback);
-    if (this._listeners.size > 1) return;
+    if (this.hasEventListener(1)) return;
     this._value = this.computedValue;
     this.rules.forEach((rule) => rule.addEventListener(this._onMatchChanged));
   }
@@ -161,7 +161,7 @@ export class ESLMediaRuleList<T = any> extends SyntheticEventTarget {
   public removeEventListener(type: 'change', callback: EventListener): void;
   public removeEventListener(type: any, callback: EventListener = type): void {
     super.removeEventListener(type, callback);
-    if (this._listeners.size) return;
+    if (this.hasEventListener()) return;
     delete this._value;
     this.rules.forEach((rule) => rule.removeEventListener(this._onMatchChanged));
   }
@@ -189,7 +189,7 @@ export class ESLMediaRuleList<T = any> extends SyntheticEventTarget {
    * Uses cache if current object is under observation
    */
   public get value(): T | undefined {
-    if (!this._listeners.size) return this.computedValue;
+    if (!this.hasEventListener()) return this.computedValue;
     return Object.hasOwnProperty.call(this, '_value') ? this._value : this.computedValue;
   }
   /** Always computed value of the current {@link ESLMediaRuleList} object */
diff --git a/src/modules/esl-traversing-query/README.md b/src/modules/esl-traversing-query/README.md
index 021dbc4a6..fb18c9fd6 100644
--- a/src/modules/esl-traversing-query/README.md
+++ b/src/modules/esl-traversing-query/README.md
@@ -13,7 +13,7 @@ Extended query supports:
  - relative selectors  
 NOTE: Selectors that don't start from a plain selector will use passed base Element as a root
  - `::next` and `::prev` sibling pseudo-selectors
- - `::parent`, `::closest` and `::child` pseudo-selectors
+ - `::parent` and `::child` pseudo-selectors
  - `::find` pseudo-selector
  - `::first`, `::last` and `:nth(#)` limitation pseudo-selectors
 
@@ -27,7 +27,6 @@ NOTE: Selectors that don't start from a plain selector will use passed base Elem
 - `::prev` - get previous sibling element
 - `::parent` - get base element parent
 - `::parent(#id .class [attr])` - find the closest parent, matching passed selector
-- `::closest(#id .class [attr])` - find the closest ancestor including base element that matches passed selector
 - `::child(#id .class [attr])` - find direct child element(s) that match passed selector
 - `::find(#id .class [attr])` - find child element(s) that match passed selector
 - `::parent::child(some-tag)` - find direct child element(s) that match tag 'some-tag' in the parent
diff --git a/src/modules/esl-traversing-query/core/esl-traversing-query.ts b/src/modules/esl-traversing-query/core/esl-traversing-query.ts
index 8b2f5a1a2..6c9d7b5d2 100644
--- a/src/modules/esl-traversing-query/core/esl-traversing-query.ts
+++ b/src/modules/esl-traversing-query/core/esl-traversing-query.ts
@@ -1,7 +1,7 @@
 import {ExportNs} from '../../esl-utils/environment/export-ns';
 import {tuple, wrap, uniq} from '../../esl-utils/misc/array';
 import {unwrapParenthesis} from '../../esl-utils/misc/format';
-import {findAll, findChildren, findNext, findParent, findClosest, findPrev} from '../../esl-utils/dom/traversing';
+import {findAll, findChildren, findNext, findParent, findPrev} from '../../esl-utils/dom/traversing';
 
 type ProcessorDescriptor = [string?, string?];
 type ElementProcessor = (base: Element, sel: string) => Element | Element[] | null;
@@ -13,7 +13,7 @@ type CollectionProcessor = (els: Element[], sel: string) => Element[];
  * - plain CSS selectors
  * - relative selectors (selectors that don't start from a plain selector will use passed base Element as a root)
  * - ::next and ::prev sibling pseudo-selectors
- * - ::parent, ::closest and ::child pseudo-selectors
+ * - ::parent and ::child pseudo-selectors
  * - ::find pseudo-selector
  * - ::first, ::last and :nth(#) limitation pseudo-selectors
  * - ::filter, ::not filtration pseudo-selectors
@@ -25,7 +25,6 @@ type CollectionProcessor = (els: Element[], sel: string) => Element[];
  * - `::prev` - get previous sibling element
  * - `::parent` - get base element parent
  * - `::parent(#id .class [attr])` - find the closest parent matching passed selector
- * - `::closest(#id .class [attr])` - find the closest ancestor including base element that matches passed selector
  * - `::child(#id .class [attr])` - find direct child element(s) that match passed selector
  * - `::find(#id .class [attr])` - find child element(s) that match passed selector
  * - `::find(buttons, a)::not([hidden])` - find all buttons and anchors that are not have hidden attribute
@@ -41,8 +40,7 @@ export class TraversingQuery {
     '::next': findNext,
     '::prev': findPrev,
     '::child': findChildren,
-    '::parent': findParent,
-    '::closest': findClosest
+    '::parent': findParent
   };
   private static COLLECTION_PROCESSORS: Record<string, CollectionProcessor> = {
     '::first': (list: Element[]) => list.slice(0, 1),
@@ -57,7 +55,7 @@ export class TraversingQuery {
 
   /**
    * @returns RegExp that selects all known processors in query string
-   * e.g. /(::parent|::closest|::child|::next|::prev)/
+   * e.g. /(::parent|::child|::next|::prev)/
    */
   private static get PROCESSORS_REGEX(): RegExp {
     const keys = Object.keys(this.ELEMENT_PROCESSORS).concat(Object.keys(this.COLLECTION_PROCESSORS));
diff --git a/src/modules/esl-utils/dom/events/target.ts b/src/modules/esl-utils/dom/events/target.ts
index 15ae4dced..19af184ea 100644
--- a/src/modules/esl-utils/dom/events/target.ts
+++ b/src/modules/esl-utils/dom/events/target.ts
@@ -4,7 +4,19 @@
  * Ignores event type
  */
 export class SyntheticEventTarget implements EventTarget {
-  protected readonly _listeners = new Set<EventListenerOrEventListenerObject>();
+  private readonly _listeners = new Set<EventListenerOrEventListenerObject>();
+
+  // Parameter "type" will be used in future update
+  public hasEventListener(): boolean;
+  public hasEventListener(type: string | number): boolean;
+  public hasEventListener(type: string, minCount: number): boolean;
+  public hasEventListener(type: string | number = 'change', minCount: number = 0): boolean {
+    if (typeof type === 'number') {
+      minCount = type;
+      type = 'change';
+    }
+    return this._listeners.size > minCount;
+  }
 
   public addEventListener(callback: EventListenerOrEventListenerObject): void;
   public addEventListener(type: 'change', callback: EventListenerOrEventListenerObject): void;
diff --git a/src/modules/esl-utils/dom/traversing.ts b/src/modules/esl-utils/dom/traversing.ts
index d55ceb374..0b081541f 100644
--- a/src/modules/esl-utils/dom/traversing.ts
+++ b/src/modules/esl-utils/dom/traversing.ts
@@ -1,18 +1,13 @@
-import type {Predicate} from '../misc/functions';
 /** Check that `nodeA` and `nodeB` are from the same tree path */
 export const isRelativeNode = (nodeA: Node | null, nodeB: Node | null): boolean => {
   return !!(nodeA && nodeB) && (nodeA.contains(nodeB) || nodeB.contains(nodeA));
 };
 
-type IteratorFn = (el: Element) => Element | null;
-
 /** Create function that finds next dom element, that matches selector, in the sequence declared by `next` function */
-export const createSequenceFinder = (next: IteratorFn, includeSelf: boolean = false) => {
-  return function (base: Element, predicate: string | Predicate<Element>): Element | null {
-    if (!predicate) return includeSelf ? base : next(base);
-    for (let target: Element | null = includeSelf ? base : next(base); target; target = next(target)) {
-      if (typeof predicate === 'string' && target.matches(predicate)) return target;
-      if (typeof predicate === 'function' && predicate.call(target, target)) return target;
+export const createSequenceFinder = (next: (el: Element) => Element | null) => {
+  return function (base: Element, sel: string): Element | null {
+    for (let target: Element | null = next(base); target; target = next(target)) {
+      if (!sel || target.matches(sel)) return target;
     }
     return null;
   };
@@ -31,8 +26,6 @@ export const findNext = createSequenceFinder((el) => el.nextElementSibling);
 export const findPrev = createSequenceFinder((el) => el.previousElementSibling);
 /** @returns first matching parent or null*/
 export const findParent = createSequenceFinder((el) => el.parentElement);
-/** @returns first matching ancestor starting from passed element or null*/
-export const findClosest = createSequenceFinder((el) => el.parentElement, true);
 
 /** @returns Array of all matching elements in subtree or empty array */
 export const findAll = (base: Element, sel: string): Element[] => {
@@ -65,7 +58,6 @@ export abstract class TraversingUtils {
   static findNext = findNext;
   static findPrev = findPrev;
   static findParent = findParent;
-  static findClosest = findClosest;
 
   static findAll = findAll;
   static findChildren = findChildren;
diff --git a/src/modules/esl-utils/misc/functions.ts b/src/modules/esl-utils/misc/functions.ts
index 09508b4cd..cdc179eea 100644
--- a/src/modules/esl-utils/misc/functions.ts
+++ b/src/modules/esl-utils/misc/functions.ts
@@ -12,8 +12,6 @@ export type AnyToAnyFnSignature = (...args: any[]) => any;
 
 export type MethodTypedDecorator<T> = (target: any, property: string, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
 
-export type Predicate<T> = (el: T) => boolean;
-
 /**
  * Property provider function
  * @param that - (equal to `this` context) host or context


Test patch:
diff --git a/src/modules/esl-traversing-query/test/esl-traversing-query.test.ts b/src/modules/esl-traversing-query/test/esl-traversing-query.test.ts
index efd755e06..9ff01e16c 100644
--- a/src/modules/esl-traversing-query/test/esl-traversing-query.test.ts
+++ b/src/modules/esl-traversing-query/test/esl-traversing-query.test.ts
@@ -31,142 +31,99 @@ describe('Traversing Query tests', () => {
   const article1 = document.querySelector('.col-1') as HTMLElement;
   const article2 = document.querySelector('.col-2') as HTMLElement;
 
-  const traversingQueryWrap = (sel: any, base: any, expectedCollection: any) => {
+  test.each([
+    '::next',
+    '::prev',
+    '::find',
+    '::find(.btn)',
+    '::child',
+    '::child(.btn)',
+    '::parent',
+    '::parent(body)'
+  ])('Null check: TraversingQuery.all/one(%s, null)', (sel) => {
+    expect(TraversingQuery.first(sel)).toBe(null);
+    expect(TraversingQuery.all(sel)).toEqual([]);
+  });
+
+  test.each([
+    // Simple queries
+    ['#null', undefined, []],
+    ['#btn3', undefined, [btn3]],
+    ['#btn3', null, [btn3]],
+    ['section', undefined, [root]],
+    ['section > .row', undefined, [row1, row2]],
+    ['section > .row:first-child', undefined, [row1]],
+
+    // Next query test
+    ['::next', btn1, [btn2]],
+    ['::next', btn6, []],
+    ['::next(article)', btn1, [article1]],
+    ['::next(article.col-1)', btn1, [article1]],
+    ['::next(article.col-2)', btn1, []],
+
+    // Prev query test
+    ['::prev', btn2, [btn1]],
+    ['::prev', btn1, []],
+    ['::prev(.btn)', article1, [btn5]],
+    ['::prev(#btn2)', article1, [btn2]],
+    ['::prev(#btn6)', article1, []],
+
+    // Child query test
+    ['::child', article1, []],
+    ['::child', row1, [btn1, btn2, btn3, btn4, btn5, article1]],
+    ['::child(#btn2)', row1, [btn2]],
+    ['::child(.btn)', article1, []],
+
+    // Parent query test
+    ['::parent', article1, [row1]],
+    ['::parent', root, [document.body]],
+    ['::parent(.container)', btn1, [root]],
+    ['::parent(.btn)', btn1, []],
+
+    // Find query test
+    ['::find', root, [root]],
+    ['::find(.btn)', root, [btn1, btn2, btn3, btn4, btn5, btn6]],
+    ['::find(.container)', root, []],
+    ['::find(#row1 .btn)', root, [btn1, btn2, btn3, btn4, btn5]],
+
+    // Postprocessors
+    ['::find(.btn)::first', root, [btn1]],
+    ['::find(.btn)::last', root, [btn6]],
+    ['::find(.btn)::nth(1)', root, [btn1]],
+    ['::find(.btn)::nth(4)', root, [btn4]],
+    ['::find(.btn)::nth(6)', root, [btn6]],
+    ['::find(.btn)::nth', root, []],
+    ['::find(.btn)::nth(8)', root, []],
+    ['::find(.btn)::nth(bla bla)', root, []],
+
+    // Filters
+    ['::find(.btn)::filter(.un-existing)', root, []],
+    ['::find(.btn)::not(button)', root, []],
+    ['::find(.btn)::filter([data-test])', root, [btn2, btn5, btn6]],
+    ['::find(.btn)::not([data-test])', root, [btn1, btn3, btn4]],
+    ['::find(.btn)::filter(:first-child)', root, [btn1]],
+    ['::find(.btn)::not(:first-child)', root, [btn2, btn3, btn4, btn5, btn6]],
+
+    // Complex query test
+    ['::parent::child', root, [root]],
+    ['::parent::find(.btn)', btn5, [btn1, btn2, btn3, btn4, btn5]],
+    ['::parent::next::find(.col-2)', article1, [article2]],
+    ['::parent(.container)::find(.btn)::last', btn5, [btn6]],
+    ['::parent(.container)::child(.row)::last::find(.col-2)', article1, [article2]],
+  ])('Main check: TraversingQuery.all/one, Sel: %s, Base: %p.', (sel, base, expectedCollection) => {
     expect(TraversingQuery.first(sel, base as Element | null))
       .toBe(expectedCollection.length > 0 ? expectedCollection[0] : null);
     expect(TraversingQuery.all(sel, base as Element | null))
       .toEqual(expectedCollection);
-  };
-
-  describe('test cases when base element is absent', () => {
-    test.each([
-      '::next',
-      '::prev',
-      '::find',
-      '::find(.btn)',
-      '::child',
-      '::child(.btn)',
-      '::parent',
-      '::parent(body)',
-      '::closest',
-      '::closest(.btn)'
-    ])('Null check: TraversingQuery.all/one(%s, null)', (sel) => {
-      expect(TraversingQuery.first(sel)).toBe(null);
-      expect(TraversingQuery.all(sel)).toEqual([]);
-    });
-  });
-
-  describe('queries with plain selectors', () => {
-    test.each([
-      ['#null', undefined, []],
-      ['#btn3', undefined, [btn3]],
-      ['#btn3', null, [btn3]],
-      ['section', undefined, [root]],
-      ['section > .row', undefined, [row1, row2]],
-      ['section > .row:first-child', undefined, [row1]]
-    ])('Main check: TraversingQuery.el: %s, Base: %p.', traversingQueryWrap);
-  });
-
-  describe('pseudo-selector ::next', () => {
-    test.each([
-      ['::next', btn1, [btn2]],
-      ['::next', btn6, []],
-      ['::next(article)', btn1, [article1]],
-      ['::next(article.col-1)', btn1, [article1]],
-      ['::next(article.col-2)', btn1, []]
-    ])('Main check: TraversSel: %s, Base: %p.', traversingQueryWrap);
-  });
-
-  describe('pseudo-selector ::prev', () => {
-    test.each([
-      ['::prev', btn2, [btn1]],
-      ['::prev', btn1, []],
-      ['::prev(.btn)', article1, [btn5]],
-      ['::prev(#btn2)', article1, [btn2]],
-      ['::prev(#btn6)', article1, []]
-    ])('Main check: TraversingQuery: %s, Base: %p.', traversingQueryWrap);
-  });
-
-  describe('pseudo-selector ::child', () => {
-    test.each([
-      ['::child', article1, []],
-      ['::child', row1, [btn1, btn2, btn3, btn4, btn5, article1]],
-      ['::child(#btn2)', row1, [btn2]],
-      ['::child(.btn)', article1, []]
-    ])('Main check: TraversingQuel: %s, Base: %p.', traversingQueryWrap);
-  });
-
-  describe('pseudo-selector ::parent', () => {
-    test.each([
-      ['::parent', article1, [row1]],
-      ['::parent', root, [document.body]],
-      ['::parent(.container)', btn1, [root]],
-      ['::parent(.btn)', btn1, []]
-    ])('Main check: TraversingQuery.all/one, Sel: %s, Base: %p.', traversingQueryWrap);
   });
 
-  describe('pseudo-selector ::closest', () => {
-    test.each([
-      ['::closest', btn1, [btn1]],
-      ['::closest(.btn)', btn1, [btn1]],
-      ['::closest(#row1)', btn1, [row1]],
-      ['::closest(.btn)', row1, []],
-    ])('Main check: TraversingQuery.all/one, Sel: %s, Base: %p.', traversingQueryWrap);
-  });
-
-  describe('pseudo-selector ::find', () => {
-    test.each([
-      ['::find', root, [root]],
-      ['::find(.btn)', root, [btn1, btn2, btn3, btn4, btn5, btn6]],
-      ['::find(.container)', root, []],
-      ['::find(#row1 .btn)', root, [btn1, btn2, btn3, btn4, btn5]]
-    ])('Main check: TraversingQuery.all/one, Sel: %s, Base: %p.', traversingQueryWrap);
-  });
-
-  describe('postprocessors (::first, ::last, ::nth)', () => {
-    test.each([
-      ['::find(.btn)::first', root, [btn1]],
-      ['::find(.btn)::last', root, [btn6]],
-      ['::find(.btn)::nth(1)', root, [btn1]],
-      ['::find(.btn)::nth(4)', root, [btn4]],
-      ['::find(.btn)::nth(6)', root, [btn6]],
-      ['::find(.btn)::nth', root, []],
-      ['::find(.btn)::nth(8)', root, []],
-      ['::find(.btn)::nth(bla bla)', root, []]
-    ])('Main check: TraversingQuery.all/one, Sel: %s, Base: %p.', traversingQueryWrap);
-  });
-
-  describe('filters (::filter, ::not)', () => {
-    test.each([
-      ['::find(.btn)::filter(.un-existing)', root, []],
-      ['::find(.btn)::not(button)', root, []],
-      ['::find(.btn)::filter([data-test])', root, [btn2, btn5, btn6]],
-      ['::find(.btn)::not([data-test])', root, [btn1, btn3, btn4]],
-      ['::find(.btn)::filter(:first-child)', root, [btn1]],
-      ['::find(.btn)::not(:first-child)', root, [btn2, btn3, btn4, btn5, btn6]]
-    ])('Main check: TraversingQuery.all/one, Sel: %s, Base: %p.', traversingQueryWrap);
-  });
-
-  describe('queries using several pseudo-selectors and plain selectors', () => {
-    test.each([
-      ['::parent::child', root, [root]],
-      ['::parent::find(.btn)', btn5, [btn1, btn2, btn3, btn4, btn5]],
-      ['::parent::next::find(.col-2)', article1, [article2]],
-      ['::parent(.container)::find(.btn)::last', btn5, [btn6]],
-      ['::parent(.container)::child(.row)::last::find(.col-2)', article1, [article2]],
-      ['::closest(.row)::find(.col-1)', btn1, [article1]]
-    ])('Main check: TraversingQuery.all/one, Sel: %s, Base: %p.', traversingQueryWrap);
-  });
-
-  describe('test cases when scope is defined', () => {
-    test.each([
-      ['#row1', null, root, [row1]],
-      ['#row1', null, row2, []]
-    ])('Main check: TraversingQuery.all/one, Sel: %s, Base: %p., Scope: %p.', (sel, base, scope, expectedCollection) => {
-      expect(TraversingQuery.first(sel, base as Element | null, scope as Element))
-        .toBe(expectedCollection.length > 0 ? expectedCollection[0] : null);
-      expect(TraversingQuery.all(sel, base as Element | null, scope as Element))
-        .toEqual(expectedCollection);
-    });
+  test.each([
+    ['#row1', null, root, [row1]],
+    ['#row1', null, row2, []],
+  ])('Main check: TraversingQuery.all/one, Sel: %s, Base: %p., Scope: %p.', (sel, base, scope, expectedCollection) => {
+    expect(TraversingQuery.first(sel, base as Element | null, scope as Element))
+      .toBe(expectedCollection.length > 0 ? expectedCollection[0] : null);
+    expect(TraversingQuery.all(sel, base as Element | null, scope as Element))
+      .toEqual(expectedCollection);
   });
 });
diff --git a/src/modules/esl-utils/dom/test/traversing.test.ts b/src/modules/esl-utils/dom/test/traversing.test.ts
index 2af882a47..8326c052a 100644
--- a/src/modules/esl-utils/dom/test/traversing.test.ts
+++ b/src/modules/esl-utils/dom/test/traversing.test.ts
@@ -1,4 +1,4 @@
-import {isRelativeNode, findClosestBy, isMatches, findNext, findPrev, findParent, findClosest, findAll, findChildren} from '../traversing';
+import {isRelativeNode, findClosestBy, isMatches} from '../traversing';
 
 describe('Common: dom/traversing helper tests', () => {
   document.body.innerHTML = `
@@ -24,108 +24,32 @@ describe('Common: dom/traversing helper tests', () => {
   const row1 = document.querySelector('#row1') as HTMLDivElement;
   const btn1 = document.querySelector('#btn1') as HTMLButtonElement;
   const btn2 = document.querySelector('#btn2') as HTMLButtonElement;
-  const btn3 = document.querySelector('#btn3') as HTMLButtonElement;
-  const btn4 = document.querySelector('#btn4') as HTMLButtonElement;
-  const btn5 = document.querySelector('#btn5') as HTMLButtonElement;
-  const row2 = document.querySelector('#row2') as HTMLDivElement;
   const article1 = document.querySelector('.col-1') as HTMLElement;
 
-  describe('isRelativeNode', () => {
-    test('checks that both nodes are from the same tree path and returns true if they are', () => {
-      expect(isRelativeNode(document.body, btn1)).toBeTruthy();
-      expect(isRelativeNode(btn1, root)).toBeTruthy();
-    });
-    test('returns false if nodes are not from the same tree path', () => {
-      expect(isRelativeNode(document.body, document.createElement('div'))).toBeFalsy();
-      expect(isRelativeNode(btn1, btn2)).toBeFalsy();
-    });
+  test('isRelativeNode', () => {
+    expect(isRelativeNode(document.body, btn1)).toBeTruthy();
+    expect(isRelativeNode(btn1, root)).toBeTruthy();
+    expect(isRelativeNode(document.body, document.createElement('div'))).toBeFalsy();
+    expect(isRelativeNode(btn1, btn2)).toBeFalsy();
   });
 
-  describe('isMatches', () => {
-    test('returns true if element matches passed selector or exact predicate function', () => {
-      expect(isMatches(div, (el) => div === el)).toBeTruthy();
-      expect(isMatches(div, 'div')).toBeTruthy();
-    });
-    test('returns false if element does not match passed selector or exact predicate function', () => {
-      expect(isMatches(div, (el) => root === el)).toBeFalsy();
-      expect(isMatches(div, 'span')).toBeFalsy();
-      expect(isMatches(div)).toBeFalsy();
-    });
+  test('isMatches', () => {
+    expect(isMatches(div, (el) => div === el)).toBeTruthy();
+    expect(isMatches(div, (el) => root === el)).toBeFalsy();
+    expect(isMatches(div, 'div')).toBeTruthy();
+    expect(isMatches(div, 'span')).toBeFalsy();
+    expect(isMatches(div)).toBeFalsy();
   });
 
-  describe('closestBy', () => {
-    test('finds closest parent node starting from the base element', () => {
-      expect(findClosestBy(null, (el: HTMLElement) => el.dataset.test === '1')).toBe(null);
-      expect(findClosestBy(document.createElement('div'), (el: HTMLElement) => el.dataset.test === '1')).toBe(null);
-      expect(findClosestBy(btn2, (el: HTMLElement) => el.classList.contains('btn'))).toBe(btn2);
-      expect(findClosestBy(btn2, (el: HTMLElement) => el.dataset.test === '1')).toBe(row1);
-      expect(findClosestBy(btn2, (el: HTMLElement) => el.tagName.toLowerCase() === 'section')).toBeTruthy();
-      expect(findClosestBy(article1, () => false)).toBe(null);
-    });
-    test('finds closest parent node skipping the base element', () => {
-      expect(findClosestBy(btn2, (el: HTMLElement) => el.dataset.test === '1', true)).toBe(row1);
-    });
+  test('closestBy', () => {
+    expect(findClosestBy(null, (el: HTMLElement) => el.dataset.test === '1')).toBe(null);
+    expect(findClosestBy(document.createElement('div'), (el: HTMLElement) => el.dataset.test === '1')).toBe(null);
+    expect(findClosestBy(btn2, (el: HTMLElement) => el.classList.contains('btn'))).toBe(btn2);
+    expect(findClosestBy(btn2, (el: HTMLElement) => el.dataset.test === '1')).toBe(row1);
+    expect(findClosestBy(btn2, (el: HTMLElement) => el.dataset.test === '1', true)).toBe(row1);
+    expect(findClosestBy(btn2, (el: HTMLElement) => el.tagName.toLowerCase() === 'section')).toBeTruthy();
+    expect(findClosestBy(article1, () => false)).toBe(null);
   });
 
-  describe('findNext', () => {
-    test('returns first next sibling that matches passed selector', () => {
-      expect(findNext(btn1, '#btn2')).toBe(btn2);
-      expect(findNext(btn1, '#btn3')).toBe(btn3);
-    });
-    test('returns null if there are no next siblings matching passed selector', () => {
-      expect(findNext(btn2, '#btn1')).toBe(null);
-      expect(findNext(btn2, '#btn2')).toBe(null);
-    });
-  });
-
-  describe('findPrev', () => {
-    test('returns first previous sibling that matches passed selector', () => {
-      expect(findPrev(btn2, '#btn1')).toBe(btn1);
-      expect(findPrev(btn3, '#btn1')).toBe(btn1);
-    });
-    test('returns null if there are no previous siblings matching passed selector', () => {
-      expect(findPrev(btn2, '#btn3')).toBe(null);
-      expect(findPrev(btn2, '#btn2')).toBe(null);
-    });
-  });
-
-  describe('findParent', () => {
-    test('returns first parent element matching passed selector', () => {
-      expect(findParent(btn1, '#row1')).toBe(row1);
-      expect(findParent(btn2, '.container')).toBe(root);
-    });
-    test('returns null if there are no parent elements matching passed selector', () => {
-      expect(findParent(btn2, '#row2')).toBe(null);
-    });
-  });
-
-  describe('findClosest', () => {
-    test('returns the element or their parent that matches passed selector', () => {
-      expect(findClosest(btn1, '.btn')).toBe(btn1);
-      expect(findClosest(btn2, '.container')).toBe(root);
-    });
-    test('returns null if the element and their parents do not match passed selector', () => {
-      expect(findClosest(btn2, '#row2')).toBe(null);
-    });
-  });
-
-  describe('findAll', () => {
-    test('returns array of all matching elements in subtree', () => {
-      expect(findAll(row1, '.btn')).toStrictEqual([btn1, btn2, btn3, btn4, btn5]);
-      expect(findAll(row1, '#btn3')).toStrictEqual([btn3]);
-    });
-    test('returns empty array if there are no matching elements in subtree', () => {
-      expect(findAll(row1, '.btn-6')).toStrictEqual([]);
-    });
-  });
-
-  describe('findChildren', () => {
-    test('returns array of all children matching passed selector', () => {
-      expect(findChildren(row1, '.btn')).toStrictEqual([btn1, btn2, btn3, btn4, btn5]);
-      expect(findChildren(root, '.row')).toStrictEqual([row1, row2]);
-    });
-    test('returns empty array if there are no children matching passed selector', () => {
-      expect(findChildren(root, '.btn')).toStrictEqual([]);
-    });
-  });
+  // TODO: add more test to cover traversing utils
 });