Repository: crimsonstrife/streamer.live
Pull request #206: Update dependencies to latest versions and refactor step.js
Author: login: crimsonstrife
Created: 2025-04-23T16:43:49Z | Merged: 2025-04-23T16:44:33Z

Upgraded various package versions in `composer.lock`, including `filament/*`, `laravel/framework`, and more, ensuring compatibility and new feature availability. Refactored `step.js` for cleaner and more consistent code formatting, improving readability and simplifying initialization logic for tutorial components.

## Summary by Sourcery

Update dependencies and refactor step.js for improved code quality and maintainability

Enhancements:
- Refactored step.js to improve code formatting and consistency
- Cleaned up JavaScript code structure in the tutorial component

Chores:
- Upgraded various package dependencies in composer.lock


Diff:
diff --git a/composer.lock b/composer.lock
index 97d1cbfd..be582b76 100644
--- a/composer.lock
+++ b/composer.lock
@@ -3468,16 +3468,16 @@
         },
         {
             "name": "filament/actions",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/actions.git",
-                "reference": "b99b705713719c3138d7666df56ca405c9ca8a8e"
+                "reference": "1532f9bbe5e0f12da860e90836983a5fd461ef1d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/actions/zipball/b99b705713719c3138d7666df56ca405c9ca8a8e",
-                "reference": "b99b705713719c3138d7666df56ca405c9ca8a8e",
+                "url": "https://api.github.com/repos/filamentphp/actions/zipball/1532f9bbe5e0f12da860e90836983a5fd461ef1d",
+                "reference": "1532f9bbe5e0f12da860e90836983a5fd461ef1d",
                 "shasum": ""
             },
             "require": {
@@ -3517,20 +3517,20 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-18T12:09:52+00:00"
+            "time": "2025-04-23T06:39:44+00:00"
         },
         {
             "name": "filament/filament",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/panels.git",
-                "reference": "fc22157f9f2d154ae653434495f252e04b2cb390"
+                "reference": "8ba5e3127bbb4c3b343f6295bd7592a1af67e312"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/panels/zipball/fc22157f9f2d154ae653434495f252e04b2cb390",
-                "reference": "fc22157f9f2d154ae653434495f252e04b2cb390",
+                "url": "https://api.github.com/repos/filamentphp/panels/zipball/8ba5e3127bbb4c3b343f6295bd7592a1af67e312",
+                "reference": "8ba5e3127bbb4c3b343f6295bd7592a1af67e312",
                 "shasum": ""
             },
             "require": {
@@ -3582,20 +3582,20 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-18T12:09:56+00:00"
+            "time": "2025-04-23T06:39:50+00:00"
         },
         {
             "name": "filament/forms",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/forms.git",
-                "reference": "78f56bfa8685cd2d2ba554ed2d6e761a0b589118"
+                "reference": "b43f1e2d0f946409d949c4bb91d2b001c2d33d00"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/forms/zipball/78f56bfa8685cd2d2ba554ed2d6e761a0b589118",
-                "reference": "78f56bfa8685cd2d2ba554ed2d6e761a0b589118",
+                "url": "https://api.github.com/repos/filamentphp/forms/zipball/b43f1e2d0f946409d949c4bb91d2b001c2d33d00",
+                "reference": "b43f1e2d0f946409d949c4bb91d2b001c2d33d00",
                 "shasum": ""
             },
             "require": {
@@ -3638,20 +3638,20 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-19T15:33:35+00:00"
+            "time": "2025-04-23T06:39:47+00:00"
         },
         {
             "name": "filament/infolists",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/infolists.git",
-                "reference": "d6cd5934aff207dcfcdec540fca92db849eeded3"
+                "reference": "cc71f1c15f132660986384d302a33a2b20618a96"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/d6cd5934aff207dcfcdec540fca92db849eeded3",
-                "reference": "d6cd5934aff207dcfcdec540fca92db849eeded3",
+                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/cc71f1c15f132660986384d302a33a2b20618a96",
+                "reference": "cc71f1c15f132660986384d302a33a2b20618a96",
                 "shasum": ""
             },
             "require": {
@@ -3689,20 +3689,20 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-18T12:10:08+00:00"
+            "time": "2025-04-23T06:39:44+00:00"
         },
         {
             "name": "filament/notifications",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/notifications.git",
-                "reference": "d4bb90c77a3e88ab833cab71d36b185b3670a314"
+                "reference": "edf7960621b2181b4c2fc040b0712fbd5dd036ef"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/notifications/zipball/d4bb90c77a3e88ab833cab71d36b185b3670a314",
-                "reference": "d4bb90c77a3e88ab833cab71d36b185b3670a314",
+                "url": "https://api.github.com/repos/filamentphp/notifications/zipball/edf7960621b2181b4c2fc040b0712fbd5dd036ef",
+                "reference": "edf7960621b2181b4c2fc040b0712fbd5dd036ef",
                 "shasum": ""
             },
             "require": {
@@ -3741,20 +3741,20 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-02T09:55:26+00:00"
+            "time": "2025-04-23T06:39:49+00:00"
         },
         {
             "name": "filament/spatie-laravel-media-library-plugin",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/spatie-laravel-media-library-plugin.git",
-                "reference": "bceb379be31201dc27c6568156ec027de95745e6"
+                "reference": "018e10282c0da65deee09f8745c10fa6ad7679c7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/spatie-laravel-media-library-plugin/zipball/bceb379be31201dc27c6568156ec027de95745e6",
-                "reference": "bceb379be31201dc27c6568156ec027de95745e6",
+                "url": "https://api.github.com/repos/filamentphp/spatie-laravel-media-library-plugin/zipball/018e10282c0da65deee09f8745c10fa6ad7679c7",
+                "reference": "018e10282c0da65deee09f8745c10fa6ad7679c7",
                 "shasum": ""
             },
             "require": {
@@ -3778,20 +3778,20 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-07T10:06:22+00:00"
+            "time": "2025-04-23T06:40:00+00:00"
         },
         {
             "name": "filament/spatie-laravel-settings-plugin",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/spatie-laravel-settings-plugin.git",
-                "reference": "4aaf2977038ee446c6cbb0d35e84996222573ce0"
+                "reference": "80c9e960b30890fdc731da262b71255cb39bee31"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/spatie-laravel-settings-plugin/zipball/4aaf2977038ee446c6cbb0d35e84996222573ce0",
-                "reference": "4aaf2977038ee446c6cbb0d35e84996222573ce0",
+                "url": "https://api.github.com/repos/filamentphp/spatie-laravel-settings-plugin/zipball/80c9e960b30890fdc731da262b71255cb39bee31",
+                "reference": "80c9e960b30890fdc731da262b71255cb39bee31",
                 "shasum": ""
             },
             "require": {
@@ -3825,20 +3825,20 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-02T09:55:11+00:00"
+            "time": "2025-04-23T06:39:48+00:00"
         },
         {
             "name": "filament/spatie-laravel-tags-plugin",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/spatie-laravel-tags-plugin.git",
-                "reference": "81843779d2f30ab21cd9a2ed8bb3d8b055469bc4"
+                "reference": "83b9ccea77d807e61f1782a1a433de2f687384c3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/spatie-laravel-tags-plugin/zipball/81843779d2f30ab21cd9a2ed8bb3d8b055469bc4",
-                "reference": "81843779d2f30ab21cd9a2ed8bb3d8b055469bc4",
+                "url": "https://api.github.com/repos/filamentphp/spatie-laravel-tags-plugin/zipball/83b9ccea77d807e61f1782a1a433de2f687384c3",
+                "reference": "83b9ccea77d807e61f1782a1a433de2f687384c3",
                 "shasum": ""
             },
             "require": {
@@ -3862,11 +3862,11 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-07T10:58:30+00:00"
+            "time": "2025-04-23T06:40:07+00:00"
         },
         {
             "name": "filament/spatie-laravel-translatable-plugin",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/spatie-laravel-translatable-plugin.git",
@@ -3911,16 +3911,16 @@
         },
         {
             "name": "filament/support",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/support.git",
-                "reference": "ca955875a0e1c67aba92a1b5bb86841dd9f9ec43"
+                "reference": "819ebbd60a72b4ee3078d4771bb75d551fbb0b43"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/support/zipball/ca955875a0e1c67aba92a1b5bb86841dd9f9ec43",
-                "reference": "ca955875a0e1c67aba92a1b5bb86841dd9f9ec43",
+                "url": "https://api.github.com/repos/filamentphp/support/zipball/819ebbd60a72b4ee3078d4771bb75d551fbb0b43",
+                "reference": "819ebbd60a72b4ee3078d4771bb75d551fbb0b43",
                 "shasum": ""
             },
             "require": {
@@ -3966,20 +3966,20 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-18T12:09:53+00:00"
+            "time": "2025-04-23T06:39:48+00:00"
         },
         {
             "name": "filament/tables",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/tables.git",
-                "reference": "e361761990eda562f874c68cc2aaec04c97d43ba"
+                "reference": "de7b1854ecfcccc97f59b89cda80ca6bd6431143"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/tables/zipball/e361761990eda562f874c68cc2aaec04c97d43ba",
-                "reference": "e361761990eda562f874c68cc2aaec04c97d43ba",
+                "url": "https://api.github.com/repos/filamentphp/tables/zipball/de7b1854ecfcccc97f59b89cda80ca6bd6431143",
+                "reference": "de7b1854ecfcccc97f59b89cda80ca6bd6431143",
                 "shasum": ""
             },
             "require": {
@@ -4018,20 +4018,20 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-04-19T15:33:35+00:00"
+            "time": "2025-04-23T06:40:04+00:00"
         },
         {
             "name": "filament/widgets",
-            "version": "v3.3.12",
+            "version": "v3.3.13",
             "source": {
                 "type": "git",
                 "url": "https://github.com/filamentphp/widgets.git",
-                "reference": "2d91f0d509b4ef497678b919e471e9099451bd21"
+                "reference": "048c5a4bf0477efbe2910c54a1aeb55c64cf1348"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/filamentphp/widgets/zipball/2d91f0d509b4ef497678b919e471e9099451bd21",
-                "reference": "2d91f0d509b4ef497678b919e471e9099451bd21",
+                "url": "https://api.github.com/repos/filamentphp/widgets/zipball/048c5a4bf0477efbe2910c54a1aeb55c64cf1348",
+                "reference": "048c5a4bf0477efbe2910c54a1aeb55c64cf1348",
                 "shasum": ""
             },
             "require": {
@@ -4062,7 +4062,7 @@
                 "issues": "https://github.com/filamentphp/filament/issues",
                 "source": "https://github.com/filamentphp/filament"
             },
-            "time": "2025-03-11T16:33:32+00:00"
+            "time": "2025-04-23T06:39:59+00:00"
         },
         {
             "name": "firebase/php-jwt",
@@ -5887,16 +5887,16 @@
         },
         {
             "name": "laravel/framework",
-            "version": "v11.44.2",
+            "version": "v11.44.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laravel/framework.git",
-                "reference": "f85216c82cbd38b66d67ebd20ea762cb3751a4b4"
+                "reference": "b0a87fbd13c0b05227a00da7968701f4274e3195"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laravel/framework/zipball/f85216c82cbd38b66d67ebd20ea762cb3751a4b4",
-                "reference": "f85216c82cbd38b66d67ebd20ea762cb3751a4b4",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/b0a87fbd13c0b05227a00da7968701f4274e3195",
+                "reference": "b0a87fbd13c0b05227a00da7968701f4274e3195",
                 "shasum": ""
             },
             "require": {
@@ -6098,7 +6098,7 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2025-03-12T14:34:30+00:00"
+            "time": "2025-04-23T14:45:24+00:00"
         },
         {
             "name": "laravel/helpers",
@@ -21235,12 +21235,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/Roave/SecurityAdvisories.git",
-                "reference": "4a535062396cc0a0bb7a6bc72e4dc15e8b2018d0"
+                "reference": "3fe23dd6d9c692ec019ba1cff225f960699a0da3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/4a535062396cc0a0bb7a6bc72e4dc15e8b2018d0",
-                "reference": "4a535062396cc0a0bb7a6bc72e4dc15e8b2018d0",
+                "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3fe23dd6d9c692ec019ba1cff225f960699a0da3",
+                "reference": "3fe23dd6d9c692ec019ba1cff225f960699a0da3",
                 "shasum": ""
             },
             "conflict": {
@@ -21268,6 +21268,7 @@
                 "anchorcms/anchor-cms": "<=0.12.7",
                 "andreapollastri/cipi": "<=3.1.15",
                 "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5",
+                "aoe/restler": "<1.7.1",
                 "apache-solr-for-typo3/solr": "<2.8.3",
                 "apereo/phpcas": "<1.6",
                 "api-platform/core": "<3.4.17|>=4.0.0.0-alpha1,<4.0.22",
@@ -21354,7 +21355,7 @@
                 "concrete5/core": "<8.5.8|>=9,<9.1",
                 "contao-components/mediaelement": ">=2.14.2,<2.21.1",
                 "contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4",
-                "contao/contao": "<=5.4.1",
+                "contao/contao": ">=3,<3.5.37|>=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4",
                 "contao/core": "<3.5.39",
                 "contao/core-bundle": "<4.13.54|>=5,<5.3.30|>=5.4,<5.5.6",
                 "contao/listing-bundle": ">=3,<=3.5.30|>=4,<4.4.8",
@@ -21627,6 +21628,7 @@
                 "livewire/volt": "<1.7",
                 "lms/routes": "<2.1.1",
                 "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2",
+                "luracast/restler": "<3.1",
                 "luyadev/yii-helpers": "<1.2.1",
                 "macropay-solutions/laravel-crud-wizard-free": "<3.4.17",
                 "maestroerror/php-heic-to-jpg": "<1.0.5",
@@ -21685,6 +21687,7 @@
                 "mustache/mustache": ">=2,<2.14.1",
                 "mwdelaney/wp-enable-svg": "<=0.2",
                 "namshi/jose": "<2.2",
+                "nasirkhan/laravel-starter": "<11.11",
                 "nategood/httpful": "<1",
                 "neoan3-apps/template": "<1.1.1",
                 "neorazorx/facturascripts": "<2022.04",
@@ -22154,7 +22157,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2025-04-21T23:05:07+00:00"
+            "time": "2025-04-23T02:32:45+00:00"
         },
         {
             "name": "sebastian/cli-parser",
@@ -23327,5 +23330,5 @@
         "php": "^8.3"
     },
     "platform-dev": [],
-    "plugin-api-version": "2.3.0"
+    "plugin-api-version": "2.6.0"
 }
diff --git a/public/js/guava/tutorials/components/step.js b/public/js/guava/tutorials/components/step.js
index 3fab8593..223881be 100644
--- a/public/js/guava/tutorials/components/step.js
+++ b/public/js/guava/tutorials/components/step.js
@@ -1,5 +1,5 @@
 // resources/js/components/step.js
-function stepComponent ({
+function stepComponent({
   key,
   selector,
   shouldInterceptClick,
@@ -7,310 +7,225 @@ function stepComponent ({
 }) {
   return {
     target: null,
-    sleep: function (ms) {
-      return new Promise((resolve) => setTimeout(resolve, ms))
+      sleep: function (ms) {
+          return new Promise((resolve) => setTimeout(resolve, ms));
     },
-    init: async function () {
-      this.target = this.findElement(key)
+      init: async function () {
+          this.target = this.findElement(key);
       if (!this.target) {
-        console.error('Tutorial step was not found:', key)
-        return
+          console.error("Tutorial step was not found:", key);
+          return;
       }
-      document.documentElement
-        .querySelectorAll('input')
-        .forEach((element) => element.blur())
+          document.documentElement.querySelectorAll("input").forEach((element) => element.blur());
       if (this.target) {
-        this.target.focus()
+          this.target.focus();
       }
-      this.configure()
-      const dialog = this.$el.querySelector('[data-dialog]')
-      const clipPath = this.$el.querySelector('[data-clip-path]')
+          this.configure();
+          const dialog = this.$el.querySelector("[data-dialog]");
+          const clipPath = this.$el.querySelector("[data-clip-path]");
       if (shouldInterceptClick) {
-        this.target.addEventListener('click', (event) => {
-          event.preventDefault()
-          this.$wire.call(interceptClickAction)
-          this.target.blur()
-          const descendants = this.target.querySelectorAll(':hover')
+          this.target.addEventListener("click", (event) => {
+              event.preventDefault();
+              this.$wire.call(interceptClickAction);
+              this.target.blur();
+              const descendants = this.target.querySelectorAll(":hover");
           for (let i = 0; i < descendants.length; i++) {
-            const descendant = descendants[i]
-            descendant.blur()
+              const descendant = descendants[i];
+              descendant.blur();
           }
-        })
+          });
       }
-      this.initializeDialog()
+          this.initializeDialog();
       this.$nextTick(() => {
-        clipPath.setAttribute('d', this.clipPath())
-        this.$dispatch('tutorial::render')
-      })
-      clipPath.setAttribute('d', this.clipPath())
+          clipPath.setAttribute("d", this.clipPath());
+          this.$dispatch("tutorial::render");
+      });
+          clipPath.setAttribute("d", this.clipPath());
     },
     timeouts: [],
-    configure: function () {
-      document.addEventListener('keydown', function (event) {
-        const key2 = event.key
-        const isShiftKey = event.shiftKey
-        const isCtrlKey = false
-        const isAltKey = false
-        if (key2 === 'Tab') {
-          event.preventDefault()
+      configure: function () {
+          document.addEventListener("keydown", function (event) {
+              var key2 = event.key;
+              var isShiftKey = event.shiftKey;
+              var isCtrlKey = false;
+              var isAltKey = false;
+              if (key2 === "Tab") {
+                  event.preventDefault();
         }
-      })
+          });
       if (this.target instanceof HTMLSelectElement) {
-        if (this.target.hasAttribute('data-choice')) {
-          this.target = this.target.parentElement.parentElement
-          const dropdown = this.target.querySelector(
-            '.choices__list.choices__list--dropdown'
-          )
-          dropdown.style.zIndex = 100
+          if (this.target.hasAttribute("data-choice")) {
+              this.target = this.target.parentElement.parentElement;
+              const dropdown = this.target.querySelector(".choices__list.choices__list--dropdown");
+              dropdown.style.zIndex = 100;
         }
       }
-      if (this.target.tagName === 'TRIX-EDITOR') {
-        this.timeouts.trix = this.target.clientHeight
-        this.target = this.target.parentElement
-        const observer = new MutationObserver(
-          (mutationsList, observer2) => {
-            mutationsList.forEach((mutation) => {
-              if (this.timeouts.trix) {
-                clearTimeout(this.timeouts.trix)
-              }
-              this.timeouts.trix = setTimeout(() => {
-                this.timeouts.trix = null
-                this.init()
-              }, 500)
-            })
-          }
-        )
+          if (this.target.tagName === "TRIX-EDITOR") {
+              this.timeouts["trix"] = this.target.clientHeight;
+              this.target = this.target.parentElement;
+              const observer = new MutationObserver((mutationsList, observer2) => {
+                  mutationsList.forEach((mutation) => {
+                      if (this.timeouts["trix"]) {
+                          clearTimeout(this.timeouts["trix"]);
+                      }
+                      this.timeouts["trix"] = setTimeout(() => {
+                          this.timeouts["trix"] = null;
+                          this.init();
+                      }, 500);
+                  });
+              });
         const config = {
           attributes: true,
-          attributeFilter: ['height'],
+            attributeFilter: ["height"],
           childList: true,
           subtree: true
-        }
-        observer.observe(this.target, config)
+        };
+              observer.observe(this.target, config);
       }
       if (this.target instanceof HTMLTextAreaElement || this.t) {
-        let initialWidth = this.target.offsetWidth
-        let initialHeight = this.target.offsetHeight
+          let initialWidth = this.target.offsetWidth;
+          let initialHeight = this.target.offsetHeight;
         const observer = new MutationObserver(() => {
-          if (
-            this.target.offsetWidth !== initialWidth ||
-                        this.target.offsetHeight !== initialHeight
-          ) {
-            initialWidth = this.target.offsetWidth
-            initialHeight = this.target.offsetHeight
-            if (this.timeouts.textarea) {
-              clearTimeout(this.timeouts.textarea)
+            if (this.target.offsetWidth !== initialWidth || this.target.offsetHeight !== initialHeight) {
+                initialWidth = this.target.offsetWidth;
+                initialHeight = this.target.offsetHeight;
+                if (this.timeouts["textarea"]) {
+                    clearTimeout(this.timeouts["textarea"]);
             }
-            this.timeouts.textarea = setTimeout(() => {
-              this.timeouts.textarea = null
-              this.init()
-            }, 100)
+                this.timeouts["textarea"] = setTimeout(() => {
+                    this.timeouts["textarea"] = null;
+                    this.init();
+                }, 100);
           }
-        })
-        observer.observe(this.target, {
-          attributes: true,
-          attributeFilter: ['style']
-        })
+        });
+          observer.observe(this.target, {attributes: true, attributeFilter: ["style"]});
       }
     },
     // You can define any other Alpine.js functions here.
-    initializeDialog: function (dialog = null) {
+      initializeDialog: function (dialog = null) {
       if (!dialog) {
-        dialog = this.$el.querySelector('[data-dialog]')
+          dialog = this.$el.querySelector("[data-dialog]");
       }
-      const dialogPath = dialog.querySelector('[data-dialog-path]')
-      const rect = this.elementRect()
-      const stroke = dialog.querySelector('[data-dialog-stroke]')
+          const dialogPath = dialog.querySelector("[data-dialog-path]");
+          const rect = this.elementRect();
+          const stroke = dialog.querySelector("[data-dialog-stroke]");
       window.scrollTo({
         top: rect[0].y - window.innerHeight / 3,
         left: rect[0].x,
-        behavior: 'smooth'
-      })
-      const width = rect[1].x - rect[0].x
-      const height = rect[2].y - rect[0].y
-      const x = rect[0].x
-      const y = rect[0].y
-      dialog.style.width = `${width}px`
-      dialog.style.transform = `translate(${x}px, ${y}px)`
-      stroke.style.height = `${height}px`
-      dialogPath.setAttribute(
-        'd',
-        this.elementPath(null, { relative: true, positive: true })
-      )
+          behavior: "smooth"
+      });
+          const width = rect[1].x - rect[0].x;
+          const height = rect[2].y - rect[0].y;
+          const x = rect[0].x;
+          const y = rect[0].y;
+          dialog.style.width = `${width}px`;
+          dialog.style.transform = `translate(${x}px, ${y}px)`;
+          stroke.style.height = `${height}px`;
+          dialogPath.setAttribute("d", this.elementPath(null, {relative: true, positive: true}));
     },
-    clipPath: function (element = null, options = {}) {
-      element = element || this.target
+      clipPath: function (element = null, options = {}) {
+          element = element || this.target;
       options = {
         radius: 24,
         margin: 10,
         offset: { x: 0, y: 0 },
         relative: false,
         ...options
-      }
-      return `${this.windowPath()} ${this.elementPath(element, options)}`.trim()
+      };
+          return `${this.windowPath()} ${this.elementPath(element, options)}`.trim();
     },
-    windowPath: function () {
+      windowPath: function () {
       const documentHeight = Math.max(
         document.documentElement.clientHeight,
         document.documentElement.scrollHeight,
         document.documentElement.offsetHeight
-      )
-      let path = 'M 0 0 '
-      path += 'L 0 ' + documentHeight + ' '
-      path += 'L ' + window.innerWidth + ' ' + documentHeight + ' '
-      path += 'L ' + window.innerWidth + ' 0 '
-      path += 'L 0 0 '
-      return path.trim()
+      );
+          let path = "M 0 0 ";
+          path += "L 0 " + documentHeight + " ";
+          path += "L " + window.innerWidth + " " + documentHeight + " ";
+          path += "L " + window.innerWidth + " 0 ";
+          path += "L 0 0 ";
+          return path.trim();
     },
-    findElement: function (name) {
-      return (
-        document.querySelector(
-          selector.replace(/\\/g, '\\\\').replace(/\./g, '\\$&')
-        ) ?? document.querySelector(selector)
-      )
+      findElement: function (name) {
+          return document.querySelector(selector.replace(/\./g, "\\$&")) ?? document.querySelector(selector);
     },
-    elementPath: function (element = null, options = {}) {
-      element = element || this.target
+      elementPath: function (element = null, options = {}) {
+          element = element || this.target;
       options = {
         radius: 24,
         margin: 10,
         offset: { x: 0, y: 0 },
         ...options
-      }
+      };
       const rect = this.elementRect(element, {
         relative: false,
         ...options
-      })
-      let path = ''
-      path += 'M ' + rect[0].x + ' ' + (rect[0].y + options.radius) + ' '
-      path +=
-                'C ' +
-                rect[0].x +
-                ' ' +
-                rect[0].y +
-                ' ' +
-                rect[0].x +
-                ' ' +
-                rect[0].y +
-                ' ' +
-                (rect[0].x + options.radius) +
-                ' ' +
-                rect[0].y +
-                ' '
-      path += 'L ' + (rect[1].x - options.radius) + ' ' + rect[1].y + ' '
-      path +=
-                'C ' +
-                rect[1].x +
-                ' ' +
-                rect[1].y +
-                ' ' +
-                rect[1].x +
-                ' ' +
-                rect[1].y +
-                ' ' +
-                rect[1].x +
-                ' ' +
-                (rect[1].y + options.radius) +
-                ' '
-      path += 'L ' + rect[2].x + ' ' + (rect[2].y - options.radius) + ' '
-      path +=
-                'C ' +
-                rect[2].x +
-                ' ' +
-                rect[2].y +
-                ' ' +
-                rect[2].x +
-                ' ' +
-                rect[2].y +
-                ' ' +
-                (rect[2].x - options.radius) +
-                ' ' +
-                rect[2].y +
-                ' '
-      path += 'L ' + (rect[3].x + options.radius) + ' ' + rect[3].y + ' '
-      path +=
-                'C ' +
-                rect[3].x +
-                ' ' +
-                rect[3].y +
-                ' ' +
-                rect[3].x +
-                ' ' +
-                rect[3].y +
-                ' ' +
-                rect[3].x +
-                ' ' +
-                (rect[3].y - options.radius) +
-                ' '
-      path += 'L ' + rect[0].x + ' ' + (rect[0].y + options.radius) + ' '
-      return path.trim()
+      });
+          let path = "";
+          path += "M " + rect[0].x + " " + (rect[0].y + options.radius) + " ";
+          path += "C " + rect[0].x + " " + rect[0].y + " " + rect[0].x + " " + rect[0].y + " " + (rect[0].x + options.radius) + " " + rect[0].y + " ";
+          path += "L " + (rect[1].x - options.radius) + " " + rect[1].y + " ";
+          path += "C " + rect[1].x + " " + rect[1].y + " " + rect[1].x + " " + rect[1].y + " " + rect[1].x + " " + (rect[1].y + options.radius) + " ";
+          path += "L " + rect[2].x + " " + (rect[2].y - options.radius) + " ";
+          path += "C " + rect[2].x + " " + rect[2].y + " " + rect[2].x + " " + rect[2].y + " " + (rect[2].x - options.radius) + " " + rect[2].y + " ";
+          path += "L " + (rect[3].x + options.radius) + " " + rect[3].y + " ";
+          path += "C " + rect[3].x + " " + rect[3].y + " " + rect[3].x + " " + rect[3].y + " " + rect[3].x + " " + (rect[3].y - options.radius) + " ";
+          path += "L " + rect[0].x + " " + (rect[0].y + options.radius) + " ";
+          return path.trim();
     },
-    elementRect: function (element = null, options = {}) {
-      element = element || this.target
-      const bounds = element.getBoundingClientRect()
+      elementRect: function (element = null, options = {}) {
+          element = element || this.target;
+          const bounds = element.getBoundingClientRect();
       options = {
         radius: 24,
         margin: 10,
         offset: { x: 0, y: 0 },
         relative: false,
         ...options
-      }
-      const left = options.relative ? 0 : bounds.left
-      const top = options.relative ? 0 : element.offsetTop
-      const result = [
+      };
+          const left = options.relative ? 0 : bounds.left;
+          const top = options.relative ? 0 : element.offsetTop;
+          let result = [
         {
           x: left - options.margin + options.offset.x,
           y: top - options.margin + options.offset.y
         },
         {
-          x:
-                        left +
-                        element.clientWidth +
-                        options.margin +
-                        options.offset.x,
+            x: left + element.clientWidth + options.margin + options.offset.x,
           y: top - options.margin + options.offset.y
         },
         {
-          x:
-                        left +
-                        element.clientWidth +
-                        options.margin +
-                        options.offset.x,
-          y:
-                        top +
-                        element.clientHeight +
-                        options.margin +
-                        options.offset.y
+            x: left + element.clientWidth + options.margin + options.offset.x,
+            y: top + element.clientHeight + options.margin + options.offset.y
         },
         {
           x: left - options.margin + options.offset.x,
-          y:
-                        top +
-                        element.clientHeight +
-                        options.margin +
-                        options.offset.y
+            y: top + element.clientHeight + options.margin + options.offset.y
         }
-      ]
+          ];
       if (options.positive) {
-        let minX = 0
-        let minY = 0
+          let minX = 0;
+          let minY = 0;
         for (let i = 0; i < result.length; i++) {
           if (result[i].x < minX) {
-            minX = result[i].x
+              minX = result[i].x;
           }
           if (result[i].y < minY) {
-            minY = result[i].y
+              minY = result[i].y;
           }
         }
         for (let i = 0; i < result.length; i++) {
-          result[i].x -= minX
-          result[i].y -= minY
+            result[i].x -= minX;
+            result[i].y -= minY;
         }
       }
-      return result
+          return result;
     }
-  }
+  };
 }
 
-export { stepComponent as default }
-// # sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vY29tcG9uZW50cy9zdGVwLmpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBzdGVwQ29tcG9uZW50KHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkSW50ZXJjZXB0Q2xpY2ssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmNlcHRDbGlja0FjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIHRhcmdldDogbnVsbCxcblxuICAgICAgICBzbGVlcDogZnVuY3Rpb24gKG1zKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaW5pdDogYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy50YXJnZXQgPSB0aGlzLmZpbmRFbGVtZW50KGtleSk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy50YXJnZXQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUdXRvcmlhbCBzdGVwIHdhcyBub3QgZm91bmQ6Jywga2V5KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHdpbmRvdy5ibHVyKCk7XG4gICAgICAgICAgICAvLyBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuYmx1cigpO1xuICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0JylcbiAgICAgICAgICAgICAgICAuZm9yRWFjaCgoZWxlbWVudCkgPT4gZWxlbWVudC5ibHVyKCkpO1xuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXQuZm9jdXMoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jb25maWd1cmUoKTtcblxuICAgICAgICAgICAgY29uc3QgZGlhbG9nID0gdGhpcy4kZWwucXVlcnlTZWxlY3RvcignW2RhdGEtZGlhbG9nXScpO1xuICAgICAgICAgICAgY29uc3QgY2xpcFBhdGggPSB0aGlzLiRlbC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1jbGlwLXBhdGhdJyk7XG5cbiAgICAgICAgICAgIGlmIChzaG91bGRJbnRlcmNlcHRDbGljaykge1xuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJHdpcmUuY2FsbChpbnRlcmNlcHRDbGlja0FjdGlvbik7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy50YXJnZXQuYmx1cigpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZXNjZW5kYW50cyA9IHRoaXMudGFyZ2V0LnF1ZXJ5U2VsZWN0b3JBbGwoXCI6aG92ZXJcIik7XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXNjZW5kYW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVzY2VuZGFudCA9IGRlc2NlbmRhbnRzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY2VuZGFudC5ibHVyKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplRGlhbG9nKCk7XG5cbiAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjbGlwUGF0aC5zZXRBdHRyaWJ1dGUoJ2QnLCB0aGlzLmNsaXBQYXRoKCkpO1xuICAgICAgICAgICAgICAgIHRoaXMuJGRpc3BhdGNoKCd0dXRvcmlhbDo6cmVuZGVyJyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2xpcFBhdGguc2V0QXR0cmlidXRlKCdkJywgdGhpcy5jbGlwUGF0aCgpKTtcbiAgICAgICAgfSxcblxuICAgICAgICB0aW1lb3V0czogW10sXG5cbiAgICAgICAgY29uZmlndXJlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBrZXkgY29kZSBvZiB0aGUga2V5IHByZXNzZWRcbiAgICAgICAgICAgICAgICB2YXIga2V5ID0gZXZlbnQua2V5O1xuXG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBzdGF0ZSBvZiB0aGUgbW9kaWZpZXIga2V5c1xuICAgICAgICAgICAgICAgIC8vIHZhciBpc0N0cmxLZXkgPSBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XG4gICAgICAgICAgICAgICAgLy8gdmFyIGlzQWx0S2V5ID0gZXZlbnQuYWx0S2V5O1xuICAgICAgICAgICAgICAgIHZhciBpc1NoaWZ0S2V5ID0gZXZlbnQuc2hpZnRLZXk7XG4gICAgICAgICAgICAgICAgdmFyIGlzQ3RybEtleSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHZhciBpc0FsdEtleSA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgYW55IGNvbWJpbmF0aW9uIG9mIG1vZGlmaWVyIGtleXMgYW5kIG5vcm1hbCBrZXlzIHdlcmUgcHJlc3NlZFxuICAgICAgICAgICAgICAgIC8vIGlmIChpc0N0cmxLZXkgfHwgaXNBbHRLZXkgfHwgaXNTaGlmdEtleSB8fCBrZXkgPT09ICdUYWInKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgKGtleSA9PT0gJ1RhYicgfHwgaXNTaGlmdEtleSAmJiBrZXkgPT09ICdUYWInKSB7XG4gICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gJ1RhYicpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8gUHJldmVudCB0aGUgZGVmYXVsdCBldmVudCBiZWhhdmlvclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnZGF0YS1jaG9pY2UnKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhcmdldCA9IHRoaXMudGFyZ2V0LnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZHJvcGRvd24gPSB0aGlzLnRhcmdldC5xdWVyeVNlbGVjdG9yKCcuY2hvaWNlc19fbGlzdC5jaG9pY2VzX19saXN0LS1kcm9wZG93bicpO1xuICAgICAgICAgICAgICAgICAgICBkcm9wZG93bi5zdHlsZS56SW5kZXggPSAxMDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQudGFnTmFtZSA9PT0gJ1RSSVgtRURJVE9SJykge1xuICAgICAgICAgICAgICAgIHRoaXMudGltZW91dHNbJ3RyaXgnXSA9IHRoaXMudGFyZ2V0LmNsaWVudEhlaWdodDtcbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldCA9IHRoaXMudGFyZ2V0LnBhcmVudEVsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnNMaXN0LCBvYnNlcnZlcikgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIG11dGF0aW9uc0xpc3QuZm9yRWFjaCgobXV0YXRpb24pID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudGltZW91dHNbJ3RyaXgnXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXRzWyd0cml4J10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbWVvdXRzWyd0cml4J10gPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbWVvdXRzWyd0cml4J10gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUZpbHRlcjogWydoZWlnaHQnXSxcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRMaXN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBzdWJ0cmVlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vYnNlcnZlKHRoaXMudGFyZ2V0LCBjb25maWcpO1xuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxUZXh0QXJlYUVsZW1lbnQgfHwgdGhpcy50KSB7XG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIHRleHRhcmVhXG4gICAgICAgICAgICAgICAgbGV0IGluaXRpYWxXaWR0aCA9IHRoaXMudGFyZ2V0Lm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgICAgIGxldCBpbml0aWFsSGVpZ2h0ID0gdGhpcy50YXJnZXQub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGEgTXV0YXRpb25PYnNlcnZlciB0byBtb25pdG9yIHNpemUgY2hhbmdlc1xuICAgICAgICAgICAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQub2Zmc2V0V2lkdGggIT09IGluaXRpYWxXaWR0aCB8fCB0aGlzLnRhcmdldC5vZmZzZXRIZWlnaHQgIT09IGluaXRpYWxIZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxXaWR0aCA9IHRoaXMudGFyZ2V0Lm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbEhlaWdodCA9IHRoaXMudGFyZ2V0Lm9mZnNldEhlaWdodDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudGltZW91dHNbJ3RleHRhcmVhJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0c1sndGV4dGFyZWEnXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGltZW91dHNbJ3RleHRhcmVhJ10gPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbWVvdXRzWyd0ZXh0YXJlYSddID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDEwMCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIFN0YXJ0IG9ic2VydmluZyBjaGFuZ2VzIGluIHRoZSB0ZXh0YXJlYSBlbGVtZW50XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLnRhcmdldCwge2F0dHJpYnV0ZXM6IHRydWUsIGF0dHJpYnV0ZUZpbHRlcjogWydzdHlsZSddfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIFlvdSBjYW4gZGVmaW5lIGFueSBvdGhlciBBbHBpbmUuanMgZnVuY3Rpb25zIGhlcmUuXG5cbiAgICAgICAgaW5pdGlhbGl6ZURpYWxvZzogZnVuY3Rpb24gKGRpYWxvZyA9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICghZGlhbG9nKSB7XG4gICAgICAgICAgICAgICAgZGlhbG9nID0gdGhpcy4kZWwucXVlcnlTZWxlY3RvcignW2RhdGEtZGlhbG9nXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZGlhbG9nUGF0aCA9IGRpYWxvZy5xdWVyeVNlbGVjdG9yKCdbZGF0YS1kaWFsb2ctcGF0aF0nKTtcblxuICAgICAgICAgICAgY29uc3QgcmVjdCA9IHRoaXMuZWxlbWVudFJlY3QoKTtcbiAgICAgICAgICAgIC8vIGNvbnN0IGhlYWRlciA9IGRpYWxvZy5xdWVyeVNlbGVjdG9yKCdbZGF0YS1kaWFsb2ctaGVhZGVyXScpO1xuICAgICAgICAgICAgY29uc3Qgc3Ryb2tlID0gZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLWRpYWxvZy1zdHJva2VdJyk7XG5cbiAgICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbyh7XG4gICAgICAgICAgICAgICAgdG9wOiByZWN0WzBdLnkgLSAod2luZG93LmlubmVySGVpZ2h0IC8gMyksXG4gICAgICAgICAgICAgICAgbGVmdDogcmVjdFswXS54LFxuICAgICAgICAgICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJ1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHdpZHRoID0gcmVjdFsxXS54IC0gcmVjdFswXS54O1xuICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gcmVjdFsyXS55IC0gcmVjdFswXS55O1xuXG4gICAgICAgICAgICBjb25zdCB4ID0gcmVjdFswXS54O1xuICAgICAgICAgICAgY29uc3QgeSA9IHJlY3RbMF0ueTtcbiAgICAgICAgICAgIGRpYWxvZy5zdHlsZS53aWR0aCA9IGAke3dpZHRofXB4YDtcbiAgICAgICAgICAgIGRpYWxvZy5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7eH1weCwgJHt5fXB4KWA7XG4gICAgICAgICAgICBzdHJva2Uuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcblxuICAgICAgICAgICAgZGlhbG9nUGF0aC5zZXRBdHRyaWJ1dGUoJ2QnLCB0aGlzLmVsZW1lbnRQYXRoKG51bGwsIHtyZWxhdGl2ZTogdHJ1ZSwgcG9zaXRpdmU6IHRydWV9KSlcbiAgICAgICAgfSxcblxuICAgICAgICBjbGlwUGF0aDogZnVuY3Rpb24gKGVsZW1lbnQgPSBudWxsLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50IHx8IHRoaXMudGFyZ2V0O1xuICAgICAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICByYWRpdXM6IDI0LFxuICAgICAgICAgICAgICAgIG1hcmdpbjogMTAsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiB7eDogMCwgeTogMH0sXG4gICAgICAgICAgICAgICAgcmVsYXRpdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIC4uLm9wdGlvbnNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBgJHt0aGlzLndpbmRvd1BhdGgoKX0gJHt0aGlzLmVsZW1lbnRQYXRoKGVsZW1lbnQsIG9wdGlvbnMpfWAudHJpbSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHdpbmRvd1BhdGg6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGRvY3VtZW50SGVpZ2h0ID0gTWF0aC5tYXgoXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCxcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsSGVpZ2h0LFxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5vZmZzZXRIZWlnaHQsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBUT0RPOiBhZGQgb3B0aW9uIHRvIHNlbGVjdCBjbG9ja3dpc2UgL2NvdW50ZXIgY2xvY2t3aXNlXG4gICAgICAgICAgICAvL00gMCA4IEMgMCAwIDAgMCA4IDAgTCAzOCAwIEMgNDYgMCA0NiAwIDQ2IDggQyA0NiAxNiA0NiAxNiAzOCAxNiBMIDggMTYgQyAwIDE2IDAgMTYgMCA4XG4gICAgICAgICAgICBsZXQgcGF0aCA9ICdNIDAgMCAnO1xuICAgICAgICAgICAgcGF0aCArPSAnTCAwICcgKyBkb2N1bWVudEhlaWdodCArICcgJztcbiAgICAgICAgICAgIHBhdGggKz0gJ0wgJyArIHdpbmRvdy5pbm5lcldpZHRoICsgJyAnICsgZG9jdW1lbnRIZWlnaHQgKyAnICc7XG4gICAgICAgICAgICBwYXRoICs9ICdMICcgKyB3aW5kb3cuaW5uZXJXaWR0aCArICcgMCAnO1xuICAgICAgICAgICAgcGF0aCArPSAnTCAwIDAgJztcblxuICAgICAgICAgICAgcmV0dXJuIHBhdGgudHJpbSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmRFbGVtZW50OiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IucmVwbGFjZSgvXFwuL2csICdcXFxcJCYnKSlcbiAgICAgICAgICAgICAgICA/PyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgfSxcblxuICAgICAgICBlbGVtZW50UGF0aDogZnVuY3Rpb24gKGVsZW1lbnQgPSBudWxsLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50IHx8IHRoaXMudGFyZ2V0O1xuICAgICAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICByYWRpdXM6IDI0LFxuICAgICAgICAgICAgICAgIG1hcmdpbjogMTAsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiB7eDogMCwgeTogMH0sXG4gICAgICAgICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmVjdCA9IHRoaXMuZWxlbWVudFJlY3QoZWxlbWVudCwge1xuICAgICAgICAgICAgICAgIHJlbGF0aXZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGxldCBwYXRoID0gJyc7XG4gICAgICAgICAgICBwYXRoICs9ICdNICcgKyByZWN0WzBdLnggKyAnICcgKyAocmVjdFswXS55ICsgb3B0aW9ucy5yYWRpdXMpICsgJyAnO1xuICAgICAgICAgICAgcGF0aCArPSAnQyAnICsgcmVjdFswXS54ICsgJyAnICsgcmVjdFswXS55ICsgJyAnICsgcmVjdFswXS54ICsgJyAnICsgcmVjdFswXS55ICsgJyAnICsgKHJlY3RbMF0ueCArIG9wdGlvbnMucmFkaXVzKSArICcgJyArIHJlY3RbMF0ueSArICcgJztcbiAgICAgICAgICAgIHBhdGggKz0gJ0wgJyArIChyZWN0WzFdLnggLSBvcHRpb25zLnJhZGl1cykgKyAnICcgKyByZWN0WzFdLnkgKyAnICc7XG4gICAgICAgICAgICBwYXRoICs9ICdDICcgKyByZWN0WzFdLnggKyAnICcgKyByZWN0WzFdLnkgKyAnICcgKyByZWN0WzFdLnggKyAnICcgKyByZWN0WzFdLnkgKyAnICcgKyByZWN0WzFdLnggKyAnICcgKyAocmVjdFsxXS55ICsgb3B0aW9ucy5yYWRpdXMpICsgJyAnO1xuICAgICAgICAgICAgcGF0aCArPSAnTCAnICsgcmVjdFsyXS54ICsgJyAnICsgKHJlY3RbMl0ueSAtIG9wdGlvbnMucmFkaXVzKSArICcgJztcbiAgICAgICAgICAgIHBhdGggKz0gJ0MgJyArIHJlY3RbMl0ueCArICcgJyArIHJlY3RbMl0ueSArICcgJyArIHJlY3RbMl0ueCArICcgJyArIHJlY3RbMl0ueSArICcgJyArIChyZWN0WzJdLnggLSBvcHRpb25zLnJhZGl1cykgKyAnICcgKyByZWN0WzJdLnkgKyAnICc7XG4gICAgICAgICAgICBwYXRoICs9ICdMICcgKyAocmVjdFszXS54ICsgb3B0aW9ucy5yYWRpdXMpICsgJyAnICsgcmVjdFszXS55ICsgJyAnO1xuICAgICAgICAgICAgcGF0aCArPSAnQyAnICsgcmVjdFszXS54ICsgJyAnICsgcmVjdFszXS55ICsgJyAnICsgcmVjdFszXS54ICsgJyAnICsgcmVjdFszXS55ICsgJyAnICsgcmVjdFszXS54ICsgJyAnICsgKHJlY3RbM10ueSAtIG9wdGlvbnMucmFkaXVzKSArICcgJztcbiAgICAgICAgICAgIC8vIHBhdGggKz0gJ1onO1xuICAgICAgICAgICAgcGF0aCArPSAnTCAnICsgcmVjdFswXS54ICsgJyAnICsgKHJlY3RbMF0ueSArIG9wdGlvbnMucmFkaXVzKSArICcgJztcblxuICAgICAgICAgICAgcmV0dXJuIHBhdGgudHJpbSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGVsZW1lbnRSZWN0OiBmdW5jdGlvbiAoZWxlbWVudCA9IG51bGwsIG9wdGlvbnMgPSB7fSkge1xuXG4gICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudCB8fCB0aGlzLnRhcmdldDtcbiAgICAgICAgICAgIGNvbnN0IGJvdW5kcyA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIHJhZGl1czogMjQsXG4gICAgICAgICAgICAgICAgbWFyZ2luOiAxMCxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IHt4OiAwLCB5OiAwfSxcbiAgICAgICAgICAgICAgICByZWxhdGl2ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbGVmdCA9IG9wdGlvbnMucmVsYXRpdmUgPyAwIDogYm91bmRzLmxlZnQ7XG4gICAgICAgICAgICBjb25zdCB0b3AgPSBvcHRpb25zLnJlbGF0aXZlID8gMCA6IGVsZW1lbnQub2Zmc2V0VG9wO1xuXG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgeDogbGVmdCAtIG9wdGlvbnMubWFyZ2luICsgb3B0aW9ucy5vZmZzZXQueCxcbiAgICAgICAgICAgICAgICAgICAgeTogdG9wIC0gb3B0aW9ucy5tYXJnaW4gKyBvcHRpb25zLm9mZnNldC55XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHg6IGxlZnQgKyBlbGVtZW50LmNsaWVudFdpZHRoICsgb3B0aW9ucy5tYXJnaW4gKyBvcHRpb25zLm9mZnNldC54LFxuICAgICAgICAgICAgICAgICAgICB5OiB0b3AgLSBvcHRpb25zLm1hcmdpbiArIG9wdGlvbnMub2Zmc2V0LnlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgeDogbGVmdCArIGVsZW1lbnQuY2xpZW50V2lkdGggKyBvcHRpb25zLm1hcmdpbiArIG9wdGlvbnMub2Zmc2V0LngsXG4gICAgICAgICAgICAgICAgICAgIHk6IHRvcCArIGVsZW1lbnQuY2xpZW50SGVpZ2h0ICsgb3B0aW9ucy5tYXJnaW4gKyBvcHRpb25zLm9mZnNldC55XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHg6IGxlZnQgLSBvcHRpb25zLm1hcmdpbiArIG9wdGlvbnMub2Zmc2V0LngsXG4gICAgICAgICAgICAgICAgICAgIHk6IHRvcCArIGVsZW1lbnQuY2xpZW50SGVpZ2h0ICsgb3B0aW9ucy5tYXJnaW4gKyBvcHRpb25zLm9mZnNldC55XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMucG9zaXRpdmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgbWluWCA9IDA7XG4gICAgICAgICAgICAgICAgbGV0IG1pblkgPSAwO1xuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdFtpXS54IDwgbWluWCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluWCA9IHJlc3VsdFtpXS54O1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdFtpXS55IDwgbWluWSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluWSA9IHJlc3VsdFtpXS55O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldLnggLT0gbWluWDtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldLnkgLT0gbWluWTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9XG59Il0sCiAgIm1hcHBpbmdzIjogIjtBQUFlLFNB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
+export {
+    stepComponent as default
+};
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vY29tcG9uZW50cy9zdGVwLmpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBzdGVwQ29tcG9uZW50KHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkSW50ZXJjZXB0Q2xpY2ssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmNlcHRDbGlja0FjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIHRhcmdldDogbnVsbCxcblxuICAgICAgICBzbGVlcDogZnVuY3Rpb24gKG1zKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaW5pdDogYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy50YXJnZXQgPSB0aGlzLmZpbmRFbGVtZW50KGtleSk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy50YXJnZXQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUdXRvcmlhbCBzdGVwIHdhcyBub3QgZm91bmQ6Jywga2V5KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHdpbmRvdy5ibHVyKCk7XG4gICAgICAgICAgICAvLyBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuYmx1cigpO1xuICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0JylcbiAgICAgICAgICAgICAgICAuZm9yRWFjaCgoZWxlbWVudCkgPT4gZWxlbWVudC5ibHVyKCkpO1xuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXQuZm9jdXMoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jb25maWd1cmUoKTtcblxuICAgICAgICAgICAgY29uc3QgZGlhbG9nID0gdGhpcy4kZWwucXVlcnlTZWxlY3RvcignW2RhdGEtZGlhbG9nXScpO1xuICAgICAgICAgICAgY29uc3QgY2xpcFBhdGggPSB0aGlzLiRlbC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1jbGlwLXBhdGhdJyk7XG5cbiAgICAgICAgICAgIGlmIChzaG91bGRJbnRlcmNlcHRDbGljaykge1xuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJHdpcmUuY2FsbChpbnRlcmNlcHRDbGlja0FjdGlvbik7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy50YXJnZXQuYmx1cigpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZXNjZW5kYW50cyA9IHRoaXMudGFyZ2V0LnF1ZXJ5U2VsZWN0b3JBbGwoXCI6aG92ZXJcIik7XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXNjZW5kYW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVzY2VuZGFudCA9IGRlc2NlbmRhbnRzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY2VuZGFudC5ibHVyKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplRGlhbG9nKCk7XG5cbiAgICAgICAgICAgIHRoaXMuJG5leHRUaWNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjbGlwUGF0aC5zZXRBdHRyaWJ1dGUoJ2QnLCB0aGlzLmNsaXBQYXRoKCkpO1xuICAgICAgICAgICAgICAgIHRoaXMuJGRpc3BhdGNoKCd0dXRvcmlhbDo6cmVuZGVyJyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2xpcFBhdGguc2V0QXR0cmlidXRlKCdkJywgdGhpcy5jbGlwUGF0aCgpKTtcbiAgICAgICAgfSxcblxuICAgICAgICB0aW1lb3V0czogW10sXG5cbiAgICAgICAgY29uZmlndXJlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBrZXkgY29kZSBvZiB0aGUga2V5IHByZXNzZWRcbiAgICAgICAgICAgICAgICB2YXIga2V5ID0gZXZlbnQua2V5O1xuXG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBzdGF0ZSBvZiB0aGUgbW9kaWZpZXIga2V5c1xuICAgICAgICAgICAgICAgIC8vIHZhciBpc0N0cmxLZXkgPSBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XG4gICAgICAgICAgICAgICAgLy8gdmFyIGlzQWx0S2V5ID0gZXZlbnQuYWx0S2V5O1xuICAgICAgICAgICAgICAgIHZhciBpc1NoaWZ0S2V5ID0gZXZlbnQuc2hpZnRLZXk7XG4gICAgICAgICAgICAgICAgdmFyIGlzQ3RybEtleSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHZhciBpc0FsdEtleSA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgYW55IGNvbWJpbmF0aW9uIG9mIG1vZGlmaWVyIGtleXMgYW5kIG5vcm1hbCBrZXlzIHdlcmUgcHJlc3NlZFxuICAgICAgICAgICAgICAgIC8vIGlmIChpc0N0cmxLZXkgfHwgaXNBbHRLZXkgfHwgaXNTaGlmdEtleSB8fCBrZXkgPT09ICdUYWInKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgKGtleSA9PT0gJ1RhYicgfHwgaXNTaGlmdEtleSAmJiBrZXkgPT09ICdUYWInKSB7XG4gICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gJ1RhYicpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8gUHJldmVudCB0aGUgZGVmYXVsdCBldmVudCBiZWhhdmlvclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnZGF0YS1jaG9pY2UnKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhcmdldCA9IHRoaXMudGFyZ2V0LnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZHJvcGRvd24gPSB0aGlzLnRhcmdldC5xdWVyeVNlbGVjdG9yKCcuY2hvaWNlc19fbGlzdC5jaG9pY2VzX19saXN0LS1kcm9wZG93bicpO1xuICAgICAgICAgICAgICAgICAgICBkcm9wZG93bi5zdHlsZS56SW5kZXggPSAxMDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy50YXJnZXQudGFnTmFtZSA9PT0gJ1RSSVgtRURJVE9SJykge1xuICAgICAgICAgICAgICAgIHRoaXMudGltZW91dHNbJ3RyaXgnXSA9IHRoaXMudGFyZ2V0LmNsaWVudEhlaWdodDtcbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldCA9IHRoaXMudGFyZ2V0LnBhcmVudEVsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnNMaXN0LCBvYnNlcnZlcikgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIG11dGF0aW9uc0xpc3QuZm9yRWFjaCgobXV0YXRpb24pID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudGltZW91dHNbJ3RyaXgnXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXRzWyd0cml4J10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbWVvdXRzWyd0cml4J10gPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbWVvdXRzWyd0cml4J10gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUZpbHRlcjogWydoZWlnaHQnXSxcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRMaXN0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBzdWJ0cmVlOiB0cnVlLFxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vYnNlcnZlKHRoaXMudGFyZ2V0LCBjb25maWcpO1xuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxUZXh0QXJlYUVsZW1lbnQgfHwgdGhpcy50KSB7XG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIHRleHRhcmVhXG4gICAgICAgICAgICAgICAgbGV0IGluaXRpYWxXaWR0aCA9IHRoaXMudGFyZ2V0Lm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgICAgIGxldCBpbml0aWFsSGVpZ2h0ID0gdGhpcy50YXJnZXQub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGEgTXV0YXRpb25PYnNlcnZlciB0byBtb25pdG9yIHNpemUgY2hhbmdlc1xuICAgICAgICAgICAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50YXJnZXQub2Zmc2V0V2lkdGggIT09IGluaXRpYWxXaWR0aCB8fCB0aGlzLnRhcmdldC5vZmZzZXRIZWlnaHQgIT09IGluaXRpYWxIZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxXaWR0aCA9IHRoaXMudGFyZ2V0Lm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbEhlaWdodCA9IHRoaXMudGFyZ2V0Lm9mZnNldEhlaWdodDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudGltZW91dHNbJ3RleHRhcmVhJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0c1sndGV4dGFyZWEnXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGltZW91dHNbJ3RleHRhcmVhJ10gPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbWVvdXRzWyd0ZXh0YXJlYSddID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDEwMCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIFN0YXJ0IG9ic2VydmluZyBjaGFuZ2VzIGluIHRoZSB0ZXh0YXJlYSBlbGVtZW50XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLnRhcmdldCwge2F0dHJpYnV0ZXM6IHRydWUsIGF0dHJpYnV0ZUZpbHRlcjogWydzdHlsZSddfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIFlvdSBjYW4gZGVmaW5lIGFueSBvdGhlciBBbHBpbmUuanMgZnVuY3Rpb25zIGhlcmUuXG5cbiAgICAgICAgaW5pdGlhbGl6ZURpYWxvZzogZnVuY3Rpb24gKGRpYWxvZyA9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICghZGlhbG9nKSB7XG4gICAgICAgICAgICAgICAgZGlhbG9nID0gdGhpcy4kZWwucXVlcnlTZWxlY3RvcignW2RhdGEtZGlhbG9nXScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZGlhbG9nUGF0aCA9IGRpYWxvZy5xdWVyeVNlbGVjdG9yKCdbZGF0YS1kaWFsb2ctcGF0aF0nKTtcblxuICAgICAgICAgICAgY29uc3QgcmVjdCA9IHRoaXMuZWxlbWVudFJlY3QoKTtcbiAgICAgICAgICAgIC8vIGNvbnN0IGhlYWRlciA9IGRpYWxvZy5xdWVyeVNlbGVjdG9yKCdbZGF0YS1kaWFsb2ctaGVhZGVyXScpO1xuICAgICAgICAgICAgY29uc3Qgc3Ryb2tlID0gZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLWRpYWxvZy1zdHJva2VdJyk7XG5cbiAgICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbyh7XG4gICAgICAgICAgICAgICAgdG9wOiByZWN0WzBdLnkgLSAod2luZG93LmlubmVySGVpZ2h0IC8gMyksXG4gICAgICAgICAgICAgICAgbGVmdDogcmVjdFswXS54LFxuICAgICAgICAgICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJ1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHdpZHRoID0gcmVjdFsxXS54IC0gcmVjdFswXS54O1xuICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gcmVjdFsyXS55IC0gcmVjdFswXS55O1xuXG4gICAgICAgICAgICBjb25zdCB4ID0gcmVjdFswXS54O1xuICAgICAgICAgICAgY29uc3QgeSA9IHJlY3RbMF0ueTtcbiAgICAgICAgICAgIGRpYWxvZy5zdHlsZS53aWR0aCA9IGAke3dpZHRofXB4YDtcbiAgICAgICAgICAgIGRpYWxvZy5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7eH1weCwgJHt5fXB4KWA7XG4gICAgICAgICAgICBzdHJva2Uuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcblxuICAgICAgICAgICAgZGlhbG9nUGF0aC5zZXRBdHRyaWJ1dGUoJ2QnLCB0aGlzLmVsZW1lbnRQYXRoKG51bGwsIHtyZWxhdGl2ZTogdHJ1ZSwgcG9zaXRpdmU6IHRydWV9KSlcbiAgICAgICAgfSxcblxuICAgICAgICBjbGlwUGF0aDogZnVuY3Rpb24gKGVsZW1lbnQgPSBudWxsLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50IHx8IHRoaXMudGFyZ2V0O1xuICAgICAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICByYWRpdXM6IDI0LFxuICAgICAgICAgICAgICAgIG1hcmdpbjogMTAsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiB7eDogMCwgeTogMH0sXG4gICAgICAgICAgICAgICAgcmVsYXRpdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIC4uLm9wdGlvbnNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBgJHt0aGlzLndpbmRvd1BhdGgoKX0gJHt0aGlzLmVsZW1lbnRQYXRoKGVsZW1lbnQsIG9wdGlvbnMpfWAudHJpbSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHdpbmRvd1BhdGg6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGRvY3VtZW50SGVpZ2h0ID0gTWF0aC5tYXgoXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCxcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsSGVpZ2h0LFxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5vZmZzZXRIZWlnaHQsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBUT0RPOiBhZGQgb3B0aW9uIHRvIHNlbGVjdCBjbG9ja3dpc2UgL2NvdW50ZXIgY2xvY2t3aXNlXG4gICAgICAgICAgICAvL00gMCA4IEMgMCAwIDAgMCA4IDAgTCAzOCAwIEMgNDYgMCA0NiAwIDQ2IDggQyA0NiAxNiA0NiAxNiAzOCAxNiBMIDggMTYgQyAwIDE2IDAgMTYgMCA4XG4gICAgICAgICAgICBsZXQgcGF0aCA9ICdNIDAgMCAnO1xuICAgICAgICAgICAgcGF0aCArPSAnTCAwICcgKyBkb2N1bWVudEhlaWdodCArICcgJztcbiAgICAgICAgICAgIHBhdGggKz0gJ0wgJyArIHdpbmRvdy5pbm5lcldpZHRoICsgJyAnICsgZG9jdW1lbnRIZWlnaHQgKyAnICc7XG4gICAgICAgICAgICBwYXRoICs9ICdMICcgKyB3aW5kb3cuaW5uZXJXaWR0aCArICcgMCAnO1xuICAgICAgICAgICAgcGF0aCArPSAnTCAwIDAgJztcblxuICAgICAgICAgICAgcmV0dXJuIHBhdGgudHJpbSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZpbmRFbGVtZW50OiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IucmVwbGFjZSgvXFwuL2csICdcXFxcJCYnKSlcbiAgICAgICAgICAgICAgICA/PyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgICAgICAgfSxcblxuICAgICAgICBlbGVtZW50UGF0aDogZnVuY3Rpb24gKGVsZW1lbnQgPSBudWxsLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50IHx8IHRoaXMudGFyZ2V0O1xuICAgICAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICByYWRpdXM6IDI0LFxuICAgICAgICAgICAgICAgIG1hcmdpbjogMTAsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiB7eDogMCwgeTogMH0sXG4gICAgICAgICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcmVjdCA9IHRoaXMuZWxlbWVudFJlY3QoZWxlbWVudCwge1xuICAgICAgICAgICAgICAgIHJlbGF0aXZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGxldCBwYXRoID0gJyc7XG4gICAgICAgICAgICBwYXRoICs9ICdNICcgKyByZWN0WzBdLnggKyAnICcgKyAocmVjdFswXS55ICsgb3B0aW9ucy5yYWRpdXMpICsgJyAnO1xuICAgICAgICAgICAgcGF0aCArPSAnQyAnICsgcmVjdFswXS54ICsgJyAnICsgcmVjdFswXS55ICsgJyAnICsgcmVjdFswXS54ICsgJyAnICsgcmVjdFswXS55ICsgJyAnICsgKHJlY3RbMF0ueCArIG9wdGlvbnMucmFkaXVzKSArICcgJyArIHJlY3RbMF0ueSArICcgJztcbiAgICAgICAgICAgIHBhdGggKz0gJ0wgJyArIChyZWN0WzFdLnggLSBvcHRpb25zLnJhZGl1cykgKyAnICcgKyByZWN0WzFdLnkgKyAnICc7XG4gICAgICAgICAgICBwYXRoICs9ICdDICcgKyByZWN0WzFdLnggKyAnICcgKyByZWN0WzFdLnkgKyAnICcgKyByZWN0WzFdLnggKyAnICcgKyByZWN0WzFdLnkgKyAnICcgKyByZWN0WzFdLnggKyAnICcgKyAocmVjdFsxXS55ICsgb3B0aW9ucy5yYWRpdXMpICsgJyAnO1xuICAgICAgICAgICAgcGF0aCArPSAnTCAnICsgcmVjdFsyXS54ICsgJyAnICsgKHJlY3RbMl0ueSAtIG9wdGlvbnMucmFkaXVzKSArICcgJztcbiAgICAgICAgICAgIHBhdGggKz0gJ0MgJyArIHJlY3RbMl0ueCArICcgJyArIHJlY3RbMl0ueSArICcgJyArIHJlY3RbMl0ueCArICcgJyArIHJlY3RbMl0ueSArICcgJyArIChyZWN0WzJdLnggLSBvcHRpb25zLnJhZGl1cykgKyAnICcgKyByZWN0WzJdLnkgKyAnICc7XG4gICAgICAgICAgICBwYXRoICs9ICdMICcgKyAocmVjdFszXS54ICsgb3B0aW9ucy5yYWRpdXMpICsgJyAnICsgcmVjdFszXS55ICsgJyAnO1xuICAgICAgICAgICAgcGF0aCArPSAnQyAnICsgcmVjdFszXS54ICsgJyAnICsgcmVjdFszXS55ICsgJyAnICsgcmVjdFszXS54ICsgJyAnICsgcmVjdFszXS55ICsgJyAnICsgcmVjdFszXS54ICsgJyAnICsgKHJlY3RbM10ueSAtIG9wdGlvbnMucmFkaXVzKSArICcgJztcbiAgICAgICAgICAgIC8vIHBhdGggKz0gJ1onO1xuICAgICAgICAgICAgcGF0aCArPSAnTCAnICsgcmVjdFswXS54ICsgJyAnICsgKHJlY3RbMF0ueSArIG9wdGlvbnMucmFkaXVzKSArICcgJztcblxuICAgICAgICAgICAgcmV0dXJuIHBhdGgudHJpbSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGVsZW1lbnRSZWN0OiBmdW5jdGlvbiAoZWxlbWVudCA9IG51bGwsIG9wdGlvbnMgPSB7fSkge1xuXG4gICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudCB8fCB0aGlzLnRhcmdldDtcbiAgICAgICAgICAgIGNvbnN0IGJvdW5kcyA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIHJhZGl1czogMjQsXG4gICAgICAgICAgICAgICAgbWFyZ2luOiAxMCxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IHt4OiAwLCB5OiAwfSxcbiAgICAgICAgICAgICAgICByZWxhdGl2ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbGVmdCA9IG9wdGlvbnMucmVsYXRpdmUgPyAwIDogYm91bmRzLmxlZnQ7XG4gICAgICAgICAgICBjb25zdCB0b3AgPSBvcHRpb25zLnJlbGF0aXZlID8gMCA6IGVsZW1lbnQub2Zmc2V0VG9wO1xuXG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgeDogbGVmdCAtIG9wdGlvbnMubWFyZ2luICsgb3B0aW9ucy5vZmZzZXQueCxcbiAgICAgICAgICAgICAgICAgICAgeTogdG9wIC0gb3B0aW9ucy5tYXJnaW4gKyBvcHRpb25zLm9mZnNldC55XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHg6IGxlZnQgKyBlbGVtZW50LmNsaWVudFdpZHRoICsgb3B0aW9ucy5tYXJnaW4gKyBvcHRpb25zLm9mZnNldC54LFxuICAgICAgICAgICAgICAgICAgICB5OiB0b3AgLSBvcHRpb25zLm1hcmdpbiArIG9wdGlvbnMub2Zmc2V0LnlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgeDogbGVmdCArIGVsZW1lbnQuY2xpZW50V2lkdGggKyBvcHRpb25zLm1hcmdpbiArIG9wdGlvbnMub2Zmc2V0LngsXG4gICAgICAgICAgICAgICAgICAgIHk6IHRvcCArIGVsZW1lbnQuY2xpZW50SGVpZ2h0ICsgb3B0aW9ucy5tYXJnaW4gKyBvcHRpb25zLm9mZnNldC55XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHg6IGxlZnQgLSBvcHRpb25zLm1hcmdpbiArIG9wdGlvbnMub2Zmc2V0LngsXG4gICAgICAgICAgICAgICAgICAgIHk6IHRvcCArIGVsZW1lbnQuY2xpZW50SGVpZ2h0ICsgb3B0aW9ucy5tYXJnaW4gKyBvcHRpb25zLm9mZnNldC55XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMucG9zaXRpdmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgbWluWCA9IDA7XG4gICAgICAgICAgICAgICAgbGV0IG1pblkgPSAwO1xuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdFtpXS54IDwgbWluWCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluWCA9IHJlc3VsdFtpXS54O1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdFtpXS55IDwgbWluWSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWluWSA9IHJlc3VsdFtpXS55O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldLnggLT0gbWluWDtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldLnkgLT0gbWluWTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9XG59Il0sCiAgIm1hcHBpbmdzIjogIjtBQUFlLFNB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


Reviews:
user: login: sourcery-ai[bot]
body: Hey @crimsonstrife - I've reviewed your changes - here's some feedback:

**Overall Comments**:
- Consider using more descriptive variable names than `key2` in the `configure` function.

<details>
<summary>Here's what I looked at during the review</summary>

- 🟢 **General issues**: all looks good
- 🟢 **Security**: all looks good
- 🟢 **Testing**: all looks good
- 🟡 **Complexity**: 1 issue found
- 🟢 **Documentation**: all looks good
</details>

***

<details>
<summary>Sourcery is free for open source - if you like our reviews please consider sharing them ✨</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20got%20an%20instant%20code%20review%20from%20%40SourceryAI%2C%20and%20it%20was%20brilliant%21%20It%27s%20free%20for%20open%20source%20and%20has%20a%20free%20trial%20for%20private%20code.%20Check%20it%20out%20https%3A//sourcery.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20got%20an%20instant%20code%20review%20from%20%40SourceryAI%2C%20and%20it%20was%20brilliant%21%20It%27s%20free%20for%20open%20source%20and%20has%20a%20free%20trial%20for%20private%20code.%20Check%20it%20out%20https%3A//sourcery.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https://sourcery.ai)
- [Facebook](https://www.facebook.com/sharer/sharer.php?u=https://sourcery.ai)

</details>

<sub>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
</sub>
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-23T16:44:58Z

Review comments:
diff_hunk: @@ -1,316 +1,231 @@
 // resources/js/components/step.js
-function stepComponent ({
+function stepComponent({
   key,
   selector,
   shouldInterceptClick,
   interceptClickAction
 }) {
   return {
     target: null,
-    sleep: function (ms) {
-      return new Promise((resolve) => setTimeout(resolve, ms))
+      sleep: function (ms) {
+          return new Promise((resolve) => setTimeout(resolve, ms));
     },
-    init: async function () {
-      this.target = this.findElement(key)
+      init: async function () {
+          this.target = this.findElement(key);
       if (!this.target) {
-        console.error('Tutorial step was not found:', key)
-        return
+          console.error("Tutorial step was not found:", key);
+          return;
       }
-      document.documentElement
-        .querySelectorAll('input')
-        .forEach((element) => element.blur())
+          document.documentElement.querySelectorAll("input").forEach((element) => element.blur());
       if (this.target) {
-        this.target.focus()
+          this.target.focus();
       }
-      this.configure()
-      const dialog = this.$el.querySelector('[data-dialog]')
-      const clipPath = this.$el.querySelector('[data-clip-path]')
+          this.configure();
+          const dialog = this.$el.querySelector("[data-dialog]");
+          const clipPath = this.$el.querySelector("[data-clip-path]");
       if (shouldInterceptClick) {
-        this.target.addEventListener('click', (event) => {
-          event.preventDefault()
-          this.$wire.call(interceptClickAction)
-          this.target.blur()
-          const descendants = this.target.querySelectorAll(':hover')
+          this.target.addEventListener("click", (event) => {
+              event.preventDefault();
+              this.$wire.call(interceptClickAction);
+              this.target.blur();
+              const descendants = this.target.querySelectorAll(":hover");
           for (let i = 0; i < descendants.length; i++) {
-            const descendant = descendants[i]
-            descendant.blur()
+              const descendant = descendants[i];
+              descendant.blur();
           }
-        })
+          });
       }
-      this.initializeDialog()
+          this.initializeDialog();
       this.$nextTick(() => {
-        clipPath.setAttribute('d', this.clipPath())
-        this.$dispatch('tutorial::render')
-      })
-      clipPath.setAttribute('d', this.clipPath())
+          clipPath.setAttribute("d", this.clipPath());
+          this.$dispatch("tutorial::render");
+      });
+          clipPath.setAttribute("d", this.clipPath());
     },
     timeouts: [],
-    configure: function () {
-      document.addEventListener('keydown', function (event) {
-        const key2 = event.key
-        const isShiftKey = event.shiftKey
-        const isCtrlKey = false
-        const isAltKey = false
-        if (key2 === 'Tab') {
-          event.preventDefault()
+      configure: function () {
+          document.addEventListener("keydown", function (event) {
+              var key2 = event.key;
+              var isShiftKey = event.shiftKey;
+              var isCtrlKey = false;
+              var isAltKey = false;
+              if (key2 === "Tab") {
+                  event.preventDefault();
         }
-      })
+          });
       if (this.target instanceof HTMLSelectElement) {
-        if (this.target.hasAttribute('data-choice')) {
-          this.target = this.target.parentElement.parentElement
-          const dropdown = this.target.querySelector(
-            '.choices__list.choices__list--dropdown'
-          )
-          dropdown.style.zIndex = 100
+          if (this.target.hasAttribute("data-choice")) {
+              this.target = this.target.parentElement.parentElement;
+              const dropdown = this.target.querySelector(".choices__list.choices__list--dropdown");
+              dropdown.style.zIndex = 100;
         }
       }
-      if (this.target.tagName === 'TRIX-EDITOR') {
-        this.timeouts.trix = this.target.clientHeight
-        this.target = this.target.parentElement
-        const observer = new MutationObserver(
-          (mutationsList, observer2) => {
-            mutationsList.forEach((mutation) => {
-              if (this.timeouts.trix) {
-                clearTimeout(this.timeouts.trix)
-              }
-              this.timeouts.trix = setTimeout(() => {
-                this.timeouts.trix = null
-                this.init()
-              }, 500)
-            })
-          }
-        )
+          if (this.target.tagName === "TRIX-EDITOR") {
+              this.timeouts["trix"] = this.target.clientHeight;
+              this.target = this.target.parentElement;
+              const observer = new MutationObserver((mutationsList, observer2) => {
+                  mutationsList.forEach((mutation) => {
+                      if (this.timeouts["trix"]) {
+                          clearTimeout(this.timeouts["trix"]);
+                      }
+                      this.timeouts["trix"] = setTimeout(() => {
+                          this.timeouts["trix"] = null;
+                          this.init();
+                      }, 500);
+                  });
+              });
         const config = {
           attributes: true,
-          attributeFilter: ['height'],
+            attributeFilter: ["height"],
           childList: true,
           subtree: true
-        }
-        observer.observe(this.target, config)
+        };
+              observer.observe(this.target, config);
       }
       if (this.target instanceof HTMLTextAreaElement || this.t) {
-        let initialWidth = this.target.offsetWidth
-        let initialHeight = this.target.offsetHeight
+          let initialWidth = this.target.offsetWidth;
+          let initialHeight = this.target.offsetHeight;
         const observer = new MutationObserver(() => {
-          if (
-            this.target.offsetWidth !== initialWidth ||
-                        this.target.offsetHeight !== initialHeight
-          ) {
-            initialWidth = this.target.offsetWidth
-            initialHeight = this.target.offsetHeight
-            if (this.timeouts.textarea) {
-              clearTimeout(this.timeouts.textarea)
+            if (this.target.offsetWidth !== initialWidth || this.target.offsetHeight !== initialHeight) {
+                initialWidth = this.target.offsetWidth;
+                initialHeight = this.target.offsetHeight;
+                if (this.timeouts["textarea"]) {
+                    clearTimeout(this.timeouts["textarea"]);
             }
-            this.timeouts.textarea = setTimeout(() => {
-              this.timeouts.textarea = null
-              this.init()
-            }, 100)
+                this.timeouts["textarea"] = setTimeout(() => {
+                    this.timeouts["textarea"] = null;
+                    this.init();
+                }, 100);
           }
-        })
-        observer.observe(this.target, {
-          attributes: true,
-          attributeFilter: ['style']
-        })
+        });
+          observer.observe(this.target, {attributes: true, attributeFilter: ["style"]});
       }
     },
     // You can define any other Alpine.js functions here.
-    initializeDialog: function (dialog = null) {
+      initializeDialog: function (dialog = null) {
       if (!dialog) {
-        dialog = this.$el.querySelector('[data-dialog]')
+          dialog = this.$el.querySelector("[data-dialog]");
       }
-      const dialogPath = dialog.querySelector('[data-dialog-path]')
-      const rect = this.elementRect()
-      const stroke = dialog.querySelector('[data-dialog-stroke]')
+          const dialogPath = dialog.querySelector("[data-dialog-path]");
+          const rect = this.elementRect();
+          const stroke = dialog.querySelector("[data-dialog-stroke]");
       window.scrollTo({
         top: rect[0].y - window.innerHeight / 3,
         left: rect[0].x,
-        behavior: 'smooth'
-      })
-      const width = rect[1].x - rect[0].x
-      const height = rect[2].y - rect[0].y
-      const x = rect[0].x
-      const y = rect[0].y
-      dialog.style.width = `${width}px`
-      dialog.style.transform = `translate(${x}px, ${y}px)`
-      stroke.style.height = `${height}px`
-      dialogPath.setAttribute(
-        'd',
-        this.elementPath(null, { relative: true, positive: true })
-      )
+          behavior: "smooth"
+      });
+          const width = rect[1].x - rect[0].x;
+          const height = rect[2].y - rect[0].y;
+          const x = rect[0].x;
+          const y = rect[0].y;
+          dialog.style.width = `${width}px`;
+          dialog.style.transform = `translate(${x}px, ${y}px)`;
+          stroke.style.height = `${height}px`;
+          dialogPath.setAttribute("d", this.elementPath(null, {relative: true, positive: true}));
     },
-    clipPath: function (element = null, options = {}) {
-      element = element || this.target
+      clipPath: function (element = null, options = {}) {
+          element = element || this.target;
       options = {
path: public/js/guava/tutorials/components/step.js
user: login: sourcery-ai[bot]
body: **issue (complexity):** Consider using an array of segments and the join method to build the SVG path string, instead of concatenating strings directly to improve readability and reduce complexity in path construction logic, and apply this pattern consistently across similar functions like windowPath and elementRect, potentially moving the logic to a shared utility module if used in multiple places.

Consider refactoring the SVG path-building logic to reduce the repetitive concatenation and deep nesting. For example, instead of continuously appending to a string, consider building an array of segments and joining them at the end. This will both simplify the code and improve readability.

**Before:**

```js
let path = 'M ' + rect[0].x + ' ' + (rect[0].y + options.radius) + ' ';
path += 'C ' + rect[0].x + ' ' + rect[0].y + ' ' + rect[0].x + ' ' + rect[0].y + ' ' + (rect[0].x + options.radius) + ' ' + rect[0].y + ' ';
...
return path.trim();
```

**After:**

```js
const segments = [
  `M ${rect[0].x} ${rect[0].y + options.radius}`,
  `C ${rect[0].x} ${rect[0].y} ${rect[0].x} ${rect[0].y} ${rect[0].x + options.radius} ${rect[0].y}`,
  `L ${rect[1].x - options.radius} ${rect[1].y}`,
  `C ${rect[1].x} ${rect[1].y} ${rect[1].x} ${rect[1].y} ${rect[1].x} ${rect[1].y + options.radius}`,
  `L ${rect[2].x} ${rect[2].y - options.radius}`,
  `C ${rect[2].x} ${rect[2].y} ${rect[2].x} ${rect[2].y} ${rect[2].x - options.radius} ${rect[2].y}`,
  `L ${rect[3].x + options.radius} ${rect[3].y}`,
  `C ${rect[3].x} ${rect[3].y} ${rect[3].x} ${rect[3].y} ${rect[3].x} ${rect[3].y - options.radius}`,
  `L ${rect[0].x} ${rect[0].y + options.radius}`
];

return segments.join(' ').trim();
```

**Actionable steps:**

1. **Abstract Concatenation:** Create helper functions (or use arrays with `.join()`) for constructing SVG paths.
2. **Apply Consistently:** Refactor the logic in all similar functions (e.g., `windowPath` and `elementRect`) using the same pattern.
3. **Optional:** Consider moving the helper function into a shared utility module if the same logic is used in multiple places.

These changes keep functionality intact while reducing code duplication and nesting complexity.
created_at: 2025-04-23T16:44:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,316 +1,231 @@
 // resources/js/components/step.js
-function stepComponent ({
+function stepComponent({
   key,
   selector,
   shouldInterceptClick,
   interceptClickAction
 }) {
   return {
     target: null,
-    sleep: function (ms) {
-      return new Promise((resolve) => setTimeout(resolve, ms))
+      sleep: function (ms) {
+          return new Promise((resolve) => setTimeout(resolve, ms));
     },
-    init: async function () {
-      this.target = this.findElement(key)
+      init: async function () {
+          this.target = this.findElement(key);
       if (!this.target) {
-        console.error('Tutorial step was not found:', key)
-        return
+          console.error("Tutorial step was not found:", key);
+          return;
       }
-      document.documentElement
-        .querySelectorAll('input')
-        .forEach((element) => element.blur())
+          document.documentElement.querySelectorAll("input").forEach((element) => element.blur());
       if (this.target) {
-        this.target.focus()
+          this.target.focus();
       }
-      this.configure()
-      const dialog = this.$el.querySelector('[data-dialog]')
-      const clipPath = this.$el.querySelector('[data-clip-path]')
+          this.configure();
+          const dialog = this.$el.querySelector("[data-dialog]");
+          const clipPath = this.$el.querySelector("[data-clip-path]");
       if (shouldInterceptClick) {
-        this.target.addEventListener('click', (event) => {
-          event.preventDefault()
-          this.$wire.call(interceptClickAction)
-          this.target.blur()
-          const descendants = this.target.querySelectorAll(':hover')
+          this.target.addEventListener("click", (event) => {
+              event.preventDefault();
+              this.$wire.call(interceptClickAction);
+              this.target.blur();
+              const descendants = this.target.querySelectorAll(":hover");
           for (let i = 0; i < descendants.length; i++) {
-            const descendant = descendants[i]
-            descendant.blur()
+              const descendant = descendants[i];
+              descendant.blur();
           }
-        })
+          });
       }
-      this.initializeDialog()
+          this.initializeDialog();
       this.$nextTick(() => {
-        clipPath.setAttribute('d', this.clipPath())
-        this.$dispatch('tutorial::render')
-      })
-      clipPath.setAttribute('d', this.clipPath())
+          clipPath.setAttribute("d", this.clipPath());
+          this.$dispatch("tutorial::render");
+      });
+          clipPath.setAttribute("d", this.clipPath());
     },
     timeouts: [],
-    configure: function () {
-      document.addEventListener('keydown', function (event) {
-        const key2 = event.key
-        const isShiftKey = event.shiftKey
-        const isCtrlKey = false
-        const isAltKey = false
-        if (key2 === 'Tab') {
-          event.preventDefault()
+      configure: function () {
+          document.addEventListener("keydown", function (event) {
+              var key2 = event.key;
path: public/js/guava/tutorials/components/step.js
user: login: sourcery-ai[bot]
body: **issue (code-quality):** Use `const` or `let` instead of `var`. ([`avoid-using-var`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-using-var))

<details><summary>Explanation</summary>`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code).
`let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than
function-scoped.

From the [Airbnb JavaScript Style Guide](https://airbnb.io/javascript/#references--prefer-const)
</details>
created_at: 2025-04-23T16:44:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,316 +1,231 @@
 // resources/js/components/step.js
-function stepComponent ({
+function stepComponent({
   key,
   selector,
   shouldInterceptClick,
   interceptClickAction
 }) {
   return {
     target: null,
-    sleep: function (ms) {
-      return new Promise((resolve) => setTimeout(resolve, ms))
+      sleep: function (ms) {
+          return new Promise((resolve) => setTimeout(resolve, ms));
     },
-    init: async function () {
-      this.target = this.findElement(key)
+      init: async function () {
+          this.target = this.findElement(key);
       if (!this.target) {
-        console.error('Tutorial step was not found:', key)
-        return
+          console.error("Tutorial step was not found:", key);
+          return;
       }
-      document.documentElement
-        .querySelectorAll('input')
-        .forEach((element) => element.blur())
+          document.documentElement.querySelectorAll("input").forEach((element) => element.blur());
       if (this.target) {
-        this.target.focus()
+          this.target.focus();
       }
-      this.configure()
-      const dialog = this.$el.querySelector('[data-dialog]')
-      const clipPath = this.$el.querySelector('[data-clip-path]')
+          this.configure();
+          const dialog = this.$el.querySelector("[data-dialog]");
+          const clipPath = this.$el.querySelector("[data-clip-path]");
       if (shouldInterceptClick) {
-        this.target.addEventListener('click', (event) => {
-          event.preventDefault()
-          this.$wire.call(interceptClickAction)
-          this.target.blur()
-          const descendants = this.target.querySelectorAll(':hover')
+          this.target.addEventListener("click", (event) => {
+              event.preventDefault();
+              this.$wire.call(interceptClickAction);
+              this.target.blur();
+              const descendants = this.target.querySelectorAll(":hover");
           for (let i = 0; i < descendants.length; i++) {
-            const descendant = descendants[i]
-            descendant.blur()
+              const descendant = descendants[i];
+              descendant.blur();
           }
-        })
+          });
       }
-      this.initializeDialog()
+          this.initializeDialog();
       this.$nextTick(() => {
-        clipPath.setAttribute('d', this.clipPath())
-        this.$dispatch('tutorial::render')
-      })
-      clipPath.setAttribute('d', this.clipPath())
+          clipPath.setAttribute("d", this.clipPath());
+          this.$dispatch("tutorial::render");
+      });
+          clipPath.setAttribute("d", this.clipPath());
     },
     timeouts: [],
-    configure: function () {
-      document.addEventListener('keydown', function (event) {
-        const key2 = event.key
-        const isShiftKey = event.shiftKey
-        const isCtrlKey = false
-        const isAltKey = false
-        if (key2 === 'Tab') {
-          event.preventDefault()
+      configure: function () {
+          document.addEventListener("keydown", function (event) {
+              var key2 = event.key;
+              var isShiftKey = event.shiftKey;
path: public/js/guava/tutorials/components/step.js
user: login: sourcery-ai[bot]
body: **issue (code-quality):** Use `const` or `let` instead of `var`. ([`avoid-using-var`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-using-var))

<details><summary>Explanation</summary>`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code).
`let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than
function-scoped.

From the [Airbnb JavaScript Style Guide](https://airbnb.io/javascript/#references--prefer-const)
</details>
created_at: 2025-04-23T16:44:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,316 +1,231 @@
 // resources/js/components/step.js
-function stepComponent ({
+function stepComponent({
   key,
   selector,
   shouldInterceptClick,
   interceptClickAction
 }) {
   return {
     target: null,
-    sleep: function (ms) {
-      return new Promise((resolve) => setTimeout(resolve, ms))
+      sleep: function (ms) {
+          return new Promise((resolve) => setTimeout(resolve, ms));
     },
-    init: async function () {
-      this.target = this.findElement(key)
+      init: async function () {
+          this.target = this.findElement(key);
       if (!this.target) {
-        console.error('Tutorial step was not found:', key)
-        return
+          console.error("Tutorial step was not found:", key);
+          return;
       }
-      document.documentElement
-        .querySelectorAll('input')
-        .forEach((element) => element.blur())
+          document.documentElement.querySelectorAll("input").forEach((element) => element.blur());
       if (this.target) {
-        this.target.focus()
+          this.target.focus();
       }
-      this.configure()
-      const dialog = this.$el.querySelector('[data-dialog]')
-      const clipPath = this.$el.querySelector('[data-clip-path]')
+          this.configure();
+          const dialog = this.$el.querySelector("[data-dialog]");
+          const clipPath = this.$el.querySelector("[data-clip-path]");
       if (shouldInterceptClick) {
-        this.target.addEventListener('click', (event) => {
-          event.preventDefault()
-          this.$wire.call(interceptClickAction)
-          this.target.blur()
-          const descendants = this.target.querySelectorAll(':hover')
+          this.target.addEventListener("click", (event) => {
+              event.preventDefault();
+              this.$wire.call(interceptClickAction);
+              this.target.blur();
+              const descendants = this.target.querySelectorAll(":hover");
           for (let i = 0; i < descendants.length; i++) {
-            const descendant = descendants[i]
-            descendant.blur()
+              const descendant = descendants[i];
+              descendant.blur();
           }
-        })
+          });
       }
-      this.initializeDialog()
+          this.initializeDialog();
       this.$nextTick(() => {
-        clipPath.setAttribute('d', this.clipPath())
-        this.$dispatch('tutorial::render')
-      })
-      clipPath.setAttribute('d', this.clipPath())
+          clipPath.setAttribute("d", this.clipPath());
+          this.$dispatch("tutorial::render");
+      });
+          clipPath.setAttribute("d", this.clipPath());
     },
     timeouts: [],
-    configure: function () {
-      document.addEventListener('keydown', function (event) {
-        const key2 = event.key
-        const isShiftKey = event.shiftKey
-        const isCtrlKey = false
-        const isAltKey = false
-        if (key2 === 'Tab') {
-          event.preventDefault()
+      configure: function () {
+          document.addEventListener("keydown", function (event) {
+              var key2 = event.key;
+              var isShiftKey = event.shiftKey;
+              var isCtrlKey = false;
path: public/js/guava/tutorials/components/step.js
user: login: sourcery-ai[bot]
body: **issue (code-quality):** Use `const` or `let` instead of `var`. ([`avoid-using-var`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-using-var))

<details><summary>Explanation</summary>`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code).
`let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than
function-scoped.

From the [Airbnb JavaScript Style Guide](https://airbnb.io/javascript/#references--prefer-const)
</details>
created_at: 2025-04-23T16:44:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,316 +1,231 @@
 // resources/js/components/step.js
-function stepComponent ({
+function stepComponent({
   key,
   selector,
   shouldInterceptClick,
   interceptClickAction
 }) {
   return {
     target: null,
-    sleep: function (ms) {
-      return new Promise((resolve) => setTimeout(resolve, ms))
+      sleep: function (ms) {
+          return new Promise((resolve) => setTimeout(resolve, ms));
     },
-    init: async function () {
-      this.target = this.findElement(key)
+      init: async function () {
+          this.target = this.findElement(key);
       if (!this.target) {
-        console.error('Tutorial step was not found:', key)
-        return
+          console.error("Tutorial step was not found:", key);
+          return;
       }
-      document.documentElement
-        .querySelectorAll('input')
-        .forEach((element) => element.blur())
+          document.documentElement.querySelectorAll("input").forEach((element) => element.blur());
       if (this.target) {
-        this.target.focus()
+          this.target.focus();
       }
-      this.configure()
-      const dialog = this.$el.querySelector('[data-dialog]')
-      const clipPath = this.$el.querySelector('[data-clip-path]')
+          this.configure();
+          const dialog = this.$el.querySelector("[data-dialog]");
+          const clipPath = this.$el.querySelector("[data-clip-path]");
       if (shouldInterceptClick) {
-        this.target.addEventListener('click', (event) => {
-          event.preventDefault()
-          this.$wire.call(interceptClickAction)
-          this.target.blur()
-          const descendants = this.target.querySelectorAll(':hover')
+          this.target.addEventListener("click", (event) => {
+              event.preventDefault();
+              this.$wire.call(interceptClickAction);
+              this.target.blur();
+              const descendants = this.target.querySelectorAll(":hover");
           for (let i = 0; i < descendants.length; i++) {
-            const descendant = descendants[i]
-            descendant.blur()
+              const descendant = descendants[i];
+              descendant.blur();
           }
-        })
+          });
       }
-      this.initializeDialog()
+          this.initializeDialog();
       this.$nextTick(() => {
-        clipPath.setAttribute('d', this.clipPath())
-        this.$dispatch('tutorial::render')
-      })
-      clipPath.setAttribute('d', this.clipPath())
+          clipPath.setAttribute("d", this.clipPath());
+          this.$dispatch("tutorial::render");
+      });
+          clipPath.setAttribute("d", this.clipPath());
     },
     timeouts: [],
-    configure: function () {
-      document.addEventListener('keydown', function (event) {
-        const key2 = event.key
-        const isShiftKey = event.shiftKey
-        const isCtrlKey = false
-        const isAltKey = false
-        if (key2 === 'Tab') {
-          event.preventDefault()
+      configure: function () {
+          document.addEventListener("keydown", function (event) {
+              var key2 = event.key;
+              var isShiftKey = event.shiftKey;
+              var isCtrlKey = false;
+              var isAltKey = false;
path: public/js/guava/tutorials/components/step.js
user: login: sourcery-ai[bot]
body: **issue (code-quality):** Use `const` or `let` instead of `var`. ([`avoid-using-var`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-using-var))

<details><summary>Explanation</summary>`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code).
`let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than
function-scoped.

From the [Airbnb JavaScript Style Guide](https://airbnb.io/javascript/#references--prefer-const)
</details>
created_at: 2025-04-23T16:44:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,316 +1,231 @@
 // resources/js/components/step.js
-function stepComponent ({
+function stepComponent({
   key,
   selector,
   shouldInterceptClick,
   interceptClickAction
 }) {
   return {
     target: null,
-    sleep: function (ms) {
-      return new Promise((resolve) => setTimeout(resolve, ms))
+      sleep: function (ms) {
+          return new Promise((resolve) => setTimeout(resolve, ms));
     },
-    init: async function () {
-      this.target = this.findElement(key)
+      init: async function () {
+          this.target = this.findElement(key);
       if (!this.target) {
-        console.error('Tutorial step was not found:', key)
-        return
+          console.error("Tutorial step was not found:", key);
+          return;
       }
-      document.documentElement
-        .querySelectorAll('input')
-        .forEach((element) => element.blur())
+          document.documentElement.querySelectorAll("input").forEach((element) => element.blur());
       if (this.target) {
-        this.target.focus()
+          this.target.focus();
       }
-      this.configure()
-      const dialog = this.$el.querySelector('[data-dialog]')
-      const clipPath = this.$el.querySelector('[data-clip-path]')
+          this.configure();
+          const dialog = this.$el.querySelector("[data-dialog]");
+          const clipPath = this.$el.querySelector("[data-clip-path]");
       if (shouldInterceptClick) {
-        this.target.addEventListener('click', (event) => {
-          event.preventDefault()
-          this.$wire.call(interceptClickAction)
-          this.target.blur()
-          const descendants = this.target.querySelectorAll(':hover')
+          this.target.addEventListener("click", (event) => {
+              event.preventDefault();
+              this.$wire.call(interceptClickAction);
+              this.target.blur();
+              const descendants = this.target.querySelectorAll(":hover");
           for (let i = 0; i < descendants.length; i++) {
-            const descendant = descendants[i]
-            descendant.blur()
+              const descendant = descendants[i];
+              descendant.blur();
           }
-        })
+          });
       }
-      this.initializeDialog()
+          this.initializeDialog();
       this.$nextTick(() => {
-        clipPath.setAttribute('d', this.clipPath())
-        this.$dispatch('tutorial::render')
-      })
-      clipPath.setAttribute('d', this.clipPath())
+          clipPath.setAttribute("d", this.clipPath());
+          this.$dispatch("tutorial::render");
+      });
+          clipPath.setAttribute("d", this.clipPath());
     },
     timeouts: [],
-    configure: function () {
-      document.addEventListener('keydown', function (event) {
-        const key2 = event.key
-        const isShiftKey = event.shiftKey
-        const isCtrlKey = false
-        const isAltKey = false
-        if (key2 === 'Tab') {
-          event.preventDefault()
+      configure: function () {
+          document.addEventListener("keydown", function (event) {
+              var key2 = event.key;
+              var isShiftKey = event.shiftKey;
+              var isCtrlKey = false;
+              var isAltKey = false;
+              if (key2 === "Tab") {
+                  event.preventDefault();
         }
-      })
+          });
       if (this.target instanceof HTMLSelectElement) {
-        if (this.target.hasAttribute('data-choice')) {
-          this.target = this.target.parentElement.parentElement
-          const dropdown = this.target.querySelector(
-            '.choices__list.choices__list--dropdown'
-          )
-          dropdown.style.zIndex = 100
+          if (this.target.hasAttribute("data-choice")) {
+              this.target = this.target.parentElement.parentElement;
+              const dropdown = this.target.querySelector(".choices__list.choices__list--dropdown");
+              dropdown.style.zIndex = 100;
         }
       }
path: public/js/guava/tutorials/components/step.js
user: login: sourcery-ai[bot]
body: **suggestion (code-quality):** Merge nested if conditions ([`merge-nested-ifs`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/merge-nested-ifs))

```suggestion
      if (this.target instanceof HTMLSelectElement && this.target.hasAttribute("data-choice")) {
            this.target = this.target.parentElement.parentElement;
            const dropdown = this.target.querySelector(".choices__list.choices__list--dropdown");
            dropdown.style.zIndex = 100;
      }

```

<br/><details><summary>Explanation</summary>Reading deeply nested conditional code is confusing, since you have to keep track of which
conditions relate to which levels. We therefore strive to reduce nesting where
possible, and the situation where two `if` conditions can be combined using
`and` is an easy win.
</details>
created_at: 2025-04-23T16:44:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,316 +1,231 @@
 // resources/js/components/step.js
-function stepComponent ({
+function stepComponent({
   key,
   selector,
   shouldInterceptClick,
   interceptClickAction
 }) {
   return {
     target: null,
-    sleep: function (ms) {
-      return new Promise((resolve) => setTimeout(resolve, ms))
+      sleep: function (ms) {
+          return new Promise((resolve) => setTimeout(resolve, ms));
     },
-    init: async function () {
-      this.target = this.findElement(key)
+      init: async function () {
+          this.target = this.findElement(key);
       if (!this.target) {
-        console.error('Tutorial step was not found:', key)
-        return
+          console.error("Tutorial step was not found:", key);
+          return;
       }
-      document.documentElement
-        .querySelectorAll('input')
-        .forEach((element) => element.blur())
+          document.documentElement.querySelectorAll("input").forEach((element) => element.blur());
       if (this.target) {
-        this.target.focus()
+          this.target.focus();
       }
-      this.configure()
-      const dialog = this.$el.querySelector('[data-dialog]')
-      const clipPath = this.$el.querySelector('[data-clip-path]')
+          this.configure();
+          const dialog = this.$el.querySelector("[data-dialog]");
+          const clipPath = this.$el.querySelector("[data-clip-path]");
       if (shouldInterceptClick) {
-        this.target.addEventListener('click', (event) => {
-          event.preventDefault()
-          this.$wire.call(interceptClickAction)
-          this.target.blur()
-          const descendants = this.target.querySelectorAll(':hover')
+          this.target.addEventListener("click", (event) => {
+              event.preventDefault();
+              this.$wire.call(interceptClickAction);
+              this.target.blur();
+              const descendants = this.target.querySelectorAll(":hover");
           for (let i = 0; i < descendants.length; i++) {
-            const descendant = descendants[i]
-            descendant.blur()
+              const descendant = descendants[i];
+              descendant.blur();
           }
-        })
+          });
       }
-      this.initializeDialog()
+          this.initializeDialog();
       this.$nextTick(() => {
-        clipPath.setAttribute('d', this.clipPath())
-        this.$dispatch('tutorial::render')
-      })
-      clipPath.setAttribute('d', this.clipPath())
+          clipPath.setAttribute("d", this.clipPath());
+          this.$dispatch("tutorial::render");
+      });
+          clipPath.setAttribute("d", this.clipPath());
     },
     timeouts: [],
-    configure: function () {
-      document.addEventListener('keydown', function (event) {
-        const key2 = event.key
-        const isShiftKey = event.shiftKey
-        const isCtrlKey = false
-        const isAltKey = false
-        if (key2 === 'Tab') {
-          event.preventDefault()
+      configure: function () {
+          document.addEventListener("keydown", function (event) {
+              var key2 = event.key;
+              var isShiftKey = event.shiftKey;
+              var isCtrlKey = false;
+              var isAltKey = false;
+              if (key2 === "Tab") {
+                  event.preventDefault();
         }
-      })
+          });
       if (this.target instanceof HTMLSelectElement) {
-        if (this.target.hasAttribute('data-choice')) {
-          this.target = this.target.parentElement.parentElement
-          const dropdown = this.target.querySelector(
-            '.choices__list.choices__list--dropdown'
-          )
-          dropdown.style.zIndex = 100
+          if (this.target.hasAttribute("data-choice")) {
+              this.target = this.target.parentElement.parentElement;
+              const dropdown = this.target.querySelector(".choices__list.choices__list--dropdown");
+              dropdown.style.zIndex = 100;
         }
       }
-      if (this.target.tagName === 'TRIX-EDITOR') {
-        this.timeouts.trix = this.target.clientHeight
-        this.target = this.target.parentElement
-        const observer = new MutationObserver(
-          (mutationsList, observer2) => {
-            mutationsList.forEach((mutation) => {
-              if (this.timeouts.trix) {
-                clearTimeout(this.timeouts.trix)
-              }
-              this.timeouts.trix = setTimeout(() => {
-                this.timeouts.trix = null
-                this.init()
-              }, 500)
-            })
-          }
-        )
+          if (this.target.tagName === "TRIX-EDITOR") {
+              this.timeouts["trix"] = this.target.clientHeight;
+              this.target = this.target.parentElement;
+              const observer = new MutationObserver((mutationsList, observer2) => {
+                  mutationsList.forEach((mutation) => {
+                      if (this.timeouts["trix"]) {
+                          clearTimeout(this.timeouts["trix"]);
+                      }
+                      this.timeouts["trix"] = setTimeout(() => {
+                          this.timeouts["trix"] = null;
+                          this.init();
+                      }, 500);
+                  });
+              });
         const config = {
           attributes: true,
-          attributeFilter: ['height'],
+            attributeFilter: ["height"],
           childList: true,
           subtree: true
-        }
-        observer.observe(this.target, config)
+        };
+              observer.observe(this.target, config);
       }
       if (this.target instanceof HTMLTextAreaElement || this.t) {
-        let initialWidth = this.target.offsetWidth
-        let initialHeight = this.target.offsetHeight
+          let initialWidth = this.target.offsetWidth;
+          let initialHeight = this.target.offsetHeight;
         const observer = new MutationObserver(() => {
-          if (
-            this.target.offsetWidth !== initialWidth ||
-                        this.target.offsetHeight !== initialHeight
-          ) {
-            initialWidth = this.target.offsetWidth
-            initialHeight = this.target.offsetHeight
-            if (this.timeouts.textarea) {
-              clearTimeout(this.timeouts.textarea)
+            if (this.target.offsetWidth !== initialWidth || this.target.offsetHeight !== initialHeight) {
+                initialWidth = this.target.offsetWidth;
+                initialHeight = this.target.offsetHeight;
+                if (this.timeouts["textarea"]) {
+                    clearTimeout(this.timeouts["textarea"]);
             }
-            this.timeouts.textarea = setTimeout(() => {
-              this.timeouts.textarea = null
-              this.init()
-            }, 100)
+                this.timeouts["textarea"] = setTimeout(() => {
+                    this.timeouts["textarea"] = null;
+                    this.init();
+                }, 100);
           }
-        })
-        observer.observe(this.target, {
-          attributes: true,
-          attributeFilter: ['style']
-        })
+        });
+          observer.observe(this.target, {attributes: true, attributeFilter: ["style"]});
       }
     },
     // You can define any other Alpine.js functions here.
-    initializeDialog: function (dialog = null) {
+      initializeDialog: function (dialog = null) {
       if (!dialog) {
-        dialog = this.$el.querySelector('[data-dialog]')
+          dialog = this.$el.querySelector("[data-dialog]");
       }
-      const dialogPath = dialog.querySelector('[data-dialog-path]')
-      const rect = this.elementRect()
-      const stroke = dialog.querySelector('[data-dialog-stroke]')
+          const dialogPath = dialog.querySelector("[data-dialog-path]");
+          const rect = this.elementRect();
+          const stroke = dialog.querySelector("[data-dialog-stroke]");
       window.scrollTo({
         top: rect[0].y - window.innerHeight / 3,
         left: rect[0].x,
-        behavior: 'smooth'
-      })
-      const width = rect[1].x - rect[0].x
-      const height = rect[2].y - rect[0].y
-      const x = rect[0].x
-      const y = rect[0].y
-      dialog.style.width = `${width}px`
-      dialog.style.transform = `translate(${x}px, ${y}px)`
-      stroke.style.height = `${height}px`
-      dialogPath.setAttribute(
-        'd',
-        this.elementPath(null, { relative: true, positive: true })
-      )
+          behavior: "smooth"
+      });
+          const width = rect[1].x - rect[0].x;
+          const height = rect[2].y - rect[0].y;
+          const x = rect[0].x;
path: public/js/guava/tutorials/components/step.js
user: login: sourcery-ai[bot]
body: **suggestion (code-quality):** Prefer object destructuring when accessing and using properties. ([`use-object-destructuring`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/use-object-destructuring))

```suggestion
          const {x} = rect[0];
```

<br/><details><summary>Explanation</summary>Object destructuring can often remove an unnecessary temporary reference, as well as making your code more succinct.

From the [Airbnb Javascript Style Guide](https://airbnb.io/javascript/#destructuring--object)
</details>
created_at: 2025-04-23T16:44:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,316 +1,231 @@
 // resources/js/components/step.js
-function stepComponent ({
+function stepComponent({
   key,
   selector,
   shouldInterceptClick,
   interceptClickAction
 }) {
   return {
     target: null,
-    sleep: function (ms) {
-      return new Promise((resolve) => setTimeout(resolve, ms))
+      sleep: function (ms) {
+          return new Promise((resolve) => setTimeout(resolve, ms));
     },
-    init: async function () {
-      this.target = this.findElement(key)
+      init: async function () {
+          this.target = this.findElement(key);
       if (!this.target) {
-        console.error('Tutorial step was not found:', key)
-        return
+          console.error("Tutorial step was not found:", key);
+          return;
       }
-      document.documentElement
-        .querySelectorAll('input')
-        .forEach((element) => element.blur())
+          document.documentElement.querySelectorAll("input").forEach((element) => element.blur());
       if (this.target) {
-        this.target.focus()
+          this.target.focus();
       }
-      this.configure()
-      const dialog = this.$el.querySelector('[data-dialog]')
-      const clipPath = this.$el.querySelector('[data-clip-path]')
+          this.configure();
+          const dialog = this.$el.querySelector("[data-dialog]");
+          const clipPath = this.$el.querySelector("[data-clip-path]");
       if (shouldInterceptClick) {
-        this.target.addEventListener('click', (event) => {
-          event.preventDefault()
-          this.$wire.call(interceptClickAction)
-          this.target.blur()
-          const descendants = this.target.querySelectorAll(':hover')
+          this.target.addEventListener("click", (event) => {
+              event.preventDefault();
+              this.$wire.call(interceptClickAction);
+              this.target.blur();
+              const descendants = this.target.querySelectorAll(":hover");
           for (let i = 0; i < descendants.length; i++) {
-            const descendant = descendants[i]
-            descendant.blur()
+              const descendant = descendants[i];
+              descendant.blur();
           }
-        })
+          });
       }
-      this.initializeDialog()
+          this.initializeDialog();
       this.$nextTick(() => {
-        clipPath.setAttribute('d', this.clipPath())
-        this.$dispatch('tutorial::render')
-      })
-      clipPath.setAttribute('d', this.clipPath())
+          clipPath.setAttribute("d", this.clipPath());
+          this.$dispatch("tutorial::render");
+      });
+          clipPath.setAttribute("d", this.clipPath());
     },
     timeouts: [],
-    configure: function () {
-      document.addEventListener('keydown', function (event) {
-        const key2 = event.key
-        const isShiftKey = event.shiftKey
-        const isCtrlKey = false
-        const isAltKey = false
-        if (key2 === 'Tab') {
-          event.preventDefault()
+      configure: function () {
+          document.addEventListener("keydown", function (event) {
+              var key2 = event.key;
+              var isShiftKey = event.shiftKey;
+              var isCtrlKey = false;
+              var isAltKey = false;
+              if (key2 === "Tab") {
+                  event.preventDefault();
         }
-      })
+          });
       if (this.target instanceof HTMLSelectElement) {
-        if (this.target.hasAttribute('data-choice')) {
-          this.target = this.target.parentElement.parentElement
-          const dropdown = this.target.querySelector(
-            '.choices__list.choices__list--dropdown'
-          )
-          dropdown.style.zIndex = 100
+          if (this.target.hasAttribute("data-choice")) {
+              this.target = this.target.parentElement.parentElement;
+              const dropdown = this.target.querySelector(".choices__list.choices__list--dropdown");
+              dropdown.style.zIndex = 100;
         }
       }
-      if (this.target.tagName === 'TRIX-EDITOR') {
-        this.timeouts.trix = this.target.clientHeight
-        this.target = this.target.parentElement
-        const observer = new MutationObserver(
-          (mutationsList, observer2) => {
-            mutationsList.forEach((mutation) => {
-              if (this.timeouts.trix) {
-                clearTimeout(this.timeouts.trix)
-              }
-              this.timeouts.trix = setTimeout(() => {
-                this.timeouts.trix = null
-                this.init()
-              }, 500)
-            })
-          }
-        )
+          if (this.target.tagName === "TRIX-EDITOR") {
+              this.timeouts["trix"] = this.target.clientHeight;
+              this.target = this.target.parentElement;
+              const observer = new MutationObserver((mutationsList, observer2) => {
+                  mutationsList.forEach((mutation) => {
+                      if (this.timeouts["trix"]) {
+                          clearTimeout(this.timeouts["trix"]);
+                      }
+                      this.timeouts["trix"] = setTimeout(() => {
+                          this.timeouts["trix"] = null;
+                          this.init();
+                      }, 500);
+                  });
+              });
         const config = {
           attributes: true,
-          attributeFilter: ['height'],
+            attributeFilter: ["height"],
           childList: true,
           subtree: true
-        }
-        observer.observe(this.target, config)
+        };
+              observer.observe(this.target, config);
       }
       if (this.target instanceof HTMLTextAreaElement || this.t) {
-        let initialWidth = this.target.offsetWidth
-        let initialHeight = this.target.offsetHeight
+          let initialWidth = this.target.offsetWidth;
+          let initialHeight = this.target.offsetHeight;
         const observer = new MutationObserver(() => {
-          if (
-            this.target.offsetWidth !== initialWidth ||
-                        this.target.offsetHeight !== initialHeight
-          ) {
-            initialWidth = this.target.offsetWidth
-            initialHeight = this.target.offsetHeight
-            if (this.timeouts.textarea) {
-              clearTimeout(this.timeouts.textarea)
+            if (this.target.offsetWidth !== initialWidth || this.target.offsetHeight !== initialHeight) {
+                initialWidth = this.target.offsetWidth;
+                initialHeight = this.target.offsetHeight;
+                if (this.timeouts["textarea"]) {
+                    clearTimeout(this.timeouts["textarea"]);
             }
-            this.timeouts.textarea = setTimeout(() => {
-              this.timeouts.textarea = null
-              this.init()
-            }, 100)
+                this.timeouts["textarea"] = setTimeout(() => {
+                    this.timeouts["textarea"] = null;
+                    this.init();
+                }, 100);
           }
-        })
-        observer.observe(this.target, {
-          attributes: true,
-          attributeFilter: ['style']
-        })
+        });
+          observer.observe(this.target, {attributes: true, attributeFilter: ["style"]});
       }
     },
     // You can define any other Alpine.js functions here.
-    initializeDialog: function (dialog = null) {
+      initializeDialog: function (dialog = null) {
       if (!dialog) {
-        dialog = this.$el.querySelector('[data-dialog]')
+          dialog = this.$el.querySelector("[data-dialog]");
       }
-      const dialogPath = dialog.querySelector('[data-dialog-path]')
-      const rect = this.elementRect()
-      const stroke = dialog.querySelector('[data-dialog-stroke]')
+          const dialogPath = dialog.querySelector("[data-dialog-path]");
+          const rect = this.elementRect();
+          const stroke = dialog.querySelector("[data-dialog-stroke]");
       window.scrollTo({
         top: rect[0].y - window.innerHeight / 3,
         left: rect[0].x,
-        behavior: 'smooth'
-      })
-      const width = rect[1].x - rect[0].x
-      const height = rect[2].y - rect[0].y
-      const x = rect[0].x
-      const y = rect[0].y
-      dialog.style.width = `${width}px`
-      dialog.style.transform = `translate(${x}px, ${y}px)`
-      stroke.style.height = `${height}px`
-      dialogPath.setAttribute(
-        'd',
-        this.elementPath(null, { relative: true, positive: true })
-      )
+          behavior: "smooth"
+      });
+          const width = rect[1].x - rect[0].x;
+          const height = rect[2].y - rect[0].y;
+          const x = rect[0].x;
+          const y = rect[0].y;
path: public/js/guava/tutorials/components/step.js
user: login: sourcery-ai[bot]
body: **suggestion (code-quality):** Prefer object destructuring when accessing and using properties. ([`use-object-destructuring`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/use-object-destructuring))

```suggestion
          const {y} = rect[0];
```

<br/><details><summary>Explanation</summary>Object destructuring can often remove an unnecessary temporary reference, as well as making your code more succinct.

From the [Airbnb Javascript Style Guide](https://airbnb.io/javascript/#destructuring--object)
</details>
created_at: 2025-04-23T16:44:58Z
author_association: CONTRIBUTOR

PR comments:
user: login: sourcery-ai[bot]
created_at: 2025-04-23T16:43:59Z
body: <!-- Generated by sourcery-ai[bot]: start review_guide -->

## Reviewer's Guide by Sourcery

This pull request updates dependencies in `composer.lock` and refactors `step.js` for improved code quality and simplified logic. The `step.js` refactor focuses on code formatting and simplifying the initialization of tutorial components. The dependency updates ensure compatibility and access to the latest features.

_No diagrams generated as the changes look simple and do not need a visual representation._

### File-Level Changes

| Change | Details | Files |
| ------ | ------- | ----- |
| Refactor step.js for improved readability and simplified initialization logic. | <ul><li>Code formatting was made more consistent.</li><li>Simplified the initialization logic for tutorial components.</li><li>Removed unused variables and simplified expressions.</li><li>Improved readability by renaming variables and functions.</li></ul> | `public/js/guava/tutorials/components/step.js` |
| Update dependencies to latest versions. | <ul><li>Upgraded filament/* packages to the latest versions.</li><li>Upgraded laravel/framework package to the latest version.</li><li>Ensured compatibility and access to new features by updating package versions.</li></ul> | `composer.lock` |

---

<details>
<summary>Tips and commands</summary>

#### Interacting with Sourcery

- **Trigger a new review:** Comment `@sourcery-ai review` on the pull request.
- **Continue discussions:** Reply directly to Sourcery's review comments.
- **Generate a GitHub issue from a review comment:** Ask Sourcery to create an
  issue from a review comment by replying to it. You can also reply to a
  review comment with `@sourcery-ai issue` to create an issue from it.
- **Generate a pull request title:** Write `@sourcery-ai` anywhere in the pull
  request title to generate a title at any time. You can also comment
  `@sourcery-ai title` on the pull request to (re-)generate the title at any time.
- **Generate a pull request summary:** Write `@sourcery-ai summary` anywhere in
  the pull request body to generate a PR summary at any time exactly where you
  want it. You can also comment `@sourcery-ai summary` on the pull request to
  (re-)generate the summary at any time.
- **Generate reviewer's guide:** Comment `@sourcery-ai guide` on the pull
  request to (re-)generate the reviewer's guide at any time.
- **Resolve all Sourcery comments:** Comment `@sourcery-ai resolve` on the
  pull request to resolve all Sourcery comments. Useful if you've already
  addressed all the comments and don't want to see them anymore.
- **Dismiss all Sourcery reviews:** Comment `@sourcery-ai dismiss` on the pull
  request to dismiss all existing Sourcery reviews. Especially useful if you
  want to start fresh with a new review - don't forget to comment
  `@sourcery-ai review` to trigger a new review!

#### Customizing Your Experience

Access your [dashboard](https://app.sourcery.ai) to:
- Enable or disable review features such as the Sourcery-generated pull request
  summary, the reviewer's guide, and others.
- Change the review language.
- Add, remove or edit custom review instructions.
- Adjust other review settings.

#### Getting Help

- [Contact our support team](mailto:support@sourcery.ai) for questions or feedback.
- Visit our [documentation](https://docs.sourcery.ai) for detailed guides and information.
- Keep in touch with the Sourcery team by following us on [X/Twitter](https://x.com/SourceryAI), [LinkedIn](https://www.linkedin.com/company/sourcery-ai/) or [GitHub](https://github.com/sourcery-ai).

</details>

<!-- Generated by sourcery-ai[bot]: end review_guide -->
author_association: CONTRIBUTOR
user: login: deepsource-io[bot]
created_at: 2025-04-23T16:44:00Z
body: <div><p>Here's the code health analysis summary for commits <code>15a8bfd..142926f</code>. <a href="https://app.deepsource.com/gh/crimsonstrife/streamer.live/run/f9ed0152-7d42-47a4-aa56-f78c76059668/">View details on DeepSource</a>&nbsp;↗.</p><h3>Analysis Summary</h3><table><thead><tr><th>Analyzer</th><th>Status</th><th>Summary</th><th>Link</th></tr></thead><tbody><tr><td><img src="https://static.deepsource.com/analyzer_logos/javascript.svg" alt="DeepSource JavaScript Logo" width="16px" height="16px"/><strong>JavaScript</strong></td><td><span>❌&nbsp;</span><span>Failure</span></td><td><div>❗ 52 occurences introduced</div><div>🎯 52 occurences resolved</div></td><td><a href="https://app.deepsource.com/gh/crimsonstrife/streamer.live/run/f9ed0152-7d42-47a4-aa56-f78c76059668/javascript/">View Check</a>&nbsp;↗</td></tr><tr><td><img src="https://static.deepsource.com/analyzer_logos/php.svg" alt="DeepSource PHP Logo" width="16px" height="16px"/><strong>PHP</strong></td><td><span>✅&nbsp;</span><span>Success</span></td><td></td><td><a href="https://app.deepsource.com/gh/crimsonstrife/streamer.live/run/f9ed0152-7d42-47a4-aa56-f78c76059668/php/">View Check</a>&nbsp;↗</td></tr></tbody></table><hr/><blockquote><div>💡 If you’re a repository administrator, you can configure the quality gates from the <a href="https://app.deepsource.com/gh/crimsonstrife/streamer.live/settings/reporting">settings</a>.</div></blockquote></div>

author_association: NONE