Repository: SVG-Edit/svgedit (language: python)

Issue:
X, Y coordinates not working for a group element
Create a element you can change x or y coordinates with decimal precision , for example 10.5 , but when you group one or more elements ,you can not change X,Y coordinates to 10.5 for the group , the work around is to enter for example 105 and after that add the dot between 0 and 5. Please can you fix this.


Discussion / hints:
Yes, this is a bug. It's going to be fixed soon. 


Fix patch:
diff --git a/.github/workflows/npmpublish on demand.yml b/.github/workflows/npmpublish on demand.yml
index a13192b8d..37470c1ad 100644
--- a/.github/workflows/npmpublish on demand.yml
+++ b/.github/workflows/npmpublish on demand.yml
@@ -9,7 +9,7 @@ jobs:
       - uses: actions/checkout@v3
       - uses: actions/setup-node@v3
         with:
-          node-version: 16.x
+          node-version: 20.x
       - run: |
           npm ci
           npm run build --workspace=packages/svgcanvas
@@ -24,7 +24,7 @@ jobs:
       - uses: actions/checkout@v3
       - uses: actions/setup-node@v3
         with:
-          node-version: 16
+          node-version: 20
           registry-url: https://registry.npmjs.org/
       - run: |
           npm ci
diff --git a/.github/workflows/npmpublish.yml b/.github/workflows/npmpublish.yml
index 73b6d9155..4bcaeedb1 100644
--- a/.github/workflows/npmpublish.yml
+++ b/.github/workflows/npmpublish.yml
@@ -11,7 +11,7 @@ jobs:
       - uses: actions/checkout@v3
       - uses: actions/setup-node@v3
         with:
-          node-version: 16.x
+          node-version: 20.x
       - run: |
           npm ci
           npm run build --workspace=packages/svgcanvas
@@ -26,7 +26,7 @@ jobs:
       - uses: actions/checkout@v3
       - uses: actions/setup-node@v3
         with:
-          node-version: 16
+          node-version: 20
           registry-url: https://registry.npmjs.org/
       - run: npm publish
         env:
diff --git a/.github/workflows/onpullrequest.yml b/.github/workflows/onpullrequest.yml
index deb948de6..b5572acc3 100644
--- a/.github/workflows/onpullrequest.yml
+++ b/.github/workflows/onpullrequest.yml
@@ -12,7 +12,7 @@ jobs:
     - name: Use Node.js
       uses: actions/setup-node@v3
       with:
-        node-version: 16.x
+        node-version: 20.x
     - name: npm install, test and lint
       run: |
         npm ci
diff --git a/.github/workflows/onpush.yml b/.github/workflows/onpush.yml
index e8e9c923e..1a1474f65 100644
--- a/.github/workflows/onpush.yml
+++ b/.github/workflows/onpush.yml
@@ -12,7 +12,7 @@ jobs:
     - name: Use Node.js
       uses: actions/setup-node@v3
       with:
-        node-version: 16.x
+        node-version: 20.x
     - name: npm install, test and lint
       run: |
         npm ci
diff --git a/coverage/coverage-summary.json b/coverage/coverage-summary.json
index 4a45cfe53..cf04a894a 100644
--- a/coverage/coverage-summary.json
+++ b/coverage/coverage-summary.json
@@ -1,69 +1,71 @@
-{"total": {"lines":{"total":6260,"covered":3796,"skipped":0,"pct":60.64},"statements":{"total":6574,"covered":3913,"skipped":0,"pct":59.52},"functions":{"total":949,"covered":495,"skipped":0,"pct":52.16},"branches":{"total":3223,"covered":1398,"skipped":0,"pct":43.38}}
-,"/Users/jfhenon/Work/svgedit/packages/svgcanvas/common/browser.js": {"lines":{"total":25,"covered":24,"skipped":0,"pct":96},"functions":{"total":6,"covered":2,"skipped":0,"pct":33.33},"statements":{"total":30,"covered":25,"skipped":0,"pct":83.33},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/packages/svgcanvas/common/util.js": {"lines":{"total":90,"covered":8,"skipped":0,"pct":8.89},"functions":{"total":7,"covered":3,"skipped":0,"pct":42.86},"statements":{"total":92,"covered":10,"skipped":0,"pct":10.87},"branches":{"total":98,"covered":10,"skipped":0,"pct":10.2}}
-,"/Users/jfhenon/Work/svgedit/src/editor/ConfigObj.js": {"lines":{"total":101,"covered":46,"skipped":0,"pct":45.54},"functions":{"total":14,"covered":11,"skipped":0,"pct":78.57},"statements":{"total":102,"covered":46,"skipped":0,"pct":45.1},"branches":{"total":96,"covered":30,"skipped":0,"pct":31.25}}
-,"/Users/jfhenon/Work/svgedit/src/editor/Editor.js": {"lines":{"total":410,"covered":200,"skipped":0,"pct":48.78},"functions":{"total":102,"covered":34,"skipped":0,"pct":33.33},"statements":{"total":417,"covered":201,"skipped":0,"pct":48.2},"branches":{"total":213,"covered":78,"skipped":0,"pct":36.62}}
-,"/Users/jfhenon/Work/svgedit/src/editor/EditorStartup.js": {"lines":{"total":346,"covered":216,"skipped":0,"pct":62.43},"functions":{"total":51,"covered":27,"skipped":0,"pct":52.94},"statements":{"total":357,"covered":224,"skipped":0,"pct":62.75},"branches":{"total":122,"covered":41,"skipped":0,"pct":33.61}}
-,"/Users/jfhenon/Work/svgedit/src/editor/MainMenu.js": {"lines":{"total":111,"covered":44,"skipped":0,"pct":39.64},"functions":{"total":14,"covered":7,"skipped":0,"pct":50},"statements":{"total":111,"covered":44,"skipped":0,"pct":39.64},"branches":{"total":48,"covered":7,"skipped":0,"pct":14.58}}
-,"/Users/jfhenon/Work/svgedit/src/editor/Rulers.js": {"lines":{"total":119,"covered":93,"skipped":0,"pct":78.15},"functions":{"total":6,"covered":5,"skipped":0,"pct":83.33},"statements":{"total":124,"covered":98,"skipped":0,"pct":79.03},"branches":{"total":43,"covered":32,"skipped":0,"pct":74.42}}
-,"/Users/jfhenon/Work/svgedit/src/editor/browser-not-supported.js": {"lines":{"total":4,"covered":3,"skipped":0,"pct":75},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":4,"covered":3,"skipped":0,"pct":75},"branches":{"total":4,"covered":3,"skipped":0,"pct":75}}
-,"/Users/jfhenon/Work/svgedit/src/editor/contextmenu.js": {"lines":{"total":22,"covered":9,"skipped":0,"pct":40.91},"functions":{"total":8,"covered":1,"skipped":0,"pct":12.5},"statements":{"total":23,"covered":9,"skipped":0,"pct":39.13},"branches":{"total":13,"covered":0,"skipped":0,"pct":0}}
-,"/Users/jfhenon/Work/svgedit/src/editor/locale.js": {"lines":{"total":14,"covered":9,"skipped":0,"pct":64.29},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":14,"covered":9,"skipped":0,"pct":64.29},"branches":{"total":10,"covered":3,"skipped":0,"pct":30}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/PaintBox.js": {"lines":{"total":64,"covered":51,"skipped":0,"pct":79.69},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"statements":{"total":67,"covered":53,"skipped":0,"pct":79.1},"branches":{"total":33,"covered":21,"skipped":0,"pct":63.64}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/index.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seButton.js": {"lines":{"total":57,"covered":40,"skipped":0,"pct":70.18},"functions":{"total":15,"covered":7,"skipped":0,"pct":46.67},"statements":{"total":60,"covered":42,"skipped":0,"pct":70},"branches":{"total":33,"covered":23,"skipped":0,"pct":69.7}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seColorPicker.js": {"lines":{"total":50,"covered":41,"skipped":0,"pct":82},"functions":{"total":16,"covered":11,"skipped":0,"pct":68.75},"statements":{"total":51,"covered":41,"skipped":0,"pct":80.39},"branches":{"total":11,"covered":8,"skipped":0,"pct":72.73}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seExplorerButton.js": {"lines":{"total":95,"covered":72,"skipped":0,"pct":75.79},"functions":{"total":17,"covered":10,"skipped":0,"pct":58.82},"statements":{"total":98,"covered":72,"skipped":0,"pct":73.47},"branches":{"total":30,"covered":17,"skipped":0,"pct":56.67}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seFlyingButton.js": {"lines":{"total":74,"covered":47,"skipped":0,"pct":63.51},"functions":{"total":14,"covered":9,"skipped":0,"pct":64.29},"statements":{"total":75,"covered":48,"skipped":0,"pct":64},"branches":{"total":29,"covered":12,"skipped":0,"pct":41.38}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seInput.js": {"lines":{"total":46,"covered":31,"skipped":0,"pct":67.39},"functions":{"total":16,"covered":8,"skipped":0,"pct":50},"statements":{"total":47,"covered":31,"skipped":0,"pct":65.96},"branches":{"total":8,"covered":4,"skipped":0,"pct":50}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seList.js": {"lines":{"total":87,"covered":59,"skipped":0,"pct":67.82},"functions":{"total":21,"covered":10,"skipped":0,"pct":47.62},"statements":{"total":89,"covered":61,"skipped":0,"pct":68.54},"branches":{"total":22,"covered":12,"skipped":0,"pct":54.55}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seListItem.js": {"lines":{"total":39,"covered":26,"skipped":0,"pct":66.67},"functions":{"total":12,"covered":4,"skipped":0,"pct":33.33},"statements":{"total":40,"covered":27,"skipped":0,"pct":67.5},"branches":{"total":10,"covered":8,"skipped":0,"pct":80}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seMenu.js": {"lines":{"total":26,"covered":20,"skipped":0,"pct":76.92},"functions":{"total":7,"covered":3,"skipped":0,"pct":42.86},"statements":{"total":27,"covered":20,"skipped":0,"pct":74.07},"branches":{"total":5,"covered":3,"skipped":0,"pct":60}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seMenuItem.js": {"lines":{"total":37,"covered":26,"skipped":0,"pct":70.27},"functions":{"total":9,"covered":5,"skipped":0,"pct":55.56},"statements":{"total":40,"covered":27,"skipped":0,"pct":67.5},"branches":{"total":19,"covered":8,"skipped":0,"pct":42.11}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/sePalette.js": {"lines":{"total":33,"covered":32,"skipped":0,"pct":96.97},"functions":{"total":7,"covered":7,"skipped":0,"pct":100},"statements":{"total":33,"covered":32,"skipped":0,"pct":96.97},"branches":{"total":13,"covered":10,"skipped":0,"pct":76.92}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/sePlainBorderButton.js": {"lines":{"total":3,"covered":3,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":3,"covered":3,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/sePlainMenuButton.js": {"lines":{"total":2,"covered":2,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":2,"covered":2,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seSelect.js": {"lines":{"total":56,"covered":45,"skipped":0,"pct":80.36},"functions":{"total":17,"covered":9,"skipped":0,"pct":52.94},"statements":{"total":59,"covered":47,"skipped":0,"pct":79.66},"branches":{"total":16,"covered":14,"skipped":0,"pct":87.5}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seSpinInput.js": {"lines":{"total":65,"covered":55,"skipped":0,"pct":84.62},"functions":{"total":18,"covered":10,"skipped":0,"pct":55.56},"statements":{"total":66,"covered":55,"skipped":0,"pct":83.33},"branches":{"total":17,"covered":13,"skipped":0,"pct":76.47}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seText.js": {"lines":{"total":28,"covered":18,"skipped":0,"pct":64.29},"functions":{"total":10,"covered":4,"skipped":0,"pct":40},"statements":{"total":29,"covered":18,"skipped":0,"pct":62.07},"branches":{"total":8,"covered":5,"skipped":0,"pct":62.5}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/seZoom.js": {"lines":{"total":99,"covered":93,"skipped":0,"pct":93.94},"functions":{"total":28,"covered":24,"skipped":0,"pct":85.71},"statements":{"total":107,"covered":100,"skipped":0,"pct":93.46},"branches":{"total":36,"covered":21,"skipped":0,"pct":58.33}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/jgraduate/ColorValuePicker.js": {"lines":{"total":231,"covered":54,"skipped":0,"pct":23.38},"functions":{"total":9,"covered":3,"skipped":0,"pct":33.33},"statements":{"total":249,"covered":63,"skipped":0,"pct":25.3},"branches":{"total":157,"covered":34,"skipped":0,"pct":21.66}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/jgraduate/Slider.js": {"lines":{"total":156,"covered":91,"skipped":0,"pct":58.33},"functions":{"total":17,"covered":9,"skipped":0,"pct":52.94},"statements":{"total":176,"covered":96,"skipped":0,"pct":54.55},"branches":{"total":186,"covered":97,"skipped":0,"pct":52.15}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/jgraduate/jQuery.jGraduate.js": {"lines":{"total":580,"covered":275,"skipped":0,"pct":47.41},"functions":{"total":44,"covered":14,"skipped":0,"pct":31.82},"statements":{"total":602,"covered":282,"skipped":0,"pct":46.84},"branches":{"total":278,"covered":100,"skipped":0,"pct":35.97}}
-,"/Users/jfhenon/Work/svgedit/src/editor/components/jgraduate/jQuery.jPicker.js": {"lines":{"total":840,"covered":449,"skipped":0,"pct":53.45},"functions":{"total":60,"covered":39,"skipped":0,"pct":65},"statements":{"total":926,"covered":475,"skipped":0,"pct":51.3},"branches":{"total":777,"covered":327,"skipped":0,"pct":42.08}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/SePlainAlertDialog.js": {"lines":{"total":7,"covered":1,"skipped":0,"pct":14.29},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":7,"covered":1,"skipped":0,"pct":14.29},"branches":{"total":2,"covered":0,"skipped":0,"pct":0}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/cmenuDialog.js": {"lines":{"total":120,"covered":112,"skipped":0,"pct":93.33},"functions":{"total":28,"covered":16,"skipped":0,"pct":57.14},"statements":{"total":131,"covered":117,"skipped":0,"pct":89.31},"branches":{"total":23,"covered":19,"skipped":0,"pct":82.61}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/cmenuLayersDialog.js": {"lines":{"total":61,"covered":49,"skipped":0,"pct":80.33},"functions":{"total":16,"covered":6,"skipped":0,"pct":37.5},"statements":{"total":66,"covered":49,"skipped":0,"pct":74.24},"branches":{"total":18,"covered":13,"skipped":0,"pct":72.22}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/editorPreferencesDialog.js": {"lines":{"total":157,"covered":125,"skipped":0,"pct":79.62},"functions":{"total":30,"covered":9,"skipped":0,"pct":30},"statements":{"total":159,"covered":126,"skipped":0,"pct":79.25},"branches":{"total":46,"covered":35,"skipped":0,"pct":76.09}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/exportDialog.js": {"lines":{"total":55,"covered":39,"skipped":0,"pct":70.91},"functions":{"total":14,"covered":5,"skipped":0,"pct":35.71},"statements":{"total":58,"covered":39,"skipped":0,"pct":67.24},"branches":{"total":12,"covered":6,"skipped":0,"pct":50}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/imagePropertiesDialog.js": {"lines":{"total":161,"covered":90,"skipped":0,"pct":55.9},"functions":{"total":20,"covered":5,"skipped":0,"pct":25},"statements":{"total":162,"covered":90,"skipped":0,"pct":55.56},"branches":{"total":53,"covered":23,"skipped":0,"pct":43.4}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/index.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/seAlertDialog.js": {"lines":{"total":6,"covered":2,"skipped":0,"pct":33.33},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":6,"covered":2,"skipped":0,"pct":33.33},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/seConfirmDialog.js": {"lines":{"total":8,"covered":2,"skipped":0,"pct":25},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":8,"covered":2,"skipped":0,"pct":25},"branches":{"total":2,"covered":0,"skipped":0,"pct":0}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/sePromptDialog.js": {"lines":{"total":24,"covered":5,"skipped":0,"pct":20.83},"functions":{"total":7,"covered":2,"skipped":0,"pct":28.57},"statements":{"total":24,"covered":5,"skipped":0,"pct":20.83},"branches":{"total":9,"covered":0,"skipped":0,"pct":0}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/seSelectDialog.js": {"lines":{"total":8,"covered":2,"skipped":0,"pct":25},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":8,"covered":2,"skipped":0,"pct":25},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/svgSourceDialog.js": {"lines":{"total":74,"covered":56,"skipped":0,"pct":75.68},"functions":{"total":17,"covered":6,"skipped":0,"pct":35.29},"statements":{"total":75,"covered":57,"skipped":0,"pct":76},"branches":{"total":17,"covered":14,"skipped":0,"pct":82.35}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/se-elix/define/NumberSpinBox.js": {"lines":{"total":1,"covered":1,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":1,"covered":1,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/se-elix/src/base/NumberSpinBox.js": {"lines":{"total":54,"covered":52,"skipped":0,"pct":96.3},"functions":{"total":13,"covered":11,"skipped":0,"pct":84.62},"statements":{"total":54,"covered":52,"skipped":0,"pct":96.3},"branches":{"total":53,"covered":47,"skipped":0,"pct":88.68}}
-,"/Users/jfhenon/Work/svgedit/src/editor/dialogs/se-elix/src/plain/PlainNumberSpinBox.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-eyedropper/ext-eyedropper.js": {"lines":{"total":60,"covered":39,"skipped":0,"pct":65},"functions":{"total":8,"covered":5,"skipped":0,"pct":62.5},"statements":{"total":71,"covered":39,"skipped":0,"pct":54.93},"branches":{"total":39,"covered":15,"skipped":0,"pct":38.46}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-eyedropper/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-grid/ext-grid.js": {"lines":{"total":88,"covered":43,"skipped":0,"pct":48.86},"functions":{"total":8,"covered":4,"skipped":0,"pct":50},"statements":{"total":90,"covered":43,"skipped":0,"pct":47.78},"branches":{"total":10,"covered":4,"skipped":0,"pct":40}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-grid/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-markers/ext-markers.js": {"lines":{"total":149,"covered":46,"skipped":0,"pct":30.87},"functions":{"total":21,"covered":12,"skipped":0,"pct":57.14},"statements":{"total":164,"covered":48,"skipped":0,"pct":29.27},"branches":{"total":80,"covered":22,"skipped":0,"pct":27.5}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-opensave/ext-opensave.js": {"lines":{"total":136,"covered":36,"skipped":0,"pct":26.47},"functions":{"total":13,"covered":3,"skipped":0,"pct":23.08},"statements":{"total":141,"covered":36,"skipped":0,"pct":25.53},"branches":{"total":32,"covered":0,"skipped":0,"pct":0}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-opensave/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-panning/ext-panning.js": {"lines":{"total":30,"covered":22,"skipped":0,"pct":73.33},"functions":{"total":7,"covered":6,"skipped":0,"pct":85.71},"statements":{"total":30,"covered":22,"skipped":0,"pct":73.33},"branches":{"total":6,"covered":2,"skipped":0,"pct":33.33}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-panning/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-polystar/ext-polystar.js": {"lines":{"total":247,"covered":232,"skipped":0,"pct":93.93},"functions":{"total":18,"covered":16,"skipped":0,"pct":88.89},"statements":{"total":256,"covered":241,"skipped":0,"pct":94.14},"branches":{"total":62,"covered":39,"skipped":0,"pct":62.9}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-polystar/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-shapes/ext-shapes.js": {"lines":{"total":76,"covered":74,"skipped":0,"pct":97.37},"functions":{"total":7,"covered":7,"skipped":0,"pct":100},"statements":{"total":80,"covered":78,"skipped":0,"pct":97.5},"branches":{"total":26,"covered":17,"skipped":0,"pct":65.38}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-shapes/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-storage/ext-storage.js": {"lines":{"total":91,"covered":59,"skipped":0,"pct":64.84},"functions":{"total":12,"covered":7,"skipped":0,"pct":58.33},"statements":{"total":91,"covered":59,"skipped":0,"pct":64.84},"branches":{"total":68,"covered":27,"skipped":0,"pct":39.71}}
-,"/Users/jfhenon/Work/svgedit/src/editor/extensions/ext-storage/storageDialog.js": {"lines":{"total":60,"covered":56,"skipped":0,"pct":93.33},"functions":{"total":10,"covered":7,"skipped":0,"pct":70},"statements":{"total":62,"covered":57,"skipped":0,"pct":91.94},"branches":{"total":15,"covered":13,"skipped":0,"pct":86.67}}
-,"/Users/jfhenon/Work/svgedit/src/editor/locale/lang.en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
-,"/Users/jfhenon/Work/svgedit/src/editor/panels/BottomPanel.js": {"lines":{"total":71,"covered":58,"skipped":0,"pct":81.69},"functions":{"total":22,"covered":14,"skipped":0,"pct":63.64},"statements":{"total":77,"covered":61,"skipped":0,"pct":79.22},"branches":{"total":30,"covered":16,"skipped":0,"pct":53.33}}
-,"/Users/jfhenon/Work/svgedit/src/editor/panels/LayersPanel.js": {"lines":{"total":157,"covered":70,"skipped":0,"pct":44.59},"functions":{"total":27,"covered":6,"skipped":0,"pct":22.22},"statements":{"total":163,"covered":71,"skipped":0,"pct":43.56},"branches":{"total":46,"covered":6,"skipped":0,"pct":13.04}}
-,"/Users/jfhenon/Work/svgedit/src/editor/panels/LeftPanel.js": {"lines":{"total":58,"covered":47,"skipped":0,"pct":81.03},"functions":{"total":20,"covered":15,"skipped":0,"pct":75},"statements":{"total":59,"covered":47,"skipped":0,"pct":79.66},"branches":{"total":32,"covered":12,"skipped":0,"pct":37.5}}
-,"/Users/jfhenon/Work/svgedit/src/editor/panels/TopPanel.js": {"lines":{"total":391,"covered":296,"skipped":0,"pct":75.7},"functions":{"total":73,"covered":48,"skipped":0,"pct":65.75},"statements":{"total":411,"covered":304,"skipped":0,"pct":73.97},"branches":{"total":207,"covered":127,"skipped":0,"pct":61.35}}
+{"total": {"lines":{"total":6564,"covered":3798,"skipped":0,"pct":57.86},"statements":{"total":6874,"covered":3901,"skipped":0,"pct":56.75},"functions":{"total":976,"covered":490,"skipped":0,"pct":50.2},"branches":{"total":3361,"covered":1358,"skipped":0,"pct":40.4}}
+,"/Users/jean-francoishenon/Work/svgedit/packages/svgcanvas/common/browser.js": {"lines":{"total":25,"covered":24,"skipped":0,"pct":96},"functions":{"total":6,"covered":2,"skipped":0,"pct":33.33},"statements":{"total":30,"covered":25,"skipped":0,"pct":83.33},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/packages/svgcanvas/common/util.js": {"lines":{"total":90,"covered":8,"skipped":0,"pct":8.89},"functions":{"total":7,"covered":3,"skipped":0,"pct":42.86},"statements":{"total":92,"covered":10,"skipped":0,"pct":10.87},"branches":{"total":98,"covered":10,"skipped":0,"pct":10.2}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/ConfigObj.js": {"lines":{"total":101,"covered":49,"skipped":0,"pct":48.51},"functions":{"total":14,"covered":11,"skipped":0,"pct":78.57},"statements":{"total":102,"covered":49,"skipped":0,"pct":48.04},"branches":{"total":96,"covered":33,"skipped":0,"pct":34.38}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/Editor.js": {"lines":{"total":410,"covered":184,"skipped":0,"pct":44.88},"functions":{"total":102,"covered":32,"skipped":0,"pct":31.37},"statements":{"total":417,"covered":185,"skipped":0,"pct":44.36},"branches":{"total":213,"covered":68,"skipped":0,"pct":31.92}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/EditorStartup.js": {"lines":{"total":346,"covered":211,"skipped":0,"pct":60.98},"functions":{"total":51,"covered":26,"skipped":0,"pct":50.98},"statements":{"total":357,"covered":219,"skipped":0,"pct":61.34},"branches":{"total":122,"covered":38,"skipped":0,"pct":31.15}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/MainMenu.js": {"lines":{"total":111,"covered":44,"skipped":0,"pct":39.64},"functions":{"total":14,"covered":7,"skipped":0,"pct":50},"statements":{"total":111,"covered":44,"skipped":0,"pct":39.64},"branches":{"total":48,"covered":7,"skipped":0,"pct":14.58}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/Rulers.js": {"lines":{"total":119,"covered":91,"skipped":0,"pct":76.47},"functions":{"total":6,"covered":4,"skipped":0,"pct":66.67},"statements":{"total":124,"covered":94,"skipped":0,"pct":75.81},"branches":{"total":43,"covered":30,"skipped":0,"pct":69.77}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/browser-not-supported.js": {"lines":{"total":4,"covered":3,"skipped":0,"pct":75},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":4,"covered":3,"skipped":0,"pct":75},"branches":{"total":4,"covered":3,"skipped":0,"pct":75}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/contextmenu.js": {"lines":{"total":22,"covered":9,"skipped":0,"pct":40.91},"functions":{"total":8,"covered":1,"skipped":0,"pct":12.5},"statements":{"total":23,"covered":9,"skipped":0,"pct":39.13},"branches":{"total":13,"covered":0,"skipped":0,"pct":0}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/locale.js": {"lines":{"total":14,"covered":9,"skipped":0,"pct":64.29},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":14,"covered":9,"skipped":0,"pct":64.29},"branches":{"total":10,"covered":3,"skipped":0,"pct":30}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/PaintBox.js": {"lines":{"total":64,"covered":35,"skipped":0,"pct":54.69},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"statements":{"total":67,"covered":35,"skipped":0,"pct":52.24},"branches":{"total":33,"covered":12,"skipped":0,"pct":36.36}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/index.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seButton.js": {"lines":{"total":57,"covered":40,"skipped":0,"pct":70.18},"functions":{"total":15,"covered":7,"skipped":0,"pct":46.67},"statements":{"total":60,"covered":42,"skipped":0,"pct":70},"branches":{"total":33,"covered":23,"skipped":0,"pct":69.7}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seColorPicker.js": {"lines":{"total":50,"covered":41,"skipped":0,"pct":82},"functions":{"total":16,"covered":11,"skipped":0,"pct":68.75},"statements":{"total":51,"covered":41,"skipped":0,"pct":80.39},"branches":{"total":11,"covered":8,"skipped":0,"pct":72.73}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seExplorerButton.js": {"lines":{"total":95,"covered":72,"skipped":0,"pct":75.79},"functions":{"total":17,"covered":10,"skipped":0,"pct":58.82},"statements":{"total":98,"covered":72,"skipped":0,"pct":73.47},"branches":{"total":30,"covered":17,"skipped":0,"pct":56.67}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seFlyingButton.js": {"lines":{"total":74,"covered":47,"skipped":0,"pct":63.51},"functions":{"total":14,"covered":9,"skipped":0,"pct":64.29},"statements":{"total":75,"covered":48,"skipped":0,"pct":64},"branches":{"total":29,"covered":12,"skipped":0,"pct":41.38}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seInput.js": {"lines":{"total":46,"covered":31,"skipped":0,"pct":67.39},"functions":{"total":16,"covered":8,"skipped":0,"pct":50},"statements":{"total":47,"covered":31,"skipped":0,"pct":65.96},"branches":{"total":8,"covered":4,"skipped":0,"pct":50}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seList.js": {"lines":{"total":87,"covered":59,"skipped":0,"pct":67.82},"functions":{"total":21,"covered":10,"skipped":0,"pct":47.62},"statements":{"total":89,"covered":61,"skipped":0,"pct":68.54},"branches":{"total":22,"covered":12,"skipped":0,"pct":54.55}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seListItem.js": {"lines":{"total":39,"covered":26,"skipped":0,"pct":66.67},"functions":{"total":12,"covered":4,"skipped":0,"pct":33.33},"statements":{"total":40,"covered":27,"skipped":0,"pct":67.5},"branches":{"total":10,"covered":8,"skipped":0,"pct":80}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seMenu.js": {"lines":{"total":26,"covered":20,"skipped":0,"pct":76.92},"functions":{"total":7,"covered":3,"skipped":0,"pct":42.86},"statements":{"total":27,"covered":20,"skipped":0,"pct":74.07},"branches":{"total":5,"covered":3,"skipped":0,"pct":60}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seMenuItem.js": {"lines":{"total":37,"covered":26,"skipped":0,"pct":70.27},"functions":{"total":9,"covered":5,"skipped":0,"pct":55.56},"statements":{"total":40,"covered":27,"skipped":0,"pct":67.5},"branches":{"total":19,"covered":8,"skipped":0,"pct":42.11}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/sePalette.js": {"lines":{"total":33,"covered":32,"skipped":0,"pct":96.97},"functions":{"total":7,"covered":7,"skipped":0,"pct":100},"statements":{"total":33,"covered":32,"skipped":0,"pct":96.97},"branches":{"total":13,"covered":10,"skipped":0,"pct":76.92}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/sePlainBorderButton.js": {"lines":{"total":3,"covered":3,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":3,"covered":3,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/sePlainMenuButton.js": {"lines":{"total":2,"covered":2,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":2,"covered":2,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seSelect.js": {"lines":{"total":56,"covered":45,"skipped":0,"pct":80.36},"functions":{"total":17,"covered":9,"skipped":0,"pct":52.94},"statements":{"total":59,"covered":47,"skipped":0,"pct":79.66},"branches":{"total":16,"covered":14,"skipped":0,"pct":87.5}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seSpinInput.js": {"lines":{"total":65,"covered":55,"skipped":0,"pct":84.62},"functions":{"total":18,"covered":10,"skipped":0,"pct":55.56},"statements":{"total":66,"covered":55,"skipped":0,"pct":83.33},"branches":{"total":17,"covered":13,"skipped":0,"pct":76.47}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seText.js": {"lines":{"total":28,"covered":18,"skipped":0,"pct":64.29},"functions":{"total":10,"covered":4,"skipped":0,"pct":40},"statements":{"total":29,"covered":18,"skipped":0,"pct":62.07},"branches":{"total":8,"covered":5,"skipped":0,"pct":62.5}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/seZoom.js": {"lines":{"total":102,"covered":65,"skipped":0,"pct":63.73},"functions":{"total":28,"covered":9,"skipped":0,"pct":32.14},"statements":{"total":107,"covered":66,"skipped":0,"pct":61.68},"branches":{"total":36,"covered":7,"skipped":0,"pct":19.44}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/jgraduate/ColorValuePicker.js": {"lines":{"total":231,"covered":54,"skipped":0,"pct":23.38},"functions":{"total":9,"covered":3,"skipped":0,"pct":33.33},"statements":{"total":249,"covered":63,"skipped":0,"pct":25.3},"branches":{"total":157,"covered":34,"skipped":0,"pct":21.66}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/jgraduate/Slider.js": {"lines":{"total":156,"covered":91,"skipped":0,"pct":58.33},"functions":{"total":17,"covered":9,"skipped":0,"pct":52.94},"statements":{"total":176,"covered":96,"skipped":0,"pct":54.55},"branches":{"total":186,"covered":97,"skipped":0,"pct":52.15}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/jgraduate/jQuery.jGraduate.js": {"lines":{"total":580,"covered":275,"skipped":0,"pct":47.41},"functions":{"total":44,"covered":14,"skipped":0,"pct":31.82},"statements":{"total":602,"covered":282,"skipped":0,"pct":46.84},"branches":{"total":278,"covered":100,"skipped":0,"pct":35.97}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/components/jgraduate/jQuery.jPicker.js": {"lines":{"total":840,"covered":449,"skipped":0,"pct":53.45},"functions":{"total":60,"covered":39,"skipped":0,"pct":65},"statements":{"total":926,"covered":475,"skipped":0,"pct":51.3},"branches":{"total":777,"covered":327,"skipped":0,"pct":42.08}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/SePlainAlertDialog.js": {"lines":{"total":7,"covered":1,"skipped":0,"pct":14.29},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":7,"covered":1,"skipped":0,"pct":14.29},"branches":{"total":2,"covered":0,"skipped":0,"pct":0}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/cmenuDialog.js": {"lines":{"total":120,"covered":112,"skipped":0,"pct":93.33},"functions":{"total":28,"covered":15,"skipped":0,"pct":53.57},"statements":{"total":131,"covered":116,"skipped":0,"pct":88.55},"branches":{"total":23,"covered":19,"skipped":0,"pct":82.61}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/cmenuLayersDialog.js": {"lines":{"total":61,"covered":49,"skipped":0,"pct":80.33},"functions":{"total":16,"covered":6,"skipped":0,"pct":37.5},"statements":{"total":66,"covered":49,"skipped":0,"pct":74.24},"branches":{"total":18,"covered":13,"skipped":0,"pct":72.22}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/editorPreferencesDialog.js": {"lines":{"total":157,"covered":124,"skipped":0,"pct":78.98},"functions":{"total":30,"covered":9,"skipped":0,"pct":30},"statements":{"total":159,"covered":125,"skipped":0,"pct":78.62},"branches":{"total":46,"covered":34,"skipped":0,"pct":73.91}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/exportDialog.js": {"lines":{"total":55,"covered":39,"skipped":0,"pct":70.91},"functions":{"total":14,"covered":5,"skipped":0,"pct":35.71},"statements":{"total":58,"covered":39,"skipped":0,"pct":67.24},"branches":{"total":12,"covered":6,"skipped":0,"pct":50}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/imagePropertiesDialog.js": {"lines":{"total":161,"covered":90,"skipped":0,"pct":55.9},"functions":{"total":20,"covered":5,"skipped":0,"pct":25},"statements":{"total":162,"covered":90,"skipped":0,"pct":55.56},"branches":{"total":53,"covered":23,"skipped":0,"pct":43.4}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/index.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/seAlertDialog.js": {"lines":{"total":6,"covered":2,"skipped":0,"pct":33.33},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":6,"covered":2,"skipped":0,"pct":33.33},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/seConfirmDialog.js": {"lines":{"total":8,"covered":2,"skipped":0,"pct":25},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":8,"covered":2,"skipped":0,"pct":25},"branches":{"total":2,"covered":0,"skipped":0,"pct":0}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/sePromptDialog.js": {"lines":{"total":24,"covered":5,"skipped":0,"pct":20.83},"functions":{"total":7,"covered":2,"skipped":0,"pct":28.57},"statements":{"total":24,"covered":5,"skipped":0,"pct":20.83},"branches":{"total":9,"covered":0,"skipped":0,"pct":0}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/seSelectDialog.js": {"lines":{"total":8,"covered":2,"skipped":0,"pct":25},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":8,"covered":2,"skipped":0,"pct":25},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/svgSourceDialog.js": {"lines":{"total":74,"covered":56,"skipped":0,"pct":75.68},"functions":{"total":17,"covered":6,"skipped":0,"pct":35.29},"statements":{"total":75,"covered":56,"skipped":0,"pct":74.67},"branches":{"total":17,"covered":13,"skipped":0,"pct":76.47}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/se-elix/define/NumberSpinBox.js": {"lines":{"total":1,"covered":1,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":1,"covered":1,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/se-elix/src/base/NumberSpinBox.js": {"lines":{"total":54,"covered":52,"skipped":0,"pct":96.3},"functions":{"total":13,"covered":11,"skipped":0,"pct":84.62},"statements":{"total":54,"covered":52,"skipped":0,"pct":96.3},"branches":{"total":53,"covered":47,"skipped":0,"pct":88.68}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/dialogs/se-elix/src/plain/PlainNumberSpinBox.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-connector/ext-connector.js": {"lines":{"total":287,"covered":83,"skipped":0,"pct":28.92},"functions":{"total":26,"covered":16,"skipped":0,"pct":61.54},"statements":{"total":295,"covered":86,"skipped":0,"pct":29.15},"branches":{"total":140,"covered":19,"skipped":0,"pct":13.57}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-connector/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-eyedropper/ext-eyedropper.js": {"lines":{"total":60,"covered":39,"skipped":0,"pct":65},"functions":{"total":8,"covered":5,"skipped":0,"pct":62.5},"statements":{"total":71,"covered":39,"skipped":0,"pct":54.93},"branches":{"total":39,"covered":14,"skipped":0,"pct":35.9}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-eyedropper/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-grid/ext-grid.js": {"lines":{"total":88,"covered":43,"skipped":0,"pct":48.86},"functions":{"total":8,"covered":4,"skipped":0,"pct":50},"statements":{"total":90,"covered":43,"skipped":0,"pct":47.78},"branches":{"total":10,"covered":4,"skipped":0,"pct":40}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-grid/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-markers/ext-markers.js": {"lines":{"total":149,"covered":46,"skipped":0,"pct":30.87},"functions":{"total":21,"covered":12,"skipped":0,"pct":57.14},"statements":{"total":164,"covered":48,"skipped":0,"pct":29.27},"branches":{"total":80,"covered":22,"skipped":0,"pct":27.5}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-opensave/ext-opensave.js": {"lines":{"total":136,"covered":36,"skipped":0,"pct":26.47},"functions":{"total":13,"covered":3,"skipped":0,"pct":23.08},"statements":{"total":141,"covered":36,"skipped":0,"pct":25.53},"branches":{"total":32,"covered":0,"skipped":0,"pct":0}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-opensave/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-panning/ext-panning.js": {"lines":{"total":30,"covered":22,"skipped":0,"pct":73.33},"functions":{"total":7,"covered":6,"skipped":0,"pct":85.71},"statements":{"total":30,"covered":22,"skipped":0,"pct":73.33},"branches":{"total":6,"covered":2,"skipped":0,"pct":33.33}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-panning/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-polystar/ext-polystar.js": {"lines":{"total":247,"covered":232,"skipped":0,"pct":93.93},"functions":{"total":18,"covered":16,"skipped":0,"pct":88.89},"statements":{"total":256,"covered":241,"skipped":0,"pct":94.14},"branches":{"total":62,"covered":39,"skipped":0,"pct":62.9}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-polystar/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-shapes/ext-shapes.js": {"lines":{"total":76,"covered":74,"skipped":0,"pct":97.37},"functions":{"total":7,"covered":7,"skipped":0,"pct":100},"statements":{"total":80,"covered":78,"skipped":0,"pct":97.5},"branches":{"total":26,"covered":17,"skipped":0,"pct":65.38}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-shapes/locale/en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-storage/ext-storage.js": {"lines":{"total":91,"covered":59,"skipped":0,"pct":64.84},"functions":{"total":12,"covered":7,"skipped":0,"pct":58.33},"statements":{"total":91,"covered":59,"skipped":0,"pct":64.84},"branches":{"total":68,"covered":26,"skipped":0,"pct":38.24}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/extensions/ext-storage/storageDialog.js": {"lines":{"total":60,"covered":56,"skipped":0,"pct":93.33},"functions":{"total":10,"covered":7,"skipped":0,"pct":70},"statements":{"total":62,"covered":57,"skipped":0,"pct":91.94},"branches":{"total":15,"covered":13,"skipped":0,"pct":86.67}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/locale/lang.en.js": {"lines":{"total":0,"covered":0,"skipped":0,"pct":100},"functions":{"total":0,"covered":0,"skipped":0,"pct":100},"statements":{"total":0,"covered":0,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/panels/BottomPanel.js": {"lines":{"total":71,"covered":56,"skipped":0,"pct":78.87},"functions":{"total":22,"covered":14,"skipped":0,"pct":63.64},"statements":{"total":77,"covered":59,"skipped":0,"pct":76.62},"branches":{"total":30,"covered":12,"skipped":0,"pct":40}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/panels/LayersPanel.js": {"lines":{"total":157,"covered":70,"skipped":0,"pct":44.59},"functions":{"total":27,"covered":6,"skipped":0,"pct":22.22},"statements":{"total":163,"covered":71,"skipped":0,"pct":43.56},"branches":{"total":46,"covered":6,"skipped":0,"pct":13.04}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/panels/LeftPanel.js": {"lines":{"total":58,"covered":47,"skipped":0,"pct":81.03},"functions":{"total":20,"covered":15,"skipped":0,"pct":75},"statements":{"total":59,"covered":47,"skipped":0,"pct":79.66},"branches":{"total":32,"covered":12,"skipped":0,"pct":37.5}}
+,"/Users/jean-francoishenon/Work/svgedit/src/editor/panels/TopPanel.js": {"lines":{"total":405,"covered":282,"skipped":0,"pct":69.63},"functions":{"total":74,"covered":47,"skipped":0,"pct":63.51},"statements":{"total":416,"covered":285,"skipped":0,"pct":68.51},"branches":{"total":205,"covered":111,"skipped":0,"pct":54.15}}
 }
diff --git a/cypress/__svgSnapshots__/scenario6-check tool_polygon_align_to_page.svg b/cypress/__svgSnapshots__/scenario6-check tool_polygon_align_to_page.svg
index 363dc28dc..9ad2cee9b 100644
--- a/cypress/__svgSnapshots__/scenario6-check tool_polygon_align_to_page.svg
+++ b/cypress/__svgSnapshots__/scenario6-check tool_polygon_align_to_page.svg
@@ -1,7 +1,7 @@
 <svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <g class="layer">
   <title>Layer 1</title>
-  <polygon cx="330" cy="250" edge="63.75" fill="#FF0000" id="svg_1" orient="x" points="637.5,250 600.0264282226562,301.5779724121094 539.3928833007812,281.8769226074219 539.3928833007812,218.12306213378906 600.0264282226562,198.4220428466797 637.5,250 " shape="regularPoly" sides="5" stroke="#000000" stroke-width="5"/>
+  <polygon cx="330" cy="250" edge="63.75" fill="#FF0000" id="svg_1" orient="x" points="637.4922637939453,250 600.0186920166016,301.5779724121094 539.3851470947266,281.8769226074219 539.3851470947266,218.12306213378906 600.0186920166016,198.4220428466797 637.4922637939453,250 " shape="regularPoly" sides="5" stroke="#000000" stroke-width="5"/>
  </g>
 
 </svg>
\ No newline at end of file
diff --git a/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_sides.svg b/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_sides.svg
index a6d115807..d2f2a6c82 100644
--- a/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_sides.svg
+++ b/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_sides.svg
@@ -1,7 +1,7 @@
 <svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <g class="layer">
   <title>Layer 1</title>
-  <polygon cx="330" cy="250" edge="63.75" fill="#bf0000" id="svg_1" orient="x" points="665.1679905202699,250 633.291057027713,305.21246839860237 569.5371900425995,305.21246839860237 537.6602565500426,250 569.5371900425994,194.78753160139763 633.291057027713,194.78753160139763 665.1679905202699,249.99999999999997 " shape="regularPoly" sides="6" stroke="#0000bf" stroke-width="15"/>
+  <polygon cx="330" cy="250" edge="63.75" fill="#bf0000" id="svg_1" orient="x" points="665.1602390554261,250 633.2833055628693,305.21246839860237 569.5294385777557,305.21246839860237 537.6525050851989,250 569.5294385777556,194.78753160139763 633.2833055628693,194.78753160139763 665.1602390554261,249.99999999999997 " shape="regularPoly" sides="6" stroke="#0000bf" stroke-width="15"/>
  </g>
 
 </svg>
\ No newline at end of file
diff --git a/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_stoke_fill_color.svg b/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_stoke_fill_color.svg
index 26d2d66e7..2301417e7 100644
--- a/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_stoke_fill_color.svg
+++ b/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_stoke_fill_color.svg
@@ -1,7 +1,7 @@
 <svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <g class="layer">
   <title>Layer 1</title>
-  <polygon cx="330" cy="250" edge="63.75" fill="#bf0000" id="svg_1" orient="x" points="637.5,250 600.0264282226562,301.5779724121094 539.3928833007812,281.8769226074219 539.3928833007812,218.12306213378906 600.0264282226562,198.4220428466797 637.5,250 " shape="regularPoly" sides="5" stroke="#0000bf" stroke-width="15"/>
+  <polygon cx="330" cy="250" edge="63.75" fill="#bf0000" id="svg_1" orient="x" points="637.4922637939453,250 600.0186920166016,301.5779724121094 539.3851470947266,281.8769226074219 539.3851470947266,218.12306213378906 600.0186920166016,198.4220428466797 637.4922637939453,250 " shape="regularPoly" sides="5" stroke="#0000bf" stroke-width="15"/>
  </g>
 
 </svg>
\ No newline at end of file
diff --git a/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_stroke_width.svg b/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_stroke_width.svg
index d630c8a61..ecd4dd638 100644
--- a/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_stroke_width.svg
+++ b/cypress/__svgSnapshots__/scenario6-check tool_polygon_change_stroke_width.svg
@@ -1,7 +1,7 @@
 <svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <g class="layer">
   <title>Layer 1</title>
-  <polygon cx="330" cy="250" edge="63.75" fill="#FF0000" id="svg_1" orient="x" points="637.5,250 600.0264282226562,301.5779724121094 539.3928833007812,281.8769226074219 539.3928833007812,218.12306213378906 600.0264282226562,198.4220428466797 637.5,250 " shape="regularPoly" sides="5" stroke="#000000" stroke-width="15"/>
+  <polygon cx="330" cy="250" edge="63.75" fill="#FF0000" id="svg_1" orient="x" points="637.4922637939453,250 600.0186920166016,301.5779724121094 539.3851470947266,281.8769226074219 539.3851470947266,218.12306213378906 600.0186920166016,198.4220428466797 637.4922637939453,250 " shape="regularPoly" sides="5" stroke="#000000" stroke-width="15"/>
  </g>
 
 </svg>
\ No newline at end of file
diff --git a/cypress/__svgSnapshots__/scenario7-check tool_star_align_to_page.svg b/cypress/__svgSnapshots__/scenario7-check tool_star_align_to_page.svg
index 489e3f5ff..e43174625 100644
--- a/cypress/__svgSnapshots__/scenario7-check tool_star_align_to_page.svg
+++ b/cypress/__svgSnapshots__/scenario7-check tool_star_align_to_page.svg
@@ -1,7 +1,7 @@
 <svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <g class="layer">
   <title>Layer 1</title>
-  <polygon cx="300" cy="150" fill="#FF0000" id="svg_1" orient="point" point="5" points="573.7792053222656,83 586.9064025878906,131.9319610595703 637.5,129.29586791992188 595.0194702148438,156.90138244628906 613.1608276367188,204.20413208007812 573.7792053222656,172.3333282470703 534.3975830078125,204.20413208007812 552.5389404296875,156.90138244628906 510.0584259033203,129.29586791992188 560.6520080566406,131.9319610595703 573.7792053222656,83 586.9064025878906,131.9319610595703 " r="67" r2="22.33" radialshift="0" shape="star" starRadiusMultiplier="3" stroke="#000000" stroke-width="5"/>
+  <polygon cx="300" cy="150" fill="#FF0000" id="svg_1" orient="point" point="5" points="573.7799987792969,83 586.9071960449219,131.9319610595703 637.5007934570312,129.29586791992188 595.020263671875,156.90138244628906 613.16162109375,204.20413208007812 573.7799987792969,172.3333282470703 534.3983764648438,204.20413208007812 552.5397338867188,156.90138244628906 510.05921936035156,129.29586791992188 560.6528015136719,131.9319610595703 573.7799987792969,83 586.9071960449219,131.9319610595703 " r="67" r2="22.33" radialshift="0" shape="star" starRadiusMultiplier="3" stroke="#000000" stroke-width="5"/>
  </g>
 
 </svg>
\ No newline at end of file
diff --git a/cypress/__svgSnapshots__/scenario7-check tool_star_change_sides.svg b/cypress/__svgSnapshots__/scenario7-check tool_star_change_sides.svg
index 7dd9fc9fd..cb997fc8e 100644
--- a/cypress/__svgSnapshots__/scenario7-check tool_star_change_sides.svg
+++ b/cypress/__svgSnapshots__/scenario7-check tool_star_change_sides.svg
@@ -1,7 +1,7 @@
 <svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <g class="layer">
   <title>Layer 1</title>
-  <polygon cx="300" cy="150" fill="#bf0000" id="svg_1" orient="point" point="6" points="575.6707502092634,69.74376460484095 586.83741687593,117.40253058698849 633.6944522628207,103.24376460484095 598.0040835425967,136.74376460484095 633.6944522628207,170.24376460484092 586.83741687593,156.0849986226934 575.6707502092634,203.74376460484095 564.5040835425967,156.0849986226934 517.647048155706,170.24376460484098 553.33741687593,136.74376460484095 517.647048155706,103.24376460484095 564.5040835425967,117.40253058698849 575.6707502092634,69.74376460484095 586.83741687593,117.40253058698849 " r="67" r2="22.33" radialshift="0" shape="star" starRadiusMultiplier="3" stroke="#0000bf" stroke-width="15"/>
+  <polygon cx="300" cy="150" fill="#bf0000" id="svg_1" orient="point" point="6" points="575.6715567452567,69.74376460484095 586.8382234119233,117.40253058698849 633.695258798814,103.24376460484095 598.00489007859,136.74376460484095 633.695258798814,170.24376460484092 586.8382234119233,156.0849986226934 575.6715567452567,203.74376460484095 564.50489007859,156.0849986226934 517.6478546916993,170.24376460484098 553.3382234119233,136.74376460484095 517.6478546916993,103.24376460484095 564.50489007859,117.40253058698849 575.6715567452567,69.74376460484095 586.8382234119233,117.40253058698849 " r="67" r2="22.33" radialshift="0" shape="star" starRadiusMultiplier="3" stroke="#0000bf" stroke-width="15"/>
  </g>
 
 </svg>
\ No newline at end of file
diff --git a/cypress/__svgSnapshots__/scenario7-check tool_star_change_stoke_fill_color.svg b/cypress/__svgSnapshots__/scenario7-check tool_star_change_stoke_fill_color.svg
index 6da95a839..cc488d112 100644
--- a/cypress/__svgSnapshots__/scenario7-check tool_star_change_stoke_fill_color.svg
+++ b/cypress/__svgSnapshots__/scenario7-check tool_star_change_stoke_fill_color.svg
@@ -1,7 +1,7 @@
 <svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <g class="layer">
   <title>Layer 1</title>
-  <polygon cx="300" cy="150" fill="#bf0000" id="svg_1" orient="point" point="5" points="573.7792053222656,83 586.9064025878906,131.9319610595703 637.5,129.29586791992188 595.0194702148438,156.90138244628906 613.1608276367188,204.20413208007812 573.7792053222656,172.3333282470703 534.3975830078125,204.20413208007812 552.5389404296875,156.90138244628906 510.0584259033203,129.29586791992188 560.6520080566406,131.9319610595703 573.7792053222656,83 586.9064025878906,131.9319610595703 " r="67" r2="22.33" radialshift="0" shape="star" starRadiusMultiplier="3" stroke="#0000bf" stroke-width="15"/>
+  <polygon cx="300" cy="150" fill="#bf0000" id="svg_1" orient="point" point="5" points="573.7799987792969,83 586.9071960449219,131.9319610595703 637.5007934570312,129.29586791992188 595.020263671875,156.90138244628906 613.16162109375,204.20413208007812 573.7799987792969,172.3333282470703 534.3983764648438,204.20413208007812 552.5397338867188,156.90138244628906 510.05921936035156,129.29586791992188 560.6528015136719,131.9319610595703 573.7799987792969,83 586.9071960449219,131.9319610595703 " r="67" r2="22.33" radialshift="0" shape="star" starRadiusMultiplier="3" stroke="#0000bf" stroke-width="15"/>
  </g>
 
 </svg>
\ No newline at end of file
diff --git a/cypress/__svgSnapshots__/scenario7-check tool_star_change_stroke_width.svg b/cypress/__svgSnapshots__/scenario7-check tool_star_change_stroke_width.svg
index 6a4d21ec7..774fc2cc7 100644
--- a/cypress/__svgSnapshots__/scenario7-check tool_star_change_stroke_width.svg
+++ b/cypress/__svgSnapshots__/scenario7-check tool_star_change_stroke_width.svg
@@ -1,7 +1,7 @@
 <svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <g class="layer">
   <title>Layer 1</title>
-  <polygon cx="300" cy="150" fill="#FF0000" id="svg_1" orient="point" point="5" points="573.7792053222656,83 586.9064025878906,131.9319610595703 637.5,129.29586791992188 595.0194702148438,156.90138244628906 613.1608276367188,204.20413208007812 573.7792053222656,172.3333282470703 534.3975830078125,204.20413208007812 552.5389404296875,156.90138244628906 510.0584259033203,129.29586791992188 560.6520080566406,131.9319610595703 573.7792053222656,83 586.9064025878906,131.9319610595703 " r="67" r2="22.33" radialshift="0" shape="star" starRadiusMultiplier="3" stroke="#000000" stroke-width="15"/>
+  <polygon cx="300" cy="150" fill="#FF0000" id="svg_1" orient="point" point="5" points="573.7799987792969,83 586.9071960449219,131.9319610595703 637.5007934570312,129.29586791992188 595.020263671875,156.90138244628906 613.16162109375,204.20413208007812 573.7799987792969,172.3333282470703 534.3983764648438,204.20413208007812 552.5397338867188,156.90138244628906 510.05921936035156,129.29586791992188 560.6528015136719,131.9319610595703 573.7799987792969,83 586.9071960449219,131.9319610595703 " r="67" r2="22.33" radialshift="0" shape="star" starRadiusMultiplier="3" stroke="#000000" stroke-width="15"/>
  </g>
 
 </svg>
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 9d3088c06..a64889d0d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,37 +15,37 @@
       "dependencies": {
         "@svgedit/svgcanvas": "7.2.1",
         "browser-fs-access": "0.35.0",
-        "core-js": "3.33.0",
+        "core-js": "3.34.0",
         "elix": "15.0.1",
         "html2canvas": "1.4.1",
-        "i18next": "23.5.1",
+        "i18next": "23.7.8",
         "jspdf": "2.5.1",
         "pathseg": "1.2.1",
         "regenerator-runtime": "0.14.0",
-        "replace-in-file": "^7.0.1",
+        "replace-in-file": "^7.0.2",
         "svg2pdf.js": "2.2.2"
       },
       "devDependencies": {
-        "@babel/core": "7.23.2",
-        "@babel/preset-env": "7.23.2",
+        "@babel/core": "7.23.5",
+        "@babel/preset-env": "7.23.5",
         "@babel/register": "7.22.15",
-        "@babel/runtime-corejs3": "7.23.2",
-        "@cypress/code-coverage": "3.12.3",
+        "@babel/runtime-corejs3": "7.23.5",
+        "@cypress/code-coverage": "3.12.13",
         "@rollup/plugin-babel": "^6.0.4",
-        "@rollup/plugin-commonjs": "25.0.5",
-        "@rollup/plugin-dynamic-import-vars": "2.0.6",
+        "@rollup/plugin-commonjs": "25.0.7",
+        "@rollup/plugin-dynamic-import-vars": "2.1.2",
         "@rollup/plugin-node-resolve": "15.2.3",
-        "@rollup/plugin-replace": "5.0.3",
+        "@rollup/plugin-replace": "5.0.5",
         "@rollup/plugin-url": "8.0.2",
-        "@web/dev-server": "0.3.3",
-        "@web/dev-server-esbuild": "^0.4.1",
-        "@web/dev-server-rollup": "0.5.2",
+        "@web/dev-server": "0.4.1",
+        "@web/dev-server-esbuild": "^1.0.1",
+        "@web/dev-server-rollup": "0.6.1",
         "babel-plugin-istanbul": "^6.1.1",
         "babel-plugin-transform-object-rest-spread": "7.0.0-beta.3",
-        "core-js-bundle": "3.33.0",
+        "core-js-bundle": "3.34.0",
         "cp-cli": "2.0.0",
-        "cypress": "13.3.1",
-        "cypress-multi-reporters": "1.6.3",
+        "cypress": "13.6.1",
+        "cypress-multi-reporters": "1.6.4",
         "jamilih": "0.58.2",
         "jsdoc": "4.0.2",
         "node-static": "0.7.11",
@@ -58,14 +58,14 @@
         "remark-cli": "12.0.0",
         "remark-lint-ordered-list-marker-value": "3.1.2",
         "rimraf": "5.0.5",
-        "rollup": "4.0.2",
+        "rollup": "4.7.0",
         "rollup-plugin-copy": "3.5.0",
         "rollup-plugin-filesize": "10.0.0",
         "rollup-plugin-html": "0.2.1",
         "rollup-plugin-progress": "1.1.2",
         "rollup-plugin-re": "1.0.7",
         "standard": "17.1.0",
-        "start-server-and-test": "2.0.1"
+        "start-server-and-test": "2.0.3"
       },
       "engines": {
         "node": ">=16"
@@ -116,12 +116,12 @@
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.22.13",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
-      "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+      "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
       "dev": true,
       "dependencies": {
-        "@babel/highlight": "^7.22.13",
+        "@babel/highlight": "^7.23.4",
         "chalk": "^2.4.2"
       },
       "engines": {
@@ -129,30 +129,30 @@
       }
     },
     "node_modules/@babel/compat-data": {
-      "version": "7.23.2",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz",
-      "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
+      "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/core": {
-      "version": "7.23.2",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz",
-      "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz",
+      "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==",
       "dev": true,
       "dependencies": {
         "@ampproject/remapping": "^2.2.0",
-        "@babel/code-frame": "^7.22.13",
-        "@babel/generator": "^7.23.0",
+        "@babel/code-frame": "^7.23.5",
+        "@babel/generator": "^7.23.5",
         "@babel/helper-compilation-targets": "^7.22.15",
-        "@babel/helper-module-transforms": "^7.23.0",
-        "@babel/helpers": "^7.23.2",
-        "@babel/parser": "^7.23.0",
+        "@babel/helper-module-transforms": "^7.23.3",
+        "@babel/helpers": "^7.23.5",
+        "@babel/parser": "^7.23.5",
         "@babel/template": "^7.22.15",
-        "@babel/traverse": "^7.23.2",
-        "@babel/types": "^7.23.0",
+        "@babel/traverse": "^7.23.5",
+        "@babel/types": "^7.23.5",
         "convert-source-map": "^2.0.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
@@ -174,12 +174,12 @@
       "dev": true
     },
     "node_modules/@babel/generator": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
-      "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz",
+      "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.23.0",
+        "@babel/types": "^7.23.5",
         "@jridgewell/gen-mapping": "^0.3.2",
         "@jridgewell/trace-mapping": "^0.3.17",
         "jsesc": "^2.5.1"
@@ -201,12 +201,12 @@
       }
     },
     "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
-      "version": "7.22.10",
-      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.10.tgz",
-      "integrity": "sha512-Av0qubwDQxC56DoUReVDeLfMEjYYSN1nZrTUrWkXd7hpU73ymRANkbuDm3yni9npkn+RXy9nNbEJZEzXr7xrfQ==",
+      "version": "7.22.15",
+      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz",
+      "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.22.10"
+        "@babel/types": "^7.22.15"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -229,17 +229,17 @@
       }
     },
     "node_modules/@babel/helper-create-class-features-plugin": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz",
-      "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz",
+      "integrity": "sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==",
       "dev": true,
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
-        "@babel/helper-environment-visitor": "^7.22.5",
-        "@babel/helper-function-name": "^7.22.5",
-        "@babel/helper-member-expression-to-functions": "^7.22.15",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-function-name": "^7.23.0",
+        "@babel/helper-member-expression-to-functions": "^7.23.0",
         "@babel/helper-optimise-call-expression": "^7.22.5",
-        "@babel/helper-replace-supers": "^7.22.9",
+        "@babel/helper-replace-supers": "^7.22.20",
         "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
         "@babel/helper-split-export-declaration": "^7.22.6",
         "semver": "^6.3.1"
@@ -252,9 +252,9 @@
       }
     },
     "node_modules/@babel/helper-create-regexp-features-plugin": {
-      "version": "7.22.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz",
-      "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==",
+      "version": "7.22.15",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz",
+      "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==",
       "dev": true,
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
@@ -343,9 +343,9 @@
       }
     },
     "node_modules/@babel/helper-module-transforms": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz",
-      "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
+      "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-environment-visitor": "^7.22.20",
@@ -400,13 +400,13 @@
       }
     },
     "node_modules/@babel/helper-replace-supers": {
-      "version": "7.22.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz",
-      "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz",
+      "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-environment-visitor": "^7.22.5",
-        "@babel/helper-member-expression-to-functions": "^7.22.5",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-member-expression-to-functions": "^7.22.15",
         "@babel/helper-optimise-call-expression": "^7.22.5"
       },
       "engines": {
@@ -453,9 +453,9 @@
       }
     },
     "node_modules/@babel/helper-string-parser": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
-      "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
+      "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
@@ -471,9 +471,9 @@
       }
     },
     "node_modules/@babel/helper-validator-option": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz",
-      "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
+      "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
@@ -494,23 +494,23 @@
       }
     },
     "node_modules/@babel/helpers": {
-      "version": "7.23.2",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz",
-      "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz",
+      "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==",
       "dev": true,
       "dependencies": {
         "@babel/template": "^7.22.15",
-        "@babel/traverse": "^7.23.2",
-        "@babel/types": "^7.23.0"
+        "@babel/traverse": "^7.23.5",
+        "@babel/types": "^7.23.5"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.22.20",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
-      "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+      "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
       "dev": true,
       "dependencies": {
         "@babel/helper-validator-identifier": "^7.22.20",
@@ -522,9 +522,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
-      "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz",
+      "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -534,9 +534,9 @@
       }
     },
     "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz",
-      "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz",
+      "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -549,14 +549,14 @@
       }
     },
     "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz",
-      "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz",
+      "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
-        "@babel/plugin-transform-optional-chaining": "^7.22.15"
+        "@babel/plugin-transform-optional-chaining": "^7.23.3"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -565,6 +565,22 @@
         "@babel/core": "^7.13.0"
       }
     },
+    "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz",
+      "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-plugin-utils": "^7.22.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
     "node_modules/@babel/plugin-proposal-private-property-in-object": {
       "version": "7.21.0-placeholder-for-preset-env.2",
       "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
@@ -641,9 +657,9 @@
       }
     },
     "node_modules/@babel/plugin-syntax-import-assertions": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz",
-      "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz",
+      "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -656,9 +672,9 @@
       }
     },
     "node_modules/@babel/plugin-syntax-import-attributes": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz",
-      "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz",
+      "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -828,9 +844,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-arrow-functions": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz",
-      "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz",
+      "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -843,9 +859,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-async-generator-functions": {
-      "version": "7.23.2",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz",
-      "integrity": "sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz",
+      "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-environment-visitor": "^7.22.20",
@@ -861,14 +877,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-async-to-generator": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz",
-      "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz",
+      "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-module-imports": "^7.22.5",
+        "@babel/helper-module-imports": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5",
-        "@babel/helper-remap-async-to-generator": "^7.22.5"
+        "@babel/helper-remap-async-to-generator": "^7.22.20"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -878,9 +894,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-block-scoped-functions": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz",
-      "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz",
+      "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -893,9 +909,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-block-scoping": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz",
-      "integrity": "sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz",
+      "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -908,12 +924,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-class-properties": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz",
-      "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz",
+      "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-create-class-features-plugin": "^7.22.5",
+        "@babel/helper-create-class-features-plugin": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -924,12 +940,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-class-static-block": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz",
-      "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz",
+      "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-create-class-features-plugin": "^7.22.11",
+        "@babel/helper-create-class-features-plugin": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/plugin-syntax-class-static-block": "^7.14.5"
       },
@@ -941,18 +957,18 @@
       }
     },
     "node_modules/@babel/plugin-transform-classes": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz",
-      "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz",
+      "integrity": "sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==",
       "dev": true,
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
         "@babel/helper-compilation-targets": "^7.22.15",
-        "@babel/helper-environment-visitor": "^7.22.5",
-        "@babel/helper-function-name": "^7.22.5",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-function-name": "^7.23.0",
         "@babel/helper-optimise-call-expression": "^7.22.5",
         "@babel/helper-plugin-utils": "^7.22.5",
-        "@babel/helper-replace-supers": "^7.22.9",
+        "@babel/helper-replace-supers": "^7.22.20",
         "@babel/helper-split-export-declaration": "^7.22.6",
         "globals": "^11.1.0"
       },
@@ -964,13 +980,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-computed-properties": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz",
-      "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz",
+      "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
-        "@babel/template": "^7.22.5"
+        "@babel/template": "^7.22.15"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -980,9 +996,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-destructuring": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz",
-      "integrity": "sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz",
+      "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -995,12 +1011,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-dotall-regex": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz",
-      "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz",
+      "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+        "@babel/helper-create-regexp-features-plugin": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1011,9 +1027,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-duplicate-keys": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz",
-      "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz",
+      "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1026,9 +1042,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-dynamic-import": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz",
-      "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz",
+      "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1042,12 +1058,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-exponentiation-operator": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz",
-      "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz",
+      "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5",
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1058,9 +1074,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-export-namespace-from": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz",
-      "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz",
+      "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1074,9 +1090,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-for-of": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz",
-      "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz",
+      "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1089,13 +1105,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-function-name": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz",
-      "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz",
+      "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-compilation-targets": "^7.22.5",
-        "@babel/helper-function-name": "^7.22.5",
+        "@babel/helper-compilation-targets": "^7.22.15",
+        "@babel/helper-function-name": "^7.23.0",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1106,9 +1122,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-json-strings": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz",
-      "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz",
+      "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1122,9 +1138,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-literals": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz",
-      "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz",
+      "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1137,9 +1153,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-logical-assignment-operators": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz",
-      "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz",
+      "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1153,9 +1169,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-member-expression-literals": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz",
-      "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz",
+      "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1168,12 +1184,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-amd": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz",
-      "integrity": "sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz",
+      "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.23.0",
+        "@babel/helper-module-transforms": "^7.23.3",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1184,12 +1200,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-commonjs": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz",
-      "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz",
+      "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.23.0",
+        "@babel/helper-module-transforms": "^7.23.3",
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/helper-simple-access": "^7.22.5"
       },
@@ -1201,13 +1217,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-systemjs": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz",
-      "integrity": "sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz",
+      "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-hoist-variables": "^7.22.5",
-        "@babel/helper-module-transforms": "^7.23.0",
+        "@babel/helper-module-transforms": "^7.23.3",
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/helper-validator-identifier": "^7.22.20"
       },
@@ -1219,12 +1235,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-umd": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz",
-      "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz",
+      "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.22.5",
+        "@babel/helper-module-transforms": "^7.23.3",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1251,9 +1267,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-new-target": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz",
-      "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz",
+      "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1266,9 +1282,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz",
-      "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz",
+      "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1282,9 +1298,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-numeric-separator": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz",
-      "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz",
+      "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1298,16 +1314,16 @@
       }
     },
     "node_modules/@babel/plugin-transform-object-rest-spread": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz",
-      "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz",
+      "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==",
       "dev": true,
       "dependencies": {
-        "@babel/compat-data": "^7.22.9",
+        "@babel/compat-data": "^7.23.3",
         "@babel/helper-compilation-targets": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
-        "@babel/plugin-transform-parameters": "^7.22.15"
+        "@babel/plugin-transform-parameters": "^7.23.3"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1317,13 +1333,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-object-super": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz",
-      "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz",
+      "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
-        "@babel/helper-replace-supers": "^7.22.5"
+        "@babel/helper-replace-supers": "^7.22.20"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1333,9 +1349,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-optional-catch-binding": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz",
-      "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz",
+      "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1349,9 +1365,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-optional-chaining": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz",
-      "integrity": "sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz",
+      "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1366,9 +1382,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-parameters": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz",
-      "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz",
+      "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1381,12 +1397,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-private-methods": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz",
-      "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz",
+      "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-create-class-features-plugin": "^7.22.5",
+        "@babel/helper-create-class-features-plugin": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1397,13 +1413,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-private-property-in-object": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz",
-      "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==",
+      "version": "7.23.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz",
+      "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==",
       "dev": true,
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
-        "@babel/helper-create-class-features-plugin": "^7.22.11",
+        "@babel/helper-create-class-features-plugin": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
       },
@@ -1415,9 +1431,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-property-literals": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz",
-      "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz",
+      "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1430,9 +1446,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-react-display-name": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz",
-      "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz",
+      "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1479,9 +1495,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-react-pure-annotations": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz",
-      "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz",
+      "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
@@ -1495,9 +1511,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-regenerator": {
-      "version": "7.22.10",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz",
-      "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz",
+      "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1511,9 +1527,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-reserved-words": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz",
-      "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz",
+      "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1526,9 +1542,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-shorthand-properties": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz",
-      "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz",
+      "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1541,9 +1557,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-spread": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz",
-      "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz",
+      "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
@@ -1557,9 +1573,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-sticky-regex": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz",
-      "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz",
+      "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1572,9 +1588,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-template-literals": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz",
-      "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz",
+      "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1587,9 +1603,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-typeof-symbol": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz",
-      "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz",
+      "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1602,9 +1618,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-unicode-escapes": {
-      "version": "7.22.10",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz",
-      "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz",
+      "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1617,12 +1633,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-unicode-property-regex": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz",
-      "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz",
+      "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+        "@babel/helper-create-regexp-features-plugin": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1633,12 +1649,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-unicode-regex": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz",
-      "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz",
+      "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+        "@babel/helper-create-regexp-features-plugin": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1649,12 +1665,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-unicode-sets-regex": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz",
-      "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz",
+      "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+        "@babel/helper-create-regexp-features-plugin": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1665,25 +1681,26 @@
       }
     },
     "node_modules/@babel/preset-env": {
-      "version": "7.23.2",
-      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.2.tgz",
-      "integrity": "sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz",
+      "integrity": "sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==",
       "dev": true,
       "dependencies": {
-        "@babel/compat-data": "^7.23.2",
+        "@babel/compat-data": "^7.23.5",
         "@babel/helper-compilation-targets": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5",
-        "@babel/helper-validator-option": "^7.22.15",
-        "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15",
-        "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15",
+        "@babel/helper-validator-option": "^7.23.5",
+        "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3",
+        "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3",
+        "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3",
         "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
         "@babel/plugin-syntax-async-generators": "^7.8.4",
         "@babel/plugin-syntax-class-properties": "^7.12.13",
         "@babel/plugin-syntax-class-static-block": "^7.14.5",
         "@babel/plugin-syntax-dynamic-import": "^7.8.3",
         "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
-        "@babel/plugin-syntax-import-assertions": "^7.22.5",
-        "@babel/plugin-syntax-import-attributes": "^7.22.5",
+        "@babel/plugin-syntax-import-assertions": "^7.23.3",
+        "@babel/plugin-syntax-import-attributes": "^7.23.3",
         "@babel/plugin-syntax-import-meta": "^7.10.4",
         "@babel/plugin-syntax-json-strings": "^7.8.3",
         "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
@@ -1695,56 +1712,55 @@
         "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
         "@babel/plugin-syntax-top-level-await": "^7.14.5",
         "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
-        "@babel/plugin-transform-arrow-functions": "^7.22.5",
-        "@babel/plugin-transform-async-generator-functions": "^7.23.2",
-        "@babel/plugin-transform-async-to-generator": "^7.22.5",
-        "@babel/plugin-transform-block-scoped-functions": "^7.22.5",
-        "@babel/plugin-transform-block-scoping": "^7.23.0",
-        "@babel/plugin-transform-class-properties": "^7.22.5",
-        "@babel/plugin-transform-class-static-block": "^7.22.11",
-        "@babel/plugin-transform-classes": "^7.22.15",
-        "@babel/plugin-transform-computed-properties": "^7.22.5",
-        "@babel/plugin-transform-destructuring": "^7.23.0",
-        "@babel/plugin-transform-dotall-regex": "^7.22.5",
-        "@babel/plugin-transform-duplicate-keys": "^7.22.5",
-        "@babel/plugin-transform-dynamic-import": "^7.22.11",
-        "@babel/plugin-transform-exponentiation-operator": "^7.22.5",
-        "@babel/plugin-transform-export-namespace-from": "^7.22.11",
-        "@babel/plugin-transform-for-of": "^7.22.15",
-        "@babel/plugin-transform-function-name": "^7.22.5",
-        "@babel/plugin-transform-json-strings": "^7.22.11",
-        "@babel/plugin-transform-literals": "^7.22.5",
-        "@babel/plugin-transform-logical-assignment-operators": "^7.22.11",
-        "@babel/plugin-transform-member-expression-literals": "^7.22.5",
-        "@babel/plugin-transform-modules-amd": "^7.23.0",
-        "@babel/plugin-transform-modules-commonjs": "^7.23.0",
-        "@babel/plugin-transform-modules-systemjs": "^7.23.0",
-        "@babel/plugin-transform-modules-umd": "^7.22.5",
+        "@babel/plugin-transform-arrow-functions": "^7.23.3",
+        "@babel/plugin-transform-async-generator-functions": "^7.23.4",
+        "@babel/plugin-transform-async-to-generator": "^7.23.3",
+        "@babel/plugin-transform-block-scoped-functions": "^7.23.3",
+        "@babel/plugin-transform-block-scoping": "^7.23.4",
+        "@babel/plugin-transform-class-properties": "^7.23.3",
+        "@babel/plugin-transform-class-static-block": "^7.23.4",
+        "@babel/plugin-transform-classes": "^7.23.5",
+        "@babel/plugin-transform-computed-properties": "^7.23.3",
+        "@babel/plugin-transform-destructuring": "^7.23.3",
+        "@babel/plugin-transform-dotall-regex": "^7.23.3",
+        "@babel/plugin-transform-duplicate-keys": "^7.23.3",
+        "@babel/plugin-transform-dynamic-import": "^7.23.4",
+        "@babel/plugin-transform-exponentiation-operator": "^7.23.3",
+        "@babel/plugin-transform-export-namespace-from": "^7.23.4",
+        "@babel/plugin-transform-for-of": "^7.23.3",
+        "@babel/plugin-transform-function-name": "^7.23.3",
+        "@babel/plugin-transform-json-strings": "^7.23.4",
+        "@babel/plugin-transform-literals": "^7.23.3",
+        "@babel/plugin-transform-logical-assignment-operators": "^7.23.4",
+        "@babel/plugin-transform-member-expression-literals": "^7.23.3",
+        "@babel/plugin-transform-modules-amd": "^7.23.3",
+        "@babel/plugin-transform-modules-commonjs": "^7.23.3",
+        "@babel/plugin-transform-modules-systemjs": "^7.23.3",
+        "@babel/plugin-transform-modules-umd": "^7.23.3",
         "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
-        "@babel/plugin-transform-new-target": "^7.22.5",
-        "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11",
-        "@babel/plugin-transform-numeric-separator": "^7.22.11",
-        "@babel/plugin-transform-object-rest-spread": "^7.22.15",
-        "@babel/plugin-transform-object-super": "^7.22.5",
-        "@babel/plugin-transform-optional-catch-binding": "^7.22.11",
-        "@babel/plugin-transform-optional-chaining": "^7.23.0",
-        "@babel/plugin-transform-parameters": "^7.22.15",
-        "@babel/plugin-transform-private-methods": "^7.22.5",
-        "@babel/plugin-transform-private-property-in-object": "^7.22.11",
-        "@babel/plugin-transform-property-literals": "^7.22.5",
-        "@babel/plugin-transform-regenerator": "^7.22.10",
-        "@babel/plugin-transform-reserved-words": "^7.22.5",
-        "@babel/plugin-transform-shorthand-properties": "^7.22.5",
-        "@babel/plugin-transform-spread": "^7.22.5",
-        "@babel/plugin-transform-sticky-regex": "^7.22.5",
-        "@babel/plugin-transform-template-literals": "^7.22.5",
-        "@babel/plugin-transform-typeof-symbol": "^7.22.5",
-        "@babel/plugin-transform-unicode-escapes": "^7.22.10",
-        "@babel/plugin-transform-unicode-property-regex": "^7.22.5",
-        "@babel/plugin-transform-unicode-regex": "^7.22.5",
-        "@babel/plugin-transform-unicode-sets-regex": "^7.22.5",
+        "@babel/plugin-transform-new-target": "^7.23.3",
+        "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4",
+        "@babel/plugin-transform-numeric-separator": "^7.23.4",
+        "@babel/plugin-transform-object-rest-spread": "^7.23.4",
+        "@babel/plugin-transform-object-super": "^7.23.3",
+        "@babel/plugin-transform-optional-catch-binding": "^7.23.4",
+        "@babel/plugin-transform-optional-chaining": "^7.23.4",
+        "@babel/plugin-transform-parameters": "^7.23.3",
+        "@babel/plugin-transform-private-methods": "^7.23.3",
+        "@babel/plugin-transform-private-property-in-object": "^7.23.4",
+        "@babel/plugin-transform-property-literals": "^7.23.3",
+        "@babel/plugin-transform-regenerator": "^7.23.3",
+        "@babel/plugin-transform-reserved-words": "^7.23.3",
+        "@babel/plugin-transform-shorthand-properties": "^7.23.3",
+        "@babel/plugin-transform-spread": "^7.23.3",
+        "@babel/plugin-transform-sticky-regex": "^7.23.3",
+        "@babel/plugin-transform-template-literals": "^7.23.3",
+        "@babel/plugin-transform-typeof-symbol": "^7.23.3",
+        "@babel/plugin-transform-unicode-escapes": "^7.23.3",
+        "@babel/plugin-transform-unicode-property-regex": "^7.23.3",
+        "@babel/plugin-transform-unicode-regex": "^7.23.3",
+        "@babel/plugin-transform-unicode-sets-regex": "^7.23.3",
         "@babel/preset-modules": "0.1.6-no-external-plugins",
-        "@babel/types": "^7.23.0",
         "babel-plugin-polyfill-corejs2": "^0.4.6",
         "babel-plugin-polyfill-corejs3": "^0.8.5",
         "babel-plugin-polyfill-regenerator": "^0.5.3",
@@ -1773,17 +1789,17 @@
       }
     },
     "node_modules/@babel/preset-react": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.15.tgz",
-      "integrity": "sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w==",
+      "version": "7.23.3",
+      "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz",
+      "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==",
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/helper-validator-option": "^7.22.15",
-        "@babel/plugin-transform-react-display-name": "^7.22.5",
+        "@babel/plugin-transform-react-display-name": "^7.23.3",
         "@babel/plugin-transform-react-jsx": "^7.22.15",
         "@babel/plugin-transform-react-jsx-development": "^7.22.5",
-        "@babel/plugin-transform-react-pure-annotations": "^7.22.5"
+        "@babel/plugin-transform-react-pure-annotations": "^7.23.3"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1818,9 +1834,9 @@
       "dev": true
     },
     "node_modules/@babel/runtime": {
-      "version": "7.22.10",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.10.tgz",
-      "integrity": "sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz",
+      "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==",
       "dependencies": {
         "regenerator-runtime": "^0.14.0"
       },
@@ -1829,9 +1845,9 @@
       }
     },
     "node_modules/@babel/runtime-corejs3": {
-      "version": "7.23.2",
-      "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.2.tgz",
-      "integrity": "sha512-54cIh74Z1rp4oIjsHjqN+WM4fMyCBYe+LpZ9jWm51CZ1fbH3SkAzQD/3XLoNkjbJ7YEmjobLXyvQrFypRHOrXw==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.5.tgz",
+      "integrity": "sha512-7+ziVclejQTLYhXl+Oi1f6gTGD1XDCeLa4R472TNGQxb08zbEJ0OdNoh5Piz+57Ltmui6xR88BXR4gS3/Toslw==",
       "dev": true,
       "dependencies": {
         "core-js-pure": "^3.30.2",
@@ -1856,19 +1872,19 @@
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.23.2",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
-      "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz",
+      "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==",
       "dev": true,
       "dependencies": {
-        "@babel/code-frame": "^7.22.13",
-        "@babel/generator": "^7.23.0",
+        "@babel/code-frame": "^7.23.5",
+        "@babel/generator": "^7.23.5",
         "@babel/helper-environment-visitor": "^7.22.20",
         "@babel/helper-function-name": "^7.23.0",
         "@babel/helper-hoist-variables": "^7.22.5",
         "@babel/helper-split-export-declaration": "^7.22.6",
-        "@babel/parser": "^7.23.0",
-        "@babel/types": "^7.23.0",
+        "@babel/parser": "^7.23.5",
+        "@babel/types": "^7.23.5",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
       },
@@ -1877,12 +1893,12 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
-      "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+      "version": "7.23.5",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz",
+      "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-string-parser": "^7.22.5",
+        "@babel/helper-string-parser": "^7.23.4",
         "@babel/helper-validator-identifier": "^7.22.20",
         "to-fast-properties": "^2.0.0"
       },
@@ -1901,18 +1917,18 @@
       }
     },
     "node_modules/@cypress/code-coverage": {
-      "version": "3.12.3",
-      "resolved": "https://registry.npmjs.org/@cypress/code-coverage/-/code-coverage-3.12.3.tgz",
-      "integrity": "sha512-XPz25Z6BShSkLpfvFX3dNJSSM/98d2vN0H4MM1hA0PMjKW1QzdsczY6p+gVFyeDBoogFdSdNf8pbMTohCXYJFQ==",
+      "version": "3.12.13",
+      "resolved": "https://registry.npmjs.org/@cypress/code-coverage/-/code-coverage-3.12.13.tgz",
+      "integrity": "sha512-T89OymsdSTcVKtdEqkKjHAKpDR0JCWxIgRBlldEcCAtDYW4Bo8QM+gkE75I18iixcPVCQbnZ9m6fx8Rl6ddc+w==",
       "dev": true,
       "dependencies": {
         "@cypress/webpack-preprocessor": "^6.0.0",
         "chalk": "4.1.2",
-        "dayjs": "1.11.9",
+        "dayjs": "1.11.10",
         "debug": "4.3.4",
         "execa": "4.1.0",
-        "globby": "11.0.4",
-        "istanbul-lib-coverage": "3.0.0",
+        "globby": "11.1.0",
+        "istanbul-lib-coverage": "^3.0.0",
         "js-yaml": "4.1.0",
         "nyc": "15.1.0"
       },
@@ -2060,9 +2076,9 @@
       }
     },
     "node_modules/@esbuild/android-arm": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
-      "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.8.tgz",
+      "integrity": "sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==",
       "cpu": [
         "arm"
       ],
@@ -2076,9 +2092,9 @@
       }
     },
     "node_modules/@esbuild/android-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
-      "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.8.tgz",
+      "integrity": "sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==",
       "cpu": [
         "arm64"
       ],
@@ -2092,9 +2108,9 @@
       }
     },
     "node_modules/@esbuild/android-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
-      "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.8.tgz",
+      "integrity": "sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==",
       "cpu": [
         "x64"
       ],
@@ -2108,9 +2124,9 @@
       }
     },
     "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
-      "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.8.tgz",
+      "integrity": "sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==",
       "cpu": [
         "arm64"
       ],
@@ -2124,9 +2140,9 @@
       }
     },
     "node_modules/@esbuild/darwin-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
-      "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz",
+      "integrity": "sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==",
       "cpu": [
         "x64"
       ],
@@ -2140,9 +2156,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
-      "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.8.tgz",
+      "integrity": "sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==",
       "cpu": [
         "arm64"
       ],
@@ -2156,9 +2172,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
-      "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.8.tgz",
+      "integrity": "sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==",
       "cpu": [
         "x64"
       ],
@@ -2172,9 +2188,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
-      "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.8.tgz",
+      "integrity": "sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==",
       "cpu": [
         "arm"
       ],
@@ -2188,9 +2204,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
-      "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.8.tgz",
+      "integrity": "sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==",
       "cpu": [
         "arm64"
       ],
@@ -2204,9 +2220,9 @@
       }
     },
     "node_modules/@esbuild/linux-ia32": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
-      "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.8.tgz",
+      "integrity": "sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==",
       "cpu": [
         "ia32"
       ],
@@ -2220,9 +2236,9 @@
       }
     },
     "node_modules/@esbuild/linux-loong64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
-      "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.8.tgz",
+      "integrity": "sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==",
       "cpu": [
         "loong64"
       ],
@@ -2236,9 +2252,9 @@
       }
     },
     "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
-      "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.8.tgz",
+      "integrity": "sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==",
       "cpu": [
         "mips64el"
       ],
@@ -2252,9 +2268,9 @@
       }
     },
     "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
-      "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.8.tgz",
+      "integrity": "sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==",
       "cpu": [
         "ppc64"
       ],
@@ -2268,9 +2284,9 @@
       }
     },
     "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
-      "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.8.tgz",
+      "integrity": "sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==",
       "cpu": [
         "riscv64"
       ],
@@ -2284,9 +2300,9 @@
       }
     },
     "node_modules/@esbuild/linux-s390x": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
-      "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.8.tgz",
+      "integrity": "sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==",
       "cpu": [
         "s390x"
       ],
@@ -2300,9 +2316,9 @@
       }
     },
     "node_modules/@esbuild/linux-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
-      "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz",
+      "integrity": "sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==",
       "cpu": [
         "x64"
       ],
@@ -2316,9 +2332,9 @@
       }
     },
     "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
-      "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.8.tgz",
+      "integrity": "sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==",
       "cpu": [
         "x64"
       ],
@@ -2332,9 +2348,9 @@
       }
     },
     "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
-      "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.8.tgz",
+      "integrity": "sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==",
       "cpu": [
         "x64"
       ],
@@ -2348,9 +2364,9 @@
       }
     },
     "node_modules/@esbuild/sunos-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
-      "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.8.tgz",
+      "integrity": "sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==",
       "cpu": [
         "x64"
       ],
@@ -2364,9 +2380,9 @@
       }
     },
     "node_modules/@esbuild/win32-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
-      "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.8.tgz",
+      "integrity": "sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==",
       "cpu": [
         "arm64"
       ],
@@ -2380,9 +2396,9 @@
       }
     },
     "node_modules/@esbuild/win32-ia32": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
-      "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.8.tgz",
+      "integrity": "sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==",
       "cpu": [
         "ia32"
       ],
@@ -2396,9 +2412,9 @@
       }
     },
     "node_modules/@esbuild/win32-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
-      "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.8.tgz",
+      "integrity": "sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA==",
       "cpu": [
         "x64"
       ],
@@ -3295,9 +3311,9 @@
       }
     },
     "node_modules/@rollup/plugin-commonjs": {
-      "version": "25.0.5",
-      "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.5.tgz",
-      "integrity": "sha512-xY8r/A9oisSeSuLCTfhssyDjo9Vp/eDiRLXkg1MXCcEEgEjPmLU+ZyDB20OOD0NlyDa/8SGbK5uIggF5XTx77w==",
+      "version": "25.0.7",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz",
+      "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==",
       "dev": true,
       "dependencies": {
         "@rollup/pluginutils": "^5.0.1",
@@ -3305,7 +3321,7 @@
         "estree-walker": "^2.0.2",
         "glob": "^8.0.3",
         "is-reference": "1.2.1",
-        "magic-string": "^0.27.0"
+        "magic-string": "^0.30.3"
       },
       "engines": {
         "node": ">=14.0.0"
@@ -3320,16 +3336,16 @@
       }
     },
     "node_modules/@rollup/plugin-dynamic-import-vars": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@rollup/plugin-dynamic-import-vars/-/plugin-dynamic-import-vars-2.0.6.tgz",
-      "integrity": "sha512-MBsToinAS+/aQjjw1vEJCXA3/wy6K4WnN6RLldZybASVvOKjacTLvvXq0gADCczcecmQGMTJMfEgUvOM0K/juA==",
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-dynamic-import-vars/-/plugin-dynamic-import-vars-2.1.2.tgz",
+      "integrity": "sha512-4lr2oXxs9hcxtGGaK8s0i9evfjzDrAs7ngw28TqruWKTEm0+U4Eljb+F6HXGYdFv8xRojQlrQwV7M/yxeh3yzQ==",
       "dev": true,
       "dependencies": {
         "@rollup/pluginutils": "^5.0.1",
         "astring": "^1.8.5",
         "estree-walker": "^2.0.2",
         "fast-glob": "^3.2.12",
-        "magic-string": "^0.27.0"
+        "magic-string": "^0.30.3"
       },
       "engines": {
         "node": ">=14.0.0"
@@ -3369,13 +3385,13 @@
       }
     },
     "node_modules/@rollup/plugin-replace": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.3.tgz",
-      "integrity": "sha512-je7fu05B800IrMlWjb2wzJcdXzHYW46iTipfChnBDbIbDXhASZs27W1B58T2Yf45jZtJUONegpbce+9Ut2Ti/Q==",
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.5.tgz",
+      "integrity": "sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==",
       "dev": true,
       "dependencies": {
         "@rollup/pluginutils": "^5.0.1",
-        "magic-string": "^0.27.0"
+        "magic-string": "^0.30.3"
       },
       "engines": {
         "node": ">=14.0.0"
@@ -3449,9 +3465,9 @@
       }
     },
     "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.0.2.tgz",
-      "integrity": "sha512-xDvk1pT4vaPU2BOLy0MqHMdYZyntqpaBf8RhBiezlqG9OjY8F50TyctHo8znigYKd+QCFhCmlmXHOL/LoaOl3w==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.7.0.tgz",
+      "integrity": "sha512-rGku10pL1StFlFvXX5pEv88KdGW6DHUghsxyP/aRYb9eH+74jTGJ3U0S/rtlsQ4yYq1Hcc7AMkoJOb1xu29Fxw==",
       "cpu": [
         "arm"
       ],
@@ -3462,9 +3478,9 @@
       ]
     },
     "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.0.2.tgz",
-      "integrity": "sha512-lqCglytY3E6raze27DD9VQJWohbwCxzqs9aSHcj5X/8hJpzZfNdbsr4Ja9Hqp6iPyF53+5PtPx0pKRlkSvlHZg==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.7.0.tgz",
+      "integrity": "sha512-/EBw0cuJ/KVHiU2qyVYUhogXz7W2vXxBzeE9xtVIMC+RyitlY2vvaoysMUqASpkUtoNIHlnKTu/l7mXOPgnKOA==",
       "cpu": [
         "arm64"
       ],
@@ -3475,9 +3491,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.0.2.tgz",
-      "integrity": "sha512-nkBKItS6E6CCzvRwgiKad+j+1ibmL7SIInj7oqMWmdkCjiSX6VeVZw2mLlRKIUL+JjsBgpATTfo7BiAXc1v0jA==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.7.0.tgz",
+      "integrity": "sha512-4VXG1bgvClJdbEYYjQ85RkOtwN8sqI3uCxH0HC5w9fKdqzRzgG39K7GAehATGS8jghA7zNoS5CjSKkDEqWmNZg==",
       "cpu": [
         "arm64"
       ],
@@ -3488,9 +3504,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.0.2.tgz",
-      "integrity": "sha512-vX2C8xvWPIbpEgQht95+dY6BReKAvtDgPDGi0XN0kWJKkm4WdNmq5dnwscv/zxvi+n6jUTBhs6GtpkkWT4q8Gg==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.7.0.tgz",
+      "integrity": "sha512-/ImhO+T/RWJ96hUbxiCn2yWI0/MeQZV/aeukQQfhxiSXuZJfyqtdHPUPrc84jxCfXTxbJLmg4q+GBETeb61aNw==",
       "cpu": [
         "x64"
       ],
@@ -3501,9 +3517,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.0.2.tgz",
-      "integrity": "sha512-DVFIfcHOjgmeHOAqji4xNz2wczt1Bmzy9MwBZKBa83SjBVO/i38VHDR+9ixo8QpBOiEagmNw12DucG+v55tCrg==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.7.0.tgz",
+      "integrity": "sha512-zhye8POvTyUXlKbfPBVqoHy3t43gIgffY+7qBFqFxNqVtltQLtWeHNAbrMnXiLIfYmxcoL/feuLDote2tx+Qbg==",
       "cpu": [
         "arm"
       ],
@@ -3514,9 +3530,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.0.2.tgz",
-      "integrity": "sha512-GCK/a9ItUxPI0V5hQEJjH4JtOJO90GF2Hja7TO+EZ8rmkGvEi8/ZDMhXmcuDpQT7/PWrTT9RvnG8snMd5SrhBQ==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.7.0.tgz",
+      "integrity": "sha512-RAdr3OJnUum6Vs83cQmKjxdTg31zJnLLTkjhcFt0auxM6jw00GD6IPFF42uasYPr/wGC6TRm7FsQiJyk0qIEfg==",
       "cpu": [
         "arm64"
       ],
@@ -3527,9 +3543,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.0.2.tgz",
-      "integrity": "sha512-cLuBp7rOjIB1R2j/VazjCmHC7liWUur2e9mFflLJBAWCkrZ+X0+QwHLvOQakIwDymungzAKv6W9kHZnTp/Mqrg==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.7.0.tgz",
+      "integrity": "sha512-nhWwYsiJwZGq7SyR3afS3EekEOsEAlrNMpPC4ZDKn5ooYSEjDLe9W/xGvoIV8/F/+HNIY6jY8lIdXjjxfxopXw==",
       "cpu": [
         "arm64"
       ],
@@ -3539,10 +3555,23 @@
         "linux"
       ]
     },
+    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.7.0.tgz",
+      "integrity": "sha512-rlfy5RnQG1aop1BL/gjdH42M2geMUyVQqd52GJVirqYc787A/XVvl3kQ5NG/43KXgOgE9HXgCaEH05kzQ+hLoA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
     "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.0.2.tgz",
-      "integrity": "sha512-Zqw4iVnJr2naoyQus0yLy7sLtisCQcpdMKUCeXPBjkJtpiflRime/TMojbnl8O3oxUAj92mxr+t7im/RbgA20w==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.7.0.tgz",
+      "integrity": "sha512-cCkoGlGWfBobdDtiiypxf79q6k3/iRVGu1HVLbD92gWV5WZbmuWJCgRM4x2N6i7ljGn1cGytPn9ZAfS8UwF6vg==",
       "cpu": [
         "x64"
       ],
@@ -3553,9 +3582,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.0.2.tgz",
-      "integrity": "sha512-jJRU9TyUD/iMqjf8aLAp7XiN3pIj5v6Qcu+cdzBfVTKDD0Fvua4oUoK8eVJ9ZuKBEQKt3WdlcwJXFkpmMLk6kg==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.7.0.tgz",
+      "integrity": "sha512-R2oBf2p/Arc1m+tWmiWbpHBjEcJnHVnv6bsypu4tcKdrYTpDfl1UT9qTyfkIL1iiii5D4WHxUHCg5X0pzqmxFg==",
       "cpu": [
         "x64"
       ],
@@ -3566,9 +3595,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.0.2.tgz",
-      "integrity": "sha512-ZkS2NixCxHKC4zbOnw64ztEGGDVIYP6nKkGBfOAxEPW71Sji9v8z3yaHNuae/JHPwXA+14oDefnOuVfxl59SmQ==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.7.0.tgz",
+      "integrity": "sha512-CPtgaQL1aaPc80m8SCVEoxFGHxKYIt3zQYC3AccL/SqqiWXblo3pgToHuBwR8eCP2Toa+X1WmTR/QKFMykws7g==",
       "cpu": [
         "arm64"
       ],
@@ -3579,9 +3608,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.0.2.tgz",
-      "integrity": "sha512-3SKjj+tvnZ0oZq2BKB+fI+DqYI83VrRzk7eed8tJkxeZ4zxJZcLSE8YDQLYGq1tZAnAX+H076RHHB4gTZXsQzw==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.7.0.tgz",
+      "integrity": "sha512-pmioUlttNh9GXF5x2CzNa7Z8kmRTyhEzzAC+2WOOapjewMbl+3tGuAnxbwc5JyG8Jsz2+hf/QD/n5VjimOZ63g==",
       "cpu": [
         "ia32"
       ],
@@ -3592,9 +3621,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.0.2.tgz",
-      "integrity": "sha512-MBdJIOxRauKkry7t2q+rTHa3aWjVez2eioWg+etRVS3dE4tChhmt5oqZYr48R6bPmcwEhxQr96gVRfeQrLbqng==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.7.0.tgz",
+      "integrity": "sha512-SeZzC2QhhdBQUm3U0c8+c/P6UlRyBcLL2Xp5KX7z46WXZxzR8RJSIWL9wSUeBTgxog5LTPJuPj0WOT9lvrtP7Q==",
       "cpu": [
         "x64"
       ],
@@ -3734,18 +3763,18 @@
       }
     },
     "node_modules/@types/accepts": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz",
-      "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==",
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz",
+      "integrity": "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==",
       "dev": true,
       "dependencies": {
         "@types/node": "*"
       }
     },
     "node_modules/@types/body-parser": {
-      "version": "1.19.2",
-      "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
-      "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
+      "version": "1.19.5",
+      "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
+      "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
       "dev": true,
       "dependencies": {
         "@types/connect": "*",
@@ -3768,24 +3797,24 @@
       }
     },
     "node_modules/@types/connect": {
-      "version": "3.4.35",
-      "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
-      "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+      "version": "3.4.38",
+      "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+      "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
       "dev": true,
       "dependencies": {
         "@types/node": "*"
       }
     },
     "node_modules/@types/content-disposition": {
-      "version": "0.5.5",
-      "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.5.tgz",
-      "integrity": "sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==",
+      "version": "0.5.8",
+      "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.8.tgz",
+      "integrity": "sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==",
       "dev": true
     },
     "node_modules/@types/cookies": {
-      "version": "0.7.7",
-      "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz",
-      "integrity": "sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==",
+      "version": "0.7.10",
+      "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.10.tgz",
+      "integrity": "sha512-hmUCjAk2fwZVPPkkPBcI7jGLIR5mg4OVoNMBwU6aVsMm/iNPY7z9/R+x2fSwLt/ZXoGua6C5Zy2k5xOo9jUyhQ==",
       "dev": true,
       "dependencies": {
         "@types/connect": "*",
@@ -3832,9 +3861,9 @@
       "dev": true
     },
     "node_modules/@types/express": {
-      "version": "4.17.17",
-      "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
-      "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==",
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
+      "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
       "dev": true,
       "dependencies": {
         "@types/body-parser": "*",
@@ -3844,9 +3873,9 @@
       }
     },
     "node_modules/@types/express-serve-static-core": {
-      "version": "4.17.35",
-      "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz",
-      "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==",
+      "version": "4.17.41",
+      "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz",
+      "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==",
       "dev": true,
       "dependencies": {
         "@types/node": "*",
@@ -3875,15 +3904,15 @@
       }
     },
     "node_modules/@types/http-assert": {
-      "version": "1.5.3",
-      "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz",
-      "integrity": "sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==",
+      "version": "1.5.5",
+      "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.5.tgz",
+      "integrity": "sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==",
       "dev": true
     },
     "node_modules/@types/http-errors": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz",
-      "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
+      "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
       "dev": true
     },
     "node_modules/@types/is-empty": {
@@ -3906,15 +3935,15 @@
       "dev": true
     },
     "node_modules/@types/keygrip": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz",
-      "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==",
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz",
+      "integrity": "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==",
       "dev": true
     },
     "node_modules/@types/koa": {
-      "version": "2.13.8",
-      "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.8.tgz",
-      "integrity": "sha512-Ugmxmgk/yPRW3ptBTh9VjOLwsKWJuGbymo1uGX0qdaqqL18uJiiG1ZoV0rxCOYSaDGhvEp5Ece02Amx0iwaxQQ==",
+      "version": "2.13.12",
+      "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.12.tgz",
+      "integrity": "sha512-vAo1KuDSYWFDB4Cs80CHvfmzSQWeUb909aQib0C0aFx4sw0K9UZFz2m5jaEP+b3X1+yr904iQiruS0hXi31jbw==",
       "dev": true,
       "dependencies": {
         "@types/accepts": "*",
@@ -3928,9 +3957,9 @@
       }
     },
     "node_modules/@types/koa-compose": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz",
-      "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==",
+      "version": "3.2.8",
+      "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.8.tgz",
+      "integrity": "sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==",
       "dev": true,
       "dependencies": {
         "@types/koa": "*"
@@ -3968,9 +3997,9 @@
       "dev": true
     },
     "node_modules/@types/mime": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
-      "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+      "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
       "dev": true
     },
     "node_modules/@types/minimatch": {
@@ -4010,9 +4039,9 @@
       "dev": true
     },
     "node_modules/@types/qs": {
-      "version": "6.9.7",
-      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
-      "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
+      "version": "6.9.10",
+      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz",
+      "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==",
       "dev": true
     },
     "node_modules/@types/raf": {
@@ -4022,9 +4051,9 @@
       "optional": true
     },
     "node_modules/@types/range-parser": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
-      "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+      "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
       "dev": true
     },
     "node_modules/@types/resolve": {
@@ -4034,9 +4063,9 @@
       "dev": true
     },
     "node_modules/@types/send": {
-      "version": "0.17.1",
-      "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
-      "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==",
+      "version": "0.17.4",
+      "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
+      "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
       "dev": true,
       "dependencies": {
         "@types/mime": "^1",
@@ -4044,9 +4073,9 @@
       }
     },
     "node_modules/@types/serve-static": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
-      "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==",
+      "version": "1.15.5",
+      "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz",
+      "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==",
       "dev": true,
       "dependencies": {
         "@types/http-errors": "*",
@@ -4110,61 +4139,25 @@
       "dev": true
     },
     "node_modules/@web/config-loader": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.2.1.tgz",
-      "integrity": "sha512-cQvTYA5lWLyyO8/R2aOReiudLa8r0LFHvMNYCwSAjzvrghb+AHxaW3BJWP9ORx6OaDcI7g5X8OATA81LSJce4A==",
-      "dev": true,
-      "dependencies": {
-        "semver": "^7.3.4"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@web/config-loader/node_modules/lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-      "dev": true,
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@web/config-loader/node_modules/semver": {
-      "version": "7.5.4",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-      "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.3.1.tgz",
+      "integrity": "sha512-IYjHXUgSGGNpO3YJQ9foLcazbJlAWDdJGRe9be7aOhon0Nd6Na5JIOJAej7jsMu76fKHr4b4w2LfIdNQ4fJ8pA==",
       "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
-      "bin": {
-        "semver": "bin/semver.js"
-      },
       "engines": {
-        "node": ">=10"
+        "node": ">=18.0.0"
       }
     },
-    "node_modules/@web/config-loader/node_modules/yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-      "dev": true
-    },
     "node_modules/@web/dev-server": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.3.3.tgz",
-      "integrity": "sha512-dILoqPa4hHh/p2jK702fDHPSRv5JSjDiDaXKE+IfCX/hNEuX7SQ65Z5JPB7T+5qbtsOxbG/KOQpo2q8ZGm7hOQ==",
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.4.1.tgz",
+      "integrity": "sha512-GHeyH8MBZQpODFiHiXAdX4hOVbeDyD/DUermUinh/nexWAZUcXyXa200RItuAL6b25MQ3D/5hKNDypujSvXxiw==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.12.11",
         "@types/command-line-args": "^5.0.0",
-        "@web/config-loader": "^0.2.1",
-        "@web/dev-server-core": "^0.5.1",
-        "@web/dev-server-rollup": "^0.5.1",
+        "@web/config-loader": "^0.3.0",
+        "@web/dev-server-core": "^0.7.0",
+        "@web/dev-server-rollup": "^0.6.1",
         "camelcase": "^6.2.0",
         "command-line-args": "^5.1.1",
         "command-line-usage": "^7.0.1",
@@ -4180,18 +4173,18 @@
         "web-dev-server": "dist/bin.js"
       },
       "engines": {
-        "node": ">=16.0.0"
+        "node": ">=18.0.0"
       }
     },
     "node_modules/@web/dev-server-core": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.5.2.tgz",
-      "integrity": "sha512-7YjWmwzM+K5fPvBCXldUIMTK4EnEufi1aWQWinQE81oW1CqzEwmyUNCtnWV9fcPA4kJC4qrpcjWNGF4YDWxuSg==",
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.0.tgz",
+      "integrity": "sha512-1FJe6cJ3r0x0ZmxY/FnXVduQD4lKX7QgYhyS6N+VmIpV+tBU4sGRbcrmeoYeY+nlnPa6p2oNuonk3X5ln/W95g==",
       "dev": true,
       "dependencies": {
         "@types/koa": "^2.11.6",
         "@types/ws": "^7.4.0",
-        "@web/parse5-utils": "^2.0.0",
+        "@web/parse5-utils": "^2.1.0",
         "chokidar": "^3.4.3",
         "clone": "^2.1.2",
         "es-module-lexer": "^1.0.0",
@@ -4209,7 +4202,7 @@
         "ws": "^7.4.2"
       },
       "engines": {
-        "node": ">=16.0.0"
+        "node": ">=18.0.0"
       }
     },
     "node_modules/@web/dev-server-core/node_modules/lru-cache": {
@@ -4222,65 +4215,49 @@
       }
     },
     "node_modules/@web/dev-server-esbuild": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/@web/dev-server-esbuild/-/dev-server-esbuild-0.4.1.tgz",
-      "integrity": "sha512-oUrxo7ggxeaWuQafu5bgiAJFatA+YEeYhgkUMB2CHq/SVleKgyPgQCqx42eVBJ2uWMyI1YWSpKtNueCmocwQzw==",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@web/dev-server-esbuild/-/dev-server-esbuild-1.0.1.tgz",
+      "integrity": "sha512-EoLLFuv5Y47pqY1IJBcGZswzkqJd+/vN4BDI3oYq8p9dDE9EuQVkC7vweAUkH7vDzI7xUp+f0UzJeQcj9t7zNQ==",
       "dev": true,
       "dependencies": {
         "@mdn/browser-compat-data": "^4.0.0",
-        "@web/dev-server-core": "^0.5.1",
-        "esbuild": "^0.16 || ^0.17",
+        "@web/dev-server-core": "^0.7.0",
+        "esbuild": "^0.19.5",
         "parse5": "^6.0.1",
         "ua-parser-js": "^1.0.33"
       },
       "engines": {
-        "node": ">=16.0.0"
+        "node": ">=18.0.0"
       }
     },
     "node_modules/@web/dev-server-rollup": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.5.2.tgz",
-      "integrity": "sha512-R1heFIOmbExKJn2auDcOcF0EPoLQotZF1HE8Bpqq4TfLRkc7w+JClLdwkOMr/+Ip608cRw8VMkc7teYDFkvSXw==",
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.1.tgz",
+      "integrity": "sha512-vhtsQ8qu1pBHailOBOYJwZnYDc1Lmx6ZAd2j+y5PD2ck0R1LmVsZ7dZK8hDCpkvpvlu2ndURjL9tbzdcsBRJmg==",
       "dev": true,
       "dependencies": {
         "@rollup/plugin-node-resolve": "^15.0.1",
-        "@web/dev-server-core": "^0.5.0",
+        "@web/dev-server-core": "^0.7.0",
         "nanocolors": "^0.2.1",
         "parse5": "^6.0.1",
-        "rollup": "^3.15.0",
+        "rollup": "^4.4.0",
         "whatwg-url": "^11.0.0"
       },
       "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@web/dev-server-rollup/node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "dev": true,
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
+        "node": ">=18.0.0"
       }
     },
     "node_modules/@web/parse5-utils": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.0.1.tgz",
-      "integrity": "sha512-FQI72BU5CXhpp7gLRskOQGGCcwvagLZnMnDwAfjrxo3pm1KOQzr8Vl+438IGpHV62xvjNdF1pjXwXcf7eekWGw==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz",
+      "integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==",
       "dev": true,
       "dependencies": {
         "@types/parse5": "^6.0.1",
         "parse5": "^6.0.1"
       },
       "engines": {
-        "node": ">=16.0.0"
+        "node": ">=18.0.0"
       }
     },
     "node_modules/@webassemblyjs/ast": {
@@ -4980,13 +4957,14 @@
       "dev": true
     },
     "node_modules/axios": {
-      "version": "0.27.2",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
-      "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
+      "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
       "dev": true,
       "dependencies": {
-        "follow-redirects": "^1.14.9",
-        "form-data": "^4.0.0"
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
       }
     },
     "node_modules/axios/node_modules/form-data": {
@@ -5003,6 +4981,12 @@
         "node": ">= 6"
       }
     },
+    "node_modules/axios/node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "dev": true
+    },
     "node_modules/babel-loader": {
       "version": "9.1.3",
       "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz",
@@ -6518,9 +6502,9 @@
       }
     },
     "node_modules/core-js": {
-      "version": "3.33.0",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.0.tgz",
-      "integrity": "sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw==",
+      "version": "3.34.0",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.34.0.tgz",
+      "integrity": "sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==",
       "hasInstallScript": true,
       "funding": {
         "type": "opencollective",
@@ -6528,9 +6512,9 @@
       }
     },
     "node_modules/core-js-bundle": {
-      "version": "3.33.0",
-      "resolved": "https://registry.npmjs.org/core-js-bundle/-/core-js-bundle-3.33.0.tgz",
-      "integrity": "sha512-RtJhxLOfMyKZaXXrqhPszvP8TdeYJxz+KX0B4tF9DXT0zFrfYa9leH7j7LovzhCcwM5xS9KtOyHmiDEZMlXOQA==",
+      "version": "3.34.0",
+      "resolved": "https://registry.npmjs.org/core-js-bundle/-/core-js-bundle-3.34.0.tgz",
+      "integrity": "sha512-6afGRU6ouqeVDVCmwXVE9H+oYmXsR77a9Iax83RcgXi3fOGgemzAzNWauwnKD4iIR8j5hzy/6bCF3d7nmAt/lA==",
       "dev": true,
       "hasInstallScript": true,
       "funding": {
@@ -6642,9 +6626,9 @@
       }
     },
     "node_modules/cypress": {
-      "version": "13.3.1",
-      "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.3.1.tgz",
-      "integrity": "sha512-g4mJLZxYN+UAF2LMy3Znd4LBnUmS59Vynd81VES59RdW48Yt+QtR2cush3melOoVNz0PPbADpWr8DcUx6mif8Q==",
+      "version": "13.6.1",
+      "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.6.1.tgz",
+      "integrity": "sha512-k1Wl5PQcA/4UoTffYKKaxA0FJKwg8yenYNYRzLt11CUR0Kln+h7Udne6mdU1cUIdXBDTVZWtmiUjzqGs7/pEpw==",
       "dev": true,
       "hasInstallScript": true,
       "dependencies": {
@@ -6700,9 +6684,9 @@
       }
     },
     "node_modules/cypress-multi-reporters": {
-      "version": "1.6.3",
-      "resolved": "https://registry.npmjs.org/cypress-multi-reporters/-/cypress-multi-reporters-1.6.3.tgz",
-      "integrity": "sha512-klb9pf6oAF4WCLHotu9gdB8ukYBdeTzbEMuESKB3KT54HhrZj65vQxubAgrULV5H2NWqxHdUhlntPbKZChNvEw==",
+      "version": "1.6.4",
+      "resolved": "https://registry.npmjs.org/cypress-multi-reporters/-/cypress-multi-reporters-1.6.4.tgz",
+      "integrity": "sha512-3xU2t6pZjZy/ORHaCvci5OT1DAboS4UuMMM8NBAizeb2C9qmHt+cgAjXgurazkwkPRdO7ccK39M5ZaPCju0r6A==",
       "dev": true,
       "dependencies": {
         "debug": "^4.3.4",
@@ -6894,9 +6878,9 @@
       }
     },
     "node_modules/dayjs": {
-      "version": "1.11.9",
-      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz",
-      "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==",
+      "version": "1.11.10",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
+      "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==",
       "dev": true
     },
     "node_modules/debounce": {
@@ -7530,9 +7514,9 @@
       "dev": true
     },
     "node_modules/esbuild": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
-      "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.8.tgz",
+      "integrity": "sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==",
       "dev": true,
       "hasInstallScript": true,
       "bin": {
@@ -7542,28 +7526,28 @@
         "node": ">=12"
       },
       "optionalDependencies": {
-        "@esbuild/android-arm": "0.17.19",
-        "@esbuild/android-arm64": "0.17.19",
-        "@esbuild/android-x64": "0.17.19",
-        "@esbuild/darwin-arm64": "0.17.19",
-        "@esbuild/darwin-x64": "0.17.19",
-        "@esbuild/freebsd-arm64": "0.17.19",
-        "@esbuild/freebsd-x64": "0.17.19",
-        "@esbuild/linux-arm": "0.17.19",
-        "@esbuild/linux-arm64": "0.17.19",
-        "@esbuild/linux-ia32": "0.17.19",
-        "@esbuild/linux-loong64": "0.17.19",
-        "@esbuild/linux-mips64el": "0.17.19",
-        "@esbuild/linux-ppc64": "0.17.19",
-        "@esbuild/linux-riscv64": "0.17.19",
-        "@esbuild/linux-s390x": "0.17.19",
-        "@esbuild/linux-x64": "0.17.19",
-        "@esbuild/netbsd-x64": "0.17.19",
-        "@esbuild/openbsd-x64": "0.17.19",
-        "@esbuild/sunos-x64": "0.17.19",
-        "@esbuild/win32-arm64": "0.17.19",
-        "@esbuild/win32-ia32": "0.17.19",
-        "@esbuild/win32-x64": "0.17.19"
+        "@esbuild/android-arm": "0.19.8",
+        "@esbuild/android-arm64": "0.19.8",
+        "@esbuild/android-x64": "0.19.8",
+        "@esbuild/darwin-arm64": "0.19.8",
+        "@esbuild/darwin-x64": "0.19.8",
+        "@esbuild/freebsd-arm64": "0.19.8",
+        "@esbuild/freebsd-x64": "0.19.8",
+        "@esbuild/linux-arm": "0.19.8",
+        "@esbuild/linux-arm64": "0.19.8",
+        "@esbuild/linux-ia32": "0.19.8",
+        "@esbuild/linux-loong64": "0.19.8",
+        "@esbuild/linux-mips64el": "0.19.8",
+        "@esbuild/linux-ppc64": "0.19.8",
+        "@esbuild/linux-riscv64": "0.19.8",
+        "@esbuild/linux-s390x": "0.19.8",
+        "@esbuild/linux-x64": "0.19.8",
+        "@esbuild/netbsd-x64": "0.19.8",
+        "@esbuild/openbsd-x64": "0.19.8",
+        "@esbuild/sunos-x64": "0.19.8",
+        "@esbuild/win32-arm64": "0.19.8",
+        "@esbuild/win32-ia32": "0.19.8",
+        "@esbuild/win32-x64": "0.19.8"
       }
     },
     "node_modules/escalade": {
@@ -8798,9 +8782,9 @@
       "dev": true
     },
     "node_modules/follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+      "version": "1.15.3",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
+      "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
       "dev": true,
       "funding": [
         {
@@ -9182,16 +9166,16 @@
       }
     },
     "node_modules/globby": {
-      "version": "11.0.4",
-      "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz",
-      "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==",
+      "version": "11.1.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
       "dev": true,
       "dependencies": {
         "array-union": "^2.1.0",
         "dir-glob": "^3.0.1",
-        "fast-glob": "^3.1.1",
-        "ignore": "^5.1.4",
-        "merge2": "^1.3.0",
+        "fast-glob": "^3.2.9",
+        "ignore": "^5.2.0",
+        "merge2": "^1.4.1",
         "slash": "^3.0.0"
       },
       "engines": {
@@ -9546,9 +9530,9 @@
       }
     },
     "node_modules/i18next": {
-      "version": "23.5.1",
-      "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.5.1.tgz",
-      "integrity": "sha512-JelYzcaCoFDaa+Ysbfz2JsGAKkrHiMG6S61+HLBUEIPaF40WMwW9hCPymlQGrP+wWawKxKPuSuD71WZscCsWHg==",
+      "version": "23.7.8",
+      "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.7.8.tgz",
+      "integrity": "sha512-yCe9964O+1abdIG01AOzk6P9mQi0HVJV1B57whYJQu6TjmrB9JHHDYonDI8amGt6M6b9bP3x3R0Zh7ROmvX7JQ==",
       "funding": [
         {
           "type": "individual",
@@ -9564,7 +9548,7 @@
         }
       ],
       "dependencies": {
-        "@babel/runtime": "^7.22.5"
+        "@babel/runtime": "^7.23.2"
       }
     },
     "node_modules/iconv-lite": {
@@ -10666,9 +10650,9 @@
       }
     },
     "node_modules/joi": {
-      "version": "17.9.2",
-      "resolved": "https://registry.npmjs.org/joi/-/joi-17.9.2.tgz",
-      "integrity": "sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==",
+      "version": "17.11.0",
+      "resolved": "https://registry.npmjs.org/joi/-/joi-17.11.0.tgz",
+      "integrity": "sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==",
       "dev": true,
       "dependencies": {
         "@hapi/hoek": "^9.0.0",
@@ -11413,12 +11397,12 @@
       }
     },
     "node_modules/magic-string": {
-      "version": "0.27.0",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz",
-      "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+      "version": "0.30.5",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
+      "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/sourcemap-codec": "^1.4.13"
+        "@jridgewell/sourcemap-codec": "^1.4.15"
       },
       "engines": {
         "node": ">=12"
@@ -16037,9 +16021,9 @@
       }
     },
     "node_modules/replace-in-file": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-7.0.1.tgz",
-      "integrity": "sha512-KbhgPq04eA+TxXuUxpgWIH9k/TjF+28ofon2PXP7vq6izAILhxOtksCVcLuuQLtyjouBaPdlH6RJYYcSPVxCOA==",
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-7.0.2.tgz",
+      "integrity": "sha512-tPG+Qmqf+x2Rf1WVdb/9B5tFIf6KJ5hs3fgxh1OTzPRUugPPvyAva7NvCJtnSpmyq6r+ABYcuUOqZkm6yzGSUw==",
       "dependencies": {
         "chalk": "^4.1.2",
         "glob": "^8.1.0",
@@ -16424,9 +16408,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.0.2.tgz",
-      "integrity": "sha512-MCScu4usMPCeVFaiLcgMDaBQeYi1z6vpWxz0r0hq0Hv77Y2YuOTZldkuNJ54BdYBH3e+nkrk6j0Rre/NLDBYzg==",
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.7.0.tgz",
+      "integrity": "sha512-7Kw0dUP4BWH78zaZCqF1rPyQ8D5DSU6URG45v1dqS/faNsx9WXyess00uTOZxKr7oR/4TOjO1CPudT8L1UsEgw==",
       "dev": true,
       "bin": {
         "rollup": "dist/bin/rollup"
@@ -16436,18 +16420,19 @@
         "npm": ">=8.0.0"
       },
       "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.0.2",
-        "@rollup/rollup-android-arm64": "4.0.2",
-        "@rollup/rollup-darwin-arm64": "4.0.2",
-        "@rollup/rollup-darwin-x64": "4.0.2",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.0.2",
-        "@rollup/rollup-linux-arm64-gnu": "4.0.2",
-        "@rollup/rollup-linux-arm64-musl": "4.0.2",
-        "@rollup/rollup-linux-x64-gnu": "4.0.2",
-        "@rollup/rollup-linux-x64-musl": "4.0.2",
-        "@rollup/rollup-win32-arm64-msvc": "4.0.2",
-        "@rollup/rollup-win32-ia32-msvc": "4.0.2",
-        "@rollup/rollup-win32-x64-msvc": "4.0.2",
+        "@rollup/rollup-android-arm-eabi": "4.7.0",
+        "@rollup/rollup-android-arm64": "4.7.0",
+        "@rollup/rollup-darwin-arm64": "4.7.0",
+        "@rollup/rollup-darwin-x64": "4.7.0",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.7.0",
+        "@rollup/rollup-linux-arm64-gnu": "4.7.0",
+        "@rollup/rollup-linux-arm64-musl": "4.7.0",
+        "@rollup/rollup-linux-riscv64-gnu": "4.7.0",
+        "@rollup/rollup-linux-x64-gnu": "4.7.0",
+        "@rollup/rollup-linux-x64-musl": "4.7.0",
+        "@rollup/rollup-win32-arm64-msvc": "4.7.0",
+        "@rollup/rollup-win32-ia32-msvc": "4.7.0",
+        "@rollup/rollup-win32-x64-msvc": "4.7.0",
         "fsevents": "~2.3.2"
       }
     },
@@ -17344,9 +17329,9 @@
       }
     },
     "node_modules/start-server-and-test": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.1.tgz",
-      "integrity": "sha512-8PFo4DLLLCDMuS51/BEEtE1m9CAXw1LNVtZSS1PzkYQh6Qf9JUwM4huYeSoUumaaoAyuwYBwCa9OsrcpMqcOdQ==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.3.tgz",
+      "integrity": "sha512-QsVObjfjFZKJE6CS6bSKNwWZCKBG6975/jKRPPGFfFh+yOQglSeGXiNWjzgQNXdphcBI9nXbyso9tPfX4YAUhg==",
       "dev": true,
       "dependencies": {
         "arg": "^5.0.2",
@@ -17356,7 +17341,7 @@
         "execa": "5.1.1",
         "lazy-ass": "1.6.0",
         "ps-tree": "1.2.0",
-        "wait-on": "7.0.1"
+        "wait-on": "7.2.0"
       },
       "bin": {
         "server-test": "src/bin/start.js",
@@ -19433,16 +19418,16 @@
       "dev": true
     },
     "node_modules/wait-on": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.0.1.tgz",
-      "integrity": "sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz",
+      "integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==",
       "dev": true,
       "dependencies": {
-        "axios": "^0.27.2",
-        "joi": "^17.7.0",
+        "axios": "^1.6.1",
+        "joi": "^17.11.0",
         "lodash": "^4.17.21",
-        "minimist": "^1.2.7",
-        "rxjs": "^7.8.0"
+        "minimist": "^1.2.8",
+        "rxjs": "^7.8.1"
       },
       "bin": {
         "wait-on": "bin/wait-on"
@@ -20176,7 +20161,7 @@
         "react-dom": "^18.2.0"
       },
       "devDependencies": {
-        "@babel/preset-react": "^7.22.15"
+        "@babel/preset-react": "^7.23.3"
       }
     },
     "packages/svgcanvas": {
diff --git a/package.json b/package.json
index 4872accc3..70c03fbf8 100644
--- a/package.json
+++ b/package.json
@@ -85,37 +85,37 @@
   "dependencies": {
     "@svgedit/svgcanvas": "7.2.1",
     "browser-fs-access": "0.35.0",
-    "core-js": "3.33.0",
+    "core-js": "3.34.0",
     "elix": "15.0.1",
     "html2canvas": "1.4.1",
-    "i18next": "23.5.1",
+    "i18next": "23.7.8",
     "jspdf": "2.5.1",
     "pathseg": "1.2.1",
     "regenerator-runtime": "0.14.0",
-    "replace-in-file": "^7.0.1",
+    "replace-in-file": "^7.0.2",
     "svg2pdf.js": "2.2.2"
   },
   "devDependencies": {
-    "@babel/core": "7.23.2",
-    "@babel/preset-env": "7.23.2",
+    "@babel/core": "7.23.5",
+    "@babel/preset-env": "7.23.5",
     "@babel/register": "7.22.15",
-    "@babel/runtime-corejs3": "7.23.2",
-    "@cypress/code-coverage": "3.12.3",
+    "@babel/runtime-corejs3": "7.23.5",
+    "@cypress/code-coverage": "3.12.13",
     "@rollup/plugin-babel": "^6.0.4",
-    "@rollup/plugin-commonjs": "25.0.5",
-    "@rollup/plugin-dynamic-import-vars": "2.0.6",
+    "@rollup/plugin-commonjs": "25.0.7",
+    "@rollup/plugin-dynamic-import-vars": "2.1.2",
     "@rollup/plugin-node-resolve": "15.2.3",
-    "@rollup/plugin-replace": "5.0.3",
+    "@rollup/plugin-replace": "5.0.5",
     "@rollup/plugin-url": "8.0.2",
-    "@web/dev-server": "0.3.3",
-    "@web/dev-server-esbuild": "^0.4.1",
-    "@web/dev-server-rollup": "0.5.2",
+    "@web/dev-server": "0.4.1",
+    "@web/dev-server-esbuild": "^1.0.1",
+    "@web/dev-server-rollup": "0.6.1",
     "babel-plugin-istanbul": "^6.1.1",
     "babel-plugin-transform-object-rest-spread": "7.0.0-beta.3",
-    "core-js-bundle": "3.33.0",
+    "core-js-bundle": "3.34.0",
     "cp-cli": "2.0.0",
-    "cypress": "13.3.1",
-    "cypress-multi-reporters": "1.6.3",
+    "cypress": "13.6.1",
+    "cypress-multi-reporters": "1.6.4",
     "jamilih": "0.58.2",
     "jsdoc": "4.0.2",
     "node-static": "0.7.11",
@@ -128,13 +128,13 @@
     "remark-cli": "12.0.0",
     "remark-lint-ordered-list-marker-value": "3.1.2",
     "rimraf": "5.0.5",
-    "rollup": "4.0.2",
+    "rollup": "4.7.0",
     "rollup-plugin-copy": "3.5.0",
     "rollup-plugin-filesize": "10.0.0",
     "rollup-plugin-html": "0.2.1",
     "rollup-plugin-progress": "1.1.2",
     "rollup-plugin-re": "1.0.7",
     "standard": "17.1.0",
-    "start-server-and-test": "2.0.1"
+    "start-server-and-test": "2.0.3"
   }
 }
diff --git a/packages/svgcanvas/core/undo.js b/packages/svgcanvas/core/undo.js
index 74482c420..fe8206bc6 100644
--- a/packages/svgcanvas/core/undo.js
+++ b/packages/svgcanvas/core/undo.js
@@ -167,8 +167,8 @@ export const changeSelectedAttributeNoUndoMethod = (attr, newValue, elems) => {
     // Set x,y vals on elements that don't have them
     if ((attr === 'x' || attr === 'y') && noXYElems.includes(elem.tagName)) {
       const bbox = getStrokedBBoxDefaultVisible([elem])
-      const diffX = attr === 'x' ? newValue - bbox.x : 0
-      const diffY = attr === 'y' ? newValue - bbox.y : 0
+      const diffX = attr === 'x' ? parseFloat(newValue) - bbox.x : 0
+      const diffY = attr === 'y' ? parseFloat(newValue) - bbox.y : 0
       svgCanvas.moveSelectedElements(diffX * zoom, diffY * zoom, true)
       continue
     }
@@ -189,7 +189,7 @@ export const changeSelectedAttributeNoUndoMethod = (attr, newValue, elems) => {
       } else if (attr === '#href') {
         setHref(elem, newValue)
       } else if (newValue) {
-        elem.setAttribute(attr, newValue)
+        elem.setAttribute(attr, isNaN(parseFloat(newValue)) ? newValue : parseFloat(newValue))
       } else if (typeof newValue === 'number') {
         elem.setAttribute(attr, newValue)
       } else {
diff --git a/packages/svgcanvas/core/utilities.js b/packages/svgcanvas/core/utilities.js
index 6ebc7ea65..9be88f32c 100644
--- a/packages/svgcanvas/core/utilities.js
+++ b/packages/svgcanvas/core/utilities.js
@@ -7,14 +7,18 @@
  */
 
 import { NS } from './namespaces.js'
-import { setUnitAttr, getTypeMap } from './units.js'
+import { setUnitAttr, getTypeMap, shortFloat } from './units.js'
 import {
-  hasMatrixTransform, transformListToTransform, transformBox, getTransformList
+  hasMatrixTransform,
+  transformListToTransform,
+  transformBox,
+  getTransformList
 } from './math.js'
 import { getClosest, mergeDeep } from '../common/util.js'
 
 // Much faster than running getBBox() every time
-const visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use,clipPath'
+const visElems =
+  'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use,clipPath'
 const visElemsArr = visElems.split(',')
 // const hidElems = 'defs,desc,feGaussianBlur,filter,linearGradient,marker,mask,metadata,pattern,radialGradient,stop,switch,symbol,title,textPath';
 
@@ -22,15 +26,15 @@ let svgCanvas = null
 let svgroot_ = null
 
 /**
-* Object with the following keys/values.
-* @typedef {PlainObject} module:utilities.SVGElementJSON
-* @property {string} element - Tag name of the SVG element to create
-* @property {PlainObject<string, string>} attr - Has key-value attributes to assign to the new element.
-*   An `id` should be set so that {@link module:utilities.EditorContext#addSVGElementsFromJson} can later re-identify the element for modification or replacement.
-* @property {boolean} [curStyles=false] - Indicates whether current style attributes should be applied first
-* @property {module:utilities.SVGElementJSON[]} [children] - Data objects to be added recursively as children
-* @property {string} [namespace="http://www.w3.org/2000/svg"] - Indicate a (non-SVG) namespace
-*/
+ * Object with the following keys/values.
+ * @typedef {PlainObject} module:utilities.SVGElementJSON
+ * @property {string} element - Tag name of the SVG element to create
+ * @property {PlainObject<string, string>} attr - Has key-value attributes to assign to the new element.
+ *   An `id` should be set so that {@link module:utilities.EditorContext#addSVGElementsFromJson} can later re-identify the element for modification or replacement.
+ * @property {boolean} [curStyles=false] - Indicates whether current style attributes should be applied first
+ * @property {module:utilities.SVGElementJSON[]} [children] - Data objects to be added recursively as children
+ * @property {string} [namespace="http://www.w3.org/2000/svg"] - Indicate a (non-SVG) namespace
+ */
 
 /**
  * An object that creates SVG elements for the canvas.
@@ -49,38 +53,38 @@ let svgroot_ = null
  * @function module:utilities.EditorContext#addSVGElementsFromJson
  * @param {module:utilities.SVGElementJSON} data
  * @returns {Element} The new element
-*/
+ */
 /**
  * @function module:utilities.EditorContext#getSelectedElements
  * @returns {Element[]} the array with selected DOM elements
-*/
+ */
 /**
  * @function module:utilities.EditorContext#getDOMDocument
  * @returns {HTMLDocument}
-*/
+ */
 /**
  * @function module:utilities.EditorContext#getDOMContainer
  * @returns {HTMLElement}
-*/
+ */
 /**
  * @function module:utilities.EditorContext#getSvgRoot
  * @returns {SVGSVGElement}
-*/
+ */
 /**
  * @function module:utilities.EditorContext#getBaseUnit
  * @returns {string}
-*/
+ */
 /**
  * @function module:utilities.EditorContext#getSnappingStep
  * @returns {Float|string}
-*/
+ */
 
 /**
-* @function module:utilities.init
-* @param {module:utilities.EditorContext} canvas
-* @returns {void}
-*/
-export const init = (canvas) => {
+ * @function module:utilities.init
+ * @param {module:utilities.EditorContext} canvas
+ * @returns {void}
+ */
+export const init = canvas => {
   svgCanvas = canvas
   svgroot_ = canvas.getSvgRoot()
 }
@@ -92,19 +96,19 @@ export const init = (canvas) => {
  * @returns {string} The string with entity declarations in the internal subset removed
  * @todo This might be needed in other places `parseFromString` is used even without LGTM flagging
  */
-export const dropXMLInternalSubset = (str) => {
+export const dropXMLInternalSubset = str => {
   return str.replace(/(<!DOCTYPE\s+\w*\s*\[).*(\?]>)/, '$1$2')
   // return str.replace(/(?<doctypeOpen><!DOCTYPE\s+\w*\s*\[).*(?<doctypeClose>\?\]>)/, '$<doctypeOpen>$<doctypeClose>');
 }
 
 /**
-* Converts characters in a string to XML-friendly entities.
-* @function module:utilities.toXml
-* @example `&` becomes `&amp;`
-* @param {string} str - The string to be converted
-* @returns {string} The converted string
-*/
-export const toXml = (str) => {
+ * Converts characters in a string to XML-friendly entities.
+ * @function module:utilities.toXml
+ * @example `&` becomes `&amp;`
+ * @param {string} str - The string to be converted
+ * @returns {string} The converted string
+ */
+export const toXml = str => {
   // &apos; is ok in XML, but not HTML
   // &gt; does not normally need escaping, though it can if within a CDATA expression (and preceded by "]]")
   return str
@@ -123,11 +127,11 @@ export const toXml = (str) => {
 //        also precalculate the size of the array needed.
 
 /**
-* Converts a string to base64.
-* @function module:utilities.encode64
-* @param {string} input
-* @returns {string} Base64 output
-*/
+ * Converts a string to base64.
+ * @function module:utilities.encode64
+ * @param {string} input
+ * @returns {string} Base64 output
+ */
 export function encode64 (input) {
   // base64 strings are 4/3 larger than the original string
   input = encodeUTF8(input) // convert non-ASCII characters
@@ -135,11 +139,11 @@ export function encode64 (input) {
 }
 
 /**
-* Converts a string from base64.
-* @function module:utilities.decode64
-* @param {string} input Base64-encoded input
-* @returns {string} Decoded output
-*/
+ * Converts a string from base64.
+ * @function module:utilities.decode64
+ * @param {string} input Base64-encoded input
+ * @returns {string} Decoded output
+ */
 export function decode64 (input) {
   return decodeUTF8(window.atob(input))
 }
@@ -155,28 +159,28 @@ export function hashCode (word) {
   if (word.length === 0) return hash
   for (let i = 0; i < word.length; i++) {
     chr = word.charCodeAt(i)
-    hash = ((hash << 5) - hash) + chr
+    hash = (hash << 5) - hash + chr
     hash |= 0 // Convert to 32bit integer
   }
   return hash
 }
 
 /**
-* @function module:utilities.decodeUTF8
-* @param {string} argString
-* @returns {string}
-*/
+ * @function module:utilities.decodeUTF8
+ * @param {string} argString
+ * @returns {string}
+ */
 export function decodeUTF8 (argString) {
   return decodeURIComponent(escape(argString))
 }
 
 // codedread:does not seem to work with webkit-based browsers on OSX // Brettz9: please test again as function upgraded
 /**
-* @function module:utilities.encodeUTF8
-* @param {string} argString
-* @returns {string}
-*/
-export const encodeUTF8 = (argString) => {
+ * @function module:utilities.encodeUTF8
+ * @param {string} argString
+ * @returns {string}
+ */
+export const encodeUTF8 = argString => {
   return unescape(encodeURIComponent(argString))
 }
 
@@ -186,8 +190,13 @@ export const encodeUTF8 = (argString) => {
  * @param {string} dataurl
  * @returns {string} object URL or empty string
  */
-export const dataURLToObjectURL = (dataurl) => {
-  if (typeof Uint8Array === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined' || !URL.createObjectURL) {
+export const dataURLToObjectURL = dataurl => {
+  if (
+    typeof Uint8Array === 'undefined' ||
+    typeof Blob === 'undefined' ||
+    typeof URL === 'undefined' ||
+    !URL.createObjectURL
+  ) {
     return ''
   }
   const arr = dataurl.split(',')
@@ -213,7 +222,7 @@ export const dataURLToObjectURL = (dataurl) => {
  * @param {Blob} blob A Blob object or File object
  * @returns {string} object URL or empty string
  */
-export const createObjectURL = (blob) => {
+export const createObjectURL = blob => {
   if (!blob || typeof URL === 'undefined' || !URL.createObjectURL) {
     return ''
   }
@@ -227,39 +236,43 @@ export const blankPageObjectURL = (() => {
   if (typeof Blob === 'undefined') {
     return ''
   }
-  const blob = new Blob(['<html><head><title>SVG-edit</title></head><body>&nbsp;</body></html>'], { type: 'text/html' })
+  const blob = new Blob(
+    ['<html><head><title>SVG-edit</title></head><body>&nbsp;</body></html>'],
+    { type: 'text/html' }
+  )
   return createObjectURL(blob)
 })()
 
 /**
-* Converts a string to use XML references (for non-ASCII).
-* @function module:utilities.convertToXMLReferences
-* @param {string} input
-* @returns {string} Decimal numeric character references
-*/
-export const convertToXMLReferences = (input) => {
-  let output = '';
-  [...input].forEach((ch) => {
+ * Converts a string to use XML references (for non-ASCII).
+ * @function module:utilities.convertToXMLReferences
+ * @param {string} input
+ * @returns {string} Decimal numeric character references
+ */
+export const convertToXMLReferences = input => {
+  let output = ''
+  ;[...input].forEach(ch => {
     const c = ch.charCodeAt()
-    output += (c <= 127) ? ch : `&#${c};`
+    output += c <= 127 ? ch : `&#${c};`
   })
   return output
 }
 
 /**
-* Cross-browser compatible method of converting a string to an XML tree.
-* Found this function [here]{@link http://groups.google.com/group/jquery-dev/browse_thread/thread/c6d11387c580a77f}.
-* @function module:utilities.text2xml
-* @param {string} sXML
-* @throws {Error}
-* @returns {XMLDocument}
-*/
-export const text2xml = (sXML) => {
+ * Cross-browser compatible method of converting a string to an XML tree.
+ * Found this function [here]{@link http://groups.google.com/group/jquery-dev/browse_thread/thread/c6d11387c580a77f}.
+ * @function module:utilities.text2xml
+ * @param {string} sXML
+ * @throws {Error}
+ * @returns {XMLDocument}
+ */
+export const text2xml = sXML => {
   if (sXML.includes('<svg:svg')) {
     sXML = sXML.replace(/<(\/?)svg:/g, '<$1').replace('xmlns:svg', 'xmlns')
   }
 
-  let out; let dXML
+  let out
+  let dXML
   try {
     dXML = new DOMParser()
     dXML.async = false
@@ -268,41 +281,43 @@ export const text2xml = (sXML) => {
   }
   try {
     out = dXML.parseFromString(sXML, 'text/xml')
-  } catch (e2) { throw new Error('Error parsing XML string') }
+  } catch (e2) {
+    throw new Error('Error parsing XML string')
+  }
   return out
 }
 
 /**
-* @typedef {PlainObject} module:utilities.BBoxObject (like `DOMRect`)
-* @property {Float} x
-* @property {Float} y
-* @property {Float} width
-* @property {Float} height
-*/
+ * @typedef {PlainObject} module:utilities.BBoxObject (like `DOMRect`)
+ * @property {Float} x
+ * @property {Float} y
+ * @property {Float} width
+ * @property {Float} height
+ */
 
 /**
-* Converts a `SVGRect` into an object.
-* @function module:utilities.bboxToObj
-* @param {SVGRect} bbox - a SVGRect
-* @returns {module:utilities.BBoxObject} An object with properties names x, y, width, height.
-*/
+ * Converts a `SVGRect` into an object.
+ * @function module:utilities.bboxToObj
+ * @param {SVGRect} bbox - a SVGRect
+ * @returns {module:utilities.BBoxObject} An object with properties names x, y, width, height.
+ */
 export const bboxToObj = ({ x, y, width, height }) => {
   return { x, y, width, height }
 }
 
 /**
-* @callback module:utilities.TreeWalker
-* @param {Element} elem - DOM element being traversed
-* @returns {void}
-*/
+ * @callback module:utilities.TreeWalker
+ * @param {Element} elem - DOM element being traversed
+ * @returns {void}
+ */
 
 /**
-* Walks the tree and executes the callback on each element in a top-down fashion.
-* @function module:utilities.walkTree
-* @param {Element} elem - DOM element to traverse
-* @param {module:utilities.TreeWalker} cbFn - Callback function to run on each element
-* @returns {void}
-*/
+ * Walks the tree and executes the callback on each element in a top-down fashion.
+ * @function module:utilities.walkTree
+ * @param {Element} elem - DOM element to traverse
+ * @param {module:utilities.TreeWalker} cbFn - Callback function to run on each element
+ * @returns {void}
+ */
 export const walkTree = (elem, cbFn) => {
   if (elem?.nodeType === 1) {
     cbFn(elem)
@@ -314,13 +329,13 @@ export const walkTree = (elem, cbFn) => {
 }
 
 /**
-* Walks the tree and executes the callback on each element in a depth-first fashion.
-* @function module:utilities.walkTreePost
-* @todo Shouldn't this be calling walkTreePost?
-* @param {Element} elem - DOM element to traverse
-* @param {module:utilities.TreeWalker} cbFn - Callback function to run on each element
-* @returns {void}
-*/
+ * Walks the tree and executes the callback on each element in a depth-first fashion.
+ * @function module:utilities.walkTreePost
+ * @todo Shouldn't this be calling walkTreePost?
+ * @param {Element} elem - DOM element to traverse
+ * @param {module:utilities.TreeWalker} cbFn - Callback function to run on each element
+ * @returns {void}
+ */
 export const walkTreePost = (elem, cbFn) => {
   if (elem?.nodeType === 1) {
     let i = elem.childNodes.length
@@ -332,15 +347,15 @@ export const walkTreePost = (elem, cbFn) => {
 }
 
 /**
-* Extracts the URL from the `url(...)` syntax of some attributes.
-* Three variants:
-*  - `<circle fill="url(someFile.svg#foo)" />`
-*  - `<circle fill="url('someFile.svg#foo')" />`
-*  - `<circle fill='url("someFile.svg#foo")' />`
-* @function module:utilities.getUrlFromAttr
-* @param {string} attrVal The attribute value as a string
-* @returns {string} String with just the URL, like "someFile.svg#foo"
-*/
+ * Extracts the URL from the `url(...)` syntax of some attributes.
+ * Three variants:
+ *  - `<circle fill="url(someFile.svg#foo)" />`
+ *  - `<circle fill="url('someFile.svg#foo')" />`
+ *  - `<circle fill='url("someFile.svg#foo")' />`
+ * @function module:utilities.getUrlFromAttr
+ * @param {string} attrVal The attribute value as a string
+ * @returns {string} String with just the URL, like "someFile.svg#foo"
+ */
 export const getUrlFromAttr = function (attrVal) {
   if (attrVal) {
     // url('#somegrad')
@@ -359,29 +374,29 @@ export const getUrlFromAttr = function (attrVal) {
 }
 
 /**
-* @function module:utilities.getHref
-* @param {Element} elem
-* @returns {string} The given element's `xlink:href` value
-*/
+ * @function module:utilities.getHref
+ * @param {Element} elem
+ * @returns {string} The given element's `xlink:href` value
+ */
 export let getHref = function (elem) {
   return elem.getAttributeNS(NS.XLINK, 'href')
 }
 
 /**
-* Sets the given element's `xlink:href` value.
-* @function module:utilities.setHref
-* @param {Element} elem
-* @param {string} val
-* @returns {void}
-*/
+ * Sets the given element's `xlink:href` value.
+ * @function module:utilities.setHref
+ * @param {Element} elem
+ * @param {string} val
+ * @returns {void}
+ */
 export let setHref = function (elem, val) {
   elem.setAttributeNS(NS.XLINK, 'xlink:href', val)
 }
 
 /**
-* @function module:utilities.findDefs
-* @returns {SVGDefsElement} The document's `<defs>` element, creating it first if necessary
-*/
+ * @function module:utilities.findDefs
+ * @returns {SVGDefsElement} The document's `<defs>` element, creating it first if necessary
+ */
 export const findDefs = function () {
   const svgElement = svgCanvas.getSvgContent()
   let defs = svgElement.getElementsByTagNameNS(NS.SVG, 'defs')
@@ -403,12 +418,12 @@ export const findDefs = function () {
 // TODO(codedread): Consider moving the next to functions to bbox.js
 
 /**
-* Get correct BBox for a path in Webkit.
-* Converted from code found [here]{@link http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html}.
-* @function module:utilities.getPathBBox
-* @param {SVGPathElement} path - The path DOM element to get the BBox for
-* @returns {module:utilities.BBoxObject} A BBox-like object
-*/
+ * Get correct BBox for a path in Webkit.
+ * Converted from code found [here]{@link http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html}.
+ * @function module:utilities.getPathBBox
+ * @param {SVGPathElement} path - The path DOM element to get the BBox for
+ * @returns {module:utilities.BBoxObject} A BBox-like object
+ */
 export const getPathBBox = function (path) {
   const seglist = path.pathSegList
   const tot = seglist.numberOfItems
@@ -419,17 +434,23 @@ export const getPathBBox = function (path) {
 
   const getCalc = function (j, P1, P2, P3) {
     return function (t) {
-      return 1 - t ** 3 * P0[j] +
-        3 * 1 - t ** 2 * t * P1[j] +
+      return (
+        1 -
+        t ** 3 * P0[j] +
+        3 * 1 -
+        t ** 2 * t * P1[j] +
         3 * (1 - t) * t ** 2 * P2[j] +
         t ** 3 * P3[j]
+      )
     }
   }
 
   for (let i = 0; i < tot; i++) {
     const seg = seglist.getItem(i)
 
-    if (seg.x === undefined) { continue }
+    if (seg.x === undefined) {
+      continue
+    }
 
     // Add actual points to limits
     bounds[0].push(P0[0])
@@ -448,7 +469,9 @@ export const getPathBBox = function (path) {
         const c = 3 * P1[j] - 3 * P0[j]
 
         if (a === 0) {
-          if (b === 0) { continue }
+          if (b === 0) {
+            continue
+          }
           const t = -c / b
           if (t > 0 && t < 1) {
             bounds[j].push(calc(t))
@@ -456,11 +479,17 @@ export const getPathBBox = function (path) {
           continue
         }
         const b2ac = b ** 2 - 4 * c * a
-        if (b2ac < 0) { continue }
+        if (b2ac < 0) {
+          continue
+        }
         const t1 = (-b + Math.sqrt(b2ac)) / (2 * a)
-        if (t1 > 0 && t1 < 1) { bounds[j].push(calc(t1)) }
+        if (t1 > 0 && t1 < 1) {
+          bounds[j].push(calc(t1))
+        }
         const t2 = (-b - Math.sqrt(b2ac)) / (2 * a)
-        if (t2 > 0 && t2 < 1) { bounds[j].push(calc(t2)) }
+        if (t2 > 0 && t2 < 1) {
+          bounds[j].push(calc(t2))
+        }
       }
       P0 = P3
     } else {
@@ -482,15 +511,17 @@ export const getPathBBox = function (path) {
 }
 
 /**
-* Get the given/selected element's bounding box object, convert it to be more
-* usable when necessary.
-* @function module:utilities.getBBox
-* @param {Element} elem - Optional DOM element to get the BBox for
-* @returns {module:utilities.BBoxObject} Bounding box object
-*/
+ * Get the given/selected element's bounding box object, convert it to be more
+ * usable when necessary.
+ * @function module:utilities.getBBox
+ * @param {Element} elem - Optional DOM element to get the BBox for
+ * @returns {module:utilities.BBoxObject} Bounding box object
+ */
 export const getBBox = function (elem) {
   const selected = elem || svgCanvas.getSelectedElements()[0]
-  if (elem.nodeType !== 1) { return null }
+  if (elem.nodeType !== 1) {
+    return null
+  }
   const elname = selected.nodeName
 
   let ret = null
@@ -512,7 +543,6 @@ export const getBBox = function (elem) {
       }
       break
     default:
-
       if (elname === 'use') {
         ret = selected.getBBox() // , true);
       } else if (visElemsArr.includes(elname)) {
@@ -520,8 +550,8 @@ export const getBBox = function (elem) {
           try {
             ret = selected.getBBox()
           } catch (err) {
-          // tspan (and textPath apparently) have no `getBBox` in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=937268
-          // Re: Chrome returning bbox for containing text element, see: https://bugs.chromium.org/p/chromium/issues/detail?id=349835
+            // tspan (and textPath apparently) have no `getBBox` in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=937268
+            // Re: Chrome returning bbox for containing text element, see: https://bugs.chromium.org/p/chromium/issues/detail?id=349835
             const extent = selected.getExtentOfChar(0) // pos+dimensions of the first glyph
             const width = selected.getComputedTextLength() // width of the tspan
             ret = {
@@ -532,7 +562,7 @@ export const getBBox = function (elem) {
             }
           }
         } else {
-        // Check if element is child of a foreignObject
+          // Check if element is child of a foreignObject
           const fo = getClosest(selected.parentNode, 'foreignObject')
           if (fo.length && fo[0].getBBox) {
             ret = fo[0].getBBox()
@@ -549,26 +579,26 @@ export const getBBox = function (elem) {
 }
 
 /**
-* @typedef {GenericArray} module:utilities.PathSegmentArray
-* @property {Integer} length 2
-* @property {"M"|"L"|"C"|"Z"} 0
-* @property {Float[]} 1
-*/
+ * @typedef {GenericArray} module:utilities.PathSegmentArray
+ * @property {Integer} length 2
+ * @property {"M"|"L"|"C"|"Z"} 0
+ * @property {Float[]} 1
+ */
 
 /**
-* Create a path 'd' attribute from path segments.
-* Each segment is an array of the form: `[singleChar, [x,y, x,y, ...]]`
-* @function module:utilities.getPathDFromSegments
-* @param {module:utilities.PathSegmentArray[]} pathSegments - An array of path segments to be converted
-* @returns {string} The converted path d attribute.
-*/
+ * Create a path 'd' attribute from path segments.
+ * Each segment is an array of the form: `[singleChar, [x,y, x,y, ...]]`
+ * @function module:utilities.getPathDFromSegments
+ * @param {module:utilities.PathSegmentArray[]} pathSegments - An array of path segments to be converted
+ * @returns {string} The converted path d attribute.
+ */
 export const getPathDFromSegments = function (pathSegments) {
   let d = ''
 
   pathSegments.forEach(function ([singleChar, pts], _j) {
     d += singleChar
     for (let i = 0; i < pts.length; i += 2) {
-      d += (pts[i] + ',' + pts[i + 1]) + ' '
+      d += pts[i] + ',' + pts[i + 1] + ' '
     }
   })
 
@@ -576,15 +606,17 @@ export const getPathDFromSegments = function (pathSegments) {
 }
 
 /**
-* Make a path 'd' attribute from a simple SVG element shape.
-* @function module:utilities.getPathDFromElement
-* @param {Element} elem - The element to be converted
-* @returns {string} The path d attribute or `undefined` if the element type is unknown.
-*/
+ * Make a path 'd' attribute from a simple SVG element shape.
+ * @function module:utilities.getPathDFromElement
+ * @param {Element} elem - The element to be converted
+ * @returns {string} The path d attribute or `undefined` if the element type is unknown.
+ */
 export const getPathDFromElement = function (elem) {
   // Possibly the cubed root of 6, but 1.81 works best
   let num = 1.81
-  let d; let rx; let ry
+  let d
+  let rx
+  let ry
   switch (elem.tagName) {
     case 'ellipse':
     case 'circle': {
@@ -597,24 +629,26 @@ export const getPathDFromElement = function (elem) {
         rx = ry
       }
       d = getPathDFromSegments([
-        ['M', [(cx - rx), (cy)]],
-        ['C', [(cx - rx), (cy - ry / num), (cx - rx / num), (cy - ry), (cx), (cy - ry)]],
-        ['C', [(cx + rx / num), (cy - ry), (cx + rx), (cy - ry / num), (cx + rx), (cy)]],
-        ['C', [(cx + rx), (cy + ry / num), (cx + rx / num), (cy + ry), (cx), (cy + ry)]],
-        ['C', [(cx - rx / num), (cy + ry), (cx - rx), (cy + ry / num), (cx - rx), (cy)]],
+        ['M', [cx - rx, cy]],
+        ['C', [cx - rx, cy - ry / num, cx - rx / num, cy - ry, cx, cy - ry]],
+        ['C', [cx + rx / num, cy - ry, cx + rx, cy - ry / num, cx + rx, cy]],
+        ['C', [cx + rx, cy + ry / num, cx + rx / num, cy + ry, cx, cy + ry]],
+        ['C', [cx - rx / num, cy + ry, cx - rx, cy + ry / num, cx - rx, cy]],
         ['Z', []]
       ])
       break
-    } case 'path':
+    }
+    case 'path':
       d = elem.getAttribute('d')
       break
-    case 'line': {
-      const x1 = elem.getAttribute('x1')
-      const y1 = elem.getAttribute('y1')
-      const x2 = elem.getAttribute('x2')
-      const y2 = elem.getAttribute('y2')
-      d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2
-    }
+    case 'line':
+      {
+        const x1 = elem.getAttribute('x1')
+        const y1 = elem.getAttribute('y1')
+        const x2 = elem.getAttribute('x2')
+        const y2 = elem.getAttribute('y2')
+        d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2
+      }
       break
     case 'polyline':
       d = 'M' + elem.getAttribute('points')
@@ -647,14 +681,25 @@ export const getPathDFromElement = function (elem) {
           ['L', [x + w - rx, y]],
           ['C', [x + w - rx / num, y, x + w, y + ry / num, x + w, y + ry]],
           ['L', [x + w, y + h - ry]],
-          ['C', [x + w, y + h - ry / num, x + w - rx / num, y + h, x + w - rx, y + h]],
+          [
+            'C',
+            [
+              x + w,
+              y + h - ry / num,
+              x + w - rx / num,
+              y + h,
+              x + w - rx,
+              y + h
+            ]
+          ],
           ['L', [x + rx, y + h]],
           ['C', [x + rx / num, y + h, x, y + h - ry / num, x, y + h - ry]],
           ['L', [x, y + ry]],
           ['Z', []]
         ])
       break
-    } default:
+    }
+    default:
       break
   }
 
@@ -662,33 +707,39 @@ export const getPathDFromElement = function (elem) {
 }
 
 /**
-* Get a set of attributes from an element that is useful for convertToPath.
-* @function module:utilities.getExtraAttributesForConvertToPath
-* @param {Element} elem - The element to be probed
-* @returns {PlainObject<"marker-start"|"marker-end"|"marker-mid"|"filter"|"clip-path", string>} An object with attributes.
-*/
+ * Get a set of attributes from an element that is useful for convertToPath.
+ * @function module:utilities.getExtraAttributesForConvertToPath
+ * @param {Element} elem - The element to be probed
+ * @returns {PlainObject<"marker-start"|"marker-end"|"marker-mid"|"filter"|"clip-path", string>} An object with attributes.
+ */
 export const getExtraAttributesForConvertToPath = function (elem) {
-  const attrs = {};
+  const attrs = {}
   // TODO: make this list global so that we can properly maintain it
   // TODO: what about @transform, @clip-rule, @fill-rule, etc?
-  ['marker-start', 'marker-end', 'marker-mid', 'filter', 'clip-path'].forEach(function (item) {
-    const a = elem.getAttribute(item)
-    if (a) {
-      attrs[item] = a
+  ;['marker-start', 'marker-end', 'marker-mid', 'filter', 'clip-path'].forEach(
+    function (item) {
+      const a = elem.getAttribute(item)
+      if (a) {
+        attrs[item] = a
+      }
     }
-  })
+  )
   return attrs
 }
 
 /**
-* Get the BBox of an element-as-path.
-* @function module:utilities.getBBoxOfElementAsPath
-* @param {Element} elem - The DOM element to be probed
-* @param {module:utilities.EditorContext#addSVGElementsFromJson} addSVGElementsFromJson - Function to add the path element to the current layer. See canvas.addSVGElementsFromJson
-* @param {module:path.pathActions} pathActions - If a transform exists, `pathActions.resetOrientation()` is used. See: canvas.pathActions.
-* @returns {DOMRect|false} The resulting path's bounding box object.
-*/
-export const getBBoxOfElementAsPath = function (elem, addSVGElementsFromJson, pathActions) {
+ * Get the BBox of an element-as-path.
+ * @function module:utilities.getBBoxOfElementAsPath
+ * @param {Element} elem - The DOM element to be probed
+ * @param {module:utilities.EditorContext#addSVGElementsFromJson} addSVGElementsFromJson - Function to add the path element to the current layer. See canvas.addSVGElementsFromJson
+ * @param {module:path.pathActions} pathActions - If a transform exists, `pathActions.resetOrientation()` is used. See: canvas.pathActions.
+ * @returns {DOMRect|false} The resulting path's bounding box object.
+ */
+export const getBBoxOfElementAsPath = function (
+  elem,
+  addSVGElementsFromJson,
+  pathActions
+) {
   const path = addSVGElementsFromJson({
     element: 'path',
     attr: getExtraAttributesForConvertToPath(elem)
@@ -726,18 +777,18 @@ export const getBBoxOfElementAsPath = function (elem, addSVGElementsFromJson, pa
 }
 
 /**
-* Convert selected element to a path.
-* @function module:utilities.convertToPath
-* @param {Element} elem - The DOM element to be converted
-* @param {module:utilities.SVGElementJSON} attrs - Apply attributes to new path. see canvas.convertToPath
-* @param {module:utilities.EditorContext#addSVGElementsFromJson} addSVGElementsFromJson - Function to add the path element to the current layer. See canvas.addSVGElementsFromJson
-* @param {module:path.pathActions} pathActions - If a transform exists, pathActions.resetOrientation() is used. See: canvas.pathActions.
-* @param {module:draw.DrawCanvasInit#clearSelection|module:path.EditorContext#clearSelection} clearSelection - see [canvas.clearSelection]{@link module:svgcanvas.SvgCanvas#clearSelection}
-* @param {module:path.EditorContext#addToSelection} addToSelection - see [canvas.addToSelection]{@link module:svgcanvas.SvgCanvas#addToSelection}
-* @param {module:history} hstry - see history module
-* @param {module:path.EditorContext#addCommandToHistory|module:draw.DrawCanvasInit#addCommandToHistory} addCommandToHistory - see [canvas.addCommandToHistory]{@link module:svgcanvas~addCommandToHistory}
-* @returns {SVGPathElement|null} The converted path element or null if the DOM element was not recognized.
-*/
+ * Convert selected element to a path.
+ * @function module:utilities.convertToPath
+ * @param {Element} elem - The DOM element to be converted
+ * @param {module:utilities.SVGElementJSON} attrs - Apply attributes to new path. see canvas.convertToPath
+ * @param {module:utilities.EditorContext#addSVGElementsFromJson} addSVGElementsFromJson - Function to add the path element to the current layer. See canvas.addSVGElementsFromJson
+ * @param {module:path.pathActions} pathActions - If a transform exists, pathActions.resetOrientation() is used. See: canvas.pathActions.
+ * @param {module:draw.DrawCanvasInit#clearSelection|module:path.EditorContext#clearSelection} clearSelection - see [canvas.clearSelection]{@link module:svgcanvas.SvgCanvas#clearSelection}
+ * @param {module:path.EditorContext#addToSelection} addToSelection - see [canvas.addToSelection]{@link module:svgcanvas.SvgCanvas#addToSelection}
+ * @param {module:history} hstry - see history module
+ * @param {module:path.EditorContext#addCommandToHistory|module:draw.DrawCanvasInit#addCommandToHistory} addCommandToHistory - see [canvas.addCommandToHistory]{@link module:svgcanvas~addCommandToHistory}
+ * @returns {SVGPathElement|null} The converted path element or null if the DOM element was not recognized.
+ */
 export const convertToPath = (elem, attrs, svgCanvas) => {
   const batchCmd = new svgCanvas.history.BatchCommand('Convert element to Path')
 
@@ -777,7 +828,13 @@ export const convertToPath = (elem, attrs, svgCanvas) => {
     }
 
     const { nextSibling } = elem
-    batchCmd.addSubCommand(new svgCanvas.history.RemoveElementCommand(elem, nextSibling, elem.parentNode))
+    batchCmd.addSubCommand(
+      new svgCanvas.history.RemoveElementCommand(
+        elem,
+        nextSibling,
+        elem.parentNode
+      )
+    )
     svgCanvas.clearSelection()
     elem.remove() // We need to remove this element otherwise the nextSibling of 'path' won't be null and an exception will be thrown after subsequent undo and redos.
 
@@ -796,25 +853,25 @@ export const convertToPath = (elem, attrs, svgCanvas) => {
 }
 
 /**
-* Can the bbox be optimized over the native getBBox? The optimized bbox is the same as the native getBBox when
-* the rotation angle is a multiple of 90 degrees and there are no complex transforms.
-* Getting an optimized bbox can be dramatically slower, so we want to make sure it's worth it.
-*
-* The best example for this is a circle rotate 45 degrees. The circle doesn't get wider or taller when rotated
-* about it's center.
-*
-* The standard, unoptimized technique gets the native bbox of the circle, rotates the box 45 degrees, uses
-* that width and height, and applies any transforms to get the final bbox. This means the calculated bbox
-* is much wider than the original circle. If the angle had been 0, 90, 180, etc. both techniques render the
-* same bbox.
-*
-* The optimization is not needed if the rotation is a multiple 90 degrees. The default technique is to call
-* getBBox then apply the angle and any transforms.
-*
-* @param {Float} angle - The rotation angle in degrees
-* @param {boolean} hasAMatrixTransform - True if there is a matrix transform
-* @returns {boolean} True if the bbox can be optimized.
-*/
+ * Can the bbox be optimized over the native getBBox? The optimized bbox is the same as the native getBBox when
+ * the rotation angle is a multiple of 90 degrees and there are no complex transforms.
+ * Getting an optimized bbox can be dramatically slower, so we want to make sure it's worth it.
+ *
+ * The best example for this is a circle rotate 45 degrees. The circle doesn't get wider or taller when rotated
+ * about it's center.
+ *
+ * The standard, unoptimized technique gets the native bbox of the circle, rotates the box 45 degrees, uses
+ * that width and height, and applies any transforms to get the final bbox. This means the calculated bbox
+ * is much wider than the original circle. If the angle had been 0, 90, 180, etc. both techniques render the
+ * same bbox.
+ *
+ * The optimization is not needed if the rotation is a multiple 90 degrees. The default technique is to call
+ * getBBox then apply the angle and any transforms.
+ *
+ * @param {Float} angle - The rotation angle in degrees
+ * @param {boolean} hasAMatrixTransform - True if there is a matrix transform
+ * @returns {boolean} True if the bbox can be optimized.
+ */
 function bBoxCanBeOptimizedOverNativeGetBBox (angle, hasAMatrixTransform) {
   const angleModulo90 = angle % 90
   const closeTo90 = angleModulo90 < -89.99 || angleModulo90 > 89.99
@@ -823,14 +880,18 @@ function bBoxCanBeOptimizedOverNativeGetBBox (angle, hasAMatrixTransform) {
 }
 
 /**
-* Get bounding box that includes any transforms.
-* @function module:utilities.getBBoxWithTransform
-* @param {Element} elem - The DOM element to be converted
-* @param {module:utilities.EditorContext#addSVGElementsFromJson} addSVGElementsFromJson - Function to add the path element to the current layer. See canvas.addSVGElementsFromJson
-* @param {module:path.pathActions} pathActions - If a transform exists, pathActions.resetOrientation() is used. See: canvas.pathActions.
-* @returns {module:utilities.BBoxObject|module:math.TransformedBox|DOMRect} A single bounding box object
-*/
-export const getBBoxWithTransform = function (elem, addSVGElementsFromJson, pathActions) {
+ * Get bounding box that includes any transforms.
+ * @function module:utilities.getBBoxWithTransform
+ * @param {Element} elem - The DOM element to be converted
+ * @param {module:utilities.EditorContext#addSVGElementsFromJson} addSVGElementsFromJson - Function to add the path element to the current layer. See canvas.addSVGElementsFromJson
+ * @param {module:path.pathActions} pathActions - If a transform exists, pathActions.resetOrientation() is used. See: canvas.pathActions.
+ * @returns {module:utilities.BBoxObject|module:math.TransformedBox|DOMRect} A single bounding box object
+ */
+export const getBBoxWithTransform = function (
+  elem,
+  addSVGElementsFromJson,
+  pathActions
+) {
   // TODO: Fix issue with rotated groups. Currently they work
   // fine in FF, but not in other browsers (same problem mentioned
   // in Issue 339 comment #2).
@@ -852,14 +913,22 @@ export const getBBoxWithTransform = function (elem, addSVGElementsFromJson, path
       // TODO: why ellipse and not circle
       const elemNames = ['ellipse', 'path', 'line', 'polyline', 'polygon']
       if (elemNames.includes(elem.tagName)) {
-        goodBb = getBBoxOfElementAsPath(elem, addSVGElementsFromJson, pathActions)
+        goodBb = getBBoxOfElementAsPath(
+          elem,
+          addSVGElementsFromJson,
+          pathActions
+        )
         bb = goodBb
       } else if (elem.tagName === 'rect') {
         // Look for radius
         const rx = Number(elem.getAttribute('rx'))
         const ry = Number(elem.getAttribute('ry'))
         if (rx || ry) {
-          goodBb = getBBoxOfElementAsPath(elem, addSVGElementsFromJson, pathActions)
+          goodBb = getBBoxOfElementAsPath(
+            elem,
+            addSVGElementsFromJson,
+            pathActions
+          )
           bb = goodBb
         }
       }
@@ -879,9 +948,9 @@ export const getBBoxWithTransform = function (elem, addSVGElementsFromJson, path
  * @todo This is problematic with large stroke-width and, for example, a single
  * horizontal line. The calculated BBox extends way beyond left and right sides.
  */
-const getStrokeOffsetForBBox = (elem) => {
+const getStrokeOffsetForBBox = elem => {
   const sw = elem.getAttribute('stroke-width')
-  return (!isNaN(sw) && elem.getAttribute('stroke') !== 'none') ? sw / 2 : 0
+  return !isNaN(sw) && elem.getAttribute('stroke') !== 'none' ? sw / 2 : 0
 }
 
 /**
@@ -893,25 +962,33 @@ const getStrokeOffsetForBBox = (elem) => {
  */
 
 /**
-* Get the bounding box for one or more stroked and/or transformed elements.
-* @function module:utilities.getStrokedBBox
-* @param {Element[]} elems - Array with DOM elements to check
-* @param {module:utilities.EditorContext#addSVGElementsFromJson} addSVGElementsFromJson - Function to add the path element to the current layer. See canvas.addSVGElementsFromJson
-* @param {module:path.pathActions} pathActions - If a transform exists, pathActions.resetOrientation() is used. See: canvas.pathActions.
-* @returns {module:utilities.BBoxObject|module:math.TransformedBox|DOMRect} A single bounding box object
-*/
+ * Get the bounding box for one or more stroked and/or transformed elements.
+ * @function module:utilities.getStrokedBBox
+ * @param {Element[]} elems - Array with DOM elements to check
+ * @param {module:utilities.EditorContext#addSVGElementsFromJson} addSVGElementsFromJson - Function to add the path element to the current layer. See canvas.addSVGElementsFromJson
+ * @param {module:path.pathActions} pathActions - If a transform exists, pathActions.resetOrientation() is used. See: canvas.pathActions.
+ * @returns {module:utilities.BBoxObject|module:math.TransformedBox|DOMRect} A single bounding box object
+ */
 export const getStrokedBBox = (elems, addSVGElementsFromJson, pathActions) => {
-  if (!elems || !elems.length) { return false }
+  if (!elems || !elems.length) {
+    return false
+  }
 
   let fullBb
-  elems.forEach((elem) => {
-    if (fullBb) { return }
-    if (!elem.parentNode) { return }
+  elems.forEach(elem => {
+    if (fullBb) {
+      return
+    }
+    if (!elem.parentNode) {
+      return
+    }
     fullBb = getBBoxWithTransform(elem, addSVGElementsFromJson, pathActions)
   })
 
   // This shouldn't ever happen...
-  if (!fullBb) { return null }
+  if (!fullBb) {
+    return null
+  }
 
   // fullBb doesn't include the stoke, so this does no good!
   // if (elems.length == 1) return fullBb;
@@ -929,8 +1006,12 @@ export const getStrokedBBox = (elems, addSVGElementsFromJson, pathActions) => {
     maxX += offset
     maxY += offset
   } else {
-    elems.forEach((elem) => {
-      const curBb = getBBoxWithTransform(elem, addSVGElementsFromJson, pathActions)
+    elems.forEach(elem => {
+      const curBb = getBBoxWithTransform(
+        elem,
+        addSVGElementsFromJson,
+        pathActions
+      )
       if (curBb) {
         const offset = getStrokeOffsetForBBox(elem)
         minX = Math.min(minX, curBb.x - offset)
@@ -944,28 +1025,33 @@ export const getStrokedBBox = (elems, addSVGElementsFromJson, pathActions) => {
     })
   }
 
-  fullBb.x = minX
-  fullBb.y = minY
-  fullBb.width = maxX - minX
-  fullBb.height = maxY - minY
+  fullBb.x = shortFloat(minX)
+  fullBb.y = shortFloat(minY)
+  fullBb.width = shortFloat(maxX - minX)
+  fullBb.height = shortFloat(maxY - minY)
   return fullBb
 }
 
 /**
-* Get all elements that have a BBox (excludes `<defs>`, `<title>`, etc).
-* Note that 0-opacity, off-screen etc elements are still considered "visible"
-* for this function.
-* @function module:utilities.getVisibleElements
-* @param {Element} parentElement - The parent DOM element to search within
-* @returns {Element[]} All "visible" elements.
-*/
-export const getVisibleElements = (parentElement) => {
+ * Get all elements that have a BBox (excludes `<defs>`, `<title>`, etc).
+ * Note that 0-opacity, off-screen etc elements are still considered "visible"
+ * for this function.
+ * @function module:utilities.getVisibleElements
+ * @param {Element} parentElement - The parent DOM element to search within
+ * @returns {Element[]} All "visible" elements.
+ */
+export const getVisibleElements = parentElement => {
   if (!parentElement) {
     const svgContent = svgCanvas.getSvgContent()
     for (let i = 0; i < svgContent.children.length; i++) {
       if (svgContent.children[i].getBBox) {
         const bbox = svgContent.children[i].getBBox()
-        if (bbox.width !== 0 && bbox.height !== 0 && bbox.width !== 0 && bbox.height !== 0) {
+        if (
+          bbox.width !== 0 &&
+          bbox.height !== 0 &&
+          bbox.width !== 0 &&
+          bbox.height !== 0
+        ) {
           parentElement = svgContent.children[i]
           break
         }
@@ -977,7 +1063,7 @@ export const getVisibleElements = (parentElement) => {
   if (parentElement) {
     const children = parentElement.children
     // eslint-disable-next-line array-callback-return
-    Array.from(children, (elem) => {
+    Array.from(children, elem => {
       if (elem.getBBox) {
         contentElems.push(elem)
       }
@@ -987,13 +1073,15 @@ export const getVisibleElements = (parentElement) => {
 }
 
 /**
-* Get the bounding box for one or more stroked and/or transformed elements.
-* @function module:utilities.getStrokedBBoxDefaultVisible
-* @param {Element[]} elems - Array with DOM elements to check
-* @returns {module:utilities.BBoxObject} A single bounding box object
-*/
-export const getStrokedBBoxDefaultVisible = (elems) => {
-  if (!elems) { elems = getVisibleElements() }
+ * Get the bounding box for one or more stroked and/or transformed elements.
+ * @function module:utilities.getStrokedBBoxDefaultVisible
+ * @param {Element[]} elems - Array with DOM elements to check
+ * @returns {module:utilities.BBoxObject} A single bounding box object
+ */
+export const getStrokedBBoxDefaultVisible = elems => {
+  if (!elems) {
+    elems = getVisibleElements()
+  }
   return getStrokedBBox(
     elems,
     svgCanvas.addSVGElementsFromJson,
@@ -1002,30 +1090,32 @@ export const getStrokedBBoxDefaultVisible = (elems) => {
 }
 
 /**
-* Get the rotation angle of the given transform list.
-* @function module:utilities.getRotationAngleFromTransformList
-* @param {SVGTransformList} tlist - List of transforms
-* @param {boolean} toRad - When true returns the value in radians rather than degrees
-* @returns {Float} The angle in degrees or radians
-*/
+ * Get the rotation angle of the given transform list.
+ * @function module:utilities.getRotationAngleFromTransformList
+ * @param {SVGTransformList} tlist - List of transforms
+ * @param {boolean} toRad - When true returns the value in radians rather than degrees
+ * @returns {Float} The angle in degrees or radians
+ */
 export const getRotationAngleFromTransformList = (tlist, toRad) => {
-  if (!tlist) { return 0 } // <svg> element have no tlist
+  if (!tlist) {
+    return 0
+  } // <svg> element have no tlist
   for (let i = 0; i < tlist.numberOfItems; ++i) {
     const xform = tlist.getItem(i)
     if (xform.type === 4) {
-      return toRad ? xform.angle * Math.PI / 180.0 : xform.angle
+      return toRad ? (xform.angle * Math.PI) / 180.0 : xform.angle
     }
   }
   return 0.0
 }
 
 /**
-* Get the rotation angle of the given/selected DOM element.
-* @function module:utilities.getRotationAngle
-* @param {Element} [elem] - DOM element to get the angle for. Default to first of selected elements.
-* @param {boolean} [toRad=false] - When true returns the value in radians rather than degrees
-* @returns {Float} The angle in degrees or radians
-*/
+ * Get the rotation angle of the given/selected DOM element.
+ * @function module:utilities.getRotationAngle
+ * @param {Element} [elem] - DOM element to get the angle for. Default to first of selected elements.
+ * @param {boolean} [toRad=false] - When true returns the value in radians rather than degrees
+ * @returns {Float} The angle in degrees or radians
+ */
 export let getRotationAngle = (elem, toRad) => {
   const selected = elem || svgCanvas.getSelectedElements()[0]
   // find the rotation transform (if any) and set it
@@ -1034,21 +1124,21 @@ export let getRotationAngle = (elem, toRad) => {
 }
 
 /**
-* Get the reference element associated with the given attribute value.
-* @function module:utilities.getRefElem
-* @param {string} attrVal - The attribute value as a string
-* @returns {Element} Reference element
-*/
-export const getRefElem = (attrVal) => {
+ * Get the reference element associated with the given attribute value.
+ * @function module:utilities.getRefElem
+ * @param {string} attrVal - The attribute value as a string
+ * @returns {Element} Reference element
+ */
+export const getRefElem = attrVal => {
   return getElement(getUrlFromAttr(attrVal).substr(1))
 }
 /**
-* Get the reference element associated with the given attribute value.
-* @function module:utilities.getFeGaussianBlur
-* @param {any} Element
-* @returns {any} Reference element
-*/
-export const getFeGaussianBlur = (ele) => {
+ * Get the reference element associated with the given attribute value.
+ * @function module:utilities.getFeGaussianBlur
+ * @param {any} Element
+ * @returns {any} Reference element
+ */
+export const getFeGaussianBlur = ele => {
   if (ele?.firstChild?.tagName === 'feGaussianBlur') {
     return ele.firstChild
   } else {
@@ -1064,30 +1154,33 @@ export const getFeGaussianBlur = (ele) => {
 }
 
 /**
-* Get a DOM element by ID within the SVG root element.
-* @function module:utilities.getElement
-* @param {string} id - String with the element's new ID
-* @returns {?Element}
-*/
-export const getElement = (id) => {
+ * Get a DOM element by ID within the SVG root element.
+ * @function module:utilities.getElement
+ * @param {string} id - String with the element's new ID
+ * @returns {?Element}
+ */
+export const getElement = id => {
   // querySelector lookup
   return svgroot_.querySelector('#' + id)
 }
 
 /**
-* Assigns multiple attributes to an element.
-* @function module:utilities.assignAttributes
-* @param {Element} elem - DOM element to apply new attribute values to
-* @param {PlainObject<string, string>} attrs - Object with attribute keys/values
-* @param {Integer} [suspendLength] - Milliseconds to suspend redraw
-* @param {boolean} [unitCheck=false] - Boolean to indicate the need to use units.setUnitAttr
-* @returns {void}
-*/
+ * Assigns multiple attributes to an element.
+ * @function module:utilities.assignAttributes
+ * @param {Element} elem - DOM element to apply new attribute values to
+ * @param {PlainObject<string, string>} attrs - Object with attribute keys/values
+ * @param {Integer} [suspendLength] - Milliseconds to suspend redraw
+ * @param {boolean} [unitCheck=false] - Boolean to indicate the need to use units.setUnitAttr
+ * @returns {void}
+ */
 export const assignAttributes = (elem, attrs, suspendLength, unitCheck) => {
   for (const [key, value] of Object.entries(attrs)) {
-    const ns = (key.substr(0, 4) === 'xml:'
-      ? NS.XML
-      : key.substr(0, 6) === 'xlink:' ? NS.XLINK : null)
+    const ns =
+      key.substr(0, 4) === 'xml:'
+        ? NS.XML
+        : key.substr(0, 6) === 'xlink:'
+          ? NS.XLINK
+          : null
     if (value === undefined) {
       if (ns) {
         elem.removeAttributeNS(ns, key)
@@ -1107,12 +1200,12 @@ export const assignAttributes = (elem, attrs, suspendLength, unitCheck) => {
 }
 
 /**
-* Remove unneeded (default) attributes, making resulting SVG smaller.
-* @function module:utilities.cleanupElement
-* @param {Element} element - DOM element to clean up
-* @returns {void}
-*/
-export const cleanupElement = (element) => {
+ * Remove unneeded (default) attributes, making resulting SVG smaller.
+ * @function module:utilities.cleanupElement
+ * @param {Element} element - DOM element to clean up
+ * @returns {void}
+ */
+export const cleanupElement = element => {
   const defaults = {
     'fill-opacity': 1,
     'stop-opacity': 1,
@@ -1141,12 +1234,12 @@ export const cleanupElement = (element) => {
 }
 
 /**
-* Round value to for snapping.
-* @function module:utilities.snapToGrid
-* @param {Float} value
-* @returns {Integer}
-*/
-export const snapToGrid = (value) => {
+ * Round value to for snapping.
+ * @function module:utilities.snapToGrid
+ * @param {Float} value
+ * @returns {Integer}
+ */
+export const snapToGrid = value => {
   const unit = svgCanvas.getBaseUnit()
   let stepSize = svgCanvas.getSnappingStep()
   if (unit !== 'px') {
@@ -1162,8 +1255,8 @@ export const snapToGrid = (value) => {
  * @param {Element} img - The DOM element to prevent the click on
  * @returns {void}
  */
-export const preventClickDefault = (img) => {
-  $click(img, (e) => {
+export const preventClickDefault = img => {
+  $click(img, e => {
     e.preventDefault()
   })
 }
@@ -1178,28 +1271,30 @@ export const preventClickDefault = (img) => {
  * @param {any} val
  * @returns {boolean}
  */
-export const isNullish = (val) => {
+export const isNullish = val => {
   return val === null || val === undefined
 }
 
 /**
-* Overwrite methods for unit testing.
-* @function module:utilities.mock
-* @param {PlainObject} mockMethods
-* @param {module:utilities.getHref} mockMethods.getHref
-* @param {module:utilities.setHref} mockMethods.setHref
-* @param {module:utilities.getRotationAngle} mockMethods.getRotationAngle
-* @returns {void}
-*/
+ * Overwrite methods for unit testing.
+ * @function module:utilities.mock
+ * @param {PlainObject} mockMethods
+ * @param {module:utilities.getHref} mockMethods.getHref
+ * @param {module:utilities.setHref} mockMethods.setHref
+ * @param {module:utilities.getRotationAngle} mockMethods.getRotationAngle
+ * @returns {void}
+ */
 export const mock = ({
-  getHref: getHrefUser, setHref: setHrefUser, getRotationAngle: getRotationAngleUser
+  getHref: getHrefUser,
+  setHref: setHrefUser,
+  getRotationAngle: getRotationAngleUser
 }) => {
   getHref = getHrefUser
   setHref = setHrefUser
   getRotationAngle = getRotationAngleUser
 }
 
-export const stringToHTML = (str) => {
+export const stringToHTML = str => {
   const parser = new DOMParser()
   const doc = parser.parseFromString(str, 'text/html')
   return doc.body.firstChild
@@ -1215,9 +1310,9 @@ export const insertChildAtIndex = (parent, child, index = 0) => {
 }
 
 // shortcuts to common DOM functions
-export const $id = (id) => document.getElementById(id)
-export const $qq = (sel) => document.querySelector(sel)
-export const $qa = (sel) => [...document.querySelectorAll(sel)]
+export const $id = id => document.getElementById(id)
+export const $qq = sel => document.querySelector(sel)
+export const $qa = sel => [...document.querySelectorAll(sel)]
 export const $click = (element, handler) => {
   element.addEventListener('click', handler)
   element.addEventListener('touchend', handler)
diff --git a/src/editor/panels/TopPanel.js b/src/editor/panels/TopPanel.js
index 6692b6cab..9f80d73df 100644
--- a/src/editor/panels/TopPanel.js
+++ b/src/editor/panels/TopPanel.js
@@ -232,7 +232,7 @@ class TopPanel {
       if (!isNode && currentMode !== 'pathedit') {
         this.displayTool('selected_panel')
         // Elements in this array already have coord fields
-        if (['line', 'circle', 'ellipse'].includes(elname)) {
+        if (['line', 'circle', 'ellipse', 'polygon'].includes(elname)) {
           this.hideTool('xy_panel')
         } else {
           let x
@@ -253,9 +253,23 @@ class TopPanel {
             x = convertUnit(x)
             y = convertUnit(y)
           }
+          /**
+           * Updates the value of an input field if needed
+           * @param {string} id - The ID of the input element to be updated.
+           * @param {number} newValue - The new numeric value to set in the input field.
+           */
+          const updateValue = (id, newValue) => {
+            const currentValue = $id(id).value // Get current value from the field
+            // do nothing if nothing changed...
+            if (parseFloat(currentValue) === newValue) {
+              return
+            }
+            $id(id).value = newValue
+          }
+
+          updateValue('selected_x', x)
+          updateValue('selected_y', y)
 
-          $id('selected_x').value = x || 0
-          $id('selected_y').value = y || 0
           this.displayTool('xy_panel')
         }
 
@@ -361,15 +375,12 @@ class TopPanel {
           this.displayTool('text_panel')
           $id('tool_italic').pressed = this.editor.svgCanvas.getItalic()
           $id('tool_bold').pressed = this.editor.svgCanvas.getBold()
-          $id(
-            'tool_text_decoration_underline'
-          ).pressed = this.editor.svgCanvas.hasTextDecoration('underline')
-          $id(
-            'tool_text_decoration_linethrough'
-          ).pressed = this.editor.svgCanvas.hasTextDecoration('line-through')
-          $id(
-            'tool_text_decoration_overline'
-          ).pressed = this.editor.svgCanvas.hasTextDecoration('overline')
+          $id('tool_text_decoration_underline').pressed =
+            this.editor.svgCanvas.hasTextDecoration('underline')
+          $id('tool_text_decoration_linethrough').pressed =
+            this.editor.svgCanvas.hasTextDecoration('line-through')
+          $id('tool_text_decoration_overline').pressed =
+            this.editor.svgCanvas.hasTextDecoration('overline')
           $id('tool_font_family').value = elem.getAttribute('font-family')
           $id('tool_text_anchor').setAttribute(
             'value',
@@ -420,7 +431,7 @@ class TopPanel {
     } else if (this.multiselected) {
       // Check if all selected elements are 'text' nodes, if yes enable text panel
       const selElems = this.editor.svgCanvas.getSelectedElements()
-      if (selElems.every((elem) => elem.tagName === 'text')) {
+      if (selElems.every(elem => elem.tagName === 'text')) {
         this.displayTool('text_panel')
       }
 
@@ -939,15 +950,21 @@ class TopPanel {
     $click($id('tool_make_link_multi'), this.makeHyperlink.bind(this))
     $click($id('tool_reorient'), this.reorientPath.bind(this))
     $click($id('tool_group_elements'), this.clickGroup.bind(this))
-    $id('tool_position').addEventListener('change', (evt) => this.clickAlignEle.bind(this)(evt))
+    $id('tool_position').addEventListener('change', evt =>
+      this.clickAlignEle.bind(this)(evt)
+    )
     $click($id('tool_align_left'), () => this.clickAlign.bind(this)('left'))
     $click($id('tool_align_right'), () => this.clickAlign.bind(this)('right'))
     $click($id('tool_align_center'), () => this.clickAlign.bind(this)('center'))
     $click($id('tool_align_top'), () => this.clickAlign.bind(this)('top'))
     $click($id('tool_align_bottom'), () => this.clickAlign.bind(this)('bottom'))
     $click($id('tool_align_middle'), () => this.clickAlign.bind(this)('middle'))
-    $click($id('tool_align_distrib_horiz'), () => this.clickAlign.bind(this)('distrib_horiz'))
-    $click($id('tool_align_distrib_verti'), () => this.clickAlign.bind(this)('distrib_verti'))
+    $click($id('tool_align_distrib_horiz'), () =>
+      this.clickAlign.bind(this)('distrib_horiz')
+    )
+    $click($id('tool_align_distrib_verti'), () =>
+      this.clickAlign.bind(this)('distrib_verti')
+    )
     $click($id('tool_node_clone'), this.clonePathNode.bind(this))
     $click($id('tool_node_delete'), this.deletePathNode.bind(this))
     $click($id('tool_openclose_path'), this.opencloseSubPath.bind(this))
@@ -960,19 +977,40 @@ class TopPanel {
     $click($id('tool_ungroup'), this.clickGroup.bind(this))
     $click($id('tool_bold'), this.clickBold.bind(this))
     $click($id('tool_italic'), this.clickItalic.bind(this))
-    $click($id('tool_text_decoration_underline'), () => this.clickTextDecoration.bind(this)('underline'))
-    $click($id('tool_text_decoration_linethrough'), () => this.clickTextDecoration.bind(this)('line-through'))
-    $click($id('tool_text_decoration_overline'), () => this.clickTextDecoration.bind(this)('overline'))
-    $id('tool_text_anchor').addEventListener('change', (evt) => this.clickTextAnchor.bind(this)(evt))
-    $id('tool_letter_spacing').addEventListener('change', this.changeLetterSpacing.bind(this))
-    $id('tool_word_spacing').addEventListener('change', this.changeWordSpacing.bind(this))
-    $id('tool_text_length').addEventListener('change', this.changeTextLength.bind(this))
-    $id('tool_length_adjust').addEventListener('change', (evt) => this.changeLengthAdjust.bind(this)(evt))
+    $click($id('tool_text_decoration_underline'), () =>
+      this.clickTextDecoration.bind(this)('underline')
+    )
+    $click($id('tool_text_decoration_linethrough'), () =>
+      this.clickTextDecoration.bind(this)('line-through')
+    )
+    $click($id('tool_text_decoration_overline'), () =>
+      this.clickTextDecoration.bind(this)('overline')
+    )
+    $id('tool_text_anchor').addEventListener('change', evt =>
+      this.clickTextAnchor.bind(this)(evt)
+    )
+    $id('tool_letter_spacing').addEventListener(
+      'change',
+      this.changeLetterSpacing.bind(this)
+    )
+    $id('tool_word_spacing').addEventListener(
+      'change',
+      this.changeWordSpacing.bind(this)
+    )
+    $id('tool_text_length').addEventListener(
+      'change',
+      this.changeTextLength.bind(this)
+    )
+    $id('tool_length_adjust').addEventListener('change', evt =>
+      this.changeLengthAdjust.bind(this)(evt)
+    )
     $click($id('tool_unlink_use'), this.clickGroup.bind(this))
-    $id('image_url').addEventListener('change', (evt) => { this.setImageURL(evt.currentTarget.value) });
+    $id('image_url').addEventListener('change', evt => {
+      this.setImageURL(evt.currentTarget.value)
+    })
 
     // all top panel attributes
-    [
+    ;[
       'elem_id',
       'elem_class',
       'circle_cx',


Test patch:
diff --git a/cypress/e2e/unit/utilities-bbox.cy.js b/cypress/e2e/unit/utilities-bbox.cy.js
index 9e5913d87..0e181c857 100644
--- a/cypress/e2e/unit/utilities-bbox.cy.js
+++ b/cypress/e2e/unit/utilities-bbox.cy.js
@@ -5,6 +5,7 @@ import * as utilities from '../../../packages/svgcanvas/core/utilities.js'
 import * as math from '../../../packages/svgcanvas/core/math.js'
 import * as path from '../../../packages/svgcanvas/core/path.js'
 import setAssertionMethods from '../../support/assert-close.js'
+import * as units from '../../../packages/svgcanvas/core/units.js'
 
 // eslint-disable-next-line
 chai.use(setAssertionMethods)
@@ -94,6 +95,7 @@ describe('utilities bbox', function () {
     }
 
     path.init(mockSvgCanvas)
+    units.init({ getRoundDigits: () => 2 }) // mock getRoundDigits
     mockaddSVGElementsFromJsonCallCount = 0
   })
 
diff --git a/cypress/e2e/unit/utilities-performance.cy.js b/cypress/e2e/unit/utilities-performance.cy.js
index 72a3c10f4..d61292742 100644
--- a/cypress/e2e/unit/utilities-performance.cy.js
+++ b/cypress/e2e/unit/utilities-performance.cy.js
@@ -4,9 +4,11 @@ import 'pathseg'
 import { NS } from '../../../packages/svgcanvas/core/namespaces.js'
 import * as utilities from '../../../packages/svgcanvas/core/utilities.js'
 import * as math from '../../../packages/svgcanvas/core/math.js'
+import * as units from '../../../packages/svgcanvas/core/units.js'
 
 describe('utilities performance', function () {
   let currentLayer; let groupWithMatrixTransform; let textWithMatrixTransform
+  units.init({ getRoundDigits: () => 2 }) // mock getRoundDigits
   beforeEach(() => {
     document.body.textContent = ''
     const style = document.createElement('style')
diff --git a/packages/react-test/package.json b/packages/react-test/package.json
index c10274913..275a69110 100644
--- a/packages/react-test/package.json
+++ b/packages/react-test/package.json
@@ -35,6 +35,6 @@
     "react-dom": "^18.2.0"
   },
   "devDependencies": {
-    "@babel/preset-react": "^7.22.15"
+    "@babel/preset-react": "^7.23.3"
   }
 }
\ No newline at end of file