diff --git a/.gitignore b/.gitignore
index c1f2078c66ab2bfdebafe285c2e2468c54d21508..35c4e8888e2c59e60f5e977b13b02d42864bd6d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 /node_modules
 /dist
+/cache
 coverage
 .nyc_output
 /cypress/screenshots
@@ -7,3 +8,4 @@ coverage
 cypress/downloads
 .vscode
 .DS_Store
+.npm
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c158bd76fad529d7776bbfcb2a64a4041d76e0ee..98a37e7e455ce6ee64afd663f86dba8b8b9cca96 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -32,6 +32,7 @@ test:
   before_script:
     - npm ci
   script:
+    - npm run lint
     - npm run check-types
     - npm run build
     - npm test
diff --git a/.jshintrc b/.jshintrc
index 53b202cb9fa3d1b2149361ca3027de37933f0a1f..2b6f469f0ce2d3d4c5828858c035c204bf976ff9 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -1,3 +1,3 @@
 {
   "esversion": 6
-}
\ No newline at end of file
+}
diff --git a/biome.jsonc b/biome.jsonc
new file mode 100644
index 0000000000000000000000000000000000000000..19a07f8c359703c8f09ba9203c7427a726345418
--- /dev/null
+++ b/biome.jsonc
@@ -0,0 +1,51 @@
+{
+  "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
+  "vcs": {
+    "enabled": true,
+    "clientKind": "git",
+    "useIgnoreFile": true
+  },
+  "files": {
+    "ignoreUnknown": false
+  },
+  "formatter": {
+    "enabled": true,
+    "indentStyle": "space"
+  },
+  "organizeImports": {
+    "enabled": true
+  },
+  "linter": {
+    "enabled": true,
+    "rules": {
+      "recommended": true,
+      "style": {
+        "noParameterAssign": "warn",
+        "noYodaExpression": "error",
+        "useExplicitLengthCheck": "error"
+      },
+      "complexity": {
+        "noBannedTypes": "warn",
+        "noExcessiveCognitiveComplexity": "warn",
+        "noUselessUndefinedInitialization": "warn"
+      },
+      "suspicious": {
+        "noConsoleLog": "warn",
+        "noExplicitAny": "warn",
+        "noAsyncPromiseExecutor": "warn",
+        "useAwait": "error"
+      },
+      "correctness": {
+        "noUnusedFunctionParameters": "error",
+        "noUnusedVariables": "error",
+        "useImportExtensions": "error"
+      }
+    }
+  },
+  "javascript": {
+    "formatter": {
+      "arrowParentheses": "asNeeded",
+      "quoteStyle": "single"
+    }
+  }
+}
diff --git a/cypress.config.ts b/cypress.config.ts
index 9d7bb283a1d1bf5980cbfc6d8f59e9f642c5d6e5..27d7f890dc7d7bff5e52513c5e0f8364c2b53701 100644
--- a/cypress.config.ts
+++ b/cypress.config.ts
@@ -1,15 +1,12 @@
-import { defineConfig } from 'cypress'
+import { defineConfig } from 'cypress';
 
 export default defineConfig({
   defaultCommandTimeout: 8000,
   screenshotOnRunFailure: false,
   video: false,
   e2e: {
-    specPattern: [
-      "cypress/e2e/unit/*.cy.ts",
-      "cypress/e2e/e2e/*.cy.ts"
-    ],
+    specPattern: ['cypress/e2e/unit/*.cy.ts', 'cypress/e2e/e2e/*.cy.ts'],
     baseUrl: 'http://0.0.0.0:3000',
     experimentalRunAllSpecs: true,
   },
-})
+});
diff --git a/cypress/e2e/e2e/alias.cy.ts b/cypress/e2e/e2e/alias.cy.ts
index 31796888a027a30537fba0a70c7f044c4fd9a064..0174c537f89d81c0adb115f5a50ae5c3b9b51dcb 100644
--- a/cypress/e2e/e2e/alias.cy.ts
+++ b/cypress/e2e/e2e/alias.cy.ts
@@ -1,96 +1,136 @@
-describe('alias', function() {
+describe('alias', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/alias.html')
+    cy.visit('/examples/e2e/alias.html');
   });
 
   it('display users with alias', () => {
-    cy.get('#alias-test > div').children().eq(0)
+    cy.get('#alias-test > div')
+      .children()
+      .eq(0)
       .should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld');
 
-    cy.get('#alias-test > div > solid-display > div').children().eq(0)
+    cy.get('#alias-test > div > solid-display > div')
+      .children()
+      .eq(0)
       .should('have.attr', 'name', '@id')
       .should('have.attr', 'value', '/examples/data/list/user-1.jsonld');
 
-    cy.get('#alias-test > div > solid-display > div').children().eq(1)
+    cy.get('#alias-test > div > solid-display > div')
+      .children()
+      .eq(1)
       .should('have.attr', 'name', '@id as user_id')
       .should('have.attr', 'value', '/examples/data/list/user-1.jsonld');
 
-    cy.get('#alias-test > div > solid-display > div').children().eq(2)
+    cy.get('#alias-test > div > solid-display > div')
+      .children()
+      .eq(2)
       .should('have.attr', 'name', 'username')
       .should('have.attr', 'value', 'admin');
 
-    cy.get('#alias-test > div > solid-display > div').children().eq(3)
+    cy.get('#alias-test > div > solid-display > div')
+      .children()
+      .eq(3)
       .should('have.attr', 'name', 'username as strangename')
       .should('have.attr', 'value', 'admin');
 
-    cy.get('#alias-test > div').children().eq(1)
+    cy.get('#alias-test > div')
+      .children()
+      .eq(1)
       .should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld');
 
-    cy.get('#alias-test > div').children().eq(1)
+    cy.get('#alias-test > div')
+      .children()
+      .eq(1)
       .find('div > solid-display-value:nth-child(2)')
-      .should(($element) => {
+      .should($element => {
         expect($element).to.have.attr('name', '@id as user_id');
-        expect($element).to.have.attr('value', '/examples/data/list/user-2.jsonld');
+        expect($element).to.have.attr(
+          'value',
+          '/examples/data/list/user-2.jsonld',
+        );
       });
 
-    cy.get('#alias-test > div').children().eq(1)
+    cy.get('#alias-test > div')
+      .children()
+      .eq(1)
       .find('div > solid-display-value:nth-child(4)')
-      .should(($element) => {
+      .should($element => {
         expect($element).to.have.attr('name', 'username as strangename');
         expect($element).to.have.attr('value', 'paris');
       });
 
-    cy.get('#alias-test > div').children().eq(2)
+    cy.get('#alias-test > div')
+      .children()
+      .eq(2)
       .find('div > solid-display-value:nth-child(2)')
-      .should(($element) => {
+      .should($element => {
         expect($element).to.have.attr('name', '@id as user_id');
-        expect($element).to.have.attr('value', '/examples/data/list/user-4.jsonld');
+        expect($element).to.have.attr(
+          'value',
+          '/examples/data/list/user-4.jsonld',
+        );
       });
 
-    cy.get('#alias-test > div').children().eq(2)
+    cy.get('#alias-test > div')
+      .children()
+      .eq(2)
       .find('div > solid-display-value:nth-child(4)')
-      .should(($element) => {
+      .should($element => {
         expect($element).to.have.attr('name', 'username as strangename');
         expect($element).to.have.attr('value', 'pierre');
       });
   });
 
   it('display users with alias for additional fields and sets', () => {
-    cy.get('#alias-test-2 > div').children().eq(0)
+    cy.get('#alias-test-2 > div')
+      .children()
+      .eq(0)
       .find('div > solid-display-value:nth-child(6)')
-      .should(($element) => {
+      .should($element => {
         expect($element).to.have.attr('name', 'email as ratatouille');
         expect($element).to.have.attr('value', 'test-user@example.com');
       });
 
-    cy.get('#alias-test-2 > div').children().eq(1)
+    cy.get('#alias-test-2 > div')
+      .children()
+      .eq(1)
       .find('div > solid-display-value:nth-child(6)')
-      .should(($element) => {
+      .should($element => {
         expect($element).to.have.attr('name', 'email as ratatouille');
         expect($element).to.have.attr('value', 'paris@hilton.hi');
       });
 
-    cy.get('#alias-test-2 > div').children().eq(2)
+    cy.get('#alias-test-2 > div')
+      .children()
+      .eq(2)
       .find('div > solid-set-default > solid-display-value:nth-child(2)')
-      .should(($element) => {
+      .should($element => {
         expect($element).to.have.attr('name', 'username as strangename');
         expect($element).to.have.attr('value', 'pierre');
       });
   });
 
   it('display users with alias and custom widget on aliased field', () => {
-    cy.get('#alias-test-3 > div').children().eq(0)
-      .find('div:nth-child(1) > custom-widget:nth-child(2) > div:nth-child(1) > solid-display:nth-child(1) > div:nth-child(1) > solid-display-value:nth-child(4)')
-      .should(($element) => {
+    cy.get('#alias-test-3 > div')
+      .children()
+      .eq(0)
+      .find(
+        'div:nth-child(1) > custom-widget:nth-child(2) > div:nth-child(1) > solid-display:nth-child(1) > div:nth-child(1) > solid-display-value:nth-child(4)',
+      )
+      .should($element => {
         expect($element).to.have.attr('name', 'username as strangename');
         expect($element).to.have.attr('value', 'admin');
-    });
+      });
 
-    cy.get('#alias-test-3 > div').children().eq(3)
-      .find('div:nth-child(1) > custom-widget:nth-child(2) > div:nth-child(1) > solid-display:nth-child(1) > div:nth-child(1) > solid-display-value:nth-child(4)')
-      .should(($element) => {
+    cy.get('#alias-test-3 > div')
+      .children()
+      .eq(3)
+      .find(
+        'div:nth-child(1) > custom-widget:nth-child(2) > div:nth-child(1) > solid-display:nth-child(1) > div:nth-child(1) > solid-display-value:nth-child(4)',
+      )
+      .should($element => {
         expect($element).to.have.attr('name', 'username as strangename');
         expect($element).to.have.attr('value', 'not-member-paris');
-    });
+      });
   });
-});
\ No newline at end of file
+});
diff --git a/cypress/e2e/e2e/array-field.cy.ts b/cypress/e2e/e2e/array-field.cy.ts
index 3c901a6b7f26a82754bbb1174ebdfbd3b48a7632..5f00e773c574df5e8b766f2d65ae295315375cdb 100644
--- a/cypress/e2e/e2e/array-field.cy.ts
+++ b/cypress/e2e/e2e/array-field.cy.ts
@@ -1,45 +1,85 @@
-describe('array-field', function() {
+describe('array-field', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/array-field.html')
+    cy.visit('/examples/e2e/array-field.html');
   });
 
   it('array-[field]', () => {
     // data-src in solid-display pointed on user-*.jsonld
-    cy.get('#display-members > div').children().eq(0)
+    cy.get('#display-members > div')
+      .children()
+      .eq(0)
       .should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld');
-    cy.get('#display-members > div').children().eq(1)
-      .should('have.attr','data-src', '/examples/data/list/user-1.jsonld');
+    cy.get('#display-members > div')
+      .children()
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld');
     // Group's name not displayed
-    cy.get('#display-members > div').children().eq(0)
-      .find('solid-display-value').should('not.contain.value', 'LDP_circle_members_1');
-    cy.get('#display-members > div').children().eq(1)
-      .find('solid-display-value').should('not.contain.value', 'LDP_circle_members_1');
+    cy.get('#display-members > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('not.contain.value', 'LDP_circle_members_1');
+    cy.get('#display-members > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('not.contain.value', 'LDP_circle_members_1');
     // User's name displayed
-    cy.get('#display-members > div').children().eq(0)
-      .find('solid-display-value').should('have.attr', 'value', 'Benoit Alessandroni');
-    cy.get('#display-members > div').children().eq(1)
-      .find('solid-display-value').should('have.attr','value', 'Blaise Pascal');
+    cy.get('#display-members > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Benoit Alessandroni');
+    cy.get('#display-members > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Blaise Pascal');
   });
 
   it('array-field and order-asc', () => {
-    cy.get('#display-members-asc > div').children().eq(0)
-      .find('solid-display-value').should('have.attr', 'value', 'Benoit Alessandroni');
-    cy.get('#display-members-asc > div').children().eq(1)
-      .find('solid-display-value').should('have.attr','value', 'Blaise Pascal');
-    cy.get('#display-members-asc > div').children().eq(2)
-      .find('solid-display-value').should('have.attr','value', 'Eric Cantona');
-    cy.get('#display-members-asc > div').children().eq(3)
-      .find('solid-display-value').should('have.attr','value', 'Vitali Klitschko');
+    cy.get('#display-members-asc > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Benoit Alessandroni');
+    cy.get('#display-members-asc > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Blaise Pascal');
+    cy.get('#display-members-asc > div')
+      .children()
+      .eq(2)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Eric Cantona');
+    cy.get('#display-members-asc > div')
+      .children()
+      .eq(3)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Vitali Klitschko');
   });
 
   it('array-field and order-desc', () => {
-    cy.get('#display-members-desc > div').children().eq(0)
-      .find('solid-display-value').should('have.attr','value', 'Vitali Klitschko');
-    cy.get('#display-members-desc > div').children().eq(1)
-      .find('solid-display-value').should('have.attr','value', 'Eric Cantona');
-    cy.get('#display-members-desc > div').children().eq(2)
-      .find('solid-display-value').should('have.attr','value', 'Blaise Pascal');
-    cy.get('#display-members-desc > div').children().eq(3)
-      .find('solid-display-value').should('have.attr', 'value', 'Benoit Alessandroni');
+    cy.get('#display-members-desc > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Vitali Klitschko');
+    cy.get('#display-members-desc > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Eric Cantona');
+    cy.get('#display-members-desc > div')
+      .children()
+      .eq(2)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Blaise Pascal');
+    cy.get('#display-members-desc > div')
+      .children()
+      .eq(3)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Benoit Alessandroni');
   });
 });
diff --git a/cypress/e2e/e2e/auto-range.cy.ts b/cypress/e2e/e2e/auto-range.cy.ts
index daea28fe74346993a15c5636d1bcf481eac97333..c2844b2c6338d0fdf966fb4b5104de2d169c6009 100644
--- a/cypress/e2e/e2e/auto-range.cy.ts
+++ b/cypress/e2e/e2e/auto-range.cy.ts
@@ -1,104 +1,165 @@
-describe('auto-range attribute', function() {
+describe('auto-range attribute', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/auto-range.html')
-  })
+    cy.visit('/examples/e2e/auto-range.html');
+  });
 
   it('solid-form-search + simple auto-range-[field]', () => {
-    cy.get('#simple-auto-range')
-      .should('have.attr', 'range-skills');
+    cy.get('#simple-auto-range').should('have.attr', 'range-skills');
     // one auto-range-[field] => one solid-form-dropdown
-    cy.get('#simple-auto-range > form')
-      .children().should('have.length', 1);
+    cy.get('#simple-auto-range > form').children().should('have.length', 1);
     cy.get('#simple-auto-range')
       .find('select')
       .should('have.attr', 'name', 'skills')
-      .children().should('have.length', 5);
+      .children()
+      .should('have.length', 5);
     // Skills value visible once in the dropdown
-    cy.get('#simple-auto-range > form >  solid-form-dropdown > select > option').eq(1)
+    cy.get('#simple-auto-range > form >  solid-form-dropdown > select > option')
+      .eq(1)
       .should('contain', 'HTML');
-    cy.get('#simple-auto-range > form >  solid-form-dropdown > select > option').eq(2)
+    cy.get('#simple-auto-range > form >  solid-form-dropdown > select > option')
+      .eq(2)
       .should('contain', 'CSS');
-    cy.get('#simple-auto-range > form >  solid-form-dropdown > select > option').eq(3)
+    cy.get('#simple-auto-range > form >  solid-form-dropdown > select > option')
+      .eq(3)
       .should('contain', 'DevOps');
-    cy.get('#simple-auto-range > form >  solid-form-dropdown > select > option').eq(4)
+    cy.get('#simple-auto-range > form >  solid-form-dropdown > select > option')
+      .eq(4)
       .should('contain', 'Node');
 
     // Each skill visible several times
-    cy.get('#auto-range1 > div')
-      .children().should('have.length', 3)
-    cy.get('#auto-range1 > div > solid-display').eq(0)
+    cy.get('#auto-range1 > div').children().should('have.length', 3);
+    cy.get('#auto-range1 > div > solid-display')
+      .eq(0)
       .should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld')
-      .find('solid-display[solid-container]').children().children().should('have.length', 1).and('contain', 'HTML')
-    cy.get('#auto-range1 > div > solid-display').eq(1)
+      .find('solid-display[solid-container]')
+      .children()
+      .children()
+      .should('have.length', 1)
+      .and('contain', 'HTML');
+    cy.get('#auto-range1 > div > solid-display')
+      .eq(1)
       .should('have.attr', 'data-src', '/examples/data/list/user-4.jsonld')
-      .find('solid-display[solid-container]').children().children().should('have.length', 3).and('contain', 'HTML').and('contain', 'CSS').and('contain', 'DevOps')
-    cy.get('#auto-range1 > div > solid-display').eq(2)
+      .find('solid-display[solid-container]')
+      .children()
+      .children()
+      .should('have.length', 3)
+      .and('contain', 'HTML')
+      .and('contain', 'CSS')
+      .and('contain', 'DevOps');
+    cy.get('#auto-range1 > div > solid-display')
+      .eq(2)
       .should('have.attr', 'data-src', '/examples/data/list/user-5.jsonld')
-      .find('solid-display[solid-container]').children().children().should('have.length', 3).and('contain', 'HTML').and('contain', 'DevOps').and('contain', 'Node')
+      .find('solid-display[solid-container]')
+      .children()
+      .children()
+      .should('have.length', 3)
+      .and('contain', 'HTML')
+      .and('contain', 'DevOps')
+      .and('contain', 'Node');
 
     // User visible after selection
-    cy.get('#simple-auto-range')
-      .find('select').select('Node')
-    cy.get('#auto-range1 > div').children().should('have.length', 1)
-    cy.get('#auto-range1 > div > solid-display')
-      .should('have.attr', 'data-src', '/examples/data/list/user-5.jsonld')
+    cy.get('#simple-auto-range').find('select').select('Node');
+    cy.get('#auto-range1 > div').children().should('have.length', 1);
+    cy.get('#auto-range1 > div > solid-display').should(
+      'have.attr',
+      'data-src',
+      '/examples/data/list/user-5.jsonld',
+    );
   });
 
   it('solid-form-search with 2 auto-range-[field] + 2 solid-display', () => {
-    cy.get('#double-auto-range').should('have.attr', 'range-skills')
-    cy.get('#double-auto-range').should('have.attr', 'range-profile')
+    cy.get('#double-auto-range').should('have.attr', 'range-skills');
+    cy.get('#double-auto-range').should('have.attr', 'range-profile');
     // two auto-range-[field] => two solid-form-dropdown
-    cy.get('#double-auto-range > form')
-      .children().should('have.length', 2);
+    cy.get('#double-auto-range > form').children().should('have.length', 2);
     cy.get('#double-auto-range')
       .find('select[name="profile"]')
-      .children().should('have.length', 6);
+      .children()
+      .should('have.length', 6);
     cy.get('#double-auto-range')
       .find('select[name="skills"]')
-      .children().should('have.length', 6);
+      .children()
+      .should('have.length', 6);
     // Each profile value visible once in the dropdown
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option').eq(1)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option',
+    )
+      .eq(1)
       .should('contain', 'profile 1');
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option').eq(2)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option',
+    )
+      .eq(2)
       .should('contain', 'profile 2');
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option').eq(3)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option',
+    )
+      .eq(3)
       .should('contain', 'profile 3');
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option').eq(4)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option',
+    )
+      .eq(4)
       .should('contain', 'profile 4');
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option').eq(5)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="profile"] > select > option',
+    )
+      .eq(5)
       .should('contain', 'profile 5');
 
     // Each skill value visible once in the dropdown
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option').eq(1)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option',
+    )
+      .eq(1)
       .should('contain', 'CSS');
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option').eq(2)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option',
+    )
+      .eq(2)
       .should('contain', 'Javascript');
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option').eq(3)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option',
+    )
+      .eq(3)
       .should('contain', 'HTML');
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option').eq(4)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option',
+    )
+      .eq(4)
       .should('contain', 'DevOps');
-    cy.get('#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option').eq(5)
+    cy.get(
+      '#double-auto-range > form >  solid-form-dropdown[name="skills"] > select > option',
+    )
+      .eq(5)
       .should('contain', 'Node');
 
     // User(s) visible after selection
+    cy.get('#double-auto-range').find('select[name="skills"]').select('HTML');
+    cy.get('#auto-range-double > div').children().should('have.length', 1);
+    cy.get('#auto-range-double > div > solid-display').should(
+      'have.attr',
+      'data-src',
+      '/examples/data/list/user-2.jsonld',
+    );
+    cy.get('#auto-range-double2 > div').children().should('have.length', 3);
+    cy.get('#auto-range-double2 > div > solid-display')
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld');
+    cy.get('#auto-range-double2 > div > solid-display')
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/user-4.jsonld');
+    cy.get('#auto-range-double2 > div > solid-display')
+      .eq(2)
+      .should('have.attr', 'data-src', '/examples/data/list/user-5.jsonld');
+
     cy.get('#double-auto-range')
-      .find('select[name="skills"]').select('HTML')
-    cy.get('#auto-range-double > div').children().should('have.length', 1)
-    cy.get('#auto-range-double > div > solid-display')
-      .should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld')
-    cy.get('#auto-range-double2 > div').children().should('have.length', 3)
-    cy.get('#auto-range-double2 > div > solid-display').eq(0)
-      .should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld')
-    cy.get('#auto-range-double2 > div > solid-display').eq(1)
-      .should('have.attr', 'data-src', '/examples/data/list/user-4.jsonld')
-    cy.get('#auto-range-double2 > div > solid-display').eq(2)
-      .should('have.attr', 'data-src', '/examples/data/list/user-5.jsonld')
-    
-    cy.get('#double-auto-range')
-      .find('select[name="profile"]').select('profile 4')
-    cy.get('#auto-range-double > div').should('be.empty')
-    cy.get('#auto-range-double2 > div').children().should('have.length', 1)
-    cy.get('#auto-range-double2 > div > solid-display').eq(0)
-      .should('have.attr', 'data-src', '/examples/data/list/user-4.jsonld')
+      .find('select[name="profile"]')
+      .select('profile 4');
+    cy.get('#auto-range-double > div').should('be.empty');
+    cy.get('#auto-range-double2 > div').children().should('have.length', 1);
+    cy.get('#auto-range-double2 > div > solid-display')
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/user-4.jsonld');
   });
-})
\ No newline at end of file
+});
diff --git a/cypress/e2e/e2e/binded-attributes.cy.ts b/cypress/e2e/e2e/binded-attributes.cy.ts
index 1981f79f7816fc7f6f9b2cb3a0c91aabfa2fcfe7..e941166011e3d4a908e8bf32ece6c2fe31564d29 100644
--- a/cypress/e2e/e2e/binded-attributes.cy.ts
+++ b/cypress/e2e/e2e/binded-attributes.cy.ts
@@ -1,16 +1,26 @@
 // TODO: We should make tests run independently of one another
-describe('binded-attributes', { testIsolation: false }, function() {
+describe('binded-attributes', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/binded-attributes.html')
+    cy.visit('/examples/e2e/binded-attributes.html');
   });
 
   it('replace store://resource and store://container and store://user', () => {
     cy.get('#events')
-      .should('have.attr', 'value-custom-id', '/examples/data/list/events.jsonld')
+      .should(
+        'have.attr',
+        'value-custom-id',
+        '/examples/data/list/events.jsonld',
+      )
       .and('have.attr', 'value-child-date', 'store://resource.date');
 
-    cy.get('#events solid-display[data-src="/examples/data/list/event-1.jsonld"]')
-      .should('have.attr', 'value-custom-id', '/examples/data/list/events.jsonld')
+    cy.get(
+      '#events solid-display[data-src="/examples/data/list/event-1.jsonld"]',
+    )
+      .should(
+        'have.attr',
+        'value-custom-id',
+        '/examples/data/list/events.jsonld',
+      )
       .and('have.attr', 'value-child-date', '2020-07-09');
 
     cy.get('#events').contains('Workshop').click();
@@ -20,15 +30,21 @@ describe('binded-attributes', { testIsolation: false }, function() {
       .should('have.attr', 'data-src', '/examples/data/list/event-2.jsonld')
       .and('have.attr', 'value-custom-field', '2020-05-10')
       .and('have.attr', 'value-wrong-field', 'store://container.@id');
-    cy.get('#infos solid-display-value[name="custom-field"]')
-      .should('have.text', '2020-05-10');
-    cy.get('#infos solid-display-value[name="wrong-field"]')
-      .should('have.text', 'store://container.@id');
+    cy.get('#infos solid-display-value[name="custom-field"]').should(
+      'have.text',
+      '2020-05-10',
+    );
+    cy.get('#infos solid-display-value[name="wrong-field"]').should(
+      'have.text',
+      'store://container.@id',
+    );
 
     // Works in solid-table
     cy.get('#table')
-      .find('tr[data-resource="/examples/data/list/event-1.jsonld"] solid-display-value[name="temp"]')
-      .should('have.attr', 'value', '/examples/data/list/event-1.jsonld')
+      .find(
+        'tr[data-resource="/examples/data/list/event-1.jsonld"] solid-display-value[name="temp"]',
+      )
+      .should('have.attr', 'value', '/examples/data/list/event-1.jsonld');
 
     // Reset attribute
     cy.get('solid-route').contains('Events').click();
@@ -36,19 +52,25 @@ describe('binded-attributes', { testIsolation: false }, function() {
     cy.get('#infos')
       .should('have.attr', 'data-src', '/examples/data/list/event-1.jsonld')
       .and('have.attr', 'value-custom-field', '2020-07-09');
-    cy.get('#infos solid-display-value[name="custom-field"]')
-      .should('have.text', '2020-07-09');
-  })
+    cy.get('#infos solid-display-value[name="custom-field"]').should(
+      'have.text',
+      '2020-07-09',
+    );
+  });
 
   it('replace store://user', () => {
-    cy.get('#infos')
-    .should('have.attr', 'value-user', 'Paris');
-    cy.get('#infos solid-display-value[name="user"]')
-    .should('have.text', 'Paris');
-  
+    cy.get('#infos').should('have.attr', 'value-user', 'Paris');
+    cy.get('#infos solid-display-value[name="user"]').should(
+      'have.text',
+      'Paris',
+    );
+
     // Back home
     cy.get('solid-route[name=home]').click();
     cy.get('[data-view=home] solid-delete button').should('have.text', 'admin');
-    cy.get('[data-view=home] solid-form-search input[type=text]').should('have.value', 'Test');    
-  })
-})
+    cy.get('[data-view=home] solid-form-search input[type=text]').should(
+      'have.value',
+      'Test',
+    );
+  });
+});
diff --git a/cypress/e2e/e2e/default-data-context.cy.ts b/cypress/e2e/e2e/default-data-context.cy.ts
index ac2e2888f10dfe142433887e97be2d7e9cbde070..43e7e70301f55d5e8069a6e7f68bc460ea98a475 100644
--- a/cypress/e2e/e2e/default-data-context.cy.ts
+++ b/cypress/e2e/e2e/default-data-context.cy.ts
@@ -1,13 +1,11 @@
-describe('default-data-context', function() {
+describe('default-data-context', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/default-data-context.html')
+    cy.visit('/examples/e2e/default-data-context.html');
   });
 
   it('default-data-context', () => {
-    cy.get('solid-display > div').children().eq(0)
-      .contains('admin');
+    cy.get('solid-display > div').children().eq(0).contains('admin');
 
-    cy.get('solid-display > div').children().eq(1)
-      .contains('Test User');
+    cy.get('solid-display > div').children().eq(1).contains('Test User');
   });
-})
\ No newline at end of file
+});
diff --git a/cypress/e2e/e2e/event-reset-file.cy.ts b/cypress/e2e/e2e/event-reset-file.cy.ts
index dc4e01f3488c49fe9c6c2c929c1554d5d0001770..b5c6508335fce0fa1fb7181aa9305536a1e2ce97 100644
--- a/cypress/e2e/e2e/event-reset-file.cy.ts
+++ b/cypress/e2e/e2e/event-reset-file.cy.ts
@@ -1,165 +1,179 @@
-describe('event-reset-file', { testIsolation: false }, function() {
-    this.beforeAll('visit', () => {
-      cy.visit('/examples/e2e/event-reset-file.html');
-      cy.intercept('PUT', 'examples/data/list/event-1.jsonld', {}).as('put')
-      cy.intercept('PUT', 'examples/data/list/event-empty.jsonld', {}).as('put-empty')
+describe('event-reset-file', { testIsolation: false }, function () {
+  this.beforeAll('visit', () => {
+    cy.visit('/examples/e2e/event-reset-file.html');
+    cy.intercept('PUT', 'examples/data/list/event-1.jsonld', {}).as('put');
+    cy.intercept('PUT', 'examples/data/list/event-empty.jsonld', {}).as(
+      'put-empty',
+    );
+  });
+
+  it('should reset form values to initial values after submit event', () => {
+    cy.get('#form-image').within(() => {
+      cy.get('input[name="someimage"]')
+        .should(
+          'have.value',
+          'https://cdn.startinblox.com/logos/spacelinkers.png',
+        )
+        .type('New Name');
+      cy.get('input[type="submit"]').click();
+      cy.get('input[name="someimage"]').should(
+        'have.value',
+        'https://cdn.startinblox.com/logos/spacelinkers.png',
+      );
     });
-        
-    it('should reset form values to initial values after submit event', () => {
-
-        cy.get('#form-image').within(() => {
-            cy.get('input[name="someimage"]').should('have.value', 'https://cdn.startinblox.com/logos/spacelinkers.png').type('New Name');
-            cy.get('input[type="submit"]').click();
-            cy.get('input[name="someimage"]').should('have.value', 'https://cdn.startinblox.com/logos/spacelinkers.png');
-        });
-
-        cy.get('#form-1').within(() => {
-            cy.get('input[name="name"]').should('have.value', 'Coliving').type('New Name');
-            cy.get('input[type="submit"]').click();
-
-            cy.get('input[name="name"]').should('have.value', 'Coliving');
-        });
-
-        cy.get('#form-2').within(() => {
-            cy.get('input[name="name"]').as('nameInput');
-            cy.get('@nameInput').should('have.value', '');
-            cy.get('@nameInput').type('New Name');
-            cy.get('input[type="submit"]').click();
-
-            cy.get('@nameInput').should('have.value', '');
-        });
-
-        //[naked]
-        cy.get('#form-3').within(() => {
-            cy.get('input[name="name"]').as('nameInput');
-            cy.get('@nameInput').type('New Name');
-            cy.get('@nameInput').blur();
-
-            cy.get('@nameInput').should('have.value', 'Coliving');
-        });
-
-        //[naked][autosave]
-        cy.get('#form-4').within(() => {
-            cy.get('input[name="name"]').as('nameInput');
-            cy.get('@nameInput').clear();
-            cy.get('@nameInput').type('New Name');
-            cy.get('@nameInput').blur();
-            
-            cy.get('@nameInput').should('have.value', 'New Name');
-        });
-
-        cy.get('#form-5').within(() => {
-            cy.get('input[name="name"]').as('nameInput');
-            cy.get('@nameInput').type('New Name');
-        
-            cy.get('input[type="reset"]').click();
-            cy.get('@nameInput').should('have.value', 'Coliving');
-
-            cy.get('@nameInput').type('New Name');
-             cy.get('input[type="submit"]').click();
-             cy.get('@nameInput').should('have.value', 'Coliving');
-        });
-    });
-})
 
-const Event3Response1 = {
-    "@id":"http://localhost:8000/events/3/",
-    "img":"/upload/b9e5d66dda.jpg",
-    "@context":"https://cdn.startinblox.com/owl/context.jsonld"};
+    cy.get('#form-1').within(() => {
+      cy.get('input[name="name"]')
+        .should('have.value', 'Coliving')
+        .type('New Name');
+      cy.get('input[type="submit"]').click();
 
-const Event4Response1 = {
-    "@id":"http://localhost:8000/events/4/",
-    "img":"https://letsenhance.io/static/8f5e523ee6b2479e26ecc91b9c25261e/1015f/MainAfter.jpg",
-    "@context":"https://cdn.startinblox.com/owl/context.jsonld"}
+      cy.get('input[name="name"]').should('have.value', 'Coliving');
+    });
 
-const Event3Response2 = {
-    "@id":"http://localhost:8000/events/3/",
-    "img":"/new/url/image",
-    "@context":"https://cdn.startinblox.com/owl/context.jsonld"}
+    cy.get('#form-2').within(() => {
+      cy.get('input[name="name"]').as('nameInput');
+      cy.get('@nameInput').should('have.value', '');
+      cy.get('@nameInput').type('New Name');
+      cy.get('input[type="submit"]').click();
 
-const Event4Response2 = {
-    "@id":"http://localhost:8000/events/4/",
-     "img":"/new/url/image2",
-     "@context":"https://cdn.startinblox.com/owl/context.jsonld"}
+      cy.get('@nameInput').should('have.value', '');
+    });
 
+    //[naked]
+    cy.get('#form-3').within(() => {
+      cy.get('input[name="name"]').as('nameInput');
+      cy.get('@nameInput').type('New Name');
+      cy.get('@nameInput').blur();
 
-describe('event-reset-file-with-route', { testIsolation: false }, function() {
-    this.beforeAll('visit', () => {
-        cy.intercept('GET', 'http://localhost:8000/events/3/', Event3Response1);
-        cy.intercept('GET', 'http://localhost:8000/events/4/', Event4Response1);
-        cy.visit('/examples/e2e/event-reset-file-with-route.html');
+      cy.get('@nameInput').should('have.value', 'Coliving');
     });
-        
-    it('should update image source in image input in first route', () => { 
-        cy.get('solid-route[name="route-1"]').click()
-        cy.get('#form-1').within(() => {
-            cy.get('input[name="img"]').as('nameInput');
-            cy.get('@nameInput').should('have.value',"/upload/b9e5d66dda.jpg" );
-            cy.get('@nameInput').type('/new/url/image');
-
-            cy.intercept('GET', 'http://localhost:8000/events/3/', Event3Response2);
-            cy.intercept('PUT', 'http://localhost:8000/events/3/', {});
-
-            cy.get('input[type="submit"]').click();
-            cy.get('@nameInput').should('have.value',"/new/url/image" );
-        });
+
+    //[naked][autosave]
+    cy.get('#form-4').within(() => {
+      cy.get('input[name="name"]').as('nameInput');
+      cy.get('@nameInput').clear();
+      cy.get('@nameInput').type('New Name');
+      cy.get('@nameInput').blur();
+
+      cy.get('@nameInput').should('have.value', 'New Name');
     });
 
-    it('should update image source in image input in second route', () => { 
-        cy.get('solid-route[name="route-2"]').click()
-        cy.get('#form-2').within(() => {
-            cy.get('input[name="img"]').as('nameInput2');
-            cy.get('@nameInput2').should('have.value',"https://letsenhance.io/static/8f5e523ee6b2479e26ecc91b9c25261e/1015f/MainAfter.jpg" );
-            cy.get('@nameInput2').type('/new/url/image2');
+    cy.get('#form-5').within(() => {
+      cy.get('input[name="name"]').as('nameInput');
+      cy.get('@nameInput').type('New Name');
 
-            cy.intercept('GET', 'http://localhost:8000/events/4/', Event4Response2);
-            cy.intercept('PUT', 'http://localhost:8000/events/4/', {});
+      cy.get('input[type="reset"]').click();
+      cy.get('@nameInput').should('have.value', 'Coliving');
 
-            cy.get('input[type="submit"]').click();
-            cy.get('@nameInput2').should('have.value',"/new/url/image2" );
-        });
+      cy.get('@nameInput').type('New Name');
+      cy.get('input[type="submit"]').click();
+      cy.get('@nameInput').should('have.value', 'Coliving');
     });
+  });
+});
 
-    it('should keep updated values when switch between routes', () => { 
-        cy.intercept('GET', 'http://localhost:8000/events/3/', Event3Response1);
-        cy.intercept('GET', 'http://localhost:8000/events/4/',Event4Response1);
-        cy.visit('/examples/e2e/event-reset-file-with-route.html');
+const Event3Response1 = {
+  '@id': 'http://localhost:8000/events/3/',
+  img: '/upload/b9e5d66dda.jpg',
+  '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
+};
 
-        cy.get('solid-route[name="route-1"]').click()
-        cy.get('#form-1').within(() => {
-            cy.get('input[name="img"]').as('nameInput');
-            cy.get('@nameInput').should('have.value',"/upload/b9e5d66dda.jpg" );
-            cy.get('@nameInput').type('/new/url/image');
+const Event4Response1 = {
+  '@id': 'http://localhost:8000/events/4/',
+  img: 'https://letsenhance.io/static/8f5e523ee6b2479e26ecc91b9c25261e/1015f/MainAfter.jpg',
+  '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
+};
+
+const Event3Response2 = {
+  '@id': 'http://localhost:8000/events/3/',
+  img: '/new/url/image',
+  '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
+};
 
-            cy.intercept('GET', 'http://localhost:8000/events/3/', Event3Response2);
-            cy.intercept('PUT', 'http://localhost:8000/events/3/', {});
+const Event4Response2 = {
+  '@id': 'http://localhost:8000/events/4/',
+  img: '/new/url/image2',
+  '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
+};
+
+describe('event-reset-file-with-route', { testIsolation: false }, function () {
+  this.beforeAll('visit', () => {
+    cy.intercept('GET', 'http://localhost:8000/events/3/', Event3Response1);
+    cy.intercept('GET', 'http://localhost:8000/events/4/', Event4Response1);
+    cy.visit('/examples/e2e/event-reset-file-with-route.html');
+  });
+
+  it('should update image source in image input in first route', () => {
+    cy.get('solid-route[name="route-1"]').click();
+    cy.get('#form-1').within(() => {
+      cy.get('input[name="img"]').as('nameInput');
+      cy.get('@nameInput').should('have.value', '/upload/b9e5d66dda.jpg');
+      cy.get('@nameInput').type('/new/url/image');
+
+      cy.intercept('GET', 'http://localhost:8000/events/3/', Event3Response2);
+      cy.intercept('PUT', 'http://localhost:8000/events/3/', {});
+
+      cy.get('input[type="submit"]').click();
+      cy.get('@nameInput').should('have.value', '/new/url/image');
+    });
+  });
+
+  it('should update image source in image input in second route', () => {
+    cy.get('solid-route[name="route-2"]').click();
+    cy.get('#form-2').within(() => {
+      cy.get('input[name="img"]').as('nameInput2');
+      cy.get('@nameInput2').should(
+        'have.value',
+        'https://letsenhance.io/static/8f5e523ee6b2479e26ecc91b9c25261e/1015f/MainAfter.jpg',
+      );
+      cy.get('@nameInput2').type('/new/url/image2');
+
+      cy.intercept('GET', 'http://localhost:8000/events/4/', Event4Response2);
+      cy.intercept('PUT', 'http://localhost:8000/events/4/', {});
+
+      cy.get('input[type="submit"]').click();
+      cy.get('@nameInput2').should('have.value', '/new/url/image2');
+    });
+  });
 
-            cy.get('input[type="submit"]').click();
-            cy.get('@nameInput').should('have.value',"/new/url/image" );
-        });
+  it('should keep updated values when switch between routes', () => {
+    cy.intercept('GET', 'http://localhost:8000/events/3/', Event3Response1);
+    cy.intercept('GET', 'http://localhost:8000/events/4/', Event4Response1);
+    cy.visit('/examples/e2e/event-reset-file-with-route.html');
 
-        cy.get('solid-route[name="route-2"]').click()
-        cy.get('#form-2').within(() => {
-            cy.get('input[name="img"]').as('nameInput2');
-            cy.get('@nameInput2').should('have.value',"https://letsenhance.io/static/8f5e523ee6b2479e26ecc91b9c25261e/1015f/MainAfter.jpg" );
-            cy.get('@nameInput2').type('/new/url/image2');
+    cy.get('solid-route[name="route-1"]').click();
+    cy.get('#form-1').within(() => {
+      cy.get('input[name="img"]').as('nameInput');
+      cy.get('@nameInput').should('have.value', '/upload/b9e5d66dda.jpg');
+      cy.get('@nameInput').type('/new/url/image');
 
-            cy.intercept('GET', 'http://localhost:8000/events/4/', Event4Response2);
-            cy.intercept('PUT', 'http://localhost:8000/events/4/', {});
+      cy.intercept('GET', 'http://localhost:8000/events/3/', Event3Response2);
+      cy.intercept('PUT', 'http://localhost:8000/events/3/', {});
 
-            cy.get('input[type="submit"]').click();
-            cy.get('@nameInput2').should('have.value',"/new/url/image2" );
-        });
+      cy.get('input[type="submit"]').click();
+      cy.get('@nameInput').should('have.value', '/new/url/image');
+    });
 
+    cy.get('solid-route[name="route-2"]').click();
+    cy.get('#form-2').within(() => {
+      cy.get('input[name="img"]').as('nameInput2');
+      cy.get('@nameInput2').should(
+        'have.value',
+        'https://letsenhance.io/static/8f5e523ee6b2479e26ecc91b9c25261e/1015f/MainAfter.jpg',
+      );
+      cy.get('@nameInput2').type('/new/url/image2');
 
-        cy.get('solid-route[name="route-1"]').click()
-        cy.get('@nameInput').should('have.value',"/new/url/image" );
-        cy.get('solid-route[name="route-2"]').click()
-        cy.get('@nameInput2').should('have.value',"/new/url/image2" );
+      cy.intercept('GET', 'http://localhost:8000/events/4/', Event4Response2);
+      cy.intercept('PUT', 'http://localhost:8000/events/4/', {});
 
+      cy.get('input[type="submit"]').click();
+      cy.get('@nameInput2').should('have.value', '/new/url/image2');
     });
-});
-  
 
-
-  
\ No newline at end of file
+    cy.get('solid-route[name="route-1"]').click();
+    cy.get('@nameInput').should('have.value', '/new/url/image');
+    cy.get('solid-route[name="route-2"]').click();
+    cy.get('@nameInput2').should('have.value', '/new/url/image2');
+  });
+});
diff --git a/cypress/e2e/e2e/extra-context.cy.ts b/cypress/e2e/e2e/extra-context.cy.ts
index 86234b857299bded7990d1545a0782ec5206a292..c3da674672f6bbe91dd156c1390dccf4d3c34300 100644
--- a/cypress/e2e/e2e/extra-context.cy.ts
+++ b/cypress/e2e/e2e/extra-context.cy.ts
@@ -1,13 +1,11 @@
-describe('extra-context', function() {
+describe('extra-context', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/extra-context.html')
+    cy.visit('/examples/e2e/extra-context.html');
   });
 
   it('default-data-context', () => {
-    cy.get('solid-display > div').children().eq(0)
-      .contains('admin');
+    cy.get('solid-display > div').children().eq(0).contains('admin');
 
-    cy.get('solid-display > div').children().eq(1)
-      .contains('Test User');
+    cy.get('solid-display > div').children().eq(1).contains('Test User');
   });
-})
\ No newline at end of file
+});
diff --git a/cypress/e2e/e2e/federation.cy.ts b/cypress/e2e/e2e/federation.cy.ts
index 909451ce7e10e055fa9e88c04c376b60d98230c4..98cba05b2155b291ac6b0d526df47baaccdcf5e0 100644
--- a/cypress/e2e/e2e/federation.cy.ts
+++ b/cypress/e2e/e2e/federation.cy.ts
@@ -3,93 +3,141 @@ let beenCalled = false;
 describe('federation', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
     cy.visit('/examples/e2e/federation.html');
-  })
+  });
 
   this.beforeEach(() => {
-    cy.intercept('http://server.com/skills', (req) => {
+    cy.intercept('http://server.com/skills', req => {
       beenCalled = true;
       req.reply({
         body: {
-          "@context": "https://cdn.startinblox.com/owl/context.jsonld",
-          "@id": "http://server.com/skills",
-          "@type": "ldp:Container",
-          "ldp:contains": [
-            {"@id": "http://server.com/skills/1", "name": "HTML"}
-          ]
-        }
-      })
-    })
+          '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
+          '@id': 'http://server.com/skills',
+          '@type': 'ldp:Container',
+          'ldp:contains': [
+            { '@id': 'http://server.com/skills/1', name: 'HTML' },
+          ],
+        },
+      });
+    });
   });
 
   it('check children', () => {
     cy.get('#federation-1').as('federation');
-    cy.get('@federation').find('> div').children().should('have.length', 4)
-    cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-1.jsonld"]')
+    cy.get('@federation').find('> div').children().should('have.length', 4);
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-1.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-1.jsonld')
       .and('contain.text', 'Circle from server 1');
-    cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-2.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-2.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-2.jsonld')
       .and('contain.text', 'Another circle from server 1');
-    cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-3.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-3.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-3.jsonld')
       .and('contain.text', 'Circle from server 2');
-    cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-4.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-4.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-4.jsonld')
       .and('contain.text', 'Another circle from server 2');
   });
 
   it('supports nested sources', () => {
     cy.get('#federation-2').as('federation');
-    cy.get('@federation').find('> div').children().should('have.length', 6)
-    cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-1.jsonld"]')
+    cy.get('@federation').find('> div').children().should('have.length', 6);
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-1.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-1.jsonld')
       .and('contain.text', 'Circle from server 1');
-      cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-2.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-2.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-2.jsonld')
       .and('contain.text', 'Another circle from server 1');
-      cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-3.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-3.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-3.jsonld')
       .and('contain.text', 'Circle from server 2');
-      cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-4.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-4.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-4.jsonld')
       .and('contain.text', 'Another circle from server 2');
-      cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-5.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-5.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-5.jsonld')
       .and('contain.text', 'Circle from server 3');
-      cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-6.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-6.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-6.jsonld')
       .and('contain.text', 'Circle from server 4');
   });
 
-  it("can fail one source", () => {
+  it('can fail one source', () => {
     cy.intercept('GET', '/examples/data/federation/circles-server3.jsonld', {
-      statusCode: 403
-    })
+      statusCode: 403,
+    });
     cy.reload();
     cy.get('#federation-2').as('federation');
     cy.get('@federation').find('> div').children().should('have.length', 5);
-    cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-1.jsonld"]')
-    .and('contain.text', '/examples/data/federation/circles-1.jsonld')
-    .and('contain.text', 'Circle from server 1');
-    cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-2.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-1.jsonld"]',
+      )
+      .and('contain.text', '/examples/data/federation/circles-1.jsonld')
+      .and('contain.text', 'Circle from server 1');
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-2.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-2.jsonld')
       .and('contain.text', 'Another circle from server 1');
-      cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-3.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-3.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-3.jsonld')
       .and('contain.text', 'Circle from server 2');
-      cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-4.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-4.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-4.jsonld')
       .and('contain.text', 'Another circle from server 2');
-      cy.get('@federation').find('> div > solid-display[data-src="/examples/data/federation/circles-6.jsonld"]')
+    cy.get('@federation')
+      .find(
+        '> div > solid-display[data-src="/examples/data/federation/circles-6.jsonld"]',
+      )
       .should('contain.text', '/examples/data/federation/circles-6.jsonld')
       .and('contain.text', 'Circle from server 4');
-  })
+  });
 
-  it("does not fetch local federations", () => {
+  it('does not fetch local federations', () => {
     expect(beenCalled).to.be.false;
-    cy.get('#loadSkills').click()
-    cy.get('#federation-3 solid-display > div').children().should('have.length', 1).then(() => {
-      expect(beenCalled).to.be.true;
-    })
-  })
-})
+    cy.get('#loadSkills').click();
+    cy.get('#federation-3 solid-display > div')
+      .children()
+      .should('have.length', 1)
+      .then(() => {
+        expect(beenCalled).to.be.true;
+      });
+  });
+});
diff --git a/cypress/e2e/e2e/fields-string.cy.ts b/cypress/e2e/e2e/fields-string.cy.ts
index a89334193ee2a8c60724d020dbedcb38c1943c60..0b82b312a8946ba0dddeb7961a4a061199d04b1e 100644
--- a/cypress/e2e/e2e/fields-string.cy.ts
+++ b/cypress/e2e/e2e/fields-string.cy.ts
@@ -1,25 +1,19 @@
-describe('fields-string', function() {
+describe('fields-string', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/fields-string.html')
+    cy.visit('/examples/e2e/fields-string.html');
   });
 
   it('display strings', () => {
     cy.get('#list-1 > div').as('list1');
     cy.get('#list-2 > div').as('list2');
 
-    cy.get('@list1').children()
-    .should('have.length', 4);
-    cy.get('@list2').children()
-    .should('have.length', 4);
+    cy.get('@list1').children().should('have.length', 4);
+    cy.get('@list2').children().should('have.length', 4);
 
-    cy.get('@list1').find('>span').eq(0)
-    .should('have.text', 'Name: ')
-    cy.get('@list2').find('>span').eq(0)
-    .should('have.text', 'Name: ')
+    cy.get('@list1').find('>span').eq(0).should('have.text', 'Name: ');
+    cy.get('@list2').find('>span').eq(0).should('have.text', 'Name: ');
 
-    cy.get('@list1').find('>span').eq(1)
-    .should('have.text', ', description: ')
-    cy.get('@list2').find('>span').eq(1)
-    .should('have.text', ', description: ')
+    cy.get('@list1').find('>span').eq(1).should('have.text', ', description: ');
+    cy.get('@list2').find('>span').eq(1).should('have.text', ', description: ');
   });
-})
+});
diff --git a/cypress/e2e/e2e/filteredBy.cy.ts b/cypress/e2e/e2e/filteredBy.cy.ts
index 7fe8f5197750d90b8f8d6646f39c0cd192386b8b..b5790490652a28c5b1715c295d1db8ce1cff4210 100644
--- a/cypress/e2e/e2e/filteredBy.cy.ts
+++ b/cypress/e2e/e2e/filteredBy.cy.ts
@@ -1,13 +1,23 @@
-describe('simple Startin’blox e2e test', function() {
+describe('simple Startin’blox e2e test', () => {
   it('check children count', () => {
-    cy.visit('/examples/filtered.html')
-    cy.get('#filter1 input').type('ma#er') // match "mayer"
-    cy.get('#filter2 input').type('linds') // match "lindsay", "collins" & "rollins"
-    cy.get('main > div:nth-child(1) > solid-display > div > solid-display').its('length').should('eq', 1);
-    cy.get('main > div:nth-child(2) > solid-display > div > solid-display').its('length').should('eq', 1);
-    cy.get('#filter1 input').clear().type('john') // match "johnston.ashley" & "frye.johns"
-    cy.get('main > div:nth-child(1) > solid-display > div > solid-display').its('length').should('eq', 2);
-    cy.get('main > div:nth-child(2) > form input[value="filter2"]').click({force: true});
-    cy.get('main > div:nth-child(2) > solid-display > div > solid-display').its('length').should('eq', 3);
-  })
-})
+    cy.visit('/examples/filtered.html');
+    cy.get('#filter1 input').type('ma#er'); // match "mayer"
+    cy.get('#filter2 input').type('linds'); // match "lindsay", "collins" & "rollins"
+    cy.get('main > div:nth-child(1) > solid-display > div > solid-display')
+      .its('length')
+      .should('eq', 1);
+    cy.get('main > div:nth-child(2) > solid-display > div > solid-display')
+      .its('length')
+      .should('eq', 1);
+    cy.get('#filter1 input').clear().type('john'); // match "johnston.ashley" & "frye.johns"
+    cy.get('main > div:nth-child(1) > solid-display > div > solid-display')
+      .its('length')
+      .should('eq', 2);
+    cy.get('main > div:nth-child(2) > form input[value="filter2"]').click({
+      force: true,
+    });
+    cy.get('main > div:nth-child(2) > solid-display > div > solid-display')
+      .its('length')
+      .should('eq', 3);
+  });
+});
diff --git a/cypress/e2e/e2e/group-by.cy.ts b/cypress/e2e/e2e/group-by.cy.ts
index f362cbeda73c7f5508e03df9374ae30a5546520e..fa41cb6f298c43c5c2b95a16d0d2f6c3a1f779c2 100644
--- a/cypress/e2e/e2e/group-by.cy.ts
+++ b/cypress/e2e/e2e/group-by.cy.ts
@@ -1,30 +1,33 @@
-describe('group-by', function() {
+describe('group-by', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/group-by.html')
-  })
+    cy.visit('/examples/e2e/group-by.html');
+  });
 
   /**
-  * Groups resource at loading time
-  */
+   * Groups resource at loading time
+   */
   it('groups resources', () => {
     cy.get('#list-1 > div > solid-group-default') // get groups
-    .should('have.length', 3) // check number
-    .and('have.class', 'custom-group-class'); // and class
+      .should('have.length', 3) // check number
+      .and('have.class', 'custom-group-class'); // and class
     cy.get('#list-1 > div > solid-group-default:first-child > span') // check title span
       .should('have.length', 1)
       .contains('2020-07-09');
     cy.get('#list-1 > div > solid-group-default:first-child > div') // check content div
-    .should('have.length', 1)
-    .and('have.attr', 'data-content');
-    cy.get('#list-1 > div > solid-group-default:first-child > div > solid-display') // check solid-display
-    .should('have.length', 1);
-  })
+      .should('have.length', 1)
+      .and('have.attr', 'data-content');
+    cy.get(
+      '#list-1 > div > solid-group-default:first-child > div > solid-display',
+    ) // check solid-display
+      .should('have.length', 1);
+  });
 
   /**
-  * Group and pagination work together
-  */
+   * Group and pagination work together
+   */
   it('groups resources and paginate', () => {
-    cy.get('#list-2 > div').within(() => { // in list-2
+    cy.get('#list-2 > div').within(() => {
+      // in list-2
       cy.get('> solid-group-default').eq(1).as('groupRow'); // get second group
       cy.get('@groupRow').find('nav').as('navPages'); // check if nav is here
 
@@ -34,21 +37,30 @@ describe('group-by', function() {
       cy.get('@navPages').find('> span [data-id=count]').contains('2');
 
       // Test content
-      cy.get('@groupRow').find('solid-display-value[name]').contains('Workshop');
+      cy.get('@groupRow')
+        .find('solid-display-value[name]')
+        .contains('Workshop');
       cy.get('@navPages').find('[data-id=next]').click();
     });
-    cy.get('#list-2 > div > solid-group-default').eq(1).find('solid-display-value[name]').contains('Assemblée générale');
+    cy.get('#list-2 > div > solid-group-default')
+      .eq(1)
+      .find('solid-display-value[name]')
+      .contains('Assemblée générale');
   });
-  
+
   /**
-  * Group widgets
-  */
+   * Group widgets
+   */
   it('groups resources in custom widgets', () => {
     cy.get('#list-3 > div > custom-group').should('have.length', 3);
 
-    cy.get('#list-3 > div > custom-group').eq(0).find('h2')
-      .should('contain', "2020")
-    cy.get('#list-3 > div > custom-group').eq(0).find('section')
-      .should('have.attr', "data-content");
-  })
-})
+    cy.get('#list-3 > div > custom-group')
+      .eq(0)
+      .find('h2')
+      .should('contain', '2020');
+    cy.get('#list-3 > div > custom-group')
+      .eq(0)
+      .find('section')
+      .should('have.attr', 'data-content');
+  });
+});
diff --git a/cypress/e2e/e2e/helpers.cy.ts b/cypress/e2e/e2e/helpers.cy.ts
index dba41bdba17b6abd652e73f82cb92695769c8c52..ef0010687a7bf4747094954dc7f9b37809c95fbf 100644
--- a/cypress/e2e/e2e/helpers.cy.ts
+++ b/cypress/e2e/e2e/helpers.cy.ts
@@ -1,6 +1,6 @@
-import sleep from '../sleep'
+import sleep from '../sleep.ts';
 
-describe('helpers', function() {
+describe('helpers', function () {
   let helpers: typeof import('../../../src/libs/helpers');
   let win: Window;
   let doc: Document;
@@ -11,62 +11,68 @@ describe('helpers', function() {
       doc = win.document;
       ///@ts-ignore
       helpers = win.helpers;
-      doc
-        .querySelectorAll('script')
-        .forEach(script => script.remove());
+      for (const script of doc.querySelectorAll('script')) script.remove();
     });
   });
 
   describe('generalComparator Function Tests', () => {
     it('should compare two numbers correctly', () => {
-        expect(helpers.generalComparator(5, 10)).to.equal(-5);
-        expect(helpers.generalComparator(10, 5)).to.equal(5);
-        expect(helpers.generalComparator(5, 5)).to.equal(0);
+      expect(helpers.generalComparator(5, 10)).to.equal(-5);
+      expect(helpers.generalComparator(10, 5)).to.equal(5);
+      expect(helpers.generalComparator(5, 5)).to.equal(0);
     });
 
     it('should compare two strings correctly', () => {
-        expect(helpers.generalComparator('apple', 'banana')).to.be.lessThan(0);
-        expect(helpers.generalComparator('panana', 'banana')).to.be.greaterThan(0);
-        expect(helpers.generalComparator('apple', 'apple')).to.equal(0);
+      expect(helpers.generalComparator('apple', 'banana')).to.be.lessThan(0);
+      expect(helpers.generalComparator('panana', 'banana')).to.be.greaterThan(
+        0,
+      );
+      expect(helpers.generalComparator('apple', 'apple')).to.equal(0);
     });
 
     it('should compare dates correctly', () => {
-        const date1 = new Date('2024-01-01');
-        const date2 = new Date('2024-12-31');
-        expect(helpers.generalComparator(date1, date2)).to.be.lessThan(0);
-        expect(helpers.generalComparator(date2, date1)).to.be.greaterThan(0);
-        expect(helpers.generalComparator(date1, date1)).to.equal(0);
+      const date1 = new Date('2024-01-01');
+      const date2 = new Date('2024-12-31');
+      expect(helpers.generalComparator(date1, date2)).to.be.lessThan(0);
+      expect(helpers.generalComparator(date2, date1)).to.be.greaterThan(0);
+      expect(helpers.generalComparator(date1, date1)).to.equal(0);
     });
 
     it('should compare booleans correctly', () => {
-        expect(helpers.generalComparator(true, false)).to.equal(1);
-        expect(helpers.generalComparator(false, true)).to.equal(-1);
-        expect(helpers.generalComparator(true, true)).to.equal(0);
+      expect(helpers.generalComparator(true, false)).to.equal(1);
+      expect(helpers.generalComparator(false, true)).to.equal(-1);
+      expect(helpers.generalComparator(true, true)).to.equal(0);
     });
 
     it('should compare arrays by length', () => {
-        expect(helpers.generalComparator([1, 2], [1, 2, 3])).to.be.lessThan(0);
-        expect(helpers.generalComparator([1, 2, 3], [1, 2])).to.be.greaterThan(0);
-        expect(helpers.generalComparator([1, 2, 3], [4, 5, 6])).to.equal(0);
+      expect(helpers.generalComparator([1, 2], [1, 2, 3])).to.be.lessThan(0);
+      expect(helpers.generalComparator([1, 2, 3], [1, 2])).to.be.greaterThan(0);
+      expect(helpers.generalComparator([1, 2, 3], [4, 5, 6])).to.equal(0);
     });
 
     it('should compare objects by number of keys', () => {
-        expect(helpers.generalComparator({ a: 1 }, { a: 1, b: 2 })).to.be.lessThan(0);
-        expect(helpers.generalComparator({ a: 1, b: 2 }, { a: 1 })).to.be.greaterThan(0);
-        expect(helpers.generalComparator({ a: 1, b: 2 }, { x: 10, y: 20 })).to.equal(0);
+      expect(
+        helpers.generalComparator({ a: 1 }, { a: 1, b: 2 }),
+      ).to.be.lessThan(0);
+      expect(
+        helpers.generalComparator({ a: 1, b: 2 }, { a: 1 }),
+      ).to.be.greaterThan(0);
+      expect(
+        helpers.generalComparator({ a: 1, b: 2 }, { x: 10, y: 20 }),
+      ).to.equal(0);
     });
 
     it('should handle null or undefined values', () => {
-        expect(helpers.generalComparator(null, undefined)).to.equal(0);
-        expect(helpers.generalComparator(null, 1)).to.equal(-1);
-        expect(helpers.generalComparator(1, null)).to.equal(1);
+      expect(helpers.generalComparator(null, undefined)).to.equal(0);
+      expect(helpers.generalComparator(null, 1)).to.equal(-1);
+      expect(helpers.generalComparator(1, null)).to.equal(1);
     });
 
     it('should handle different orders correctly', () => {
-        expect(helpers.generalComparator(5, 10, 'asc')).to.be.lessThan(0);
-        expect(helpers.generalComparator(5, 10, 'desc')).to.be.greaterThan(0);
+      expect(helpers.generalComparator(5, 10, 'asc')).to.be.lessThan(0);
+      expect(helpers.generalComparator(5, 10, 'desc')).to.be.greaterThan(0);
     });
-});
+  });
 
   describe('importCSS', () => {
     it('add one stylesheet', () => {
@@ -96,9 +102,7 @@ describe('helpers', function() {
       const url = 'helpers.css';
       helpers.importCSS(url);
       helpers.importCSS(url);
-      cy.get('link')
-        .its('length')
-        .should('eq', 1);
+      cy.get('link').its('length').should('eq', 1);
     });
   });
 
@@ -107,12 +111,16 @@ describe('helpers', function() {
       helpers.importInlineCSS('test1', 'html {background-color: green}');
       cy.get('html').should('have.css', 'background-color', 'rgb(0, 128, 0)');
     });
-    
+
     it('avoid import stylesheet twice', () => {
       helpers.importInlineCSS('test2', 'html {background-color: green}');
       helpers.importInlineCSS('test2', 'html {background-color: red}');
       cy.get('html').should('have.css', 'background-color', 'rgb(0, 128, 0)');
-      cy.get('html').should('not.have.css', 'background-color', 'rgb(255, 0, 0)');
+      cy.get('html').should(
+        'not.have.css',
+        'background-color',
+        'rgb(255, 0, 0)',
+      );
     });
   });
 
@@ -142,24 +150,22 @@ describe('helpers', function() {
         expect(srcs).deep.eq(urls.map(url => new URL(url, doc.baseURI).href));
       });
     });
-    
+
     it('add script only once', () => {
       const url = 'script';
       helpers.importJS(url);
       helpers.importJS(url);
-      cy.get('script')
-        .its('length')
-        .should('eq', 1);
+      cy.get('script').its('length').should('eq', 1);
     });
   });
 
-  describe('defineComponent', function() {
+  describe('defineComponent', () => {
     it('define my-component', () => {
       expect(win.customElements.get('my-component')).to.be.undefined;
       helpers.defineComponent('my-component', class extends HTMLElement {});
       expect(win.customElements.get('my-component')).to.not.be.undefined;
     });
-    
+
     it('show a warning', () => {
       const spy = cy.spy((win as Window & typeof globalThis).console, 'warn');
       helpers.defineComponent('my-component', class extends HTMLElement {});
@@ -168,83 +174,96 @@ describe('helpers', function() {
     });
   });
 
-  
-  describe('asyncQuerySelector', function () {
+  describe('asyncQuerySelector', () => {
     it('select an element already in document', async () => {
-      const list = doc.querySelector('#async-qs ul')!
-      const list2 = await helpers.asyncQuerySelector('#async-qs ul')
-      expect(list2).to.equal(list)
-    })
+      const list = doc.querySelector('#async-qs ul');
+      const list2 = await helpers.asyncQuerySelector('#async-qs ul');
+      expect(list2).to.equal(list);
+    });
     it('select an element already in another element', async () => {
-      const list = doc.querySelector('#async-qs ul')!
-      const first1 = list.querySelector<HTMLLIElement>(':scope > :first-child')
+      const list = doc.querySelector('#async-qs ul') as HTMLUListElement;
+      const first1 = list.querySelector<HTMLLIElement>(':scope > :first-child');
       const first2 = await helpers.asyncQuerySelector<HTMLLIElement>(
         ':scope > :first-child',
         list,
-      )
-      expect(first2).to.equal(first1!)
-    })
+      );
+      expect(first2).to.equal(first1);
+    });
 
     it('select an element not yet in the DOM', async () => {
-      const list = doc.querySelector('#async-qs ul')!
-      const li = doc.createElement('li')
-      li.classList.add('added')
-      setTimeout(() => list.append(li))
-      const added1 = list.querySelector(':scope > .added')
-      expect(added1).to.be.null
-      const added2 = await helpers.asyncQuerySelector(':scope > .added', list)
-      const added3 = list.querySelector(':scope > .added')
-      expect(added2).to.equal(added3!)
-    })
+      const list = doc.querySelector('#async-qs ul') as HTMLUListElement;
+      const li = doc.createElement('li');
+      li.classList.add('added');
+      setTimeout(() => list.append(li));
+      const added1 = list.querySelector(':scope > .added');
+      expect(added1).to.be.null;
+      const added2 = await helpers.asyncQuerySelector(':scope > .added', list);
+      const added3 = list.querySelector(':scope > .added');
+      expect(added2).to.equal(added3);
+    });
 
     it('select an element not yet matching selector', async () => {
-      const list = doc.querySelector('#async-qs ul')!
-      const li = doc.createElement('li')
-      list.append(li)
-      setTimeout(() => li.classList.add('classed'))
-      const classed1 = list.querySelector(':scope > .classed')
-      expect(classed1).to.be.null
-      const classed2 = await helpers.asyncQuerySelector(':scope > .classed', list)
-      const classed3 = list.querySelector(':scope > .classed')
-      expect(classed2).to.equal(classed3!)
-    })
+      const list = doc.querySelector('#async-qs ul') as HTMLUListElement;
+      const li = doc.createElement('li');
+      list.append(li);
+      setTimeout(() => li.classList.add('classed'));
+      const classed1 = list.querySelector(':scope > .classed');
+      expect(classed1).to.be.null;
+      const classed2 = await helpers.asyncQuerySelector(
+        ':scope > .classed',
+        list,
+      );
+      const classed3 = list.querySelector(':scope > .classed');
+      expect(classed2).to.equal(classed3);
+    });
     it('select an element generated by a solid-display', () => {
       cy.get('#async-qs').then(async div => {
-        const sd = div.append(/* html */ `<solid-display data-src="/examples/data/list/event-1.jsonld"
+        const sd =
+          div.append(/* html */ `<solid-display data-src="/examples/data/list/event-1.jsonld"
           fields="event, name, date"
           widget-date="solid-display-value-date"
-        >`)[0]
-        const sdv = await helpers.asyncQuerySelector('solid-display-value-date', sd)
-        expect(sdv).has.nested.property('component.name', 'date')
-      })
-    })
-  })
+        >`)[0];
+        const sdv = await helpers.asyncQuerySelector(
+          'solid-display-value-date',
+          sd,
+        );
+        expect(sdv).has.nested.property('component.name', 'date');
+      });
+    });
+  });
 
   describe('asyncQuerySelectorAll', () => {
-    const items: Element[] = []
+    const items: Element[] = [];
     it('select currents and futures elements in DOM', async () => {
-      const list = doc.querySelector('#async-qs ol')!
-      ;(async () => {
-        for await (const li of helpers.asyncQuerySelectorAll('li', list)) items.push(li)
-      })()
-      await sleep()
-      expect(items).to.have.length(2)
+      const list = doc.querySelector('#async-qs ol');
+      if (!list) throw new Error('no `#async-qs ol`');
+      (async () => {
+        for await (const li of helpers.asyncQuerySelectorAll('li', list))
+          items.push(li);
+      })();
+      await sleep();
+      expect(items).to.have.length(2);
       for (let index = 0; index < 3; index++)
-        list.append(doc.createElement('li'))
-      await sleep()
-      expect(items).to.have.length(5)
-    })
+        list.append(doc.createElement('li'));
+      await sleep();
+      expect(items).to.have.length(5);
+    });
 
     it('select elements generated by a solid-display', () => {
       cy.get('#async-qs').then(async div => {
-        const sd = div.append(/* html */ `<solid-display data-src="/examples/data/list/users.jsonld">`)[0]
-        let limit = 20
-        for await (const sdv of helpers.asyncQuerySelectorAll<HTMLElement>('solid-display-value', sd)) {
-          if (limit-- <= 0) break
-          expect(sdv).has.nested.property('component.name')
-          sdv.style.background = '#9f9'
+        const sd = div.append(
+          /* html */ `<solid-display data-src="/examples/data/list/users.jsonld">`,
+        )[0];
+        let limit = 20;
+        for await (const sdv of helpers.asyncQuerySelectorAll<HTMLElement>(
+          'solid-display-value',
+          sd,
+        )) {
+          if (limit-- <= 0) break;
+          expect(sdv).has.nested.property('component.name');
+          sdv.style.background = '#9f9';
         }
-      })
-    })
-  })
+      });
+    });
+  });
 });
diff --git a/cypress/e2e/e2e/navigate-active.cy.ts b/cypress/e2e/e2e/navigate-active.cy.ts
index 477b3d0a9bcd3bd1deb0cce9efedf0b671c4a9e2..a57be6a0903da39d5dd1ce0b9425532e8fad026c 100644
--- a/cypress/e2e/e2e/navigate-active.cy.ts
+++ b/cypress/e2e/e2e/navigate-active.cy.ts
@@ -1,29 +1,53 @@
 // TODO: We should make tests run independently of one another
 describe('uses active on navigate', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/active-navigate.html').as("loadPage")
+    cy.visit('/examples/e2e/active-navigate.html').as('loadPage');
   });
 
   it('set active by default | unset active on leaveRoute | set active on enterRoute', () => {
-    cy.get('solid-display[data-src="/examples/data/list/user-2.jsonld"]').should('exist').and('have.attr', 'active');
-    cy.get('solid-display[data-src="/examples/data/list/user-1.jsonld"]').should('exist').and('not.have.attr', 'active');
-    cy.get('solid-display[data-src="/examples/data/list/user-3.jsonld"]').should('exist').and('not.have.attr', 'active');
-    cy.get('solid-display[data-src="/examples/data/list/user-4.jsonld"]').should('exist').and('not.have.attr', 'active');
+    cy.get('solid-display[data-src="/examples/data/list/user-2.jsonld"]')
+      .should('exist')
+      .and('have.attr', 'active');
+    cy.get('solid-display[data-src="/examples/data/list/user-1.jsonld"]')
+      .should('exist')
+      .and('not.have.attr', 'active');
+    cy.get('solid-display[data-src="/examples/data/list/user-3.jsonld"]')
+      .should('exist')
+      .and('not.have.attr', 'active');
+    cy.get('solid-display[data-src="/examples/data/list/user-4.jsonld"]')
+      .should('exist')
+      .and('not.have.attr', 'active');
   });
 
-  it("unset active on leaveRoute", () => {
+  it('unset active on leaveRoute', () => {
     cy.get('#leave-route').click();
-    cy.get('solid-display[data-src="/examples/data/list/user-1.jsonld"]').should('not.have.attr', 'active');
-    cy.get('solid-display[data-src="/examples/data/list/user-2.jsonld"]').should('not.have.attr', 'active');
-    cy.get('solid-display[data-src="/examples/data/list/user-3.jsonld"]').should('not.have.attr', 'active');
-    cy.get('solid-display[data-src="/examples/data/list/user-4.jsonld"]').should('not.have.attr', 'active');
-  })
+    cy.get(
+      'solid-display[data-src="/examples/data/list/user-1.jsonld"]',
+    ).should('not.have.attr', 'active');
+    cy.get(
+      'solid-display[data-src="/examples/data/list/user-2.jsonld"]',
+    ).should('not.have.attr', 'active');
+    cy.get(
+      'solid-display[data-src="/examples/data/list/user-3.jsonld"]',
+    ).should('not.have.attr', 'active');
+    cy.get(
+      'solid-display[data-src="/examples/data/list/user-4.jsonld"]',
+    ).should('not.have.attr', 'active');
+  });
 
-  it("set active on enterRoute", () => {
+  it('set active on enterRoute', () => {
     cy.get('#enter-route').click();
-    cy.get('solid-display[data-src="/examples/data/list/user-1.jsonld"]').should('have.attr', 'active');
-    cy.get('solid-display[data-src="/examples/data/list/user-2.jsonld"]').should('not.have.attr', 'active');
-    cy.get('solid-display[data-src="/examples/data/list/user-3.jsonld"]').should('not.have.attr', 'active');
-    cy.get('solid-display[data-src="/examples/data/list/user-4.jsonld"]').should('not.have.attr', 'active');
-  })
-})
+    cy.get(
+      'solid-display[data-src="/examples/data/list/user-1.jsonld"]',
+    ).should('have.attr', 'active');
+    cy.get(
+      'solid-display[data-src="/examples/data/list/user-2.jsonld"]',
+    ).should('not.have.attr', 'active');
+    cy.get(
+      'solid-display[data-src="/examples/data/list/user-3.jsonld"]',
+    ).should('not.have.attr', 'active');
+    cy.get(
+      'solid-display[data-src="/examples/data/list/user-4.jsonld"]',
+    ).should('not.have.attr', 'active');
+  });
+});
diff --git a/cypress/e2e/e2e/nested-field.cy.ts b/cypress/e2e/e2e/nested-field.cy.ts
index 1261f17ae345c31844ce8e16fb7a3f0951e46aaf..2dd49149971e5b1d3b2af54ee0df7ae2f51deee5 100644
--- a/cypress/e2e/e2e/nested-field.cy.ts
+++ b/cypress/e2e/e2e/nested-field.cy.ts
@@ -1,43 +1,73 @@
-describe('nested-field', function() {
+describe('nested-field', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/nested-field.html')
+    cy.visit('/examples/e2e/nested-field.html');
   });
 
   it('nested-[field]', () => {
     // data-src in solid-display pointed on skill-*.jsonld
-    cy.get('#display-skills > div').children().eq(0)
+    cy.get('#display-skills > div')
+      .children()
+      .eq(0)
       .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld');
-    cy.get('#display-skills > div').children().eq(1)
-      .should('have.attr','data-src', '/examples/data/list/skill-3.jsonld');
+    cy.get('#display-skills > div')
+      .children()
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld');
     // User's name not displayed
-    cy.get('#display-skills > div').children().eq(0)
-      .find('solid-display-value').should('not.contain.value', 'Test User');
-    cy.get('#display-skills > div').children().eq(1)
-      .find('solid-display-value').should('not.contain.value', 'Test User');
+    cy.get('#display-skills > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('not.contain.value', 'Test User');
+    cy.get('#display-skills > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('not.contain.value', 'Test User');
     // Skills' name displayed
-    cy.get('#display-skills > div').children().eq(0)
-      .find('solid-display-value').should('have.attr', 'value', 'CSS');
-    cy.get('#display-skills > div').children().eq(1)
-      .find('solid-display-value').should('have.attr','value', 'Javascript');
+    cy.get('#display-skills > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'CSS');
+    cy.get('#display-skills > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Javascript');
   });
 
-
   it('nested-[field] on related object', () => {
     // data-src in solid-display pointed on skill-*.jsonld
-    cy.get('#display-job-skills > div').children().eq(0)
+    cy.get('#display-job-skills > div')
+      .children()
+      .eq(0)
       .should('have.attr', 'data-src', '/examples/data/list/skill-1.jsonld');
-    cy.get('#display-job-skills > div').children().eq(1)
-      .should('have.attr','data-src', '/examples/data/list/skill-4.jsonld');
+    cy.get('#display-job-skills > div')
+      .children()
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-4.jsonld');
     // User's name not displayed
-    cy.get('#display-job-skills > div').children().eq(0)
-      .find('solid-display-value').should('not.contain.value', 'Test User');
-    cy.get('#display-job-skills > div').children().eq(1)
-      .find('solid-display-value').should('not.contain.value', 'Test User');
+    cy.get('#display-job-skills > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('not.contain.value', 'Test User');
+    cy.get('#display-job-skills > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('not.contain.value', 'Test User');
     // Skills' name displayed
-    cy.get('#display-job-skills > div').children().eq(0)
-      .find('solid-display-value').should('have.attr', 'value', 'HTML');
-    cy.get('#display-job-skills > div').children().eq(1)
-      .find('solid-display-value').should('have.attr','value', 'DevOps');
+    cy.get('#display-job-skills > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'HTML');
+    cy.get('#display-job-skills > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'DevOps');
   });
-
 });
diff --git a/cypress/e2e/e2e/next.cy.ts b/cypress/e2e/e2e/next.cy.ts
index 576b2431c3bd2348b1133835d30e2a4d77d17d8a..c598d578ad3ced7e95bb9b9621a832a2ff2ea8c4 100644
--- a/cypress/e2e/e2e/next.cy.ts
+++ b/cypress/e2e/e2e/next.cy.ts
@@ -1,21 +1,24 @@
 // TODO: We should make tests run independently of one another
-describe('next', { testIsolation: false }, function() {
+describe('next', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/next.html')
+    cy.visit('/examples/e2e/next.html');
   });
 
   it('goes to next', () => {
     cy.get('#list-1 > div').as('list');
 
-    cy.get('@list').children()
-      .should('have.length', 8);
+    cy.get('@list').children().should('have.length', 8);
 
     // Check next in solid-display
     cy.get('@list').contains('PHP').click();
-    cy.get('#detail > div').should('be.visible').should('contain', '/examples/data/list/skill-5.jsonld')
-    cy.location().should((loc) => {
-      expect(loc.hash).to.eq('#view/@%2Fexamples%2Fdata%2Flist%2Fskill-5.jsonld@')
-    })
+    cy.get('#detail > div')
+      .should('be.visible')
+      .should('contain', '/examples/data/list/skill-5.jsonld');
+    cy.location().should(loc => {
+      expect(loc.hash).to.eq(
+        '#view/@%2Fexamples%2Fdata%2Flist%2Fskill-5.jsonld@',
+      );
+    });
   });
 
   it('uses the right id with nested components', () => {
@@ -23,18 +26,26 @@ describe('next', { testIsolation: false }, function() {
 
     // Check next in solid-display
     cy.get('@list').contains('CSS').click();
-    cy.get('#user-detail > div').should('be.visible').should('contain', '/examples/data/list/user-1.jsonld')
-    cy.location().should((loc) => {
-      expect(loc.hash).to.eq('#user/@%2Fexamples%2Fdata%2Flist%2Fuser-1.jsonld@')
-    })
+    cy.get('#user-detail > div')
+      .should('be.visible')
+      .should('contain', '/examples/data/list/user-1.jsonld');
+    cy.location().should(loc => {
+      expect(loc.hash).to.eq(
+        '#user/@%2Fexamples%2Fdata%2Flist%2Fuser-1.jsonld@',
+      );
+    });
   });
 
   // Check next mixin on solid-display with keyboard
   it('next mixin accessibility', () => {
     cy.get('body').tab().tab().type('{enter}'); //.tab() from plugin to use tab keypress
-    cy.get('#detail > div').should('be.visible').should('contain', '/examples/data/list/skill-2.jsonld')
-    cy.location().should((loc) => {
-      expect(loc.hash).to.eq('#view/@%2Fexamples%2Fdata%2Flist%2Fskill-2.jsonld@')
-    })
+    cy.get('#detail > div')
+      .should('be.visible')
+      .should('contain', '/examples/data/list/skill-2.jsonld');
+    cy.location().should(loc => {
+      expect(loc.hash).to.eq(
+        '#view/@%2Fexamples%2Fdata%2Flist%2Fskill-2.jsonld@',
+      );
+    });
   });
-})
\ No newline at end of file
+});
diff --git a/cypress/e2e/e2e/no-render.cy.ts b/cypress/e2e/e2e/no-render.cy.ts
index 8bf53b44a8c78c3731296f2b7101da90d7dd62c5..6605910e6ebaa934941979878fd8da11f2b84d9c 100644
--- a/cypress/e2e/e2e/no-render.cy.ts
+++ b/cypress/e2e/e2e/no-render.cy.ts
@@ -1,4 +1,4 @@
-describe('no-render', function() {
+describe('no-render', function () {
   let win: Window;
 
   this.beforeEach('visit', () => {
@@ -7,20 +7,22 @@ describe('no-render', function() {
       win = w;
     });
   });
-  
+
   it('blocks rendering', () => {
     cy.spy(win.sibStore, 'fetchData');
 
-    cy.get('#list').as('list')
+    cy.get('#list').as('list');
     cy.wait(500);
-    cy.get('@list').children()
-      .should('have.length', 0);
+    cy.get('@list').children().should('have.length', 0);
 
     cy.get('@list').then($el => {
       expect(win.sibStore.fetchData).to.have.callCount(0);
       $el.removeAttr('no-render');
-      cy.get('@list').find(' > div').children()
-        .should('have.length', 8).then(() => {
+      cy.get('@list')
+        .find(' > div')
+        .children()
+        .should('have.length', 8)
+        .then(() => {
           expect(win.sibStore.fetchData).to.be.called;
         });
     });
@@ -29,30 +31,30 @@ describe('no-render', function() {
   it('blocks nested rendering', () => {
     cy.spy(win.sibStore, 'fetchData');
 
-    cy.get('#nested-list').as('list')
+    cy.get('#nested-list').as('list');
     cy.wait(500);
-    cy.get('@list').children()
-      .should('have.length', 0);
+    cy.get('@list').children().should('have.length', 0);
 
     cy.get('@list').then($el => {
       expect(win.sibStore.fetchData).to.have.callCount(0);
       $el.removeAttr('no-render');
-      cy.get('@list').find(' > div').children()
-        .should('have.length', 4).then(() => {
+      cy.get('@list')
+        .find(' > div')
+        .children()
+        .should('have.length', 4)
+        .then(() => {
           expect(win.sibStore.fetchData).to.be.called;
         });
     });
   });
 
   it('blocks rendering if no data-src', () => {
-    cy.get('#form').as('form')
+    cy.get('#form').as('form');
     cy.wait(500);
-    cy.get('@form').children()
-      .should('have.length', 0);
+    cy.get('@form').children().should('have.length', 0);
 
-    cy.get('#form-search').as('form-search')
-      cy.wait(500);
-      cy.get('@form-search').children()
-        .should('have.length', 0);
+    cy.get('#form-search').as('form-search');
+    cy.wait(500);
+    cy.get('@form-search').children().should('have.length', 0);
   });
-})
\ No newline at end of file
+});
diff --git a/cypress/e2e/e2e/order-by.cy.ts b/cypress/e2e/e2e/order-by.cy.ts
index 33403a83232e14b91fb0b598881bdc96b4b49ea2..4f17cf305757c3578efafbbaea377d886f4f915c 100644
--- a/cypress/e2e/e2e/order-by.cy.ts
+++ b/cypress/e2e/e2e/order-by.cy.ts
@@ -1,92 +1,130 @@
 // TODO: We should make tests run independently of one another
-describe('order-by', { testIsolation: false }, function() {
+describe('order-by', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/order-by.html')
+    cy.visit('/examples/e2e/order-by.html');
   });
 
   /**
-  * Order-asc
-  */
+   * Order-asc
+   */
   it('order-asc', () => {
     cy.get('#list-1 > div').as('list');
 
-    cy.get('@list').children()
-    .should('have.length', 8);
+    cy.get('@list').children().should('have.length', 8);
     // Check elements order
-    cy.get('@list').find('solid-display').eq(0)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-2.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('CSS');
-    });
-
-    cy.get('@list').find('solid-display').eq(1)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-4.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-4.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('DevOps');
-    });
-
-    cy.get('@list').find('solid-display').eq(2)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-6.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-6.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Git');
-    });
-
-    cy.get('@list').find('solid-display').eq(3)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-1.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-1.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('HTML');
-    });
-
-    cy.get('@list').find('solid-display').eq(4)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-3.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Javascript');
-    });
-
-    cy.get('@list').find('solid-display').eq(5)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-8.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-8.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Node');
-    });
-
-    cy.get('@list').find('solid-display').eq(6)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-5.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-5.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('PHP');
-    });
-
-    cy.get('@list').find('solid-display').eq(7)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-7.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-7.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Python');
-    });
+    cy.get('@list')
+      .find('solid-display')
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-2.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('CSS');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-4.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-4.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('DevOps');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(2)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-6.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-6.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Git');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(3)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-1.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-1.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('HTML');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(4)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-3.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Javascript');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(5)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-8.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-8.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Node');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(6)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-5.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-5.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('PHP');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(7)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-7.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-7.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Python');
+      });
   });
 
   /**
-  * order-by-random
-  */
+   * order-by-random
+   */
   it('sorts resources by random', () => {
     cy.get('#list-2').as('list');
 
-    cy.get('@list').find('> div').children()
-    .should('have.length', 8);
-
-    cy.get('@list').find('> div > solid-display').then($div => {
-      let currentOrder = Array.from($div.map((_index, el) => el.dataset.src))
-      cy.get('#reloadList').click();
-      cy.get('@list').find('> div > solid-display').then($newDiv => {
-        let newOrder = Array.from($newDiv.map((_index, el) => el.dataset.src))
-        expect(currentOrder).to.not.include.ordered.members(newOrder);
-      })
-    });
+    cy.get('@list').find('> div').children().should('have.length', 8);
+
+    cy.get('@list')
+      .find('> div > solid-display')
+      .then($div => {
+        const currentOrder = Array.from(
+          $div.map((_index, el) => el.dataset.src),
+        );
+        cy.get('#reloadList').click();
+        cy.get('@list')
+          .find('> div > solid-display')
+          .then($newDiv => {
+            const newOrder = Array.from(
+              $newDiv.map((_index, el) => el.dataset.src),
+            );
+            expect(currentOrder).to.not.include.ordered.members(newOrder);
+          });
+      });
   });
 
   /**
@@ -95,64 +133,95 @@ describe('order-by', { testIsolation: false }, function() {
   it('order-desc', () => {
     cy.get('#list-3 > div').as('list');
 
-    cy.get('@list').children()
-    .should('have.length', 8);
+    cy.get('@list').children().should('have.length', 8);
     // Check elements order
-    cy.get('@list').find('solid-display').eq(0)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-7.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-7.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Python');
-    });
-
-    cy.get('@list').find('solid-display').eq(1)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-5.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-5.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('PHP');
-    });
-
-    cy.get('@list').find('solid-display').eq(2)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-8.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-8.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Node');
-    });
-
-    cy.get('@list').find('solid-display').eq(3)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-3.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Javascript');
-    });
-
-    cy.get('@list').find('solid-display').eq(4)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-1.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-1.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('HTML');
-    });
-
-    cy.get('@list').find('solid-display').eq(5)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-6.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-6.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Git');
-    });
-
-    cy.get('@list').find('solid-display').eq(6)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-4.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-4.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('DevOps');
-    });
-
-    cy.get('@list').find('solid-display').eq(7)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-2.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('CSS');
-    });
+    cy.get('@list')
+      .find('solid-display')
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-7.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-7.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Python');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-5.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-5.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('PHP');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(2)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-8.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-8.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Node');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(3)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-3.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Javascript');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(4)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-1.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-1.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('HTML');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(5)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-6.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-6.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Git');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(6)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-4.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-4.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('DevOps');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(7)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-2.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('CSS');
+      });
   });
 
   /**
@@ -160,64 +229,95 @@ describe('order-by', { testIsolation: false }, function() {
    */
   it('number', () => {
     cy.get('#list-4 > div').as('list');
-    cy.get('@list').children()
-    .should('have.length', 8);
+    cy.get('@list').children().should('have.length', 8);
     // Check elements order
-    cy.get('@list').find('solid-display').eq(0)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-1.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-1.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('HTML');
-    });
-
-    cy.get('@list').find('solid-display').eq(1)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-3.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Javascript');
-    });
-
-    cy.get('@list').find('solid-display').eq(2)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-2.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('CSS');
-    });
-
-    cy.get('@list').find('solid-display').eq(3)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-4.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-4.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('DevOps');
-    });
-
-    cy.get('@list').find('solid-display').eq(4)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-5.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-5.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('PHP');
-    });
-
-    cy.get('@list').find('solid-display').eq(5)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-6.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-6.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Git');
-    });
-
-    cy.get('@list').find('solid-display').eq(6)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-7.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-7.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Python');
-    });
-
-    cy.get('@list').find('solid-display').eq(7)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-8.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-8.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Node');
-    });
+    cy.get('@list')
+      .find('solid-display')
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-1.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-1.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('HTML');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-3.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Javascript');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(2)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-2.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('CSS');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(3)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-4.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-4.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('DevOps');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(4)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-5.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-5.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('PHP');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(5)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-6.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-6.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Git');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(6)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-7.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-7.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Python');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(7)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-8.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-8.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Node');
+      });
   });
 
   /**
@@ -226,64 +326,95 @@ describe('order-by', { testIsolation: false }, function() {
   it('order-by', () => {
     cy.get('#list-5 > div').as('list');
 
-    cy.get('@list').children()
-    .should('have.length', 8);
+    cy.get('@list').children().should('have.length', 8);
     // Check elements order
-    cy.get('@list').find('solid-display').eq(0)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-2.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('CSS');
-    });
-
-    cy.get('@list').find('solid-display').eq(1)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-4.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-4.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('DevOps');
-    });
-
-    cy.get('@list').find('solid-display').eq(2)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-6.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-6.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Git');
-    });
-
-    cy.get('@list').find('solid-display').eq(3)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-1.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-1.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('HTML');
-    });
-
-    cy.get('@list').find('solid-display').eq(4)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-3.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Javascript');
-    });
-
-    cy.get('@list').find('solid-display').eq(5)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-8.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-8.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Node');
-    });
-
-    cy.get('@list').find('solid-display').eq(6)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-5.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-5.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('PHP');
-    });
-
-    cy.get('@list').find('solid-display').eq(7)
-    .should('have.attr', 'data-src', '/examples/data/list/skill-7.jsonld')
-    .within(() => {
-      cy.get('solid-display-value[name="@id"]').contains('/examples/data/list/skill-7.jsonld');
-      cy.get('solid-display-value[name="name"]').contains('Python');
-    });
+    cy.get('@list')
+      .find('solid-display')
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-2.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('CSS');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-4.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-4.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('DevOps');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(2)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-6.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-6.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Git');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(3)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-1.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-1.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('HTML');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(4)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-3.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Javascript');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(5)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-8.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-8.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Node');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(6)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-5.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-5.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('PHP');
+      });
+
+    cy.get('@list')
+      .find('solid-display')
+      .eq(7)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-7.jsonld')
+      .within(() => {
+        cy.get('solid-display-value[name="@id"]').contains(
+          '/examples/data/list/skill-7.jsonld',
+        );
+        cy.get('solid-display-value[name="name"]').contains('Python');
+      });
   });
 
   /**
@@ -293,17 +424,41 @@ describe('order-by', { testIsolation: false }, function() {
     cy.get('#sorter select[name="field"]').select('username');
     cy.get('#sorter select[name="order"]').select('desc');
     cy.get('#list-6 > div').children().should('have.length', 4);
-    cy.get('#list-6 > div').children().eq(0).should('have.attr', 'data-src', '/examples/data/list/user-4.jsonld');
-    cy.get('#list-6 > div').children().eq(1).should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld');
-    cy.get('#list-6 > div').children().eq(2).should('have.attr', 'data-src', '/examples/data/list/user-3.jsonld');
-    cy.get('#list-6 > div').children().eq(3).should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld');
+    cy.get('#list-6 > div')
+      .children()
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/user-4.jsonld');
+    cy.get('#list-6 > div')
+      .children()
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld');
+    cy.get('#list-6 > div')
+      .children()
+      .eq(2)
+      .should('have.attr', 'data-src', '/examples/data/list/user-3.jsonld');
+    cy.get('#list-6 > div')
+      .children()
+      .eq(3)
+      .should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld');
 
     cy.get('#sorter select[name="field"]').select('email');
     cy.get('#sorter select[name="order"]').select('asc');
     cy.get('#list-6 > div').children().should('have.length', 4);
-    cy.get('#list-6 > div').children().eq(0).should('have.attr', 'data-src', '/examples/data/list/user-3.jsonld');
-    cy.get('#list-6 > div').children().eq(1).should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld');
-    cy.get('#list-6 > div').children().eq(2).should('have.attr', 'data-src', '/examples/data/list/user-4.jsonld');
-    cy.get('#list-6 > div').children().eq(3).should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld');
+    cy.get('#list-6 > div')
+      .children()
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/user-3.jsonld');
+    cy.get('#list-6 > div')
+      .children()
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/user-2.jsonld');
+    cy.get('#list-6 > div')
+      .children()
+      .eq(2)
+      .should('have.attr', 'data-src', '/examples/data/list/user-4.jsonld');
+    cy.get('#list-6 > div')
+      .children()
+      .eq(3)
+      .should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld');
   });
-})
+});
diff --git a/cypress/e2e/e2e/paginate-by.cy.ts b/cypress/e2e/e2e/paginate-by.cy.ts
index bd740a03d74b503d7dd824ec67b2bddf366e731b..194ab6ea2940592ee8e7aaa101c05e0aaa444452 100644
--- a/cypress/e2e/e2e/paginate-by.cy.ts
+++ b/cypress/e2e/e2e/paginate-by.cy.ts
@@ -1,37 +1,40 @@
 // TODO: We should make tests run independently of one another
-describe('paginate-by', { testIsolation: false }, function() {
+describe('paginate-by', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/paginate-by.html')
+    cy.visit('/examples/e2e/paginate-by.html');
   });
 
   /**
-  * Paginates at loading time
-  */
+   * Paginates at loading time
+   */
   it('paginates resources', () => {
-    cy.get('#list-1 > nav').as('nav')
-    .should('have.length', 1);
+    cy.get('#list-1 > nav').as('nav').should('have.length', 1);
 
     // Check buttons
-    cy.get('@nav').find('button[data-id="prev"]')
-    .should('have.length', 1)
-    .and('be.disabled');
-    cy.get('@nav').find('button[data-id="next"]')
-    .should('have.length', 1)
-    .and('not.be.disabled');
+    cy.get('@nav')
+      .find('button[data-id="prev"]')
+      .should('have.length', 1)
+      .and('be.disabled');
+    cy.get('@nav')
+      .find('button[data-id="next"]')
+      .should('have.length', 1)
+      .and('not.be.disabled');
 
     // Check page infos
-    cy.get('@nav').find('> span > span:first-child')
-    .should('have.attr', 'data-id', 'current')
-    .contains('1');
-
-    cy.get('@nav').find('> span > span:last-child')
-    .should('have.attr', 'data-id', 'count')
-    .contains('2');
+    cy.get('@nav')
+      .find('> span > span:first-child')
+      .should('have.attr', 'data-id', 'current')
+      .contains('1');
+
+    cy.get('@nav')
+      .find('> span > span:last-child')
+      .should('have.attr', 'data-id', 'count')
+      .contains('2');
   });
 
   /**
-  * Navigate between pages
-  */
+   * Navigate between pages
+   */
   it('goes to prev/next page', () => {
     cy.get('#list-1').as('list');
     cy.get('#list-1 > nav').as('nav');
@@ -50,17 +53,13 @@ describe('paginate-by', { testIsolation: false }, function() {
     cy.get('@list').contains('user-4.jsonld');
 
     // Check pager buttons
-    cy.get('@nav').find('button[data-id="prev"]')
-    .should('not.be.disabled');
-    cy.get('@nav').find('button[data-id="next"]')
-    .should('be.disabled');
+    cy.get('@nav').find('button[data-id="prev"]').should('not.be.disabled');
+    cy.get('@nav').find('button[data-id="next"]').should('be.disabled');
 
     // Check pager infos
-    cy.get('@nav').find('> span [data-id=current]')
-    .contains('2');
+    cy.get('@nav').find('> span [data-id=current]').contains('2');
 
-    cy.get('@nav').find('> span [data-id=count]')
-    .contains('2');
+    cy.get('@nav').find('> span [data-id=count]').contains('2');
 
     // Click prev
     cy.get('@nav').find('button[data-id="prev"]').click();
@@ -71,22 +70,18 @@ describe('paginate-by', { testIsolation: false }, function() {
     cy.get('@list').contains('user-4.jsonld').should('not.exist');
 
     // Check pager buttons
-    cy.get('@nav').find('button[data-id="prev"]')
-    .should('be.disabled');
-    cy.get('@nav').find('button[data-id="next"]')
-    .should('not.be.disabled');
+    cy.get('@nav').find('button[data-id="prev"]').should('be.disabled');
+    cy.get('@nav').find('button[data-id="next"]').should('not.be.disabled');
 
     // Check pager infos
-    cy.get('@nav').find('> span [data-id=current]')
-    .contains('1');
+    cy.get('@nav').find('> span [data-id=current]').contains('1');
 
-    cy.get('@nav').find('> span [data-id=count]')
-    .contains('2');
+    cy.get('@nav').find('> span [data-id=count]').contains('2');
   });
 
   /**
-  * Pagination loop
-  */
+   * Pagination loop
+   */
   it('loops pagination', () => {
     cy.get('#list-2').as('list');
     cy.get('#list-2 > nav').as('nav');
@@ -105,17 +100,13 @@ describe('paginate-by', { testIsolation: false }, function() {
     cy.get('@list').contains('user-4.jsonld');
 
     // Check pager buttons
-    cy.get('@nav').find('button[data-id="prev"]')
-    .should('not.be.disabled');
-    cy.get('@nav').find('button[data-id="next"]')
-    .should('not.be.disabled');
+    cy.get('@nav').find('button[data-id="prev"]').should('not.be.disabled');
+    cy.get('@nav').find('button[data-id="next"]').should('not.be.disabled');
 
     // Check pager infos
-    cy.get('@nav').find('> span [data-id=current]')
-    .contains('2');
+    cy.get('@nav').find('> span [data-id=current]').contains('2');
 
-    cy.get('@nav').find('> span [data-id=count]')
-    .contains('2');
+    cy.get('@nav').find('> span [data-id=count]').contains('2');
 
     // Click next again
     cy.get('@nav').find('button[data-id="next"]').click();
@@ -126,17 +117,13 @@ describe('paginate-by', { testIsolation: false }, function() {
     cy.get('@list').contains('user-4.jsonld').should('not.exist');
 
     // Check pager buttons
-    cy.get('@nav').find('button[data-id="prev"]')
-    .should('not.be.disabled');
-    cy.get('@nav').find('button[data-id="next"]')
-    .should('not.be.disabled');
+    cy.get('@nav').find('button[data-id="prev"]').should('not.be.disabled');
+    cy.get('@nav').find('button[data-id="next"]').should('not.be.disabled');
 
     // Check pager infos
-    cy.get('@nav').find('> span [data-id=current]')
-    .contains('1');
+    cy.get('@nav').find('> span [data-id=current]').contains('1');
 
-    cy.get('@nav').find('> span [data-id=count]')
-    .contains('2');
+    cy.get('@nav').find('> span [data-id=count]').contains('2');
 
     // Click previous
     cy.get('@nav').find('button[data-id="prev"]').click();
@@ -147,22 +134,18 @@ describe('paginate-by', { testIsolation: false }, function() {
     cy.get('@list').contains('user-4.jsonld');
 
     // Check pager buttons
-    cy.get('@nav').find('button[data-id="prev"]')
-    .should('not.be.disabled');
-    cy.get('@nav').find('button[data-id="next"]')
-    .should('not.be.disabled');
+    cy.get('@nav').find('button[data-id="prev"]').should('not.be.disabled');
+    cy.get('@nav').find('button[data-id="next"]').should('not.be.disabled');
 
     // Check pager infos
-    cy.get('@nav').find('> span [data-id=current]')
-    .contains('2');
+    cy.get('@nav').find('> span [data-id=current]').contains('2');
 
-    cy.get('@nav').find('> span [data-id=count]')
-    .contains('2');
+    cy.get('@nav').find('> span [data-id=count]').contains('2');
   });
 
   /**
-  * Paginate and search
-  */
+   * Paginate and search
+   */
   it('search and paginate', () => {
     cy.get('#list-3').as('list');
     cy.get('@list').find('button[data-id="next"]').click();
@@ -182,4 +165,4 @@ describe('paginate-by', { testIsolation: false }, function() {
 
     cy.get('#list-3 > nav').should('be.hidden');
   });
-})
+});
diff --git a/cypress/e2e/e2e/reactivity-e2e.cy.ts b/cypress/e2e/e2e/reactivity-e2e.cy.ts
index 089343835717fd327afbd80b0b9f5b5bc8a8c61c..b676d48d53e0443467c6e29e5d19f3052e06b5a4 100644
--- a/cypress/e2e/e2e/reactivity-e2e.cy.ts
+++ b/cypress/e2e/e2e/reactivity-e2e.cy.ts
@@ -2,231 +2,303 @@
 describe('Reactivity e2e test2', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
     cy.intercept('GET', 'https://ldp-server2.test/users/', {
-      fixture: "users-nantes.jsonld"
-    })
+      fixture: 'users-nantes.jsonld',
+    });
     cy.intercept('GET', 'https://ldp-server.test/users/', {
-      fixture: "users-paris.jsonld"
-    })
+      fixture: 'users-paris.jsonld',
+    });
     cy.intercept('GET', '**/sources/users/', {
-      fixture: "users-source.jsonld"
-    })
+      fixture: 'users-source.jsonld',
+    });
     cy.intercept('GET', '**/users/matthieu/', {
-      fixture: "users-matthieu.jsonld"
-    })
+      fixture: 'users-matthieu.jsonld',
+    });
     cy.intercept('GET', '**/users/matthieu/circles/', {
-      fixture: "users-matthieu-circles.jsonld"
-    })
+      fixture: 'users-matthieu-circles.jsonld',
+    });
     cy.intercept('GET', '**/profiles/matthieu/', {
-      fixture: "profiles-matthieu.jsonld"
-    })
+      fixture: 'profiles-matthieu.jsonld',
+    });
     cy.intercept('GET', '**/profiles/jbpasquier/', {
-      fixture: "profiles-jbpasquier.jsonld"
-    })
+      fixture: 'profiles-jbpasquier.jsonld',
+    });
     cy.intercept('GET', '**/profiles/alex/', {
-      fixture: "profiles-alex.jsonld"
-    })
+      fixture: 'profiles-alex.jsonld',
+    });
     cy.intercept('GET', '**/circles/16/', {
-      fixture: "circles-16.jsonld"
-    })
+      fixture: 'circles-16.jsonld',
+    });
     cy.intercept('GET', '**/circles/17/members/', {
-      fixture: "circles-17-members.jsonld"
-    })
+      fixture: 'circles-17-members.jsonld',
+    });
 
     cy.visit('/examples/e2e/reactivity-e2e-test.html');
-  })
+  });
 
   it('check display', () => {
     cy.intercept('GET', 'https://ldp-server2.test/users/', {
-      fixture: "users-nantes.jsonld"
-    })
+      fixture: 'users-nantes.jsonld',
+    });
     cy.intercept('GET', 'https://ldp-server.test/users/', {
-      fixture: "users-paris.jsonld" // add fixture in case everything is not loaded yet
-    })
-
-    cy.get('solid-display#user > div > solid-display-value:nth-child(1)').should('have.attr', 'name', 'first_name').should('contain', 'Matthieu');
-    cy.get('solid-display#user > div > solid-display-value:nth-child(2)').should('have.attr', 'name', 'last_name').should('contain', 'Fesselier');
-    cy.get('solid-display#user > div > solid-display-value:nth-child(3)').should('have.attr', 'name', 'username').should('contain', 'matthieu');
-    cy.get('solid-display#user > div > solid-display-value:nth-child(4)').should('have.attr', 'name', 'profile.city').should('contain', 'Rennes');
-    cy.get('solid-display#profile > div > solid-display-value:nth-child(1)').should('have.attr', 'name', 'city').should('contain', 'Rennes');
-    cy.get('solid-display#circle > div > solid-display-value:nth-child(1)').should('have.attr', 'name', 'owner.profile.city').should('contain', 'Rennes');
-    cy.get('solid-display#profile-widget > div > custom-widget').should('have.attr', 'name', 'profile');
-    cy.get('solid-display#profile-widget > div > custom-widget > div').should('contain', 'Rennes');
+      fixture: 'users-paris.jsonld', // add fixture in case everything is not loaded yet
+    });
+
+    cy.get('solid-display#user > div > solid-display-value:nth-child(1)')
+      .should('have.attr', 'name', 'first_name')
+      .should('contain', 'Matthieu');
+    cy.get('solid-display#user > div > solid-display-value:nth-child(2)')
+      .should('have.attr', 'name', 'last_name')
+      .should('contain', 'Fesselier');
+    cy.get('solid-display#user > div > solid-display-value:nth-child(3)')
+      .should('have.attr', 'name', 'username')
+      .should('contain', 'matthieu');
+    cy.get('solid-display#user > div > solid-display-value:nth-child(4)')
+      .should('have.attr', 'name', 'profile.city')
+      .should('contain', 'Rennes');
+    cy.get('solid-display#profile > div > solid-display-value:nth-child(1)')
+      .should('have.attr', 'name', 'city')
+      .should('contain', 'Rennes');
+    cy.get('solid-display#circle > div > solid-display-value:nth-child(1)')
+      .should('have.attr', 'name', 'owner.profile.city')
+      .should('contain', 'Rennes');
+    cy.get('solid-display#profile-widget > div > custom-widget').should(
+      'have.attr',
+      'name',
+      'profile',
+    );
+    cy.get('solid-display#profile-widget > div > custom-widget > div').should(
+      'contain',
+      'Rennes',
+    );
     cy.get('solid-display#federation solid-display').should('have.length', 3);
     cy.get('solid-display#circles-user solid-display').should('have.length', 1);
   });
 
   it('has reactive nested resources', () => {
-    cy.intercept("PATCH", '**/profiles/matthieu/',
-    {
+    cy.intercept('PATCH', '**/profiles/matthieu/', {
       headers: {
-        "content-type": "application/ld+json"
+        'content-type': 'application/ld+json',
       },
-    })
+    });
 
-    cy.intercept("PATCH", '**/users/matthieu/',
-    {
+    cy.intercept('PATCH', '**/users/matthieu/', {
       headers: {
-        "content-type": "application/ld+json"
+        'content-type': 'application/ld+json',
       },
-    })
-
-    cy.intercept("GET", '**/users/matthieu/', {
-      fixture: "users-matthieu.jsonld"
-    })
-    cy.intercept("GET", '**/profiles/matthieu/', {
-      fixture: "profiles-matthieu-edited.jsonld"
-    })
-    cy.intercept("GET", '**/sources/users/', {
-      fixture: "users-source.jsonld"
-    })
-    cy.intercept("GET", 'https://ldp-server.test/users/', {
-      fixture: "users-paris.jsonld"
-    })
-    cy.intercept("GET", 'https://ldp-server2.test/users/', {
-      fixture: "users-nantes.jsonld"
-    })
+    });
+
+    cy.intercept('GET', '**/users/matthieu/', {
+      fixture: 'users-matthieu.jsonld',
+    });
+    cy.intercept('GET', '**/profiles/matthieu/', {
+      fixture: 'profiles-matthieu-edited.jsonld',
+    });
+    cy.intercept('GET', '**/sources/users/', {
+      fixture: 'users-source.jsonld',
+    });
+    cy.intercept('GET', 'https://ldp-server.test/users/', {
+      fixture: 'users-paris.jsonld',
+    });
+    cy.intercept('GET', 'https://ldp-server2.test/users/', {
+      fixture: 'users-nantes.jsonld',
+    });
 
     cy.get('solid-form#profile-form input[name="city"]').clear().type('Paris');
     cy.get('solid-form#profile-form input[type=submit]').click();
 
     // Nested resource in dot field
-    cy.get('solid-display#user > div > solid-display-value[name="profile.city"]').should('contain', 'Paris');
+    cy.get(
+      'solid-display#user > div > solid-display-value[name="profile.city"]',
+    ).should('contain', 'Paris');
 
     // Nested resource in nested field
-    cy.get('solid-display#profile > div > solid-display-value[name="city"]').should('contain', 'Paris');
+    cy.get(
+      'solid-display#profile > div > solid-display-value[name="city"]',
+    ).should('contain', 'Paris');
 
     // Nested resource in custom widget
-    cy.get('solid-display#profile-widget > div > custom-widget[name="profile"] > div').should('contain', 'Paris');
+    cy.get(
+      'solid-display#profile-widget > div > custom-widget[name="profile"] > div',
+    ).should('contain', 'Paris');
 
     // Nested field in form
-    cy.intercept("GET", '**/profiles/matthieu/', {
-      fixture: "profiles-matthieu-edited-2.jsonld"
-    })
-    cy.get('solid-form#user-form-city input[name="profile.city"]').clear().type('Briouze');
+    cy.intercept('GET', '**/profiles/matthieu/', {
+      fixture: 'profiles-matthieu-edited-2.jsonld',
+    });
+    cy.get('solid-form#user-form-city input[name="profile.city"]')
+      .clear()
+      .type('Briouze');
     cy.get('solid-form#user-form-city input[type=submit]').click();
 
-    cy.get('solid-display#user > div > solid-display-value[name="profile.city"]').should('have.text', 'Briouze');
-    cy.get('solid-display#profile > div > solid-display-value[name="city"]').should('have.text', 'Briouze');
-    cy.get('solid-display#profile-widget > div > custom-widget[name="profile"] > div').should('have.text', 'Briouze');
+    cy.get(
+      'solid-display#user > div > solid-display-value[name="profile.city"]',
+    ).should('have.text', 'Briouze');
+    cy.get(
+      'solid-display#profile > div > solid-display-value[name="city"]',
+    ).should('have.text', 'Briouze');
+    cy.get(
+      'solid-display#profile-widget > div > custom-widget[name="profile"] > div',
+    ).should('have.text', 'Briouze');
 
     // Nested resource in multi dot field
     // cy.get('solid-display#circle > solid-display-value[name="owner.profile.city"]').should('contain', 'Paris'); DOES NOT WORK YET
   });
 
   it('has reactive properties', () => {
-    cy.intercept("GET", '**/users/matthieu/', {
-      fixture: "users-matthieu-edited.jsonld"
-    })
-    cy.intercept("GET", '**/sources/users/', {
-      fixture: "users-source.jsonld"
-    })
-    cy.intercept("GET", 'https://ldp-server.test/users/', {
-      fixture: "users-edited.jsonld"
-    })
-    cy.intercept("GET", 'https://ldp-server2.test/users/', {
-      fixture: "users-nantes.jsonld"
-    })
-    cy.intercept("GET", '**/users/jbpasquier/', {
-      fixture: "users-jbpasquier.jsonld"
-    })
+    cy.intercept('GET', '**/users/matthieu/', {
+      fixture: 'users-matthieu-edited.jsonld',
+    });
+    cy.intercept('GET', '**/sources/users/', {
+      fixture: 'users-source.jsonld',
+    });
+    cy.intercept('GET', 'https://ldp-server.test/users/', {
+      fixture: 'users-edited.jsonld',
+    });
+    cy.intercept('GET', 'https://ldp-server2.test/users/', {
+      fixture: 'users-nantes.jsonld',
+    });
+    cy.intercept('GET', '**/users/jbpasquier/', {
+      fixture: 'users-jbpasquier.jsonld',
+    });
     cy.intercept('GET', '**/profiles/jbpasquier/', {
-      fixture: "profiles-jbpasquier.jsonld"
-    })
-    cy.intercept("GET", '**/users/alex/', {
-      fixture: "users-alex.jsonld"
-    })
+      fixture: 'profiles-jbpasquier.jsonld',
+    });
+    cy.intercept('GET', '**/users/alex/', {
+      fixture: 'users-alex.jsonld',
+    });
     cy.intercept('GET', '**/profiles/alex/', {
-      fixture: "profiles-alex.jsonld"
-    })
+      fixture: 'profiles-alex.jsonld',
+    });
 
-    cy.intercept("PATCH", '**/users/matthieu/', {
+    cy.intercept('PATCH', '**/users/matthieu/', {
       headers: {
-        "content-type": "application/ld+json"
+        'content-type': 'application/ld+json',
       },
-    })
+    });
 
-    cy.intercept("POST", "https://ldp-server.test/users/", {
+    cy.intercept('POST', 'https://ldp-server.test/users/', {
       headers: {
-        "content-type": "application/ld+json"
+        'content-type': 'application/ld+json',
       },
-    })
+    });
 
-    cy.intercept("DELETE", "**/users/alex/", {
+    cy.intercept('DELETE', '**/users/alex/', {
       headers: {
-        "content-type": "application/ld+json"
+        'content-type': 'application/ld+json',
       },
-    })
+    });
 
     // Fill matthieu's form
-    cy.get('solid-form#user-form input[name="first_name"]').clear().type('Test');
+    cy.get('solid-form#user-form input[name="first_name"]')
+      .clear()
+      .type('Test');
     cy.get('solid-form#user-form input[name="last_name"]').clear().type('User');
     cy.get('solid-form#user-form input[name="username"]').clear().type('admin');
 
     cy.get('solid-form#user-form input[type=submit]').click();
 
     // Single solid-display
-    cy.get('solid-display#user > div > solid-display-value[name="first_name"]').should('contain', 'Test');
-    cy.get('solid-display#user > div > solid-display-value[name="last_name"]').should('contain', 'User');
-    cy.get('solid-display#user > div > solid-display-value[name="username"]').should('contain', 'admin');
+    cy.get(
+      'solid-display#user > div > solid-display-value[name="first_name"]',
+    ).should('contain', 'Test');
+    cy.get(
+      'solid-display#user > div > solid-display-value[name="last_name"]',
+    ).should('contain', 'User');
+    cy.get(
+      'solid-display#user > div > solid-display-value[name="username"]',
+    ).should('contain', 'admin');
 
     // List solid-display & range
-    const src = "https://ldp-server.test/users/matthieu/";
-    cy.get(`solid-display#users solid-display[data-src="${src}"] > div > solid-display-value[name="first_name"]`).should('contain', 'Test');
-    cy.get(`solid-display#users solid-display[data-src="${src}"] > div > solid-display-value[name="last_name"]`).should('contain', 'User');
-    cy.get(`solid-display#users solid-display[data-src="${src}"] > div > solid-display-value[name="username"]`).should('contain', 'admin');
-    cy.get(`solid-form#range option[value='{"@id": "${src}"}']`).should('contain', 'Test User');
+    const src = 'https://ldp-server.test/users/matthieu/';
+    cy.get(
+      `solid-display#users solid-display[data-src="${src}"] > div > solid-display-value[name="first_name"]`,
+    ).should('contain', 'Test');
+    cy.get(
+      `solid-display#users solid-display[data-src="${src}"] > div > solid-display-value[name="last_name"]`,
+    ).should('contain', 'User');
+    cy.get(
+      `solid-display#users solid-display[data-src="${src}"] > div > solid-display-value[name="username"]`,
+    ).should('contain', 'admin');
+    cy.get(`solid-form#range option[value='{"@id": "${src}"}']`).should(
+      'contain',
+      'Test User',
+    );
 
     // Federation
-    cy.get(`solid-display#federation solid-display[data-src="${src}"] > div > solid-display-value[name="first_name"]`).should('contain', 'Test');
-    cy.get(`solid-display#federation solid-display[data-src="${src}"] > div > solid-display-value[name="last_name"]`).should('contain', 'User');
-    cy.get(`solid-display#federation solid-display[data-src="${src}"] > div > solid-display-value[name="username"]`).should('contain', 'admin');
+    cy.get(
+      `solid-display#federation solid-display[data-src="${src}"] > div > solid-display-value[name="first_name"]`,
+    ).should('contain', 'Test');
+    cy.get(
+      `solid-display#federation solid-display[data-src="${src}"] > div > solid-display-value[name="last_name"]`,
+    ).should('contain', 'User');
+    cy.get(
+      `solid-display#federation solid-display[data-src="${src}"] > div > solid-display-value[name="username"]`,
+    ).should('contain', 'admin');
 
     // Fill new user form
-    cy.get('solid-form#users-form input[name="first_name"]').clear().type('Alex');
-    cy.get('solid-form#users-form input[name="last_name"]').clear().type('Bourlier');
+    cy.get('solid-form#users-form input[name="first_name"]')
+      .clear()
+      .type('Alex');
+    cy.get('solid-form#users-form input[name="last_name"]')
+      .clear()
+      .type('Bourlier');
     cy.get('solid-form#users-form input[name="username"]').clear().type('alex');
 
     cy.get('solid-form#users-form input[type=submit]').click();
 
     // List solid-display & range
-    const newSrc = "https://ldp-server.test/users/alex/";
-    cy.get(`solid-display#users solid-display`).should('have.length', 3);
-    cy.get(`solid-display#users solid-display[data-src="${newSrc}"] > div > solid-display-value[name="first_name"]`).should('contain', 'Alex');
-    cy.get(`solid-display#users solid-display[data-src="${newSrc}"] > div > solid-display-value[name="last_name"]`).should('contain', 'Bourlier');
-    cy.get(`solid-display#users solid-display[data-src="${newSrc}"] > div > solid-display-value[name="username"]`).should('contain', 'alex');
-    cy.get(`solid-form#range option`).should('have.length', 4);
+    const newSrc = 'https://ldp-server.test/users/alex/';
+    cy.get('solid-display#users solid-display').should('have.length', 3);
+    cy.get(
+      `solid-display#users solid-display[data-src="${newSrc}"] > div > solid-display-value[name="first_name"]`,
+    ).should('contain', 'Alex');
+    cy.get(
+      `solid-display#users solid-display[data-src="${newSrc}"] > div > solid-display-value[name="last_name"]`,
+    ).should('contain', 'Bourlier');
+    cy.get(
+      `solid-display#users solid-display[data-src="${newSrc}"] > div > solid-display-value[name="username"]`,
+    ).should('contain', 'alex');
+    cy.get('solid-form#range option').should('have.length', 4);
 
     // Federation
-    cy.get(`solid-display#federation solid-display[data-src="${newSrc}"] > div > solid-display-value[name="first_name"]`).should('contain', 'Alex');
-    cy.get(`solid-display#federation solid-display[data-src="${newSrc}"] > div > solid-display-value[name="last_name"]`).should('contain', 'Bourlier');
-    cy.get(`solid-display#federation solid-display[data-src="${newSrc}"] > div > solid-display-value[name="username"]`).should('contain', 'alex');
+    cy.get(
+      `solid-display#federation solid-display[data-src="${newSrc}"] > div > solid-display-value[name="first_name"]`,
+    ).should('contain', 'Alex');
+    cy.get(
+      `solid-display#federation solid-display[data-src="${newSrc}"] > div > solid-display-value[name="last_name"]`,
+    ).should('contain', 'Bourlier');
+    cy.get(
+      `solid-display#federation solid-display[data-src="${newSrc}"] > div > solid-display-value[name="username"]`,
+    ).should('contain', 'alex');
 
     // delete user & range
-    cy.intercept("GET", 'https://ldp-server.test/users/', {
-      fixture: "users-paris.jsonld"
-    })
+    cy.intercept('GET', 'https://ldp-server.test/users/', {
+      fixture: 'users-paris.jsonld',
+    });
     cy.get('solid-delete#delete-user > button').click();
-    cy.get(`solid-display#users solid-display`).should('have.length', 2);
-    cy.get(`solid-form#range option`).should('have.length', 3);
+    cy.get('solid-display#users solid-display').should('have.length', 2);
+    cy.get('solid-form#range option').should('have.length', 3);
     // cy.get(`solid-display#federation solid-display`).should('have.length', 3); NOT WORKING: should we loop on subscription index?
   });
 
   it('makes virtual containers reactive', () => {
-    cy.intercept("GET", '**/users/matthieu/circles/', {
-      fixture: "users-matthieu-circles-edited.jsonld"
-    })
-    cy.intercept("GET", '**/circles/17/members/', {
-      fixture: "circles-17-members.jsonld"
-    })
-
-    cy.intercept("POST", "https://ldp-server.test/circles/17/members/", {
+    cy.intercept('GET', '**/users/matthieu/circles/', {
+      fixture: 'users-matthieu-circles-edited.jsonld',
+    });
+    cy.intercept('GET', '**/circles/17/members/', {
+      fixture: 'circles-17-members.jsonld',
+    });
+
+    cy.intercept('POST', 'https://ldp-server.test/circles/17/members/', {
       headers: {
-        "content-type": "application/ld+json"
+        'content-type': 'application/ld+json',
       },
-    })
+    });
 
-    cy.get('solid-form#circles-user-form input[name="name"]').clear().type('New circle');
+    cy.get('solid-form#circles-user-form input[name="name"]')
+      .clear()
+      .type('New circle');
     cy.get('solid-form#circles-user-form input[type=submit]').click();
     cy.get('solid-display#circles-user solid-display').should('have.length', 2);
   });
-})
+});
diff --git a/cypress/e2e/e2e/search.cy.ts b/cypress/e2e/e2e/search.cy.ts
index 7a01d6bd4bd3a790bb6a5743d9da393a6d466eab..6b03230c86d7cea0d021bd0e7df0cedf6007a46f 100644
--- a/cypress/e2e/e2e/search.cy.ts
+++ b/cypress/e2e/e2e/search.cy.ts
@@ -1,61 +1,72 @@
 // TODO: We should make tests run independently of one another
-describe('solid-form-search widget', { testIsolation: false }, function() {
+describe('solid-form-search widget', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/search.html')
-  })
+    cy.visit('/examples/e2e/search.html');
+  });
 
   it('solid-form-search', () => {
     cy.get('solid-form-search#filter1')
       .find('select')
       .should('have.attr', 'name', 'username')
-      .children().and('have.length', 6)
+      .children()
+      .and('have.length', 6);
     cy.get('solid-form-search#filter1')
-      .find('option').eq(0)
+      .find('option')
+      .eq(0)
       .should('have.attr', 'value', '')
       .contains('-');
     cy.get('solid-form-search#filter1')
-      .find('option').eq(1)
+      .find('option')
+      .eq(1)
       .should('have.attr', 'value', 'admin')
       .contains('admin');
-      
+
     cy.get('solid-form-search#filter2')
       .find('select')
       .should('have.attr', 'name', 'last_name')
-      .children().and('have.length', 5);
+      .children()
+      .and('have.length', 5);
     cy.get('solid-form-search#filter2')
-      .find('option').eq(0)
+      .find('option')
+      .eq(0)
       .should('have.attr', 'value', '')
       .contains('-');
     cy.get('solid-form-search#filter2')
-      .find('option').eq(1)
+      .find('option')
+      .eq(1)
       .should('have.attr', 'value', 'a')
       .contains('User');
   });
 
   it('solid-form-search + submit-button', () => {
     cy.get('#filter3')
-      .find('input[type=submit]').as('btn')
+      .find('input[type=submit]')
+      .as('btn')
       .should('have.attr', 'value', 'update result');
     cy.get('#filter3 > form').find('div').children('input[type="submit"]');
     cy.get('#display3 > div > solid-display').should('have.length', 4);
     cy.get('#filter3 select').select('User');
     cy.get('#display3 > div > solid-display').should('have.length', 4);
-    cy.get('@btn').click()
+    cy.get('@btn').click();
     cy.get('#display3 > div > solid-display').should('have.length', 1);
   });
 
   it('solid-form-search + submit-widget', () => {
-    cy.get('solid-form-search#filter-submit-widget').find('input[type="submit"]')
+    cy.get('solid-form-search#filter-submit-widget')
+      .find('input[type="submit"]')
       .should('not.exist');
-    cy.get('solid-form-search#filter-submit-widget').find('button[type="submit"]')
+    cy.get('solid-form-search#filter-submit-widget')
+      .find('button[type="submit"]')
       .should('exist')
       .and('have.text', 'OK');
   });
 
   it('solid-form-search + class-submit-button', () => {
     cy.get('solid-form-search#filter-class-submit-button')
-      .find('div').should('have.class', 'button-class')
-      .find('input').should('exist');
+      .find('div')
+      .should('have.class', 'button-class')
+      .find('input')
+      .should('exist');
   });
 
   it('solid-form-search + start-value & end-value', () => {
@@ -63,15 +74,13 @@ describe('solid-form-search widget', { testIsolation: false }, function() {
       .find('solid-form-rangedate')
       .should('have.attr', 'start-value', '2020-06-01')
       .and('have.attr', 'end-value', '2021-01-12');
-    cy.get('#display4 > div ')
-      .children().should('have.length', 2)
+    cy.get('#display4 > div ').children().should('have.length', 2);
 
     cy.get('#filter5 > form')
       .find('solid-form-rangenumber')
       .should('have.attr', 'start-value', '2')
       .and('have.attr', 'end-value', '10');
-    cy.get('#display5 > div ')
-      .children().should('have.length', 3)
+    cy.get('#display5 > div ').children().should('have.length', 3);
   });
 
   it('solid-form-search + search-[field]', () => {
@@ -79,28 +88,30 @@ describe('solid-form-search widget', { testIsolation: false }, function() {
       .find('solid-form-label-text')
       .should('have.attr', 'name', 'global_name')
       .find('input')
-      .type('em')
+      .type('em');
 
     cy.get('#display-search-field-1 > div')
-      .children().should('have.length', 1)
+      .children()
+      .should('have.length', 1)
       .filter('solid-display[data-src="/examples/data/list/user-3.jsonld"]');
     cy.get('#display-search-field-2 > div')
-      .children().should('have.length', 1)
+      .children()
+      .should('have.length', 1)
       .filter('solid-display[data-src="/examples/data/list/event-4.jsonld"]');
   });
 
   it('solid-form-search + solid-form-hidden', () => {
-    cy.get('#display-filter-hidden > div')
-      .children().should('have.length', 2)
+    cy.get('#display-filter-hidden > div').children().should('have.length', 2);
     cy.get('#display-filter-hidden-bool > div')
-      .children().should('have.length', 2)
+      .children()
+      .should('have.length', 2);
     cy.get('#display-filter-hidden-num > div')
-      .children().should('have.length', 2)
+      .children()
+      .should('have.length', 2);
   });
 
   it('solid-form-search + fakeField', () => {
-    cy.get('#display-fake-field > div ')
-      .children().should('have.length', 4)
+    cy.get('#display-fake-field > div ').children().should('have.length', 4);
 
     cy.get('#filter-fake-field > form')
       .find('solid-form-label-text')
@@ -108,91 +119,103 @@ describe('solid-form-search widget', { testIsolation: false }, function() {
       .find('input')
       .type('em');
 
-    cy.get('#display-fake-field > div ')
-      .children().should('have.length', 0)
+    cy.get('#display-fake-field > div ').children().should('have.length', 0);
   });
 
   it('solid-form-search + solid-form-hidden', () => {
-    cy.get('#display-filter-hidden > div')
-      .children().should('have.length', 2)
+    cy.get('#display-filter-hidden > div').children().should('have.length', 2);
     cy.get('#display-filter-hidden-bool > div')
-      .children().should('have.length', 2)
+      .children()
+      .should('have.length', 2);
     cy.get('#display-filter-hidden-num > div')
-      .children().should('have.length', 2)
+      .children()
+      .should('have.length', 2);
   });
 
   it('solid-form-search + container', () => {
-    cy.get('#filter-container > div ')
-      .children().should('have.length', 4)
+    cy.get('#filter-container > div ').children().should('have.length', 4);
 
-    cy.get('#skill-search > form')
-      .find('select')
-      .select('HTML');
+    cy.get('#skill-search > form').find('select').select('HTML');
 
-    cy.get('#filter-container > div ')
-      .children().should('have.length', 2)
+    cy.get('#filter-container > div ').children().should('have.length', 2);
   });
 
   it('solid-form-search + subject=null', () => {
-    cy.get('#display-null-subject solid-display-value[name="profile.available"][value=""]').should('exist')
-    cy.get('#filter-null-subject input').type("foo")
-    cy.get('#display-null-subject solid-display-value[name="profile.available"][value=""]').should('not.exist')
+    cy.get(
+      '#display-null-subject solid-display-value[name="profile.available"][value=""]',
+    ).should('exist');
+    cy.get('#filter-null-subject input').type('foo');
+    cy.get(
+      '#display-null-subject solid-display-value[name="profile.available"][value=""]',
+    ).should('not.exist');
   });
 
   it('solid-form-search + resource', () => {
-    cy.get('#display-profile-search > div').children().should('have.length', '1')
-    cy.get('#display-profile-search > div > solid-display').should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld')
+    cy.get('#display-profile-search > div')
+      .children()
+      .should('have.length', '1');
+    cy.get('#display-profile-search > div > solid-display').should(
+      'have.attr',
+      'data-src',
+      '/examples/data/list/user-1.jsonld',
+    );
   });
 
   it('solid-form-search + number', () => {
-    cy.get('#number-search solid-form-label-text[name=username] input').type('123');
-    cy.get('#display-number-search > div').children().should('have.length', 0)
+    cy.get('#number-search solid-form-label-text[name=username] input').type(
+      '123',
+    );
+    cy.get('#display-number-search > div').children().should('have.length', 0);
   });
 
   it('solid-form-search + empty-widget', () => {
+    cy.get('#span-empty-widget > div').children().should('have.length', 4);
+    cy.get('#filter-with-empty-widget').find('input').type('rrr');
     cy.get('#span-empty-widget > div')
-      .children().should('have.length', 4);
-    cy.get('#filter-with-empty-widget')
-      .find('input').type('rrr');
-    cy.get('#span-empty-widget > div')
-      .children().should('have.length', 1)
+      .children()
+      .should('have.length', 1)
       .and('contain', 'Pierre DLC');
-    cy.get('#filter-with-empty-widget')
-      .find('input').type('r');
+    cy.get('#filter-with-empty-widget').find('input').type('r');
     cy.get('#span-empty-widget > span')
-      .children().should('have.length', 1)
+      .children()
+      .should('have.length', 1)
       .and('contain', 'No name found');
-    cy.get('#filter-with-empty-widget')
-      .find('input').type('{backspace}');
+    cy.get('#filter-with-empty-widget').find('input').type('{backspace}');
     cy.get('#span-empty-widget > div')
-      .children().should('have.length', 1)
+      .children()
+      .should('have.length', 1)
       .and('contain', 'Pierre DLC');
-  })
+  });
 
   it('solid-form-search + checkboxes', () => {
     cy.get('#enum-checkboxes-display > div')
-      .children().should('have.length', 8);
+      .children()
+      .should('have.length', 8);
 
     cy.get('#enum-checkboxes')
-      .find('input[value="HTML"]').check({ force: true });
+      .find('input[value="HTML"]')
+      .check({ force: true });
 
     cy.get('#enum-checkboxes-display > div')
-      .children().should('have.length', 1);
+      .children()
+      .should('have.length', 1);
 
     cy.get('#enum-checkboxes')
-      .find('input[value="CSS"]').check({ force: true });
+      .find('input[value="CSS"]')
+      .check({ force: true });
 
     cy.get('#enum-checkboxes-display > div')
-      .children().should('have.length', 2);
-  })
+      .children()
+      .should('have.length', 2);
+  });
 
   it('solid-form-search + debounce', () => {
-    const input = cy.get('#filter-debounce input')
-    input.type('p')
-    cy.wait(1000)
-    cy.get('#debounce>div>solid-display').should('not.have.length', 4)
-    input.type('hp')
-    cy.get('#debounce>div>solid-display').should('have.length', 1)
+    const input = cy.get('#filter-debounce input');
+    input.type('p');
+    cy.wait(1000);
+    cy.get('#debounce>div>solid-display').should('not.have.length', 4);
+    input.type('hp');
+    cy.get('#debounce>div>solid-display').should('have.length', 1);
   });
 
   it('solid-form-search + enter should not trigger default submit', () => {
diff --git a/cypress/e2e/e2e/server-pagination.cy.ts b/cypress/e2e/e2e/server-pagination.cy.ts
index 34c52c7a6b1e6e9db9f7391b6aa265732227abc2..f0dbae8f5ef2722a055cb27a8d7cf76775be8bbb 100644
--- a/cypress/e2e/e2e/server-pagination.cy.ts
+++ b/cypress/e2e/e2e/server-pagination.cy.ts
@@ -1,95 +1,112 @@
 // TODO: We should make tests run independently of one another
 describe('server-pagination', { testIsolation: false }, function () {
-    this.beforeAll('visit', () => {
-        cy.visit('/examples/e2e/server-pagination.html')
-    });
-    
-    /**
-    * Paginates from server
-    */
-    it('paginates resources', () => {
-        cy.get('#list-1 > nav').as('nav')
-        .should('have.length', 1);
-
-        // Check buttons
-        cy.get('@nav').find('button[data-id="prev"]')
-        .should('have.length', 1)
-        .and('be.disabled');
-        cy.get('@nav').find('button[data-id="next"]')
-        .should('have.length', 1)
-        .and('not.be.disabled');
-
-        // Check page infos
-        cy.get('@nav').find('> span')
-        .should('have.attr', 'data-id', 'current')
-        .contains('1');
-    });
-
-    it('goes to prev/next page', () => {
-        cy.get('#list-1').as('list');
-        cy.get('#list-1 > nav').as('nav');
-    
-        // Click next -> To investigate how to answer paginated responses in the test context (static files)
-        cy.get('@list').contains('/examples/data/list/--user-0.jsonld');
-        cy.get('@list').contains('/examples/data/list/--user-1.jsonld');
-        cy.get('@list').contains('/examples/data/list/--user-2.jsonld').should('not.exist');
-        cy.get('@list').contains('/examples/data/list/--user-3.jsonld').should('not.exist');
-        // cy.get('@list').contains('user-4.jsonld').should('not.exist');
-    
-        cy.get('@nav').find('button[data-id="next"]').click();
-        
-        // Click next -> To investigate how to answer paginated responses in the test context (static files)
-        cy.get('@list').contains('/examples/data/list/--user-1.jsonld').should('not.exist');
-        cy.get('@list').contains('/examples/data/list/--user-0.jsonld').should('not.exist');
-        cy.get('@list').contains('/examples/data/list/--user-2.jsonld');
-        cy.get('@list').contains('/examples/data/list/--user-3.jsonld');
-    
-        // Check pager buttons
-        cy.get('@nav').find('button[data-id="prev"]')
-        .should('not.be.disabled');
-
-        // Check pager infos
-        cy.get('@nav').find('> [data-id=current]')
-        .contains('2');
-
-        // Click prev
-        cy.get('@nav').find('button[data-id="prev"]').click();
-
-        // Check pager buttons
-        cy.get('@nav').find('button[data-id="prev"]')
-        .should('be.disabled');
-        cy.get('@nav').find('button[data-id="next"]')
-        .should('not.be.disabled');
-
-        // Check pager infos
-        cy.get('@nav').find('> [data-id=current]')
-        .contains('1');
-    });
+  this.beforeAll('visit', () => {
+    cy.visit('/examples/e2e/server-pagination.html');
+  });
+
+  /**
+   * Paginates from server
+   */
+  it('paginates resources', () => {
+    cy.get('#list-1 > nav').as('nav').should('have.length', 1);
+
+    // Check buttons
+    cy.get('@nav')
+      .find('button[data-id="prev"]')
+      .should('have.length', 1)
+      .and('be.disabled');
+    cy.get('@nav')
+      .find('button[data-id="next"]')
+      .should('have.length', 1)
+      .and('not.be.disabled');
+
+    // Check page infos
+    cy.get('@nav')
+      .find('> span')
+      .should('have.attr', 'data-id', 'current')
+      .contains('1');
+  });
+
+  it('goes to prev/next page', () => {
+    cy.get('#list-1').as('list');
+    cy.get('#list-1 > nav').as('nav');
+
+    // Click next -> To investigate how to answer paginated responses in the test context (static files)
+    cy.get('@list').contains('/examples/data/list/--user-0.jsonld');
+    cy.get('@list').contains('/examples/data/list/--user-1.jsonld');
+    cy.get('@list')
+      .contains('/examples/data/list/--user-2.jsonld')
+      .should('not.exist');
+    cy.get('@list')
+      .contains('/examples/data/list/--user-3.jsonld')
+      .should('not.exist');
+    // cy.get('@list').contains('user-4.jsonld').should('not.exist');
+
+    cy.get('@nav').find('button[data-id="next"]').click();
+
+    // Click next -> To investigate how to answer paginated responses in the test context (static files)
+    cy.get('@list')
+      .contains('/examples/data/list/--user-1.jsonld')
+      .should('not.exist');
+    cy.get('@list')
+      .contains('/examples/data/list/--user-0.jsonld')
+      .should('not.exist');
+    cy.get('@list').contains('/examples/data/list/--user-2.jsonld');
+    cy.get('@list').contains('/examples/data/list/--user-3.jsonld');
+
+    // Check pager buttons
+    cy.get('@nav').find('button[data-id="prev"]').should('not.be.disabled');
+
+    // Check pager infos
+    cy.get('@nav').find('> [data-id=current]').contains('2');
+
+    // Click prev
+    cy.get('@nav').find('button[data-id="prev"]').click();
+
+    // Check pager buttons
+    cy.get('@nav').find('button[data-id="prev"]').should('be.disabled');
+    cy.get('@nav').find('button[data-id="next"]').should('not.be.disabled');
+
+    // Check pager infos
+    cy.get('@nav').find('> [data-id=current]').contains('1');
+  });
 
   /**
-  * Paginate and search client-side
-  */
+   * Paginate and search client-side
+   */
   it('search and paginate', () => {
     cy.get('#list-2').as('list');
     cy.get('@list').contains('/examples/data/list/--user-2.jsonld');
     cy.get('@list').contains('/examples/data/list/--user-3.jsonld');
-    
+
     cy.get('@list').find('button[data-id="next"]').click();
 
-    cy.get('@list').contains('/examples/data/list/--user-2.jsonld').should('not.exist');
-    cy.get('@list').contains('/examples/data/list/--user-3.jsonld').should('not.exist');
+    cy.get('@list')
+      .contains('/examples/data/list/--user-2.jsonld')
+      .should('not.exist');
+    cy.get('@list')
+      .contains('/examples/data/list/--user-3.jsonld')
+      .should('not.exist');
     cy.get('@list').contains('/examples/data/list/--user-6.jsonld');
     cy.get('@list').contains('/examples/data/list/--user-7.jsonld');
-    
+
     // search
     cy.get('#username-form').find('input[name="username"]').type('henry');
 
-    cy.get('@list').contains('/examples/data/list/--user-10.jsonld').should('exist');
-    cy.get('@list').contains('/examples/data/list/--user-6.jsonld').should('not.exist');
-    cy.get('@list').contains('/examples/data/list/--user-7.jsonld').should('not.exist');
-    cy.get('@list').contains('/examples/data/list/--user-8.jsonld').should('not.exist');
+    cy.get('@list')
+      .contains('/examples/data/list/--user-10.jsonld')
+      .should('exist');
+    cy.get('@list')
+      .contains('/examples/data/list/--user-6.jsonld')
+      .should('not.exist');
+    cy.get('@list')
+      .contains('/examples/data/list/--user-7.jsonld')
+      .should('not.exist');
+    cy.get('@list')
+      .contains('/examples/data/list/--user-8.jsonld')
+      .should('not.exist');
 
     //TODO: Improvement: hide the navigation when searching
     // cy.get('#list-2 > nav').should('be.hidden');
   });
-});
\ No newline at end of file
+});
diff --git a/cypress/e2e/e2e/server-search.cy.ts b/cypress/e2e/e2e/server-search.cy.ts
index 7da1dce22093ff7235681024e90e7905e230bfe2..a0cd329302e3d9b98c1944c0195dff739d707bdb 100644
--- a/cypress/e2e/e2e/server-search.cy.ts
+++ b/cypress/e2e/e2e/server-search.cy.ts
@@ -1,47 +1,49 @@
 describe('server-search', function () {
-    this.beforeEach('visit', () => {
-        cy.visit('/examples/e2e/server-search.html');
-    })
-
-    /**
-     * Server Search only test
-     */
-    it('server search', () => {
-        // Get forms
-        cy.get("#search-form-1").as('forms');
-
-        // Check firstname field
-        cy.get("@forms").find("input[name='first_name']").as('first_name')
-        cy.get('@first_name').type('Santiago')
-
-        // Start Search
-        cy.get('@forms').find('input[type="submit"]').as("forms_submit")
-        cy.get('@forms_submit').click()
-
-        // Check result
-        cy.get('#result1')
-            .should('have.attr', 'data-src', '/mock/users.jsonld')
-            .find('div > solid-display').should('have.length', 1);
-    })
-
-    /**
-     * Server Search with Server pagination test
-     */
-    it('server-search with server-pagination', () => {
-        // Get forms
-        cy.get("#search-form-2").as('forms');
-
-        // Check firstname field
-        cy.get("@forms").find("input[name='first_name']").as('first_name')
-        cy.get('@first_name').type('an')
-
-        // Start Search
-        cy.get('@forms').find('input[type="submit"]').as("forms_submit")
-        cy.get('@forms_submit').click()
-
-        // Check result
-        cy.get('#result2')
-            .should('have.attr', 'data-src', '/mock/users.jsonld')
-            .find('div > solid-display').should('have.length', 5);
-    });
-})
\ No newline at end of file
+  this.beforeEach('visit', () => {
+    cy.visit('/examples/e2e/server-search.html');
+  });
+
+  /**
+   * Server Search only test
+   */
+  it('server search', () => {
+    // Get forms
+    cy.get('#search-form-1').as('forms');
+
+    // Check firstname field
+    cy.get('@forms').find("input[name='first_name']").as('first_name');
+    cy.get('@first_name').type('Santiago');
+
+    // Start Search
+    cy.get('@forms').find('input[type="submit"]').as('forms_submit');
+    cy.get('@forms_submit').click();
+
+    // Check result
+    cy.get('#result1')
+      .should('have.attr', 'data-src', '/mock/users.jsonld')
+      .find('div > solid-display')
+      .should('have.length', 1);
+  });
+
+  /**
+   * Server Search with Server pagination test
+   */
+  it('server-search with server-pagination', () => {
+    // Get forms
+    cy.get('#search-form-2').as('forms');
+
+    // Check firstname field
+    cy.get('@forms').find("input[name='first_name']").as('first_name');
+    cy.get('@first_name').type('an');
+
+    // Start Search
+    cy.get('@forms').find('input[type="submit"]').as('forms_submit');
+    cy.get('@forms_submit').click();
+
+    // Check result
+    cy.get('#result2')
+      .should('have.attr', 'data-src', '/mock/users.jsonld')
+      .find('div > solid-display')
+      .should('have.length', 5);
+  });
+});
diff --git a/cypress/e2e/e2e/sib-register.cy.ts b/cypress/e2e/e2e/sib-register.cy.ts
index fb785b1d7b533478a3803a471a01abd84b3e07a6..3f08ab8e5422faabadb3835a6abaa0df4f64e676 100644
--- a/cypress/e2e/e2e/sib-register.cy.ts
+++ b/cypress/e2e/e2e/sib-register.cy.ts
@@ -1,4 +1,4 @@
-describe('Component factory', function() {
+describe('Component factory', function () {
   let Sib: typeof import('../../../src/libs/Sib').Sib;
   let win: Window;
   let doc: Document;
@@ -11,9 +11,8 @@ describe('Component factory', function() {
       cnsl = (win as Window & typeof globalThis).console;
       ///@ts-ignore
       Sib = win.Sib;
-      win.document
-        .querySelectorAll('script')
-        .forEach(script => script.remove());
+      for (const script of win.document.querySelectorAll('script'))
+        script.remove();
     });
   });
 
diff --git a/cypress/e2e/e2e/simple-startinblox-e2e.cy.ts b/cypress/e2e/e2e/simple-startinblox-e2e.cy.ts
index c45081bca6b7931b63c0010a42d0a6a58103dd0c..b6508c704626ec73cbe082874fd2eaad3a5790ed 100644
--- a/cypress/e2e/e2e/simple-startinblox-e2e.cy.ts
+++ b/cypress/e2e/e2e/simple-startinblox-e2e.cy.ts
@@ -1,15 +1,17 @@
-describe('simple Startin’blox e2e test', function() {
+describe('simple Startin’blox e2e test', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/simple-startinblox-e2e-test.html')
-  })
+    cy.visit('/examples/e2e/simple-startinblox-e2e-test.html');
+  });
 
   it('check children count', () => {
-    cy.get('body > solid-display > div').children().should('have.length', 4)
-  })
+    cy.get('body > solid-display > div').children().should('have.length', 4);
+  });
 
   it('check first children content', () => {
-    cy.get('body > solid-display > div > solid-display:first-child > div > solid-display-value:first-child')
+    cy.get(
+      'body > solid-display > div > solid-display:first-child > div > solid-display-value:first-child',
+    )
       .should('have.attr', 'name', 'first_name')
-      .should('contain', 'Test')
-  })
-})
+      .should('contain', 'Test');
+  });
+});
diff --git a/cypress/e2e/e2e/solid-ac-checker.cy.ts b/cypress/e2e/e2e/solid-ac-checker.cy.ts
index 3c691a366aebc0353e81931a560bca7a0d7e358e..962b8c8371c6e330b5f1964a042316b4b04d9421 100644
--- a/cypress/e2e/e2e/solid-ac-checker.cy.ts
+++ b/cypress/e2e/e2e/solid-ac-checker.cy.ts
@@ -1,6 +1,6 @@
-describe('solid-ac-checker', function() {
+describe('solid-ac-checker', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/solid-ac-checker.html')
+    cy.visit('/examples/e2e/solid-ac-checker.html');
   });
 
   it('permission attribute', () => {
@@ -20,4 +20,4 @@ describe('solid-ac-checker', function() {
     cy.get('#ac-checker-3').should('not.have.attr', 'hidden');
     cy.get('#test3').should('be.visible');
   });
-})
\ No newline at end of file
+});
diff --git a/cypress/e2e/e2e/solid-delete.cy.ts b/cypress/e2e/e2e/solid-delete.cy.ts
index d95e10cf2c97dd02093aaa672b27bf8e7f3fba67..f7e986dce8dc8cd70d59edaf77cc5faffc581e23 100644
--- a/cypress/e2e/e2e/solid-delete.cy.ts
+++ b/cypress/e2e/e2e/solid-delete.cy.ts
@@ -11,18 +11,19 @@ describe('solid-delete', function () {
   it('calls store.delete and send events', () => {
     cy.spy(win.sibStore, 'delete');
 
-    cy.intercept("DELETE", '**/project.jsonld',
-    {
-      statusCode: 204
-    })
+    cy.intercept('DELETE', '**/project.jsonld', {
+      statusCode: 204,
+    });
 
     // button created
     cy.get('solid-delete#test1').find('button').should('have.length', 1);
     cy.get('solid-delete#test1 button').should('have.text', 'Supprimer');
     // on click, store.delete is called
-    cy.get('solid-delete#test1 button').click({ force: true }).then(() => {
-      expect(win.sibStore.delete).to.be.called;
-    });
+    cy.get('solid-delete#test1 button')
+      .click({ force: true })
+      .then(() => {
+        expect(win.sibStore.delete).to.be.called;
+      });
     // events have been fired
     cy.get('#res')
       .should('contain', 'save: /examples/data/project.jsonld')
@@ -33,12 +34,11 @@ describe('solid-delete', function () {
   it('does not send events on failure', () => {
     cy.reload();
 
-    cy.intercept("DELETE", '**/project.jsonld',
-    {
-      statusCode: 403
-    })
+    cy.intercept('DELETE', '**/project.jsonld', {
+      statusCode: 403,
+    });
 
-    cy.get('solid-delete#test1 button').click({ force: true })
+    cy.get('solid-delete#test1 button').click({ force: true });
     // if server fails, events not fired
     cy.get('#res').should('be.empty');
   });
@@ -46,8 +46,10 @@ describe('solid-delete', function () {
   it('re-render when label change', () => {
     cy.get('solid-delete#test1').then(el => {
       el.attr('data-label', 'Supprimer la ressource');
-    cy.get('solid-delete#test1 > button').should('have.text', 'Supprimer la ressource');
-    })
+      cy.get('solid-delete#test1 > button').should(
+        'have.text',
+        'Supprimer la ressource',
+      );
+    });
   });
-})
-
+});
diff --git a/cypress/e2e/e2e/solid-display.cy.ts b/cypress/e2e/e2e/solid-display.cy.ts
index 450219e64563cf2a4a1881edbe89a1ccdf397f5f..7631e04d57117e52df32ae684f66b944dcc11c70 100644
--- a/cypress/e2e/e2e/solid-display.cy.ts
+++ b/cypress/e2e/e2e/solid-display.cy.ts
@@ -1,44 +1,59 @@
-describe('solid-display', function() {
+describe('solid-display', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/solid-display.html')
+    cy.visit('/examples/e2e/solid-display.html');
   });
 
   it('display event', () => {
-    cy.get('#display-1>div').children().eq(0).should('have.attr', 'name', 'event')
+    cy.get('#display-1>div')
+      .children()
+      .eq(0)
+      .should('have.attr', 'name', 'event')
       .should('have.attr', 'value', 'Event name and date : ')
       .should('have.class', 'presentationEvent');
 
-    cy.get('#display-2 solid-set-default').should('have.attr', 'name', 'completeName')
+    cy.get('#display-2 solid-set-default')
+      .should('have.attr', 'name', 'completeName')
       .should('have.class', 'completeName')
-      .children().should('have.length', 3);
+      .children()
+      .should('have.length', 3);
   });
 
   it('handle fields attribute', () => {
     // all fields
-    cy.get('#display-3>div').children().eq(0)
-      .should('not.have.attr', 'fields');
-    cy.get('#display-3>div').children().eq(0)
-      .find('>div').children()
+    cy.get('#display-3>div').children().eq(0).should('not.have.attr', 'fields');
+    cy.get('#display-3>div')
+      .children()
+      .eq(0)
+      .find('>div')
+      .children()
       .should('have.length', 10);
-    cy.get('#display-3 > div ')
-      .find("[name=permissions]")
-      .should('not.exist');
-    
+    cy.get('#display-3 > div ').find('[name=permissions]').should('not.exist');
+
     // child-[field] attribute
-    cy.get('#display-3 > div').children().eq(0)
+    cy.get('#display-3 > div')
+      .children()
+      .eq(0)
       .should('have.attr', 'attribute-child', 'child-value');
-    cy.get('#display-3 > div').children().eq(1)
+    cy.get('#display-3 > div')
+      .children()
+      .eq(1)
       .should('have.attr', 'attribute-child', 'child-value');
-    cy.get('#display-3 > div').children().eq(2)
+    cy.get('#display-3 > div')
+      .children()
+      .eq(2)
       .should('have.attr', 'attribute-chIld', 'child-value');
-    cy.get('#display-3 > div').children().eq(3)
+    cy.get('#display-3 > div')
+      .children()
+      .eq(3)
       .should('have.attr', 'attribute-child', 'child-value');
 
     // no fields
-    cy.get('#display-4>div').children()
-      .should('have.attr', 'fields', '');
-    cy.get('#display-4>div').children().eq(0)
-      .find('>div').children()
+    cy.get('#display-4>div').children().should('have.attr', 'fields', '');
+    cy.get('#display-4>div')
+      .children()
+      .eq(0)
+      .find('>div')
+      .children()
       .should('have.length', 0);
   });
 
@@ -50,34 +65,41 @@ describe('solid-display', function() {
   });
 
   it('required mixin', () => {
-    cy.get('#display-6 > div')
-    .children().should('have.length', 4);
+    cy.get('#display-6 > div').children().should('have.length', 4);
 
     cy.get('#display-7').should('have.attr', 'required-ocean');
-    cy.get('#display-7 > div')
-    .children().should('have.length', 0);
+    cy.get('#display-7 > div').children().should('have.length', 0);
 
     cy.get('#display-8').should('have.attr', 'required-city');
+    cy.get('#display-8 > div').children().should('have.length', 2);
     cy.get('#display-8 > div')
-    .children().should('have.length', 2)
-    cy.get('#display-8 > div').children().eq(0)
-    .should('have.attr', 'data-src', '/examples/data/list/event-3.jsonld');
-    cy.get('#display-8 > div').children().eq(1)
-    .should('have.attr', 'data-src', '/examples/data/list/event-4.jsonld');
+      .children()
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/event-3.jsonld');
+    cy.get('#display-8 > div')
+      .children()
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/event-4.jsonld');
 
     cy.get('#display-9').should('have.attr', 'required-place');
+    cy.get('#display-9 > div').children().should('have.length', 2);
+    cy.get('#display-9 > div')
+      .children()
+      .eq(0)
+      .should('have.attr', 'data-src', '/examples/data/list/event-2.jsonld');
     cy.get('#display-9 > div')
-    .children().should('have.length', 2);
-    cy.get('#display-9 > div').children().eq(0)
-    .should('have.attr', 'data-src', '/examples/data/list/event-2.jsonld');
-    cy.get('#display-9 > div').children().eq(1)
-    .should('have.attr', 'data-src', '/examples/data/list/event-3.jsonld');
+      .children()
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/event-3.jsonld');
 
     cy.get('#display-10').should('have.attr', 'required-city');
     cy.get('#display-10').should('have.attr', 'required-place');
-    cy.get('#display-10 > div').children().should('have.length', 1)
-    cy.get('#display-10 > div > solid-display')
-    .should('have.attr', 'data-src', '/examples/data/list/event-3.jsonld');;
+    cy.get('#display-10 > div').children().should('have.length', 1);
+    cy.get('#display-10 > div > solid-display').should(
+      'have.attr',
+      'data-src',
+      '/examples/data/list/event-3.jsonld',
+    );
   });
 
   it('list-mixin : solid-container & solid-resource attributes', () => {
@@ -85,71 +107,112 @@ describe('solid-display', function() {
     cy.get('#display-11 > div').children().should('have.length', 4);
 
     cy.get('#display-12').should('have.attr', 'solid-resource');
-    cy.get('#display-12 > div').children().should('have.length',1);
+    cy.get('#display-12 > div').children().should('have.length', 1);
   });
 
   it('list-mixin : empty-value', () => {
     cy.get('#display-13').find('no-skill');
-    cy.get('#display-13 > span > no-skill').contains('No skill yet')
+    cy.get('#display-13 > span > no-skill').contains('No skill yet');
   });
 
   it('define src attribute of solid-link by action', () => {
-    cy.get('#display-14 > div > solid-action')
-      .should('have.attr', 'src', '/examples/data/list/user-1.jsonld');
-    cy.get('#display-14 > div > solid-action > solid-link')
-      .should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld');
+    cy.get('#display-14 > div > solid-action').should(
+      'have.attr',
+      'src',
+      '/examples/data/list/user-1.jsonld',
+    );
+    cy.get('#display-14 > div > solid-action > solid-link').should(
+      'have.attr',
+      'data-src',
+      '/examples/data/list/user-1.jsonld',
+    );
 
-    cy.get('#display-15 > div > solid-action')
-      .should('have.attr', 'src', 'other-resource');
-    cy.get('#display-15 > div > solid-action > solid-link')
-      .should('have.attr', 'data-src', 'other-resource');
-    });
+    cy.get('#display-15 > div > solid-action').should(
+      'have.attr',
+      'src',
+      'other-resource',
+    );
+    cy.get('#display-15 > div > solid-action > solid-link').should(
+      'have.attr',
+      'data-src',
+      'other-resource',
+    );
+  });
 
   it('handle default-[field] attribute', () => {
-    cy.get('#default-field > div solid-display-value')
-      .should('have.text', 'not defined');
+    cy.get('#default-field > div solid-display-value').should(
+      'have.text',
+      'not defined',
+    );
   });
 
   it('counter mixin', () => {
-    cy.get('#display-16').children().eq(0)
+    cy.get('#display-16')
+      .children()
+      .eq(0)
       .should('contain', '8 skills displayed :');
-    cy.get('#display-16').children().eq(1)
-      .find('div').should('have.length', '8');
+    cy.get('#display-16')
+      .children()
+      .eq(1)
+      .find('div')
+      .should('have.length', '8');
   });
 
   it('highlighter-mixin', () => {
-    cy.get('#display-17 > div').children().eq(0)
-      .find('solid-display-value').should('contain', 'Javascript')
+    cy.get('#display-17 > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('contain', 'Javascript');
   });
 
   it('nested-[field]', () => {
     // data-src in solid-display pointed on skill-*.jsonld
-    cy.get('#display-18 > div').children().eq(0)
+    cy.get('#display-18 > div')
+      .children()
+      .eq(0)
       .should('have.attr', 'data-src', '/examples/data/list/skill-2.jsonld');
-    cy.get('#display-18 > div').children().eq(1)
-      .should('have.attr','data-src', '/examples/data/list/skill-3.jsonld');
+    cy.get('#display-18 > div')
+      .children()
+      .eq(1)
+      .should('have.attr', 'data-src', '/examples/data/list/skill-3.jsonld');
     // User's name not displayed
-    cy.get('#display-18 > div').children().eq(0)
-      .find('solid-display-value').should('not.contain.value', 'Test User');
-    cy.get('#display-18 > div').children().eq(1)
-      .find('solid-display-value').should('not.contain.value', 'Test User');
+    cy.get('#display-18 > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('not.contain.value', 'Test User');
+    cy.get('#display-18 > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('not.contain.value', 'Test User');
     // Skills' name displayed
-    cy.get('#display-18 > div').children().eq(0)
-      .find('solid-display-value').should('have.attr', 'value', 'CSS');
-    cy.get('#display-18 > div').children().eq(1)
-      .find('solid-display-value').should('have.attr','value', 'Javascript');
+    cy.get('#display-18 > div')
+      .children()
+      .eq(0)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'CSS');
+    cy.get('#display-18 > div')
+      .children()
+      .eq(1)
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Javascript');
   });
 
   it('default-widget', () => {
     // default-widget applied to every child
     cy.get('#display-19 > div')
-      .find('solid-display-link').eq(0)
+      .find('solid-display-link')
+      .eq(0)
       .should('have.attr', 'name', 'name');
     cy.get('#display-19 > div')
-      .find('solid-display-link').eq(1)
+      .find('solid-display-link')
+      .eq(1)
       .should('have.attr', 'name', 'email');
     cy.get('#display-19 > div')
-      .find('solid-display-link').eq(2)
+      .find('solid-display-link')
+      .eq(2)
       .should('have.attr', 'name', 'username');
 
     // default-widget applied to several children
@@ -157,32 +220,44 @@ describe('solid-display', function() {
       .find('solid-display-div')
       .should('have.attr', 'name', 'name');
     cy.get('#display-20 > div')
-      .find('solid-display-link').eq(0)
+      .find('solid-display-link')
+      .eq(0)
       .should('have.attr', 'name', 'email');
     cy.get('#display-20 > div')
-      .find('solid-display-link').eq(1)
+      .find('solid-display-link')
+      .eq(1)
       .should('have.attr', 'name', 'username');
   });
 
   it('oembed template', () => {
     cy.get('#display-21 > div')
       .find('solid-display-value-oembed')
-      .should('have.attr', 'value', 'https://www.audiomack.com/oembed?url=https%3A%2F%2Faudiomack.com%2Faudiomack%2Fplaylist%2Fjust-chillin&format=json');
+      .should(
+        'have.attr',
+        'value',
+        'https://www.audiomack.com/oembed?url=https%3A%2F%2Faudiomack.com%2Faudiomack%2Fplaylist%2Fjust-chillin&format=json',
+      );
   });
 
   it('default-widget-[field]', () => {
+    cy.get('#display-22 > div').children().should('have.length', 4);
+    cy.get('#display-22 > div').children().eq(1).should('contain', 'Rennes');
+    cy.get('#display-22 > div > custom-default-widget').should(
+      'contain',
+      'Field empty',
+    );
     cy.get('#display-22 > div')
-      .children().should('have.length', 4);
-    cy.get('#display-22 > div').children().eq(1)
-      .should('contain', 'Rennes');
-    cy.get('#display-22 > div > custom-default-widget')
-      .should('contain', 'Field empty');
-    cy.get('#display-22 > div').children().eq(0)
+      .children()
+      .eq(0)
       .should('contain', 'Field empty');
-    cy.get('#display-22 > div').children().eq(2)
+    cy.get('#display-22 > div')
+      .children()
+      .eq(2)
       .should('contain', 'Field empty');
-    cy.get('#display-22 > div > custom-default-widget-website')
-      .should('contain', 'No website');
+    cy.get('#display-22 > div > custom-default-widget-website').should(
+      'contain',
+      'No website',
+    );
   });
 
   it('dispatch event when widget rendered', () => {
@@ -191,46 +266,68 @@ describe('solid-display', function() {
 
   it('widget for empty set', () => {
     // empty set widget displayed
+    cy.get('#widget-empty-set1 > div').children().should('have.length', 2);
     cy.get('#widget-empty-set1 > div')
-      .children().should('have.length', 2);
-    cy.get('#widget-empty-set1 > div')
-      .children().eq(1).children()
+      .children()
+      .eq(1)
+      .children()
       .should('have.length', 1);
     cy.get('#widget-empty-set1 > div')
-      .children().eq(1)
+      .children()
+      .eq(1)
       .should('contain', 'set empty');
     // empty set widget not displayed
+    cy.get('#widget-empty-set2 > div').children().should('have.length', 2);
     cy.get('#widget-empty-set2 > div')
-      .children().should('have.length', 2);
-    cy.get('#widget-empty-set2 > div')
-      .children().eq(1).children()
+      .children()
+      .eq(1)
+      .children()
       .should('have.length', 3);
     cy.get('#widget-empty-set2 > div')
-      .children().eq(1).should('contain', 'Paris')
+      .children()
+      .eq(1)
+      .should('contain', 'Paris')
       .and('not.contain', 'set empty');
     // empty set with value attribute displayed
+    cy.get('#widget-empty-set3 > div').children().should('have.length', 2);
     cy.get('#widget-empty-set3 > div')
-      .children().should('have.length', 2);
-    cy.get('#widget-empty-set3 > div')
-      .children().eq(1)
+      .children()
+      .eq(1)
       .should('have.attr', 'value', 'empty set value');
     cy.get('#widget-empty-set3 > div')
-      .children().eq(1).should('contain', 'empty set value')
+      .children()
+      .eq(1)
+      .should('contain', 'empty set value')
       .and('not.contain', 'set empty');
   });
 
-  it('solid-set-div-label', () =>  {
+  it('solid-set-div-label', () => {
+    cy.get('#solid-set-div-label > div').children().should('have.length', 4);
+    cy.get('#solid-set-div-label > div')
+      .children()
+      .eq(0)
+      .find('solid-set-div-label')
+      .children()
+      .should('have.length', 2);
+    cy.get(
+      '#solid-set-div-label > div > solid-display > div > solid-set-div-label',
+    )
+      .find('label')
+      .should('contain', 'identity');
     cy.get('#solid-set-div-label > div')
-      .children().should('have.length', 4);
-    cy.get('#solid-set-div-label > div').children().eq(0)
-      .find('solid-set-div-label').children().should('have.length', 2);
-    cy.get('#solid-set-div-label > div > solid-display > div > solid-set-div-label')
-      .find('label').should('contain', 'identity');
-    cy.get('#solid-set-div-label > div').children().eq(1)
-      .find('label').should('contain', 'identity');
-    cy.get('#solid-set-div-label > div').children().eq(2)
-      .find('label').should('contain', 'identity');
-    cy.get('#solid-set-div-label > div').children().eq(3)
-      .find('label').should('contain', 'identity');
-  })
-})
\ No newline at end of file
+      .children()
+      .eq(1)
+      .find('label')
+      .should('contain', 'identity');
+    cy.get('#solid-set-div-label > div')
+      .children()
+      .eq(2)
+      .find('label')
+      .should('contain', 'identity');
+    cy.get('#solid-set-div-label > div')
+      .children()
+      .eq(3)
+      .find('label')
+      .should('contain', 'identity');
+  });
+});
diff --git a/cypress/e2e/e2e/solid-form-file.cy.ts b/cypress/e2e/e2e/solid-form-file.cy.ts
index c48f2cfd3c07d2935744be0b7a556d04f7035685..4d6fad10c9fdc8fa5aaefd7c23636270ad09d792 100644
--- a/cypress/e2e/e2e/solid-form-file.cy.ts
+++ b/cypress/e2e/e2e/solid-form-file.cy.ts
@@ -1,55 +1,97 @@
 // TODO: We should make tests run independently of one another
-describe('solid-form-file test', { testIsolation: false }, function() {
+describe('solid-form-file test', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/solid-form-file.html')
+    cy.visit('/examples/e2e/solid-form-file.html');
   });
 
-  it('upload file with solid-form-file', function() {
-    cy.get('#form-file [name=picture]+input[type=file]').uploadFile('../../fake-image.svg')
+  it('upload file with solid-form-file', () => {
+    cy.get('#form-file [name=picture] input[type=file]').uploadFile(
+      '../../fake-image.svg',
+    );
     cy.get('#form-file input[name=picture]').should($i => {
-      expect($i.val()).to.match(/\/upload\/[0-9a-f]+.jpg$/)
-    })
-  })
+      expect($i.val()).to.match(/\/upload\/[0-9a-f]+.jpg$/);
+    });
+  });
 
-  it('upload image with solid-form-file-image', function() {
-    cy.get('#form-image solid-form-image input[type=file]').uploadFile('../../fake-image.svg')
+  it('upload image with solid-form-file-image', () => {
+    cy.get('#form-image solid-form-image input[type=file]').uploadFile(
+      '../../fake-image.svg',
+    );
     cy.get('#form-image solid-form-image img').should($i => {
-      expect($i.attr('src')).to.not.match(/\/upload\/fruits.jpg$/)
-      expect($i.attr('src')).to.match(/\/upload\/[0-9a-f]+.jpg$/)
-    })
-  })
-  
-  it('resets the file', function() {
-    cy.get('#reset-file solid-form-file input[type=file]').uploadFile('../../fake-image.svg')
+      expect($i.attr('src')).to.not.match(/\/upload\/fruits.jpg$/);
+      expect($i.attr('src')).to.match(/\/upload\/[0-9a-f]+.jpg$/);
+    });
+  });
+
+  it('resets the file', () => {
+    cy.get('#reset-file solid-form-file input[type=file]').uploadFile(
+      '../../fake-image.svg',
+    );
     cy.get('#reset-file solid-form-file input[name=picture]').should($i => {
-      expect($i.val()).to.match(/\/upload\/[0-9a-f]+.jpg$/)
-    })
+      expect($i.val()).to.match(/\/upload\/[0-9a-f]+.jpg$/);
+    });
     cy.wait(500);
     cy.get('#reset-file input[type=reset]').click();
     cy.get('#reset-file solid-form-file input[type=file]').should('be.empty');
-    cy.get('#reset-file solid-form-file input[type=text]').should('have.value', '../../upload/fruits.jpg');
+    cy.get('#reset-file solid-form-file input[type=text]').should(
+      'have.value',
+      '../../upload/fruits.jpg',
+    );
     cy.get('#reset-file solid-form-file button').should('have.attr', 'hidden');
-  })
+  });
 
-  it('resets the image', function () {
-    cy.get('#reset-image solid-form-image input[type=file]').uploadFile('../../fake-image.svg')
+  it('resets the image', () => {
+    cy.get('#reset-image solid-form-image input[type=file]').uploadFile(
+      '../../fake-image.svg',
+    );
     cy.get('#reset-image solid-form-image img').should($i => {
-      expect($i.attr('src')).to.not.match(/\/upload\/fruits.jpg$/)
-      expect($i.attr('src')).to.match(/\/upload\/[0-9a-f]+.jpg$/)
-    })
+      expect($i.attr('src')).to.not.match(/\/upload\/fruits.jpg$/);
+      expect($i.attr('src')).to.match(/\/upload\/[0-9a-f]+.jpg$/);
+    });
     cy.get('#reset-image input[type=reset]').click();
     cy.get('#reset-image solid-form-image img').should($i => {
-      expect($i.attr('src')).to.match(/\/upload\/fruits.jpg$/)
-    })
+      expect($i.attr('src')).to.match(/\/upload\/fruits.jpg$/);
+    });
     cy.get('#reset-image solid-form-image input[type=file]').should('be.empty');
-    cy.get('#reset-image solid-form-image input[type=text]').should('have.value', '../../upload/fruits.jpg');
-    cy.get('#reset-image solid-form-image button').should('have.attr', 'hidden');
+    cy.get('#reset-image solid-form-image input[type=text]').should(
+      'have.value',
+      '../../upload/fruits.jpg',
+    );
+    cy.get('#reset-image solid-form-image button').should(
+      'have.attr',
+      'hidden',
+    );
   });
 
-  it('handles required', function() {
-    cy.get('#form-required-image solid-form-image input[type=text]').should('have.attr', 'required')
-    cy.get('#form-required-image solid-form-image input[type=file]').should('not.have.attr', 'required')
-    cy.get('#form-required-file solid-form-file input[type=text]').should('have.attr', 'required')
-    cy.get('#form-required-file solid-form-file input[type=file]').should('not.have.attr', 'required')
-  })
-})
\ No newline at end of file
+  it('handles required', () => {
+    cy.get('#form-required-image solid-form-image input[type=text]').should(
+      'have.attr',
+      'required',
+    );
+    cy.get('#form-required-image solid-form-image input[type=file]').should(
+      'not.have.attr',
+      'required',
+    );
+    cy.get('#form-required-file solid-form-file input[type=text]').should(
+      'have.attr',
+      'required',
+    );
+    cy.get('#form-required-file solid-form-file input[type=file]').should(
+      'not.have.attr',
+      'required',
+    );
+  });
+
+  it('displays file name if source not empty', () => {
+    cy.visit('/examples/e2e/solid-form-file.html'); // if not then page is not updated, and another file is uploaded from the prev test
+    cy.get(
+      '#form-file solid-form-file[name=picture] a[href="../../upload/fruits.jpg"]',
+    ).contains('fruits.jpg');
+    cy.get(
+      '#reset-file solid-form-file[name=picture] a[href="../../upload/fruits.jpg"]',
+    ).contains('fruits.jpg');
+    cy.get(
+      '#form-required-file solid-form-file[name=picture] a[href="../../upload/fruits.jpg"]',
+    ).contains('fruits.jpg');
+  });
+});
diff --git a/cypress/e2e/e2e/solid-form-richtext.cy.ts b/cypress/e2e/e2e/solid-form-richtext.cy.ts
index 430b07f08330da4c71948a2349daeb58a9fa5f06..3643f68fc816067fdef9f1b594f973cfa37273ab 100644
--- a/cypress/e2e/e2e/solid-form-richtext.cy.ts
+++ b/cypress/e2e/e2e/solid-form-richtext.cy.ts
@@ -1,86 +1,121 @@
 describe('solid-form-richtext test', function () {
-    this.beforeEach('visit', () => {
-      cy.visit('/examples/e2e/solid-form-richtext.html');
-    });
+  this.beforeEach('visit', () => {
+    cy.visit('/examples/e2e/solid-form-richtext.html');
+  });
 
-    it('Submitting form with filled rich text input should not display an error', () => {
-        cy.get('solid-form div[data-richtext] p').should('not.have.length', 0);
-        cy.get('#form-1 input[type="submit"]').click();
-        cy.get('#form-1 div[data-richtext] .required-error-message').should('not.exist');
-        cy.get('#form-1 div[data-richtext] .error-border-richtext').should('not.exist');
-    });
+  it('Submitting form with filled rich text input should not display an error', () => {
+    cy.get('solid-form div[data-richtext] p').should('not.have.length', 0);
+    cy.get('#form-1 input[type="submit"]').click();
+    cy.get('#form-1 div[data-richtext] .required-error-message').should(
+      'not.exist',
+    );
+    cy.get('#form-1 div[data-richtext] .error-border-richtext').should(
+      'not.exist',
+    );
+  });
+
+  it('Submitting form with empty rich text input should display an error mesage', () => {
+    cy.get('#form-1 div[data-richtext] [contenteditable]')
+      .should('have.text', 'some description')
+      .clear();
+    cy.get('#form-1 div[data-richtext] p').clear();
+    cy.get('#form-1 input[type="submit"]').click();
+    cy.get('#form-1 div[data-richtext] .required-error-message').should(
+      'exist',
+    );
+    cy.get('#form-1 div[data-richtext].error-border-richtext').should('exist');
+  });
 
-    it('Submitting form with empty rich text input should display an error mesage', () => {
-        cy.get('#form-1 div[data-richtext] p').clear();
-        cy.get('#form-1 input[type="submit"]').click();
-        cy.get('#form-1 div[data-richtext] .required-error-message').should('exist');
-        cy.get('#form-1 div[data-richtext].error-border-richtext').should('exist');
-    }); 
-    
-    it('Error message disappears when retyping in rich text input', () => {
-        // Empty fields , error is shown
-        cy.get('#form-1 div[data-richtext] p').clear();
-        cy.get('#form-1 input[type="submit"]').click();
-        cy.get('#form-1 div[data-richtext] .required-error-message').should('exist');
-        cy.get('#form-1 div[data-richtext].error-border-richtext').should('exist');
+  it('Error message disappears when retyping in rich text input', () => {
+    // Empty fields , error is shown
+    cy.get('#form-1 div[data-richtext] [contenteditable]')
+      .should('have.text', 'some description')
+      .clear();
+    cy.get('#form-1 input[type="submit"]').click();
+    cy.get('#form-1 div[data-richtext] .required-error-message').should(
+      'exist',
+    );
+    cy.get('#form-1 div[data-richtext].error-border-richtext').should('exist');
 
-        // Retype text , error disapears
-        cy.get('#form-1 div[data-richtext] p').type('some text');
-        cy.get('#form-1 input[type="submit"]').click();
-        cy.get('#form-1 div[data-richtext] .required-error-message').should('not.exist');
-        cy.get('#form-1 div[data-richtext] .error-border-richtext').should('not.exist');
-    }); 
+    // Retype text , error disapears
+    cy.get('#form-1 div[data-richtext] p').type('some text');
+    cy.get('#form-1 input[type="submit"]').click();
+    cy.get('#form-1 div[data-richtext] .required-error-message').should(
+      'not.exist',
+    );
+    cy.get('#form-1 div[data-richtext] .error-border-richtext').should(
+      'not.exist',
+    );
+  });
 
-    it('Placeholder is displayed text value is empty if placeholder is assigned', () => {
-        cy.get('#form-1 div[data-richtext] p').clear();
-        cy.get('#form-1 div[data-richtext] div[data-placeholder]').should('exist')
-        cy.get('#form-1 div[data-richtext] div[data-placeholder]').should('have.attr', 'data-placeholder', 'some placeholder')
-    }); 
+  it('Placeholder is displayed text value is empty if placeholder is assigned', () => {
+    cy.get('#form-1 div[data-richtext] p').clear();
+    cy.get('#form-1 div[data-richtext] div[data-placeholder]').should('exist');
+    cy.get('#form-1 div[data-richtext] div[data-placeholder]').should(
+      'have.attr',
+      'data-placeholder',
+      'some placeholder',
+    );
+  });
 
-    it('richtext html rendering', () => {
-        cy.get('#form-2 solid-form-richtext')
-          .children().should('have.have.length', 2)
-          .find('button')
-          .and('have.attr', 'class', 'ql-bold');
-        cy.get('#form-2 solid-form-richtext').then($el => {
-          expect((<any>$el[0]).component.getValue()).to.equal('**Jean-Bernard**\n');
-          cy.get('#form-2 solid-form-richtext .ql-editor').type('{selectall}Jean-Claude{selectall}')
-          cy.get('#form-2 solid-form-richtext .ql-italic')
-            .click()
-            cy.get('#form-2 solid-form-richtext .ql-bold')
-            .click()
-          cy.get('#form-2 solid-form-richtext .ql-editor')
-            .find('em')
-            .should('have.text', 'Jean-Claude')
-          cy.get('#form-2 solid-form-richtext').then($el => {
-            expect((<any>$el[0]).component.getValue()).to.equal('_Jean-Claude_\n')
-          });
-        });
-        // add link button in richtext mixin
-        cy.get('#form-3 solid-form-richtext > div ').children().eq(4)
-          .find('button')
-          .and('have.attr', 'class', 'ql-link');
-        cy.get('#form-3 solid-form-richtext .ql-editor').type('{selectall}test link{selectall}')
-        cy.get('#form-3 solid-form-richtext .ql-link')
-          .click()
-        cy.get('#form-3 solid-form-richtext > div[name=name] > div[data-mode=link] > input[type=text]')
-          .type('http://www.yesnoif.com/')
-        cy.get('#form-3 solid-form-richtext > div[name=name] > div[data-mode=link] > a[class=ql-action]')
-          .click()
-        cy.get('#form-3 solid-form-richtext .ql-editor')
-          .find('a').should('have.attr', 'href', 'http://www.yesnoif.com/')
-          .and('contain', 'test link');
-        // verify value format sent in the form
-        cy.get('#form-3 input[type=submit]').click()
-        cy.get('#form-3').then($el => {
-          return (<any>$el[0]).component.getFormValue().then(res => {
-            expect(res.name).to.equal('[test link](http://www.yesnoif.com/)\n');
-          });
-        });
-        // value stocked in markdown well displayed in the solid-form-richtext
-        cy.get('#form-4 solid-form-richtext > div[name=website]')
-          .find('a').should('have.attr', 'href', 'http://drawing.garden/')
-          .and('contain', 'my site')
+  it('richtext html rendering', () => {
+    cy.get('#form-2 solid-form-richtext')
+      .children()
+      .should('have.have.length', 2)
+      .find('button')
+      .and('have.attr', 'class', 'ql-bold');
+    cy.get('#form-2 solid-form-richtext').then($el => {
+      expect((<any>$el[0]).component.getValue()).to.equal('**Jean-Bernard**\n');
+      cy.get('#form-2 solid-form-richtext .ql-editor').type(
+        '{selectall}Jean-Claude{selectall}',
+      );
+      cy.get('#form-2 solid-form-richtext .ql-italic').click();
+      cy.get('#form-2 solid-form-richtext .ql-bold').click();
+      cy.get('#form-2 solid-form-richtext .ql-editor')
+        .find('em')
+        .should('have.text', 'Jean-Claude');
+      cy.get('#form-2 solid-form-richtext').then($el => {
+        expect((<any>$el[0]).component.getValue()).to.equal('_Jean-Claude_\n');
       });
+    });
+    // add link button in richtext mixin
+    cy.get('#form-3 solid-form-richtext > div ')
+      .children()
+      .eq(4)
+      .find('button')
+      .and('have.attr', 'class', 'ql-link');
+    cy.get('#form-3 solid-form-richtext .ql-editor').type(
+      '{selectall}test link{selectall}',
+    );
+    cy.get('#form-3 solid-form-richtext .ql-link').click();
+    cy.get(
+      '#form-3 solid-form-richtext > div[name=name] > div[data-mode=link] > input[type=text]',
+    ).type('http://www.yesnoif.com/');
+    cy.get(
+      '#form-3 solid-form-richtext > div[name=name] > div[data-mode=link] > a[class=ql-action]',
+    ).click();
+    cy.get('#form-3 solid-form-richtext .ql-editor')
+      .find('a')
+      .should('have.attr', 'href', 'http://www.yesnoif.com/')
+      .and('contain', 'test link');
+    // verify value format sent in the form
+    cy.get('#form-3 input[type=submit]').click();
+    cy.get('#form-3').then($el => {
+      return (<any>$el[0]).component.getFormValue().then(res => {
+        expect(res.name).to.equal('[test link](http://www.yesnoif.com/)\n');
+      });
+    });
+    // value stocked in markdown well displayed in the solid-form-richtext
+    cy.get('#form-4 solid-form-richtext > div[name=website]')
+      .find('a')
+      .should('have.attr', 'href', 'http://drawing.garden/')
+      .and('contain', 'my site');
+  });
 
-})  
\ No newline at end of file
+  it('Editor displays correctly multiple new lines', () => {
+    cy.get('#form-5 div[data-richtext] [contenteditable]').should(
+      'have.html',
+      '<p>Première ligne</p><p><br></p><p><br></p><p><br></p><p>Seconde Ligne avec quatre sauts de ligne</p>',
+    );
+  });
+});
diff --git a/cypress/e2e/e2e/solid-form.cy.ts b/cypress/e2e/e2e/solid-form.cy.ts
index aa7c53051c1ddb401a0c27948fc3e43cd60da202..824c10fa2dace4f9b22dfb7a0c9869d55fc36ec3 100644
--- a/cypress/e2e/e2e/solid-form.cy.ts
+++ b/cypress/e2e/e2e/solid-form.cy.ts
@@ -1,18 +1,20 @@
 // TODO: We should make tests run independently of one another
-describe('solid-form', { testIsolation: false }, function() {
+describe('solid-form', { testIsolation: false }, function () {
   let win: Window;
   this.beforeAll('visit', () => {
     cy.visit('/examples/e2e/solid-form.html');
     cy.window().then(w => {
       win = w;
     });
-
   });
 
   it('creation form', () => {
-    cy.get('#form-1 input[type=text]').should('have.length', 2)
+    cy.get('#form-1 input[type=text]').should('have.length', 2);
     cy.get('#form-1 input[type=text][name=name]').should('have.value', '');
-    cy.get('#form-1 input[type=text][name="contact.email"]').should('have.value', '');
+    cy.get('#form-1 input[type=text][name="contact.email"]').should(
+      'have.value',
+      '',
+    );
     cy.get('#form-1').then($el => {
       return (<any>$el[0]).component.getFormValue().then(res => {
         expect(res).to.deep.equal({ name: '', contact: { email: '' } });
@@ -25,12 +27,11 @@ describe('solid-form', { testIsolation: false }, function() {
       cy.get('input[type=text]').should('have.length', 2);
       cy.get('input[name=with]').should('exist');
       cy.get('input[name=field]').should('exist');
-    })
-    
+    });
   });
 
   it('edition form', () => {
-    cy.get('#form-edition-1 input[type=text]').should('have.length', 2)
+    cy.get('#form-edition-1 input[type=text]').should('have.length', 2);
     cy.get('#form-edition-1 input[type=text][name=name]')
       .should('have.value', 'Coliving')
       .type(' in BZH');
@@ -41,55 +42,58 @@ describe('solid-form', { testIsolation: false }, function() {
     cy.get('#form-edition-1').then($el => {
       return (<any>$el[0]).component.getFormValue().then(res => {
         expect(res).to.deep.equal({
-          "@id": "/examples/data/list/event-1.jsonld",
+          '@id': '/examples/data/list/event-1.jsonld',
           contact: {
             email: 'admin@example.com',
-            "@id": "/examples/data/list/user-1.jsonld",
+            '@id': '/examples/data/list/user-1.jsonld',
           },
           name: 'Coliving in BZH',
         });
       });
     });
 
-    cy.intercept("PUT", '**/event-1.jsonld', {
+    cy.intercept('PUT', '**/event-1.jsonld', {
       headers: {
-        contentType: 'application/ld+json'
-      }
-    })
+        contentType: 'application/ld+json',
+      },
+    });
 
-    cy.get('#form-edition-2 input[type=text][name=name]')
-      .type(' in BZH');
-    cy.get('#form-edition-2 select').select('Pierre DLC')
+    cy.get('#form-edition-2 input[type=text][name=name]').type(' in BZH');
+    cy.get('#form-edition-2 select').select('Pierre DLC');
     cy.get('#form-edition-2').then($el => {
       return (<any>$el[0]).component.getFormValue().then(res => {
         expect(res).to.deep.equal({
           name: 'Coliving in BZH',
           contact: {
-            "@id": "/examples/data/list/user-4.jsonld",
+            '@id': '/examples/data/list/user-4.jsonld',
           },
-          "@id": "/examples/data/list/event-1.jsonld",
+          '@id': '/examples/data/list/event-1.jsonld',
         });
       });
     });
     cy.get('#form-edition-2 input[type="submit"]').click();
     // After submit, form is re-rendered properly
-    cy.get('#form-edition-2 input[type=text][name=name]')
-      .should('have.value', 'Coliving');
-    cy.get('#form-edition-2 select')
-      .should('have.value', '{"@id": "/examples/data/list/user-1.jsonld"}');
+    cy.get('#form-edition-2 input[type=text][name=name]').should(
+      'have.value',
+      'Coliving',
+    );
+    cy.get('#form-edition-2 select').should(
+      'have.value',
+      '{"@id": "/examples/data/list/user-1.jsonld"}',
+    );
 
     // Nested container
     cy.get('#form-edition-3').then($el => {
       return (<any>$el[0]).component.getFormValue().then(res => {
         expect(res).to.deep.equal({
           skills: {
-            "ldp:contains": [
-              { "@id": "/examples/data/list/skill-2.jsonld" },
-              { "@id": "/examples/data/list/skill-3.jsonld" },
+            'ldp:contains': [
+              { '@id': '/examples/data/list/skill-2.jsonld' },
+              { '@id': '/examples/data/list/skill-3.jsonld' },
             ],
-            "@id": "/examples/data/list/user-1-skills.jsonld",
+            '@id': '/examples/data/list/user-1-skills.jsonld',
           },
-          "@id": "/examples/data/list/user-1.jsonld"
+          '@id': '/examples/data/list/user-1.jsonld',
         });
       });
     });
@@ -100,17 +104,17 @@ describe('solid-form', { testIsolation: false }, function() {
       .should('have.attr', 'range', '/examples/data/list/skills.jsonld')
       .should('have.attr', 'data-src', '/examples/data/list/skills.jsonld')
       .should('have.attr', 'order-desc', 'name')
-      .should('have.attr', 'name', 'skills')
+      .should('have.attr', 'name', 'skills');
 
     cy.get('#form-3 solid-form-label-placeholder-text')
       .should('have.attr', 'label', 'Test label')
       .should('have.attr', 'placeholder', 'test placeholder')
       .should('have.attr', 'class', 'test-class')
-      .should('have.attr', 'required')
+      .should('have.attr', 'required');
 
     cy.get('#form-3 solid-form-label-placeholder-text')
       .find('input')
-      .should('have.attr', 'placeholder', 'test placeholder')
+      .should('have.attr', 'placeholder', 'test placeholder');
   });
 
   it('solid-form + pattern, title attributes', () => {
@@ -128,94 +132,90 @@ describe('solid-form', { testIsolation: false }, function() {
       .find('input[type=submit]')
       .should('have.value', 'Register');
 
-    cy.get('solid-form#form-6')
-      .then(el => {
-        el.attr('submit-button', 'Register the user');
-        cy.get('solid-form#form-6')
+    cy.get('solid-form#form-6').then(el => {
+      el.attr('submit-button', 'Register the user');
+      cy.get('solid-form#form-6')
         .find('input[type=submit]')
         .should('have.value', 'Register the user');
-      })
-    cy.get('solid-form-search#form-search-6')
-      .then(el => {
-        el.attr('submit-button', 'Register the user');
-        cy.get('solid-form-search#form-search-6')
+    });
+    cy.get('solid-form-search#form-search-6').then(el => {
+      el.attr('submit-button', 'Register the user');
+      cy.get('solid-form-search#form-search-6')
         .find('input[type=submit]')
         .should('have.value', 'Register the user');
-      })
+    });
   });
 
   it('show errors without resetting', () => {
     cy.intercept('POST', '**/events.jsonld', {
       statusCode: 400,
-      body: { 
-        "name": 
-        [
-          "Ensure this field has no more than 10 characters."
-        ],
-        "batches": {
-          "title": ["Title too long", "Title not unique"],
-          "tasks": {
-            "@id": ["Task with this urlid already exists."],
-            "amount": ["Should be > 0"]
-          }
+      body: {
+        name: ['Ensure this field has no more than 10 characters.'],
+        batches: {
+          title: ['Title too long', 'Title not unique'],
+          tasks: {
+            '@id': ['Task with this urlid already exists.'],
+            amount: ['Should be > 0'],
+          },
         },
-      "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+        '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
       },
       headers: {
-        'content-type': 'application/ld+json'
-      }
-    })
+        'content-type': 'application/ld+json',
+      },
+    });
 
     cy.get('solid-form#form-7')
       .find('input[name=name]')
       .type('Mon très long titre');
-    cy.get('solid-form#form-7')
-      .find('input[type=submit]')
-      .click();
+    cy.get('solid-form#form-7').find('input[type=submit]').click();
     cy.get('solid-form#form-7')
       .find('[data-id="error"]')
       .should('contain', 'A validation error occurred.')
       .and('not.contain', '@context');
     cy.get('solid-form#form-7')
       .find('input[name=name]')
-      .should('have.value', 'Mon très long titre')
+      .should('have.value', 'Mon très long titre');
     cy.get('solid-form#form-7')
       .find('.error[name=name] .error-message')
-      .should('contain', 'Ensure this field has no more than 10 characters.')
+      .should('contain', 'Ensure this field has no more than 10 characters.');
     cy.get('solid-form#form-7')
       .find('.error[name="batches.title"] .error-message')
-      .should('contain', 'Title too long')
+      .should('contain', 'Title too long');
     cy.get('solid-form#form-7')
       .find('.error[name="batches.tasks"] .error-message')
-      .should('contain', 'Task with this urlid already exists.')
+      .should('contain', 'Task with this urlid already exists.');
     cy.get('solid-form#form-7')
       .find('.error[name="batches.tasks"] .error-message')
-      .should('contain', 'Should be > 0')
+      .should('contain', 'Should be > 0');
 
     // removes error after new submission
-    cy.intercept("POST", '**/events.jsonld', {
+    cy.intercept('POST', '**/events.jsonld', {
       headers: {
-        contentType: 'application/ld+json'
+        contentType: 'application/ld+json',
       },
-      body: 'ok'
-    })
+      body: 'ok',
+    });
 
-    cy.get('solid-form#form-7')
-    .find('input[type=submit]')
-    .click();
-    cy.get('solid-form#form-7')
-      .find('[data-id="error"]').should('be.empty')
+    cy.get('solid-form#form-7').find('input[type=submit]').click();
+    cy.get('solid-form#form-7').find('[data-id="error"]').should('be.empty');
   });
 
   it('partial attribute', () => {
     cy.spy(win.sibStore, 'put');
-    cy.get('#form-8').find('input[type=submit]').click().then(() => {
-      expect(win.sibStore.put).to.be.called;
-    });
+    cy.get('#form-8')
+      .find('input[type=submit]')
+      .click()
+      .then(() => {
+        expect(win.sibStore.put).to.be.called;
+      });
     cy.spy(win.sibStore, 'patch');
-    cy.get('#form-9').find('input[type=submit]').click().then(() => {
-      expect(win.sibStore.patch).to.be.called;
-    });
+    cy.get('#form-9')
+      .find('input[type=submit]')
+      .click()
+      .then(() => {
+        expect(win.sibStore.patch).to.be.called;
+      });
   });
 
   it('naked attribute', () => {
@@ -224,129 +224,155 @@ describe('solid-form', { testIsolation: false }, function() {
 
   it('loader-id attribute', () => {
     cy.get('#form-loader').should('have.attr', 'hidden');
-    cy.intercept("POST", '**/users.jsonld', {
-        delay: 3000
-    })
-    
-    cy.get('#form-11')
-      .find('input[name=name]')
-      .type('Tryphon');
-    cy.get('#form-11')
-      .find('input[type=submit]')
-      .click();
+    cy.intercept('POST', '**/users.jsonld', {
+      delay: 3000,
+    });
+
+    cy.get('#form-11').find('input[name=name]').type('Tryphon');
+    cy.get('#form-11').find('input[type=submit]').click();
     cy.get('#form-loader').should('not.have.attr', 'hidden');
   });
 
   it('solid-form with addable attributes', () => {
     // Verify addable's attributes are passed in the solid-form-dropdown-addable
     cy.get('solid-form#form-addable > form > solid-form-dropdown-addable')
-    .should('have.attr', 'name', 'skills')
-    .and('have.attr', 'addable-data-src', '/examples/data/list/users.jsonld')
-    .and('have.attr', 'addable-fields', 'name')
-    .and('have.attr', 'addable-widget-name', 'solid-form-text-placeholder-label')
-    .and('have.attr', 'addable-placeholder-name', 'Enter skill name')
-    .and('have.attr', 'addable-submit-button', 'Send name')
+      .should('have.attr', 'name', 'skills')
+      .and('have.attr', 'addable-data-src', '/examples/data/list/users.jsonld')
+      .and('have.attr', 'addable-fields', 'name')
+      .and(
+        'have.attr',
+        'addable-widget-name',
+        'solid-form-text-placeholder-label',
+      )
+      .and('have.attr', 'addable-placeholder-name', 'Enter skill name')
+      .and('have.attr', 'addable-submit-button', 'Send name');
   });
 
   it('autocomplete attribute', () => {
-    cy.get('solid-form#form-12 > form > solid-form-label-text').eq(0)
-      .should('have.attr', 'autocomplete', 'off')
-    cy.get('solid-form#form-12 > form > solid-form-label-text').eq(0)
+    cy.get('solid-form#form-12 > form > solid-form-label-text')
+      .eq(0)
+      .should('have.attr', 'autocomplete', 'off');
+    cy.get('solid-form#form-12 > form > solid-form-label-text')
+      .eq(0)
       .find('input[type=text]')
-      .should('have.attr', 'autocomplete', 'off')
-    cy.get('solid-form#form-12 > form > solid-form-label-text').eq(1)
-      .should('not.have.attr', 'autocomplete')
+      .should('have.attr', 'autocomplete', 'off');
+    cy.get('solid-form#form-12 > form > solid-form-label-text')
+      .eq(1)
+      .should('not.have.attr', 'autocomplete');
   });
 
   it('autosaves form', () => {
     cy.spy(win.sibStore, 'patch');
-    cy.get('solid-form#form-autosave').find('input[type="submit"]')
+    cy.get('solid-form#form-autosave')
+      .find('input[type="submit"]')
       .should('not.exist');
-    cy.get('solid-form#form-autosave input[name="username"]').type('a').then(() => {
-      expect(win.sibStore.patch).to.have.callCount(0);
-    });
-    cy.get('solid-form#form-autosave input[name="username"]').blur().then(() => {
-      cy.wait(200).then(() => {
-        expect(win.sibStore.patch).to.have.callCount(1);
+    cy.get('solid-form#form-autosave input[name="username"]')
+      .type('a')
+      .then(() => {
+        expect(win.sibStore.patch).to.have.callCount(0);
+      });
+    cy.get('solid-form#form-autosave input[name="username"]')
+      .blur()
+      .then(() => {
+        cy.wait(200).then(() => {
+          expect(win.sibStore.patch).to.have.callCount(1);
+        });
+      });
+    cy.get('solid-form#form-autosave [data-index="skills0"] button')
+      .click()
+      .then(() => {
+        expect(win.sibStore.patch).to.have.callCount(2);
       });
-    });
-    cy.get('solid-form#form-autosave [data-index="skills0"] button').click().then(() => {
-      expect(win.sibStore.patch).to.have.callCount(2);
-    });
     cy.get('solid-form#form-autosave [data-index="skills1"] select')
-    .select("PHP")
-    .then(() => {
-      cy.wait(200).then(() => {
-        expect(win.sibStore.patch).to.have.callCount(3);
-      })
-    });
+      .select('PHP')
+      .then(() => {
+        cy.wait(200).then(() => {
+          expect(win.sibStore.patch).to.have.callCount(3);
+        });
+      });
 
     // Without autosave, no requests
-    cy.get('solid-form#form-autosave').then(($el) => {
+    cy.get('solid-form#form-autosave').then($el => {
       $el.removeAttr('autosave');
-      cy.get('solid-form#form-autosave input[name="username"]').type('a').blur().then(() => {
-        expect(win.sibStore.patch).to.have.callCount(3);
-      });
+      cy.get('solid-form#form-autosave input[name="username"]')
+        .type('a')
+        .blur()
+        .then(() => {
+          expect(win.sibStore.patch).to.have.callCount(3);
+        });
     });
   });
 
   it('submit-widget attribute', () => {
-    cy.get('solid-form#form-submit-widget').find('input[type="submit"]')
+    cy.get('solid-form#form-submit-widget')
+      .find('input[type="submit"]')
       .should('not.exist');
-    cy.get('solid-form#form-submit-widget').find('div').children('button[type="submit"]')
+    cy.get('solid-form#form-submit-widget')
+      .find('div')
+      .children('button[type="submit"]')
       .should('exist')
       .and('have.text', 'OK');
   });
 
   it('solid-form-time widget with attributes', () => {
     cy.spy(win.sibStore, 'post');
-    cy.get('solid-form#time-widget').find('input[name="name"]')
-      .type('webinar');
+    cy.get('solid-form#time-widget').find('input[name="name"]').type('webinar');
     // Check min attribute consideration
-    cy.get('solid-form#time-widget').find('input[type="time"]')
-      .type('11:00');
-    cy.get('solid-form#time-widget').find('input[type="submit"]')
-      .click().then(() => {
+    cy.get('solid-form#time-widget').find('input[type="time"]').type('11:00');
+    cy.get('solid-form#time-widget')
+      .find('input[type="submit"]')
+      .click()
+      .then(() => {
         expect(win.sibStore.post).not.be.called;
       });
     // Check max attribute consideration
-    cy.get('solid-form#time-widget').find('input[type="time"]')
-      .type('16:00');
-    cy.get('solid-form#time-widget').find('input[type="submit"]')
-      .click().then(() => {
+    cy.get('solid-form#time-widget').find('input[type="time"]').type('16:00');
+    cy.get('solid-form#time-widget')
+      .find('input[type="submit"]')
+      .click()
+      .then(() => {
         expect(win.sibStore.post).not.be.called;
       });
     // Check step attribute consideration
-    cy.get('solid-form#time-widget').find('input[type="time"]')
-      .type('13:10');
-    cy.get('solid-form#time-widget').find('input[type="submit"]')
-      .click().then(() => {
+    cy.get('solid-form#time-widget').find('input[type="time"]').type('13:10');
+    cy.get('solid-form#time-widget')
+      .find('input[type="submit"]')
+      .click()
+      .then(() => {
         expect(win.sibStore.post).not.be.called;
       });
-    cy.get('solid-form#time-widget').find('input[type="time"]')
-      .type('13:00');
-    cy.get('solid-form#time-widget').find('input[type="submit"]')
-      .click().then(() => {
+    cy.get('solid-form#time-widget').find('input[type="time"]').type('13:00');
+    cy.get('solid-form#time-widget')
+      .find('input[type="submit"]')
+      .click()
+      .then(() => {
         expect(win.sibStore.post).to.be.called;
       });
   });
 
   it('minlength attribute', () => {
     cy.spy(win.sibStore, 'post');
-    cy.get('solid-form#minlength').find('input[type="text"]')
+    cy.get('solid-form#minlength')
+      .find('input[type="text"]')
       .type('{selectall}Sacha');
-    cy.get('solid-form#minlength').find('input[type="submit"]').click()
+    cy.get('solid-form#minlength')
+      .find('input[type="submit"]')
+      .click()
       .then(() => {
         expect(win.sibStore.post).not.be.called;
       });
   });
 
   it('class-submit-button attribute', () => {
-    cy.get('solid-form#class-submit-button > form').find('div')
+    cy.get('solid-form#class-submit-button > form')
+      .find('div')
       .should('have.attr', 'class', 'submitB-class')
-      .find('input[type="submit"]').should('exist');
-    cy.get('solid-form#class-submit-button2 > form').find('div')
+      .find('input[type="submit"]')
+      .should('exist');
+    cy.get('solid-form#class-submit-button2 > form')
+      .find('div')
       .should('have.attr', 'class', 'submitB-class2')
-      .find('button').should('exist');
+      .find('button')
+      .should('exist');
   });
-})
+});
diff --git a/cypress/e2e/e2e/solid-lang.cy.ts b/cypress/e2e/e2e/solid-lang.cy.ts
index 742fbfbcab6c2c97099ba3020a72e2b35bfa03e3..b35bf7cceda26921ff252415834bf47120990740 100644
--- a/cypress/e2e/e2e/solid-lang.cy.ts
+++ b/cypress/e2e/e2e/solid-lang.cy.ts
@@ -1,22 +1,24 @@
-describe('solid-lang', function() {
+describe('solid-lang', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/solid-lang.html')
+    cy.visit('/examples/e2e/solid-lang.html');
   });
-  
+
   it('test solid-lang', () => {
     // mark in window object to show reload
-    cy.window().then((w: any) => w.beforeReload = true)
-    
-    // initilization of a property
-    cy.window().should('have.prop', 'beforeReload', true)
-    
-    
-    cy.contains('English').click().should(() => {
-      expect(localStorage.getItem('language')).to.eq('en')
+    cy.window().then((w: any) => {
+      w.beforeReload = true;
     });
 
-    // reload verification : if no property, it confirms the page reload
-    cy.window().should('not.have.prop', 'beforeReload')
-  })
-})
+    // initilization of a property
+    cy.window().should('have.prop', 'beforeReload', true);
 
+    cy.contains('English')
+      .click()
+      .should(() => {
+        expect(localStorage.getItem('language')).to.eq('en');
+      });
+
+    // reload verification : if no property, it confirms the page reload
+    cy.window().should('not.have.prop', 'beforeReload');
+  });
+});
diff --git a/cypress/e2e/e2e/solid-map.cy.ts b/cypress/e2e/e2e/solid-map.cy.ts
deleted file mode 100644
index 71468bf0e891599d00198b0e27c0e1dd9e64148f..0000000000000000000000000000000000000000
--- a/cypress/e2e/e2e/solid-map.cy.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-describe('solid-map', function() {
-  this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/solid-map.html')
-  })
-
-  it('display markers', () => {
-    cy.get('#map-1 .leaflet-marker-pane').children().should('have.length', 6)
-  })
-
-  it('display content in popup markers', () => {
-    cy.get('#map-2 .leaflet-marker-pane').children().first().click({force: true})
-    cy.get('#map-2 .leaflet-popup-pane').children().should('have.length', 1)
-    cy.get('#map-2 .leaflet-popup-content solid-display')
-      .should('have.length', 1)
-      .and('have.attr', 'data-src', '/examples/data/map/event-1.jsonld')
-    cy.get('#map-2 .leaflet-popup-content solid-display > div > solid-set-default')
-      .should('have.length', 1)
-      .and('have.attr', 'name', 'infos')
-    cy.get('#map-2 .leaflet-popup-content solid-display > div > solid-set-default[name=infos] > solid-display-value').should('have.length', 2)
-    cy.get('#map-2 .leaflet-popup-content solid-display > div > solid-set-default[name=infos] > solid-display-value[name=name]').contains('Test 1')
-    cy.get('#map-2 .leaflet-popup-content solid-display > div > solid-set-default[name=infos] > solid-display-value[name=category]').contains('showcase event')
-  })
-
-  it('groups markers', () => {
-    cy.get('#map-3 .leaflet-marker-pane .group-meetup').should('have.length', 4)
-    cy.get('#map-3 .leaflet-marker-pane .group-showcaseevent').should('have.length', 2)
-  })
-
-  it('applies attributes', () => {
-    cy.get('#map-4 .leaflet-marker-pane').children().first().click({force: true})
-    cy.get('#map-4 .leaflet-popup-content solid-display-div[name=name]')
-      .should('have.length', 1)
-      .should('have.class', 'test-class-name')
-    cy.get('#map-4 .leaflet-popup-content solid-display-div[name=name] button')
-      .should('have.length', 1)
-      .contains('Modifier')
-      .click()
-    cy.get('#map-4 .leaflet-popup-content solid-display-div[name=name] > div')
-      .should('have.attr', "contenteditable")
-  })
-
-  it('filters markers', () => {
-    cy.get('#filter input[name=category]').type('showcase')
-    cy.get('#map-5 .leaflet-marker-pane').children().should('have.length', 2)
-    cy.get('#map-5 span#counter').contains('2 results')
-    cy.get('#filter input[name=category]').clear().type('mee')
-    cy.get('#map-5 .leaflet-marker-pane').children().should('have.length', 4)
-    cy.get('#map-5 span#counter').contains('4 results')
-  })
-
-  it('markers clusters', () => {
-    cy.get('#map-6 .leaflet-marker-pane').children().should('have.length', 3)
-    cy.get('#map-6 .leaflet-marker-pane').children().eq(2)
-      .find('span').should('contain', '4')
-  })
-
-  it('display federated markers', () => {
-    cy.get('#map-federated .leaflet-marker-pane').children().should('have.length', 7)
-  })
-})
diff --git a/cypress/e2e/e2e/solid-table.cy.ts b/cypress/e2e/e2e/solid-table.cy.ts
index 3c3b9e2c0ad372b3a3bc5d8986c1c091a365d9dc..5cd5789fb41ec8072a59d596a786f1b399f37b51 100644
--- a/cypress/e2e/e2e/solid-table.cy.ts
+++ b/cypress/e2e/e2e/solid-table.cy.ts
@@ -1,7 +1,7 @@
 // TODO: We should make tests run independently of one another
 describe('solid-table', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/solid-table.html')
+    cy.visit('/examples/e2e/solid-table.html');
   });
 
   it('display users', () => {
@@ -26,23 +26,27 @@ describe('solid-table', { testIsolation: false }, function () {
 
       // HEADER
       // Checkbox first
-      .children().eq(0)
+      .children()
+      .eq(0)
       .should('have.length', 1)
       .filter('input[type="checkbox"]')
 
       // Custom label
       .parents('tr')
-      .find('th').eq(1)
+      .find('th')
+      .eq(1)
       .should('contain', 'First Name')
 
       // Default label
       .parents('tr')
-      .find('th').eq(2)
+      .find('th')
+      .eq(2)
       .should('contain', 'last_name')
 
       // FIRST LINE
       .parents('table')
-      .find('tr').eq(1)
+      .find('tr')
+      .eq(1)
       .should('have.attr', 'data-resource', '/examples/data/list/user-3.jsonld')
       .children('td')
       .should('have.length', 5)
@@ -55,13 +59,15 @@ describe('solid-table', { testIsolation: false }, function () {
 
       // First name
       .parents('tr')
-      .find('td').eq(1)
+      .find('td')
+      .eq(1)
       .find('solid-display-value')
       .should('have.text', 'Not A')
 
       // Custom widget
       .parents('tr')
-      .find('td').eq(3)
+      .find('td')
+      .eq(3)
       .find('solid-display-link-mailto')
       .find('a');
   });
@@ -70,46 +76,55 @@ describe('solid-table', { testIsolation: false }, function () {
     cy.get('#table-users')
 
       // Line 2
-      .find('input[type="checkbox"][data-selection]').eq(1)
+      .find('input[type="checkbox"][data-selection]')
+      .eq(1)
       .check()
 
       // Line 3
-      .parents('table').find('input[type="checkbox"][data-selection]').eq(2)
+      .parents('table')
+      .find('input[type="checkbox"][data-selection]')
+      .eq(2)
       .check();
 
     // Check data
     cy.get('#table-users').then($el => {
       expect((<any>$el[0]).component.selectedLines).to.deep.equal([
-        '/examples/data/list/user-2.jsonld', '/examples/data/list/user-4.jsonld'
-      ])
+        '/examples/data/list/user-2.jsonld',
+        '/examples/data/list/user-4.jsonld',
+      ]);
     });
 
     // Select all
-    cy.get('#table-users')
-      .find('input[type="checkbox"]').eq(0).check();
+    cy.get('#table-users').find('input[type="checkbox"]').eq(0).check();
     cy.get('#table-users').then($el => {
       expect((<any>$el[0]).component.selectedLines).to.deep.equal([
-        '/examples/data/list/user-3.jsonld', '/examples/data/list/user-2.jsonld', '/examples/data/list/user-4.jsonld', '/examples/data/list/user-1.jsonld'
-      ])
+        '/examples/data/list/user-3.jsonld',
+        '/examples/data/list/user-2.jsonld',
+        '/examples/data/list/user-4.jsonld',
+        '/examples/data/list/user-1.jsonld',
+      ]);
     });
 
     // Unselect all
-    cy.get('#table-users')
-      .find('input[type="checkbox"]').eq(0).uncheck();
+    cy.get('#table-users').find('input[type="checkbox"]').eq(0).uncheck();
     cy.get('#table-users').then($el => {
-      expect((<any>$el[0]).component.selectedLines).to.deep.equal([])
+      expect((<any>$el[0]).component.selectedLines).to.deep.equal([]);
     });
   });
 
   it('orders lines', () => {
     cy.get('#table-users solid-display-value[name="first_name"]')
-      .eq(0).should('have.text', 'Not A');
+      .eq(0)
+      .should('have.text', 'Not A');
     cy.get('#table-users solid-display-value[name="first_name"]')
-      .eq(1).should('have.text', 'Paris');
+      .eq(1)
+      .should('have.text', 'Paris');
     cy.get('#table-users solid-display-value[name="first_name"]')
-      .eq(2).should('have.text', 'Pierre');
+      .eq(2)
+      .should('have.text', 'Pierre');
     cy.get('#table-users solid-display-value[name="first_name"]')
-      .eq(3).should('have.text', 'Test');
+      .eq(3)
+      .should('have.text', 'Test');
   });
 
   it('shows user-1', () => {
@@ -135,28 +150,33 @@ describe('solid-table', { testIsolation: false }, function () {
       .find('solid-display-value')
       .should('have.text', 'Test')
       // Last name
-      .parents('tr').find('td')
+      .parents('tr')
+      .find('td')
       .eq(1)
       .find('solid-display-value')
       .should('have.text', 'User')
       // email
-      .parents('tr').find('td')
+      .parents('tr')
+      .find('td')
       .eq(2)
       .find('solid-display-value')
       .should('have.text', 'test-user@example.com')
       // username
-      .parents('tr').find('td')
+      .parents('tr')
+      .find('td')
       .eq(3)
       .find('solid-display-value')
-      .should('have.text', 'admin')
+      .should('have.text', 'admin');
   });
 
   it('makes cells editable', () => {
     cy.get('#table-users-editable')
-      .find('tr').eq(0)
+      .find('tr')
+      .eq(0)
 
       // first_name
-      .find('td').eq(0)
+      .find('td')
+      .eq(0)
       .find('solid-form')
       .should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld')
       .and('have.attr', 'fields', 'first_name')
@@ -165,8 +185,10 @@ describe('solid-table', { testIsolation: false }, function () {
       .should('have.value', 'Test')
 
       // last_name
-      .parents('tr').eq(0)
-      .find('td').eq(1)
+      .parents('tr')
+      .eq(0)
+      .find('td')
+      .eq(1)
       .find('solid-form')
       .should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld')
       .and('have.attr', 'fields', 'last_name')
@@ -174,8 +196,10 @@ describe('solid-table', { testIsolation: false }, function () {
       .and('have.attr', 'partial', '')
 
       // email
-      .parents('tr').eq(0)
-      .find('td').eq(2)
+      .parents('tr')
+      .eq(0)
+      .find('td')
+      .eq(2)
       .find('solid-form')
       .should('have.attr', 'data-src', '/examples/data/list/user-1.jsonld')
       .and('have.attr', 'fields', 'email')
@@ -189,18 +213,22 @@ describe('solid-table', { testIsolation: false }, function () {
     cy.get('#table-skills')
 
       // Line 2 (CSS)
-      .find('input[type="checkbox"][data-selection]').eq(1)
+      .find('input[type="checkbox"][data-selection]')
+      .eq(1)
       .check()
 
       // Line 3 (Javascript)
-      .parents('table').find('input[type="checkbox"][data-selection]').eq(2)
+      .parents('table')
+      .find('input[type="checkbox"][data-selection]')
+      .eq(2)
       .check();
 
     // Check data
     cy.get('#table-skills').then($el => {
       expect((<any>$el[0]).component.selectedLines).to.deep.equal([
-        '/examples/data/list/skill-2.jsonld', '/examples/data/list/skill-3.jsonld'
-      ])
+        '/examples/data/list/skill-2.jsonld',
+        '/examples/data/list/skill-3.jsonld',
+      ]);
     });
 
     // Order list
@@ -209,112 +237,132 @@ describe('solid-table', { testIsolation: false }, function () {
     // Check data
     cy.get('#table-skills').then($el => {
       expect((<any>$el[0]).component.selectedLines).to.deep.equal([
-        '/examples/data/list/skill-2.jsonld', '/examples/data/list/skill-3.jsonld'
-      ])
+        '/examples/data/list/skill-2.jsonld',
+        '/examples/data/list/skill-3.jsonld',
+      ]);
     });
 
     cy.get('#table-skills')
 
       // Line 1 (CSS)
-      .find('input[type="checkbox"][data-selection]').eq(0)
+      .find('input[type="checkbox"][data-selection]')
+      .eq(0)
       .should('be.checked')
 
       // Line 2 (DevOps)
-      .parents('table').find('input[type="checkbox"][data-selection]').eq(1)
+      .parents('table')
+      .find('input[type="checkbox"][data-selection]')
+      .eq(1)
       .should('not.be.checked')
 
       // Line 3 (Git)
-      .parents('table').find('input[type="checkbox"][data-selection]').eq(2)
+      .parents('table')
+      .find('input[type="checkbox"][data-selection]')
+      .eq(2)
       .should('not.be.checked')
 
       // Line 5 (Javascript)
-      .parents('table').find('input[type="checkbox"][data-selection]').eq(4)
-      .should('be.checked')
+      .parents('table')
+      .find('input[type="checkbox"][data-selection]')
+      .eq(4)
+      .should('be.checked');
   });
 
   it('numbers displayed', () => {
     cy.get('#table-skills')
       // Check numbers displayed
-      .find('solid-display-value[name="order"]').eq(0)
-      .should('be.visible').and('contain', '5');
+      .find('solid-display-value[name="order"]')
+      .eq(0)
+      .should('be.visible')
+      .and('contain', '5');
   });
 
-
   it('grouped ordered tables', () => {
-    cy.get('#grouped-table')
-    .within(() => {
+    cy.get('#grouped-table').within(() => {
       cy.get('solid-group-default').should('have.length', 4);
       cy.get('solid-group-default').each((item, index) => {
         if (index === 0) {
-          cy.wrap(item).find('span').contains('Opéra3')
+          cy.wrap(item).find('span').contains('Opéra3');
         }
         if (index === 1) {
-          cy.wrap(item).find('span').contains('Opéra2')
+          cy.wrap(item).find('span').contains('Opéra2');
         }
         if (index === 2) {
-          cy.wrap(item).find('span').contains('Opéra')
+          cy.wrap(item).find('span').contains('Opéra');
         }
-      }); 
+      });
     });
 
-    cy.get('#grouped-table-year-desc')
-    .within(() => {
+    cy.get('#grouped-table-year-desc').within(() => {
       cy.get('solid-group-default').should('have.length', 4);
       cy.get('solid-group-default').each((item, index) => {
         if (index === 0) {
-          cy.wrap(item).find('span').contains('2020')
+          cy.wrap(item).find('span').contains('2020');
         }
         if (index === 1) {
-          cy.wrap(item).find('span').contains('2019')
+          cy.wrap(item).find('span').contains('2019');
         }
         if (index === 2) {
-          cy.wrap(item).find('span').contains('2017')
+          cy.wrap(item).find('span').contains('2017');
         }
         if (index === 3) {
-          cy.wrap(item).find('span').contains('2015')
+          cy.wrap(item).find('span').contains('2015');
         }
-      }); 
+      });
     });
 
-    cy.get('#grouped-table-year-asc')
-    .within(() => {
+    cy.get('#grouped-table-year-asc').within(() => {
       cy.get('solid-group-default').should('have.length', 4);
       cy.get('solid-group-default').each((item, index) => {
         if (index === 0) {
-          cy.wrap(item).find('span').contains('2015')
+          cy.wrap(item).find('span').contains('2015');
         }
         if (index === 1) {
-          cy.wrap(item).find('span').contains('2017')
+          cy.wrap(item).find('span').contains('2017');
         }
         if (index === 2) {
-          cy.wrap(item).find('span').contains('2019')
+          cy.wrap(item).find('span').contains('2019');
         }
         if (index === 3) {
-          cy.wrap(item).find('span').contains('2020')
+          cy.wrap(item).find('span').contains('2020');
         }
-      }); 
+      });
     });
 
-    cy.get('#grouped-table-date-asc')
-    .within(() => {
+    cy.get('#grouped-table-date-desc').within(() => {
       cy.get('solid-group-default').should('have.length', 4);
       cy.get('solid-group-default').each((item, index) => {
         if (index === 0) {
-          cy.wrap(item).find('span').contains('2020-07-09')
+          cy.wrap(item).find('span').contains('2020-07-09');
         }
         if (index === 1) {
-          cy.wrap(item).find('span').contains('2020-05-10')
+          cy.wrap(item).find('span').contains('2020-05-10');
         }
         if (index === 2) {
-          cy.wrap(item).find('span').contains('2017-05-10')
+          cy.wrap(item).find('span').contains('2017-05-10');
         }
         if (index === 3) {
-          cy.wrap(item).find('span').contains('2015-05-10')
+          cy.wrap(item).find('span').contains('2015-05-10');
         }
-      }); 
+      });
     });
 
-
+    cy.get('#grouped-table-date-asc').within(() => {
+      cy.get('solid-group-default').should('have.length', 4);
+      cy.get('solid-group-default').each((item, index) => {
+        if (index === 0) {
+          cy.wrap(item).find('span').contains('2015-05-10');
+        }
+        if (index === 1) {
+          cy.wrap(item).find('span').contains('2017-05-10');
+        }
+        if (index === 2) {
+          cy.wrap(item).find('span').contains('2020-05-10');
+        }
+        if (index === 3) {
+          cy.wrap(item).find('span').contains('2020-07-09');
+        }
+      });
+    });
   });
-
-})
\ No newline at end of file
+});
diff --git a/cypress/e2e/e2e/solid-widget.cy.ts b/cypress/e2e/e2e/solid-widget.cy.ts
index 6800e7be61c8cba327daab412d6193bf3c463a24..57f000efac78a92dcd80de313b33be67ef002c2f 100644
--- a/cypress/e2e/e2e/solid-widget.cy.ts
+++ b/cypress/e2e/e2e/solid-widget.cy.ts
@@ -1,7 +1,7 @@
 // TODO: We should make tests run independently of one another
 describe('solid-widget', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/solid-widget.html')
+    cy.visit('/examples/e2e/solid-widget.html');
   });
 
   // Display
@@ -45,7 +45,6 @@ describe('solid-widget', { testIsolation: false }, function () {
     cy.get('#display-5')
       .find('custom-widget-5 span[name=value]')
       .should('have.text', 'next-view');
-
   });
 
   // Form
@@ -57,36 +56,45 @@ describe('solid-widget', { testIsolation: false }, function () {
     cy.get('#form-1').then($el => {
       return (<any>$el[0]).component.getFormValue().then(res => {
         expect(res).to.deep.equal({
-          "email": "new-email@example.com"
-        })
-      })
+          email: 'new-email@example.com',
+        });
+      });
     });
   });
 
   it('form edition', () => {
-    cy.get('#form-2')
-      .find('custom-form-widget-2 input');
+    cy.get('#form-2').find('custom-form-widget-2 input');
 
     cy.get('#form-2').then($el => {
       return (<any>$el[0]).component.getFormValue().then(res => {
         expect(res).to.deep.equal({
-          "email": "test-user@example.com",
-          "@id": "/examples/data/list/user-1.jsonld",
-        })
-      })
+          email: 'test-user@example.com',
+          '@id': '/examples/data/list/user-1.jsonld',
+        });
+      });
     });
   });
 
   it('form nested', () => {
     cy.get('#form-3')
-      .find('custom-form-widget-3').eq(0)
+      .find('custom-form-widget-3')
+      .eq(0)
       .find('solid-form')
-      .should('have.attr', 'data-src', '/examples/data/nested-forms/batch-1.jsonld');
+      .should(
+        'have.attr',
+        'data-src',
+        '/examples/data/nested-forms/batch-1.jsonld',
+      );
 
     cy.get('#form-3')
-      .find('custom-form-widget-3').eq(1)
+      .find('custom-form-widget-3')
+      .eq(1)
       .find('solid-form')
-      .should('have.attr', 'data-src', '/examples/data/nested-forms/batch-2.jsonld')
+      .should(
+        'have.attr',
+        'data-src',
+        '/examples/data/nested-forms/batch-2.jsonld',
+      )
       .find('input[name=title]')
       .type(' automatique');
 
@@ -94,21 +102,22 @@ describe('solid-widget', { testIsolation: false }, function () {
       return (<any>$el[0]).component.getFormValue().then(res => {
         expect(res).to.deep.equal({
           batches: {
-            "ldp:contains": [
+            'ldp:contains': [
               {
-                title: "Développement",
-                "@id": "/examples/data/nested-forms/batch-1.jsonld"
+                title: 'Développement',
+                '@id': '/examples/data/nested-forms/batch-1.jsonld',
               },
               {
-                title: "Déploiement automatique",
-                "@id": "/examples/data/nested-forms/batch-2.jsonld"
-              }
+                title: 'Déploiement automatique',
+                '@id': '/examples/data/nested-forms/batch-2.jsonld',
+              },
             ],
-            "@id": "/examples/data/nested-forms/customer-invoice-1-batches.jsonld",
+            '@id':
+              '/examples/data/nested-forms/customer-invoice-1-batches.jsonld',
           },
-          "@id": "/examples/data/nested-forms/customer-invoice-1.jsonld"
-        })
-      })
+          '@id': '/examples/data/nested-forms/customer-invoice-1.jsonld',
+        });
+      });
     });
   });
 
diff --git a/cypress/e2e/e2e/translation.cy.ts b/cypress/e2e/e2e/translation.cy.ts
index 440a90812c118dfcd0927280cd0dfc94037a68b8..4f5507a6088362c260ca5190d026e72f830ba8f6 100644
--- a/cypress/e2e/e2e/translation.cy.ts
+++ b/cypress/e2e/e2e/translation.cy.ts
@@ -3,86 +3,111 @@ describe('translation', function () {
     cy.visit('/examples/e2e/translation.html', {
       onBeforeLoad(win) {
         Object.defineProperty(win.navigator, 'language', {
-          value: 'fr'
-        })
-      }
+          value: 'fr',
+        });
+      },
     });
   });
 
   it('French translation in validation attributes, submit buttons, autocompletion mixin', () => {
     // french in confirm and buttons
     const stub = cy.stub();
-    cy.on('window:confirm', stub)
+    cy.on('window:confirm', stub);
     cy.get('solid-delete#confirm')
-      .find('button').should('contain', 'Supprimer')
+      .find('button')
+      .should('contain', 'Supprimer')
       .click()
       .then(() => {
-        expect(stub.getCall(0)).to.be.calledWith('Merci de confirmer votre choix');
+        expect(stub.getCall(0)).to.be.calledWith(
+          'Merci de confirmer votre choix',
+        );
       });
     cy.get('solid-form#void-submitbutton')
-      .find('input[type=submit]').should('contain', 'Envoyer');
+      .find('input[type=submit]')
+      .should('contain', 'Envoyer');
 
     // french in dialog, buttons customized
     cy.get('solid-delete#dialog')
-      .find('button').should('contain', 'Delete data');
+      .find('button')
+      .should('contain', 'Delete data');
     cy.get('solid-delete#dialog > dialog')
       .should('contain', 'Merci de confirmer votre choix')
       .and('contain', 'Oui')
       .and('contain', 'Annuler');
     cy.get('solid-form#custom-submitbutton')
-      .find('input[type=submit]').should('contain', 'Send form');
+      .find('input[type=submit]')
+      .should('contain', 'Send form');
 
     // french in autompletion multipleselect
     cy.get('solid-form-search#translation-autocomp')
-      .find('.ss-disabled').should('contain', 'Sélectionner une valeur')
+      .find('.ss-placeholder')
+      .filter(':visible')
+      .should('contain', 'Sélectionner une valeur')
       .click();
-    cy.get('solid-form-search#translation-autocomp')
-      .find('.ss-search').children().should('have.attr', 'placeholder', 'Rechercher')
-      .wait(200).type('00');
-    cy.get('solid-form-search#translation-autocomp')
-      .find('.ss-list').children().contains('Aucun résultat')
+    cy.get('.ss-content')
+      .find('.ss-search')
+      .filter(':visible')
+      .children()
+      .should('have.attr', 'placeholder', 'Rechercher')
+      .wait(200)
+      .type('00');
+    cy.get('.ss-content')
+      .find('.ss-list')
+      .children()
+      .contains('Aucun résultat');
   });
 
   it('English translation in validation attributes, submit buttons, autocompletion mixin', () => {
     cy.get('#en').click();
     // english in confirm and buttons
     const stub = cy.stub();
-    cy.on('window:confirm', stub)
+    cy.on('window:confirm', stub);
     cy.get('solid-delete#confirm')
-      .find('button').should('contain', 'Delete')
+      .find('button')
+      .should('contain', 'Delete')
       .click()
       .then(() => {
         expect(stub.getCall(0)).to.be.calledWith('Please, confirm your choice');
       });
     cy.get('solid-form#void-submitbutton')
-      .find('input[type=submit]').should('contain', 'Submit');
+      .find('input[type=submit]')
+      .should('contain', 'Submit');
 
     // english in dialog, buttons customized
     cy.get('solid-delete#dialog')
-      .find('button').should('contain', 'Delete data');
+      .find('button')
+      .should('contain', 'Delete data');
     cy.get('solid-delete#dialog > dialog')
       .should('contain', 'Please, confirm your choice')
       .and('contain', 'Yes')
       .and('contain', 'Cancel');
     cy.get('solid-form#custom-submitbutton')
-      .find('input[type=submit]').should('contain', 'Send form');
+      .find('input[type=submit]')
+      .should('contain', 'Send form');
 
     // english in autompletion multipleselect
     cy.get('solid-form-search#translation-autocomp')
-      .find('.ss-disabled').should('contain', 'Select a value')
+      .find('.ss-placeholder')
+      .filter(':visible')
+      .should('contain', 'Select a value')
       .click();
-    cy.get('solid-form-search#translation-autocomp')
-      .find('.ss-search').children().should('have.attr', 'placeholder', 'Search')
-      .wait(200).type('00');
-    cy.get('solid-form-search#translation-autocomp')
-      .find('.ss-list').children().contains('No result')
+    cy.get('.ss-content')
+      .find('.ss-search')
+      .filter(':visible')
+      .children()
+      .should('have.attr', 'placeholder', 'Search')
+      .wait(200)
+      .type('00');
+    cy.get('.ss-content').find('.ss-list').children().contains('No result');
   });
 
   it('Missing translation file', () => {
     cy.get('#fr').find('button').click();
-    cy.get('solid-delete#confirm').find('button').should('contain', 'Supprimer');
+    cy.get('solid-delete#confirm')
+      .find('button')
+      .should('contain', 'Supprimer');
     // Asking to get a missing file, English loaded by default
     cy.get('#it').find('button').click();
     cy.get('solid-delete#confirm').find('button').should('contain', 'Delete');
-  })
-});
\ No newline at end of file
+  });
+});
diff --git a/cypress/e2e/e2e/validation.cy.ts b/cypress/e2e/e2e/validation.cy.ts
index 00cbac81472cf7eccdc280c6058a94549fb799a5..7afb4d815588229f327b7b91aa1cafa5aed60d98 100644
--- a/cypress/e2e/e2e/validation.cy.ts
+++ b/cypress/e2e/e2e/validation.cy.ts
@@ -5,9 +5,9 @@ describe('validation', function () {
     cy.visit('/examples/e2e/validation.html', {
       onBeforeLoad(win) {
         Object.defineProperty(win.navigator, 'language', {
-          value: 'en'
-        })
-      }
+          value: 'en',
+        });
+      },
     });
     cy.window().then(w => {
       win = w;
@@ -17,105 +17,136 @@ describe('validation', function () {
 
   it('confirm popup on solid-delete', () => {
     const stub = cy.stub();
-    cy.on('window:confirm', stub)
+    cy.on('window:confirm', stub);
     cy.get('solid-delete#confirm')
       .should('have.attr', 'confirmation-type', 'confirm')
-      .and('have.attr', 'confirmation-message')
+      .and('have.attr', 'confirmation-message');
     cy.get('solid-delete#confirm')
       .find('button')
       .click()
       .then(() => {
-        expect(stub.getCall(0)).to.be.calledWith('Are you sure ?')
+        expect(stub.getCall(0)).to.be.calledWith('Are you sure ?');
       });
   });
 
   it('confirm popup on solid-form', () => {
     const stub = cy.stub();
-    cy.on('window:confirm', stub)
+    cy.on('window:confirm', stub);
     cy.get('solid-form#confirm')
       .find('input[type=submit]')
       .click()
       .then(() => {
-        expect(stub.getCall(0)).to.be.calledWith('Please, confirm your choice') //message by default displayed in English translation
+        expect(stub.getCall(0)).to.be.calledWith('Please, confirm your choice'); //message by default displayed in English translation
       });
   });
 
   it('dialog popup on solid-form', () => {
     // simple dialog popup
     cy.get('solid-form#simple-dialog > dialog')
-      .find('p').should('contain', 'Please, confirm your choice')//message by default displayed in English translation
-    cy.get('solid-form#simple-dialog > dialog > div').children().eq(0)
-      .should('contain', 'Yes')
-    cy.get('solid-form#simple-dialog > dialog > div').children().eq(1)
-      .should('contain', 'Cancel')
+      .find('p')
+      .should('contain', 'Please, confirm your choice'); //message by default displayed in English translation
+    cy.get('solid-form#simple-dialog > dialog > div')
+      .children()
+      .eq(0)
+      .should('contain', 'Yes');
+    cy.get('solid-form#simple-dialog > dialog > div')
+      .children()
+      .eq(1)
+      .should('contain', 'Cancel');
     cy.get('solid-form#simple-dialog > dialog')
-      .find('button').should('have.not.attr', 'class')
+      .find('button')
+      .should('have.not.attr', 'class');
     //custom dialog popup
     cy.get('solid-form#custom-dialog > dialog')
-      .find('p').should('contain', 'Custom message : Are you sure ?')
-    cy.get('solid-form#custom-dialog > dialog > div').children().eq(0)
+      .find('p')
+      .should('contain', 'Custom message : Are you sure ?');
+    cy.get('solid-form#custom-dialog > dialog > div')
+      .children()
+      .eq(0)
       .should('contain', 'Certainly')
-      .and('have.attr', 'class', 'submit-button')
-    cy.get('solid-form#custom-dialog > dialog > div').children().eq(1)
+      .and('have.attr', 'class', 'submit-button');
+    cy.get('solid-form#custom-dialog > dialog > div')
+      .children()
+      .eq(1)
       .should('contain', 'Quit')
-      .and('have.attr', 'class', 'cancel-button')
+      .and('have.attr', 'class', 'cancel-button');
   });
 
   it('actions on dialog popup', () => {
     //dialog modal correctly opened and closed with buttons
-    cy.get('solid-form#custom-dialog > form > solid-form-label-text > input')
-      .type('{selectall}Presentation')
-    cy.get('solid-form#custom-dialog > form > div > input').click()
-    cy.get('solid-form#custom-dialog > dialog')
-      .should('have.attr', 'open')
+    cy.get(
+      'solid-form#custom-dialog > form > solid-form-label-text > input',
+    ).type('{selectall}Presentation');
+    cy.get('solid-form#custom-dialog > form > div > input').click();
+    cy.get('solid-form#custom-dialog > dialog').should('have.attr', 'open');
 
-    cy.get('solid-form#custom-dialog > dialog > div').children().eq(1).click()
-    cy.get('solid-form#custom-dialog > dialog')
-      .should('not.have.attr', 'open')
-    cy.get('solid-form#custom-dialog > form > div > input').click()
-    cy.get('solid-form#custom-dialog > dialog')
-      .should('have.attr', 'open')
+    cy.get('solid-form#custom-dialog > dialog > div').children().eq(1).click();
+    cy.get('solid-form#custom-dialog > dialog').should('not.have.attr', 'open');
+    cy.get('solid-form#custom-dialog > form > div > input').click();
+    cy.get('solid-form#custom-dialog > dialog').should('have.attr', 'open');
 
     //form well sent, data well deleted
     cy.spy(win.sibStore, 'post');
-    cy.get('solid-form#custom-dialog > dialog > div').children().eq(0).click().then(() => {
-      expect(win.sibStore.post).to.be.called;
-      cy.get('solid-form#custom-dialog > dialog')
-        .should('not.have.attr', 'open')
-    });
+    cy.get('solid-form#custom-dialog > dialog > div')
+      .children()
+      .eq(0)
+      .click()
+      .then(() => {
+        expect(win.sibStore.post).to.be.called;
+        cy.get('solid-form#custom-dialog > dialog').should(
+          'not.have.attr',
+          'open',
+        );
+      });
     cy.spy(win.sibStore, 'delete');
-    cy.get('solid-delete#delete-data > dialog > div').children().eq(0).click({ force: true }).then(() => {
-      expect(win.sibStore.delete).to.be.called;
-      cy.get('solid-delete#delete-data > dialog')
-        .should('not.have.attr', 'open')
-    });
+    cy.get('solid-delete#delete-data > dialog > div')
+      .children()
+      .eq(0)
+      .click({ force: true })
+      .then(() => {
+        expect(win.sibStore.delete).to.be.called;
+        cy.get('solid-delete#delete-data > dialog').should(
+          'not.have.attr',
+          'open',
+        );
+      });
   });
 
   it('confirmation-type missing', () => {
     cy.spy(cnsl, 'warn');
-    cy.get('solid-delete#missing-type').find('button').click().then(() => {
-      expect(cnsl.warn).to.be.called;
-    });
+    cy.get('solid-delete#missing-type')
+      .find('button')
+      .click()
+      .then(() => {
+        expect(cnsl.warn).to.be.called;
+      });
   });
 
   it('confirmation widget', () => {
     cy.get('solid-form#confirmation-widget')
       .find('dialog')
-      .find('my-widget-confirm').should('have.attr', 'value', '/examples/data/project.jsonld')
-      .find('solid-display-value').should('have.attr', 'value', 'Envoyer une fusée')
-    cy.get('solid-form#confirmation-widget > form > div > input')
-      .click()
+      .find('my-widget-confirm')
+      .should('have.attr', 'value', '/examples/data/project.jsonld')
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Envoyer une fusée');
+    cy.get('solid-form#confirmation-widget > form > div > input').click();
     cy.get('solid-form#confirmation-widget')
-      .find('dialog').should('contain', 'Envoyer une fusée')
-      .find('div').children().eq(1).click();
+      .find('dialog')
+      .should('contain', 'Envoyer une fusée')
+      .find('div')
+      .children()
+      .eq(1)
+      .click();
 
     cy.get('solid-delete#confirmation-widget')
       .find('dialog')
-      .find('my-widget-confirm2').should('have.attr', 'value', '/examples/data/project.jsonld')
-      .find('solid-display-value').should('have.attr', 'value', 'Envoyer une fusée')
-    cy.get('solid-delete#confirmation-widget > button')
-      .click()
+      .find('my-widget-confirm2')
+      .should('have.attr', 'value', '/examples/data/project.jsonld')
+      .find('solid-display-value')
+      .should('have.attr', 'value', 'Envoyer une fusée');
+    cy.get('solid-delete#confirmation-widget > button').click();
     cy.get('solid-delete#confirmation-widget')
-      .find('dialog').should('contain', 'Envoyer une fusée')
-  })
-});
\ No newline at end of file
+      .find('dialog')
+      .should('contain', 'Envoyer une fusée');
+  });
+});
diff --git a/cypress/e2e/e2e/widgets-custom.cy.ts b/cypress/e2e/e2e/widgets-custom.cy.ts
index f1785d364fc424284434b8a21058c1ac22d64486..6ab4beefece48a85b52f945c767528e24bfc6bf6 100644
--- a/cypress/e2e/e2e/widgets-custom.cy.ts
+++ b/cypress/e2e/e2e/widgets-custom.cy.ts
@@ -1,7 +1,7 @@
 describe('custom widgets', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/widgets-custom.html')
-  })
+    cy.visit('/examples/e2e/widgets-custom.html');
+  });
 
   it('set value', () => {
     cy.get('solid-display#test1')
@@ -9,12 +9,12 @@ describe('custom widgets', function () {
       .should('have.length', 1)
       .find('h1')
       .should('contain', 'Envoyer une fusée');
-  })
+  });
 
   it('set attributes', () => {
     cy.get('solid-display#test2')
       .find('custom-widget')
       .should('have.length', 1)
-      .and('have.attr', 'class', 'test-class')
-  })
-})
+      .and('have.attr', 'class', 'test-class');
+  });
+});
diff --git a/cypress/e2e/e2e/widgets-display-multiple.cy.ts b/cypress/e2e/e2e/widgets-display-multiple.cy.ts
index 595a285e853a2da45fd4afdc43024b71294fc1dc..a1b8d4d53c53d9d5dda9aab6087ee89de07010bd 100644
--- a/cypress/e2e/e2e/widgets-display-multiple.cy.ts
+++ b/cypress/e2e/e2e/widgets-display-multiple.cy.ts
@@ -1,6 +1,6 @@
-describe('multiple widgets', function() {
+describe('multiple widgets', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/widgets-display-multiple.html')
+    cy.visit('/examples/e2e/widgets-display-multiple.html');
   });
 
   it('solid-display-multiple and empty widget', () => {
@@ -9,14 +9,17 @@ describe('multiple widgets', function() {
       .find('empty-skills')
       .should('contain', 'This username has no skills');
     cy.get('solid-multiple#noskill > solid-display > span')
-      .children().should('have.length', 1);
+      .children()
+      .should('have.length', 1);
 
     cy.get('solid-multiple#skills')
       .should('have.attr', 'empty-widget', 'empty-skills')
-      .find('solid-display-value')
+      .find('solid-display-value');
     cy.get('solid-multiple#skills > solid-display > div')
-      .children().should('have.length', 2);
+      .children()
+      .should('have.length', 2);
     cy.get('solid-multiple#skills > solid-display > span')
-      .children().should('not.exist')
+      .children()
+      .should('not.exist');
   });
-})
+});
diff --git a/cypress/e2e/e2e/widgets-display.cy.ts b/cypress/e2e/e2e/widgets-display.cy.ts
index 3ba5dfd53132bafaa1ea9b7faf093033f7509ffe..dd85fccdce680c01bb937722858f1f6188ea8044 100644
--- a/cypress/e2e/e2e/widgets-display.cy.ts
+++ b/cypress/e2e/e2e/widgets-display.cy.ts
@@ -1,36 +1,36 @@
 describe('display widgets', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/widgets-display.html')
-  })
+    cy.visit('/examples/e2e/widgets-display.html');
+  });
 
   it('solid-display-value', () => {
     cy.get('solid-display-value')
       .should('contain', 'test value 1')
-      .children().should('have.length', 0);
-  })
+      .children()
+      .should('have.length', 0);
+  });
 
   it('solid-display-div', () => {
     cy.get('solid-display-div#test1')
       .should('contain', 'test value 1')
       .find('> div')
       .should('have.length', 1)
-      .should('have.attr', 'name', 'test1')
-  })
+      .should('have.attr', 'name', 'test1');
+  });
 
   it('solid-display-div editable', () => {
-    cy.intercept("PATCH", '**/resource-1.jsonld', {
+    cy.intercept('PATCH', '**/resource-1.jsonld', {
       headers: {
-        contentType: 'application/ld+json'
-      }
-    })
-    cy.intercept("GET", '**/resource-1.jsonld', {
+        contentType: 'application/ld+json',
+      },
+    });
+    cy.intercept('GET', '**/resource-1.jsonld', {
       headers: {
-        contentType: 'application/ld+json'
-      }
-    })
-   
-    cy.get('solid-display-div#test2')
-      .children().should('have.length', 2);
+        contentType: 'application/ld+json',
+      },
+    });
+
+    cy.get('solid-display-div#test2').children().should('have.length', 2);
     cy.get('solid-display-div#test2')
       .find('> div')
       .should('have.attr', 'data-editable', '');
@@ -50,8 +50,8 @@ describe('display widgets', function () {
       .should('have.length', 1)
       .and('have.attr', 'name', 'test1')
       .and('have.attr', 'href', 'http://example.com')
-      .and('contain', 'http://example.com')
-  })
+      .and('contain', 'http://example.com');
+  });
 
   it('solid-display-link-mailto', () => {
     cy.get('solid-display-link-mailto')
@@ -59,19 +59,19 @@ describe('display widgets', function () {
       .should('have.length', 1)
       .and('have.attr', 'name', 'test1')
       .and('have.attr', 'href', 'mailto:http://example.com')
-      .and('contain', 'http://example.com')
-  })
+      .and('contain', 'http://example.com');
+  });
 
   it('solid-display-link-mailto-label', () => {
     cy.get('solid-display-link-mailto-label')
       .find('label')
-      .should('contain', 'mail: ')
+      .should('contain', 'mail: ');
     cy.get('solid-display-link-mailto-label')
       .find('a')
       .should('have.attr', 'name', 'test1')
       .and('have.attr', 'href', 'mailto:http://example.com')
-      .and('contain', 'http://example.com')
-  })
+      .and('contain', 'http://example.com');
+  });
 
   it('solid-display-link-tel', () => {
     cy.get('solid-display-link-tel')
@@ -79,19 +79,19 @@ describe('display widgets', function () {
       .should('have.length', 1)
       .and('have.attr', 'name', 'test1')
       .and('have.attr', 'href', 'tel:http://example.com')
-      .and('contain', 'http://example.com')
-  })
+      .and('contain', 'http://example.com');
+  });
 
   it('solid-display-link-tel-label', () => {
     cy.get('solid-display-link-tel-label')
       .find('label')
-      .should('contain', 'tel: ')
+      .should('contain', 'tel: ');
     cy.get('solid-display-link-tel-label')
       .find('a')
       .should('have.attr', 'name', 'test1')
       .and('have.attr', 'href', 'tel:http://example.com')
-      .and('contain', 'http://example.com')
-  })
+      .and('contain', 'http://example.com');
+  });
 
   it('solid-display-link-blank', () => {
     cy.get('solid-display-link-blank')
@@ -101,19 +101,19 @@ describe('display widgets', function () {
       .and('have.attr', 'href', 'http://example.com')
       .and('have.attr', 'target', '_blank')
       .and('have.attr', 'link-text', 'link text')
-      .and('contain', 'link text')
-  })
-  
+      .and('contain', 'link text');
+  });
+
   it('solid-display-link-blank-label', () => {
     cy.get('solid-display-link-blank-label')
       .find('label')
-      .should('contain', 'blank test: ')
+      .should('contain', 'blank test: ');
     cy.get('solid-display-link-blank-label')
       .find('a')
       .should('have.attr', 'name', 'test1')
       .and('have.attr', 'href', 'http://example.com')
-      .and('contain', 'http://example.com')
-  })
+      .and('contain', 'http://example.com');
+  });
 
   it('solid-display-img', () => {
     cy.get('solid-display-img')
@@ -121,8 +121,8 @@ describe('display widgets', function () {
       .should('have.length', 1)
       .and('have.attr', 'name', 'test1')
       .and('have.attr', 'src', 'test-img.png')
-      .and('have.attr', 'alt', 'alternative text')
-  })
+      .and('have.attr', 'alt', 'alternative text');
+  });
 
   it('solid-display-boolean', () => {
     cy.get('solid-display-boolean[name=test1]')
@@ -131,9 +131,9 @@ describe('display widgets', function () {
       .and('contain', 'Is displayed ?');
     cy.get('solid-display-boolean[name=test2]')
       .find('label')
-      .should('not.exist')
-  })
-  
+      .should('not.exist');
+  });
+
   it('solid-display-label-div', () => {
     cy.get('solid-display-label-div[name=test1]')
       .find('label')
@@ -152,7 +152,7 @@ describe('display widgets', function () {
       .find('> div')
       .should('have.length', 1)
       .and('contain', 'test value 1');
-  })
+  });
 
   it('solid-display-date-div', () => {
     cy.get('solid-display-date-div')
@@ -162,7 +162,7 @@ describe('display widgets', function () {
       .and('contain', '28')
       .and('contain', '5')
       .and('contain', '2020');
-  })
+  });
 
   it('solid-display-datetime-div', () => {
     cy.get('solid-display-datetime-div')
@@ -174,14 +174,14 @@ describe('display widgets', function () {
       .and('contain', '2020')
       .and('contain', '00')
       .and('contain', ':');
-  })
+  });
 
   it('solid-display-multiline-div', () => {
     cy.get('solid-display-multiline-div')
       .find('> div')
       .should('have.length', 1)
-      .and('contain.html', '<br>')
-  })
+      .and('contain.html', '<br>');
+  });
 
   it('solid-multiple', () => {
     cy.get('solid-multiple')
@@ -195,34 +195,36 @@ describe('display widgets', function () {
       .and('contain', 'CSS')
       .and('contain', 'Javascript')
       .and('not.contain', 'DevOps')
-      .and('not.contain', 'HTML')
-  })
+      .and('not.contain', 'HTML');
+  });
 
   it('solid-action', () => {
-    cy.get('solid-action').first()
+    cy.get('solid-action')
+      .first()
       .find('solid-link')
       .should('have.attr', 'data-src', 'resource-1.jsonld')
       .and('have.attr', 'next', 'next-page')
       .and('contain', 'test1');
-  })
+  });
   it('solid-action', () => {
-    cy.get('solid-action').last()
+    cy.get('solid-action')
+      .last()
       .find('solid-link')
       .should('have.attr', 'data-src', 'resource-1.jsonld')
       .and('have.attr', 'next', 'next-page')
       .and('contain', 'link text');
-  })
+  });
 
   it('solid-action-label', () => {
     cy.get('solid-action-label')
       .find('label')
-      .should('contain', 'label solid-action: ')
+      .should('contain', 'label solid-action: ');
     cy.get('solid-action-label')
       .find('solid-link')
       .should('have.attr', 'data-src', 'resource-1.jsonld')
       .and('have.attr', 'next', 'next-page')
       .and('contain', 'test1');
-  })
+  });
 
   it('solid-display-div-markdown', () => {
     cy.get('solid-display-div-markdown')
@@ -231,9 +233,7 @@ describe('display widgets', function () {
     cy.get('solid-display-div-markdown')
       .find('strong')
       .should('contain', 'bold');
-    cy.get('solid-display-div-markdown')
-      .find('em')
-      .should('contain', 'italic');
+    cy.get('solid-display-div-markdown').find('em').should('contain', 'italic');
     cy.get('solid-display-div-markdown')
       .find('a')
       .should('contain', 'link')
@@ -242,40 +242,54 @@ describe('display widgets', function () {
     // Change value to something else
     cy.get('solid-display-div-markdown')
       .invoke('attr', 'value', '**bold** [link](http://corndog.io/)')
-      .find('em').should('not.exist');
+      .find('em')
+      .should('not.exist');
 
     // Change value to empty
     cy.get('solid-display-div-markdown')
       .invoke('attr', 'value', '')
       .find('div[name="test display markdown"]')
-      .children().should('have.length', 0)
+      .children()
+      .should('have.length', 0);
   });
-  
+
   it('solid-display-div-autolink', () => {
-    cy.get('solid-display-div-autolink > div').children()
+    cy.get('solid-display-div-autolink > div')
+      .children()
       .should('have.length', 2);
-    cy.get('solid-display-div-autolink > div').children().eq(0)
+    cy.get('solid-display-div-autolink > div')
+      .children()
+      .eq(0)
       .should('have.attr', 'href', 'http://www.w3.org');
-    cy.get('solid-display-div-autolink > div').children().eq(1)
-      .should('have.attr', 'href', 'http://www.window-swap.com')
+    cy.get('solid-display-div-autolink > div')
+      .children()
+      .eq(1)
+      .should('have.attr', 'href', 'http://www.window-swap.com');
   });
 
   it('solid-display-value-oembed', () => {
-    cy.intercept("GET", 'https://ldp-server2.test/oembed/', {
+    cy.intercept('GET', 'https://ldp-server2.test/oembed/', {
       headers: {
-        contentType: 'application/ld+json'
-      }, fixture: "oembed.jsonld"
+        contentType: 'application/ld+json',
+      },
+      fixture: 'oembed.jsonld',
+    });
 
-    })
-   
-    cy.get('solid-display-value-oembed').children()
-      .should('have.length', 1);
+    cy.get('solid-display-value-oembed').children().should('have.length', 1);
     cy.get('solid-display-value-oembed > iframe')
-      .should('have.attr', 'src', 'https://www.youtube.com/embed/M3r2XDceM6A?feature=oembed')
+      .should(
+        'have.attr',
+        'src',
+        'https://www.youtube.com/embed/M3r2XDceM6A?feature=oembed',
+      )
       .and('have.attr', 'width', '200')
       .and('have.attr', 'height', '113')
       .and('have.attr', 'frameborder', '0')
-      .and('have.attr', 'allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share')
+      .and(
+        'have.attr',
+        'allow',
+        'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share',
+      )
       .and('have.attr', 'allowfullscreen');
   });
-})
+});
diff --git a/cypress/e2e/e2e/widgets-form-multiple.cy.ts b/cypress/e2e/e2e/widgets-form-multiple.cy.ts
index 8424d9e37ff62a7fc14d9adc9156bb5e4d66c0aa..2851f1306fd5768fd2e9cfe7fea21f361fae6bb9 100644
--- a/cypress/e2e/e2e/widgets-form-multiple.cy.ts
+++ b/cypress/e2e/e2e/widgets-form-multiple.cy.ts
@@ -1,12 +1,11 @@
 // TODO: We should make tests run independently of one another
 describe('multiple widgets', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/widgets-form-multiple.html')
-  })
+    cy.visit('/examples/e2e/widgets-form-multiple.html');
+  });
 
   it('solid-form-multiple', () => {
-    cy.get('solid-form-multiple#test1')
-      .children().should('have.length', 1);
+    cy.get('solid-form-multiple#test1').children().should('have.length', 1);
 
     cy.get('solid-form-multiple#test1')
       .find('button')
@@ -14,18 +13,18 @@ describe('multiple widgets', { testIsolation: false }, function () {
       .click(); // add a line
 
     // Check new line
-    cy.get('solid-form-multiple#test1')
-      .children().should('have.length', 2);
+    cy.get('solid-form-multiple#test1').children().should('have.length', 2);
 
     cy.get('solid-form-multiple#test1 > div[data-index="test0"]')
-      .children().should('have.length', 2);
+      .children()
+      .should('have.length', 2);
 
     cy.get('solid-form-multiple#test1 > div[data-index="test0"]')
       .find('solid-form-text')
       .should('have.attr', 'data-holder', '')
       .should('have.attr', 'value', '')
       .should('have.attr', 'range', '')
-      .should('have.attr', 'name', 'test')
+      .should('have.attr', 'name', 'test');
 
     // Remove line
     cy.get('solid-form-multiple#test1 > div[data-index="test0"]')
@@ -33,22 +32,21 @@ describe('multiple widgets', { testIsolation: false }, function () {
       .should('contain', '×')
       .click();
 
-    cy.get('solid-form-multiple#test1')
-      .children().should('have.length', 1);
-    cy.get('solid-form-multiple#test1 > div[data-index="test0"]').should('not.exist')
-  })
+    cy.get('solid-form-multiple#test1').children().should('have.length', 1);
+    cy.get('solid-form-multiple#test1 > div[data-index="test0"]').should(
+      'not.exist',
+    );
+  });
 
   it('solid-form-multiple and range', () => {
-    cy.get('solid-form-multiple#test2')
-      .find('button').contains('+')
-      .click(); // add a line
+    cy.get('solid-form-multiple#test2').find('button').contains('+').click(); // add a line
 
     // Check new line
-    cy.get('solid-form-multiple#test2')
-      .children().should('have.length', 2);
+    cy.get('solid-form-multiple#test2').children().should('have.length', 2);
 
     cy.get('solid-form-multiple#test2 > div[data-index="test0"]')
-      .children().should('have.length', 2);
+      .children()
+      .should('have.length', 2);
 
     cy.get('solid-form-multiple#test2 > div[data-index="test0"]') // check attributes
       .find('solid-form-dropdown')
@@ -56,32 +54,43 @@ describe('multiple widgets', { testIsolation: false }, function () {
       .should('have.attr', 'value', '')
       .should('have.attr', 'range', '/examples/data/list/skills.jsonld')
       .should('have.attr', 'data-src', '/examples/data/list/skills.jsonld')
-      .should('have.attr', 'name', 'test')
+      .should('have.attr', 'name', 'test');
 
-    cy.get('solid-form-multiple#test2 > div[data-index="test0"] solid-form-dropdown')
+    cy.get(
+      'solid-form-multiple#test2 > div[data-index="test0"] solid-form-dropdown',
+    )
       .find('select > option') // check options
       .should('have.length', 9)
-      .eq(4).should('contain', 'DevOps');
+      .eq(4)
+      .should('contain', 'DevOps');
 
     // add 2 new lines
     cy.get('solid-form-multiple#test2')
-      .find('button').contains('+')
+      .find('button')
+      .contains('+')
       .click()
       .click();
 
     cy.get('solid-form-multiple#test2') // check children added
-      .children().should('have.length', 4);
+      .children()
+      .should('have.length', 4);
 
-    cy.get('solid-form-multiple#test2 > div[data-index="test1"] solid-form-dropdown')
-      .find('select > option').should('have.length', 9); // check options of children
+    cy.get(
+      'solid-form-multiple#test2 > div[data-index="test1"] solid-form-dropdown',
+    )
+      .find('select > option')
+      .should('have.length', 9); // check options of children
 
     // Select values
-    cy.get('solid-form-multiple#test2 > div[data-index="test0"] solid-form-dropdown > select')
-      .select('DevOps');
-    cy.get('solid-form-multiple#test2 > div[data-index="test1"] solid-form-dropdown > select')
-      .select('HTML');
-    cy.get('solid-form-multiple#test2 > div[data-index="test2"] solid-form-dropdown > select')
-      .select('Javascript');
+    cy.get(
+      'solid-form-multiple#test2 > div[data-index="test0"] solid-form-dropdown > select',
+    ).select('DevOps');
+    cy.get(
+      'solid-form-multiple#test2 > div[data-index="test1"] solid-form-dropdown > select',
+    ).select('HTML');
+    cy.get(
+      'solid-form-multiple#test2 > div[data-index="test2"] solid-form-dropdown > select',
+    ).select('Javascript');
 
     // Remove line
     cy.get('solid-form-multiple#test2 > div[data-index="test0"]')
@@ -90,62 +99,104 @@ describe('multiple widgets', { testIsolation: false }, function () {
       .click();
 
     cy.get('solid-form-multiple#test2') // check children
-      .children().should('have.length', 3);
-    cy.get('solid-form-multiple#test2 > div[data-index="test0"]').should('not.exist')
-    cy.get('solid-form-multiple#test2 > div[data-index="test1"]').should('exist')
-    cy.get('solid-form-multiple#test2 > div[data-index="test2"]').should('exist')
+      .children()
+      .should('have.length', 3);
+    cy.get('solid-form-multiple#test2 > div[data-index="test0"]').should(
+      'not.exist',
+    );
+    cy.get('solid-form-multiple#test2 > div[data-index="test1"]').should(
+      'exist',
+    );
+    cy.get('solid-form-multiple#test2 > div[data-index="test2"]').should(
+      'exist',
+    );
 
     // Check select values still here
-    cy.get('solid-form-multiple#test2 > div[data-index="test1"] select')
-      .should('have.value', '{"@id": "/examples/data/list/skill-1.jsonld"}');
-    cy.get('solid-form-multiple#test2 > div[data-index="test2"] select')
-      .should('have.value', '{"@id": "/examples/data/list/skill-3.jsonld"}');
+    cy.get('solid-form-multiple#test2 > div[data-index="test1"] select').should(
+      'have.value',
+      '{"@id": "/examples/data/list/skill-1.jsonld"}',
+    );
+    cy.get('solid-form-multiple#test2 > div[data-index="test2"] select').should(
+      'have.value',
+      '{"@id": "/examples/data/list/skill-3.jsonld"}',
+    );
 
     // Check widget value
-    cy.get('solid-form-multiple#test2').then($el => { // Check API
+    cy.get('solid-form-multiple#test2').then($el => {
+      // Check API
       expect((<any>$el[0]).component.value).to.equal(''); // value attribute
-      expect((<any>$el[0]).component.getValue()).to.deep.equal(['{"@id": "/examples/data/list/skill-1.jsonld"}', '{"@id": "/examples/data/list/skill-3.jsonld"}']); // form value
+      expect((<any>$el[0]).component.getValue()).to.deep.equal([
+        '{"@id": "/examples/data/list/skill-1.jsonld"}',
+        '{"@id": "/examples/data/list/skill-3.jsonld"}',
+      ]); // form value
     });
-  })
+  });
 
   it('solid-form-multiple and value', () => {
     cy.get('solid-form-multiple#test3') // check data-src
-      .should('have.attr', 'data-src', '/examples/data/list/user-1-skills.jsonld')
-      .children().should('have.length', 3);
-
-    cy.get('solid-form-multiple#test3 > button')
-      .should('contain', 'add');
-    cy.get('solid-form-multiple#test3 > div[data-index="test0"] > button')
-      .should('contain', 'remove');
-
-    cy.get('solid-form-multiple#test3 > div[data-index="test0"] solid-form-dropdown')
-      .should('have.attr', 'value', '/examples/data/list/skill-2.jsonld');
-    cy.get('solid-form-multiple#test3 > div[data-index="test1"] solid-form-dropdown')
-      .should('have.attr', 'value', '/examples/data/list/skill-3.jsonld');
+      .should(
+        'have.attr',
+        'data-src',
+        '/examples/data/list/user-1-skills.jsonld',
+      )
+      .children()
+      .should('have.length', 3);
+
+    cy.get('solid-form-multiple#test3 > button').should('contain', 'add');
+    cy.get(
+      'solid-form-multiple#test3 > div[data-index="test0"] > button',
+    ).should('contain', 'remove');
+
+    cy.get(
+      'solid-form-multiple#test3 > div[data-index="test0"] solid-form-dropdown',
+    ).should('have.attr', 'value', '/examples/data/list/skill-2.jsonld');
+    cy.get(
+      'solid-form-multiple#test3 > div[data-index="test1"] solid-form-dropdown',
+    ).should('have.attr', 'value', '/examples/data/list/skill-3.jsonld');
 
     // Check widget value
-    cy.get('solid-form-multiple#test3').then($el => { // Check API
-      expect((<any>$el[0]).component.value).to.equal('/examples/data/list/user-1-skills.jsonld'); // value attribute
-      expect((<any>$el[0]).component.getValue()).to.deep.equal(['{"@id": "/examples/data/list/skill-2.jsonld"}', '{"@id": "/examples/data/list/skill-3.jsonld"}']); // form value
+    cy.get('solid-form-multiple#test3').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal(
+        '/examples/data/list/user-1-skills.jsonld',
+      ); // value attribute
+      expect((<any>$el[0]).component.getValue()).to.deep.equal([
+        '{"@id": "/examples/data/list/skill-2.jsonld"}',
+        '{"@id": "/examples/data/list/skill-3.jsonld"}',
+      ]); // form value
     });
 
-    cy.get('solid-form-multiple#test3 > div[data-index="test1"] button').click(); //remove line
-
-    cy.get('solid-form-multiple#test3').then($el => { // Check API
-      expect((<any>$el[0]).component.value).to.equal('/examples/data/list/user-1-skills.jsonld'); // value attribute
-      expect((<any>$el[0]).component.getValue()).to.deep.equal(['{"@id": "/examples/data/list/skill-2.jsonld"}']); // form value
+    cy.get(
+      'solid-form-multiple#test3 > div[data-index="test1"] button',
+    ).click(); //remove line
+
+    cy.get('solid-form-multiple#test3').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal(
+        '/examples/data/list/user-1-skills.jsonld',
+      ); // value attribute
+      expect((<any>$el[0]).component.getValue()).to.deep.equal([
+        '{"@id": "/examples/data/list/skill-2.jsonld"}',
+      ]); // form value
     });
-    cy.get('solid-form-multiple#test3 > button')
-      .should('have.class', 'class-addbutton');
-    cy.get('solid-form-multiple#test3 > div[data-index="test0"] > button')
-      .should('have.class', 'class-removebutton');
+    cy.get('solid-form-multiple#test3 > button').should(
+      'have.class',
+      'class-addbutton',
+    );
+    cy.get(
+      'solid-form-multiple#test3 > div[data-index="test0"] > button',
+    ).should('have.class', 'class-removebutton');
   });
 
-
   it('solid-form-multipleselect', () => {
     cy.get('solid-form-multipleselect') // check data-src
-      .should('have.attr', 'data-src', '/examples/data/list/user-1-skills.jsonld')
-      .children().should('have.length', 1);
+      .should(
+        'have.attr',
+        'data-src',
+        '/examples/data/list/user-1-skills.jsonld',
+      )
+      .children()
+      .should('have.length', 1);
 
     cy.get('solid-form-multipleselect')
       .find('solid-form-dropdown')
@@ -153,22 +204,39 @@ describe('multiple widgets', { testIsolation: false }, function () {
       .should('have.attr', 'name', 'test')
       .should('have.attr', 'range', '/examples/data/list/skills.jsonld')
       .should('have.attr', 'data-src', '/examples/data/list/skills.jsonld')
-      .should('have.attr', 'values', '["/examples/data/list/skill-2.jsonld","/examples/data/list/skill-3.jsonld"]');
-
-    cy.get('solid-form-multipleselect').then($el => { // Check API
-      expect((<any>$el[0]).component.value).to.equal('/examples/data/list/user-1-skills.jsonld'); // value attribute
-      expect((<any>$el[0]).component.getValue()).to.deep.equal([{ "@id": "/examples/data/list/skill-2.jsonld" }, { "@id": "/examples/data/list/skill-3.jsonld" }]); // form value
+      .should(
+        'have.attr',
+        'values',
+        '["/examples/data/list/skill-2.jsonld","/examples/data/list/skill-3.jsonld"]',
+      );
+
+    cy.get('solid-form-multipleselect').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal(
+        '/examples/data/list/user-1-skills.jsonld',
+      ); // value attribute
+      expect((<any>$el[0]).component.getValue()).to.deep.equal([
+        { '@id': '/examples/data/list/skill-2.jsonld' },
+        { '@id': '/examples/data/list/skill-3.jsonld' },
+      ]); // form value
     });
 
-    cy.get('solid-form-multipleselect select').select(['CSS', 'Javascript', 'DevOps']);
-    cy.get('solid-form-multipleselect').then($el => { // Check API
-      expect((<any>$el[0]).component.getValue()).to.deep.equal([{ "@id": "/examples/data/list/skill-2.jsonld" }, { "@id": "/examples/data/list/skill-3.jsonld" }, { "@id": "/examples/data/list/skill-4.jsonld" }]); // form value
+    cy.get('solid-form-multipleselect select').select([
+      'CSS',
+      'Javascript',
+      'DevOps',
+    ]);
+    cy.get('solid-form-multipleselect').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.getValue()).to.deep.equal([
+        { '@id': '/examples/data/list/skill-2.jsonld' },
+        { '@id': '/examples/data/list/skill-3.jsonld' },
+        { '@id': '/examples/data/list/skill-4.jsonld' },
+      ]); // form value
     });
   });
 
   it('solid-form-multipleselect-autocompletion', () => {
-    cy.get('solid-form-multipleselect-autocompletion')
-      .children().should('have.length', 1);
     cy.get('solid-form-multipleselect-autocompletion')
       .find('solid-form-dropdown')
       .should('have.attr', 'data-holder', '')
@@ -177,64 +245,86 @@ describe('multiple widgets', { testIsolation: false }, function () {
       .and('have.attr', 'range', '/examples/data/list/skills.jsonld')
       .and('have.attr', 'data-src', '/examples/data/list/skills.jsonld')
       .and('have.attr', 'order-asc', 'name');
-    cy.get('solid-form-multipleselect-autocompletion > solid-form-dropdown')
-      .children().should('have.length', 2);
     cy.get('solid-form-multipleselect-autocompletion > solid-form-dropdown')
       .find('select')
       .should('have.attr', 'data-holder', '')
       .and('have.attr', 'multiple', 'multiple')
       .and('have.attr', 'name', 'test1')
       .and('have.attr', 'style', 'display: none;')
-      .and('have.attr', 'data-ssid');
-    cy.get('solid-form-multipleselect-autocompletion > solid-form-dropdown')
-      .find('> div')
-      .children().should('have.length', 2);
-    cy.get('solid-form-multipleselect-autocompletion > solid-form-dropdown .ss-option').eq(0)
+      .and('have.attr', 'data-id');
+    cy.get(
+      'solid-form-multipleselect-autocompletion > div.ss-content > div.ss-list .ss-option',
+    )
+      .eq(0)
       .should('contain', 'CSS');
     // select values
-    cy.get('solid-form-multipleselect-autocompletion .ss-main').click();
-    cy.get('solid-form-multipleselect-autocompletion .ss-content.ss-open .ss-option').eq(1).click();
-    cy.get('solid-form-multipleselect-autocompletion .ss-option').eq(1)
-      .should('have.class', 'ss-option-selected');
+    cy.get('solid-form-multipleselect-autocompletion .ss-main')
+      .filter(':visible')
+      .eq(0)
+      .click();
+    cy.get(
+      'solid-form-multipleselect-autocompletion .ss-content.ss-open-below .ss-option',
+    )
+      .eq(1)
+      .click();
+    cy.get('solid-form-multipleselect-autocompletion .ss-option')
+      .eq(1)
+      .should('have.class', 'ss-selected');
     cy.get('solid-form-multipleselect-autocompletion .ss-values')
-      .children().should('have.length', 1)
+      .eq(1)
+      .children()
+      .should('have.length', 1)
       .should('contain', 'DevOps');
-    cy.get('solid-form-multipleselect-autocompletion')
-      .find('.ss-add').click();
   });
 
   it('solid-form-autocompletion-placeholder & search attributes', () => {
     // attributes for placeholders and text displayed in SlimSelect
     cy.get('#search-attr')
-      .find('.ss-disabled').contains('Sélectionne une compétence')
-      .click({force: true});
+      .find('.ss-placeholder')
+      .filter(':visible')
+      .contains('Sélectionne une compétence')
+      .click({ force: true });
     cy.get('solid-form-multipleselect-autocompletion-placeholder')
-      .find('.ss-search').children().should('have.attr', 'placeholder', 'Rechercher par clavier')
+      .find('.ss-search')
+      .children()
+      .eq(0)
+      .should('have.attr', 'placeholder', 'Rechercher par clavier')
       .wait(200)
       .type('00');
     cy.get('#search-attr')
-      .find('.ss-list').children().contains('Pas de concordance')
-  })
+      .find('.ss-list')
+      .children()
+      .contains('Pas de concordance');
+  });
 
   it('solid-form-checkboxes', () => {
     cy.get('solid-form-checkboxes#test1')
       .find('solid-form-multicheckbox > div[name=test1]')
-      .children().should('have.length', 8);
-    cy.get('solid-form-checkboxes#test1 input[type=checkbox]').eq(0)
+      .children()
+      .should('have.length', 8);
+    cy.get('solid-form-checkboxes#test1 input[type=checkbox]')
+      .eq(0)
       .should('not.have.attr', 'checked');
-    cy.get('solid-form-checkboxes#test1 input[type=checkbox]').eq(1)
+    cy.get('solid-form-checkboxes#test1 input[type=checkbox]')
+      .eq(1)
       .should('have.attr', 'checked');
-    cy.get('solid-form-checkboxes#test1 input[type=checkbox]').eq(2)
+    cy.get('solid-form-checkboxes#test1 input[type=checkbox]')
+      .eq(2)
       .should('have.attr', 'checked');
-    cy.get('solid-form-checkboxes#test1 input[type=checkbox]').eq(3)
+    cy.get('solid-form-checkboxes#test1 input[type=checkbox]')
+      .eq(3)
       .should('not.have.attr', 'checked');
-    cy.get('solid-form-checkboxes#test1 input[type=checkbox]').eq(4)
+    cy.get('solid-form-checkboxes#test1 input[type=checkbox]')
+      .eq(4)
       .should('not.have.attr', 'checked');
-    cy.get('solid-form-checkboxes#test1 input[type=checkbox]').eq(5)
+    cy.get('solid-form-checkboxes#test1 input[type=checkbox]')
+      .eq(5)
       .should('not.have.attr', 'checked');
-    cy.get('solid-form-checkboxes#test1 input[type=checkbox]').eq(6)
+    cy.get('solid-form-checkboxes#test1 input[type=checkbox]')
+      .eq(6)
       .should('not.have.attr', 'checked');
-    cy.get('solid-form-checkboxes#test1 input[type=checkbox]').eq(7)
+    cy.get('solid-form-checkboxes#test1 input[type=checkbox]')
+      .eq(7)
       .should('not.have.attr', 'checked');
 
     // Get value
@@ -242,8 +332,9 @@ describe('multiple widgets', { testIsolation: false }, function () {
       .find('input[value="html"]')
       .check({ force: true });
 
-    cy.get('solid-form-checkboxes#test2').then($el => { // Check API
+    cy.get('solid-form-checkboxes#test2').then($el => {
+      // Check API
       expect((<any>$el[0]).component.getValue()).to.deep.equal(['html']); // form value
     });
   });
-})
+});
diff --git a/cypress/e2e/e2e/widgets-form.cy.ts b/cypress/e2e/e2e/widgets-form.cy.ts
index e498933041f81348c5734b75ac4cd291d48b969f..9d755fc321eccea2abe87191978d7bba751e757a 100644
--- a/cypress/e2e/e2e/widgets-form.cy.ts
+++ b/cypress/e2e/e2e/widgets-form.cy.ts
@@ -2,12 +2,11 @@
 describe('form widgets', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
     cy.clock(Date.UTC(2020, 11, 15), ['Date']); // Define fake date for start-value="today" test
-    cy.visit('/examples/e2e/widgets-form.html')
-  })
+    cy.visit('/examples/e2e/widgets-form.html');
+  });
 
   it('solid-form-text', () => {
-    cy.get('solid-form-text')
-      .children().should('have.length', 1);
+    cy.get('solid-form-text').children().should('have.length', 1);
 
     cy.get('solid-form-text') // check attributes
       .find('input')
@@ -15,50 +14,54 @@ describe('form widgets', { testIsolation: false }, function () {
       .and('have.attr', 'name', 'test1')
       .and('have.attr', 'value', 'test value 1')
       .and('have.attr', 'data-holder');
-    cy.get('solid-form-text').then($el => { // check API value
+    cy.get('solid-form-text').then($el => {
+      // check API value
       expect((<any>$el[0]).component.getValue()).to.equal('test value 1'); // form value
     });
 
     cy.get('solid-form-text > input') // type value
       .clear()
       .type('new value');
-    cy.get('solid-form-text > input')
-      .and('have.attr', 'value', 'test value 1'); // attr does not change
+    cy.get('solid-form-text > input').and('have.attr', 'value', 'test value 1'); // attr does not change
 
-    cy.get('solid-form-text').then($el => { // Check API
-      expect((<any>$el[0]).component['value']).to.equal('test value 1'); // value attribute
+    cy.get('solid-form-text').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal('test value 1'); // value attribute
       expect((<any>$el[0]).component.getValue()).to.equal('new value'); // form value
     });
 
     cy.get('solid-form-text > input') // clear value
       .clear();
-    cy.get('solid-form-text').then($el => { // Check API
+    cy.get('solid-form-text').then($el => {
+      // Check API
       expect((<any>$el[0]).component.getValue()).to.equal(''); // value attribute
     });
   });
 
   it('solid-form-text + label and placeholders', () => {
+    cy.get('solid-form-text-label').children().should('have.length', 2);
     cy.get('solid-form-text-label')
-      .children().should('have.length', 2);
-    cy.get('solid-form-text-label')
-      .find('> label').should('contain', 'My label');
+      .find('> label')
+      .should('contain', 'My label');
 
+    cy.get('solid-form-text-placeholder').children().should('have.length', 1);
     cy.get('solid-form-text-placeholder')
-      .children().should('have.length', 1);
-    cy.get('solid-form-text-placeholder')
-      .find('> input').should('have.attr', 'placeholder', 'My placeholder');
+      .find('> input')
+      .should('have.attr', 'placeholder', 'My placeholder');
 
     cy.get('solid-form-text-label-placeholder')
-      .children().should('have.length', 2);
+      .children()
+      .should('have.length', 2);
     cy.get('solid-form-text-label-placeholder')
-      .find('> label').should('contain', 'test1');
+      .find('> label')
+      .should('contain', 'test1');
     cy.get('solid-form-text-label-placeholder')
-      .find('> input').should('have.attr', 'placeholder', 'test1');
+      .find('> input')
+      .should('have.attr', 'placeholder', 'test1');
   });
 
   it('solid-form-textarea', () => {
-    cy.get('solid-form-textarea')
-      .children().should('have.length', 1);
+    cy.get('solid-form-textarea').children().should('have.length', 1);
 
     cy.get('solid-form-textarea') // check attributes
       .find('textarea')
@@ -66,7 +69,8 @@ describe('form widgets', { testIsolation: false }, function () {
       .and('have.attr', 'maxlength', '15')
       .and('have.attr', 'data-holder');
 
-    cy.get('solid-form-textarea').then($el => { // check API value
+    cy.get('solid-form-textarea').then($el => {
+      // check API value
       expect((<any>$el[0]).component.getValue()).to.equal('test value 1'); // form value
     });
 
@@ -74,25 +78,24 @@ describe('form widgets', { testIsolation: false }, function () {
       .clear()
       .type('new value');
 
-
-    cy.get('solid-form-textarea').then($el => { // Check API
-      expect((<any>$el[0]).component['value']).to.equal('test value 1'); // value attribute
+    cy.get('solid-form-textarea').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal('test value 1'); // value attribute
       expect((<any>$el[0]).component.getValue()).to.equal('new value'); // form value
     });
 
     cy.get('solid-form-textarea > textarea') // type value
       .clear()
       .type('new value with a maxlength');
-    cy.get('solid-form-textarea').then($el => { // Check API
+    cy.get('solid-form-textarea').then($el => {
+      // Check API
       expect((<any>$el[0]).component.getValue()).to.equal('new value with '); // maxlength attribute effect
     });
-  })
+  });
 
   it('solid-form-checkbox', () => {
-    cy.get('solid-form-checkbox')
-      .children().should('have.length', 1);
-    cy.get('solid-form-checkbox > label')
-      .children().should('have.length', 2);
+    cy.get('solid-form-checkbox').children().should('have.length', 1);
+    cy.get('solid-form-checkbox > label').children().should('have.length', 2);
 
     cy.get('solid-form-checkbox') // check attributes
       .find('input')
@@ -100,30 +103,27 @@ describe('form widgets', { testIsolation: false }, function () {
       .and('have.attr', 'type', 'checkbox')
       .and('have.attr', 'data-holder', '')
       .and('have.attr', 'checked');
-    cy.get('solid-form-checkbox')
-      .find('div')
-      .contains('test1');
-
+    cy.get('solid-form-checkbox').find('div').contains('test1');
 
-    cy.get('solid-form-checkbox').then($el => { // Check API
-      expect((<any>$el[0]).component['value']).to.equal('true'); // value attribute
+    cy.get('solid-form-checkbox').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal('true'); // value attribute
       expect((<any>$el[0]).component.getValue()).to.equal(true); // form value
     });
 
-
     cy.get('solid-form-checkbox') // Change value
-      .find('input').click();
-
+      .find('input')
+      .click();
 
-    cy.get('solid-form-checkbox').then($el => { // Check API
-      expect((<any>$el[0]).component['value']).to.equal('true'); // value attribute
+    cy.get('solid-form-checkbox').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal('true'); // value attribute
       expect((<any>$el[0]).component.getValue()).to.equal(false); // form value
     });
-  })
+  });
 
   it('solid-form-date', () => {
-    cy.get('solid-form-date#test1')
-      .children().should('have.length', 1);
+    cy.get('solid-form-date#test1').children().should('have.length', 1);
     // check attributes
     cy.get('solid-form-date#test1')
       .find('input')
@@ -132,29 +132,27 @@ describe('form widgets', { testIsolation: false }, function () {
       .and('have.attr', 'value', '2020-05-21')
       .and('have.attr', 'data-holder');
     // type value
-    cy.get('solid-form-date#test1 > input')
-      .clear()
-      .type('2020-12-31');
-    cy.get('solid-form-date#test1 > input')
-      .and('have.attr', 'value', '2020-05-21'); // attr does not change
+    cy.get('solid-form-date#test1 > input').clear().type('2020-12-31');
+    cy.get('solid-form-date#test1 > input').and(
+      'have.attr',
+      'value',
+      '2020-05-21',
+    ); // attr does not change
 
     // Check API
     cy.get('solid-form-date#test1').then($el => {
-      expect((<any>$el[0]).component['value']).to.equal('2020-05-21'); // value attribute
+      expect((<any>$el[0]).component.value).to.equal('2020-05-21'); // value attribute
       expect((<any>$el[0]).component.getValue()).to.equal('2020-12-31'); // form value
     });
 
     cy.get('solid-form-date#test2')
       .find('input')
       .and('have.attr', 'value', '2020-05-21');
-    cy.get('solid-form-date#test3')
-      .find('input')
-      .and('have.attr', 'value', '');
-  })
+    cy.get('solid-form-date#test3').find('input').and('have.attr', 'value', '');
+  });
 
   it('solid-form-number', () => {
-    cy.get('solid-form-number')
-      .children().should('have.length', 1);
+    cy.get('solid-form-number').children().should('have.length', 1);
 
     cy.get('solid-form-number') // check attributes
       .find('input')
@@ -165,36 +163,35 @@ describe('form widgets', { testIsolation: false }, function () {
       .and('have.attr', 'max', '7')
       .and('have.attr', 'data-holder');
 
-    cy.get('solid-form-number').then($el => { // check API value
+    cy.get('solid-form-number').then($el => {
+      // check API value
       expect((<any>$el[0]).component.getValue()).to.equal(5); // form value
     });
 
     cy.get('solid-form-number > input') // type value
       .clear()
       .type('8');
-    cy.get('solid-form-number > input')
-      .and('have.attr', 'value', '5'); // attr does not change
-
+    cy.get('solid-form-number > input').and('have.attr', 'value', '5'); // attr does not change
 
-    cy.get('solid-form-number').then($el => { // Check API
-      expect((<any>$el[0]).component['value']).to.equal('5'); // value attribute
+    cy.get('solid-form-number').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal('5'); // value attribute
       expect((<any>$el[0]).component.getValue()).to.equal(8); // form value
     });
 
-    // step attribute 
+    // step attribute
     cy.get('solid-form-number > input') // type value
       .clear()
       .type('{upArrow}{upArrow}{upArrow}');
 
-    cy.get('solid-form-number').then($el => { // check API value
+    cy.get('solid-form-number').then($el => {
+      // check API value
       expect((<any>$el[0]).component.getValue()).to.equal(6); // form value
     });
-
   });
 
   it('solid-form-email', () => {
-    cy.get('solid-form-email')
-      .children().should('have.length', 1);
+    cy.get('solid-form-email').children().should('have.length', 1);
 
     cy.get('solid-form-email') // check attributes
       .find('input')
@@ -203,26 +200,29 @@ describe('form widgets', { testIsolation: false }, function () {
       .and('have.attr', 'value', 'test@test.com')
       .and('have.attr', 'data-holder');
 
-    cy.get('solid-form-email').then($el => { // check API value
+    cy.get('solid-form-email').then($el => {
+      // check API value
       expect((<any>$el[0]).component.getValue()).to.equal('test@test.com'); // form value
     });
 
     cy.get('solid-form-email > input') // type value
       .clear()
       .type('new@example.com');
-    cy.get('solid-form-email > input')
-      .and('have.attr', 'value', 'test@test.com'); // attr does not change
-
-
-    cy.get('solid-form-email').then($el => { // Check API
-      expect((<any>$el[0]).component['value']).to.equal('test@test.com'); // value attribute
+    cy.get('solid-form-email > input').and(
+      'have.attr',
+      'value',
+      'test@test.com',
+    ); // attr does not change
+
+    cy.get('solid-form-email').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal('test@test.com'); // value attribute
       expect((<any>$el[0]).component.getValue()).to.equal('new@example.com'); // form value
     });
   });
 
   it('solid-form-hidden', () => {
-    cy.get('solid-form-hidden')
-      .children().should('have.length', 1);
+    cy.get('solid-form-hidden').children().should('have.length', 1);
 
     cy.get('solid-form-hidden') // check attributes
       .find('input')
@@ -231,113 +231,162 @@ describe('form widgets', { testIsolation: false }, function () {
       .and('have.attr', 'value', 'test value 1')
       .and('have.attr', 'data-holder');
 
-    cy.get('solid-form-hidden').then($el => { // check API value
+    cy.get('solid-form-hidden').then($el => {
+      // check API value
       expect((<any>$el[0]).component.getValue()).to.equal('test value 1'); // form value
     });
 
     cy.get('solid-form-hidden > input') // type value
       .invoke('attr', 'value', 'new value');
 
-    cy.get('solid-form-hidden').then($el => { // Check API
-      expect((<any>$el[0]).component['value']).to.equal('test value 1'); // value attribute
+    cy.get('solid-form-hidden').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal('test value 1'); // value attribute
       expect((<any>$el[0]).component.getValue()).to.equal('new value'); // form value
     });
-  })
+  });
 
   it('solid-form-dropdown', () => {
     // With no initial value
     cy.get('solid-form-dropdown#test1')
       .should('have.attr', 'data-src', '/examples/data/list/skills.jsonld')
-      .children().should('have.length', 1);
+      .children()
+      .should('have.length', 1);
 
     cy.get('solid-form-dropdown#test1') // check attributes
       .find('select')
       .and('have.attr', 'name', 'test1')
       .and('have.attr', 'data-holder', '')
-      .children().and('have.length', 9);
+      .children()
+      .and('have.length', 9);
 
-    cy.get('solid-form-dropdown#test1 > select > option').eq(0) // check options
+    cy.get('solid-form-dropdown#test1 > select > option')
+      .eq(0) // check options
       .should('have.attr', 'value', '')
       .contains('-');
-    cy.get('solid-form-dropdown#test1 > select > option').eq(1)
-      .should('have.attr', 'value', '{"@id": "/examples/data/list/skill-1.jsonld"}')
+    cy.get('solid-form-dropdown#test1 > select > option')
+      .eq(1)
+      .should(
+        'have.attr',
+        'value',
+        '{"@id": "/examples/data/list/skill-1.jsonld"}',
+      )
       .contains('HTML');
 
-    cy.get('solid-form-dropdown#test1').then($el => { // Check API value
+    cy.get('solid-form-dropdown#test1').then($el => {
+      // Check API value
       expect((<any>$el[0]).component.getValue()).to.equal(''); // form value
     });
 
-    cy.get('solid-form-dropdown#test1 > select').select('CSS').should('have.value', '{"@id": "/examples/data/list/skill-2.jsonld"}'); // test change value
+    cy.get('solid-form-dropdown#test1 > select')
+      .select('CSS')
+      .should('have.value', '{"@id": "/examples/data/list/skill-2.jsonld"}'); // test change value
 
-    cy.get('solid-form-dropdown#test1').then($el => { // Check API
-      expect((<any>$el[0]).component['value']).to.equal(''); // value attribute
-      expect((<any>$el[0]).component.getValue()).to.equal('{"@id": "/examples/data/list/skill-2.jsonld"}'); // form value
+    cy.get('solid-form-dropdown#test1').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal(''); // value attribute
+      expect((<any>$el[0]).component.getValue()).to.equal(
+        '{"@id": "/examples/data/list/skill-2.jsonld"}',
+      ); // form value
       expect((<any>$el[0]).component.context).to.be.not.empty; // check storeMixin properties
       expect((<any>$el[0]).component.resourceId).to.be.not.empty; // check storeMixin properties
     });
 
     // With initial value
-    cy.get('solid-form-dropdown#test2 > select').should('have.value', '{"@id": "/examples/data/list/skill-2.jsonld"}');
+    cy.get('solid-form-dropdown#test2 > select').should(
+      'have.value',
+      '{"@id": "/examples/data/list/skill-2.jsonld"}',
+    );
     cy.get('solid-form-dropdown#test2').then($el => {
-      expect((<any>$el[0]).component['value']).to.equal('/examples/data/list/skill-2.jsonld'); // value attribute
-      expect((<any>$el[0]).component.getValue()).to.equal('{"@id": "/examples/data/list/skill-2.jsonld"}'); // form value
+      expect((<any>$el[0]).component.value).to.equal(
+        '/examples/data/list/skill-2.jsonld',
+      ); // value attribute
+      expect((<any>$el[0]).component.getValue()).to.equal(
+        '{"@id": "/examples/data/list/skill-2.jsonld"}',
+      ); // form value
     });
 
     // With optionLabel
-    cy.get('solid-form-dropdown#test3 > select > option').eq(1)
-      .should('have.attr', 'value', '{"@id": "/examples/data/list/skill-1.jsonld"}')
+    cy.get('solid-form-dropdown#test3 > select > option')
+      .eq(1)
+      .should(
+        'have.attr',
+        'value',
+        '{"@id": "/examples/data/list/skill-1.jsonld"}',
+      )
       .contains('/examples/data/list/skill-1.jsonld');
 
     // With multiple
     cy.get('solid-form-dropdown#test4 > select')
       .should('have.attr', 'multiple', 'multiple')
-      .children().should('have.length', 8);
+      .children()
+      .should('have.length', 8);
     cy.get('solid-form-dropdown#test4').then($el => {
-      expect((<any>$el[0]).component.getValue()).to.deep.equal([{ '@id': '/examples/data/list/skill-1.jsonld' }, { '@id': '/examples/data/list/skill-3.jsonld' }]); // form value
+      expect((<any>$el[0]).component.getValue()).to.deep.equal([
+        { '@id': '/examples/data/list/skill-1.jsonld' },
+        { '@id': '/examples/data/list/skill-3.jsonld' },
+      ]); // form value
     });
 
-    cy.get('solid-form-dropdown#test4 > select').select(['CSS', 'Javascript']) // change value
+    cy.get('solid-form-dropdown#test4 > select').select(['CSS', 'Javascript']); // change value
     cy.get('solid-form-dropdown#test4').then($el => {
-      expect((<any>$el[0]).component.getValue()).to.deep.equal([{ '@id': '/examples/data/list/skill-2.jsonld' }, { '@id': '/examples/data/list/skill-3.jsonld' }]); // form value
+      expect((<any>$el[0]).component.getValue()).to.deep.equal([
+        { '@id': '/examples/data/list/skill-2.jsonld' },
+        { '@id': '/examples/data/list/skill-3.jsonld' },
+      ]); // form value
     });
 
     // With order-desc
-    cy.get('solid-form-dropdown#test5 > select > option').eq(1)
+    cy.get('solid-form-dropdown#test5 > select > option')
+      .eq(1)
       .should('contain', 'Python');
-    cy.get('solid-form-dropdown#test5 > select > option').eq(2)
+    cy.get('solid-form-dropdown#test5 > select > option')
+      .eq(2)
       .should('contain', 'PHP');
-    cy.get('solid-form-dropdown#test5 > select > option').eq(3)
+    cy.get('solid-form-dropdown#test5 > select > option')
+      .eq(3)
       .should('contain', 'Node');
-    cy.get('solid-form-dropdown#test5 > select > option').eq(4)
+    cy.get('solid-form-dropdown#test5 > select > option')
+      .eq(4)
       .should('contain', 'Javascript');
-    cy.get('solid-form-dropdown#test5 > select > option').eq(5)
+    cy.get('solid-form-dropdown#test5 > select > option')
+      .eq(5)
       .should('contain', 'HTML');
-    cy.get('solid-form-dropdown#test5 > select > option').eq(6)
+    cy.get('solid-form-dropdown#test5 > select > option')
+      .eq(6)
       .should('contain', 'Git');
-    cy.get('solid-form-dropdown#test5 > select > option').eq(7)
+    cy.get('solid-form-dropdown#test5 > select > option')
+      .eq(7)
       .should('contain', 'DevOps');
-    cy.get('solid-form-dropdown#test5 > select > option').eq(8)
+    cy.get('solid-form-dropdown#test5 > select > option')
+      .eq(8)
       .should('contain', 'CSS');
 
     // With federation
-    cy.get('solid-form-dropdown#test6 > select > option[value="{\\"@id\\": \\"/examples/data/federation/circles-1.jsonld\\"}"]')
-      .should('contain', 'Circle from server 1');
-      cy.get('solid-form-dropdown#test6 > select > option[value="{\\"@id\\": \\"/examples/data/federation/circles-2.jsonld\\"}"]')
-      .should('contain', 'Another circle from server 1');
-      cy.get('solid-form-dropdown#test6 > select > option[value="{\\"@id\\": \\"/examples/data/federation/circles-3.jsonld\\"}"]')
-      .should('contain', 'Circle from server 2');
-      cy.get('solid-form-dropdown#test6 > select > option[value="{\\"@id\\": \\"/examples/data/federation/circles-4.jsonld\\"}"]')
-      .should('contain', 'Another circle from server 2');
+    cy.get(
+      'solid-form-dropdown#test6 > select > option[value="{\\"@id\\": \\"/examples/data/federation/circles-1.jsonld\\"}"]',
+    ).should('contain', 'Circle from server 1');
+    cy.get(
+      'solid-form-dropdown#test6 > select > option[value="{\\"@id\\": \\"/examples/data/federation/circles-2.jsonld\\"}"]',
+    ).should('contain', 'Another circle from server 1');
+    cy.get(
+      'solid-form-dropdown#test6 > select > option[value="{\\"@id\\": \\"/examples/data/federation/circles-3.jsonld\\"}"]',
+    ).should('contain', 'Circle from server 2');
+    cy.get(
+      'solid-form-dropdown#test6 > select > option[value="{\\"@id\\": \\"/examples/data/federation/circles-4.jsonld\\"}"]',
+    ).should('contain', 'Another circle from server 2');
 
     // With enumeration in range
     cy.get('solid-form-dropdown#test7 > select')
       .should('have.value', 'option1')
-      .children().should('have.length', 5)
+      .children()
+      .should('have.length', 5)
       .eq(2)
       .should('have.attr', 'value', 'option2')
       .should('contain', 'option2');
     cy.get('solid-form-dropdown#test8 > select')
-      .children().should('have.length', 4)
+      .children()
+      .should('have.length', 4)
       .eq(1)
       .should('have.attr', 'value', '1')
       .should('contain', 'option a');
@@ -347,72 +396,105 @@ describe('form widgets', { testIsolation: false }, function () {
       .children()
       .should('have.length', 8);
     cy.get('solid-form-dropdown-autocompletion-placeholder > div')
-      .find('div .ss-search').children()
+      .find('div.ss-search')
+      .children()
       .eq(0)
       .should('have.attr', 'placeholder', 'Skills :');
     cy.get('solid-form-dropdown-autocompletion-placeholder > div')
-      .find('div .ss-list')
+      .find('div.ss-list')
+      .first()
       .children()
       .should('have.length', 8)
       .should('not.contain', 'Skills :');
 
     // With option-value
     cy.get('solid-form-dropdown#test10 > select')
-      .children().eq(2)
+      .children()
+      .eq(2)
       .should('have.attr', 'value', 'CSS')
       .should('contain', 'CSS');
     cy.get('solid-form-dropdown#test11 > select')
-      .children().eq(2)
-      .should('have.attr', 'value', '{"@id": "/examples/data/list/profile-2.jsonld"}');
+      .children()
+      .eq(2)
+      .should(
+        'have.attr',
+        'value',
+        '{"@id": "/examples/data/list/profile-2.jsonld"}',
+      );
     cy.get('solid-form-dropdown#test12 > select')
-      .children().eq(2)
-      .should('have.attr', 'value', '{"@id": "/examples/data/list/profile-2.jsonld"}');
-  })
+      .children()
+      .eq(2)
+      .should(
+        'have.attr',
+        'value',
+        '{"@id": "/examples/data/list/profile-2.jsonld"}',
+      );
+  });
 
   it('solid-form-radio', () => {
     // With no initial value
     cy.get('solid-form-radio#test1')
       .should('have.attr', 'data-src', '/examples/data/list/skills.jsonld')
-      .children().should('have.length', 1);
+      .children()
+      .should('have.length', 1);
 
     cy.get('solid-form-radio#test1') // check attributes
       .find('> div')
       .and('have.attr', 'name', 'test1')
-      .children().and('have.length', 8);
+      .children()
+      .and('have.length', 8);
 
-    cy.get('solid-form-radio#test1 > div > label').eq(0) // check options
+    cy.get('solid-form-radio#test1 > div > label')
+      .eq(0) // check options
       .contains('HTML')
       .parent()
       .find('input')
       .should('have.attr', 'type', 'radio')
-      .should('have.attr', 'value', '{"@id": "/examples/data/list/skill-1.jsonld"}');
-
-    cy.get('solid-form-radio#test1').then($el => { // Check API value
+      .should(
+        'have.attr',
+        'value',
+        '{"@id": "/examples/data/list/skill-1.jsonld"}',
+      );
+
+    cy.get('solid-form-radio#test1').then($el => {
+      // Check API value
       expect((<any>$el[0]).component.getValue()).to.equal(''); // form value
     });
 
     cy.get('solid-form-radio#test1 > div > label').eq(1).click(); // test change value
 
-    cy.get('solid-form-radio#test1').then($el => { // Check API
-      expect((<any>$el[0]).component['value']).to.equal(''); // value attribute
-      expect((<any>$el[0]).component.getValue()).to.equal('{"@id": "/examples/data/list/skill-2.jsonld"}'); // form value
+    cy.get('solid-form-radio#test1').then($el => {
+      // Check API
+      expect((<any>$el[0]).component.value).to.equal(''); // value attribute
+      expect((<any>$el[0]).component.getValue()).to.equal(
+        '{"@id": "/examples/data/list/skill-2.jsonld"}',
+      ); // form value
       expect((<any>$el[0]).component.context).to.be.not.empty; // check storeMixin properties
       expect((<any>$el[0]).component.resourceId).to.be.not.empty; // check storeMixin properties
     });
 
     // With initial value
-    cy.get('solid-form-radio#test2 label').eq(2).find('input').should('have.attr', 'checked', 'checked');
+    cy.get('solid-form-radio#test2 label')
+      .eq(2)
+      .find('input')
+      .should('have.attr', 'checked', 'checked');
     cy.get('solid-form-radio#test2').then($el => {
-      expect((<any>$el[0]).component['value']).to.equal('/examples/data/list/skill-3.jsonld'); // value attribute
-      expect((<any>$el[0]).component.getValue()).to.equal('{"@id": "/examples/data/list/skill-3.jsonld"}'); // form value
+      expect((<any>$el[0]).component.value).to.equal(
+        '/examples/data/list/skill-3.jsonld',
+      ); // value attribute
+      expect((<any>$el[0]).component.getValue()).to.equal(
+        '{"@id": "/examples/data/list/skill-3.jsonld"}',
+      ); // form value
     });
 
     cy.get('solid-form-radio#test3')
       .find('> div')
       .and('have.attr', 'name', 'test3')
-      .children().and('have.length', '3');
+      .children()
+      .and('have.length', '3');
 
-    cy.get('solid-form-radio#test3 > div > label').eq(0)
+    cy.get('solid-form-radio#test3 > div > label')
+      .eq(0)
       .contains('option1')
       .parent()
       .find('input')
@@ -421,54 +503,66 @@ describe('form widgets', { testIsolation: false }, function () {
 
     // Test click on multiple radio
     cy.get('solid-form-radio#test3 input[type=radio][value="option1"]')
-      .check().should('be.checked');
-    cy.get('solid-form-radio#test3 input[type=radio][value="option2"]')
-      .should('not.be.checked');
-    cy.get('solid-form-radio#test3 input[type=radio][value="option3"]')
-      .should('not.be.checked');
+      .check()
+      .should('be.checked');
+    cy.get('solid-form-radio#test3 input[type=radio][value="option2"]').should(
+      'not.be.checked',
+    );
+    cy.get('solid-form-radio#test3 input[type=radio][value="option3"]').should(
+      'not.be.checked',
+    );
 
     cy.get('solid-form-radio#test3 input[type=radio][value="option3"]')
-      .check().should('be.checked');
-    cy.get('solid-form-radio#test3 input[type=radio][value="option1"]')
-      .should('not.be.checked');
-    cy.get('solid-form-radio#test3 input[type=radio][value="option2"]')
-      .should('not.be.checked');
+      .check()
+      .should('be.checked');
+    cy.get('solid-form-radio#test3 input[type=radio][value="option1"]').should(
+      'not.be.checked',
+    );
+    cy.get('solid-form-radio#test3 input[type=radio][value="option2"]').should(
+      'not.be.checked',
+    );
 
     cy.get('solid-form-radio#test4')
       .find('> div')
       .and('have.attr', 'name', 'test4')
-      .children().and('have.length', '4')
+      .children()
+      .and('have.length', '4');
 
-    cy.get('solid-form-radio#test4 > div > label').eq(0)
+    cy.get('solid-form-radio#test4 > div > label')
+      .eq(0)
       .contains('option1')
       .parent()
       .find('input')
       .should('have.attr', 'type', 'radio')
       .should('have.attr', 'value', 'a');
-  })
+  });
 
   it('solid-form-checkboxes', () => {
     cy.get('#test-checkboxes')
-      .find('label:nth-child(-2n + 6)').click({ multiple: true })
+      .find('label:nth-child(-2n + 6)')
+      .click({ multiple: true });
     cy.get('#test-checkboxes').then(async ($el: any) => {
       const values = await $el[0].component.getValue();
       expect(values).to.deep.equal([
-        { "@id": "/examples/data/list/skill-2.jsonld" },
-        { "@id": "/examples/data/list/skill-4.jsonld" },
-        { "@id": "/examples/data/list/skill-6.jsonld" },
+        { '@id': '/examples/data/list/skill-2.jsonld' },
+        { '@id': '/examples/data/list/skill-4.jsonld' },
+        { '@id': '/examples/data/list/skill-6.jsonld' },
       ]);
     });
-  })
+  });
 
   it('solid-form-rangenumber', () => {
     cy.get('solid-form-rangenumber[name=test1]')
-      .children().should('have.length', 2);
+      .children()
+      .should('have.length', 2);
 
-    cy.get('solid-form-rangenumber > input').eq(0)
+    cy.get('solid-form-rangenumber > input')
+      .eq(0)
       .should('have.attr', 'data-holder', '')
       .and('have.attr', 'type', 'number')
       .and('have.attr', 'name', 'test1-start');
-    cy.get('solid-form-rangenumber > input').eq(1)
+    cy.get('solid-form-rangenumber > input')
+      .eq(1)
       .should('have.attr', 'data-holder', '')
       .and('have.attr', 'type', 'number')
       .and('have.attr', 'name', 'test1-end');
@@ -487,21 +581,26 @@ describe('form widgets', { testIsolation: false }, function () {
     });
 
     // Addition start-value-[field] and end-value-[field] attributes
-    cy.get('solid-form-rangenumber[name=test2] > input').eq(0)
-      .should('have.attr', 'value', '2')
-    cy.get('solid-form-rangenumber[name=test2] > input').eq(1)
-      .should('have.attr', 'value', '10')
+    cy.get('solid-form-rangenumber[name=test2] > input')
+      .eq(0)
+      .should('have.attr', 'value', '2');
+    cy.get('solid-form-rangenumber[name=test2] > input')
+      .eq(1)
+      .should('have.attr', 'value', '10');
   });
 
   it('solid-form-rangedate', () => {
     cy.get('solid-form-rangedate[name=test1]')
-      .children().should('have.length', 2);
+      .children()
+      .should('have.length', 2);
 
-    cy.get('solid-form-rangedate > input').eq(0)
+    cy.get('solid-form-rangedate > input')
+      .eq(0)
       .should('have.attr', 'data-holder', '')
       .and('have.attr', 'type', 'date')
       .and('have.attr', 'name', 'test1-start');
-    cy.get('solid-form-rangedate > input').eq(1)
+    cy.get('solid-form-rangedate > input')
+      .eq(1)
       .should('have.attr', 'data-holder', '')
       .and('have.attr', 'type', 'date')
       .and('have.attr', 'name', 'test1-end');
@@ -512,50 +611,69 @@ describe('form widgets', { testIsolation: false }, function () {
 
     cy.get('solid-form-rangedate > input').eq(0).type('2020-02-12');
     cy.get('solid-form-rangedate').then($el => {
-      expect((<any>$el[0]).component.getValue()).to.deep.equal(['2020-02-12', '']); // form value
+      expect((<any>$el[0]).component.getValue()).to.deep.equal([
+        '2020-02-12',
+        '',
+      ]); // form value
     });
     cy.get('solid-form-rangedate > input').eq(1).type('2020-05-24');
     cy.get('solid-form-rangedate').then($el => {
-      expect((<any>$el[0]).component.getValue()).to.deep.equal(['2020-02-12', '2020-05-24']); // form value
+      expect((<any>$el[0]).component.getValue()).to.deep.equal([
+        '2020-02-12',
+        '2020-05-24',
+      ]); // form value
     });
 
     // Addition start-value-[field] and end-value-[field] attributes
-    cy.get('solid-form-rangedate[name=test2] > input').eq(0)
-      .should('have.attr', 'value', '2020-12-15')
-    cy.get('solid-form-rangedate[name=test2] > input').eq(1)
-      .should('have.attr', 'value', '2222-12-22')
+    cy.get('solid-form-rangedate[name=test2] > input')
+      .eq(0)
+      .should('have.attr', 'value', '2020-12-15');
+    cy.get('solid-form-rangedate[name=test2] > input')
+      .eq(1)
+      .should('have.attr', 'value', '2222-12-22');
   });
 
   it('solid-form-color', () => {
-    cy.get('solid-form-color')
-      .children().should('have.length', 1)
+    cy.get('solid-form-color').children().should('have.length', 1);
 
-    cy.get('solid-form-color > input')
-      .should('have.attr', 'type', 'color')
+    cy.get('solid-form-color > input').should('have.attr', 'type', 'color');
   });
 
   it('solid-form-text-labellast', () => {
-    cy.get('solid-form-text-labellast').children()
-      .should('have.length', 2);
-    cy.get('solid-form-text-labellast').find('label').last()
+    cy.get('solid-form-text-labellast').children().should('have.length', 2);
+    cy.get('solid-form-text-labellast')
+      .find('label')
+      .last()
       .should('contain', 'test labellast');
   });
 
   it('solid-form-dropdown-addable', () => {
     // Without addable-data-src provided
     cy.get('solid-form-dropdown-addable#test1')
-      .children().should('have.length', 2);
-    cy.get('solid-form-dropdown-addable#test1 > solid-form')
-      .should('have.attr', 'data-src', '/examples/data/list/skills.jsonld');
+      .children()
+      .should('have.length', 2);
+    cy.get('solid-form-dropdown-addable#test1 > solid-form').should(
+      'have.attr',
+      'data-src',
+      '/examples/data/list/skills.jsonld',
+    );
 
     cy.get('solid-form-dropdown-addable#test1 > solid-form > form')
-      .children().should('have.length', 3)
-    cy.get('solid-form-dropdown-addable#test1 > solid-form > form > solid-form-label-text').eq(0)
-      .should('have.attr', 'name', 'name')
-    cy.get('solid-form-dropdown-addable#test1 > solid-form > form > solid-form-label-text').eq(1)
-      .should('have.attr', 'name', 'order')
-    cy.get('solid-form-dropdown-addable#test1 > solid-form > form > div > input')
-      .should('have.attr', 'type', 'submit')
+      .children()
+      .should('have.length', 3);
+    cy.get(
+      'solid-form-dropdown-addable#test1 > solid-form > form > solid-form-label-text',
+    )
+      .eq(0)
+      .should('have.attr', 'name', 'name');
+    cy.get(
+      'solid-form-dropdown-addable#test1 > solid-form > form > solid-form-label-text',
+    )
+      .eq(1)
+      .should('have.attr', 'name', 'order');
+    cy.get(
+      'solid-form-dropdown-addable#test1 > solid-form > form > div > input',
+    ).should('have.attr', 'type', 'submit');
 
     // With addable-data-src provided
 
@@ -565,52 +683,73 @@ describe('form widgets', { testIsolation: false }, function () {
       .and('have.attr', 'fields', 'name, username, age')
       .and('have.attr', 'widget-name', 'solid-form-text-placeholder-label')
       .and('have.attr', 'placeholder-name', 'Enter your name')
-      .and('have.attr', 'submit-button', 'Send data')
+      .and('have.attr', 'submit-button', 'Send data');
     cy.get('solid-form-dropdown-addable#test2 > solid-form > form')
-      .children().should('have.length', 4)
-    // Verify attributes and values in tags created by widget  
-    cy.get('solid-form-dropdown-addable#test2 > solid-form > form > solid-form-text-placeholder-label')
+      .children()
+      .should('have.length', 4);
+    // Verify attributes and values in tags created by widget
+    cy.get(
+      'solid-form-dropdown-addable#test2 > solid-form > form > solid-form-text-placeholder-label',
+    )
       .should('have.attr', 'name', 'name')
-      .and('have.attr', 'placeholder', 'Enter your name')
-    cy.get('solid-form-dropdown-addable#test2 > solid-form > form > solid-form-text-placeholder-label')
-      .find('label').should('contain', 'name')
-    cy.get('solid-form-dropdown-addable#test2 > solid-form > form > solid-form-text-placeholder-label')
-      .find('input').should('have.attr', 'placeholder', 'Enter your name')
-
-    cy.get('solid-form-dropdown-addable#test2 > solid-form > form > solid-form-label-text').eq(0)
-      .should('have.attr', 'name', 'username')
-    cy.get('solid-form-dropdown-addable#test2 > solid-form > form > solid-form-label-text').eq(1)
-      .should('have.attr', 'name', 'age')
-    cy.get('solid-form-dropdown-addable#test2 > solid-form > form > div > input')
+      .and('have.attr', 'placeholder', 'Enter your name');
+    cy.get(
+      'solid-form-dropdown-addable#test2 > solid-form > form > solid-form-text-placeholder-label',
+    )
+      .find('label')
+      .should('contain', 'name');
+    cy.get(
+      'solid-form-dropdown-addable#test2 > solid-form > form > solid-form-text-placeholder-label',
+    )
+      .find('input')
+      .should('have.attr', 'placeholder', 'Enter your name');
+
+    cy.get(
+      'solid-form-dropdown-addable#test2 > solid-form > form > solid-form-label-text',
+    )
+      .eq(0)
+      .should('have.attr', 'name', 'username');
+    cy.get(
+      'solid-form-dropdown-addable#test2 > solid-form > form > solid-form-label-text',
+    )
+      .eq(1)
+      .should('have.attr', 'name', 'age');
+    cy.get(
+      'solid-form-dropdown-addable#test2 > solid-form > form > div > input',
+    )
       .should('have.attr', 'type', 'submit')
-      .and('have.attr', 'value', 'Send data')
+      .and('have.attr', 'value', 'Send data');
   });
 
   it('solid-form-password', () => {
+    cy.get('solid-form-label-password').children().should('have.length', 2);
     cy.get('solid-form-label-password')
-      .children().should('have.length', 2);
-    cy.get('solid-form-label-password')
-      .children().eq(0).should('contain', 'password');
+      .children()
+      .eq(0)
+      .should('contain', 'password');
     cy.get('solid-form-label-password > input')
       .should('have.attr', 'type', 'password')
       .and('have.value', 'password123');
   });
 
   it('solid-form-time', () => {
+    cy.get('solid-form-label-time#time1').children().should('have.length', 2);
     cy.get('solid-form-label-time#time1')
-      .children().should('have.length', 2);
-    cy.get('solid-form-label-time#time1')
-      .children().eq(0).should('contain', 'time');
+      .children()
+      .eq(0)
+      .should('contain', 'time');
     cy.get('solid-form-label-time#time1 > input')
       .should('have.attr', 'type', 'time')
       .and('have.value', '15:15');
 
     cy.get('solid-form-label-time#time2')
-      .children().eq(0).should('contain', 'start time');
+      .children()
+      .eq(0)
+      .should('contain', 'start time');
     cy.get('solid-form-label-time#time2 > input')
       .should('have.attr', 'type', 'time')
-      .and('have.attr', 'min', "12:00")
-      .and('have.attr', 'max', "14:00")
-      .and('have.attr', 'step', "3600");
+      .and('have.attr', 'min', '12:00')
+      .and('have.attr', 'max', '14:00')
+      .and('have.attr', 'step', '3600');
   });
-})
+});
diff --git a/cypress/e2e/e2e/widgets-sets.cy.ts b/cypress/e2e/e2e/widgets-sets.cy.ts
index cf3524621d1aaa4f5a958091e8fcdffdaca2ac2d..00cc7f4cd9cf3c66b1abe2b7b60fea963e197e18 100644
--- a/cypress/e2e/e2e/widgets-sets.cy.ts
+++ b/cypress/e2e/e2e/widgets-sets.cy.ts
@@ -1,26 +1,19 @@
-describe('set widget', function() {
+describe('set widget', function () {
   this.beforeEach('visit', () => {
-    cy.visit('/examples/e2e/widgets-sets.html')
-  }) 
+    cy.visit('/examples/e2e/widgets-sets.html');
+  });
 
   it('solid-set-default', () => {
-    cy.get('solid-set-default')
-      .children().should('have.length', 0);
-  })
+    cy.get('solid-set-default').children().should('have.length', 0);
+  });
 
   it('solid-set-div', () => {
-    cy.get('solid-set-div')
-      .children().should('have.length', 1);
-    cy.get('solid-set-div')
-      .find('div')
-      .should('have.attr', 'data-content', '');
-  })
-  
+    cy.get('solid-set-div').children().should('have.length', 1);
+    cy.get('solid-set-div').find('div').should('have.attr', 'data-content', '');
+  });
+
   it('solid-set-ul', () => {
-    cy.get('solid-set-ul')
-      .children().should('have.length', 1);
-    cy.get('solid-set-ul')
-      .find('ul')
-      .should('have.attr', 'data-content', '');
-  })
-})
+    cy.get('solid-set-ul').children().should('have.length', 1);
+    cy.get('solid-set-ul').find('ul').should('have.attr', 'data-content', '');
+  });
+});
diff --git a/cypress/e2e/sleep.ts b/cypress/e2e/sleep.ts
index c3f3d43fba5dde86a93654b00b405621b05fb3e9..4c58c343861092547a22f5cef3ef5331d80add0c 100644
--- a/cypress/e2e/sleep.ts
+++ b/cypress/e2e/sleep.ts
@@ -1,3 +1,3 @@
 export default function sleep(time = 0) {
-  return new Promise(resolve => setTimeout(resolve, time))
+  return new Promise(resolve => setTimeout(resolve, time));
 }
diff --git a/cypress/e2e/unit/ComponentFactory.cy.ts b/cypress/e2e/unit/ComponentFactory.cy.ts
index 9d44e782753e99c083bfcfc4ffd77d11e5308e3e..0cac4c787faf94caa5004aa24a05fbf2006de0b2 100644
--- a/cypress/e2e/unit/ComponentFactory.cy.ts
+++ b/cypress/e2e/unit/ComponentFactory.cy.ts
@@ -1,4 +1,4 @@
-import { ComponentFactory } from '../../../src/libs/ComponentFactory';
+import { ComponentFactory } from '../../../src/libs/ComponentFactory.ts';
 
 const MixinTestTwo = {
   name: 'mixin2',
@@ -67,7 +67,7 @@ const Component = {
     myAttribute: {
       type: String,
       default: 'awesome',
-      callback: function() {
+      callback: function () {
         this.change = true;
       },
     },
@@ -93,7 +93,7 @@ const Component = {
     message: '',
   },
   get accessorTest() {
-    return 'hello ' + this.accessorValue;
+    return `hello ${this.accessorValue}`;
   },
   created() {
     this.message += '!!';
@@ -112,7 +112,7 @@ const Component = {
   },
 };
 
-describe('Component factory', function() {
+describe('Component factory', () => {
   it('expose html element', () => {
     const ComponentConstructor = ComponentFactory.build(Component);
     const component = new ComponentConstructor(document.createElement('p'));
diff --git a/cypress/e2e/unit/Compositor.cy.ts b/cypress/e2e/unit/Compositor.cy.ts
index 552335eb99c9fabdb5c7db34fb8c1141eaee5d67..10d3933e5b107e6a0e079003cf795ba10a175473 100644
--- a/cypress/e2e/unit/Compositor.cy.ts
+++ b/cypress/e2e/unit/Compositor.cy.ts
@@ -1,4 +1,4 @@
-import { Compositor } from '../../../src/libs/Compositor';
+import { Compositor } from '../../../src/libs/Compositor.ts';
 
 const MixinTestTwo = {
   name: 'mixin2',
@@ -73,7 +73,7 @@ const component = {
     },
   },
   get accessorTest() {
-    return 'hello ' + this.accessorValue;
+    return `hello ${this.accessorValue}`;
   },
   created() {
     console.log('created3');
@@ -92,7 +92,7 @@ const component = {
   },
 };
 
-describe('Mixin Compositor', function() {
+describe('Mixin Compositor', () => {
   it('merge mixin', () => {
     const result = Compositor.mergeMixin(component);
     expect(result.length).eq(2);
@@ -133,11 +133,11 @@ describe('Mixin Compositor', function() {
     const hookNames = Reflect.ownKeys(result);
 
     expect(hookNames.length).eq(3);
-    hookNames.forEach(hookName => {
-      result[hookName].forEach(hook => {
+    for (const hookName of hookNames) {
+      for (const hook of result[hookName]) {
         expect(typeof hook).eq('function');
-      });
-    });
+      }
+    }
 
     expect(result.created.length).eq(3);
     expect(result.attached.length).eq(2);
@@ -157,22 +157,22 @@ describe('Mixin Compositor', function() {
     const accessors = Object.keys(result);
 
     expect(accessors.length).eq(1);
-    accessors.forEach(accessorName => {
+    for (const accessorName of accessors) {
       expect(typeof result[accessorName].get).eq('function');
       expect(typeof result[accessorName].set).eq('function');
-    });
+    }
 
-    expect(result['accessorTest'].get.toString()).eq(
+    expect(result.accessorTest.get.toString()).eq(
       Reflect.getOwnPropertyDescriptor(
         component,
         'accessorTest',
-      )!.get!.toString(),
+      )?.get?.toString(),
     );
-    expect(result['accessorTest'].set.toString()).eq(
+    expect(result.accessorTest.set.toString()).eq(
       Reflect.getOwnPropertyDescriptor(
         MixinTestOne,
         'accessorTest',
-      )!.set!.toString(),
+      )?.set?.toString(),
     );
   });
 
@@ -185,9 +185,9 @@ describe('Mixin Compositor', function() {
     const methodNames = Array.from(result.keys());
 
     expect(methodNames.length).eq(4);
-    methodNames.forEach(methodName => {
+    for (const methodName of methodNames) {
       expect(typeof result.get(methodName)).eq('function');
-    });
+    }
 
     expect(result.get('methodA').toString()).eq(
       MixinTestOne.methodA.toString(),
diff --git a/cypress/e2e/unit/helpers.cy.ts b/cypress/e2e/unit/helpers.cy.ts
index 3dd5784c5b6d950e0916a0066921d21ab3c5a516..16a1d65bd151560f5f5a8239a34f8876239ad588 100644
--- a/cypress/e2e/unit/helpers.cy.ts
+++ b/cypress/e2e/unit/helpers.cy.ts
@@ -1,28 +1,28 @@
 import {
-  uniqID,
-  stringToDom,
-  setDeepProperty,
-  parseFieldsString,
-  findClosingBracketMatchIndex,
-  evalTemplateString,
   AsyncIterableBuilder,
-} from '../../../src/libs/helpers';
+  evalTemplateString,
+  findClosingBracketMatchIndex,
+  parseFieldsString,
+  setDeepProperty,
+  stringToDom,
+  uniqID,
+} from '../../../src/libs/helpers.ts';
 
 /**
  * uniqID
  */
-describe('uniqID', function() {
+describe('uniqID', () => {
   it('returns an id', () => {
-    let test = uniqID();
+    const test = uniqID();
     expect(test).to.match(/[_].{10}/g);
   });
   it('returns a different id 50 times in a row', () => {
-    let ids: string[] = [];
+    const ids: string[] = [];
     const arraySize = 50;
     for (let index = 0; index < arraySize; index++) {
       ids.push(uniqID());
     }
-    let noDuplicates = [...new Set(ids)];
+    const noDuplicates = [...new Set(ids)];
     expect(noDuplicates.length).to.eq(arraySize);
   });
 });
@@ -30,7 +30,7 @@ describe('uniqID', function() {
 /**
  * stringToDom
  */
-describe('stringToDom', function() {
+describe('stringToDom', () => {
   it('returns a fragment', () => {
     const fragment = stringToDom('<h1>Test element</h1>');
     expect(fragment.constructor.name).to.eq('DocumentFragment');
@@ -54,7 +54,7 @@ describe('stringToDom', function() {
 /**
  * setDeepProperty
  */
-describe('setDeepProperty', function() {
+describe('setDeepProperty', () => {
   it('set properties', () => {
     const object = {
       name: 'test',
@@ -91,7 +91,7 @@ describe('setDeepProperty', function() {
 /**
  * parseFieldsString
  */
-describe('parseFieldsString', function() {
+describe('parseFieldsString', () => {
   it('returns first level of fields', () => {
     const fields =
       'field1, field2(field3,field4, field5( field6, field7) ),  field8,field9';
@@ -108,7 +108,7 @@ describe('parseFieldsString', function() {
 /**
  * findClosingBracketMatchIndex
  */
-describe('findClosingBracketMatchIndex', function() {
+describe('findClosingBracketMatchIndex', () => {
   it('throw error', () => {
     const fields =
       'field1, field2(field3,field4, field5( field6, field7) ),  field8,field9';
@@ -140,7 +140,7 @@ describe('findClosingBracketMatchIndex', function() {
 /**
  * evalTemplateString
  */
-describe('evalTemplateString', function() {
+describe('evalTemplateString', () => {
   it('render template with values', async () => {
     const values = {
       val1: 'test 1',
@@ -177,9 +177,7 @@ describe('evalTemplateString', function() {
     </div>
     `;
     const promise = new Cypress.Promise((resolve, reject) => {
-      evalTemplateString(template, values)
-        .then(resolve)
-        .catch(reject);
+      evalTemplateString(template, values).then(resolve).catch(reject);
     });
     promise.finally(() => {
       expect(promise.isRejected).to.be.true;
@@ -265,7 +263,7 @@ describe('evalTemplateString', function() {
 //         }
 //       ]
 //     };
-    
+
 //     const newValue = transformArrayToContainer(value);
 //     expect(newValue).to.deep.equal({
 //       "@id": "myresource",
@@ -296,27 +294,27 @@ describe('evalTemplateString', function() {
 //     })
 //   })
 // })
-import sleep from '../sleep'
-describe('AsyncIterableBuilder',  () => {
+import sleep from '../sleep.ts';
+describe('AsyncIterableBuilder', () => {
   it('create an asyncIterable', async () => {
-    const { iterable, next } = new AsyncIterableBuilder<number>()
-    next(1)
-    next(2)
-    const values: number[] = []
-    let done = false
-    ;(async () => {
+    const { iterable, next } = new AsyncIterableBuilder<number>();
+    next(1);
+    next(2);
+    const values: number[] = [];
+    let done = false;
+    (async () => {
       for await (const number of iterable) {
-        values.push(number)
+        values.push(number);
       }
-      done = true
-    })()
-    await sleep()
-    expect(values).to.deep.eq([1, 2])
-    expect(done).to.be.false
-    next(3)
-    next(4, true)
-    await sleep()
-    expect(values).to.deep.eq([1, 2, 3, 4])
-    expect(done).to.be.true
-  })
-})
\ No newline at end of file
+      done = true;
+    })();
+    await sleep();
+    expect(values).to.deep.eq([1, 2]);
+    expect(done).to.be.false;
+    next(3);
+    next(4, true);
+    await sleep();
+    expect(values).to.deep.eq([1, 2, 3, 4]);
+    expect(done).to.be.true;
+  });
+});
diff --git a/cypress/e2e/unit/store.cy.ts b/cypress/e2e/unit/store.cy.ts
index 6957f79c1cd3141d09b5c5177b51e35a43491447..e379d2ca001eb45c9bd9ef02b99b814b8caad997 100644
--- a/cypress/e2e/unit/store.cy.ts
+++ b/cypress/e2e/unit/store.cy.ts
@@ -10,23 +10,25 @@ export const base_context = {
   acl: 'http://www.w3.org/ns/auth/acl#',
   permissions: 'acl:accessControl',
   mode: 'acl:mode',
-  geo: "http://www.w3.org/2003/01/geo/wgs84_pos#",
-  lat: "geo:lat",
-  lng: "geo:long"
+  geo: 'http://www.w3.org/2003/01/geo/wgs84_pos#',
+  lat: 'geo:lat',
+  lng: 'geo:long',
 };
 
 // FIXME: Fix this tests suite
 describe('store', { testIsolation: false }, function () {
   this.beforeAll('visit', () => {
-    cy.visit('/examples/e2e/store.html')
-  })
+    cy.visit('/examples/e2e/store.html');
+  });
 
   it('has prototype', () => {
     cy.window().then((win: any) => {
       // properties
       expect(win.sibStore.cache).to.exist;
       expect(win.sibStore.subscriptionIndex).to.exist;
-      expect(win.sibStore.loadingList).to.be.a('Set').and.have.property('size', 0);
+      expect(win.sibStore.loadingList)
+        .to.be.a('Set')
+        .and.have.property('size', 0);
       expect(win.sibStore.headers).to.exist;
       // public methods
       expect(win.sibStore.fetchAuthn).to.be.a('function');
@@ -41,227 +43,205 @@ describe('store', { testIsolation: false }, function () {
       expect(win.sibStore.selectLanguage).to.be.a('function');
       // PubSub
       expect(win.PubSub).to.exist;
-    })
+    });
   });
 
   it('save local data', () => {
     cy.window().then(async (win: any) => {
       const store = win.sibStore;
-      const customID = "myCustomID";
-      const url = `store://local.${customID}`
+      const customID = 'myCustomID';
+      const url = `store://local.${customID}`;
 
       // Now the context needs to be explicitly defined
       const dataToSave1 = {
         foo: 'bar',
-        "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+        '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
       };
       await store.setLocalData(dataToSave1, url);
-      let dataRead1 = await store.getData(url);
-      expect(await dataRead1!['foo']).eq('bar');
+      const dataRead1 = await store.getData(url);
+      expect(await dataRead1?.foo).eq('bar');
       store.clearCache(url);
     });
   });
 
   it('replaces local data', () => {
-    cy.intercept("GET", "*/data/list/users.jsonld").as('users')
+    cy.intercept('GET', '*/data/list/users.jsonld').as('users');
 
     cy.window().then(async (win: any) => {
       const store = win.sibStore;
       await store.getData('/examples/data/list/user-1.jsonld', base_context);
       const dataToSave1 = {
-        "@id": "/examples/data/list/user-1.jsonld",
-        "@type": "foaf:user",
-        "username": "local user",
-        "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-      }
-      await store.setLocalData(dataToSave1, '/examples/data/list/user-1.jsonld');
+        '@id': '/examples/data/list/user-1.jsonld',
+        '@type': 'foaf:user',
+        username: 'local user',
+        '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
+      };
+      await store.setLocalData(
+        dataToSave1,
+        '/examples/data/list/user-1.jsonld',
+      );
       const dataRead = store.get('/examples/data/list/user-1.jsonld');
-      expect(await dataRead['username']).eq('local user');
-      expect(await dataRead['email']).not.exist;
+      expect(await dataRead.username).eq('local user');
+      expect(await dataRead.email).not.exist;
       store.clearCache('/examples/data/list/user-1.jsonld');
     });
   });
 
   it('fetches data and cache it', () => {
-    cy.intercept("GET", "/examples/data/list/users.jsonld", {
+    cy.intercept('GET', '/examples/data/list/users.jsonld', {
       statusCode: 200,
       body: {
-        "@id": "/examples/data/list/users.jsonld",
-        "@type": "ldp:Container",
-        "ldp:contains": [
+        '@id': '/examples/data/list/users.jsonld',
+        '@type': 'ldp:Container',
+        'ldp:contains': [
           {
-            "@id": "/examples/data/list/user-1.jsonld",
-            "first_name": "Test",
-            "last_name": "User",
-            "name": "Test User",
-            "username": "admin",
-            "email": "test-user@example.com",
-            "available": true,
-            "years_experience": 3,
-            "skills": {
-              "@id": "/examples/data/list/user-1-skills.jsonld",
-              "@type": "ldp:Container",
-              "ldp:contains": [
+            '@id': '/examples/data/list/user-1.jsonld',
+            first_name: 'Test',
+            last_name: 'User',
+            name: 'Test User',
+            username: 'admin',
+            email: 'test-user@example.com',
+            available: true,
+            years_experience: 3,
+            skills: {
+              '@id': '/examples/data/list/user-1-skills.jsonld',
+              '@type': 'ldp:Container',
+              'ldp:contains': [
                 {
-                  "@id": "/examples/data/list/skill-2.jsonld"
+                  '@id': '/examples/data/list/skill-2.jsonld',
                 },
                 {
-                  "@id": "/examples/data/list/skill-3.jsonld"
-                }
+                  '@id': '/examples/data/list/skill-3.jsonld',
+                },
               ],
-              "permissions": [
-                "view"
-              ]
+              permissions: ['view'],
             },
-            "profile": {
-              "@id": "/examples/data/list/profile-1.jsonld"
+            profile: {
+              '@id': '/examples/data/list/profile-1.jsonld',
             },
-            "@type": "foaf:user",
-            "permissions": [
-              "view"
-            ]
+            '@type': 'foaf:user',
+            permissions: ['view'],
           },
           {
-            "@id": "/examples/data/list/user-2.jsonld",
-            "first_name": "Paris",
-            "last_name": "Hilton",
-            "name": "Paris Hilton",
-            "username": "paris",
-            "email": "paris@hilton.hi",
-            "available": true,
-            "years_experience": 5,
-            "skills": {
-              "@id": "/examples/data/list/user-2-skills.jsonld",
-              "@type": "ldp:Container",
-              "ldp:contains": [
+            '@id': '/examples/data/list/user-2.jsonld',
+            first_name: 'Paris',
+            last_name: 'Hilton',
+            name: 'Paris Hilton',
+            username: 'paris',
+            email: 'paris@hilton.hi',
+            available: true,
+            years_experience: 5,
+            skills: {
+              '@id': '/examples/data/list/user-2-skills.jsonld',
+              '@type': 'ldp:Container',
+              'ldp:contains': [
                 {
-                  "@id": "/examples/data/list/skill-1.jsonld"
-                }
+                  '@id': '/examples/data/list/skill-1.jsonld',
+                },
               ],
-              "permissions": [
-                "view"
-              ]
+              permissions: ['view'],
             },
-            "profile": {
-              "@id": "/examples/data/list/profile-2.jsonld"
+            profile: {
+              '@id': '/examples/data/list/profile-2.jsonld',
             },
-            "@type": "foaf:user",
-            "permissions": [
-              "view"
-            ]
+            '@type': 'foaf:user',
+            permissions: ['view'],
           },
           {
-            "@id": "/examples/data/list/user-4.jsonld",
-            "first_name": "Pierre",
-            "last_name": "DLC",
-            "name": "Pierre DLC",
-            "username": "pierre",
-            "email": "pierredelacroix@happy-dev.fr",
-            "available": false,
-            "years_experience": 5,
-            "skills": {
-              "@id": "/examples/data/list/user-4-skills.jsonld",
-              "@type": "ldp:Container",
-              "ldp:contains": [
+            '@id': '/examples/data/list/user-4.jsonld',
+            first_name: 'Pierre',
+            last_name: 'DLC',
+            name: 'Pierre DLC',
+            username: 'pierre',
+            email: 'pierredelacroix@happy-dev.fr',
+            available: false,
+            years_experience: 5,
+            skills: {
+              '@id': '/examples/data/list/user-4-skills.jsonld',
+              '@type': 'ldp:Container',
+              'ldp:contains': [
                 {
-                  "@id": "/examples/data/list/skill-1.jsonld"
+                  '@id': '/examples/data/list/skill-1.jsonld',
                 },
                 {
-                  "@id": "/examples/data/list/skill-2.jsonld"
+                  '@id': '/examples/data/list/skill-2.jsonld',
                 },
                 {
-                  "@id": "/examples/data/list/skill-4.jsonld"
-                }
+                  '@id': '/examples/data/list/skill-4.jsonld',
+                },
               ],
-              "permissions": [
-                "view"
-              ]
+              permissions: ['view'],
             },
-            "profile": {
-              "@id": "/examples/data/list/profile-4.jsonld"
+            profile: {
+              '@id': '/examples/data/list/profile-4.jsonld',
             },
-            "@type": "foaf:user",
-            "permissions": [
-              "view"
-            ]
+            '@type': 'foaf:user',
+            permissions: ['view'],
           },
           {
-            "@id": "/examples/data/list/user-3.jsonld",
-            "first_name": "Not A",
-            "last_name": "Paris Member",
-            "name": "Not A Paris Member",
-            "username": "not-member-paris",
-            "email": "not-a@paris.members",
-            "available": false,
-            "years_experience": 7,
-            "skills": {
-              "@id": "/examples/data/list/user-3-skills.jsonld",
-              "@type": "ldp:Container",
-              "ldp:contains": [
-      
-              ],
-              "permissions": [
-                "view"
-              ]
+            '@id': '/examples/data/list/user-3.jsonld',
+            first_name: 'Not A',
+            last_name: 'Paris Member',
+            name: 'Not A Paris Member',
+            username: 'not-member-paris',
+            email: 'not-a@paris.members',
+            available: false,
+            years_experience: 7,
+            skills: {
+              '@id': '/examples/data/list/user-3-skills.jsonld',
+              '@type': 'ldp:Container',
+              'ldp:contains': [],
+              permissions: ['view'],
             },
-            "profile": {
-              "@id": "/examples/data/list/profile-3.jsonld"
+            profile: {
+              '@id': '/examples/data/list/profile-3.jsonld',
             },
-            "@type": "foaf:user",
-            "permissions": [
-              "view"
-            ]
-          }
-        ],
-        "permissions": [
-          "view"
+            '@type': 'foaf:user',
+            permissions: ['view'],
+          },
         ],
-        "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+        permissions: ['view'],
+        '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
       },
       headers: {
-        'content-type': 'application/ld+json'
-      }
-    }).as('users')
+        'content-type': 'application/ld+json',
+      },
+    }).as('users');
 
-    cy.intercept("GET", "/examples/data/extra-context/user-6.jsonld", {
+    cy.intercept('GET', '/examples/data/extra-context/user-6.jsonld', {
       statusCode: 200,
       body: {
-        "@id": "/examples/data/extra-context/user-6.jsonld",
-        "first_name": "Test",
-        "last_name": "User",
-        "username": "admin",
-        "email": "test-user@example.com",
-        "name": "Test User",
-        "profile": {
-          "@id": "/examples/data/extra-context/profile-6.jsonld",
-          "@context": {
-            "picture": "foaf:depiction"
+        '@id': '/examples/data/extra-context/user-6.jsonld',
+        first_name: 'Test',
+        last_name: 'User',
+        username: 'admin',
+        email: 'test-user@example.com',
+        name: 'Test User',
+        profile: {
+          '@id': '/examples/data/extra-context/profile-6.jsonld',
+          '@context': {
+            picture: 'foaf:depiction',
           },
-          "picture": "my-avatar.png"
+          picture: 'my-avatar.png',
         },
-        "@type": "foaf:user",
-        "permissions": [
-          "view"
-        ],
-        "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+        '@type': 'foaf:user',
+        permissions: ['view'],
+        '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
       },
       headers: {
-        'content-type': 'application/ld+json'
-      }
-    }).as('user-6')
+        'content-type': 'application/ld+json',
+      },
+    }).as('user-6');
 
     cy.window()
       .its('sibStore')
       .invoke('getData', '/examples/data/list/users.jsonld', base_context);
 
-    cy.get('@users').its("response.statusCode").should('equal', 200);
+    cy.get('@users').its('response.statusCode').should('equal', 200);
 
-    cy.window()
-      .its('sibStore.cache').should('have.length', 13); // cache
-    cy.window()
-      .its('sibStore.loadingList').should('have.property', 'size', 0); // loading list
-    cy.window()
-      .its('sibStore.subscriptionIndex').should('have.length', 8); // Subscription index
+    cy.window().its('sibStore.cache').should('have.length', 13); // cache
+    cy.window().its('sibStore.loadingList').should('have.property', 'size', 0); // loading list
+    cy.window().its('sibStore.subscriptionIndex').should('have.length', 8); // Subscription index
 
     cy.window()
       .its('sibStore')
@@ -271,57 +251,69 @@ describe('store', { testIsolation: false }, function () {
     // properties are expanded
     cy.window()
       .its('sibStore')
-      .invoke('getData', '/examples/data/extra-context/user-6.jsonld', base_context);
+      .invoke(
+        'getData',
+        '/examples/data/extra-context/user-6.jsonld',
+        base_context,
+      );
     cy.window()
       .its('sibStore')
       .invoke('get', '/examples/data/extra-context/user-6.jsonld')
       .invoke('getResourceData')
-      .should('have.property', 'https://cdn.startinblox.com/owl#email', "test-user@example.com"); // @vocab
+      .should(
+        'have.property',
+        'https://cdn.startinblox.com/owl#email',
+        'test-user@example.com',
+      ); // @vocab
     cy.window()
       .its('sibStore')
       .invoke('get', '/examples/data/extra-context/profile-6.jsonld')
       .invoke('getResourceData')
-      .should('have.property', 'http://xmlns.com/foaf/0.1/depiction', "my-avatar.png"); // nested additionnal context
+      .should(
+        'have.property',
+        'http://xmlns.com/foaf/0.1/depiction',
+        'my-avatar.png',
+      ); // nested additionnal context
   });
 
   it('send xhr requests', () => {
-    cy.intercept("PATCH", "/examples/data/list/user-1.jsonld", {
+    cy.intercept('PATCH', '/examples/data/list/user-1.jsonld', {
       headers: {
-        'content-type': 'application/ld+json'
-      }
-    }).as("patch")
-    
-    cy.intercept("PUT", "/examples/data/list/user-1.jsonld", {
+        'content-type': 'application/ld+json',
+      },
+    }).as('patch');
+
+    cy.intercept('PUT', '/examples/data/list/user-1.jsonld', {
       headers: {
-        'content-type': 'application/ld+json'
-      }
-    }).as("put")
-    
-    cy.intercept("POST", "/examples/data/list/users.jsonld", {
+        'content-type': 'application/ld+json',
+      },
+    }).as('put');
+
+    cy.intercept('POST', '/examples/data/list/users.jsonld', {
       headers: {
-        'content-type': 'application/ld+json'
-      }
-    }).as("post")
+        'content-type': 'application/ld+json',
+      },
+    }).as('post');
 
-    cy.intercept("DELETE", "/examples/data/list/user-1.jsonld", {
+    cy.intercept('DELETE', '/examples/data/list/user-1.jsonld', {
       headers: {
-        'content-type': 'application/ld+json'
-      }
-    }).as("delete")
+        'content-type': 'application/ld+json',
+      },
+    }).as('delete');
 
-    cy.intercept("GET", `${baseUrl}/examples/data/list/user-1.jsonld`, {
+    cy.intercept('GET', `${baseUrl}/examples/data/list/user-1.jsonld`, {
       statusCode: 200,
       body: {
-          "@id": "/examples/data/list/user-1.jsonld",
-          "@type": "foaf:user",
-          "first_name": "Matthieu",
-          "last_name": "Garcia",
-          "email": "matthieu@example.com"
+        '@id': '/examples/data/list/user-1.jsonld',
+        '@type': 'foaf:user',
+        first_name: 'Matthieu',
+        last_name: 'Garcia',
+        email: 'matthieu@example.com',
       },
       headers: {
-        'content-type': 'application/ld+json'
-      }
-    }).as("get")
+        'content-type': 'application/ld+json',
+      },
+    }).as('get');
 
     cy.window().then((win: any) => {
       cy.spy(win.sibStore, 'clearCache');
@@ -331,27 +323,49 @@ describe('store', { testIsolation: false }, function () {
     cy.window()
       .its('sibStore')
       .invoke('fetchData', '/examples/data/list/user-1.jsonld');
-    cy.get('@get').its("request.url").should('equal', `${baseUrl}/examples/data/list/user-1.jsonld`);
-    
+    cy.get('@get')
+      .its('request.url')
+      .should('equal', `${baseUrl}/examples/data/list/user-1.jsonld`);
+
     cy.window()
       .its('sibStore')
-      .invoke('patch', { first_name: 'Monsieur' }, '/examples/data/list/user-1.jsonld');
-    cy.get('@patch').its("request.url").should('equal', `${baseUrl}/examples/data/list/user-1.jsonld`);
+      .invoke(
+        'patch',
+        { first_name: 'Monsieur' },
+        '/examples/data/list/user-1.jsonld',
+      );
+    cy.get('@patch')
+      .its('request.url')
+      .should('equal', `${baseUrl}/examples/data/list/user-1.jsonld`);
 
     cy.window()
       .its('sibStore')
-      .invoke('put', { first_name: 'Monsieur' }, '/examples/data/list/user-1.jsonld');
-    cy.get('@put').its("request.url").should('equal', `${baseUrl}/examples/data/list/user-1.jsonld`);
+      .invoke(
+        'put',
+        { first_name: 'Monsieur' },
+        '/examples/data/list/user-1.jsonld',
+      );
+    cy.get('@put')
+      .its('request.url')
+      .should('equal', `${baseUrl}/examples/data/list/user-1.jsonld`);
 
     cy.window()
       .its('sibStore')
-      .invoke('post', { first_name: 'Monsieur' }, '/examples/data/list/users.jsonld');
-    cy.get('@post').its("request.url").should('equal', `${baseUrl}/examples/data/list/users.jsonld`);
+      .invoke(
+        'post',
+        { first_name: 'Monsieur' },
+        '/examples/data/list/users.jsonld',
+      );
+    cy.get('@post')
+      .its('request.url')
+      .should('equal', `${baseUrl}/examples/data/list/users.jsonld`);
 
     cy.window()
       .its('sibStore')
       .invoke('delete', '/examples/data/list/user-1.jsonld');
-    cy.get('@delete').its("request.url").should('equal', `${baseUrl}/examples/data/list/user-1.jsonld`);
+    cy.get('@delete')
+      .its('request.url')
+      .should('equal', `${baseUrl}/examples/data/list/user-1.jsonld`);
 
     cy.window().then((win: any) => {
       expect(win.sibStore.clearCache).to.be.called;
@@ -362,7 +376,9 @@ describe('store', { testIsolation: false }, function () {
   it('expands id', () => {
     cy.window()
       .its('sibStore')
-      .invoke('_getExpandedId', 'user:1/', { 'user': "https://ldp-server.test/users/" })
+      .invoke('_getExpandedId', 'user:1/', {
+        user: 'https://ldp-server.test/users/',
+      })
       .should('equal', 'https://ldp-server.test/users/1/');
 
     cy.window()
@@ -377,8 +393,7 @@ describe('store', { testIsolation: false }, function () {
   });
 
   it('clears cache', () => {
-    cy.window()
-      .its('sibStore.cache').should('have.length', 15);
+    cy.window().its('sibStore.cache').should('have.length', 15);
 
     cy.window()
       .its('sibStore')
@@ -389,26 +404,26 @@ describe('store', { testIsolation: false }, function () {
       .its('sibStore')
       .invoke('clearCache', '/examples/data/list/user-1.jsonld');
 
-    cy.window()
-      .its('sibStore.cache').should('have.length', 14);
+    cy.window().its('sibStore.cache').should('have.length', 14);
 
     cy.window()
       .its('sibStore')
       .invoke('get', '/examples/data/list/user-1.jsonld')
       .should('not.exist');
 
-    cy.window()
-      .its('sibStore')
-      .invoke('clearCache', 'wrong-id.jsonld');
+    cy.window().its('sibStore').invoke('clearCache', 'wrong-id.jsonld');
 
-    cy.window()
-      .its('sibStore.cache').should('have.length', 14);
+    cy.window().its('sibStore.cache').should('have.length', 14);
   });
 
   it('subscribes resource', () => {
     cy.window()
       .its('sibStore')
-      .invoke('subscribeResourceTo', 'ldp-server.test/circles/', 'ldp-server.test/circles/1/');
+      .invoke(
+        'subscribeResourceTo',
+        'ldp-server.test/circles/',
+        'ldp-server.test/circles/1/',
+      );
 
     cy.window().then((win: any) => {
       expect(win.sibStore.subscriptionIndex).to.have.length(9);
@@ -419,65 +434,117 @@ describe('store', { testIsolation: false }, function () {
 
     cy.window()
       .its('sibStore')
-      .invoke('subscribeResourceTo', 'ldp-server.test/users/matthieu/', 'ldp-server.test/circles/1/');
+      .invoke(
+        'subscribeResourceTo',
+        'ldp-server.test/users/matthieu/',
+        'ldp-server.test/circles/1/',
+      );
 
     cy.window().then((win: any) => {
       expect(win.sibStore.subscriptionIndex).to.have.length(9);
       expect(win.sibStore.subscriptionIndex.get('ldp-server.test/circles/1/'))
         .to.have.length(2)
-        .and.to.have.members(['ldp-server.test/circles/', 'ldp-server.test/users/matthieu/']);
+        .and.to.have.members([
+          'ldp-server.test/circles/',
+          'ldp-server.test/users/matthieu/',
+        ]);
     });
   });
 
   it('subscribes virtual container', () => {
     cy.window()
       .its('sibStore')
-      .invoke('subscribeVirtualContainerTo', 'ldp-server.test/circles/joinable', 'ldp-server.test/circles/1/members');
+      .invoke(
+        'subscribeVirtualContainerTo',
+        'ldp-server.test/circles/joinable',
+        'ldp-server.test/circles/1/members',
+      );
 
     cy.window().then((win: any) => {
       expect(win.sibStore.subscriptionVirtualContainersIndex).to.have.length(1);
-      expect(win.sibStore.subscriptionVirtualContainersIndex.get('ldp-server.test/circles/1/members'))
+      expect(
+        win.sibStore.subscriptionVirtualContainersIndex.get(
+          'ldp-server.test/circles/1/members',
+        ),
+      )
         .to.have.length(1)
         .and.to.have.members(['ldp-server.test/circles/joinable']);
     });
 
     cy.window()
       .its('sibStore')
-      .invoke('subscribeVirtualContainerTo', 'ldp-server.test/users/matthieu/circles', 'ldp-server.test/circles/1/members');
+      .invoke(
+        'subscribeVirtualContainerTo',
+        'ldp-server.test/users/matthieu/circles',
+        'ldp-server.test/circles/1/members',
+      );
 
     cy.window().then((win: any) => {
       expect(win.sibStore.subscriptionVirtualContainersIndex).to.have.length(1);
-      expect(win.sibStore.subscriptionVirtualContainersIndex.get('ldp-server.test/circles/1/members'))
+      expect(
+        win.sibStore.subscriptionVirtualContainersIndex.get(
+          'ldp-server.test/circles/1/members',
+        ),
+      )
         .to.have.length(2)
-        .and.to.have.members(['ldp-server.test/users/matthieu/circles', 'ldp-server.test/circles/joinable']);
+        .and.to.have.members([
+          'ldp-server.test/users/matthieu/circles',
+          'ldp-server.test/circles/joinable',
+        ]);
     });
 
     cy.window()
-    .its('sibStore')
-    .invoke('subscribeVirtualContainerTo', 'ldp-server.test/circles/joinable', 'ldp-server.test/circles/1/members');
+      .its('sibStore')
+      .invoke(
+        'subscribeVirtualContainerTo',
+        'ldp-server.test/circles/joinable',
+        'ldp-server.test/circles/1/members',
+      );
 
     cy.window().then((win: any) => {
       expect(win.sibStore.subscriptionVirtualContainersIndex).to.have.length(1);
-      expect(win.sibStore.subscriptionVirtualContainersIndex.get('ldp-server.test/circles/1/members'))
+      expect(
+        win.sibStore.subscriptionVirtualContainersIndex.get(
+          'ldp-server.test/circles/1/members',
+        ),
+      )
         .to.have.length(2)
-        .and.to.have.members(['ldp-server.test/users/matthieu/circles', 'ldp-server.test/circles/joinable']);
+        .and.to.have.members([
+          'ldp-server.test/users/matthieu/circles',
+          'ldp-server.test/circles/joinable',
+        ]);
     });
   });
 
   it('gets absolute iri', () => {
     cy.window()
       .its('sibStore')
-      .invoke('_getAbsoluteIri', '/examples/data/list/users.jsonld', base_context, '')
+      .invoke(
+        '_getAbsoluteIri',
+        '/examples/data/list/users.jsonld',
+        base_context,
+        '',
+      )
       .should('equal', `${baseUrl}/examples/data/list/users.jsonld`);
 
     cy.window()
       .its('sibStore')
-      .invoke('_getAbsoluteIri', 'user-1.jsonld', base_context, '/examples/data/list/users.jsonld')
+      .invoke(
+        '_getAbsoluteIri',
+        'user-1.jsonld',
+        base_context,
+        '/examples/data/list/users.jsonld',
+      )
       .should('equal', `${baseUrl}/examples/data/list/user-1.jsonld`);
 
     cy.window()
       .its('sibStore')
-      .invoke('_getAbsoluteIri', 'https://ldp-server.test/circles/', base_context, '')
+      .invoke(
+        '_getAbsoluteIri',
+        'https://ldp-server.test/circles/',
+        base_context,
+        '',
+      )
       .should('equal', 'https://ldp-server.test/circles/');
   });
 
@@ -488,28 +555,34 @@ describe('store', { testIsolation: false }, function () {
       await store.getData('/examples/data/list/user-1.jsonld', base_context);
 
       const resource = {
-        "@id": "/examples/data/list/user-1.jsonld",
-        name: "Test User",
+        '@id': '/examples/data/list/user-1.jsonld',
+        name: 'Test User',
         available: true,
         skills: {
-          "@id": "/examples/data/list/user-1-skills.jsonld",
-          "@type": "ldp:Container",
-          "ldp:contains": [
+          '@id': '/examples/data/list/user-1-skills.jsonld',
+          '@type': 'ldp:Container',
+          'ldp:contains': [
             {
-              "@id": "/examples/data/list/skill-2.jsonld"
+              '@id': '/examples/data/list/skill-2.jsonld',
             },
             {
-              "@id": "/examples/data/list/skill-3.jsonld"
-            }
+              '@id': '/examples/data/list/skill-3.jsonld',
+            },
           ],
         },
         profile: {
-          "@id": "/examples/data/list/profile-1.jsonld"
+          '@id': '/examples/data/list/profile-1.jsonld',
         },
-        "@type": "foaf:user"
+        '@type': 'foaf:user',
       };
-      const nestedResources = await store.getNestedResources(resource, '/examples/data/list/user-1.jsonld');
-      expect(nestedResources).to.deep.equal(["/examples/data/list/user-1-skills.jsonld", "/examples/data/list/profile-1.jsonld"]);
+      const nestedResources = await store.getNestedResources(
+        resource,
+        '/examples/data/list/user-1.jsonld',
+      );
+      expect(nestedResources).to.deep.equal([
+        '/examples/data/list/user-1-skills.jsonld',
+        '/examples/data/list/profile-1.jsonld',
+      ]);
       expect(store.fetchData).to.be.calledOnce;
     });
   });
@@ -522,7 +595,10 @@ describe('store', { testIsolation: false }, function () {
       cy.spy(store, 'fetchData');
 
       expect(store.cache).to.have.length(15);
-      await store.refreshResources(['/examples/data/list/user-1.jsonld', '/examples/data/list/users.jsonld']);
+      await store.refreshResources([
+        '/examples/data/list/user-1.jsonld',
+        '/examples/data/list/users.jsonld',
+      ]);
 
       expect(store.clearCache).to.be.calledTwice;
       expect(store.getData).to.be.calledTwice;
@@ -536,7 +612,10 @@ describe('store', { testIsolation: false }, function () {
     cy.window().then(async (win: any) => {
       const store = win.sibStore;
       cy.spy(win.PubSub, 'publish');
-      await store.notifyResources(['/examples/data/list/user-1.jsonld', '/examples/data/list/users.jsonld']);
+      await store.notifyResources([
+        '/examples/data/list/user-1.jsonld',
+        '/examples/data/list/users.jsonld',
+      ]);
       expect(win.PubSub.publish).to.be.calledTwice;
     });
   });
@@ -544,24 +623,30 @@ describe('store', { testIsolation: false }, function () {
   it('refreshResource and localData', () => {
     cy.window().then(async (win: any) => {
       const store = win.sibStore;
-      await store.setLocalData({
-        "@context": "https://cdn.startinblox.com/owl/context.jsonld",
-        "@id": "store://local.2",
-        "name": "ok",
-      }, "store://local.2");
-
-      await store.setLocalData({
-        "@context": "https://cdn.startinblox.com/owl/context.jsonld",
-        "@id": "store://local.1",
-        "ref": { "@id": "store://local.2" },
-      }, "store://local.1");
+      await store.setLocalData(
+        {
+          '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
+          '@id': 'store://local.2',
+          name: 'ok',
+        },
+        'store://local.2',
+      );
+
+      await store.setLocalData(
+        {
+          '@context': 'https://cdn.startinblox.com/owl/context.jsonld',
+          '@id': 'store://local.1',
+          ref: { '@id': 'store://local.2' },
+        },
+        'store://local.1',
+      );
 
       cy.wait(100).then(async () => {
-        const resource = store.get('store://local.2')
+        const resource = store.get('store://local.2');
         expect(resource).to.exist;
-        const name = await resource['name']
+        const name = await resource.name;
         expect(name).to.equal('ok');
-      } );
+      });
     });
   });
-});
\ No newline at end of file
+});
diff --git a/cypress/fixtures/circles-16.jsonld b/cypress/fixtures/circles-16.jsonld
index 2153cd98bc9482a27e3c2466d8ee539fb354bf4f..8def997cf65fbd697dc2028a8abfcd0c6f1b44a7 100644
--- a/cypress/fixtures/circles-16.jsonld
+++ b/cypress/fixtures/circles-16.jsonld
@@ -10,10 +10,6 @@
     "@id": "https://ldp-server.test/users/matthieu/"
   },
   "@type": "hd:circle",
-  "permissions": [
-    "view",
-    "change",
-    "delete"
-  ],
+  "permissions": ["view", "change", "delete"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/circles-17-members.jsonld b/cypress/fixtures/circles-17-members.jsonld
index 22c625e2d9f326015b9c0ae6475f7231bbdb0335..7a26fc37ad18ad82b7da9329f89834a783a54ce2 100644
--- a/cypress/fixtures/circles-17-members.jsonld
+++ b/cypress/fixtures/circles-17-members.jsonld
@@ -1,11 +1,7 @@
 {
   "@id": "https://ldp-server.test/circles/17/members/",
   "@type": "ldp:Container",
-  "ldp:contains": [
-  ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "ldp:contains": [],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/oembed.jsonld b/cypress/fixtures/oembed.jsonld
index 95a03703d222e11ed6f70e5e90fb9507908bcfe4..2abbe728a5538ae510dcfa82a0806bc4ee60ebba 100644
--- a/cypress/fixtures/oembed.jsonld
+++ b/cypress/fixtures/oembed.jsonld
@@ -13,4 +13,3 @@
   "thumbnail_url": "https://i.ytimg.com/vi/M3r2XDceM6A/hqdefault.jpg",
   "html": "<iframe width=\"200\" height=\"113\" src=\"https://www.youtube.com/embed/M3r2XDceM6A?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
 }
- 
\ No newline at end of file
diff --git a/cypress/fixtures/profiles-alex.jsonld b/cypress/fixtures/profiles-alex.jsonld
index 927901f93491c034c1f14c33db50688d61f5e129..0f8a2ca727dccb632f35d0dd123285b1db30db88 100644
--- a/cypress/fixtures/profiles-alex.jsonld
+++ b/cypress/fixtures/profiles-alex.jsonld
@@ -9,8 +9,6 @@
   "user": {
     "@id": "https://ldp-server.test/users/alex/"
   },
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/profiles-jbpasquier.jsonld b/cypress/fixtures/profiles-jbpasquier.jsonld
index 943f90f4017107ec49508c45161578e9a858d1ce..c5c49ddc0c8331d631cf66856045eb5443158ccc 100644
--- a/cypress/fixtures/profiles-jbpasquier.jsonld
+++ b/cypress/fixtures/profiles-jbpasquier.jsonld
@@ -9,8 +9,6 @@
   "user": {
     "@id": "https://ldp-server.test/users/jbpasquier/"
   },
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/profiles-matthieu-edited-2.jsonld b/cypress/fixtures/profiles-matthieu-edited-2.jsonld
index 2cf1a1ebc1e36c900b8e5a95c3d989cc621e8e4b..7fed20f57d624f3a56e6df01f0f6900ba0a015dd 100644
--- a/cypress/fixtures/profiles-matthieu-edited-2.jsonld
+++ b/cypress/fixtures/profiles-matthieu-edited-2.jsonld
@@ -9,8 +9,6 @@
   "user": {
     "@id": "https://ldp-server.test/users/matthieu/"
   },
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/profiles-matthieu-edited.jsonld b/cypress/fixtures/profiles-matthieu-edited.jsonld
index 1d3e0d34f5d82e689d393e30e5e2045cb0a2b41c..e51509306fa25aa4248230ead47d6a0e6e89e24d 100644
--- a/cypress/fixtures/profiles-matthieu-edited.jsonld
+++ b/cypress/fixtures/profiles-matthieu-edited.jsonld
@@ -9,8 +9,6 @@
   "user": {
     "@id": "https://ldp-server.test/users/matthieu/"
   },
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/profiles-matthieu.jsonld b/cypress/fixtures/profiles-matthieu.jsonld
index 5a1b6638183fc4cb41436c2ba2e737d75c8b6b30..5c47e1631a649e8eca879ed5518785509799c206 100644
--- a/cypress/fixtures/profiles-matthieu.jsonld
+++ b/cypress/fixtures/profiles-matthieu.jsonld
@@ -9,8 +9,6 @@
   "user": {
     "@id": "https://ldp-server.test/users/matthieu/"
   },
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/users-alex.jsonld b/cypress/fixtures/users-alex.jsonld
index f9e6284ec8946b1bbd1f2bc49409abe146279ea9..64506e7746220fd647aab7b14d8b63d2792876fa 100644
--- a/cypress/fixtures/users-alex.jsonld
+++ b/cypress/fixtures/users-alex.jsonld
@@ -15,8 +15,5 @@
       "get_full_name": "rdfs:label"
     }
   ],
-  "permissions": [
-    "view",
-    "change"
-  ]
+  "permissions": ["view", "change"]
 }
diff --git a/cypress/fixtures/users-edited.jsonld b/cypress/fixtures/users-edited.jsonld
index 5f518d91f2526b327f0baf60dbb23d60904f56a7..8a204e56a154f8e4a3fa5b3f9cb9c55230ea3791 100644
--- a/cypress/fixtures/users-edited.jsonld
+++ b/cypress/fixtures/users-edited.jsonld
@@ -16,10 +16,7 @@
       "@context": {
         "get_full_name": "rdfs:label"
       },
-      "permissions": [
-        "view",
-        "change"
-      ]
+      "permissions": ["view", "change"]
     },
     {
       "@id": "https://ldp-server.test/users/jbpasquier/",
@@ -35,9 +32,7 @@
       "@context": {
         "get_full_name": "rdfs:label"
       },
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "https://ldp-server.test/users/alex/",
@@ -53,14 +48,9 @@
       "@context": {
         "get_full_name": "rdfs:label"
       },
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/users-jbpasquier.jsonld b/cypress/fixtures/users-jbpasquier.jsonld
index bc5472ae2e79fca8d7b267aa5761a3c4024f0517..392e5a7d29eba34c045d7b2018fba3afebea9a85 100644
--- a/cypress/fixtures/users-jbpasquier.jsonld
+++ b/cypress/fixtures/users-jbpasquier.jsonld
@@ -15,8 +15,5 @@
       "get_full_name": "rdfs:label"
     }
   ],
-  "permissions": [
-    "view",
-    "change"
-  ]
+  "permissions": ["view", "change"]
 }
diff --git a/cypress/fixtures/users-matthieu-circles-edited.jsonld b/cypress/fixtures/users-matthieu-circles-edited.jsonld
index 0defa5d0b5520509326f71d484046ebb802039fa..8dfa8711a541a7193be9f6b321f42e125661fac7 100644
--- a/cypress/fixtures/users-matthieu-circles-edited.jsonld
+++ b/cypress/fixtures/users-matthieu-circles-edited.jsonld
@@ -12,10 +12,7 @@
         "name": "circle one"
       },
       "@type": "hd:circlemember",
-      "permissions": [
-        "view",
-        "delete"
-      ]
+      "permissions": ["view", "delete"]
     },
     {
       "@id": "https://ldp-server.test/circle-members/127/",
@@ -27,15 +24,9 @@
         "name": "circle two"
       },
       "@type": "hd:circlemember",
-      "permissions": [
-        "view",
-        "delete"
-      ]
+      "permissions": ["view", "delete"]
     }
   ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/users-matthieu-circles.jsonld b/cypress/fixtures/users-matthieu-circles.jsonld
index 9a59dfb8be044492d3185ed1bcddee0533f82bf4..21fe2692c22ac44b740a79dcc876455d68b64afa 100644
--- a/cypress/fixtures/users-matthieu-circles.jsonld
+++ b/cypress/fixtures/users-matthieu-circles.jsonld
@@ -12,15 +12,9 @@
         "name": "circle one"
       },
       "@type": "hd:circlemember",
-      "permissions": [
-        "view",
-        "delete"
-      ]
+      "permissions": ["view", "delete"]
     }
   ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/users-matthieu-edited.jsonld b/cypress/fixtures/users-matthieu-edited.jsonld
index 1b9e7ceb1d9b39cf91c5522a52c61dfbdbbf5406..5d8134e66a8fbab39551a617337917dfdec6fb9c 100644
--- a/cypress/fixtures/users-matthieu-edited.jsonld
+++ b/cypress/fixtures/users-matthieu-edited.jsonld
@@ -15,8 +15,5 @@
       "get_full_name": "rdfs:label"
     }
   ],
-  "permissions": [
-    "view",
-    "change"
-  ]
+  "permissions": ["view", "change"]
 }
diff --git a/cypress/fixtures/users-matthieu.jsonld b/cypress/fixtures/users-matthieu.jsonld
index 5154239aa4a3001f40dad128ef24822ad10e730a..ecc6e12b4290a03f63ce41907960ae026144e21a 100644
--- a/cypress/fixtures/users-matthieu.jsonld
+++ b/cypress/fixtures/users-matthieu.jsonld
@@ -15,8 +15,5 @@
       "get_full_name": "rdfs:label"
     }
   ],
-  "permissions": [
-    "view",
-    "change"
-  ]
+  "permissions": ["view", "change"]
 }
diff --git a/cypress/fixtures/users-nantes.jsonld b/cypress/fixtures/users-nantes.jsonld
index 4380d82982217ac1a9fd1f2a2d7e16e5192855ec..7a6d3a3a216aaaac5043b2430bcb49116ebc1e38 100644
--- a/cypress/fixtures/users-nantes.jsonld
+++ b/cypress/fixtures/users-nantes.jsonld
@@ -16,14 +16,9 @@
       "@context": {
         "get_full_name": "rdfs:label"
       },
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/users-paris.jsonld b/cypress/fixtures/users-paris.jsonld
index e7be80cebe27e158f8ca7179047b6bff57925b37..7647ca2cae2ee5affc75477d831622765763734c 100644
--- a/cypress/fixtures/users-paris.jsonld
+++ b/cypress/fixtures/users-paris.jsonld
@@ -16,10 +16,7 @@
       "@context": {
         "get_full_name": "rdfs:label"
       },
-      "permissions": [
-        "view",
-        "change"
-      ]
+      "permissions": ["view", "change"]
     },
     {
       "@id": "https://ldp-server.test/users/jbpasquier/",
@@ -35,14 +32,9 @@
       "@context": {
         "get_full_name": "rdfs:label"
       },
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/cypress/fixtures/users-source.jsonld b/cypress/fixtures/users-source.jsonld
index 9058bca692f517b73bb3e782753ff92544d3f4d3..459ef51e9b06b518e3ad0cc035cc279ebcba5f16 100644
--- a/cypress/fixtures/users-source.jsonld
+++ b/cypress/fixtures/users-source.jsonld
@@ -6,21 +6,15 @@
       "federation": "users",
       "@id": "https://ldp-server.test/users/",
       "@type": "sib:federatedContainer",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "federation": "users",
       "@id": "https://ldp-server2.test/users/",
       "@type": "sib:federatedContainer",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/cypress/index.d.ts b/cypress/index.d.ts
index 6f0b0745ec4da0e1e2f4209a29885ba0c764b3c1..9e0ae69c8908a67c6c91448ed0001beda2ff8be9 100644
--- a/cypress/index.d.ts
+++ b/cypress/index.d.ts
@@ -1,14 +1,13 @@
-
 declare namespace Cypress {
   interface Chainable {
     /**
      * Load file in <input type="file">
      * @example cy.get('input[type=file]').uploadFile('./img/image.jpg')
-    */
-   uploadFile(fileName: string): Chainable<Element>
+     */
+    uploadFile(fileName: string): Chainable<Element>;
   }
 }
 
 interface Window {
-  sibStore: any
-}
\ No newline at end of file
+  sibStore: import('../src/libs/store/store').Store;
+}
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
index 6a17dae138f15b08b917d4f0eec705fab80f253c..15a942ee17b9caa15e90e0aa1506fd47277cd160 100644
--- a/cypress/plugins/index.js
+++ b/cypress/plugins/index.js
@@ -11,4 +11,4 @@
 // This function is called when a project is opened or re-opened (e.g. due to
 // the project's config changing)
 
-module.exports = (on, config) => {};
+module.exports = (_on, _config) => {};
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index 11869a8c4403a5f66ccda26026461b0bc704e977..ab88c9664ca6a61e0cf39306d3b3fc56e050e9bc 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -24,16 +24,20 @@
 // -- This will overwrite an existing command --
 // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
 
-Cypress.Commands.add('uploadFile', { prevSubject: true }, (subject, fileName) => {
-  cy.fixture(fileName).then((content) => {
-      const el = subject[0]
-      const testFile = new File([content], fileName)
-      const dataTransfer = new DataTransfer()
-      dataTransfer.items.add(testFile)
-      el.files = dataTransfer.files
-      cy.wrap(subject).trigger('change', { force: true })
-  })
-});
+Cypress.Commands.add(
+  'uploadFile',
+  { prevSubject: true },
+  (subject, fileName) => {
+    cy.fixture(fileName).then(content => {
+      const el = subject[0];
+      const testFile = new File([content], fileName);
+      const dataTransfer = new DataTransfer();
+      dataTransfer.items.add(testFile);
+      el.files = dataTransfer.files;
+      cy.wrap(subject).trigger('change', { force: true });
+    });
+  },
+);
 
 Cypress.Commands.add('iframe', { prevSubject: 'element' }, $iframe => {
   return new Cypress.Promise(resolve => {
@@ -41,4 +45,4 @@ Cypress.Commands.add('iframe', { prevSubject: 'element' }, $iframe => {
       resolve($iframe.contents().find('body'));
     });
   });
-});
\ No newline at end of file
+});
diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js
index 537ef46fb10f6ad823f1decaabef1401653458cc..d7d0b817fb9e9374b2d4113e35ca3bb705735985 100644
--- a/cypress/support/e2e.js
+++ b/cypress/support/e2e.js
@@ -14,7 +14,7 @@
 // ***********************************************************
 
 // Import commands.js using ES2015 syntax:
-import './commands'
+import './commands.js';
 
 // Alternatively you can use CommonJS syntax:
 // require('./commands')
@@ -25,5 +25,5 @@ import '@rckeller/cypress-unfetch';
 import 'cypress-plugin-tab';
 
 Cypress.on('uncaught:exception', () => {
-  return false
-})
+  return false;
+});
diff --git a/examples/data/calendar/event-1.jsonld b/examples/data/calendar/event-1.jsonld
deleted file mode 100644
index d7d6820f7e28224f2287dc1b21bad536fe79ab06..0000000000000000000000000000000000000000
--- a/examples/data/calendar/event-1.jsonld
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-	"@id": "/examples/data/calendar/event-1.jsonld",
-	"name": "Test",
-	"deadline": "2019-09-09T19:55:44Z",
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
diff --git a/examples/data/calendar/event-2.jsonld b/examples/data/calendar/event-2.jsonld
deleted file mode 100644
index e27b349852768e38b14ac5ca8763940b7e0ca80f..0000000000000000000000000000000000000000
--- a/examples/data/calendar/event-2.jsonld
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-	"@id": "/examples/data/calendar/event-2.jsonld",
-	"name": "Test demain",
-	"deadline": "2019-09-10T19:55:56Z",
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
diff --git a/examples/data/calendar/events.jsonld b/examples/data/calendar/events.jsonld
deleted file mode 100644
index d539f88e8dd03d0d2fc63dc709d37b3a13b1c853..0000000000000000000000000000000000000000
--- a/examples/data/calendar/events.jsonld
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-	"@type": "ldp:Container",
-	"ldp:contains": [{
-		"@id": "/examples/data/calendar/event-1.jsonld",
-		"name": "Test",
-		"deadline": "2019-09-09T19:55:44Z",
-		"permissions": []
-	}, {
-		"@id": "/examples/data/calendar/event-2.jsonld",
-		"name": "Test demain",
-		"deadline": "2019-09-10T19:55:56Z",
-		"permissions": []
-	}],
-	"@id": "/examples/data/calendar/events.jsonld",
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
diff --git a/examples/data/carrot.jsonld b/examples/data/carrot.jsonld
index 86eb0aad420678934ec511bb753d7d8beab4565f..9fd84be63ac1fadb4a097bc6e0462ca7fd6347cb 100644
--- a/examples/data/carrot.jsonld
+++ b/examples/data/carrot.jsonld
@@ -11,11 +11,5 @@
   "dfc-b:hasType": {
     "@id": "dfc-pt:carrot"
   },
-  "permissions": [
-    "view",
-    "control",
-    "add",
-    "delete",
-    "change"
-  ]
-}
\ No newline at end of file
+  "permissions": ["view", "control", "add", "delete", "change"]
+}
diff --git a/examples/data/dfc-enterprise.jsonld b/examples/data/dfc-enterprise.jsonld
index 59c979faf1ec754aecbdf8adf6f416bc6c4f3d51..76b20af8e4708ee6dae08a022a30eba14d706caf 100644
--- a/examples/data/dfc-enterprise.jsonld
+++ b/examples/data/dfc-enterprise.jsonld
@@ -52,11 +52,5 @@
       "dfc-b:offeredThrough": "http://test.host/api/dfc/enterprises/10000/offers/10001"
     }
   ],
-  "permissions": [
-    "view",
-    "control",
-    "add",
-    "delete",
-    "change"
-  ]
-}
\ No newline at end of file
+  "permissions": ["view", "control", "add", "delete", "change"]
+}
diff --git a/examples/data/empty-container.jsonld b/examples/data/empty-container.jsonld
index 5251752e0bb74dc488b34df851128ed217f6cc8f..c3f49e87a9a1fe70a51dc319f853a5813f15827f 100644
--- a/examples/data/empty-container.jsonld
+++ b/examples/data/empty-container.jsonld
@@ -2,12 +2,6 @@
   "@id": "/examples/data/empty-container.jsonld",
   "@type": "ldp:Container",
   "ldp:contains": [],
-  "permissions": [
-    "view",
-    "control",
-    "add",
-    "delete",
-    "change"
-  ],
+  "permissions": ["view", "control", "add", "delete", "change"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/extra-context/user-1.jsonld b/examples/data/extra-context/user-1.jsonld
index 1eb8d30d633e019ed0a9a343d1a7a16d96aebadb..f3626b9327232a3294f5768163126fe256c49990 100644
--- a/examples/data/extra-context/user-1.jsonld
+++ b/examples/data/extra-context/user-1.jsonld
@@ -6,8 +6,6 @@
   "email": "test-user@example.com",
   "name": "Test User",
   "@type": "foaf:user",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/extra-context/user-2.jsonld b/examples/data/extra-context/user-2.jsonld
index b71760abef6c6ab2d0138513e3b4d6db5aa8e180..c6cbf400b82690f8d2c34c29dc822ccc1b6d1c78 100644
--- a/examples/data/extra-context/user-2.jsonld
+++ b/examples/data/extra-context/user-2.jsonld
@@ -6,8 +6,6 @@
   "email": "paris@hilton.hi",
   "name": "Paris Hilton",
   "@type": "foaf:user",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/extra-context/user-6.jsonld b/examples/data/extra-context/user-6.jsonld
index e94bd05e1edb23a0c140c7664cbf606cd60a519d..d5c361311efc398bb8bebdc87ac193b28ba02f6e 100644
--- a/examples/data/extra-context/user-6.jsonld
+++ b/examples/data/extra-context/user-6.jsonld
@@ -13,8 +13,6 @@
     "picture": "my-avatar.png"
   },
   "@type": "foaf:user",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/extra-context/users.jsonld b/examples/data/extra-context/users.jsonld
index e8e0d5da776b10e9423cdbc0bd28a3ef4d49326f..0085b852f1b8fc1fb6ed9697d0d5c367fc7f22b7 100644
--- a/examples/data/extra-context/users.jsonld
+++ b/examples/data/extra-context/users.jsonld
@@ -10,9 +10,7 @@
       "email": "test-user@example.com",
       "name": "Test User",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "http://localhost:3000/examples/data/extra-context/user-2.jsonld",
@@ -22,13 +20,9 @@
       "email": "paris@hilton.hi",
       "name": "Paris Hilton",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/federation/circles-server1.jsonld b/examples/data/federation/circles-server1.jsonld
index cdc45002afdc371a5df5dfa366d079054b64cab6..ced7e406094241f9020e5d60cd39bfeb1306ebca 100644
--- a/examples/data/federation/circles-server1.jsonld
+++ b/examples/data/federation/circles-server1.jsonld
@@ -13,9 +13,7 @@
       "jabberID": "3oa55lvwyzs6@conference.test1.startinblox.com",
       "jabberRoom": true,
       "@type": "hd:circle",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/federation/circles-2.jsonld",
@@ -28,14 +26,9 @@
       "jabberID": "3oa55lvwyqq6@conference.test1.startinblox.com",
       "jabberRoom": true,
       "@type": "hd:circle",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/federation/circles-server2.jsonld b/examples/data/federation/circles-server2.jsonld
index 064c55d345a8cacebd55cbe0c2d665031a763e81..63de5a56dbe2a357fc0dc9855f14bcb91e9bf30a 100644
--- a/examples/data/federation/circles-server2.jsonld
+++ b/examples/data/federation/circles-server2.jsonld
@@ -13,9 +13,7 @@
       "jabberID": "3oa5aaaazee6@conference.test1.startinblox.com",
       "jabberRoom": true,
       "@type": "hd:circle",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/federation/circles-4.jsonld",
@@ -28,14 +26,9 @@
       "jabberID": "3oa55lvwyqq6@conference.test1.startinblox.com",
       "jabberRoom": true,
       "@type": "hd:circle",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/federation/circles-server3.jsonld b/examples/data/federation/circles-server3.jsonld
index 106257fc7b5dc9a4008dd6040546524d0604548e..8dfc96e220369a1881629d75596e25a2aa82c3f7 100644
--- a/examples/data/federation/circles-server3.jsonld
+++ b/examples/data/federation/circles-server3.jsonld
@@ -13,9 +13,7 @@
       "jabberID": "3oa5aaaazee6@conference.test1.startinblox.com",
       "jabberRoom": true,
       "@type": "hd:circle",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/federation/circles-1.jsonld",
@@ -28,14 +26,9 @@
       "jabberID": "3oa55lvwyzs6@conference.test1.startinblox.com",
       "jabberRoom": true,
       "@type": "hd:circle",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/federation/circles-server4.jsonld b/examples/data/federation/circles-server4.jsonld
index 2567bcfd9cc86aafc299f4fd2173e48639446133..9b86be1616c417240a88da924f5d8797ea02b555 100644
--- a/examples/data/federation/circles-server4.jsonld
+++ b/examples/data/federation/circles-server4.jsonld
@@ -13,14 +13,9 @@
       "jabberID": "3oa5aaaazee6@conference.test1.startinblox.com",
       "jabberRoom": true,
       "@type": "hd:circle",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "add",
-    "view"
-  ],
+  "permissions": ["add", "view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/federation/nested-source.jsonld b/examples/data/federation/nested-source.jsonld
index dbc759f9942ce47861fa4ae1e924fe189047d250..12f8db3cbf59747c3858e8c79d83f166fe825e14 100644
--- a/examples/data/federation/nested-source.jsonld
+++ b/examples/data/federation/nested-source.jsonld
@@ -6,9 +6,7 @@
       "federation": "circles",
       "@id": "/examples/data/federation/circles-server1.jsonld",
       "@type": "sib:federatedContainer",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/federation/circles-server2.jsonld",
@@ -23,8 +21,6 @@
       "@type": "sib:federatedContainer"
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/federation/source1.jsonld b/examples/data/federation/source1.jsonld
index 12e8c65c44e05393e49d78e22335469692392e17..3574646526f62de8ae560152046da28966403c21 100644
--- a/examples/data/federation/source1.jsonld
+++ b/examples/data/federation/source1.jsonld
@@ -6,17 +6,13 @@
       "federation": "circles",
       "@id": "/examples/data/federation/circles-server1.jsonld",
       "@type": "sib:federatedContainer",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/federation/circles-server2.jsonld",
       "@type": "sib:federatedContainer"
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/federation/source2.jsonld b/examples/data/federation/source2.jsonld
index 91a2a8e94952d65efe08270c6e7fb0f3f060cc73..5d2b0818720b8774ecfaa985203bd4e1c8e0b061 100644
--- a/examples/data/federation/source2.jsonld
+++ b/examples/data/federation/source2.jsonld
@@ -6,17 +6,13 @@
       "federation": "circles",
       "@id": "/examples/data/federation/circles-server3.jsonld",
       "@type": "sib:federatedContainer",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/federation/circles-server4.jsonld",
       "@type": "sib:federatedContainer"
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/galaxy.jsonld b/examples/data/galaxy.jsonld
index 72e86a46149804d2a34507d6e142e632571b3520..19603f083b1c6839ea34f61a711a7a78fb7f46cc 100644
--- a/examples/data/galaxy.jsonld
+++ b/examples/data/galaxy.jsonld
@@ -179,11 +179,5 @@
       }
     }
   ],
-  "permissions": [
-    "view",
-    "control",
-    "add",
-    "delete",
-    "change"
-  ]
-}
\ No newline at end of file
+  "permissions": ["view", "control", "add", "delete", "change"]
+}
diff --git a/examples/data/groups/group1.jsonld b/examples/data/groups/group1.jsonld
index 7537d63429c65d8b0555b25abeecbf46c5da34f2..658ee380b4cb73fa32925e62fc8847a5419e7aeb 100644
--- a/examples/data/groups/group1.jsonld
+++ b/examples/data/groups/group1.jsonld
@@ -8,8 +8,6 @@
       "@id": "/examples/data/list/--user-2.jsonld"
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/image.jsonld b/examples/data/image.jsonld
index 532b474c0a044f79f75e31a036b8aa5e88eba5bf..e9625b972470a5f27bc7fa25bac4a395d0447180 100644
--- a/examples/data/image.jsonld
+++ b/examples/data/image.jsonld
@@ -4,11 +4,5 @@
   "description": "basket containing apples, oranges, kiwis, bananas, pineapples\u2026",
   "picture": "../../upload/fruits.jpg",
   "@context": "https://cdn.startinblox.com/owl/context.jsonld",
-  "permissions": [
-    "view",
-    "control",
-    "add",
-    "delete",
-    "change"
-  ]
-}
\ No newline at end of file
+  "permissions": ["view", "control", "add", "delete", "change"]
+}
diff --git a/examples/data/list/chewbacca.jsonld b/examples/data/list/chewbacca.jsonld
index 2a94287b075d04ab2c76b850f280e9c694c9f378..ffeec6d6415a19fdf8ddb618ad23f5fe26212d32 100644
--- a/examples/data/list/chewbacca.jsonld
+++ b/examples/data/list/chewbacca.jsonld
@@ -1,5 +1,5 @@
 {
-	"@id": "/examples/data/list/examples/data/list/chewbacca.jsonld",
-	"name": "Chewbacca",
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
+  "@id": "/examples/data/list/examples/data/list/chewbacca.jsonld",
+  "name": "Chewbacca",
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/list/colibris.jsonld b/examples/data/list/colibris.jsonld
index f47c67f8dda3735a913ce964a04a11957421a8f7..4204ed56e1aa182e0e73e68687defb69e7b8a1d2 100644
--- a/examples/data/list/colibris.jsonld
+++ b/examples/data/list/colibris.jsonld
@@ -5,139 +5,71 @@
   "ldp:contains": [
     {
       "@id": "/examples/data/list/universite.jsonld",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/bots.jsonld",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/miniparcours",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/users",
-      "@type": [
-        "ldp:BasicContainer",
-        "ldp:Container",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:BasicContainer", "ldp:Container", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/lafabrique",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/laboutique",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/lemouvement",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/groupeslocaux",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/activities",
-      "@type": [
-        "ldp:BasicContainer",
-        "ldp:Container",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:BasicContainer", "ldp:Container", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/lemag",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/status",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/themes",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/files",
-      "@type": [
-        "ldp:BasicContainer",
-        "ldp:Container",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:BasicContainer", "ldp:Container", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/@types",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/services",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/skills",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     },
     {
       "@id": "/examples/data/list/presdecheznous",
-      "@type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "@type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     }
   ]
 }
diff --git a/examples/data/list/community-group.jsonld b/examples/data/list/community-group.jsonld
index eafa7d00fb99e61f7a916b4661e4c945176242c4..300f75a14a20b3f624e688bff49b845820325efd 100644
--- a/examples/data/list/community-group.jsonld
+++ b/examples/data/list/community-group.jsonld
@@ -33,7 +33,5 @@
       "user_set": "foaf:member"
     }
   ],
-  "permissions": [
-    "view"
-  ]
+  "permissions": ["view"]
 }
diff --git a/examples/data/list/darth-vader.json b/examples/data/list/darth-vader.json
index b6b8d6d33291c099626d699402c640de5bc8c71b..912d99ac54fe5f269327a51f3e90dbc381428745 100644
--- a/examples/data/list/darth-vader.json
+++ b/examples/data/list/darth-vader.json
@@ -1,5 +1,5 @@
 {
-	"@id": "/examples/data/list/examples/data/list/darth-vader.json",
-	"name": "Darth Vader",
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
+  "@id": "/examples/data/list/examples/data/list/darth-vader.json",
+  "name": "Darth Vader",
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/list/event-1.jsonld b/examples/data/list/event-1.jsonld
index be932c4d2ecdf13a612e080caf647566dd7733d1..2695942f2daa9bb6497181ef7b6f4918a089f9c5 100644
--- a/examples/data/list/event-1.jsonld
+++ b/examples/data/list/event-1.jsonld
@@ -1,12 +1,12 @@
 {
-	"@id": "/examples/data/list/event-1.jsonld",
-	"name": "Coliving",
-	"date": "2020-07-09",
-	"seats": 12,
-	"description": "some description",
-	"contact": {
-		"@id": "/examples/data/list/user-1.jsonld"
-	},
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
+  "@id": "/examples/data/list/event-1.jsonld",
+  "name": "Coliving",
+  "date": "2020-07-09",
+  "seats": 12,
+  "description": "some description",
+  "contact": {
+    "@id": "/examples/data/list/user-1.jsonld"
+  },
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/list/event-2.jsonld b/examples/data/list/event-2.jsonld
index 63a038775cf9306851b8d3d0f2bb5766792f9bd6..5ead38247ac30be1f8e1732d456c4de24aaab4f1 100644
--- a/examples/data/list/event-2.jsonld
+++ b/examples/data/list/event-2.jsonld
@@ -1,11 +1,11 @@
 {
-	"@id": "/examples/data/list/event-2.jsonld",
-	"name": "Workshop",
-	"date": "2020-05-10",
-	"seats": 2,
-	"contact": {
-		"@id": "/examples/data/list/user-2.jsonld"
-	},
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
+  "@id": "/examples/data/list/event-2.jsonld",
+  "name": "Workshop",
+  "date": "2020-05-10",
+  "seats": 2,
+  "contact": {
+    "@id": "/examples/data/list/user-2.jsonld"
+  },
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/list/event-3.jsonld b/examples/data/list/event-3.jsonld
index 7b60d50788b0a245fa94fa85859dd990cc13ce21..f147886cbc7714f6dd89f9da179cc9f672ab4137 100644
--- a/examples/data/list/event-3.jsonld
+++ b/examples/data/list/event-3.jsonld
@@ -1,11 +1,11 @@
 {
-	"@id": "/examples/data/list/event-3.jsonld",
-	"name": "Réunion d'information",
-	"date": "2020-07-10",
-	"seats": 230,
-	"contact": {
-		"@id": "/examples/data/list/user-3.jsonld"
-	},
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
+  "@id": "/examples/data/list/event-3.jsonld",
+  "name": "Réunion d'information",
+  "date": "2020-07-10",
+  "seats": 230,
+  "contact": {
+    "@id": "/examples/data/list/user-3.jsonld"
+  },
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/list/event-4.jsonld b/examples/data/list/event-4.jsonld
index f93aa92769ea323141871faaceeb4eb5b2a81389..0bb9359867f7999872bfb7f9533015e41af36b43 100644
--- a/examples/data/list/event-4.jsonld
+++ b/examples/data/list/event-4.jsonld
@@ -1,11 +1,11 @@
 {
-	"@id": "/examples/data/list/event-4.jsonld",
-	"name": "Assemblée générale",
-	"date": "2020-05-10",
-	"seats": 55,
-	"contact": {
-		"@id": "/examples/data/list/user-4.jsonld"
-	},
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
+  "@id": "/examples/data/list/event-4.jsonld",
+  "name": "Assemblée générale",
+  "date": "2020-05-10",
+  "seats": 55,
+  "contact": {
+    "@id": "/examples/data/list/user-4.jsonld"
+  },
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/list/event-5.jsonld b/examples/data/list/event-5.jsonld
index e81d0a811373ed71a890bd8919beb114068d7a6a..4e9540f5f89b81e402cc9a4f193ba2c64c21d140 100644
--- a/examples/data/list/event-5.jsonld
+++ b/examples/data/list/event-5.jsonld
@@ -1,67 +1,67 @@
 {
-	"@type": "ldp:Container",
-	"ldp:contains": [
-		{
-			"@id": "/examples/data/list/event-1.jsonld",
-			"name": "Coliving",
-			"date": "2020-07-09",
-			"year": 2020,
-			"seats": 12,
-			"place":"",
-			"city":"",
-			"permissions": []
-		},
-		{
-			"@id": "/examples/data/list/event-2.jsonld",
-			"name": "Workshop3",
-			"date": "2020-05-10",
-			"year": 2020,
-			"seats": 2,
-			"place":"Opéra",
-			"city":"",
-			"permissions": []
-		},
-		{
-			"@id": "/examples/data/list/event-3.jsonld",
-			"name": "Workshop1",
-			"date": "2017-05-10",
-			"year": 2017,
-			"seats": 23,
-			"place":"Opéra3",
-			"city":"",
-			"permissions": []
-		},
-		{
-			"@id": "/examples/data/list/event-4.jsonld",
-			"name": "Workshop",
-			"date": "2015-05-10",
-			"year": 2015,
-			"seats": 2,
-			"place":"Opéra2",
-			"city":"",
-			"permissions": []
-		},
-		{
-			"@id": "/examples/data/list/event-5.jsonld",
-			"name": "Réunion d'information",
-			"date": "2020-07-10",
-			"year": 2020,
-			"seats": 36,
-			"place":"Couvent des jacobins",
-			"city":"Rennes",
-			"permissions": []
-		},
-		{
-			"@id": "/examples/data/list/event-6.jsonld",
-			"name": "Assemblée générale",
-			"date": "2020-05-10",
-			"year": 2019,
-			"seats": 5,
-			"place":"",
-			"city":"Marseille",
-			"permissions": []
-		}
-	],
-	"@id": "/examples/data/list/event-5.jsonld",
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
+  "@type": "ldp:Container",
+  "ldp:contains": [
+    {
+      "@id": "/examples/data/list/event-1.jsonld",
+      "name": "Coliving",
+      "date": "2020-07-09",
+      "year": 2020,
+      "seats": 12,
+      "place": "",
+      "city": "",
+      "permissions": []
+    },
+    {
+      "@id": "/examples/data/list/event-2.jsonld",
+      "name": "Workshop3",
+      "date": "2020-05-10",
+      "year": 2020,
+      "seats": 2,
+      "place": "Opéra",
+      "city": "",
+      "permissions": []
+    },
+    {
+      "@id": "/examples/data/list/event-3.jsonld",
+      "name": "Workshop1",
+      "date": "2017-05-10",
+      "year": 2017,
+      "seats": 23,
+      "place": "Opéra3",
+      "city": "",
+      "permissions": []
+    },
+    {
+      "@id": "/examples/data/list/event-4.jsonld",
+      "name": "Workshop",
+      "date": "2015-05-10",
+      "year": 2015,
+      "seats": 2,
+      "place": "Opéra2",
+      "city": "",
+      "permissions": []
+    },
+    {
+      "@id": "/examples/data/list/event-5.jsonld",
+      "name": "Réunion d'information",
+      "date": "2020-07-10",
+      "year": 2020,
+      "seats": 36,
+      "place": "Couvent des jacobins",
+      "city": "Rennes",
+      "permissions": []
+    },
+    {
+      "@id": "/examples/data/list/event-6.jsonld",
+      "name": "Assemblée générale",
+      "date": "2020-05-10",
+      "year": 2019,
+      "seats": 5,
+      "place": "",
+      "city": "Marseille",
+      "permissions": []
+    }
+  ],
+  "@id": "/examples/data/list/event-5.jsonld",
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/list/event-6.jsonld b/examples/data/list/event-6.jsonld
new file mode 100644
index 0000000000000000000000000000000000000000..9a36c477e9fb38b07a3a749ed14a5777be59e5eb
--- /dev/null
+++ b/examples/data/list/event-6.jsonld
@@ -0,0 +1,12 @@
+{
+  "@id": "/examples/data/list/event-6.jsonld",
+  "name": "Coliving",
+  "date": "2020-07-09",
+  "seats": 12,
+  "description": "Première ligne\r\n\r\n\r\n\r\nSeconde Ligne avec quatre sauts de ligne",
+  "contact": {
+    "@id": "/examples/data/list/user-1.jsonld"
+  },
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+}
diff --git a/examples/data/list/event-empty.jsonld b/examples/data/list/event-empty.jsonld
index d35de1493fdb1fd6c1039e84935bb3d254730674..c952e62f6d5adb7a34f2dbe28eeb328c41dfeec1 100644
--- a/examples/data/list/event-empty.jsonld
+++ b/examples/data/list/event-empty.jsonld
@@ -1,12 +1,12 @@
 {
-	"@id": "/examples/data/list/event-empty.jsonld",
-	"name": "",
-	"date": "",
-	"seats": 0,
-	"description": "",
-	"contact": {
-		"@id": "/examples/data/list/user-1.jsonld"
-	},
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
+  "@id": "/examples/data/list/event-empty.jsonld",
+  "name": "",
+  "date": "",
+  "seats": 0,
+  "description": "",
+  "contact": {
+    "@id": "/examples/data/list/user-1.jsonld"
+  },
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/list/events.jsonld b/examples/data/list/events.jsonld
index 85d9a78b8662b10582981a727dcb72d28e0ada47..453a9df42208e04fb9c77129dd996313b12210c3 100644
--- a/examples/data/list/events.jsonld
+++ b/examples/data/list/events.jsonld
@@ -1,43 +1,43 @@
 {
-	"@type": "ldp:Container",
-	"ldp:contains": [
-		{
-			"@id": "/examples/data/list/event-1.jsonld",
-			"name": "Coliving",
-			"date": "2020-07-09",
-			"seats": 12,
-			"place":"",
-			"city":"",
-			"permissions": []
-		},
-		{
-			"@id": "/examples/data/list/event-2.jsonld",
-			"name": "Workshop",
-			"date": "2020-05-10",
-			"seats": 2,
-			"place":"Opéra",
-			"city":"",
-			"permissions": []
-		},
-		{
-			"@id": "/examples/data/list/event-3.jsonld",
-			"name": "Réunion d'information",
-			"date": "2020-07-10",
-			"seats": 36,
-			"place":"Couvent des jacobins",
-			"city":"Rennes",
-			"permissions": []
-		},
-		{
-			"@id": "/examples/data/list/event-4.jsonld",
-			"name": "Assemblée générale",
-			"date": "2020-05-10",
-			"seats": 5,
-			"place":"",
-			"city":"Marseille",
-			"permissions": []
-		}
-	],
-	"@id": "/examples/data/list/events.jsonld",
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
+  "@type": "ldp:Container",
+  "ldp:contains": [
+    {
+      "@id": "/examples/data/list/event-1.jsonld",
+      "name": "Coliving",
+      "date": "2020-07-09",
+      "seats": 12,
+      "place": "",
+      "city": "",
+      "permissions": []
+    },
+    {
+      "@id": "/examples/data/list/event-2.jsonld",
+      "name": "Workshop",
+      "date": "2020-05-10",
+      "seats": 2,
+      "place": "Opéra",
+      "city": "",
+      "permissions": []
+    },
+    {
+      "@id": "/examples/data/list/event-3.jsonld",
+      "name": "Réunion d'information",
+      "date": "2020-07-10",
+      "seats": 36,
+      "place": "Couvent des jacobins",
+      "city": "Rennes",
+      "permissions": []
+    },
+    {
+      "@id": "/examples/data/list/event-4.jsonld",
+      "name": "Assemblée générale",
+      "date": "2020-05-10",
+      "seats": 5,
+      "place": "",
+      "city": "Marseille",
+      "permissions": []
+    }
+  ],
+  "@id": "/examples/data/list/events.jsonld",
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
 }
diff --git a/examples/data/list/group-3.jsonld b/examples/data/list/group-3.jsonld
index ba821d132f41c1198bfbaa0389b0fc5ac6f4ab46..103d8374c46ae337640b7488a6c65eb5bda24c2a 100644
--- a/examples/data/list/group-3.jsonld
+++ b/examples/data/list/group-3.jsonld
@@ -1,50 +1,50 @@
 {
   "name": "LDP_circle_members_1",
   "members": [
-      {
-        "@id": "/examples/data/list/user-2.jsonld",
-        "@type": "foaf:user",
-        "name": "Benoit Alessandroni",
-        "email": "benoit@toto.com",
-        "last_name": "Alessandroni",
-        "first_name": "Benoit",
-        "@context": {
-          "get_full_name": "rdfs:label"
-        }
-      },
-      {
-        "@id": "/examples/data/list/user-1.jsonld",
-        "@type": "foaf:user",
-        "name": "Blaise Pascal",
-        "email": "blaise@toto.com",
-        "last_name": "Pascal",
-        "first_name": "Blaise",
-        "@context": {
-          "get_full_name": "rdfs:label"
-        }
-      },
-      {
-        "@id": "/examples/data/list/user-3.jsonld",
-        "@type": "foaf:user",
-        "name": "Vitali Klitschko",
-        "email": "blaise@toto.com",
-        "last_name": "Klitschko",
-        "first_name": "Vitali",
-        "@context": {
-          "get_full_name": "rdfs:label"
-        }
-      },
-      {
-        "@id": "/examples/data/list/user-4.jsonld",
-        "@type": "foaf:user",
-        "name": "Eric Cantona",
-        "email": "cantona@toto.com",
-        "last_name": "Cantona",
-        "first_name": "Eric",
-        "@context": {
-          "get_full_name": "rdfs:label"
-        }
+    {
+      "@id": "/examples/data/list/user-2.jsonld",
+      "@type": "foaf:user",
+      "name": "Benoit Alessandroni",
+      "email": "benoit@toto.com",
+      "last_name": "Alessandroni",
+      "first_name": "Benoit",
+      "@context": {
+        "get_full_name": "rdfs:label"
+      }
+    },
+    {
+      "@id": "/examples/data/list/user-1.jsonld",
+      "@type": "foaf:user",
+      "name": "Blaise Pascal",
+      "email": "blaise@toto.com",
+      "last_name": "Pascal",
+      "first_name": "Blaise",
+      "@context": {
+        "get_full_name": "rdfs:label"
+      }
+    },
+    {
+      "@id": "/examples/data/list/user-3.jsonld",
+      "@type": "foaf:user",
+      "name": "Vitali Klitschko",
+      "email": "blaise@toto.com",
+      "last_name": "Klitschko",
+      "first_name": "Vitali",
+      "@context": {
+        "get_full_name": "rdfs:label"
+      }
+    },
+    {
+      "@id": "/examples/data/list/user-4.jsonld",
+      "@type": "foaf:user",
+      "name": "Eric Cantona",
+      "email": "cantona@toto.com",
+      "last_name": "Cantona",
+      "first_name": "Eric",
+      "@context": {
+        "get_full_name": "rdfs:label"
       }
+    }
   ],
   "events": {
     "@type": "ldp:Container",
@@ -55,8 +55,8 @@
         "name": "Coliving",
         "date": "2020-07-09",
         "seats": 12,
-        "place":"",
-        "city":"",
+        "place": "",
+        "city": "",
         "permissions": []
       },
       {
@@ -64,8 +64,8 @@
         "name": "Workshop",
         "date": "2020-05-10",
         "seats": 2,
-        "place":"Opéra",
-        "city":"",
+        "place": "Opéra",
+        "city": "",
         "permissions": []
       }
     ]
@@ -77,7 +77,5 @@
   "admin_circle": null,
   "@id": "/examples/data/list/group-3.jsonld",
   "@type": "foaf:Group",
-  "@context": [
-    "https://cdn.startinblox.com/owl/context.jsonld"
-  ]
+  "@context": ["https://cdn.startinblox.com/owl/context.jsonld"]
 }
diff --git a/examples/data/list/job-1.jsonld b/examples/data/list/job-1.jsonld
index a256e69b19a3deaea83a6800d9b4d46eab257f2f..2c493c67a4ec107ff31eafdbe8cdd20379ed3563 100644
--- a/examples/data/list/job-1.jsonld
+++ b/examples/data/list/job-1.jsonld
@@ -11,11 +11,9 @@
       },
       {
         "@id": "/examples/data/list/skill-4.jsonld"
-      }      
+      }
     ]
   },
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/profile-1.jsonld b/examples/data/list/profile-1.jsonld
index e00d67bf93c88163ce6c9163ca1754b440dc0e1e..7074cc28524ead26bf9c889b57969aa7bfd102a1 100644
--- a/examples/data/list/profile-1.jsonld
+++ b/examples/data/list/profile-1.jsonld
@@ -10,8 +10,6 @@
   "city": "Paris",
   "phone": "06-03-23-98-23",
   "website": "www.startinblox.com",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/profile-2.jsonld b/examples/data/list/profile-2.jsonld
index 558806b3203ab457f0321be3187ad53d12c2aabd..8c6dcee1dc9d20b3c8ea9e8b12d9d5178a9e0cb7 100644
--- a/examples/data/list/profile-2.jsonld
+++ b/examples/data/list/profile-2.jsonld
@@ -10,8 +10,6 @@
   "city": "Paris",
   "phone": "",
   "website": "",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/profile-3.jsonld b/examples/data/list/profile-3.jsonld
index 4ec2e70412edda351cf65d2e3db305a92f7417fa..b5520a0afd0c9455e4e6a7e8e2f486738dc21de0 100644
--- a/examples/data/list/profile-3.jsonld
+++ b/examples/data/list/profile-3.jsonld
@@ -10,8 +10,6 @@
   "city": "Rennes",
   "phone": "",
   "website": "",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/profile-4.jsonld b/examples/data/list/profile-4.jsonld
index c51f3cb339986e2699f26b812ba99006f8351f47..850f2999fa1c3219e91fa6f64685008c66df8179 100644
--- a/examples/data/list/profile-4.jsonld
+++ b/examples/data/list/profile-4.jsonld
@@ -10,8 +10,6 @@
   "city": "",
   "phone": "",
   "website": "",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/profile-5.jsonld b/examples/data/list/profile-5.jsonld
index cf52fc446b06c10f3156b191ce3c7571583fc209..67be8b94b954a59879f084b4b483f6a4985716dd 100644
--- a/examples/data/list/profile-5.jsonld
+++ b/examples/data/list/profile-5.jsonld
@@ -10,8 +10,6 @@
   "city": "",
   "phone": "",
   "website": "[my site](http://drawing.garden/)",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/skill-1.jsonld b/examples/data/list/skill-1.jsonld
index 779d8d675982ed044b64a6164dcab78be286960b..efee030021df598eb7291bc969f89403f4566948 100644
--- a/examples/data/list/skill-1.jsonld
+++ b/examples/data/list/skill-1.jsonld
@@ -2,11 +2,6 @@
   "@id": "/examples/data/list/skill-1.jsonld",
   "name": "HTML",
   "@type": "hd:skill",
-  "permissions": [
-    "view",
-    "change",
-    "control",
-    "delete"
-  ],
+  "permissions": ["view", "change", "control", "delete"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/skill-2.jsonld b/examples/data/list/skill-2.jsonld
index 53f546588d7cbdbfeddbd7d8594c1e549e2e02dd..074f19e2882950a954370380bf322c44778dab0a 100644
--- a/examples/data/list/skill-2.jsonld
+++ b/examples/data/list/skill-2.jsonld
@@ -20,11 +20,6 @@
       }
     ]
   },
-  "permissions": [
-    "view",
-    "change",
-    "control",
-    "delete"
-  ],
+  "permissions": ["view", "change", "control", "delete"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/skill-3.jsonld b/examples/data/list/skill-3.jsonld
index e13029aafad01b0b7ebfb451977a865ffd31d435..492846fd6629cdb39626d543515f0705a636e493 100644
--- a/examples/data/list/skill-3.jsonld
+++ b/examples/data/list/skill-3.jsonld
@@ -20,11 +20,6 @@
       }
     ]
   },
-  "permissions": [
-    "view",
-    "change",
-    "control",
-    "delete"
-  ],
+  "permissions": ["view", "change", "control", "delete"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/skill-4.jsonld b/examples/data/list/skill-4.jsonld
index 718aceeb14adb379db77542ada490eb1e6dd2f5a..97a2298c619dadf3e7cff0f0d011b8d9dd84668b 100644
--- a/examples/data/list/skill-4.jsonld
+++ b/examples/data/list/skill-4.jsonld
@@ -2,11 +2,6 @@
   "@id": "/examples/data/list/skill-4.jsonld",
   "name": "DevOps",
   "@type": "hd:skill",
-  "permissions": [
-    "view",
-    "change",
-    "control",
-    "delete"
-  ],
+  "permissions": ["view", "change", "control", "delete"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/skill-5.jsonld b/examples/data/list/skill-5.jsonld
index 536ff49c5fe9af265f6f1bfe22e3cdfe1d1f3ad4..8264f8cd185ae8f0ea8a81585328afcab1aebee5 100644
--- a/examples/data/list/skill-5.jsonld
+++ b/examples/data/list/skill-5.jsonld
@@ -2,11 +2,6 @@
   "@id": "/examples/data/list/skill-5.jsonld",
   "name": "PHP",
   "@type": "hd:skill",
-  "permissions": [
-    "view",
-    "change",
-    "control",
-    "delete"
-  ],
+  "permissions": ["view", "change", "control", "delete"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/skill-6.jsonld b/examples/data/list/skill-6.jsonld
index f0e706eb1c46f9ca4763bf4c958a6c1bfc0ad089..158dee7c85d2632fd05b5fb33e6e5835d446965b 100644
--- a/examples/data/list/skill-6.jsonld
+++ b/examples/data/list/skill-6.jsonld
@@ -2,11 +2,6 @@
   "@id": "/examples/data/list/skill-6.jsonld",
   "name": "Git",
   "@type": "hd:skill",
-  "permissions": [
-    "view",
-    "change",
-    "control",
-    "delete"
-  ],
+  "permissions": ["view", "change", "control", "delete"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/skill-7.jsonld b/examples/data/list/skill-7.jsonld
index 9f5f34b1b39c35a9793d84fa55006d9e9abb1c5a..9cf2d4aac9b2c3d6c5482e15c3aa09c1763dcd43 100644
--- a/examples/data/list/skill-7.jsonld
+++ b/examples/data/list/skill-7.jsonld
@@ -2,11 +2,6 @@
   "@id": "/examples/data/list/skill-7.jsonld",
   "name": "Python",
   "@type": "hd:skill",
-  "permissions": [
-    "view",
-    "change",
-    "control",
-    "delete"
-  ],
+  "permissions": ["view", "change", "control", "delete"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/skill-8.jsonld b/examples/data/list/skill-8.jsonld
index 077b844032fab34fafc068a15b1e59aa3660cbae..fc771b9846368f51feb35ee81b047bdf1c21cd7c 100644
--- a/examples/data/list/skill-8.jsonld
+++ b/examples/data/list/skill-8.jsonld
@@ -2,11 +2,6 @@
   "@id": "/examples/data/list/skill-8.jsonld",
   "name": "Node",
   "@type": "hd:skill",
-  "permissions": [
-    "view",
-    "change",
-    "control",
-    "delete"
-  ],
+  "permissions": ["view", "change", "control", "delete"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/skills.jsonld b/examples/data/list/skills.jsonld
index fdc0d5b59db714cb2c4e433bb36456ced729f902..2ab8fccbacbdaa00c2ba065ae2e0f83364e8e4eb 100644
--- a/examples/data/list/skills.jsonld
+++ b/examples/data/list/skills.jsonld
@@ -7,8 +7,7 @@
       "name": "HTML",
       "order": 1,
       "@type": "hd:skill",
-      "permissions": [
-      ]
+      "permissions": []
     },
     {
       "@id": "/examples/data/list/skill-2.jsonld",
@@ -21,69 +20,44 @@
       "name": "Javascript",
       "order": 2,
       "@type": "hd:skill",
-      "permissions": [
-      ]
+      "permissions": []
     },
     {
       "@id": "/examples/data/list/skill-4.jsonld",
       "name": "DevOps",
       "order": 10,
       "@type": "hd:skill",
-      "permissions": [
-        "view",
-        "change",
-        "control",
-        "delete"
-      ]
+      "permissions": ["view", "change", "control", "delete"]
     },
     {
       "@id": "/examples/data/list/skill-5.jsonld",
       "name": "PHP",
       "order": 15,
       "@type": "hd:skill",
-      "permissions": [
-      ]
+      "permissions": []
     },
     {
       "@id": "/examples/data/list/skill-6.jsonld",
       "name": "Git",
       "order": 20,
       "@type": "hd:skill",
-      "permissions": [
-        "view",
-        "change",
-        "control",
-        "delete"
-      ]
+      "permissions": ["view", "change", "control", "delete"]
     },
     {
       "@id": "/examples/data/list/skill-7.jsonld",
       "name": "Python",
       "order": 27,
       "@type": "hd:skill",
-      "permissions": [
-        "view",
-        "change",
-        "control",
-        "delete"
-      ]
+      "permissions": ["view", "change", "control", "delete"]
     },
     {
       "@id": "/examples/data/list/skill-8.jsonld",
       "name": "Node",
       "order": 30,
       "@type": "hd:skill",
-      "permissions": [
-        "view",
-        "change",
-        "control",
-        "delete"
-      ]
+      "permissions": ["view", "change", "control", "delete"]
     }
   ],
-  "permissions": [
-    "view",
-    "add"
-  ],
+  "permissions": ["view", "add"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/starwars-origin.jsonld b/examples/data/list/starwars-origin.jsonld
index 05e14fcc5223736d61d2935933c6d3d3d1c729f3..fb422c740bb1777a505b7656cd6bd63917394e7e 100644
--- a/examples/data/list/starwars-origin.jsonld
+++ b/examples/data/list/starwars-origin.jsonld
@@ -4,14 +4,18 @@
   "@type": "hd:film",
   "ebu:originalTitle": "Star Wars",
   "characters": {
-      "@id": "/examples/data/list/local.jsonld",
-      "@type": "ldp:Container",
-      "ldp:contains": [
-          { "@id": "/examples/data/list/examples/data/list/darth-vader.json" },
-          { "@id": "/examples/data/list/examples/data/list/chewbacca.jsonld", "name": "tata" },
-          {
-            "@id": "/examples/data/list/examples/data/list/hansolo.jsonld", "name": "trotro"
-          }
-      ]
+    "@id": "/examples/data/list/local.jsonld",
+    "@type": "ldp:Container",
+    "ldp:contains": [
+      { "@id": "/examples/data/list/examples/data/list/darth-vader.json" },
+      {
+        "@id": "/examples/data/list/examples/data/list/chewbacca.jsonld",
+        "name": "tata"
+      },
+      {
+        "@id": "/examples/data/list/examples/data/list/hansolo.jsonld",
+        "name": "trotro"
+      }
+    ]
   }
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/starwars.jsonld b/examples/data/list/starwars.jsonld
index 8a63d48517c78b263ba0248f0af904b5f7505916..b36632a3cda98ed6eef72aaea90e9650a63388ab 100644
--- a/examples/data/list/starwars.jsonld
+++ b/examples/data/list/starwars.jsonld
@@ -14,5 +14,5 @@
       "name": "Han solo"
     }
   ],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+}
diff --git a/examples/data/list/types.jsonld b/examples/data/list/types.jsonld
index 7f18cb03cde79dfb7677c05f7f41567d0dee03f5..a3455fbf5db64f3b71a1c662ef8f315029649493 100644
--- a/examples/data/list/types.jsonld
+++ b/examples/data/list/types.jsonld
@@ -1,10 +1,7 @@
 {
   "@context": "https://colibris.social/context.json",
   "id": "https://colibris.social/types",
-  "type": [
-    "ldp:Container",
-    "ldp:BasicContainer"
-  ],
+  "type": ["ldp:Container", "ldp:BasicContainer"],
   "ldp:contains": [
     {
       "id": "https://colibris.social/types/camping",
diff --git a/examples/data/list/universite.jsonld b/examples/data/list/universite.jsonld
index 02156fb52b13bb503d54ceecbc26d52d84982ba6..9508e428a06d1324f45b5ec549f17287f55cbe66 100644
--- a/examples/data/list/universite.jsonld
+++ b/examples/data/list/universite.jsonld
@@ -1,18 +1,11 @@
 {
   "@context": "https://colibris.social/context.json",
   "id": "/examples/data/list/universite.jsonld",
-  "type": [
-    "ldp:Container",
-    "ldp:BasicContainer"
-  ],
+  "type": ["ldp:Container", "ldp:BasicContainer"],
   "ldp:contains": [
     {
       "id": "/examples/data/list/universite/courses.jsonld",
-      "type": [
-        "ldp:Container",
-        "ldp:BasicContainer",
-        "ldp:Resource"
-      ]
+      "type": ["ldp:Container", "ldp:BasicContainer", "ldp:Resource"]
     }
   ]
 }
diff --git a/examples/data/list/universite/courses.jsonld b/examples/data/list/universite/courses.jsonld
index 56eb50a0fccfa61832490a2bd88955dc3b2ae373..ffff6b670c8923422a6f5255fe5ad0e2fff45c19 100644
--- a/examples/data/list/universite/courses.jsonld
+++ b/examples/data/list/universite/courses.jsonld
@@ -1,10 +1,7 @@
 {
   "@context": "https://cdn.startinblox.com/owl/context.jsonld",
   "id": "/examples/data/list/universite/courses.jsonld",
-  "type": [
-    "ldp:Container",
-    "ldp:BasicContainer"
-  ],
+  "type": ["ldp:Container", "ldp:BasicContainer"],
   "ldp:contains": [
     {
       "id": "universite/courses/concevoir-une-oasis-partie-2-la-creation-du-collectif-0",
diff --git a/examples/data/list/user-1-skills.jsonld b/examples/data/list/user-1-skills.jsonld
index 8db9211c9626fa17bd915772be0d51d21ceb2949..1708ecaa0946a572c3558e8739def08dde47bb2b 100644
--- a/examples/data/list/user-1-skills.jsonld
+++ b/examples/data/list/user-1-skills.jsonld
@@ -9,8 +9,6 @@
       "@id": "/examples/data/list/skill-3.jsonld"
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/user-1.jsonld b/examples/data/list/user-1.jsonld
index 20b6d1367b11f39b8690c60176f987df9359482b..f2f7ab94030410ddefba8a52ab15b99aa8d9bc43 100644
--- a/examples/data/list/user-1.jsonld
+++ b/examples/data/list/user-1.jsonld
@@ -17,9 +17,7 @@
         "@id": "/examples/data/list/skill-3.jsonld"
       }
     ],
-    "permissions": [
-      "view"
-    ]
+    "permissions": ["view"]
   },
   "job": {
     "@id": "/examples/data/list/job-1.jsonld"
@@ -28,8 +26,6 @@
     "@id": "/examples/data/list/profile-1.jsonld"
   },
   "@type": "foaf:user",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/user-2-skills.jsonld b/examples/data/list/user-2-skills.jsonld
index 67f2ee4aa9746da22016dd792e5685bafbf3138d..0cac47d59f56dc4f393cb31e67510c943f2e7638 100644
--- a/examples/data/list/user-2-skills.jsonld
+++ b/examples/data/list/user-2-skills.jsonld
@@ -6,8 +6,6 @@
       "@id": "/examples/data/list/skill-1.jsonld"
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/user-2.jsonld b/examples/data/list/user-2.jsonld
index 17586e2bfcd588df397f25485797309c874547ff..499a5a0bc93da3c8ebe7e54f8c3a3c4b06365dfd 100644
--- a/examples/data/list/user-2.jsonld
+++ b/examples/data/list/user-2.jsonld
@@ -14,16 +14,12 @@
         "@id": "/examples/data/list/skill-1.jsonld"
       }
     ],
-    "permissions": [
-      "view"
-    ]
+    "permissions": ["view"]
   },
   "profile": {
     "@id": "/examples/data/list/profile-2.jsonld"
   },
   "@type": "foaf:user",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/user-3-skills.jsonld b/examples/data/list/user-3-skills.jsonld
index ffe5dbcceb75003259f9a5f4846ae2e3872a4876..af30fae84916e1c01cb286332e34eb093e0e8e1f 100644
--- a/examples/data/list/user-3-skills.jsonld
+++ b/examples/data/list/user-3-skills.jsonld
@@ -1,11 +1,7 @@
 {
   "@id": "/examples/data/list/user-3-skills.jsonld",
   "@type": "ldp:Container",
-  "ldp:contains": [
-
-  ],
-  "permissions": [
-    "view"
-  ],
+  "ldp:contains": [],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/user-3.jsonld b/examples/data/list/user-3.jsonld
index 31b4e6baa8b7a95ac704be33561f0e11a461a1d5..146fd0f052f65d96bc6cdae31e62d6e17a8bad95 100644
--- a/examples/data/list/user-3.jsonld
+++ b/examples/data/list/user-3.jsonld
@@ -9,19 +9,13 @@
   "skills": {
     "@id": "/examples/data/list/user-3-skills.jsonld",
     "@type": "ldp:Container",
-    "ldp:contains": [
-
-    ],
-    "permissions": [
-      "view"
-    ]
+    "ldp:contains": [],
+    "permissions": ["view"]
   },
   "profile": {
     "@id": "/examples/data/list/profile-3.jsonld"
   },
   "@type": "foaf:user",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/user-4-skills.jsonld b/examples/data/list/user-4-skills.jsonld
index 078d534ef47090adf7ae5aec9e0b6e409c1ad16f..37fbd60c7c5bfef21d877227faa25c1171da90b3 100644
--- a/examples/data/list/user-4-skills.jsonld
+++ b/examples/data/list/user-4-skills.jsonld
@@ -12,8 +12,6 @@
       "@id": "/examples/data/list/skill-4.jsonld"
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/user-4.jsonld b/examples/data/list/user-4.jsonld
index d18fcd9d5201524c335090ef853ff4d100a52475..ccd661a4bf2a83a2f27146c22f1d133640997cdd 100644
--- a/examples/data/list/user-4.jsonld
+++ b/examples/data/list/user-4.jsonld
@@ -20,16 +20,12 @@
         "@id": "/examples/data/list/skill-4.jsonld"
       }
     ],
-    "permissions": [
-      "view"
-    ]
+    "permissions": ["view"]
   },
   "profile": {
     "@id": "/examples/data/list/profile-4.jsonld"
   },
   "@type": "foaf:user",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/user-5-skills.jsonld b/examples/data/list/user-5-skills.jsonld
index 737dd30139336713a0493d28d2244855c98046d7..a437071cd38de50f7470e5e7c5e24e1c606da37e 100644
--- a/examples/data/list/user-5-skills.jsonld
+++ b/examples/data/list/user-5-skills.jsonld
@@ -12,8 +12,6 @@
       "@id": "/examples/data/list/skill-8.jsonld"
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/user-5.jsonld b/examples/data/list/user-5.jsonld
index ceffd4dac632a5acaba86f79f3d8717a25ccd767..658c1a7aef018b0c2b8bfd3fb8da7d7ac7354c9d 100644
--- a/examples/data/list/user-5.jsonld
+++ b/examples/data/list/user-5.jsonld
@@ -20,16 +20,12 @@
         "@id": "/examples/data/list/skill-8.jsonld"
       }
     ],
-    "permissions": [
-      "view"
-    ]
+    "permissions": ["view"]
   },
   "profile": {
     "@id": "/examples/data/list/profile-5.jsonld"
   },
   "@type": "foaf:user",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/users-group1.jsonld b/examples/data/list/users-group1.jsonld
index de9fa3b3586905dcfa3952a413689b7c8dafdbac..9e6a188f623c9408e6219239f2533071bd7250a1 100644
--- a/examples/data/list/users-group1.jsonld
+++ b/examples/data/list/users-group1.jsonld
@@ -22,17 +22,13 @@
             "@id": "/examples/data/list/skill-3.jsonld"
           }
         ],
-        "permissions": [
-          "view"
-        ]
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-1.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/user-2.jsonld",
@@ -51,17 +47,13 @@
             "@id": "/examples/data/list/skill-1.jsonld"
           }
         ],
-        "permissions": [
-          "view"
-        ]
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-2.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/user-3.jsonld",
@@ -75,24 +67,16 @@
       "skills": {
         "@id": "/examples/data/list/user-3-skills.jsonld",
         "@type": "ldp:Container",
-        "ldp:contains": [
-
-        ],
-        "permissions": [
-          "view"
-        ]
+        "ldp:contains": [],
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-3.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/users-group2.jsonld b/examples/data/list/users-group2.jsonld
index 9aeb2bae8652dbce987289e5114a106612dcf83c..acd5eedc47af9ef192c161c1c59d0a27e701a546 100644
--- a/examples/data/list/users-group2.jsonld
+++ b/examples/data/list/users-group2.jsonld
@@ -19,17 +19,13 @@
             "@id": "/examples/data/list/skill-1.jsonld"
           }
         ],
-        "permissions": [
-          "view"
-        ]
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-2.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/user-4.jsonld",
@@ -54,17 +50,13 @@
             "@id": "/examples/data/list/skill-4.jsonld"
           }
         ],
-        "permissions": [
-          "view"
-        ]
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-4.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/user-5.jsonld",
@@ -88,21 +80,15 @@
             "@id": "/examples/data/list/skill-8.jsonld"
           }
         ],
-        "permissions": [
-          "view"
-        ]
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-5.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/users-long.jsonld b/examples/data/list/users-long.jsonld
index 82e62771967b0e1ea4cc024fa89cd6eb8dad30ae..f286a947d1df8e7a9a16a5ef8d480c5f91f73c03 100644
--- a/examples/data/list/users-long.jsonld
+++ b/examples/data/list/users-long.jsonld
@@ -1,9 +1,7 @@
 {
   "@id": "/examples/data/list/users-long.jsonld",
   "@type": "ldp:Container",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld",
   "ldp:contains": [
     {
@@ -14,9 +12,7 @@
       "username": "mayer.glenn",
       "email": "mayer.glenn@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-1.jsonld",
@@ -26,9 +22,7 @@
       "username": "santiago.fowler",
       "email": "santiago.fowler@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-2.jsonld",
@@ -38,9 +32,7 @@
       "username": "imelda.kemp",
       "email": "imelda.kemp@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-3.jsonld",
@@ -50,9 +42,7 @@
       "username": "tillman.mcmahon",
       "email": "tillman.mcmahon@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-4.jsonld",
@@ -62,9 +52,7 @@
       "username": "torres.henry",
       "email": "torres.henry@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-5.jsonld",
@@ -74,9 +62,7 @@
       "username": "ines.head",
       "email": "ines.head@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-6.jsonld",
@@ -86,9 +72,7 @@
       "username": "cotton.sullivan",
       "email": "cotton.sullivan@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-7.jsonld",
@@ -98,9 +82,7 @@
       "username": "nelda.armstrong",
       "email": "nelda.armstrong@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-8.jsonld",
@@ -110,9 +92,7 @@
       "username": "marianne.gentry",
       "email": "marianne.gentry@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-9.jsonld",
@@ -122,9 +102,7 @@
       "username": "sweet.petersen",
       "email": "sweet.petersen@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-10.jsonld",
@@ -134,9 +112,7 @@
       "username": "henry.noble",
       "email": "henry.noble@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-11.jsonld",
@@ -146,9 +122,7 @@
       "username": "rhodes.michael",
       "email": "rhodes.michael@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-12.jsonld",
@@ -158,9 +132,7 @@
       "username": "browning.sherman",
       "email": "browning.sherman@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-13.jsonld",
@@ -170,9 +142,7 @@
       "username": "ellen.walter",
       "email": "ellen.walter@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-14.jsonld",
@@ -182,9 +152,7 @@
       "username": "jolene.winters",
       "email": "jolene.winters@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-15.jsonld",
@@ -194,9 +162,7 @@
       "username": "benton.powell",
       "email": "benton.powell@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-16.jsonld",
@@ -206,9 +172,7 @@
       "username": "lott.franklin",
       "email": "lott.franklin@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-17.jsonld",
@@ -218,9 +182,7 @@
       "username": "noble.ramirez",
       "email": "noble.ramirez@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-18.jsonld",
@@ -230,9 +192,7 @@
       "username": "case.gillespie",
       "email": "case.gillespie@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-19.jsonld",
@@ -242,9 +202,7 @@
       "username": "oneill.frank",
       "email": "oneill.frank@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-20.jsonld",
@@ -254,9 +212,7 @@
       "username": "francesca.tanner",
       "email": "francesca.tanner@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-21.jsonld",
@@ -266,9 +222,7 @@
       "username": "shauna.floyd",
       "email": "shauna.floyd@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-22.jsonld",
@@ -278,9 +232,7 @@
       "username": "michelle.terrell",
       "email": "michelle.terrell@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-23.jsonld",
@@ -290,9 +242,7 @@
       "username": "carmella.bennett",
       "email": "carmella.bennett@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-24.jsonld",
@@ -302,9 +252,7 @@
       "username": "levine.morrison",
       "email": "levine.morrison@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-25.jsonld",
@@ -314,9 +262,7 @@
       "username": "janice.lane",
       "email": "janice.lane@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-26.jsonld",
@@ -326,9 +272,7 @@
       "username": "woods.clay",
       "email": "woods.clay@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-27.jsonld",
@@ -338,9 +282,7 @@
       "username": "anna.abbott",
       "email": "anna.abbott@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-28.jsonld",
@@ -350,9 +292,7 @@
       "username": "atkins.levine",
       "email": "atkins.levine@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-29.jsonld",
@@ -362,9 +302,7 @@
       "username": "tiffany.dunn",
       "email": "tiffany.dunn@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-30.jsonld",
@@ -374,9 +312,7 @@
       "username": "valarie.lindsay",
       "email": "valarie.lindsay@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-31.jsonld",
@@ -386,9 +322,7 @@
       "username": "finley.solis",
       "email": "finley.solis@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-32.jsonld",
@@ -398,9 +332,7 @@
       "username": "mclaughlin.wagner",
       "email": "mclaughlin.wagner@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-33.jsonld",
@@ -410,9 +342,7 @@
       "username": "roslyn.hyde",
       "email": "roslyn.hyde@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-34.jsonld",
@@ -422,9 +352,7 @@
       "username": "rosetta.craig",
       "email": "rosetta.craig@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-35.jsonld",
@@ -434,9 +362,7 @@
       "username": "geraldine.waters",
       "email": "geraldine.waters@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-36.jsonld",
@@ -446,9 +372,7 @@
       "username": "zamora.ellison",
       "email": "zamora.ellison@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-37.jsonld",
@@ -458,9 +382,7 @@
       "username": "eileen.cantu",
       "email": "eileen.cantu@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-38.jsonld",
@@ -470,9 +392,7 @@
       "username": "lynette.oconnor",
       "email": "lynette.oconnor@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-39.jsonld",
@@ -482,9 +402,7 @@
       "username": "maritza.middleton",
       "email": "maritza.middleton@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-40.jsonld",
@@ -494,9 +412,7 @@
       "username": "norman.peters",
       "email": "norman.peters@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-41.jsonld",
@@ -506,9 +422,7 @@
       "username": "lane.navarro",
       "email": "lane.navarro@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-42.jsonld",
@@ -518,9 +432,7 @@
       "username": "oliver.fulton",
       "email": "oliver.fulton@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-43.jsonld",
@@ -530,9 +442,7 @@
       "username": "dale.bishop",
       "email": "dale.bishop@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-44.jsonld",
@@ -542,9 +452,7 @@
       "username": "wise.vazquez",
       "email": "wise.vazquez@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-45.jsonld",
@@ -554,9 +462,7 @@
       "username": "gilliam.moran",
       "email": "gilliam.moran@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-46.jsonld",
@@ -566,9 +472,7 @@
       "username": "ellison.wilson",
       "email": "ellison.wilson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-47.jsonld",
@@ -578,9 +482,7 @@
       "username": "fanny.sandoval",
       "email": "fanny.sandoval@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-48.jsonld",
@@ -590,9 +492,7 @@
       "username": "hale.macdonald",
       "email": "hale.macdonald@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-49.jsonld",
@@ -602,9 +502,7 @@
       "username": "riley.mcfarland",
       "email": "riley.mcfarland@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-50.jsonld",
@@ -614,9 +512,7 @@
       "username": "prince.wilkerson",
       "email": "prince.wilkerson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-51.jsonld",
@@ -626,9 +522,7 @@
       "username": "barnett.klein",
       "email": "barnett.klein@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-52.jsonld",
@@ -638,9 +532,7 @@
       "username": "amy.collins",
       "email": "amy.collins@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-53.jsonld",
@@ -650,9 +542,7 @@
       "username": "wells.grant",
       "email": "wells.grant@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-54.jsonld",
@@ -662,9 +552,7 @@
       "username": "melton.peterson",
       "email": "melton.peterson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-55.jsonld",
@@ -674,9 +562,7 @@
       "username": "davenport.townsend",
       "email": "davenport.townsend@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-56.jsonld",
@@ -686,9 +572,7 @@
       "username": "mayo.flynn",
       "email": "mayo.flynn@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-57.jsonld",
@@ -698,9 +582,7 @@
       "username": "latoya.haynes",
       "email": "latoya.haynes@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-58.jsonld",
@@ -710,9 +592,7 @@
       "username": "catherine.parrish",
       "email": "catherine.parrish@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-59.jsonld",
@@ -722,9 +602,7 @@
       "username": "bernadette.roman",
       "email": "bernadette.roman@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-60.jsonld",
@@ -734,9 +612,7 @@
       "username": "jeanne.rosa",
       "email": "jeanne.rosa@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-61.jsonld",
@@ -746,9 +622,7 @@
       "username": "ward.cunningham",
       "email": "ward.cunningham@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-62.jsonld",
@@ -758,9 +632,7 @@
       "username": "melba.nelson",
       "email": "melba.nelson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-63.jsonld",
@@ -770,9 +642,7 @@
       "username": "johnston.ashley",
       "email": "johnston.ashley@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-64.jsonld",
@@ -782,9 +652,7 @@
       "username": "mavis.sellers",
       "email": "mavis.sellers@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-65.jsonld",
@@ -794,9 +662,7 @@
       "username": "veronica.rollins",
       "email": "veronica.rollins@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-66.jsonld",
@@ -806,9 +672,7 @@
       "username": "renee.melendez",
       "email": "renee.melendez@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-67.jsonld",
@@ -818,9 +682,7 @@
       "username": "mccarty.gates",
       "email": "mccarty.gates@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-68.jsonld",
@@ -830,9 +692,7 @@
       "username": "day.rios",
       "email": "day.rios@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-69.jsonld",
@@ -842,9 +702,7 @@
       "username": "frye.johns",
       "email": "frye.johns@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-70.jsonld",
@@ -854,9 +712,7 @@
       "username": "cheryl.wilkinson",
       "email": "cheryl.wilkinson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-71.jsonld",
@@ -866,9 +722,7 @@
       "username": "munoz.douglas",
       "email": "munoz.douglas@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-72.jsonld",
@@ -878,9 +732,7 @@
       "username": "debra.cook",
       "email": "debra.cook@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-73.jsonld",
@@ -890,9 +742,7 @@
       "username": "schneider.villarreal",
       "email": "schneider.villarreal@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-74.jsonld",
@@ -902,9 +752,7 @@
       "username": "hayes.holloway",
       "email": "hayes.holloway@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-75.jsonld",
@@ -914,9 +762,7 @@
       "username": "buck.velazquez",
       "email": "buck.velazquez@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-76.jsonld",
@@ -926,9 +772,7 @@
       "username": "aida.pugh",
       "email": "aida.pugh@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-77.jsonld",
@@ -938,9 +782,7 @@
       "username": "pamela.olsen",
       "email": "pamela.olsen@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-78.jsonld",
@@ -950,9 +792,7 @@
       "username": "trudy.lucas",
       "email": "trudy.lucas@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-79.jsonld",
@@ -962,9 +802,7 @@
       "username": "madge.casey",
       "email": "madge.casey@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-80.jsonld",
@@ -974,9 +812,7 @@
       "username": "nicole.palmer",
       "email": "nicole.palmer@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-81.jsonld",
@@ -986,9 +822,7 @@
       "username": "hopper.harrell",
       "email": "hopper.harrell@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-82.jsonld",
@@ -998,9 +832,7 @@
       "username": "chelsea.kennedy",
       "email": "chelsea.kennedy@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-83.jsonld",
@@ -1010,9 +842,7 @@
       "username": "townsend.morin",
       "email": "townsend.morin@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-84.jsonld",
@@ -1022,9 +852,7 @@
       "username": "valenzuela.herring",
       "email": "valenzuela.herring@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-85.jsonld",
@@ -1034,9 +862,7 @@
       "username": "iris.durham",
       "email": "iris.durham@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-86.jsonld",
@@ -1046,9 +872,7 @@
       "username": "guerrero.wooten",
       "email": "guerrero.wooten@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/users-mocked.jsonld b/examples/data/list/users-mocked.jsonld
index 66976ac647467bb0f5b90db3e0eb33534c9b089d..d98da4bfe4ead2316a6d2ada7c611002a85761e9 100644
--- a/examples/data/list/users-mocked.jsonld
+++ b/examples/data/list/users-mocked.jsonld
@@ -1,9 +1,7 @@
 {
   "@id": "/mock/users.jsonld",
   "@type": "ldp:Container",
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld",
   "ldp:contains": [
     {
@@ -14,9 +12,7 @@
       "username": "mayer.glenn",
       "email": "mayer.glenn@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-1.jsonld",
@@ -26,9 +22,7 @@
       "username": "santiago.fowler",
       "email": "santiago.fowler@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-2.jsonld",
@@ -38,9 +32,7 @@
       "username": "imelda.kemp",
       "email": "imelda.kemp@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-3.jsonld",
@@ -50,9 +42,7 @@
       "username": "tillman.mcmahon",
       "email": "tillman.mcmahon@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-4.jsonld",
@@ -62,9 +52,7 @@
       "username": "torres.henry",
       "email": "torres.henry@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-5.jsonld",
@@ -74,9 +62,7 @@
       "username": "ines.head",
       "email": "ines.head@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-6.jsonld",
@@ -86,9 +72,7 @@
       "username": "cotton.sullivan",
       "email": "cotton.sullivan@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-7.jsonld",
@@ -98,9 +82,7 @@
       "username": "nelda.armstrong",
       "email": "nelda.armstrong@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-8.jsonld",
@@ -110,9 +92,7 @@
       "username": "marianne.gentry",
       "email": "marianne.gentry@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-9.jsonld",
@@ -122,9 +102,7 @@
       "username": "sweet.petersen",
       "email": "sweet.petersen@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-10.jsonld",
@@ -134,9 +112,7 @@
       "username": "henry.noble",
       "email": "henry.noble@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-11.jsonld",
@@ -146,9 +122,7 @@
       "username": "rhodes.michael",
       "email": "rhodes.michael@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-12.jsonld",
@@ -158,9 +132,7 @@
       "username": "browning.sherman",
       "email": "browning.sherman@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-13.jsonld",
@@ -170,9 +142,7 @@
       "username": "ellen.walter",
       "email": "ellen.walter@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-14.jsonld",
@@ -182,9 +152,7 @@
       "username": "jolene.winters",
       "email": "jolene.winters@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-15.jsonld",
@@ -194,9 +162,7 @@
       "username": "benton.powell",
       "email": "benton.powell@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-16.jsonld",
@@ -206,9 +172,7 @@
       "username": "lott.franklin",
       "email": "lott.franklin@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-17.jsonld",
@@ -218,9 +182,7 @@
       "username": "noble.ramirez",
       "email": "noble.ramirez@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-18.jsonld",
@@ -230,9 +192,7 @@
       "username": "case.gillespie",
       "email": "case.gillespie@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-19.jsonld",
@@ -242,9 +202,7 @@
       "username": "oneill.frank",
       "email": "oneill.frank@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-20.jsonld",
@@ -254,9 +212,7 @@
       "username": "francesca.tanner",
       "email": "francesca.tanner@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-21.jsonld",
@@ -266,9 +222,7 @@
       "username": "shauna.floyd",
       "email": "shauna.floyd@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-22.jsonld",
@@ -278,9 +232,7 @@
       "username": "michelle.terrell",
       "email": "michelle.terrell@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-23.jsonld",
@@ -290,9 +242,7 @@
       "username": "carmella.bennett",
       "email": "carmella.bennett@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-24.jsonld",
@@ -302,9 +252,7 @@
       "username": "levine.morrison",
       "email": "levine.morrison@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-25.jsonld",
@@ -314,9 +262,7 @@
       "username": "janice.lane",
       "email": "janice.lane@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-26.jsonld",
@@ -326,9 +272,7 @@
       "username": "woods.clay",
       "email": "woods.clay@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-27.jsonld",
@@ -338,9 +282,7 @@
       "username": "anna.abbott",
       "email": "anna.abbott@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-28.jsonld",
@@ -350,9 +292,7 @@
       "username": "atkins.levine",
       "email": "atkins.levine@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-29.jsonld",
@@ -362,9 +302,7 @@
       "username": "tiffany.dunn",
       "email": "tiffany.dunn@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-30.jsonld",
@@ -374,9 +312,7 @@
       "username": "valarie.lindsay",
       "email": "valarie.lindsay@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-31.jsonld",
@@ -386,9 +322,7 @@
       "username": "finley.solis",
       "email": "finley.solis@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-32.jsonld",
@@ -398,9 +332,7 @@
       "username": "mclaughlin.wagner",
       "email": "mclaughlin.wagner@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-33.jsonld",
@@ -410,9 +342,7 @@
       "username": "roslyn.hyde",
       "email": "roslyn.hyde@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-34.jsonld",
@@ -422,9 +352,7 @@
       "username": "rosetta.craig",
       "email": "rosetta.craig@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-35.jsonld",
@@ -434,9 +362,7 @@
       "username": "geraldine.waters",
       "email": "geraldine.waters@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-36.jsonld",
@@ -446,9 +372,7 @@
       "username": "zamora.ellison",
       "email": "zamora.ellison@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-37.jsonld",
@@ -458,9 +382,7 @@
       "username": "eileen.cantu",
       "email": "eileen.cantu@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-38.jsonld",
@@ -470,9 +392,7 @@
       "username": "lynette.oconnor",
       "email": "lynette.oconnor@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-39.jsonld",
@@ -482,9 +402,7 @@
       "username": "maritza.middleton",
       "email": "maritza.middleton@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-40.jsonld",
@@ -494,9 +412,7 @@
       "username": "norman.peters",
       "email": "norman.peters@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-41.jsonld",
@@ -506,9 +422,7 @@
       "username": "lane.navarro",
       "email": "lane.navarro@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-42.jsonld",
@@ -518,9 +432,7 @@
       "username": "oliver.fulton",
       "email": "oliver.fulton@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-43.jsonld",
@@ -530,9 +442,7 @@
       "username": "dale.bishop",
       "email": "dale.bishop@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-44.jsonld",
@@ -542,9 +452,7 @@
       "username": "wise.vazquez",
       "email": "wise.vazquez@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-45.jsonld",
@@ -554,9 +462,7 @@
       "username": "gilliam.moran",
       "email": "gilliam.moran@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-46.jsonld",
@@ -566,9 +472,7 @@
       "username": "ellison.wilson",
       "email": "ellison.wilson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-47.jsonld",
@@ -578,9 +482,7 @@
       "username": "fanny.sandoval",
       "email": "fanny.sandoval@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-48.jsonld",
@@ -590,9 +492,7 @@
       "username": "hale.macdonald",
       "email": "hale.macdonald@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-49.jsonld",
@@ -602,9 +502,7 @@
       "username": "riley.mcfarland",
       "email": "riley.mcfarland@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-50.jsonld",
@@ -614,9 +512,7 @@
       "username": "prince.wilkerson",
       "email": "prince.wilkerson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-51.jsonld",
@@ -626,9 +522,7 @@
       "username": "barnett.klein",
       "email": "barnett.klein@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-52.jsonld",
@@ -638,9 +532,7 @@
       "username": "amy.collins",
       "email": "amy.collins@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-53.jsonld",
@@ -650,9 +542,7 @@
       "username": "wells.grant",
       "email": "wells.grant@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-54.jsonld",
@@ -662,9 +552,7 @@
       "username": "melton.peterson",
       "email": "melton.peterson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-55.jsonld",
@@ -674,9 +562,7 @@
       "username": "davenport.townsend",
       "email": "davenport.townsend@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-56.jsonld",
@@ -686,9 +572,7 @@
       "username": "mayo.flynn",
       "email": "mayo.flynn@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-57.jsonld",
@@ -698,9 +582,7 @@
       "username": "latoya.haynes",
       "email": "latoya.haynes@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-58.jsonld",
@@ -710,9 +592,7 @@
       "username": "catherine.parrish",
       "email": "catherine.parrish@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-59.jsonld",
@@ -722,9 +602,7 @@
       "username": "bernadette.roman",
       "email": "bernadette.roman@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-60.jsonld",
@@ -734,9 +612,7 @@
       "username": "jeanne.rosa",
       "email": "jeanne.rosa@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-61.jsonld",
@@ -746,9 +622,7 @@
       "username": "ward.cunningham",
       "email": "ward.cunningham@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-62.jsonld",
@@ -758,9 +632,7 @@
       "username": "melba.nelson",
       "email": "melba.nelson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-63.jsonld",
@@ -770,9 +642,7 @@
       "username": "johnston.ashley",
       "email": "johnston.ashley@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-64.jsonld",
@@ -782,9 +652,7 @@
       "username": "mavis.sellers",
       "email": "mavis.sellers@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-65.jsonld",
@@ -794,9 +662,7 @@
       "username": "veronica.rollins",
       "email": "veronica.rollins@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-66.jsonld",
@@ -806,9 +672,7 @@
       "username": "renee.melendez",
       "email": "renee.melendez@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-67.jsonld",
@@ -818,9 +682,7 @@
       "username": "mccarty.gates",
       "email": "mccarty.gates@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-68.jsonld",
@@ -830,9 +692,7 @@
       "username": "day.rios",
       "email": "day.rios@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-69.jsonld",
@@ -842,9 +702,7 @@
       "username": "frye.johns",
       "email": "frye.johns@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-70.jsonld",
@@ -854,9 +712,7 @@
       "username": "cheryl.wilkinson",
       "email": "cheryl.wilkinson@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-71.jsonld",
@@ -866,9 +722,7 @@
       "username": "munoz.douglas",
       "email": "munoz.douglas@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-72.jsonld",
@@ -878,9 +732,7 @@
       "username": "debra.cook",
       "email": "debra.cook@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-73.jsonld",
@@ -890,9 +742,7 @@
       "username": "schneider.villarreal",
       "email": "schneider.villarreal@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-74.jsonld",
@@ -902,9 +752,7 @@
       "username": "hayes.holloway",
       "email": "hayes.holloway@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-75.jsonld",
@@ -914,9 +762,7 @@
       "username": "buck.velazquez",
       "email": "buck.velazquez@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-76.jsonld",
@@ -926,9 +772,7 @@
       "username": "aida.pugh",
       "email": "aida.pugh@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-77.jsonld",
@@ -938,9 +782,7 @@
       "username": "pamela.olsen",
       "email": "pamela.olsen@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-78.jsonld",
@@ -950,9 +792,7 @@
       "username": "trudy.lucas",
       "email": "trudy.lucas@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-79.jsonld",
@@ -962,9 +802,7 @@
       "username": "madge.casey",
       "email": "madge.casey@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-80.jsonld",
@@ -974,9 +812,7 @@
       "username": "nicole.palmer",
       "email": "nicole.palmer@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-81.jsonld",
@@ -986,9 +822,7 @@
       "username": "hopper.harrell",
       "email": "hopper.harrell@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-82.jsonld",
@@ -998,9 +832,7 @@
       "username": "chelsea.kennedy",
       "email": "chelsea.kennedy@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-83.jsonld",
@@ -1010,9 +842,7 @@
       "username": "townsend.morin",
       "email": "townsend.morin@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-84.jsonld",
@@ -1022,9 +852,7 @@
       "username": "valenzuela.herring",
       "email": "valenzuela.herring@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-85.jsonld",
@@ -1034,9 +862,7 @@
       "username": "iris.durham",
       "email": "iris.durham@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/--user-86.jsonld",
@@ -1046,9 +872,7 @@
       "username": "guerrero.wooten",
       "email": "guerrero.wooten@example.com",
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ]
 }
diff --git a/examples/data/list/users.jsonld b/examples/data/list/users.jsonld
index a866540238bb9ae4db270763591c17101e4f2bd9..b9c1b0b79650e5230f113f4ea24ffb2c284360aa 100644
--- a/examples/data/list/users.jsonld
+++ b/examples/data/list/users.jsonld
@@ -22,17 +22,13 @@
             "@id": "/examples/data/list/skill-3.jsonld"
           }
         ],
-        "permissions": [
-          "view"
-        ]
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-1.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/user-2.jsonld",
@@ -51,17 +47,13 @@
             "@id": "/examples/data/list/skill-1.jsonld"
           }
         ],
-        "permissions": [
-          "view"
-        ]
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-2.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/user-4.jsonld",
@@ -86,17 +78,13 @@
             "@id": "/examples/data/list/skill-4.jsonld"
           }
         ],
-        "permissions": [
-          "view"
-        ]
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-4.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     },
     {
       "@id": "/examples/data/list/user-3.jsonld",
@@ -110,24 +98,16 @@
       "skills": {
         "@id": "/examples/data/list/user-3-skills.jsonld",
         "@type": "ldp:Container",
-        "ldp:contains": [
-
-        ],
-        "permissions": [
-          "view"
-        ]
+        "ldp:contains": [],
+        "permissions": ["view"]
       },
       "profile": {
         "@id": "/examples/data/list/profile-3.jsonld"
       },
       "@type": "foaf:user",
-      "permissions": [
-        "view"
-      ]
+      "permissions": ["view"]
     }
   ],
-  "permissions": [
-    "view"
-  ],
+  "permissions": ["view"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/list/users/balessan.jsonld b/examples/data/list/users/balessan.jsonld
index 517684404a2072d53f0554df241e0ff8e63c353a..314b62454a883b5199051e884ef230d8f010285d 100644
--- a/examples/data/list/users/balessan.jsonld
+++ b/examples/data/list/users/balessan.jsonld
@@ -261,11 +261,5 @@
       "get_full_name": "rdfs:label"
     }
   ],
-  "permissions": [
-    "change",
-    "control",
-    "view",
-    "delete",
-    "add"
-  ]
+  "permissions": ["change", "control", "view", "delete", "add"]
 }
diff --git a/examples/data/list/users/blaisepascal.jsonld b/examples/data/list/users/blaisepascal.jsonld
index 32ab48bdd87f3cd04318b6900c852e0080609df9..752a80ad82a66495a24887d824e659114f8bbcbe 100644
--- a/examples/data/list/users/blaisepascal.jsonld
+++ b/examples/data/list/users/blaisepascal.jsonld
@@ -170,11 +170,5 @@
       "get_full_name": "rdfs:label"
     }
   ],
-  "permissions": [
-    "change",
-    "control",
-    "view",
-    "delete",
-    "add"
-  ]
+  "permissions": ["change", "control", "view", "delete", "add"]
 }
diff --git a/examples/data/map/event-1.jsonld b/examples/data/map/event-1.jsonld
deleted file mode 100644
index b745c872fcfab7fce50f42cd066903b3e076b5d3..0000000000000000000000000000000000000000
--- a/examples/data/map/event-1.jsonld
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "@id": "/examples/data/map/event-1.jsonld",
-  "name": "Test",
-  "category": "showcase event",
-  "lat": "21.028511",
-  "lng": "105.804817",
-  "permissions": [],
-  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
diff --git a/examples/data/map/event-2.jsonld b/examples/data/map/event-2.jsonld
deleted file mode 100644
index ddf97bf9efd41b383fff5020c0c35fd6db141f2a..0000000000000000000000000000000000000000
--- a/examples/data/map/event-2.jsonld
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "@id": "/examples/data/map/event-2.jsonld",
-  "name": "Test",
-  "category": "meetup",
-  "lat": "48.864716",
-  "lng": "2.349014",
-  "permissions": [],
-  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
diff --git a/examples/data/map/event-3.jsonld b/examples/data/map/event-3.jsonld
deleted file mode 100644
index d081d5f15cfeb5346269b0486462236c5ac8a134..0000000000000000000000000000000000000000
--- a/examples/data/map/event-3.jsonld
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "@id": "/examples/data/map/event-3.jsonld",
-  "name": "Test 3",
-  "category": "showcase event",
-  "lat": "41.8902102",
-  "lng": "12.4922309",
-  "permissions": [],
-  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
diff --git a/examples/data/map/events.jsonld b/examples/data/map/events.jsonld
deleted file mode 100644
index b674eef61e8c49d82525eda84e0f00d310f378dd..0000000000000000000000000000000000000000
--- a/examples/data/map/events.jsonld
+++ /dev/null
@@ -1,55 +0,0 @@
-{
-  "@type": "ldp:Container",
-  "ldp:contains": [
-    {
-      "name": "Test 1, Vietnam, Asia",
-      "category": "showcase event",
-      "lat": "21.028511",
-      "lng": "105.804817",
-      "permissions": [],
-      "@id": "/examples/data/map/event-1.jsonld"
-    },
-    {
-      "name": "Test 2, France, Europe",
-      "category": "meetup",
-      "lat": "48.864716",
-      "lng": "2.349014",
-      "permissions": [],
-      "@id": "/examples/data/map/event-2.jsonld"
-    },
-    {
-      "name": "Test 3, Italy, Europe",
-      "category": "showcase event",
-      "lat": "41.8902102",
-      "lng": "12.4922309",
-      "permissions": [],
-      "@id": "/examples/data/map/event-3.jsonld"
-    },
-    {
-      "name": "Test 4, France, Europe",
-      "category": "meetup",
-      "lat": "48.63976",
-      "lng": "-2.42516",
-      "permissions": [],
-      "@id": "/examples/data/map/event-4.jsonld"
-    },
-    {
-      "name": "Test 5, France, Europe",
-      "category": "meetup",
-      "lat": "48.64636",
-      "lng": "-2.41981",
-      "permissions": [],
-      "@id": "/examples/data/map/event-5.jsonld"
-    },
-    {
-      "name": "Test 6, France, Europe",
-      "category": "meetup",
-      "lat": "48.63683",
-      "lng": "-2.47765",
-      "permissions": [],
-      "@id": "/examples/data/map/event-6.jsonld"
-    }
-  ],
-  "@id": "/examples/data/map/events.jsonld",
-  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
diff --git a/examples/data/map/other-events.jsonld b/examples/data/map/other-events.jsonld
deleted file mode 100644
index 16f5e8c92cc3ce560bc84f6ac356eddcfab5e879..0000000000000000000000000000000000000000
--- a/examples/data/map/other-events.jsonld
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "@type": "ldp:Container",
-  "ldp:contains": [
-    {
-      "name": "Test 7, New York",
-      "category": "other event",
-      "lat": "40.741895",
-      "lng": "-73.989308",
-      "permissions": [],
-      "@id": "/examples/data/map/event-7.jsonld"
-    }
-  ],
-  "@id": "/examples/data/map/other-events.jsonld",
-  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
diff --git a/examples/data/map/source.jsonld b/examples/data/map/source.jsonld
deleted file mode 100644
index 97a5affe76ab233a4d7ea4be05b19727705125db..0000000000000000000000000000000000000000
--- a/examples/data/map/source.jsonld
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "@id": "/examples/data/map/source.jsonld",
-  "@type": "ldp:Container",
-  "ldp:contains": [
-    {
-      "federation": "events",
-      "@id": "/examples/data/map/events.jsonld",
-      "@type": "sib:federatedContainer",
-      "permissions": [
-        "view"
-      ]
-    },
-    {
-      "@id": "/examples/data/map/other-events.jsonld",
-      "@type": "sib:federatedContainer"
-    }
-  ],
-  "permissions": [
-    "view"
-  ],
-  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
diff --git a/examples/data/nested-forms/batch-1.jsonld b/examples/data/nested-forms/batch-1.jsonld
index ed143312759357cf6f1171c7ee71f43339177867..724febeca3eb89cd7fe58e39b31d2b735e6b6f0b 100644
--- a/examples/data/nested-forms/batch-1.jsonld
+++ b/examples/data/nested-forms/batch-1.jsonld
@@ -1,12 +1,12 @@
 {
-	"@id": "/examples/data/nested-forms/batch-1.jsonld",
-	"invoice": {
-		"@id": "/examples/data/nested-forms/customer-invoice-1.jsonld"
-	},
-	"title": "Développement",
-	"creationDate": "2020-10-02",
-	"modificationDate": "2020-10-04",
-	"htAmount": 1500,
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+  "@id": "/examples/data/nested-forms/batch-1.jsonld",
+  "invoice": {
+    "@id": "/examples/data/nested-forms/customer-invoice-1.jsonld"
+  },
+  "title": "Développement",
+  "creationDate": "2020-10-02",
+  "modificationDate": "2020-10-04",
+  "htAmount": 1500,
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+}
diff --git a/examples/data/nested-forms/batch-2.jsonld b/examples/data/nested-forms/batch-2.jsonld
index 6fed5861423fdf969907f09a79f6027ab4c0d1cd..ea3043847ecc650ef813b6244e48f0a78531df26 100644
--- a/examples/data/nested-forms/batch-2.jsonld
+++ b/examples/data/nested-forms/batch-2.jsonld
@@ -1,12 +1,12 @@
 {
-	"@id": "/examples/data/nested-forms/batch-2.jsonld",
-	"invoice": {
-		"@id": "/examples/data/nested-forms/customer-invoice-1.jsonld"
-	},
-	"title": "Déploiement",
-	"creationDate": "2020-10-02",
-	"modificationDate": "2020-10-04",
-	"htAmount": 500,
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+  "@id": "/examples/data/nested-forms/batch-2.jsonld",
+  "invoice": {
+    "@id": "/examples/data/nested-forms/customer-invoice-1.jsonld"
+  },
+  "title": "Déploiement",
+  "creationDate": "2020-10-02",
+  "modificationDate": "2020-10-04",
+  "htAmount": 500,
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+}
diff --git a/examples/data/nested-forms/customer-invoice-1-batches.jsonld b/examples/data/nested-forms/customer-invoice-1-batches.jsonld
index 3e4fb5ed83f9ebaf13b39e9d580fe43c521ad81c..6098b6cad2e6074864b59d46de2f46e4887fdbd6 100644
--- a/examples/data/nested-forms/customer-invoice-1-batches.jsonld
+++ b/examples/data/nested-forms/customer-invoice-1-batches.jsonld
@@ -1,30 +1,30 @@
 {
-	"@id": "/examples/data/nested-forms/customer-invoice-1-batches.jsonld",
-	"@type": "ldp:Container",
-	"ldp:contains": [
-		{
-			"@id": "/examples/data/nested-forms/batch-1.jsonld",
-			"invoice": {
-				"@id": "/examples/data/nested-forms/customer-invoice-1.jsonld"
-			},
-			"title": "Développement",
-			"creationDate": "2020-10-02",
-			"modificationDate": "2020-10-04",
-			"htAmount": 1500,
-			"permissions": []
-		},
-		{
-			"@id": "/examples/data/nested-forms/batch-2.jsonld",
-			"invoice": {
-				"@id": "/examples/data/nested-forms/customer-invoice-1.jsonld"
-			},
-			"title": "Déploiement",
-			"creationDate": "2020-10-02",
-			"modificationDate": "2020-10-04",
-			"htAmount": 500,
-			"permissions": []
-		}
-	],
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+  "@id": "/examples/data/nested-forms/customer-invoice-1-batches.jsonld",
+  "@type": "ldp:Container",
+  "ldp:contains": [
+    {
+      "@id": "/examples/data/nested-forms/batch-1.jsonld",
+      "invoice": {
+        "@id": "/examples/data/nested-forms/customer-invoice-1.jsonld"
+      },
+      "title": "Développement",
+      "creationDate": "2020-10-02",
+      "modificationDate": "2020-10-04",
+      "htAmount": 1500,
+      "permissions": []
+    },
+    {
+      "@id": "/examples/data/nested-forms/batch-2.jsonld",
+      "invoice": {
+        "@id": "/examples/data/nested-forms/customer-invoice-1.jsonld"
+      },
+      "title": "Déploiement",
+      "creationDate": "2020-10-02",
+      "modificationDate": "2020-10-04",
+      "htAmount": 500,
+      "permissions": []
+    }
+  ],
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+}
diff --git a/examples/data/nested-forms/customer-invoice-1.jsonld b/examples/data/nested-forms/customer-invoice-1.jsonld
index 6d03b5b11f06974645dc2f6538face928c70f310..eac5c2fe4a94d10a0c2c315df1d228040dd1ed6b 100644
--- a/examples/data/nested-forms/customer-invoice-1.jsonld
+++ b/examples/data/nested-forms/customer-invoice-1.jsonld
@@ -1,31 +1,31 @@
 {
-	"@id": "/examples/data/nested-forms/customer-invoice-1.jsonld",
-	"@type": "hd:customerinvoice",
-	"customer": {
-		"@id": "/examples/data/nested-forms/customer-1.jsonld"
-	},
-	"project": {
-		"@id": "/examples/data/nested-forms/project-1.jsonld"
-	},
-	"batches": {
-		"@id": "/examples/data/nested-forms/customer-invoice-1-batches.jsonld",
-		"@type": "ldp:Container",
-		"ldp:contains": [
-			{ "@id": "/examples/data/nested-forms/batch-1.jsonld" },
-			{ "@id": "/examples/data/nested-forms/batch-2.jsonld" }
-		]
-	},
-	"identifier": "F-202001",
-	"title": "Création plateforme Coopedia",
-	"state": "pending",
-	"tvaRate": 20,
-	"creationDate": "2020-10-02",
-	"modificationDate": "2020-10-04",
-	"invoicingDate": "2020-10-10",
-	"additionalText": "Pénalités de retard: 4%",
-	"htAmount": 2000,
-	"tvaAmount": 400,
-	"ttcAmount": 2400,
-	"permissions": [],
-	"@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+  "@id": "/examples/data/nested-forms/customer-invoice-1.jsonld",
+  "@type": "hd:customerinvoice",
+  "customer": {
+    "@id": "/examples/data/nested-forms/customer-1.jsonld"
+  },
+  "project": {
+    "@id": "/examples/data/nested-forms/project-1.jsonld"
+  },
+  "batches": {
+    "@id": "/examples/data/nested-forms/customer-invoice-1-batches.jsonld",
+    "@type": "ldp:Container",
+    "ldp:contains": [
+      { "@id": "/examples/data/nested-forms/batch-1.jsonld" },
+      { "@id": "/examples/data/nested-forms/batch-2.jsonld" }
+    ]
+  },
+  "identifier": "F-202001",
+  "title": "Création plateforme Coopedia",
+  "state": "pending",
+  "tvaRate": 20,
+  "creationDate": "2020-10-02",
+  "modificationDate": "2020-10-04",
+  "invoicingDate": "2020-10-10",
+  "additionalText": "Pénalités de retard: 4%",
+  "htAmount": 2000,
+  "tvaAmount": 400,
+  "ttcAmount": 2400,
+  "permissions": [],
+  "@context": "https://cdn.startinblox.com/owl/context.jsonld"
+}
diff --git a/examples/data/project.jsonld b/examples/data/project.jsonld
index 18beaf044e647ac42b694d7c0938333f68cc8a0a..dbe84128da0b2d2b48ff7e3b28fc3b99213e1f0f 100644
--- a/examples/data/project.jsonld
+++ b/examples/data/project.jsonld
@@ -10,11 +10,6 @@
   "jabberRoom": true,
   "texte": "ceci est un texte avec du **markdown** \u00e0 l'int\u00e9rieur and a [link](https://startinblox.com).",
   "@type": "doap:project",
-  "permissions": [
-    "control",
-    "add",
-    "delete",
-    "change"
-  ],
+  "permissions": ["control", "add", "delete", "change"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/project2.jsonld b/examples/data/project2.jsonld
index 7a326b5d183b9469cc7f0ac5305315d610d66fb3..b7064441ca6f08df9ac369c5c9b0bf107a51c692 100644
--- a/examples/data/project2.jsonld
+++ b/examples/data/project2.jsonld
@@ -9,12 +9,6 @@
   "jabberID": "fusee@conference.happy-dev.fr",
   "jabberRoom": true,
   "@type": "doap:project",
-  "permissions": [
-    "view",
-    "control",
-    "add",
-    "delete",
-    "change"
-  ],
+  "permissions": ["view", "control", "add", "delete", "change"],
   "@context": "https://cdn.startinblox.com/owl/context.jsonld"
-}
\ No newline at end of file
+}
diff --git a/examples/data/xwiki.jsonld b/examples/data/xwiki.jsonld
index 6fa92f63f83bb6ad9bfef04ef48759edba4290f0..7a874e44d20c9246d1abba0b2b5498dc9df6a7c8 100644
--- a/examples/data/xwiki.jsonld
+++ b/examples/data/xwiki.jsonld
@@ -116,11 +116,5 @@
       "fieldName": "wysiwyg"
     }
   },
-  "permissions": [
-    "view",
-    "control",
-    "add",
-    "delete",
-    "change"
-  ]
-}
\ No newline at end of file
+  "permissions": ["view", "control", "add", "delete", "change"]
+}
diff --git a/examples/e2e/helpers.css b/examples/e2e/helpers.css
index 2c7f3bdd4d2178687f7def9fe0d9f4b87813c2d3..600a424a9e0a638f5bd337cf391c11072ae282f9 100644
--- a/examples/e2e/helpers.css
+++ b/examples/e2e/helpers.css
@@ -1,7 +1,7 @@
-html{
+html {
   background-color: green;
 }
 
-html::before{
-  content: 'styles loaded';
-}
\ No newline at end of file
+html::before {
+  content: "styles loaded";
+}
diff --git a/examples/e2e/helpers.js b/examples/e2e/helpers.js
index 42c4dd90b24341485349999706c67a0bffae5698..7a663e542b7a790542b4b5d2e2639503944f685b 100644
--- a/examples/e2e/helpers.js
+++ b/examples/e2e/helpers.js
@@ -1 +1 @@
-window.scriptLoaded = true;
\ No newline at end of file
+window.scriptLoaded = true;
diff --git a/examples/e2e/solid-form-richtext.html b/examples/e2e/solid-form-richtext.html
index fe111ed4d5ce4561b1afea183538414225000672..ab4266e0fa734fa4027950a3ed817964def83fc9 100644
--- a/examples/e2e/solid-form-richtext.html
+++ b/examples/e2e/solid-form-richtext.html
@@ -47,6 +47,14 @@
     widget-website="solid-form-richtext"
   ></solid-form>
 
+  <h3>multiple new lines</h3>
+  <solid-form
+    id="form-5"
+    data-src="/examples/data/list/event-6.jsonld"
+    fields="description"
+    widget-description="solid-form-richtext">
+  </solid-form>
+
   <style>
     .id {
       font-family: monospace;
diff --git a/examples/e2e/solid-map.html b/examples/e2e/solid-map.html
deleted file mode 100644
index 764012730b628f63e2560bcf69d922f593847914..0000000000000000000000000000000000000000
--- a/examples/e2e/solid-map.html
+++ /dev/null
@@ -1,86 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
-    <title>SIB test: solid-map</title>
-    <script type="module" src="../../dist/index.js"></script>
-    <script>
-        document.addEventListener("DOMContentLoaded", event => {
-          document.querySelector("solid-map").addEventListener("resourceSelect", event => console.log(event.detail.resource));
-        });
-    </script>
-
-    <link rel="stylesheet" href="../styles.css" />
-  </head>
-
-  <body>
-    <h2>solid-map</h2>
-
-    <solid-map
-      id="map-1"
-      data-src="/examples/data/map/events.jsonld"
-      style="display: block; width: 800px; height: 600px;"
-    ></solid-map>
-    <br>
-    <solid-map
-      id="map-2"
-      data-src="/examples/data/map/events.jsonld"
-      fields="infos(name, category)"
-      style="display: block; width: 800px; height: 600px;"
-    ></solid-map>
-    <br>
-    <solid-map
-      id="map-3"
-      data-src="/examples/data/map/events.jsonld"
-      group-by="category"
-      style="display: block; width: 800px; height: 600px;"
-    ></solid-map>
-    <br>
-    <solid-map
-      id="map-4"
-      data-src="/examples/data/map/events.jsonld"
-      fields="infos(name, category)"
-      group-by="category"
-      class-name="test-class-name"
-      widget-name="solid-display-div"
-      editable-name
-      style="display: block; width: 800px; height: 600px;"
-    ></solid-map>
-    <br>
-    <solid-form-search
-      id="filter"
-      fields="category"
-    ></solid-form-search>
-    <br>
-    <solid-map
-      id="map-5"
-      data-src="/examples/data/map/events.jsonld"
-      fields="name, category"
-      filtered-by="filter"
-      counter-template="<span id='counter'>${counter} results<span>"
-      style="display: block; width: 800px; height: 600px;"
-    ></solid-map>
-<br>
-    <solid-map
-      id="map-6"
-      data-src="/examples/data/map/events.jsonld"
-      fields="name, category"
-      style="display: block; width: 800px; height: 600px;"
-      clustering
-    ></solid-map>
-    <br>
-    <solid-map
-      id="map-federated"
-      data-src="/examples/data/map/source.jsonld"
-      style="display: block; width: 800px; height: 600px;"
-    ></solid-map>
-
-    <style>
-      .group-meetup {
-        border-color: coral;
-      }
-    </style>
-  </body>
-</html>
diff --git a/examples/e2e/solid-table.html b/examples/e2e/solid-table.html
index 4b3ed9a3107a84f5562b857974afb79fed441183..f377f69baf474cb6a240c7ac71d18d226162b92e 100644
--- a/examples/e2e/solid-table.html
+++ b/examples/e2e/solid-table.html
@@ -93,6 +93,15 @@
       order-group-asc
     ></solid-table>
 
+    <h4>Table grouped by desc date</h4>
+    <solid-table
+      id="grouped-table-date-desc"
+      data-src="/examples/data/list/event-5.jsonld"
+      fields="name, date, place, year"
+      group-by="date"
+      order-group-desc
+    ></solid-table>
+
     <h4>Table grouped by asc date</h4>
     <solid-table
       id="grouped-table-date-asc"
diff --git a/examples/filtered-map.html b/examples/filtered-map.html
deleted file mode 100644
index ed9bcb1e8559fb914f0b3a415ab46786a56fd9dd..0000000000000000000000000000000000000000
--- a/examples/filtered-map.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
-    <title>SIB test: filtered solid-map</title>
-    <script type="module" src="../dist/index.js"></script>
-    <script>
-        document.addEventListener("DOMContentLoaded", event => {
-          document.querySelector("solid-map").addEventListener("resourceSelect", event => console.log(event.detail.resource));
-        });
-    </script>
-
-    <link rel="stylesheet" href="styles.css" />
-  </head>
-
-  <body>
-    <h2>Filtered Solid Map</h2>
-    <solid-form-search
-      id="filter"
-      fields="name"
-      label-name='Filter places (try "Europe")'
-      submit-button="update map"
-    ></solid-form-search>
-    <solid-map
-      data-src="/examples/data/map/events.jsonld"
-      fields="infos(name, category)"
-      group-by="category"
-      filtered-by="filter"
-      style="display: block; width: 800px; height: 600px;"
-    ></solid-map>
-
-    <style>
-      .group-meetup {
-        border-color: coral;
-      }
-    </style>
-  </body>
-</html>
diff --git a/examples/filtered.html b/examples/filtered.html
index 6b7a8922cd3f6a7df8720f47c0be37d298b9a841..cd3f1886782fb3b6380d77610b653f5bfe0debd9 100644
--- a/examples/filtered.html
+++ b/examples/filtered.html
@@ -29,16 +29,17 @@
       function change(input) {
         if (!(input instanceof HTMLInputElement)) return;
         const value = input.value;
-        const elm = input.closest('form').nextElementSibling;
+        const elm = input.closest("form").nextElementSibling;
         elm.component.filteredBy = value;
       }
-      document.addEventListener('DOMContentLoaded', () => {
-        document.querySelector('main').addEventListener('change', ({ target }) =>
-          change(target),
-        );
-        [...document.querySelectorAll('input[type=radio]')]
-          .filter((elm) => elm.checked)
-          .forEach(change);
+      document.addEventListener("DOMContentLoaded", () => {
+        document
+          .querySelector("main")
+          .addEventListener("change", ({ target }) => change(target));
+        for (const input of document.querySelectorAll("input[type=radio]")) {
+          if (!input.checked) continue;
+          change(input);
+        }
       });
     </script>
   </head>
@@ -61,7 +62,7 @@
       <div>
         <h3>solid-display 1</h3>
         <form>
-          filteredBy: 
+          filteredBy:
           <label
             ><input type="radio" name="filterBy" value="filter1" checked />
             filter1</label
@@ -80,7 +81,7 @@
       <div>
         <h3>solid-display 2</h3>
         <form>
-          filteredBy: 
+          filteredBy:
           <label
             ><input type="radio" name="filterBy" value="filter1" checked />
             filter1</label
diff --git a/examples/pagination.html b/examples/pagination.html
index 89bb6486ac6e1d388ebcbcce7a68942f70215458..18c57fc011aeae3d60acff269c40068074dfbdc7 100644
--- a/examples/pagination.html
+++ b/examples/pagination.html
@@ -27,6 +27,17 @@
           search-fields="email"
           paginate-by="2"
         ></solid-display>
-      </details>
+    </details>
+
+    <details>
+      <summary>Search + Pagination + Order:</summary>
+      <solid-display
+        data-src="/examples/data/list/users-medium.jsonld"
+        fields="@id, username, first_name, last_name, email"
+        order-asc="first_name"
+        search-fields="email"
+        paginate-by="2"
+      ></solid-display>
+  </details>
   </body>
 </html>
diff --git a/examples/solid-calendar.html b/examples/solid-calendar.html
deleted file mode 100644
index 00aa4c3b23e98316f626f2ad968a3c832fdcaed9..0000000000000000000000000000000000000000
--- a/examples/solid-calendar.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
-    <title>SIB test: solid-calendar</title>
-    <script type="module" src="../dist/components/solid-calendar.js"></script>
-    <script>
-      document.addEventListener('DOMContentLoaded', event => {
-        document
-          .querySelector('solid-calendar')
-          .addEventListener('resourceSelect', event =>
-            console.log(event.detail.resource),
-          );
-      });
-    </script>
-    <style>
-      solid-calendar {
-        display: block;
-        width: 800px;
-        height: 600px;
-        border: 1px solid red;
-        position: relative;
-      }
-      .tui-view-7{
-        height: 100% !important;
-      }
-    </style>
-  </head>
-  <body>
-    <h2>solid-calendar</h2>
-    <solid-calendar data-src="/examples/data/calendar/events.jsonld"></solid-calendar>
-  </body>
-</html>
diff --git a/examples/solid-form-auto-complete.html b/examples/solid-form-auto-complete.html
new file mode 100644
index 0000000000000000000000000000000000000000..3589279cf08f500932a21e0f8bab57867244fa91
--- /dev/null
+++ b/examples/solid-form-auto-complete.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>SIB test: solid-form auto-complete</title>
+    <script type="module" src="../dist/index.js"></script>
+    <link rel="stylesheet" href="styles.css" />
+  </head>
+
+  <body>
+    <h1>Auto complete</h1>
+    <h2>Single skill</h2>
+    <solid-form
+      data-src="/examples/data/list/user-1.jsonld"
+      fields="skills"
+      widget-skills="solid-form-dropdown-autocompletion"
+      range-skills="/examples/data/list/skills.jsonld"
+    ></solid-form>
+    <h2>Multiple skills</h2>
+    <solid-form
+      data-src="/examples/data/list/user-1.jsonld"
+      fields="skills"
+      range-skills="/examples/data/list/skills.jsonld"
+      multiple-skills="solid-form-multipleselect-autocompletion"
+    ></solid-form>
+   
+    <h2>New Widget Factory</h2>
+    <script type="module">
+      import { newWidgetFactory } from '../../dist/index.js';
+
+      newWidgetFactory('solid-form-dropdown-autocompletion-placeholder');
+    </script>
+
+    <solid-form-dropdown-autocompletion-placeholder
+      id="test9"
+      name="test9"
+      search-placeholder="Skills :"
+      range="/examples/data/list/skills.jsonld"
+    ></solid-form-dropdown-autocompletion-placeholder>
+  </body>
+</html>
diff --git a/examples/solid-form.html b/examples/solid-form.html
index 696c9fb6b2ca5979ee1fc352a053c1fad347ca62..b13ab928c234881632825702fd126997deb4d3f4 100644
--- a/examples/solid-form.html
+++ b/examples/solid-form.html
@@ -120,7 +120,7 @@
           data-src="/examples/data/list/event-1.jsonld"
           fields="contact"
           widget-contact="solid-form-dropdown-autocompletion"
-          range-contact="data/list/users.jsonld"
+          range-contact="/examples/data/list/skills.jsonld"
           ></solid-form>
           <h2>Multiple skills</h2>
           <solid-form
diff --git a/examples/solid-map.html b/examples/solid-map.html
deleted file mode 100644
index c746cf378d3bf607fefeb51b73e2938b8c66e876..0000000000000000000000000000000000000000
--- a/examples/solid-map.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
-    <title>SIB test: solid-map</title>
-    <script type="module" src="../dist/index.js"></script>
-    <script>
-        document.addEventListener("DOMContentLoaded", event => {
-          document.querySelector("solid-map").addEventListener("resourceSelect", event => console.log(event.detail.resource));
-        });
-    </script>
-
-    <link rel="stylesheet" href="styles.css" />
-  </head>
-
-  <body>
-    <h2>Solid Map</h2>
-    <solid-map
-      data-src="/examples/data/map/events.jsonld"
-      fields="infos(name, category)"
-      group-by="category"
-      style="display: block; width: 800px; height: 600px;"
-    ></solid-map>
-
-    <style>
-      .group-meetup {
-        border-color: coral;
-      }
-    </style>
-  </body>
-</html>
diff --git a/examples/styles.css b/examples/styles.css
index 812f75b7ba65dd643cca127203dfe2acdf0ddcfd..4b0a6e768699146d1d0f5f038c142722321864dd 100644
--- a/examples/styles.css
+++ b/examples/styles.css
@@ -44,7 +44,7 @@ solid-route[active] {
   background-color: #ccc;
 }
 
-[active]{
+[active] {
   outline: 2px dotted;
 }
 
diff --git a/index.html b/index.html
index 71adacda37fb78942c391115d536d28c51740f92..ce13ee5c44c2e05b6efa06363d802c27e3b35e6b 100644
--- a/index.html
+++ b/index.html
@@ -26,8 +26,6 @@
           <li><a href="./examples/solid-display.html">solid-display</a></li>
           <li><a href="./examples/solid-display-server-search.html">solid-display, with server search</a></li>
           <li><a href="./examples/solid-form.html">solid-form</a></li>
-          <li><a href="./examples/solid-map.html">solid-map</a></li>
-          <li><a href="./examples/solid-calendar.html">solid-calendar</a></li>
           <li><a href="./examples/solid-delete.html">solid-delete</a></li>
           <li><a href="./examples/solid-ac-checker.html">solid-ac-checker</a></li>
           <li><a href="./examples/solid-widget.html">solid-widget</a></li>
@@ -46,6 +44,7 @@
           <li><a href="./examples/nested-form.html">nested-form</a></li>
           <li><a href="./examples/validation.html">solid-form + confirm or dialog popup</a></li>
           <li><a href="./examples/auto-range.html">auto-range</a></li>
+          <li><a href="./examples/solid-form-auto-complete.html">solid-form auto-complete</a></li>
         </ul>
       </li>
       <li>
@@ -53,7 +52,6 @@
         <ul>
           <li><a href="./examples/search.html">search</a></li>
           <li><a href="./examples/filtered.html">filtered-by</a></li>
-          <li><a href="./examples/filtered-map.html">filtered-by + solid-map</a></li>
           <li><a href="./examples/pagination.html">pagination</a></li>
           <li><a href="./examples/counter.html">counter</a></li>
           <li><a href="./examples/order-by.html">order-by</a></li>
diff --git a/package-lock.json b/package-lock.json
index bbf27f56cd82e4291cc73e97b85ae22cbed79544..c1bac42d0f61b8ebd609075e3f162e995dfc2965 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,41 +9,192 @@
       "version": "0.0.0",
       "license": "MIT",
       "dependencies": {
-        "cors": "^2.8.5"
+        "cors": "^2.8.5",
+        "lit": "^3.2.1",
+        "loglevel": "^1.9.1"
       },
       "devDependencies": {
+        "@biomejs/biome": "1.9.4",
         "@rckeller/cypress-unfetch": "^1.0.1",
         "@types/autolinker": "^2.0.0",
-        "@types/leaflet": "^1.5.21",
-        "@types/leaflet.markercluster": "^1.4.3",
-        "@types/markdown-it": "^12.0.1",
-        "@types/node": "^20.5.0",
-        "@types/pubsub-js": "^1.8.2",
-        "@types/quill": "^2.0.4",
-        "autolinker": "^3.14.2",
-        "cypress": "^13.2.0",
+        "@types/jsonld": "^1.5.15",
+        "@types/markdown-it": "^14.1.2",
+        "@types/markdown-it-link-attributes": "^3.0.5",
+        "@types/node": "^22.7.1",
+        "@types/pubsub-js": "^1.8.6",
+        "autolinker": "^4.0.0",
+        "cypress": "^13.14.2",
         "cypress-plugin-tab": "^1.0.5",
-        "delta-markdown-for-quill": "0.0.9",
         "dialog-polyfill": "^0.5.6",
-        "express": "^4.17.1",
+        "express": "^4.21.0",
         "find-free-port": "^2.0.0",
-        "fuse.js": "^6.4.6",
-        "jsonld": "^8.3.1",
+        "fuse.js": "^7.0.0",
+        "jsonld": "^8.3.2",
         "jsonld-context-parser": "^1.3.4",
-        "leaflet": "1.7.1",
-        "leaflet.markercluster": "1.5.3",
-        "lit-html": "^1.3.0",
-        "markdown-it": "^12.0.4",
+        "markdown-it": "^14.1.0",
         "markdown-it-link-attributes": "4.0.1",
-        "markdown-to-quill-delta": "^0.7.0",
-        "pubsub-js": "^1.9.2",
-        "quill": "^1.3.7",
+        "pubsub-js": "^1.9.4",
+        "quill": "^2.0.3",
         "quill-delta-to-markdown": "^0.6.0",
-        "semver": "7.5.4",
-        "slim-select": "^1.27.0",
-        "tui-calendar": "^1.13.0",
-        "typescript": "^4.9.5",
-        "vite": "^5.0.12"
+        "semver": "7.6.3",
+        "slim-select": "^2.9.2",
+        "typescript": "^5.6.2",
+        "vite": "^5.4.8"
+      }
+    },
+    "node_modules/@biomejs/biome": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz",
+      "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "biome": "bin/biome"
+      },
+      "engines": {
+        "node": ">=14.21.3"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/biome"
+      },
+      "optionalDependencies": {
+        "@biomejs/cli-darwin-arm64": "1.9.4",
+        "@biomejs/cli-darwin-x64": "1.9.4",
+        "@biomejs/cli-linux-arm64": "1.9.4",
+        "@biomejs/cli-linux-arm64-musl": "1.9.4",
+        "@biomejs/cli-linux-x64": "1.9.4",
+        "@biomejs/cli-linux-x64-musl": "1.9.4",
+        "@biomejs/cli-win32-arm64": "1.9.4",
+        "@biomejs/cli-win32-x64": "1.9.4"
+      }
+    },
+    "node_modules/@biomejs/cli-darwin-arm64": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz",
+      "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=14.21.3"
+      }
+    },
+    "node_modules/@biomejs/cli-darwin-x64": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz",
+      "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=14.21.3"
+      }
+    },
+    "node_modules/@biomejs/cli-linux-arm64": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz",
+      "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=14.21.3"
+      }
+    },
+    "node_modules/@biomejs/cli-linux-arm64-musl": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz",
+      "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=14.21.3"
+      }
+    },
+    "node_modules/@biomejs/cli-linux-x64": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz",
+      "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=14.21.3"
+      }
+    },
+    "node_modules/@biomejs/cli-linux-x64-musl": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz",
+      "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=14.21.3"
+      }
+    },
+    "node_modules/@biomejs/cli-win32-arm64": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz",
+      "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=14.21.3"
+      }
+    },
+    "node_modules/@biomejs/cli-win32-x64": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz",
+      "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=14.21.3"
       }
     },
     "node_modules/@colors/colors": {
@@ -57,9 +208,9 @@
       }
     },
     "node_modules/@cypress/request": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz",
-      "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==",
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.6.tgz",
+      "integrity": "sha512-fi0eVdCOtKu5Ed6+E8mYxUF6ZTFJDZvHogCBelM0xVXmrDEkyM22gRArQzq1YcHPm1V47Vf/iAD+WgVdUlJCGg==",
       "dev": true,
       "dependencies": {
         "aws-sign2": "~0.7.0",
@@ -68,16 +219,16 @@
         "combined-stream": "~1.0.6",
         "extend": "~3.0.2",
         "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "http-signature": "~1.3.6",
+        "form-data": "~4.0.0",
+        "http-signature": "~1.4.0",
         "is-typedarray": "~1.0.0",
         "isstream": "~0.1.2",
         "json-stringify-safe": "~5.0.1",
         "mime-types": "~2.1.19",
         "performance-now": "^2.1.0",
-        "qs": "6.10.4",
+        "qs": "6.13.0",
         "safe-buffer": "^5.1.2",
-        "tough-cookie": "^4.1.3",
+        "tough-cookie": "^5.0.0",
         "tunnel-agent": "^0.6.0",
         "uuid": "^8.3.2"
       },
@@ -85,21 +236,6 @@
         "node": ">= 6"
       }
     },
-    "node_modules/@cypress/request/node_modules/qs": {
-      "version": "6.10.4",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz",
-      "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==",
-      "dev": true,
-      "dependencies": {
-        "side-channel": "^1.0.4"
-      },
-      "engines": {
-        "node": ">=0.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/@cypress/xvfb": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz",
@@ -134,9 +270,9 @@
       }
     },
     "node_modules/@esbuild/aix-ppc64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
-      "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
       "cpu": [
         "ppc64"
       ],
@@ -150,9 +286,9 @@
       }
     },
     "node_modules/@esbuild/android-arm": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
-      "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+      "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
       "cpu": [
         "arm"
       ],
@@ -166,9 +302,9 @@
       }
     },
     "node_modules/@esbuild/android-arm64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
-      "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+      "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
       "cpu": [
         "arm64"
       ],
@@ -182,9 +318,9 @@
       }
     },
     "node_modules/@esbuild/android-x64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
-      "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+      "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
       "cpu": [
         "x64"
       ],
@@ -198,9 +334,9 @@
       }
     },
     "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
-      "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+      "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
       "cpu": [
         "arm64"
       ],
@@ -214,9 +350,9 @@
       }
     },
     "node_modules/@esbuild/darwin-x64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
-      "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+      "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
       "cpu": [
         "x64"
       ],
@@ -230,9 +366,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
-      "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+      "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
       "cpu": [
         "arm64"
       ],
@@ -246,9 +382,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
-      "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+      "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
       "cpu": [
         "x64"
       ],
@@ -262,9 +398,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
-      "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+      "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
       "cpu": [
         "arm"
       ],
@@ -278,9 +414,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
-      "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+      "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
       "cpu": [
         "arm64"
       ],
@@ -294,9 +430,9 @@
       }
     },
     "node_modules/@esbuild/linux-ia32": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
-      "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+      "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
       "cpu": [
         "ia32"
       ],
@@ -310,9 +446,9 @@
       }
     },
     "node_modules/@esbuild/linux-loong64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
-      "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+      "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
       "cpu": [
         "loong64"
       ],
@@ -326,9 +462,9 @@
       }
     },
     "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
-      "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+      "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
       "cpu": [
         "mips64el"
       ],
@@ -342,9 +478,9 @@
       }
     },
     "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
-      "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+      "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
       "cpu": [
         "ppc64"
       ],
@@ -358,9 +494,9 @@
       }
     },
     "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
-      "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+      "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
       "cpu": [
         "riscv64"
       ],
@@ -374,9 +510,9 @@
       }
     },
     "node_modules/@esbuild/linux-s390x": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
-      "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+      "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
       "cpu": [
         "s390x"
       ],
@@ -390,9 +526,9 @@
       }
     },
     "node_modules/@esbuild/linux-x64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
-      "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+      "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
       "cpu": [
         "x64"
       ],
@@ -406,9 +542,9 @@
       }
     },
     "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
-      "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
       "cpu": [
         "x64"
       ],
@@ -422,9 +558,9 @@
       }
     },
     "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
-      "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+      "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
       "cpu": [
         "x64"
       ],
@@ -438,9 +574,9 @@
       }
     },
     "node_modules/@esbuild/sunos-x64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
-      "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+      "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
       "cpu": [
         "x64"
       ],
@@ -454,9 +590,9 @@
       }
     },
     "node_modules/@esbuild/win32-arm64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
-      "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+      "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
       "cpu": [
         "arm64"
       ],
@@ -470,9 +606,9 @@
       }
     },
     "node_modules/@esbuild/win32-ia32": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
-      "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+      "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
       "cpu": [
         "ia32"
       ],
@@ -486,9 +622,9 @@
       }
     },
     "node_modules/@esbuild/win32-x64": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
-      "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+      "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
       "cpu": [
         "x64"
       ],
@@ -580,6 +716,19 @@
         "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
+    "node_modules/@lit-labs/ssr-dom-shim": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz",
+      "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ=="
+    },
+    "node_modules/@lit/reactive-element": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz",
+      "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.2.0"
+      }
+    },
     "node_modules/@rckeller/cypress-unfetch": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@rckeller/cypress-unfetch/-/cypress-unfetch-1.0.1.tgz",
@@ -590,9 +739,9 @@
       }
     },
     "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz",
-      "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz",
+      "integrity": "sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==",
       "cpu": [
         "arm"
       ],
@@ -603,9 +752,9 @@
       ]
     },
     "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz",
-      "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.4.tgz",
+      "integrity": "sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==",
       "cpu": [
         "arm64"
       ],
@@ -616,9 +765,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz",
-      "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.4.tgz",
+      "integrity": "sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==",
       "cpu": [
         "arm64"
       ],
@@ -629,9 +778,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz",
-      "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.4.tgz",
+      "integrity": "sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==",
       "cpu": [
         "x64"
       ],
@@ -641,10 +790,49 @@
         "darwin"
       ]
     },
+    "node_modules/@rollup/rollup-freebsd-arm64": {
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.4.tgz",
+      "integrity": "sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-x64": {
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.4.tgz",
+      "integrity": "sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
     "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz",
-      "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.4.tgz",
+      "integrity": "sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.4.tgz",
+      "integrity": "sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==",
       "cpu": [
         "arm"
       ],
@@ -655,9 +843,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz",
-      "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.4.tgz",
+      "integrity": "sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==",
       "cpu": [
         "arm64"
       ],
@@ -668,9 +856,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz",
-      "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.4.tgz",
+      "integrity": "sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==",
       "cpu": [
         "arm64"
       ],
@@ -680,10 +868,23 @@
         "linux"
       ]
     },
+    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.4.tgz",
+      "integrity": "sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
     "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz",
-      "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.4.tgz",
+      "integrity": "sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==",
       "cpu": [
         "riscv64"
       ],
@@ -693,10 +894,23 @@
         "linux"
       ]
     },
+    "node_modules/@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.4.tgz",
+      "integrity": "sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
     "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz",
-      "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.4.tgz",
+      "integrity": "sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==",
       "cpu": [
         "x64"
       ],
@@ -707,9 +921,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz",
-      "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.4.tgz",
+      "integrity": "sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==",
       "cpu": [
         "x64"
       ],
@@ -720,9 +934,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz",
-      "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.4.tgz",
+      "integrity": "sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==",
       "cpu": [
         "arm64"
       ],
@@ -733,9 +947,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz",
-      "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.4.tgz",
+      "integrity": "sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==",
       "cpu": [
         "ia32"
       ],
@@ -746,9 +960,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz",
-      "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.4.tgz",
+      "integrity": "sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==",
       "cpu": [
         "x64"
       ],
@@ -768,104 +982,66 @@
         "autolinker": "*"
       }
     },
-    "node_modules/@types/debug": {
-      "version": "4.1.12",
-      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
-      "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/ms": "*"
-      }
-    },
     "node_modules/@types/estree": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
-      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
-      "dev": true
-    },
-    "node_modules/@types/geojson": {
-      "version": "7946.0.10",
-      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
-      "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==",
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
       "dev": true
     },
-    "node_modules/@types/leaflet": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.3.tgz",
-      "integrity": "sha512-Caa1lYOgKVqDkDZVWkto2Z5JtVo09spEaUt2S69LiugbBpoqQu92HYFMGUbYezZbnBkyOxMNPXHSgRrRY5UyIA==",
-      "dev": true,
-      "dependencies": {
-        "@types/geojson": "*"
-      }
-    },
-    "node_modules/@types/leaflet.markercluster": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/@types/leaflet.markercluster/-/leaflet.markercluster-1.5.1.tgz",
-      "integrity": "sha512-gzJzP10qO6Zkts5QNVmSAEDLYicQHTEBLT9HZpFrJiSww9eDAs5OWHvIskldf41MvDv1gbMukuEBQEawHn+wtA==",
+    "node_modules/@types/jsonld": {
+      "version": "1.5.15",
+      "resolved": "https://registry.npmjs.org/@types/jsonld/-/jsonld-1.5.15.tgz",
+      "integrity": "sha512-PlAFPZjL+AuGYmwlqwKEL0IMP8M8RexH0NIPGfCVWSQ041H2rR/8OlyZSD7KsCVoN8vCfWdtWDBxX8yBVP+xow==",
       "dev": true,
-      "dependencies": {
-        "@types/leaflet": "*"
-      }
+      "license": "MIT"
     },
     "node_modules/@types/linkify-it": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
-      "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+      "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
       "dev": true
     },
     "node_modules/@types/markdown-it": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
-      "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
+      "version": "14.1.2",
+      "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+      "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
       "dev": true,
       "dependencies": {
-        "@types/linkify-it": "*",
-        "@types/mdurl": "*"
+        "@types/linkify-it": "^5",
+        "@types/mdurl": "^2"
       }
     },
-    "node_modules/@types/mdast": {
-      "version": "3.0.15",
-      "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz",
-      "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==",
+    "node_modules/@types/markdown-it-link-attributes": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@types/markdown-it-link-attributes/-/markdown-it-link-attributes-3.0.5.tgz",
+      "integrity": "sha512-VZ2BGN3ywUg7mBD8W6PwR8ChpOxaQSBDbLqPgvNI+uIra3zY2af1eG/3XzWTKjEraTWskMKnZqZd6m1fDF67Bg==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
-        "@types/unist": "^2"
+        "@types/markdown-it": "*"
       }
     },
     "node_modules/@types/mdurl": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
-      "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
-      "dev": true
-    },
-    "node_modules/@types/ms": {
-      "version": "0.7.34",
-      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz",
-      "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+      "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "20.5.0",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.0.tgz",
-      "integrity": "sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==",
-      "dev": true
-    },
-    "node_modules/@types/pubsub-js": {
-      "version": "1.8.3",
-      "resolved": "https://registry.npmjs.org/@types/pubsub-js/-/pubsub-js-1.8.3.tgz",
-      "integrity": "sha512-6BqY04dh2UV1dNV690tyJVJYQ0U6qBH4tU+FCwY1Mhl8jOPOP9qiIvgLnB59cVik/E6/R002oXZpGiDm+2C8eA==",
-      "dev": true
-    },
-    "node_modules/@types/quill": {
-      "version": "2.0.10",
-      "resolved": "https://registry.npmjs.org/@types/quill/-/quill-2.0.10.tgz",
-      "integrity": "sha512-L6OHONEj2v4NRbWQOsn7j1N0SyzhRR3M4g1M6j/uuIwIsIW2ShWHhwbqNvH8hSmVktzqu0lITfdnqVOQ4qkrhA==",
+      "version": "22.10.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz",
+      "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==",
       "dev": true,
       "dependencies": {
-        "parchment": "^1.1.2",
-        "quill-delta": "^4.0.1"
+        "undici-types": "~6.20.0"
       }
     },
+    "node_modules/@types/pubsub-js": {
+      "version": "1.8.6",
+      "resolved": "https://registry.npmjs.org/@types/pubsub-js/-/pubsub-js-1.8.6.tgz",
+      "integrity": "sha512-Kwug5cwV0paUDm/NfwDx1sp9xI0bGIvmWJjJWCU8NngkCCMt3EIC7oPDvb6fV7BR8kPpFyyBu4D11bda/2MdPA==",
+      "dev": true
+    },
     "node_modules/@types/sinonjs__fake-timers": {
       "version": "8.1.1",
       "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
@@ -878,11 +1054,10 @@
       "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
       "dev": true
     },
-    "node_modules/@types/unist": {
-      "version": "2.0.11",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
-      "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
-      "dev": true
+    "node_modules/@types/trusted-types": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+      "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="
     },
     "node_modules/@types/yauzl": {
       "version": "2.10.0",
@@ -1070,9 +1245,9 @@
       }
     },
     "node_modules/autolinker": {
-      "version": "3.16.2",
-      "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz",
-      "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-4.0.0.tgz",
+      "integrity": "sha512-fl5Kh6BmEEZx+IWBfEirnRUU5+cOiV0OK7PEt0RBKvJMJ8GaRseIOeDU3FKf4j3CE5HVefcjHmhYPOcaVt0bZw==",
       "dev": true,
       "dependencies": {
         "tslib": "^2.3.0"
@@ -1088,25 +1263,9 @@
       }
     },
     "node_modules/aws4": {
-      "version": "1.12.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
-      "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==",
-      "dev": true
-    },
-    "node_modules/bail": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
-      "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
-      "dev": true,
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz",
+      "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==",
       "dev": true
     },
     "node_modules/base64-js": {
@@ -1150,16 +1309,45 @@
       "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
       "dev": true
     },
-    "node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+    "node_modules/body-parser": {
+      "version": "1.20.3",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+      "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.2",
+        "content-type": "~1.0.5",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "on-finished": "2.4.1",
+        "qs": "6.13.0",
+        "raw-body": "2.5.2",
+        "type-is": "~1.6.18",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/body-parser/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
       "dev": true,
       "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
+        "ms": "2.0.0"
       }
     },
+    "node_modules/body-parser/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
+    },
     "node_modules/buffer": {
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
@@ -1220,14 +1408,19 @@
       }
     },
     "node_modules/call-bind": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
-      "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+      "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
       "dev": true,
       "dependencies": {
+        "es-define-property": "^1.0.0",
+        "es-errors": "^1.3.0",
         "function-bind": "^1.1.2",
-        "get-intrinsic": "^1.2.1",
-        "set-function-length": "^1.1.1"
+        "get-intrinsic": "^1.2.4",
+        "set-function-length": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -1245,26 +1438,6 @@
       "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
       "dev": true
     },
-    "node_modules/ccount": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
-      "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
-      "dev": true,
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/character-entities": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
-      "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
-      "dev": true,
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
     "node_modules/check-more-types": {
       "version": "2.24.0",
       "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
@@ -1275,9 +1448,9 @@
       }
     },
     "node_modules/ci-info": {
-      "version": "3.8.0",
-      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz",
-      "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.1.0.tgz",
+      "integrity": "sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==",
       "dev": true,
       "funding": [
         {
@@ -1341,15 +1514,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/clone": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
-      "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
     "node_modules/colorette": {
       "version": "2.0.20",
       "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
@@ -1377,30 +1541,6 @@
         "node": ">=4.0.0"
       }
     },
-    "node_modules/commonmark": {
-      "version": "0.26.0",
-      "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.26.0.tgz",
-      "integrity": "sha512-0PvjGTgkIjIdImgpt1xgR049Nyz/x27vhYT+C0ZkNuxEiys/lJZKotOVKa4y7JbtMsTutg/gCLH+13DFnaOjWg==",
-      "dev": true,
-      "dependencies": {
-        "entities": "~ 1.1.1",
-        "mdurl": "~ 1.0.1",
-        "minimist": "~ 1.2.0",
-        "string.prototype.repeat": "^0.2.0"
-      },
-      "bin": {
-        "commonmark": "bin/commonmark"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
-      "dev": true
-    },
     "node_modules/content-disposition": {
       "version": "0.5.4",
       "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@@ -1423,9 +1563,9 @@
       }
     },
     "node_modules/cookie": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
-      "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+      "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
       "dev": true,
       "engines": {
         "node": ">= 0.6"
@@ -1437,6 +1577,12 @@
       "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
       "dev": true
     },
+    "node_modules/core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
+      "dev": true
+    },
     "node_modules/cors": {
       "version": "2.8.5",
       "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
@@ -1470,24 +1616,24 @@
       "dev": true
     },
     "node_modules/cypress": {
-      "version": "13.5.1",
-      "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.5.1.tgz",
-      "integrity": "sha512-yqLViT0D/lPI8Kkm7ciF/x/DCK/H/DnogdGyiTnQgX4OVR2aM30PtK+kvklTOD1u3TuItiD9wUQAF8EYWtyZug==",
+      "version": "13.16.0",
+      "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.16.0.tgz",
+      "integrity": "sha512-g6XcwqnvzXrqiBQR/5gN+QsyRmKRhls1y5E42fyOvsmU7JuY+wM6uHJWj4ZPttjabzbnRvxcik2WemR8+xT6FA==",
       "dev": true,
       "hasInstallScript": true,
       "dependencies": {
-        "@cypress/request": "^3.0.0",
+        "@cypress/request": "^3.0.6",
         "@cypress/xvfb": "^1.2.4",
-        "@types/node": "^18.17.5",
         "@types/sinonjs__fake-timers": "8.1.1",
         "@types/sizzle": "^2.3.2",
         "arch": "^2.2.0",
         "blob-util": "^2.0.2",
         "bluebird": "^3.7.2",
-        "buffer": "^5.6.0",
+        "buffer": "^5.7.1",
         "cachedir": "^2.3.0",
         "chalk": "^4.1.0",
         "check-more-types": "^2.24.0",
+        "ci-info": "^4.0.0",
         "cli-cursor": "^3.1.0",
         "cli-table3": "~0.6.1",
         "commander": "^6.2.1",
@@ -1502,7 +1648,6 @@
         "figures": "^3.2.0",
         "fs-extra": "^9.1.0",
         "getos": "^3.2.1",
-        "is-ci": "^3.0.0",
         "is-installed-globally": "~0.4.0",
         "lazy-ass": "^1.6.0",
         "listr2": "^3.8.3",
@@ -1516,7 +1661,8 @@
         "request-progress": "^3.0.0",
         "semver": "^7.5.3",
         "supports-color": "^8.1.1",
-        "tmp": "~0.2.1",
+        "tmp": "~0.2.3",
+        "tree-kill": "1.2.2",
         "untildify": "^4.0.0",
         "yauzl": "^2.10.0"
       },
@@ -1536,15 +1682,6 @@
         "ally.js": "^1.4.1"
       }
     },
-    "node_modules/cypress/node_modules/@types/node": {
-      "version": "18.18.11",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.11.tgz",
-      "integrity": "sha512-c1vku6qnTeujJneYH94/4aq73XrVcsJe35UPyAsSok1ijiKrkRzK+AxQPSpNMUnC03roWBBwJx/9I8V7lQoxmA==",
-      "dev": true,
-      "dependencies": {
-        "undici-types": "~5.26.4"
-      }
-    },
     "node_modules/cypress/node_modules/ansi-styles": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -1683,59 +1820,15 @@
         }
       }
     },
-    "node_modules/decode-named-character-reference": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
-      "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
-      "dev": true,
-      "dependencies": {
-        "character-entities": "^2.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/deep-equal": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
-      "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
-      "dev": true,
-      "dependencies": {
-        "is-arguments": "^1.0.4",
-        "is-date-object": "^1.0.1",
-        "is-regex": "^1.0.4",
-        "object-is": "^1.0.1",
-        "object-keys": "^1.1.1",
-        "regexp.prototype.flags": "^1.2.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/define-data-property": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
-      "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
-      "dev": true,
-      "dependencies": {
-        "get-intrinsic": "^1.2.1",
-        "gopd": "^1.0.1",
-        "has-property-descriptors": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/define-properties": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
-      "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+      "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
       "dev": true,
       "dependencies": {
-        "define-data-property": "^1.0.1",
-        "has-property-descriptors": "^1.0.0",
-        "object-keys": "^1.1.1"
+        "es-define-property": "^1.0.0",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.0.1"
       },
       "engines": {
         "node": ">= 0.4"
@@ -1753,37 +1846,6 @@
         "node": ">=0.4.0"
       }
     },
-    "node_modules/delta-markdown-for-quill": {
-      "version": "0.0.9",
-      "resolved": "https://registry.npmjs.org/delta-markdown-for-quill/-/delta-markdown-for-quill-0.0.9.tgz",
-      "integrity": "sha512-Pb6LjAey0I1N5od660V3cisq7XBRK1VOS7ctJbm6z98fNRj1w6Kd0HT8Boqvsue42FfQ0+6UVfwFXyug8THKLA==",
-      "dev": true,
-      "dependencies": {
-        "commonmark": "^0.26.0",
-        "lodash": "^4.16.4",
-        "quill-delta": "^3.4.0"
-      }
-    },
-    "node_modules/delta-markdown-for-quill/node_modules/fast-diff": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
-      "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
-      "dev": true
-    },
-    "node_modules/delta-markdown-for-quill/node_modules/quill-delta": {
-      "version": "3.6.3",
-      "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
-      "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
-      "dev": true,
-      "dependencies": {
-        "deep-equal": "^1.0.1",
-        "extend": "^3.0.2",
-        "fast-diff": "1.1.2"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
     "node_modules/depd": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -1793,15 +1855,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/dequal": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
-      "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/destroy": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@@ -1818,21 +1871,6 @@
       "integrity": "sha512-ZbVDJI9uvxPAKze6z146rmfUZjBqNEwcnFTVamQzXH+svluiV7swmVIGr7miwADgfgt1G2JQIytypM9fbyhX4w==",
       "dev": true
     },
-    "node_modules/diff": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
-      "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.3.1"
-      }
-    },
-    "node_modules/dompurify": {
-      "version": "2.4.7",
-      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz",
-      "integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ==",
-      "dev": true
-    },
     "node_modules/ecc-jsbn": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -1856,9 +1894,9 @@
       "dev": true
     },
     "node_modules/encodeurl": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
-      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+      "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
       "dev": true,
       "engines": {
         "node": ">= 0.8"
@@ -1907,16 +1945,31 @@
         "node": ">=8.6"
       }
     },
-    "node_modules/entities": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
-      "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
-      "dev": true
+    "node_modules/es-define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+      "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.2.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
     },
     "node_modules/esbuild": {
-      "version": "0.19.12",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
-      "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
+      "version": "0.21.5",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+      "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
       "dev": true,
       "hasInstallScript": true,
       "bin": {
@@ -1926,29 +1979,29 @@
         "node": ">=12"
       },
       "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.19.12",
-        "@esbuild/android-arm": "0.19.12",
-        "@esbuild/android-arm64": "0.19.12",
-        "@esbuild/android-x64": "0.19.12",
-        "@esbuild/darwin-arm64": "0.19.12",
-        "@esbuild/darwin-x64": "0.19.12",
-        "@esbuild/freebsd-arm64": "0.19.12",
-        "@esbuild/freebsd-x64": "0.19.12",
-        "@esbuild/linux-arm": "0.19.12",
-        "@esbuild/linux-arm64": "0.19.12",
-        "@esbuild/linux-ia32": "0.19.12",
-        "@esbuild/linux-loong64": "0.19.12",
-        "@esbuild/linux-mips64el": "0.19.12",
-        "@esbuild/linux-ppc64": "0.19.12",
-        "@esbuild/linux-riscv64": "0.19.12",
-        "@esbuild/linux-s390x": "0.19.12",
-        "@esbuild/linux-x64": "0.19.12",
-        "@esbuild/netbsd-x64": "0.19.12",
-        "@esbuild/openbsd-x64": "0.19.12",
-        "@esbuild/sunos-x64": "0.19.12",
-        "@esbuild/win32-arm64": "0.19.12",
-        "@esbuild/win32-ia32": "0.19.12",
-        "@esbuild/win32-x64": "0.19.12"
+        "@esbuild/aix-ppc64": "0.21.5",
+        "@esbuild/android-arm": "0.21.5",
+        "@esbuild/android-arm64": "0.21.5",
+        "@esbuild/android-x64": "0.21.5",
+        "@esbuild/darwin-arm64": "0.21.5",
+        "@esbuild/darwin-x64": "0.21.5",
+        "@esbuild/freebsd-arm64": "0.21.5",
+        "@esbuild/freebsd-x64": "0.21.5",
+        "@esbuild/linux-arm": "0.21.5",
+        "@esbuild/linux-arm64": "0.21.5",
+        "@esbuild/linux-ia32": "0.21.5",
+        "@esbuild/linux-loong64": "0.21.5",
+        "@esbuild/linux-mips64el": "0.21.5",
+        "@esbuild/linux-ppc64": "0.21.5",
+        "@esbuild/linux-riscv64": "0.21.5",
+        "@esbuild/linux-s390x": "0.21.5",
+        "@esbuild/linux-x64": "0.21.5",
+        "@esbuild/netbsd-x64": "0.21.5",
+        "@esbuild/openbsd-x64": "0.21.5",
+        "@esbuild/sunos-x64": "0.21.5",
+        "@esbuild/win32-arm64": "0.21.5",
+        "@esbuild/win32-ia32": "0.21.5",
+        "@esbuild/win32-x64": "0.21.5"
       }
     },
     "node_modules/escape-html": {
@@ -1991,9 +2044,9 @@
       "dev": true
     },
     "node_modules/eventemitter3": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
-      "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+      "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
       "dev": true
     },
     "node_modules/execa": {
@@ -2032,37 +2085,37 @@
       }
     },
     "node_modules/express": {
-      "version": "4.18.2",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
-      "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+      "version": "4.21.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
+      "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
       "dev": true,
       "dependencies": {
         "accepts": "~1.3.8",
         "array-flatten": "1.1.1",
-        "body-parser": "1.20.1",
+        "body-parser": "1.20.3",
         "content-disposition": "0.5.4",
         "content-type": "~1.0.4",
-        "cookie": "0.5.0",
+        "cookie": "0.7.1",
         "cookie-signature": "1.0.6",
         "debug": "2.6.9",
         "depd": "2.0.0",
-        "encodeurl": "~1.0.2",
+        "encodeurl": "~2.0.0",
         "escape-html": "~1.0.3",
         "etag": "~1.8.1",
-        "finalhandler": "1.2.0",
+        "finalhandler": "1.3.1",
         "fresh": "0.5.2",
         "http-errors": "2.0.0",
-        "merge-descriptors": "1.0.1",
+        "merge-descriptors": "1.0.3",
         "methods": "~1.1.2",
         "on-finished": "2.4.1",
         "parseurl": "~1.3.3",
-        "path-to-regexp": "0.1.7",
+        "path-to-regexp": "0.1.10",
         "proxy-addr": "~2.0.7",
-        "qs": "6.11.0",
+        "qs": "6.13.0",
         "range-parser": "~1.2.1",
         "safe-buffer": "5.2.1",
-        "send": "0.18.0",
-        "serve-static": "1.15.0",
+        "send": "0.19.0",
+        "serve-static": "1.16.2",
         "setprototypeof": "1.2.0",
         "statuses": "2.0.1",
         "type-is": "~1.6.18",
@@ -2073,30 +2126,6 @@
         "node": ">= 0.10.0"
       }
     },
-    "node_modules/express/node_modules/body-parser": {
-      "version": "1.20.1",
-      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
-      "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
-      "dev": true,
-      "dependencies": {
-        "bytes": "3.1.2",
-        "content-type": "~1.0.4",
-        "debug": "2.6.9",
-        "depd": "2.0.0",
-        "destroy": "1.2.0",
-        "http-errors": "2.0.0",
-        "iconv-lite": "0.4.24",
-        "on-finished": "2.4.1",
-        "qs": "6.11.0",
-        "raw-body": "2.5.1",
-        "type-is": "~1.6.18",
-        "unpipe": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8",
-        "npm": "1.2.8000 || >= 1.4.16"
-      }
-    },
     "node_modules/express/node_modules/debug": {
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -2112,21 +2141,6 @@
       "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
       "dev": true
     },
-    "node_modules/express/node_modules/raw-body": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
-      "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
-      "dev": true,
-      "dependencies": {
-        "bytes": "3.1.2",
-        "http-errors": "2.0.0",
-        "iconv-lite": "0.4.24",
-        "unpipe": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -2162,12 +2176,6 @@
         "node >=0.6.0"
       ]
     },
-    "node_modules/fast-diff": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
-      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
-      "dev": true
-    },
     "node_modules/fd-slicer": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
@@ -2216,13 +2224,13 @@
       }
     },
     "node_modules/finalhandler": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
-      "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+      "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
       "dev": true,
       "dependencies": {
         "debug": "2.6.9",
-        "encodeurl": "~1.0.2",
+        "encodeurl": "~2.0.0",
         "escape-html": "~1.0.3",
         "on-finished": "2.4.1",
         "parseurl": "~1.3.3",
@@ -2264,17 +2272,17 @@
       }
     },
     "node_modules/form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+      "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
       "dev": true,
       "dependencies": {
         "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
+        "combined-stream": "^1.0.8",
         "mime-types": "^2.1.12"
       },
       "engines": {
-        "node": ">= 0.12"
+        "node": ">= 6"
       }
     },
     "node_modules/formdata-polyfill": {
@@ -2322,12 +2330,6 @@
         "node": ">=10"
       }
     },
-    "node_modules/fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
-      "dev": true
-    },
     "node_modules/fsevents": {
       "version": "2.3.3",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -2351,35 +2353,30 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/functions-have-names": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
-      "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/fuse.js": {
-      "version": "6.6.2",
-      "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz",
-      "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
+      "integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
       "dev": true,
       "engines": {
         "node": ">=10"
       }
     },
     "node_modules/get-intrinsic": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
-      "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
+      "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
       "dev": true,
       "dependencies": {
+        "es-errors": "^1.3.0",
         "function-bind": "^1.1.2",
         "has-proto": "^1.0.1",
         "has-symbols": "^1.0.3",
         "hasown": "^2.0.0"
       },
+      "engines": {
+        "node": ">= 0.4"
+      },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -2417,26 +2414,6 @@
         "assert-plus": "^1.0.0"
       }
     },
-    "node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-      "dev": true,
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
     "node_modules/global-dirs": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz",
@@ -2471,12 +2448,12 @@
       "dev": true
     },
     "node_modules/has-property-descriptors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
-      "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+      "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
       "dev": true,
       "dependencies": {
-        "get-intrinsic": "^1.2.2"
+        "es-define-property": "^1.0.0"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -2506,21 +2483,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/has-tostringtag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
-      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
-      "dev": true,
-      "dependencies": {
-        "has-symbols": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/hasown": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
@@ -2550,14 +2512,14 @@
       }
     },
     "node_modules/http-signature": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
-      "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz",
+      "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==",
       "dev": true,
       "dependencies": {
         "assert-plus": "^1.0.0",
         "jsprim": "^2.0.2",
-        "sshpk": "^1.14.1"
+        "sshpk": "^1.18.0"
       },
       "engines": {
         "node": ">=0.10"
@@ -2613,16 +2575,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
-      "dev": true,
-      "dependencies": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
     "node_modules/inherits": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -2647,72 +2599,6 @@
         "node": ">= 0.10"
       }
     },
-    "node_modules/is-arguments": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
-      "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-buffer": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
-      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/is-ci": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
-      "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
-      "dev": true,
-      "dependencies": {
-        "ci-info": "^3.2.0"
-      },
-      "bin": {
-        "is-ci": "bin.js"
-      }
-    },
-    "node_modules/is-date-object": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
-      "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
-      "dev": true,
-      "dependencies": {
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -2747,34 +2633,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/is-plain-obj": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
-      "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-regex": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
-      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-stream": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -2900,15 +2758,6 @@
         "verror": "1.10.0"
       }
     },
-    "node_modules/kleur": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
-      "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/ky": {
       "version": "0.33.3",
       "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz",
@@ -2973,28 +2822,13 @@
         "node": "> 0.8"
       }
     },
-    "node_modules/leaflet": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz",
-      "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==",
-      "dev": true
-    },
-    "node_modules/leaflet.markercluster": {
-      "version": "1.5.3",
-      "resolved": "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz",
-      "integrity": "sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA==",
-      "dev": true,
-      "peerDependencies": {
-        "leaflet": "^1.3.1"
-      }
-    },
     "node_modules/linkify-it": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
-      "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
+      "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
       "dev": true,
       "dependencies": {
-        "uc.micro": "^1.0.1"
+        "uc.micro": "^2.0.0"
       }
     },
     "node_modules/listr2": {
@@ -3024,11 +2858,33 @@
         }
       }
     },
+    "node_modules/lit": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz",
+      "integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==",
+      "dependencies": {
+        "@lit/reactive-element": "^2.0.4",
+        "lit-element": "^4.1.0",
+        "lit-html": "^3.2.0"
+      }
+    },
+    "node_modules/lit-element": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz",
+      "integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==",
+      "dependencies": {
+        "@lit-labs/ssr-dom-shim": "^1.2.0",
+        "@lit/reactive-element": "^2.0.4",
+        "lit-html": "^3.2.0"
+      }
+    },
     "node_modules/lit-html": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.4.1.tgz",
-      "integrity": "sha512-B9btcSgPYb1q4oSOb/PrOT6Z/H+r6xuNzfH4lFli/AWhYwdtrgQkQWBbIc6mdnf6E2IL3gDXdkkqNktpU0OZQA==",
-      "dev": true
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.1.tgz",
+      "integrity": "sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==",
+      "dependencies": {
+        "@types/trusted-types": "^2.0.2"
+      }
     },
     "node_modules/lodash": {
       "version": "4.17.21",
@@ -3036,6 +2892,12 @@
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
+    "node_modules/lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
+      "dev": true
+    },
     "node_modules/lodash.clonedeep": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
@@ -3222,14 +3084,16 @@
         "node": ">=8"
       }
     },
-    "node_modules/longest-streak": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
-      "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
-      "dev": true,
+    "node_modules/loglevel": {
+      "version": "1.9.2",
+      "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz",
+      "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==",
+      "engines": {
+        "node": ">= 0.6.0"
+      },
       "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
+        "type": "tidelift",
+        "url": "https://tidelift.com/funding/github/npm/loglevel"
       }
     },
     "node_modules/lru-cache": {
@@ -3245,19 +3109,20 @@
       }
     },
     "node_modules/markdown-it": {
-      "version": "12.3.2",
-      "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
-      "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+      "version": "14.1.0",
+      "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
+      "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
       "dev": true,
       "dependencies": {
         "argparse": "^2.0.1",
-        "entities": "~2.1.0",
-        "linkify-it": "^3.0.1",
-        "mdurl": "^1.0.1",
-        "uc.micro": "^1.0.5"
+        "entities": "^4.4.0",
+        "linkify-it": "^5.0.0",
+        "mdurl": "^2.0.0",
+        "punycode.js": "^2.3.1",
+        "uc.micro": "^2.1.0"
       },
       "bin": {
-        "markdown-it": "bin/markdown-it.js"
+        "markdown-it": "bin/markdown-it.mjs"
       }
     },
     "node_modules/markdown-it-link-attributes": {
@@ -3267,234 +3132,21 @@
       "dev": true
     },
     "node_modules/markdown-it/node_modules/entities": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
-      "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/fb55/entities?sponsor=1"
-      }
-    },
-    "node_modules/markdown-table": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
-      "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==",
-      "dev": true,
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/markdown-to-quill-delta": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/markdown-to-quill-delta/-/markdown-to-quill-delta-0.7.0.tgz",
-      "integrity": "sha512-FLBUAd8vW7vuUR0hu1I8+8+meJQ3B+Jk5NsxFkJ4WE4g6zj8PrvPj+rLV11SZqEQ3J3kaUoBSxgJR7zMcokfgQ==",
-      "dev": true,
-      "dependencies": {
-        "quill-delta": "^4.1.0",
-        "remark-gfm": "^3.0.1",
-        "remark-parse": "^10.0.1",
-        "unified": "^10.1.2",
-        "unist-util-visit": "^4.1.0"
-      }
-    },
-    "node_modules/mdast-util-find-and-replace": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz",
-      "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "escape-string-regexp": "^5.0.0",
-        "unist-util-is": "^5.0.0",
-        "unist-util-visit-parents": "^5.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
-      "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
       "dev": true,
       "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/mdast-util-from-markdown": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz",
-      "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "@types/unist": "^2.0.0",
-        "decode-named-character-reference": "^1.0.0",
-        "mdast-util-to-string": "^3.1.0",
-        "micromark": "^3.0.0",
-        "micromark-util-decode-numeric-character-reference": "^1.0.0",
-        "micromark-util-decode-string": "^1.0.0",
-        "micromark-util-normalize-identifier": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0",
-        "unist-util-stringify-position": "^3.0.0",
-        "uvu": "^0.5.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-gfm": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz",
-      "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==",
-      "dev": true,
-      "dependencies": {
-        "mdast-util-from-markdown": "^1.0.0",
-        "mdast-util-gfm-autolink-literal": "^1.0.0",
-        "mdast-util-gfm-footnote": "^1.0.0",
-        "mdast-util-gfm-strikethrough": "^1.0.0",
-        "mdast-util-gfm-table": "^1.0.0",
-        "mdast-util-gfm-task-list-item": "^1.0.0",
-        "mdast-util-to-markdown": "^1.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-gfm-autolink-literal": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz",
-      "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "ccount": "^2.0.0",
-        "mdast-util-find-and-replace": "^2.0.0",
-        "micromark-util-character": "^1.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-gfm-footnote": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz",
-      "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "mdast-util-to-markdown": "^1.3.0",
-        "micromark-util-normalize-identifier": "^1.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-gfm-strikethrough": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz",
-      "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "mdast-util-to-markdown": "^1.3.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-gfm-table": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz",
-      "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "markdown-table": "^3.0.0",
-        "mdast-util-from-markdown": "^1.0.0",
-        "mdast-util-to-markdown": "^1.3.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-gfm-task-list-item": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz",
-      "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "mdast-util-to-markdown": "^1.3.0"
+        "node": ">=0.12"
       },
       "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-phrasing": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz",
-      "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "unist-util-is": "^5.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-to-markdown": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz",
-      "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "@types/unist": "^2.0.0",
-        "longest-streak": "^3.0.0",
-        "mdast-util-phrasing": "^3.0.0",
-        "mdast-util-to-string": "^3.0.0",
-        "micromark-util-decode-string": "^1.0.0",
-        "unist-util-visit": "^4.0.0",
-        "zwitch": "^2.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/mdast-util-to-string": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
-      "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
+        "url": "https://github.com/fb55/entities?sponsor=1"
       }
     },
-    "node_modules/mdurl": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
-      "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
+    "node_modules/markdown-it/node_modules/mdurl": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+      "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
       "dev": true
     },
     "node_modules/media-typer": {
@@ -3507,10 +3159,13 @@
       }
     },
     "node_modules/merge-descriptors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
-      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
-      "dev": true
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+      "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
     "node_modules/merge-stream": {
       "version": "2.0.0",
@@ -3527,569 +3182,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/micromark": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
-      "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "@types/debug": "^4.0.0",
-        "debug": "^4.0.0",
-        "decode-named-character-reference": "^1.0.0",
-        "micromark-core-commonmark": "^1.0.1",
-        "micromark-factory-space": "^1.0.0",
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-chunked": "^1.0.0",
-        "micromark-util-combine-extensions": "^1.0.0",
-        "micromark-util-decode-numeric-character-reference": "^1.0.0",
-        "micromark-util-encode": "^1.0.0",
-        "micromark-util-normalize-identifier": "^1.0.0",
-        "micromark-util-resolve-all": "^1.0.0",
-        "micromark-util-sanitize-uri": "^1.0.0",
-        "micromark-util-subtokenize": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.1",
-        "uvu": "^0.5.0"
-      }
-    },
-    "node_modules/micromark-core-commonmark": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz",
-      "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "decode-named-character-reference": "^1.0.0",
-        "micromark-factory-destination": "^1.0.0",
-        "micromark-factory-label": "^1.0.0",
-        "micromark-factory-space": "^1.0.0",
-        "micromark-factory-title": "^1.0.0",
-        "micromark-factory-whitespace": "^1.0.0",
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-chunked": "^1.0.0",
-        "micromark-util-classify-character": "^1.0.0",
-        "micromark-util-html-tag-name": "^1.0.0",
-        "micromark-util-normalize-identifier": "^1.0.0",
-        "micromark-util-resolve-all": "^1.0.0",
-        "micromark-util-subtokenize": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.1",
-        "uvu": "^0.5.0"
-      }
-    },
-    "node_modules/micromark-extension-gfm": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz",
-      "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==",
-      "dev": true,
-      "dependencies": {
-        "micromark-extension-gfm-autolink-literal": "^1.0.0",
-        "micromark-extension-gfm-footnote": "^1.0.0",
-        "micromark-extension-gfm-strikethrough": "^1.0.0",
-        "micromark-extension-gfm-table": "^1.0.0",
-        "micromark-extension-gfm-tagfilter": "^1.0.0",
-        "micromark-extension-gfm-task-list-item": "^1.0.0",
-        "micromark-util-combine-extensions": "^1.0.0",
-        "micromark-util-types": "^1.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/micromark-extension-gfm-autolink-literal": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz",
-      "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==",
-      "dev": true,
-      "dependencies": {
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-sanitize-uri": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/micromark-extension-gfm-footnote": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz",
-      "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==",
-      "dev": true,
-      "dependencies": {
-        "micromark-core-commonmark": "^1.0.0",
-        "micromark-factory-space": "^1.0.0",
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-normalize-identifier": "^1.0.0",
-        "micromark-util-sanitize-uri": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0",
-        "uvu": "^0.5.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/micromark-extension-gfm-strikethrough": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz",
-      "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==",
-      "dev": true,
-      "dependencies": {
-        "micromark-util-chunked": "^1.0.0",
-        "micromark-util-classify-character": "^1.0.0",
-        "micromark-util-resolve-all": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0",
-        "uvu": "^0.5.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/micromark-extension-gfm-table": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz",
-      "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==",
-      "dev": true,
-      "dependencies": {
-        "micromark-factory-space": "^1.0.0",
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0",
-        "uvu": "^0.5.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/micromark-extension-gfm-tagfilter": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz",
-      "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==",
-      "dev": true,
-      "dependencies": {
-        "micromark-util-types": "^1.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/micromark-extension-gfm-task-list-item": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz",
-      "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==",
-      "dev": true,
-      "dependencies": {
-        "micromark-factory-space": "^1.0.0",
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0",
-        "uvu": "^0.5.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/micromark-factory-destination": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz",
-      "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-factory-label": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz",
-      "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0",
-        "uvu": "^0.5.0"
-      }
-    },
-    "node_modules/micromark-factory-space": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz",
-      "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-types": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-factory-title": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz",
-      "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-factory-space": "^1.0.0",
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-factory-whitespace": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz",
-      "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-factory-space": "^1.0.0",
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-character": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz",
-      "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-chunked": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz",
-      "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-symbol": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-classify-character": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz",
-      "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-combine-extensions": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz",
-      "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-chunked": "^1.0.0",
-        "micromark-util-types": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-decode-numeric-character-reference": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz",
-      "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-symbol": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-decode-string": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz",
-      "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "decode-named-character-reference": "^1.0.0",
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-decode-numeric-character-reference": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-encode": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz",
-      "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ]
-    },
-    "node_modules/micromark-util-html-tag-name": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz",
-      "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ]
-    },
-    "node_modules/micromark-util-normalize-identifier": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz",
-      "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-symbol": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-resolve-all": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz",
-      "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-types": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-sanitize-uri": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz",
-      "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-character": "^1.0.0",
-        "micromark-util-encode": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0"
-      }
-    },
-    "node_modules/micromark-util-subtokenize": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz",
-      "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ],
-      "dependencies": {
-        "micromark-util-chunked": "^1.0.0",
-        "micromark-util-symbol": "^1.0.0",
-        "micromark-util-types": "^1.0.0",
-        "uvu": "^0.5.0"
-      }
-    },
-    "node_modules/micromark-util-symbol": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz",
-      "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ]
-    },
-    "node_modules/micromark-util-types": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz",
-      "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "GitHub Sponsors",
-          "url": "https://github.com/sponsors/unifiedjs"
-        },
-        {
-          "type": "OpenCollective",
-          "url": "https://opencollective.com/unified"
-        }
-      ]
-    },
     "node_modules/mime": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@@ -4129,19 +3221,7 @@
       "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
       "dev": true,
       "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
+        "node": ">=6"
       }
     },
     "node_modules/minimist": {
@@ -4153,15 +3233,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/mri": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
-      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -4169,9 +3240,9 @@
       "dev": true
     },
     "node_modules/nanoid": {
-      "version": "3.3.7",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
-      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+      "version": "3.3.8",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+      "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
       "dev": true,
       "funding": [
         {
@@ -4254,23 +3325,10 @@
       }
     },
     "node_modules/object-inspect": {
-      "version": "1.12.3",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
-      "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/object-is": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
-      "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
+      "version": "1.13.3",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
+      "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
       "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3"
-      },
       "engines": {
         "node": ">= 0.4"
       },
@@ -4278,15 +3336,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/object-keys": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/on-finished": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -4344,12 +3393,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/parchment": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
-      "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==",
-      "dev": true
-    },
     "node_modules/parseurl": {
       "version": "1.3.3",
       "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -4359,15 +3402,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/path-key": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -4378,9 +3412,9 @@
       }
     },
     "node_modules/path-to-regexp": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
-      "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
+      "version": "0.1.10",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
+      "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==",
       "dev": true
     },
     "node_modules/pend": {
@@ -4396,9 +3430,9 @@
       "dev": true
     },
     "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
       "dev": true
     },
     "node_modules/pify": {
@@ -4417,9 +3451,9 @@
       "dev": true
     },
     "node_modules/postcss": {
-      "version": "8.4.32",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
-      "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
+      "version": "8.4.49",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+      "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
       "dev": true,
       "funding": [
         {
@@ -4437,8 +3471,8 @@
       ],
       "dependencies": {
         "nanoid": "^3.3.7",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
       },
       "engines": {
         "node": "^10 || ^12 || >=14"
@@ -4484,12 +3518,6 @@
       "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==",
       "dev": true
     },
-    "node_modules/psl": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
-      "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
-      "dev": true
-    },
     "node_modules/pubsub-js": {
       "version": "1.9.4",
       "resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.9.4.tgz",
@@ -4506,22 +3534,22 @@
         "once": "^1.3.1"
       }
     },
-    "node_modules/punycode": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
-      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+    "node_modules/punycode.js": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+      "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
       "dev": true,
       "engines": {
         "node": ">=6"
       }
     },
     "node_modules/qs": {
-      "version": "6.11.0",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
-      "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+      "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
       "dev": true,
       "dependencies": {
-        "side-channel": "^1.0.4"
+        "side-channel": "^1.0.6"
       },
       "engines": {
         "node": ">=0.6"
@@ -4530,35 +3558,19 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/querystringify": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
-      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
-      "dev": true
-    },
     "node_modules/quill": {
-      "version": "1.3.7",
-      "resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
-      "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
-      "dev": true,
-      "dependencies": {
-        "clone": "^2.1.1",
-        "deep-equal": "^1.0.1",
-        "eventemitter3": "^2.0.3",
-        "extend": "^3.0.2",
-        "parchment": "^1.1.4",
-        "quill-delta": "^3.6.2"
-      }
-    },
-    "node_modules/quill-delta": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-4.2.2.tgz",
-      "integrity": "sha512-qjbn82b/yJzOjstBgkhtBjN2TNK+ZHP/BgUQO+j6bRhWQQdmj2lH6hXG7+nwwLF41Xgn//7/83lxs9n2BkTtTg==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz",
+      "integrity": "sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==",
       "dev": true,
       "dependencies": {
-        "fast-diff": "1.2.0",
-        "lodash.clonedeep": "^4.5.0",
-        "lodash.isequal": "^4.5.0"
+        "eventemitter3": "^5.0.1",
+        "lodash-es": "^4.17.21",
+        "parchment": "^3.0.0",
+        "quill-delta": "^5.1.0"
+      },
+      "engines": {
+        "npm": ">=8.2.3"
       }
     },
     "node_modules/quill-delta-to-markdown": {
@@ -4574,23 +3586,29 @@
       }
     },
     "node_modules/quill/node_modules/fast-diff": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
-      "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+      "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+      "dev": true
+    },
+    "node_modules/quill/node_modules/parchment": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz",
+      "integrity": "sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==",
       "dev": true
     },
     "node_modules/quill/node_modules/quill-delta": {
-      "version": "3.6.3",
-      "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
-      "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz",
+      "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
       "dev": true,
       "dependencies": {
-        "deep-equal": "^1.0.1",
-        "extend": "^3.0.2",
-        "fast-diff": "1.1.2"
+        "fast-diff": "^1.3.0",
+        "lodash.clonedeep": "^4.5.0",
+        "lodash.isequal": "^4.5.0"
       },
       "engines": {
-        "node": ">=0.10"
+        "node": ">= 12.0.0"
       }
     },
     "node_modules/range-parser": {
@@ -4602,33 +3620,31 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/rdf-canonize": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-3.4.0.tgz",
-      "integrity": "sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==",
+    "node_modules/raw-body": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+      "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
       "dev": true,
       "dependencies": {
-        "setimmediate": "^1.0.5"
+        "bytes": "3.1.2",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
       },
       "engines": {
-        "node": ">=12"
+        "node": ">= 0.8"
       }
     },
-    "node_modules/regexp.prototype.flags": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
-      "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
+    "node_modules/rdf-canonize": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-3.4.0.tgz",
+      "integrity": "sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.2.0",
-        "functions-have-names": "^1.2.3"
+        "setimmediate": "^1.0.5"
       },
       "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+        "node": ">=12"
       }
     },
     "node_modules/relative-to-absolute-iri": {
@@ -4637,37 +3653,6 @@
       "integrity": "sha512-Xjyl4HmIzg2jzK/Un2gELqbcE8Fxy85A/aLSHE6PE/3+OGsFwmKVA1vRyGaz6vLWSqLDMHA+5rjD/xbibSQN1Q==",
       "dev": true
     },
-    "node_modules/remark-gfm": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz",
-      "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "mdast-util-gfm": "^2.0.0",
-        "micromark-extension-gfm": "^2.0.0",
-        "unified": "^10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/remark-parse": {
-      "version": "10.0.2",
-      "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz",
-      "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==",
-      "dev": true,
-      "dependencies": {
-        "@types/mdast": "^3.0.0",
-        "mdast-util-from-markdown": "^1.0.0",
-        "unified": "^10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
     "node_modules/request-progress": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz",
@@ -4677,12 +3662,6 @@
         "throttleit": "^1.0.0"
       }
     },
-    "node_modules/requires-port": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
-      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
-      "dev": true
-    },
     "node_modules/restore-cursor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
@@ -4702,28 +3681,13 @@
       "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
       "dev": true
     },
-    "node_modules/rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
     "node_modules/rollup": {
-      "version": "4.9.6",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz",
-      "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==",
+      "version": "4.27.4",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.4.tgz",
+      "integrity": "sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==",
       "dev": true,
       "dependencies": {
-        "@types/estree": "1.0.5"
+        "@types/estree": "1.0.6"
       },
       "bin": {
         "rollup": "dist/bin/rollup"
@@ -4733,19 +3697,24 @@
         "npm": ">=8.0.0"
       },
       "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.9.6",
-        "@rollup/rollup-android-arm64": "4.9.6",
-        "@rollup/rollup-darwin-arm64": "4.9.6",
-        "@rollup/rollup-darwin-x64": "4.9.6",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.9.6",
-        "@rollup/rollup-linux-arm64-gnu": "4.9.6",
-        "@rollup/rollup-linux-arm64-musl": "4.9.6",
-        "@rollup/rollup-linux-riscv64-gnu": "4.9.6",
-        "@rollup/rollup-linux-x64-gnu": "4.9.6",
-        "@rollup/rollup-linux-x64-musl": "4.9.6",
-        "@rollup/rollup-win32-arm64-msvc": "4.9.6",
-        "@rollup/rollup-win32-ia32-msvc": "4.9.6",
-        "@rollup/rollup-win32-x64-msvc": "4.9.6",
+        "@rollup/rollup-android-arm-eabi": "4.27.4",
+        "@rollup/rollup-android-arm64": "4.27.4",
+        "@rollup/rollup-darwin-arm64": "4.27.4",
+        "@rollup/rollup-darwin-x64": "4.27.4",
+        "@rollup/rollup-freebsd-arm64": "4.27.4",
+        "@rollup/rollup-freebsd-x64": "4.27.4",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.27.4",
+        "@rollup/rollup-linux-arm-musleabihf": "4.27.4",
+        "@rollup/rollup-linux-arm64-gnu": "4.27.4",
+        "@rollup/rollup-linux-arm64-musl": "4.27.4",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.27.4",
+        "@rollup/rollup-linux-riscv64-gnu": "4.27.4",
+        "@rollup/rollup-linux-s390x-gnu": "4.27.4",
+        "@rollup/rollup-linux-x64-gnu": "4.27.4",
+        "@rollup/rollup-linux-x64-musl": "4.27.4",
+        "@rollup/rollup-win32-arm64-msvc": "4.27.4",
+        "@rollup/rollup-win32-ia32-msvc": "4.27.4",
+        "@rollup/rollup-win32-x64-msvc": "4.27.4",
         "fsevents": "~2.3.2"
       }
     },
@@ -4758,18 +3727,6 @@
         "tslib": "^2.1.0"
       }
     },
-    "node_modules/sade": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
-      "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
-      "dev": true,
-      "dependencies": {
-        "mri": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -4797,13 +3754,10 @@
       "dev": true
     },
     "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": "7.6.3",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
       "dev": true,
-      "dependencies": {
-        "lru-cache": "^6.0.0"
-      },
       "bin": {
         "semver": "bin/semver.js"
       },
@@ -4812,9 +3766,9 @@
       }
     },
     "node_modules/send": {
-      "version": "0.18.0",
-      "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
-      "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+      "version": "0.19.0",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+      "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
       "dev": true,
       "dependencies": {
         "debug": "2.6.9",
@@ -4850,6 +3804,15 @@
       "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
       "dev": true
     },
+    "node_modules/send/node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/send/node_modules/ms": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -4857,31 +3820,32 @@
       "dev": true
     },
     "node_modules/serve-static": {
-      "version": "1.15.0",
-      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
-      "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+      "version": "1.16.2",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+      "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
       "dev": true,
       "dependencies": {
-        "encodeurl": "~1.0.2",
+        "encodeurl": "~2.0.0",
         "escape-html": "~1.0.3",
         "parseurl": "~1.3.3",
-        "send": "0.18.0"
+        "send": "0.19.0"
       },
       "engines": {
         "node": ">= 0.8.0"
       }
     },
     "node_modules/set-function-length": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz",
-      "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==",
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+      "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
       "dev": true,
       "dependencies": {
-        "define-data-property": "^1.1.1",
+        "define-data-property": "^1.1.4",
+        "es-errors": "^1.3.0",
         "function-bind": "^1.1.2",
-        "get-intrinsic": "^1.2.2",
+        "get-intrinsic": "^1.2.4",
         "gopd": "^1.0.1",
-        "has-property-descriptors": "^1.0.1"
+        "has-property-descriptors": "^1.0.2"
       },
       "engines": {
         "node": ">= 0.4"
@@ -4921,14 +3885,18 @@
       }
     },
     "node_modules/side-channel": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
-      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+      "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.0",
-        "get-intrinsic": "^1.0.2",
-        "object-inspect": "^1.9.0"
+        "call-bind": "^1.0.7",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.4",
+        "object-inspect": "^1.13.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -4988,13 +3956,10 @@
       "dev": true
     },
     "node_modules/slim-select": {
-      "version": "1.27.1",
-      "resolved": "https://registry.npmjs.org/slim-select/-/slim-select-1.27.1.tgz",
-      "integrity": "sha512-LvJ02cKKk6/jSHIcQv7dZwkQSXHLCVQR3v3lo8RJUssUUcmKPkpBmTpQ8au8KSMkxwca9+yeg+dO0iHAaVr5Aw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/slim-select/-/slim-select-2.10.0.tgz",
+      "integrity": "sha512-sOKXH8YlgspTn+wy1jYbscVlFbBsAIOmtrmx1e16sV+NbYDTIyJCCdLH0EL9gDxDdHzBgE/s5XZ+VChaxz0JGg==",
+      "dev": true
     },
     "node_modules/source-map": {
       "version": "0.6.1",
@@ -5008,9 +3973,9 @@
       }
     },
     "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -5076,12 +4041,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/string.prototype.repeat": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz",
-      "integrity": "sha512-1BH+X+1hSthZFW+X+JaUkjkkUPwIlLEMJBLANN3hOob3RhEk5snLWNECDnYbgn/m5c5JV7Ersu1Yubaf+05cIA==",
-      "dev": true
-    },
     "node_modules/strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -5143,16 +4102,31 @@
       "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
       "dev": true
     },
-    "node_modules/tmp": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
-      "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+    "node_modules/tldts": {
+      "version": "6.1.64",
+      "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.64.tgz",
+      "integrity": "sha512-ph4AE5BXWIOsSy9stpoeo7bYe/Cy7VfpciIH4RhVZUPItCJmhqWCN0EVzxd8BOHiyNb42vuJc6NWTjJkg91Tuw==",
       "dev": true,
       "dependencies": {
-        "rimraf": "^3.0.0"
+        "tldts-core": "^6.1.64"
       },
+      "bin": {
+        "tldts": "bin/cli.js"
+      }
+    },
+    "node_modules/tldts-core": {
+      "version": "6.1.64",
+      "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.64.tgz",
+      "integrity": "sha512-uqnl8vGV16KsyflHOzqrYjjArjfXaU6rMPXYy2/ZWoRKCkXtghgB4VwTDXUG+t0OTGeSewNAG31/x1gCTfLt+Q==",
+      "dev": true
+    },
+    "node_modules/tmp": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
+      "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==",
+      "dev": true,
       "engines": {
-        "node": ">=8.17.0"
+        "node": ">=14.14"
       }
     },
     "node_modules/toidentifier": {
@@ -5165,37 +4139,24 @@
       }
     },
     "node_modules/tough-cookie": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
-      "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz",
+      "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==",
       "dev": true,
       "dependencies": {
-        "psl": "^1.1.33",
-        "punycode": "^2.1.1",
-        "universalify": "^0.2.0",
-        "url-parse": "^1.5.3"
+        "tldts": "^6.1.32"
       },
       "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/tough-cookie/node_modules/universalify": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
-      "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4.0.0"
+        "node": ">=16"
       }
     },
-    "node_modules/trough": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
-      "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
+    "node_modules/tree-kill": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+      "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
       "dev": true,
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
+      "bin": {
+        "tree-kill": "cli.js"
       }
     },
     "node_modules/tslib": {
@@ -5204,39 +4165,6 @@
       "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==",
       "dev": true
     },
-    "node_modules/tui-calendar": {
-      "version": "1.15.3",
-      "resolved": "https://registry.npmjs.org/tui-calendar/-/tui-calendar-1.15.3.tgz",
-      "integrity": "sha512-S+QxtSPunLUNIX/eHoHcBB9XlPVT15Wh6ItR62n5K/Gq3WeSQdyhdbsuZJYV9z75bgJbFzp6x32v2yEPm6iWrg==",
-      "dev": true,
-      "dependencies": {
-        "dompurify": "^2.3.1",
-        "tui-code-snippet": "^1.5.0",
-        "tui-date-picker": "^4.3.0",
-        "tui-time-picker": "^2.1.4"
-      }
-    },
-    "node_modules/tui-code-snippet": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/tui-code-snippet/-/tui-code-snippet-1.5.2.tgz",
-      "integrity": "sha512-6UqTlQaaC1KLcmC0HAoq5dtl1G4Fib+R+NC7pmaV7kiIlZ7JqKhUmnOoGRcreAyzd81UTK/vCvhrw9QJskpCFQ==",
-      "dev": true
-    },
-    "node_modules/tui-date-picker": {
-      "version": "4.3.3",
-      "resolved": "https://registry.npmjs.org/tui-date-picker/-/tui-date-picker-4.3.3.tgz",
-      "integrity": "sha512-/2YoLnj5c1e+Ag1ZZYOgzEs2o0v7Ol7c5UAnBj438zGlkwkMxyH0HwP2pVqqIYX05WE7K0+6nTWVMybS8otBgw==",
-      "dev": true,
-      "dependencies": {
-        "tui-time-picker": "^2.1.6"
-      }
-    },
-    "node_modules/tui-time-picker": {
-      "version": "2.1.6",
-      "resolved": "https://registry.npmjs.org/tui-time-picker/-/tui-time-picker-2.1.6.tgz",
-      "integrity": "sha512-4Jmo3wjGS+Ii4/qQgt5DaFEohHpB3U6BzWeTODVVFHD9sx3NOsbomY9K0xMobSLODi+tQEH7wfOtNU0IJmcQ6Q==",
-      "dev": true
-    },
     "node_modules/tunnel-agent": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -5281,22 +4209,22 @@
       }
     },
     "node_modules/typescript": {
-      "version": "4.9.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
-      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+      "version": "5.7.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
+      "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
       },
       "engines": {
-        "node": ">=4.2.0"
+        "node": ">=14.17"
       }
     },
     "node_modules/uc.micro": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
-      "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+      "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
       "dev": true
     },
     "node_modules/undici": {
@@ -5312,9 +4240,9 @@
       }
     },
     "node_modules/undici-types": {
-      "version": "5.26.5",
-      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
-      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+      "version": "6.20.0",
+      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+      "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
       "dev": true
     },
     "node_modules/unfetch": {
@@ -5323,80 +4251,6 @@
       "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==",
       "dev": true
     },
-    "node_modules/unified": {
-      "version": "10.1.2",
-      "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz",
-      "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==",
-      "dev": true,
-      "dependencies": {
-        "@types/unist": "^2.0.0",
-        "bail": "^2.0.0",
-        "extend": "^3.0.0",
-        "is-buffer": "^2.0.0",
-        "is-plain-obj": "^4.0.0",
-        "trough": "^2.0.0",
-        "vfile": "^5.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/unist-util-is": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
-      "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
-      "dev": true,
-      "dependencies": {
-        "@types/unist": "^2.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/unist-util-stringify-position": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz",
-      "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==",
-      "dev": true,
-      "dependencies": {
-        "@types/unist": "^2.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/unist-util-visit": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz",
-      "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==",
-      "dev": true,
-      "dependencies": {
-        "@types/unist": "^2.0.0",
-        "unist-util-is": "^5.0.0",
-        "unist-util-visit-parents": "^5.1.1"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/unist-util-visit-parents": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz",
-      "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==",
-      "dev": true,
-      "dependencies": {
-        "@types/unist": "^2.0.0",
-        "unist-util-is": "^5.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
     "node_modules/universalify": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
@@ -5424,16 +4278,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/url-parse": {
-      "version": "1.5.10",
-      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
-      "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
-      "dev": true,
-      "dependencies": {
-        "querystringify": "^2.1.1",
-        "requires-port": "^1.0.0"
-      }
-    },
     "node_modules/utils-merge": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -5452,24 +4296,6 @@
         "uuid": "dist/bin/uuid"
       }
     },
-    "node_modules/uvu": {
-      "version": "0.5.6",
-      "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
-      "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
-      "dev": true,
-      "dependencies": {
-        "dequal": "^2.0.0",
-        "diff": "^5.0.0",
-        "kleur": "^4.0.3",
-        "sade": "^1.7.3"
-      },
-      "bin": {
-        "uvu": "bin.js"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/vary": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -5492,51 +4318,15 @@
         "extsprintf": "^1.2.0"
       }
     },
-    "node_modules/verror/node_modules/core-util-is": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
-      "dev": true
-    },
-    "node_modules/vfile": {
-      "version": "5.3.7",
-      "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz",
-      "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==",
-      "dev": true,
-      "dependencies": {
-        "@types/unist": "^2.0.0",
-        "is-buffer": "^2.0.0",
-        "unist-util-stringify-position": "^3.0.0",
-        "vfile-message": "^3.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
-    "node_modules/vfile-message": {
-      "version": "3.1.4",
-      "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz",
-      "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==",
-      "dev": true,
-      "dependencies": {
-        "@types/unist": "^2.0.0",
-        "unist-util-stringify-position": "^3.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/unified"
-      }
-    },
     "node_modules/vite": {
-      "version": "5.0.12",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz",
-      "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==",
+      "version": "5.4.11",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz",
+      "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==",
       "dev": true,
       "dependencies": {
-        "esbuild": "^0.19.3",
-        "postcss": "^8.4.32",
-        "rollup": "^4.2.0"
+        "esbuild": "^0.21.3",
+        "postcss": "^8.4.43",
+        "rollup": "^4.20.0"
       },
       "bin": {
         "vite": "bin/vite.js"
@@ -5555,6 +4345,7 @@
         "less": "*",
         "lightningcss": "^1.21.0",
         "sass": "*",
+        "sass-embedded": "*",
         "stylus": "*",
         "sugarss": "*",
         "terser": "^5.4.0"
@@ -5572,6 +4363,9 @@
         "sass": {
           "optional": true
         },
+        "sass-embedded": {
+          "optional": true
+        },
         "stylus": {
           "optional": true
         },
@@ -5684,16 +4478,6 @@
         "buffer-crc32": "~0.2.3",
         "fd-slicer": "~1.1.0"
       }
-    },
-    "node_modules/zwitch": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
-      "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
-      "dev": true,
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
     }
   }
 }
diff --git a/package.json b/package.json
index 22e33da36d43c814e04fe0be4372475fa03b92dd..c50bd5459c6298d5413f8441d05b97ca2d7ff29e 100644
--- a/package.json
+++ b/package.json
@@ -8,14 +8,14 @@
   "directories": {
     "example": "examples"
   },
-  "files": [
-    "dist",
-    "doc"
-  ],
+  "files": ["dist", "doc"],
   "scripts": {
     "build": "vite build",
-    "watch": "vite build --watch",
+    "watch": "vite build --watch --sourcemap 'inline'",
     "serve": "node --watch server.js",
+    "lint": "biome check --diagnostic-level=error",
+    "lint-all": "biome check",
+    "lint-fix": "biome check --write",
     "check-types": "tsc",
     "test": "node server.js --test",
     "cypress": "node server.js --test-ui",
@@ -65,40 +65,36 @@
     "access": "public"
   },
   "devDependencies": {
+    "@biomejs/biome": "1.9.4",
     "@rckeller/cypress-unfetch": "^1.0.1",
     "@types/autolinker": "^2.0.0",
-    "@types/leaflet": "^1.5.21",
-    "@types/leaflet.markercluster": "^1.4.3",
-    "@types/markdown-it": "^12.0.1",
-    "@types/node": "^20.5.0",
-    "@types/pubsub-js": "^1.8.2",
-    "@types/quill": "^2.0.4",
-    "autolinker": "^3.14.2",
-    "cypress": "^13.2.0",
+    "@types/jsonld": "^1.5.15",
+    "@types/markdown-it": "^14.1.2",
+    "@types/markdown-it-link-attributes": "^3.0.5",
+    "@types/node": "^22.7.1",
+    "@types/pubsub-js": "^1.8.6",
+    "autolinker": "^4.0.0",
+    "cypress": "^13.14.2",
     "cypress-plugin-tab": "^1.0.5",
-    "delta-markdown-for-quill": "0.0.9",
     "dialog-polyfill": "^0.5.6",
-    "express": "^4.17.1",
+    "express": "^4.21.0",
     "find-free-port": "^2.0.0",
-    "fuse.js": "^6.4.6",
-    "jsonld": "^8.3.1",
+    "fuse.js": "^7.0.0",
+    "jsonld": "^8.3.2",
     "jsonld-context-parser": "^1.3.4",
-    "leaflet": "1.7.1",
-    "leaflet.markercluster": "1.5.3",
-    "lit-html": "^1.3.0",
-    "markdown-it": "^12.0.4",
+    "markdown-it": "^14.1.0",
     "markdown-it-link-attributes": "4.0.1",
-    "markdown-to-quill-delta": "^0.7.0",
-    "pubsub-js": "^1.9.2",
-    "quill": "^1.3.7",
+    "pubsub-js": "^1.9.4",
+    "quill": "^2.0.3",
     "quill-delta-to-markdown": "^0.6.0",
-    "semver": "7.5.4",
-    "slim-select": "^1.27.0",
-    "tui-calendar": "^1.13.0",
-    "typescript": "^4.9.5",
-    "vite": "^5.0.12"
+    "semver": "7.6.3",
+    "slim-select": "^2.9.2",
+    "typescript": "^5.6.2",
+    "vite": "^5.4.8"
   },
   "dependencies": {
-    "cors": "^2.8.5"
+    "cors": "^2.8.5",
+    "lit": "^3.2.1",
+    "loglevel": "^1.9.1"
   }
 }
diff --git a/server.js b/server.js
index 3f08c387985beaf982fc5479a3d839703647f386..ce97cb81a922cca40e9eb6fc334776dbf5377d35 100644
--- a/server.js
+++ b/server.js
@@ -1,22 +1,25 @@
-import crypto from 'crypto';
+// @ts-check
+
+import crypto from 'node:crypto';
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import url from 'node:url';
+import cors from 'cors';
 import cypress from 'cypress';
-import url from 'url';
-import path from 'path';
 import express from 'express';
 import findFreePort from 'find-free-port';
-import fs from 'fs/promises';
-import cors from 'cors';
 const port = findFreePort(3000);
 const app = express();
 const distPath = '.';
-
 app.use(cors());
+// Set the browser language to English to ensure consistent test conditions.
+process.env.ELECTRON_EXTRA_LAUNCH_ARGS = '--lang=en';
 (async () => {
   const updateURLs = /.*jsonld/;
   const server = app
     .use(express.static(distPath))
     .use(express.json({ type: 'application/*+json' }))
-    .get('/favicon.ico', (req, rep) => rep.send())
+    .get('/favicon.ico', (_req, rep) => void rep.send())
     // Handle upload
     .post('/upload', (req, rep) => {
       const originalUrl = url.format({
@@ -27,28 +30,28 @@ app.use(cors());
       rep.setHeader('location', `${originalUrl}/${uniqID()}.jpg`);
       setTimeout(() => rep.send(), 1200);
     })
-    .get(/^\/upload\/.+/, (req, rep) => {
+    .get(/^\/upload\/.+/, (_req, rep) => {
       rep.sendFile(path.resolve('./fake-image.svg'));
     })
     .get('/mock/users.jsonld', async (req, res) => {
       const limit = Number(req.query.limit);
       const offset = Number(req.query.offset);
-      const val = req.query['search-terms'] || '';
+      const val = String(req.query['search-terms'] || '');
 
       const jsonData = await fs.readFile(
         './examples/data/list/users-mocked.jsonld',
-        { encoding: 'utf8' }
+        { encoding: 'utf8' },
       );
       const data = JSON.parse(jsonData);
-      const list = data['ldp:contains'].filter((user) =>
-        user['first_name'].toLowerCase().includes(val.toLowerCase())
+      const list = data['ldp:contains'].filter(user =>
+        user.first_name.toLowerCase().includes(val.toLowerCase()),
       );
       data['ldp:contains'] = limit ? list.slice(offset, offset + limit) : list;
 
       res.send(data);
       res.end();
     })
-    .get('/examples/', (req, rep) => rep.redirect('/'))
+    .get('/examples/', (_req, rep) => rep.redirect('/'))
     // Listen for write requests
     .patch(updateURLs, handleUpdate)
     .post(updateURLs, handleUpdate)
@@ -64,13 +67,17 @@ app.use(cors());
       console.log(addr);
       return;
     }
+    /** @type {Partial<CypressCommandLine.CypressOpenOptions>}) */
+    const opt = {
+      testingType: 'e2e',
+      browser: 'electron',
+      config: {
+        e2e: { baseUrl: addr },
+      },
+    };
+    /** @type {void | undefined | CypressCommandLine.CypressRunResult | CypressCommandLine.CypressFailedRunResult} */
     let test;
     try {
-      const opt = {
-        config: {
-          baseUrl: addr,
-        },
-      };
       test = process.argv.includes('--test-ui')
         ? await cypress.open(opt)
         : await cypress.run(opt);
@@ -78,7 +85,7 @@ app.use(cors());
       console.error(error);
     } finally {
       server.close();
-      if (test.totalFailed) {
+      if (test && 'totalFailed' in test && test.totalFailed > 0) {
         process.exit(1);
       }
     }
@@ -95,7 +102,7 @@ function uniqID() {
 }
 
 function handleUpdate(req, rep) {
-  if (req.headers['content-type'] != 'application/ld+json') {
+  if (req.headers['content-type'] !== 'application/ld+json') {
     rep.status(500).send('Content not JSON');
     return;
   }
diff --git a/src/components/solid-ac-checker.ts b/src/components/solid-ac-checker.ts
index 4f5d1034debd7f867e800acc6d51ef5827ae3830..745c9e28f0aaed8bd61dfeda5ba70c7ebefb196f 100644
--- a/src/components/solid-ac-checker.ts
+++ b/src/components/solid-ac-checker.ts
@@ -1,6 +1,7 @@
 import JSONLDContextParser from 'jsonld-context-parser';
-import { Sib } from '../libs/Sib';
-import { StoreMixin } from '../mixins/storeMixin';
+import { Sib } from '../libs/Sib.ts';
+import { trackRenderAsync } from '../logger.ts';
+import { StoreMixin } from '../mixins/storeMixin.ts';
 
 export const SolidAcChecker = {
   name: 'solid-ac-checker',
@@ -13,32 +14,40 @@ export const SolidAcChecker = {
     noPermission: {
       type: String,
       default: '',
-    }
+    },
   },
-
-  async populate(): Promise<void> {
+  populate: trackRenderAsync(async function (): Promise<void> {
     if (!this.resource) return;
     let displayElement: boolean;
     const ContextParser = JSONLDContextParser.ContextParser;
     const permissions = await this.resource.permissions;
-    if (this.permission) { // User has permission of ...
-      displayElement = permissions.some((p:any) => {
-        return ContextParser.expandTerm(p, this.context, true) === this.permission;
+    if (this.permission) {
+      // User has permission of ...
+      displayElement = permissions.some((p: any) => {
+        return (
+          ContextParser.expandTerm(p, this.context, true) === this.permission
+        );
       });
-    } else if (this.noPermission) { // User has no permission of ...
-      displayElement = permissions.every((p:any) => {
-        return ContextParser.expandTerm(p, this.context, true) !== this.noPermission;
+    } else if (this.noPermission) {
+      // User has no permission of ...
+      displayElement = permissions.every((p: any) => {
+        return (
+          ContextParser.expandTerm(p, this.context, true) !== this.noPermission
+        );
       });
-    } else { // No parameter provided
-      console.warn('solid-ac-checker: you should define at least one of "permission" or "no-permission" attribute.');
+    } else {
+      // No parameter provided
+      console.warn(
+        'solid-ac-checker: you should define at least one of "permission" or "no-permission" attribute.',
+      );
       return;
     }
 
     if (displayElement) this.element.removeAttribute('hidden');
-  },
+  }, 'SolidAcChecker:populate'),
   empty(): void {
     this.element.setAttribute('hidden', '');
-  }
+  },
 };
 
-Sib.register(SolidAcChecker);
\ No newline at end of file
+Sib.register(SolidAcChecker);
diff --git a/src/components/solid-calendar.ts b/src/components/solid-calendar.ts
deleted file mode 100644
index ea14e232bf4afe78941e5e6172af9896014813b1..0000000000000000000000000000000000000000
--- a/src/components/solid-calendar.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { Sib } from '../libs/Sib';
-import { ListMixin } from '../mixins/listMixin';
-import { StoreMixin } from '../mixins/storeMixin';
-import { NextMixin } from '../mixins/nextMixin';
-import { store } from '../libs/store/store';
-import { importInlineCSS, uniqID } from '../libs/helpers';
-
-import Calendar from 'tui-calendar';
-import { html, render } from 'lit-html';
-
-export const SolidCalendar = {
-  name: 'solid-calendar',
-  use: [
-    ListMixin,
-    StoreMixin,
-    NextMixin
-  ],
-  initialState: {
-    subscriptions: null
-  },
-  created(): void {
-    importInlineCSS('tui-calendar', () => import('tui-calendar/dist/tui-calendar.css?inline'))
-
-    const id = uniqID();
-    const template = html`
-      <div id=${id} style="width:100%;height:100%;"></div>
-    `;
-    render(template, this.element);
-    this.calendar = new Calendar(this.element.querySelector(`#${id}`), { defaultView: 'month' });
-    this.calendar.on('clickSchedule', this.dispatchSelect.bind(this));
-    this.subscriptions = new Map();
-  },
-  get extra_context(): object {
-    return { date: "http://www.w3.org/2001/XMLSchema#dateTime" }
-  },
-  dispatchSelect(event: Event): void {
-    const resource = { '@id': event['schedule'].id };
-    this.element.dispatchEvent(
-      new CustomEvent('resourceSelect', { detail: { resource: resource } }),
-    );
-    this.goToNext(resource);
-  },
-  async appendChildElt(resourceId: string) {
-    const resource = await store.getData(resourceId, this.context);
-    if(!resource) return;
-    if (!this.subscriptions.get(resourceId)) {
-      this.subscriptions.set(resourceId, PubSub.subscribe(resourceId, () => this.updateDOM()))
-    } // TODO : mixin gestion des enfants
-    const date = await resource['date'];
-    const name = await resource['name'];
-
-    if (name && date) {
-      this.calendar.createSchedules([
-        {
-          id: resource['@id'],
-          title: name.toString(),
-          category: 'time',
-          start: date.toString(),
-        },
-      ]);
-    }
-  },
-  empty(): void {
-    this.calendar.clear();
-  }
-};
-
-Sib.register(SolidCalendar);
\ No newline at end of file
diff --git a/src/components/solid-delete.ts b/src/components/solid-delete.ts
index b6797de2daeec17ca2fe5210931e6e4864b7e16d..796614951852448dba65d885f57143320de99a41 100644
--- a/src/components/solid-delete.ts
+++ b/src/components/solid-delete.ts
@@ -1,11 +1,12 @@
-import { Sib } from '../libs/Sib';
-import { store } from '../libs/store/store';
-import { NextMixin } from '../mixins/nextMixin';
-import { ValidationMixin } from '../mixins/validationMixin';
-import { AttributeBinderMixin } from '../mixins/attributeBinderMixin';
+import { Sib } from '../libs/Sib.ts';
+import { store } from '../libs/store/store.ts';
+import { AttributeBinderMixin } from '../mixins/attributeBinderMixin.ts';
+import { NextMixin } from '../mixins/nextMixin.ts';
+import { ValidationMixin } from '../mixins/validationMixin.ts';
 
-import { html, render } from 'lit-html';
-import { ContextMixin } from '../mixins/contextMixin';
+import { html, render } from 'lit';
+import { trackRenderAsync } from '../logger.ts';
+import { ContextMixin } from '../mixins/contextMixin.ts';
 
 export const SolidDelete = {
   name: 'solid-delete',
@@ -15,7 +16,7 @@ export const SolidDelete = {
       type: String,
       default: null,
       callback: function () {
-       this.resourceId = this.dataSrc;
+        this.resourceId = this.dataSrc;
       },
     },
     dataLabel: {
@@ -24,7 +25,7 @@ export const SolidDelete = {
       callback: function (newValue: string, oldValue: string) {
         if (newValue !== oldValue) this.planRender();
       },
-    }
+    },
   },
   initialState: {
     renderPlanned: false,
@@ -41,7 +42,7 @@ export const SolidDelete = {
       });
     }
   },
-  async delete(e: Event): Promise<void> {
+  delete(e: Event) {
     e.stopPropagation();
     if (!this.dataSrc) return;
     this.performAction(); // In validationMixin, method defining what to do according to the present attributes
@@ -50,25 +51,26 @@ export const SolidDelete = {
     return store.delete(this.dataSrc, this.context).then(response => {
       if (!response.ok) return;
       this.goToNext(null);
-      const eventData = { detail: { resource: { "@id": this.dataSrc } }, bubbles: true };
+      const eventData = {
+        detail: { resource: { '@id': this.dataSrc } },
+        bubbles: true,
+      };
       this.element.dispatchEvent(new CustomEvent('save', eventData));
       this.element.dispatchEvent(new CustomEvent('resourceDeleted', eventData)); // Deprecated. To remove in 0.15
-    })
+    });
   },
-  validateModal() { // Send method to validationMixin, used by the dialog modal and performAction method
+  validateModal() {
+    // Send method to validationMixin, used by the dialog modal and performAction method
     return this.deletion();
   },
   update() {
     this.render();
   },
-  async render(): Promise<void> {
+  render: trackRenderAsync(async function (): Promise<void> {
     await this.replaceAttributesData(false);
-    const button = html`
-      <button @click=${this.delete.bind(this)}>${this.dataLabel || this.t("solid-delete.button")}</button>
-      ${this.getModalDialog()}
-    `;
+    const button = html`<button @click=${this.delete.bind(this)}>${this.dataLabel || this.t('solid-delete.button')}</button>${this.getModalDialog()}`;
     render(button, this.element);
-  }
+  }, 'SolidDelete:render'),
 };
 
-Sib.register(SolidDelete);
\ No newline at end of file
+Sib.register(SolidDelete);
diff --git a/src/components/solid-display.ts b/src/components/solid-display.ts
index df4f833f2807e874b913453a615a523e149c2aae..98e49babbbb5b2eb251219c1ff0a8dd4a09b386b 100644
--- a/src/components/solid-display.ts
+++ b/src/components/solid-display.ts
@@ -1,20 +1,22 @@
-import { Sib } from '../libs/Sib';
-import { WidgetMixin } from '../mixins/widgetMixin';
-import { ListMixin } from '../mixins/listMixin';
-import { StoreMixin } from '../mixins/storeMixin';
-import { PaginateMixin } from '../mixins/paginateMixin';
-import { FilterMixin } from '../mixins/filterMixin';
-import { CounterMixin } from '../mixins/counterMixin';
-import { SorterMixin } from '../mixins/sorterMixin';
-import { GrouperMixin } from '../mixins/grouperMixin';
-import { FederationMixin } from '../mixins/federationMixin';
-import { HighlighterMixin } from '../mixins/highlighterMixin';
-import { NextMixin } from '../mixins/nextMixin';
-import { RequiredMixin } from '../mixins/requiredMixin';
-import { spread } from '../libs/lit-helpers';
+import { Sib } from '../libs/Sib.ts';
+import { spread } from '../libs/lit-helpers.ts';
+import { CounterMixin } from '../mixins/counterMixin.ts';
+import { FederationMixin } from '../mixins/federationMixin.ts';
+import { FilterMixin } from '../mixins/filterMixin.ts';
+import { GrouperMixin } from '../mixins/grouperMixin.ts';
+import { HighlighterMixin } from '../mixins/highlighterMixin.ts';
+import { ListMixin } from '../mixins/listMixin.ts';
+import { NextMixin } from '../mixins/nextMixin.ts';
+import { PaginateMixin } from '../mixins/paginateMixin.ts';
+import { RequiredMixin } from '../mixins/requiredMixin.ts';
+import { SorterMixin } from '../mixins/sorterMixin.ts';
+import { StoreMixin } from '../mixins/storeMixin.ts';
+import { WidgetMixin } from '../mixins/widgetMixin.ts';
 
-import { html, render } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
+import { html, render } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+import { trackRenderAsync } from '../logger.ts';
 
 export const SolidDisplay = {
   name: 'solid-display',
@@ -41,18 +43,20 @@ export const SolidDisplay = {
   initialState: {
     activeSubscription: null,
     removeActiveSubscription: null,
+    resources: [],
   },
   created(): void {
     // Set route active at initialization
     const route = document.querySelector('solid-route[active]') as any;
     if (!route) return;
     setTimeout(() => {
-      if (route['resourceId'] === this.resourceId) this.addActiveCallback();
+      if (route.resourceId === this.resourceId) this.addActiveCallback();
     });
   },
   detached(): void {
     if (this.activeSubscription) PubSub.unsubscribe(this.activeSubscription);
-    if (this.removeActiveSubscription) PubSub.unsubscribe(this.removeActiveSubscription);
+    if (this.removeActiveSubscription)
+      PubSub.unsubscribe(this.removeActiveSubscription);
   },
   // Update subscription when id changes
   updateNavigateSubscription() {
@@ -60,8 +64,8 @@ export const SolidDisplay = {
 
     if (this.resourceId) {
       this.activeSubscription = PubSub.subscribe(
-        'enterRoute.' + this.resourceId,
-        this.addActiveCallback.bind(this)
+        `enterRoute.${this.resourceId}`,
+        this.addActiveCallback.bind(this),
       );
     }
   },
@@ -69,7 +73,7 @@ export const SolidDisplay = {
     this.element.setAttribute('active', '');
     this.removeActiveSubscription = PubSub.subscribe(
       'leaveRoute',
-      this.removeActiveCallback.bind(this)
+      this.removeActiveCallback.bind(this),
     );
   },
   removeActiveCallback() {
@@ -87,18 +91,18 @@ export const SolidDisplay = {
   },
   // Here "even.target" points to the content of the widgets of the children of solid-display
   dispatchSelect(event: Event, resourceId: string): void {
-    const linkTarget = (event!.target as Element).closest('a');
-    if (linkTarget && linkTarget.hasAttribute('href')) return;
-    const resource = { "@id": resourceId };
+    const linkTarget = (event?.target as Element).closest('a');
+    if (linkTarget?.hasAttribute('href')) return;
+    const resource = { '@id': resourceId };
     this.element.dispatchEvent(
       new CustomEvent('resourceSelect', { detail: { resource: resource } }),
     );
     this.goToNext(resource);
   },
-  
-  enterKeydownAction (event, resourceId: string): void {
+
+  enterKeydownAction(event, resourceId: string): void {
     if (event.keyCode === 13) {
-      const resource = { "@id" : resourceId };
+      const resource = { '@id': resourceId };
       this.goToNext(resource);
     }
   },
@@ -108,7 +112,7 @@ export const SolidDisplay = {
    * @param attributes
    */
   getChildTemplate(resourceId: string, attributes: object) {
-    let template = html`
+    const template = html`
       <solid-display
         data-src=${resourceId}
         @click=${(event: Event) => this.dispatchSelect(event, resourceId)}
@@ -116,7 +120,7 @@ export const SolidDisplay = {
         fields=${ifDefined(this.fields)}
         ...=${spread(attributes)}
       ></solid-display>
-    `
+    `;
     return template;
   },
 
@@ -126,8 +130,9 @@ export const SolidDisplay = {
    */
   async appendSingleElt(parent: HTMLElement): Promise<void> {
     const fields = await this.getFields();
-    const widgetTemplates = await Promise.all( // generate all widget templates
-      fields.map((field: string) => this.createWidgetTemplate(field))
+    const widgetTemplates = await Promise.all(
+      // generate all widget templates
+      fields.map((field: string) => this.createWidgetTemplate(field)),
     );
     render(html`${widgetTemplates}`, parent);
   },
@@ -141,59 +146,55 @@ export const SolidDisplay = {
    * @param div
    * @param context
    */
-  async renderDOM(
+  renderDOM: trackRenderAsync(async function (
     resources: object[],
-    listPostProcessors: Function[],
+    listPostProcessors: PostProcessorRegistry,
     div: HTMLElement,
     context: string,
   ) {
     const attributes = this.getChildAttributes(); // get attributes of children only once
     // and create a child template for each resource
-    const template = html`${resources.map(r => r ? this.getChildTemplate(r['@id'], attributes) : null)}`;
+    const template = html`${resources.map(r => (r ? this.getChildTemplate(r['@id'], attributes) : null))}`;
     render(template, div);
 
     const nextProcessor = listPostProcessors.shift();
+
     if (nextProcessor)
-      await nextProcessor(
-        resources,
-        listPostProcessors,
-        div,
-        context
-      );
-  },
+      await nextProcessor(resources, listPostProcessors, div, context);
+  }, 'SolidDisplay:renderDom'),
 
   /**
    * Get attributes to dispatch to children from current element
    */
   getChildAttributes() {
-    const attributes:{[key:string]: string} = {};
-    for (let attr of this.element.attributes) {
+    const attributes: { [key: string]: string } = {};
+    for (const attr of this.element.attributes) {
       //copy widget and value attributes
       if (
-        attr.name.startsWith('value-')        ||
-        attr.name.startsWith('label-')        ||
-        attr.name.startsWith('placeholder-')  ||
-        attr.name.startsWith('widget-')       ||
-        attr.name.startsWith('class-')        ||
-        attr.name.startsWith('multiple-')     ||
-        attr.name.startsWith('editable-')     ||
-        attr.name.startsWith('action-')       ||
-        attr.name.startsWith('default-')      ||
-        attr.name.startsWith('link-text-')    ||
-        attr.name.startsWith('target-src-')   ||
-        attr.name.startsWith('data-label-')   ||
-        attr.name == 'extra-context'
+        attr.name.startsWith('value-') ||
+        attr.name.startsWith('label-') ||
+        attr.name.startsWith('placeholder-') ||
+        attr.name.startsWith('widget-') ||
+        attr.name.startsWith('class-') ||
+        attr.name.startsWith('multiple-') ||
+        attr.name.startsWith('editable-') ||
+        attr.name.startsWith('action-') ||
+        attr.name.startsWith('default-') ||
+        attr.name.startsWith('link-text-') ||
+        attr.name.startsWith('target-src-') ||
+        attr.name.startsWith('data-label-') ||
+        attr.name === 'extra-context'
       )
         attributes[attr.name] = attr.value;
       if (attr.name.startsWith('child-'))
         attributes[attr.name.replace(/^child-/, '')] = attr.value;
-      if (attr.name == 'next') {
-        attributes['role'] = 'button';
-        attributes['tabindex'] = '0';
+      if (attr.name === 'next') {
+        attributes.role = 'button';
+        attributes.tabindex = '0';
       }
     }
     return attributes;
-  }
+  },
 };
 
 Sib.register(SolidDisplay);
diff --git a/src/components/solid-form-search.ts b/src/components/solid-form-search.ts
index f165b54c5295e1f51a2ca9f153e58fd4db320645..02a30c819d749bc12b52200b49995b3b189be259 100644
--- a/src/components/solid-form-search.ts
+++ b/src/components/solid-form-search.ts
@@ -1,19 +1,20 @@
-import { Sib } from '../libs/Sib';
-import { WidgetMixin } from '../mixins/widgetMixin';
-import { AttributeBinderMixin } from '../mixins/attributeBinderMixin';
-import { ContextMixin } from '../mixins/contextMixin';
-import type { WidgetInterface } from '../mixins/interfaces';
-import { newWidgetFactory } from '../new-widgets/new-widget-factory';
+import { Sib } from '../libs/Sib.ts';
+import { AttributeBinderMixin } from '../mixins/attributeBinderMixin.ts';
+import { ContextMixin } from '../mixins/contextMixin.ts';
+import type { WidgetInterface } from '../mixins/interfaces.ts';
+import { WidgetMixin } from '../mixins/widgetMixin.ts';
+import { newWidgetFactory } from '../new-widgets/new-widget-factory.ts';
 
-import { html, render } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
-import { uniqID } from '../libs/helpers';
-import type { SearchQuery, FilterEventOptions } from '../libs/interfaces';
+import { html, render } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { uniqID } from '../libs/helpers.ts';
+import type { FilterEventOptions, SearchQuery } from '../libs/interfaces.ts';
+import { trackRenderAsync } from '../logger.ts';
 
 export const SolidFormSearch = {
   name: 'solid-form-search',
   use: [WidgetMixin, AttributeBinderMixin, ContextMixin],
-  debounceTimeout: undefined as (number | undefined),
+  debounceTimeout: undefined as number | undefined,
   attributes: {
     defaultWidget: {
       type: String,
@@ -28,7 +29,7 @@ export const SolidFormSearch = {
     },
     submitWidget: {
       type: String,
-      default: undefined
+      default: undefined,
     },
     classSubmitButton: {
       type: String,
@@ -38,13 +39,13 @@ export const SolidFormSearch = {
       type: String,
       default: null,
       callback: function (value: boolean) {
-        if (value === null) this.populate()
-      }
+        if (value === null) this.populate();
+      },
     },
     debounce: {
       type: Number,
-      default: 0 // Avoiding blink effect with static values
-    }
+      default: 0, // Avoiding blink effect with static values
+    },
   },
   initialState: {
     error: '',
@@ -64,10 +65,10 @@ export const SolidFormSearch = {
 
   get value(): SearchQuery {
     const values: SearchQuery = {};
-    this.widgets.forEach((widget) => {
-      if (widget == null) return;
+    for (const widget of this.widgets) {
+      if (widget == null) continue;
       const name = (widget.component || widget).name;
-      if (name == null) return;
+      if (name == null) continue;
       let value = widget.component ? widget.component.getValue() : widget.value;
       try {
         value = JSON.parse(value);
@@ -76,62 +77,75 @@ export const SolidFormSearch = {
         type: widget.component.type,
         list: !!widget.component.multiple,
         value: value,
-      }
+      };
       values[name] = value;
-    });
+    }
     return values;
   },
-  getWidget(field: string, isSet: boolean = false): WidgetInterface {
+  getWidget(field: string, isSet = false): WidgetInterface {
     let tagName = '';
     // If auto-range-[field] exists, create range-[field] and sets its value
-    if(this.element.hasAttribute('auto-range-' + field) && !this.element.hasAttribute('range-' + field)) {
+    if (
+      this.element.hasAttribute(`auto-range-${field}`) &&
+      !this.element.hasAttribute(`range-${field}`)
+    ) {
       const idField = `${this.rangeId}_${field}`;
-      this.element.setAttribute('range-' + field, 'store://local.' + idField);
+      this.element.setAttribute(`range-${field}`, `store://local.${idField}`);
       this.populate();
     }
-    
-    const widgetAttribute = this.element.getAttribute('widget-' + field);
+
+    const widgetAttribute = this.element.getAttribute(`widget-${field}`);
     // Choose widget
-    if (!widgetAttribute && (this.element.hasAttribute('range-' + field) || this.element.hasAttribute('enum-' + field))) {
-      tagName = 'solid-form-dropdown'
+    if (
+      !widgetAttribute &&
+      (this.element.hasAttribute(`range-${field}`) ||
+        this.element.hasAttribute(`enum-${field}`))
+    ) {
+      tagName = 'solid-form-dropdown';
     } else {
-      tagName = widgetAttribute || (!isSet ? this.defaultWidget : this.defaultSetWidget);
+      tagName =
+        widgetAttribute ||
+        (!isSet ? this.defaultWidget : this.defaultSetWidget);
     }
     // Create widget
-    if (!customElements.get(tagName)) { // component does not exist
+    if (!customElements.get(tagName)) {
+      // component does not exist
       if (tagName.startsWith('solid')) newWidgetFactory(tagName); // solid- -> create it
     }
 
     return this.widgetFromTagName(tagName);
   },
-  async attach(elm: any) {
-    if(this.attachedElements.has(elm)) return;
+  async attach(elm: unknown) {
+    if (this.attachedElements.has(elm)) return;
     this.attachedElements.add(elm);
     await this.updateAutoRanges();
   },
-  async detach(elm: any) {
-    if(!this.attachedElements.has(elm)) return;
+  async detach(elm: unknown) {
+    if (!this.attachedElements.has(elm)) return;
     this.attachedElements.delete(elm);
     await this.updateAutoRanges();
   },
   async updateAutoRanges() {
-    for(const attr of (this.element as Element).attributes) {
-      if (!attr['name'].startsWith('auto-range-')) continue;
-      let fieldName = attr.value !== '' ? attr.value : attr['name'].replace('auto-range-', '');
+    for (const attr of (this.element as Element).attributes) {
+      if (!attr.name.startsWith('auto-range-')) continue;
+      const fieldName =
+        attr.value !== '' ? attr.value : attr.name.replace('auto-range-', '');
       const autoRangeValues = new Set();
-      for(const elm of this.attachedElements) {
-        for(const value of await elm.getValuesOfField(fieldName)) {
+      for (const elm of this.attachedElements) {
+        for (const value of await elm.getValuesOfField(fieldName)) {
           autoRangeValues.add(value);
         }
       }
 
       const idField = `${this.rangeId}_${fieldName}`;
       const id = `store://local.${idField}`;
-      const ldpContains = Array.from(autoRangeValues).map(id => ({'@id' : id}));
+      const ldpContains = Array.from(autoRangeValues).map(id => ({
+        '@id': id,
+      }));
       const data = {
-        "@type": "ldp:Container",
-        "@context": this.context,
-        "ldp:contains" : ldpContains,
+        '@type': 'ldp:Container',
+        '@context': this.context,
+        'ldp:contains': ldpContains,
       };
       sibStore.setLocalData(data, id);
     }
@@ -152,45 +166,44 @@ export const SolidFormSearch = {
         detail: {
           value: eventOptions.value,
           inputLabel: eventOptions.inputLabel,
-          type: eventOptions.type
-        }
+          type: eventOptions.type,
+        },
       }),
     );
   },
-  async inputChange(input: EventTarget): Promise<void> {
+  inputChange(input: EventTarget) {
     // FIXME: Improve this as we need to support more than input and single select.
     // What about multiple select, checkboxes, radio buttons, etc?
-    let parentElementLabel = (input as HTMLInputElement)?.parentElement?.getAttribute('label');
+    const parentElementLabel = (
+      input as HTMLInputElement
+    )?.parentElement?.getAttribute('label');
     try {
-      const selectedLabel = (input as HTMLSelectElement).selectedOptions[0].textContent?.trim();
-      this.change(
-        this.value,
-        {
-          value: selectedLabel,
-          inputLabel: parentElementLabel,
-          type: 'select'
-        }
-      );
+      const selectedLabel = (
+        input as HTMLSelectElement
+      ).selectedOptions[0].textContent?.trim();
+      this.change(this.value, {
+        value: selectedLabel,
+        inputLabel: parentElementLabel,
+        type: 'select',
+      });
     } catch {
-      this.change(this.value,
-        {
-          value: (input as HTMLInputElement).value,
-          inputLabel: parentElementLabel,
-          type: 'input'
-        }
-      );
+      this.change(this.value, {
+        value: (input as HTMLInputElement).value,
+        inputLabel: parentElementLabel,
+        type: 'input',
+      });
     }
   },
   getSubmitTemplate() {
     return html`
       <div class=${ifDefined(this.classSubmitButton)}>
-        ${this.submitWidget === 'button' ? html`
-          <button type="submit">${this.submitButton || ''}</button>
-        ` : html`
-          <input type="submit" value=${ifDefined(this.submitButton || undefined)}>
-        `}
+        ${
+          this.submitWidget === 'button'
+            ? html`<button type="submit">${this.submitButton || ''}</button>`
+            : html`<input type="submit" value=${ifDefined(this.submitButton || undefined)}>`
+        }
       </div>
-    ` 
+    `;
   },
   empty(): void {},
   debounceInput(input: EventTarget | null) {
@@ -200,7 +213,7 @@ export const SolidFormSearch = {
       this.inputChange(input);
     }, this.debounce);
   },
-  async populate(): Promise<void> {
+  populate: trackRenderAsync(async function (): Promise<void> {
     await this.replaceAttributesData();
     if (this.submitButton == null) {
       this.element.addEventListener('input', (e: Event) => {
@@ -212,15 +225,17 @@ export const SolidFormSearch = {
       this.inputChange(e.target);
     });
     const fields = await this.getFields();
-    const widgetTemplates = await Promise.all(fields.map((field: string) => this.createWidgetTemplate(field)));
+    const widgetTemplates = await Promise.all(
+      fields.map((field: string) => this.createWidgetTemplate(field)),
+    );
     const template = html`
-      <form>
-        ${widgetTemplates}
-        ${this.submitButton == null ? '' : this.getSubmitTemplate()}
-      </form>
-    `;
+        <form>
+          ${widgetTemplates}
+          ${this.submitButton == null ? '' : this.getSubmitTemplate()}
+        </form>
+      `;
     render(template, this.element);
-  }
+  }, 'SolidFormSearch:populate'),
 };
 
-Sib.register(SolidFormSearch);
\ No newline at end of file
+Sib.register(SolidFormSearch);
diff --git a/src/components/solid-form.ts b/src/components/solid-form.ts
index b79e2da7145429591ab7abce1d68087bd5c7f8ea..b7dc1bd48d341e57d411d6a627a0f42beea5259a 100644
--- a/src/components/solid-form.ts
+++ b/src/components/solid-form.ts
@@ -1,14 +1,15 @@
-import { Sib } from '../libs/Sib';
-import { WidgetMixin } from '../mixins/widgetMixin';
-import { StoreMixin } from '../mixins/storeMixin';
-import { NextMixin } from '../mixins/nextMixin';
-import { ValidationMixin } from '../mixins/validationMixin';
-import { store } from '../libs/store/store';
-import { setDeepProperty, transformArrayToContainer } from '../libs/helpers';
-import type { WidgetInterface } from '../mixins/interfaces';
+import { Sib } from '../libs/Sib.ts';
+import { setDeepProperty, transformArrayToContainer } from '../libs/helpers.ts';
+import { store } from '../libs/store/store.ts';
+import type { WidgetInterface } from '../mixins/interfaces.ts';
+import { NextMixin } from '../mixins/nextMixin.ts';
+import { StoreMixin } from '../mixins/storeMixin.ts';
+import { ValidationMixin } from '../mixins/validationMixin.ts';
+import { WidgetMixin } from '../mixins/widgetMixin.ts';
 
-import { html, render } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
+import { html, render } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { trackRenderAsync } from '../logger.ts';
 
 export const SolidForm = {
   name: 'solid-form',
@@ -16,7 +17,7 @@ export const SolidForm = {
   attributes: {
     autosave: {
       type: Boolean,
-      default: null
+      default: null,
     },
     classSubmitButton: {
       type: String,
@@ -24,15 +25,15 @@ export const SolidForm = {
     },
     defaultWidget: {
       type: String,
-      default: 'solid-form-label-text'
+      default: 'solid-form-label-text',
     },
     naked: {
       type: Boolean,
-      default: null
+      default: null,
     },
     partial: {
       type: Boolean,
-      default: null
+      default: null,
     },
     submitButton: {
       type: String,
@@ -43,11 +44,11 @@ export const SolidForm = {
     },
     submitWidget: {
       type: String,
-      default: null
+      default: null,
     },
   },
   initialState: {
-    error: ''
+    error: '',
   },
   get defaultMultipleWidget(): string {
     return 'solid-multiple-form';
@@ -57,17 +58,18 @@ export const SolidForm = {
   },
   get value(): object {
     const values = {};
-    this.widgets.forEach((widget) => {
+    for (const widget of this.widgets) {
       const name = (widget.component || widget).name;
-      if (name == null) return;
+      if (name == null) continue;
       let value = widget.component ? widget.component.getValue() : widget.value;
       try {
         value = JSON.parse(value);
-      } catch (e) {}
+      } catch {}
       setDeepProperty(values, name.split('.'), value);
-    });
+    }
     // add @id if edition
-    if (this.resource && !this.resource.isContainer?.()) values['@id'] = this.resourceId;
+    if (this.resource && !this.resource.isContainer?.())
+      values['@id'] = this.resourceId;
     return values;
   },
   get isNaked(): boolean {
@@ -80,43 +82,54 @@ export const SolidForm = {
     return !('@id' in formValue);
   },
   async getFormValue() {
-    let value = this.value;
+    const value = this.value;
     if (this.resource && !this.resource.isContainer?.()) {
-      for (let predicate of Object.keys(this.value)) {
+      for (const predicate of Object.keys(this.value)) {
         // add @id for nested resources
         let object = await this.resource[predicate];
         // edge-case where object is null because predicate needs to be expanded manually (arrays)
         if (!object) {
-          object = await this.resource[store.getExpandedPredicate(predicate, this.context)];
+          object =
+            await this.resource[
+              store.getExpandedPredicate(predicate, this.context)
+            ];
         }
 
         // Nested containers
-        if (object
-          && object['@id']
-          && !value[predicate]['@id']) value[predicate]['@id'] = object['@id'];
+        if (object?.['@id'] && !value[predicate]['@id'])
+          value[predicate]['@id'] = object['@id'];
 
         //FIXME: Edge case of array support, ugly management
-        if (object && !object['@id']
-          && Array.isArray(object)
-          && value[predicate].length == 0
-          && object.length > 0) {
+        if (
+          object &&
+          !object['@id'] &&
+          Array.isArray(object) &&
+          value[predicate].length === 0 &&
+          object.length > 0
+        ) {
           value[predicate] = object;
         }
       }
     }
     return transformArrayToContainer(value);
   },
-  getWidget(field: string, isSet: boolean = false): WidgetInterface {
+  getWidget(field: string, isSet = false): WidgetInterface {
     let tagName = '';
-    const widgetAttribute = this.element.getAttribute('widget-' + field);
+    const widgetAttribute = this.element.getAttribute(`widget-${field}`);
 
     // Choose widget
-    if (!widgetAttribute && this.element.hasAttribute('upload-url-' + field)) {
-      tagName = 'solid-form-file'
-    } else if (!widgetAttribute && (this.element.hasAttribute('range-' + field) || this.element.hasAttribute('enum-' + field))) {
-      tagName = 'solid-form-dropdown'
+    if (!widgetAttribute && this.element.hasAttribute(`upload-url-${field}`)) {
+      tagName = 'solid-form-file';
+    } else if (
+      !widgetAttribute &&
+      (this.element.hasAttribute(`range-${field}`) ||
+        this.element.hasAttribute(`enum-${field}`))
+    ) {
+      tagName = 'solid-form-dropdown';
     } else {
-      tagName = widgetAttribute || (!isSet ? this.defaultWidget : this.defaultSetWidget);
+      tagName =
+        widgetAttribute ||
+        (!isSet ? this.defaultWidget : this.defaultSetWidget);
     }
     // Create widget
     return this.widgetFromTagName(tagName);
@@ -129,23 +142,24 @@ export const SolidForm = {
       }),
     );
   },
-  async save(): Promise<object> {
+  async save() {
     this.toggleLoaderHidden(false);
     this.hideError();
     const resource = await this.getFormValue();
     resource['@context'] = this.context;
-    let saved;
+    let saved: string | null | undefined;
     try {
       if (this.partial == null) {
-        saved = resource['@id'] ?
-          await store.put(resource, this.resourceId) :
-          await store.post(resource, this.resourceId);
+        saved = resource['@id']
+          ? await store.put(resource, this.resourceId)
+          : await store.post(resource, this.resourceId);
       } else {
         saved = await store.patch(resource, this.resourceId);
       }
     } catch (e: any) {
       this.toggleLoaderHidden(true);
-      if (e) { // if server error
+      if (e?.json) {
+        // if server error
         e.json().then(error => this.showError(error));
         throw e;
       }
@@ -155,7 +169,7 @@ export const SolidForm = {
         bubbles: true,
         detail: {
           resource: resource,
-          id: saved || null
+          id: saved || null,
         },
       }),
     );
@@ -165,10 +179,12 @@ export const SolidForm = {
   async submitForm(): Promise<void> {
     let id: string;
     try {
-      id = await this.save() || this.getFormValue()['@id'];
-    } catch (e) { return; }
+      id = (await this.save()) || this.getFormValue()['@id'];
+    } catch (_e) {
+      return;
+    }
     this.reset();
-    this.goToNext({'@id': id})
+    this.goToNext({ '@id': id });
   },
   async onInput(): Promise<void> {
     const formValue = await this.getFormValue();
@@ -179,37 +195,41 @@ export const SolidForm = {
     if (!this.isCreationForm(formValue) && this.isSavingAutomatically)
       this.submitForm(); // if autosave, submitForm
   },
-  displayErrorMessage(errors: [string, any][], errorFullName: string = '') {
-    errors.forEach((member: [string, any]) => {
-      let errorNextName: string = Object.values(member)[0];
-      let subErrorName = (errorFullName === "" ? errorNextName : errorFullName.concat('.' + errorNextName));
-      let errorFieldName = ""
+  displayErrorMessage(errors: [string, any][], errorFullName = '') {
+    for (const member of errors) {
+      const errorNextName: string = Object.values(member)[0];
+      const subErrorName =
+        errorFullName === ''
+          ? errorNextName
+          : `${errorFullName}.${errorNextName}`;
+      let errorFieldName = '';
 
-      if (errorFullName) errorFieldName = errorFullName.concat('.' + errorNextName);
+      if (errorFullName) errorFieldName = `${errorFullName}.${errorNextName}`;
       else errorFieldName = errorNextName;
 
       if (errorFieldName) {
-        let formField = this.element.querySelector(`[name="${errorFieldName}"]`);
+        const formField = this.element.querySelector(
+          `[name="${errorFieldName}"]`,
+        );
         if (formField) {
           formField.classList.add('error');
-          let errorParagraph = document.createElement('p');
+          const errorParagraph = document.createElement('p');
           if (Array.isArray(Object.values(member)[1]) === true) {
-            Object.values(member)[1].forEach((error) => {
-              let errorText = document.createElement('p');
+            for (const error of Object.values(member)[1]) {
+              const errorText = document.createElement('p');
               errorText.textContent = error;
               errorParagraph.appendChild(errorText);
-            });
+            }
           } else if (typeof Object.values(member)[1] === 'object') {
-            // @ts-ignore
-            for (const [key, value] of Object.entries(Object.values(member)[1])) {
+            for (const value of Object.values(Object.values(member)[1])) {
               if (Array.isArray(value)) {
-                value.forEach((error) => {
-                  let errorText = document.createElement('p');
+                for (const error of value) {
+                  const errorText = document.createElement('p');
                   errorText.textContent = error;
                   errorParagraph.appendChild(errorText);
-                });
+                }
               } else if (typeof value === 'string') {
-                let errorText = document.createElement('p');
+                const errorText = document.createElement('p');
                 errorText.textContent = value;
                 errorParagraph.appendChild(errorText);
               }
@@ -223,30 +243,32 @@ export const SolidForm = {
       }
 
       if (!Array.isArray(Object.values(member)[1]) === true) {
-        let objectErrors = Object.values(member)[1];
-        let subErrors = Object.entries(objectErrors);
-        this.displayErrorMessage(subErrors, subErrorName)
+        const objectErrors = Object.values(member)[1];
+        const subErrors = Object.entries(objectErrors);
+        this.displayErrorMessage(subErrors, subErrorName);
       }
-    });
+    }
   },
   empty(): void {},
   showError(e: object) {
-    let errors = Object.entries(e).filter(field => !field[0].startsWith('@context'));
+    const errors = Object.entries(e).filter(
+      field => !field[0].startsWith('@context'),
+    );
     this.displayErrorMessage(errors);
-    const errorTemplate = html`
-      <p>${this.t('solid-form.validation-error')}</p>
-    `;
+    const errorTemplate = html`<p>${this.t('solid-form.validation-error')}</p>`;
 
     // Validation message in english ?
     const parentElement = this.element.querySelector('[data-id=error]');
     if (parentElement) render(errorTemplate, parentElement);
   },
   hideError() {
-    let formErrors = this.element.querySelectorAll('.error-message');
-    if (formErrors) formErrors.forEach((error) => error.remove());
+    const formErrors = this.element.querySelectorAll('.error-message');
+    if (formErrors) for (const error of formErrors) error.remove();
 
-    let errorFields = this.element.querySelectorAll('.error');
-    if (errorFields) errorFields.forEach((errorField) => errorField.classList.remove('error'));
+    const errorFields = this.element.querySelectorAll('.error');
+    if (errorFields)
+      for (const errorField of errorFields)
+        errorField.classList.remove('error');
 
     const parentElement = this.element.querySelector('[data-id=error]');
     if (parentElement) render('', parentElement);
@@ -260,48 +282,55 @@ export const SolidForm = {
       this.performAction(); // In validationMixin, method defining what to do according to the present attributes
     }
   },
-  validateModal() { //send method to validationMixin, used by the dialog modal and performAction method
+  validateModal() {
+    //send method to validationMixin, used by the dialog modal and performAction method
     return this.submitForm();
   },
   onReset() {
-    if (!this.isNaked) setTimeout(() => this.onInput())
+    if (!this.isNaked) setTimeout(() => this.onInput());
   },
   getSubmitTemplate() {
     return html`
       <div class=${ifDefined(this.classSubmitButton)}>
-        ${this.submitWidget === 'button' ? html`
-          <button type="submit">${this.submitButton || this.t("solid-form.submit-button")}</button>
-        ` : html`
-          <input type="submit" value=${this.submitButton || this.t("solid-form.submit-button")}>
-        `}
+        ${
+          this.submitWidget === 'button'
+            ? html`<button type="submit">${this.submitButton || this.t('solid-form.submit-button')}</button>`
+            : html`<input type="submit" value=${this.submitButton || this.t('solid-form.submit-button')}>`
+        }
       </div>
-    `
+    `;
   },
-  async populate(): Promise<void> {
+  populate: trackRenderAsync(async function (): Promise<void> {
     this.element.oninput = () => this.onInput(); // prevent from firing change multiple times
     this.element.onchange = () => this.onChange();
     const fields = await this.getFields();
-    const widgetTemplates = await Promise.all(fields.map((field: string) => this.createWidgetTemplate(field)));
+    const widgetTemplates = await Promise.all(
+      fields.map((field: string) => this.createWidgetTemplate(field)),
+    );
     const template = html`
-      <div data-id="error"></div>
-      ${!this.isNaked ? html`
-        <form
-          @submit=${this.onSubmit.bind(this)}
-          @reset=${this.onReset.bind(this)}
-        >
-          ${widgetTemplates}
-          ${!this.isSavingAutomatically ? this.getSubmitTemplate() : ''}
-          ${this.element.hasAttribute('reset')
-            ? html`<input type="reset" />` : ''}
-        </form>
-      ` : html`
-        ${widgetTemplates}
-      `
-      }
-      ${this.getModalDialog()}
-    `;
+        <div data-id="error"></div>
+        ${
+          !this.isNaked
+            ? html`
+          <form
+            @submit=${this.onSubmit.bind(this)}
+            @reset=${this.onReset.bind(this)}
+          >
+            ${widgetTemplates}
+            ${!this.isSavingAutomatically ? this.getSubmitTemplate() : ''}
+            ${
+              this.element.hasAttribute('reset')
+                ? html`<input type="reset" />`
+                : ''
+            }
+          </form>
+        `
+            : html`${widgetTemplates}`
+        }
+        ${this.getModalDialog()}
+      `;
     render(template, this.element);
-  }
+  }, 'SolidForm:populate'),
 };
 
-Sib.register(SolidForm);
\ No newline at end of file
+Sib.register(SolidForm);
diff --git a/src/components/solid-lang.ts b/src/components/solid-lang.ts
index 82b5c254419ae3b9cf97b482d4d4894fd546883b..1f30d969ba0440377a0c813b059058ed80903ebe 100644
--- a/src/components/solid-lang.ts
+++ b/src/components/solid-lang.ts
@@ -1,7 +1,7 @@
-import { Sib } from '../libs/Sib';
-import { store } from '../libs/store/store';
+import { Sib } from '../libs/Sib.ts';
+import { store } from '../libs/store/store.ts';
 
-import { html, render } from 'lit-html';
+import { html, render } from 'lit';
 
 export const SolidLang = {
   name: 'solid-lang',
@@ -9,34 +9,28 @@ export const SolidLang = {
   attributes: {
     lang: {
       type: String,
-      default: null
+      default: null,
     },
     dataLabel: {
       type: String,
-      default: null
-    }
+      default: null,
+    },
   },
 
   created(): void {
     this.render();
   },
 
-  languageLoader () {
+  languageLoader() {
     store.selectLanguage(this.lang);
     location.reload();
   },
 
   render() {
-    let template = html`
-    <button
-      @click=${this.languageLoader.bind(this)}
-    >
-      ${this.dataLabel}
-    </button>
-    `;
+    const template = html`<button @click=${this.languageLoader.bind(this)}>${this.dataLabel}</button>`;
 
     render(template, this.element);
-  }
+  },
 };
 
-Sib.register(SolidLang);
\ No newline at end of file
+Sib.register(SolidLang);
diff --git a/src/components/solid-map.ts b/src/components/solid-map.ts
deleted file mode 100644
index 9c80693fa964c1f743fc93c7b87ed998b0456e1c..0000000000000000000000000000000000000000
--- a/src/components/solid-map.ts
+++ /dev/null
@@ -1,229 +0,0 @@
-import { Sib } from '../libs/Sib';
-import { ListMixin } from '../mixins/listMixin';
-import { StoreMixin } from '../mixins/storeMixin';
-import { WidgetMixin } from '../mixins/widgetMixin';
-import { CounterMixin } from '../mixins/counterMixin';
-import { FilterMixin } from '../mixins/filterMixin';
-import { FederationMixin } from '../mixins/federationMixin';
-import { GrouperMixin } from '../mixins/grouperMixin';
-import { NextMixin } from '../mixins/nextMixin';
-import { store } from '../libs/store/store';
-import { importInlineCSS, uniqID } from '../libs/helpers';
-import { spread } from '../libs/lit-helpers';
-
-//@ts-ignore
-import L, { MarkerOptions } from 'https://cdn.skypack.dev/leaflet'; // TODO : revert to "leaflet" when apps up to date
-import 'https://cdn.skypack.dev/leaflet.markercluster'; // TODO : revert to "leaflet.markercluster" when apps up to date
-
-import { html, render } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
-
-export const SolidMap = {
-  name: 'solid-map',
-  use: [
-    WidgetMixin,
-    ListMixin,
-    StoreMixin,
-    GrouperMixin,
-    CounterMixin,
-    FilterMixin,
-    FederationMixin,
-    NextMixin,
-  ],
-  attributes: {
-    clustering: {
-      type: Boolean,
-      default: null
-    }
-  },
-  initialState: {
-    markers: {
-      default: null
-    },
-    subscriptions: null,
-    resetPlanned: false,
-    hasBeenResetOnce: false
-  },
-  created(): void {
-    importInlineCSS('leaflet', () => import('leaflet/dist/leaflet.css?inline'))
-    importInlineCSS('default-theme', () => import('../style/default-theme.css?inline'))
-    importInlineCSS('marker-cluster', () => import('leaflet.markercluster/dist/MarkerCluster.css?inline'))
-    importInlineCSS('marker-cluster-default', () => import('leaflet.markercluster/dist/MarkerCluster.Default.css?inline'))
-
-    // reset when it becomes visible to prevent bug https://git.startinblox.com/framework/sib-core/issues/661
-    document.body.addEventListener('navigate', () =>
-      setTimeout(() => this.isVisible && !this.hasBeenResetOnce && this.reset())
-    );
-    this.markers = [];
-    this.subscriptions = new Map();
-  },
-  get isVisible() {
-    return this.element.offsetParent !== null
-  },
-  attached(): void {
-    const id = uniqID();
-    const template = html`
-      <div id=${id} style="width:100%;height:100%;"></div>
-    `;
-    render(template, this.element);
-
-    const div = this.element.querySelector(`#${id}`);
-    this.map = L.map(div);
-
-    L.tileLayer(
-      'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png'
-    ).addTo(this.map);
-
-    if (this.clustering !== null) {
-      this.markersCluster = L.markerClusterGroup();
-      this.map.addLayer(this.markersCluster);
-    }
-  },
-  reset() {
-    if (this.isVisible) { // reset only if visible
-      this.map.invalidateSize();
-
-      if (this.markers.length) {
-        this.map.fitBounds(L.featureGroup(this.markers).getBounds()); // Center map on markers if some available
-      } else {
-        this.map.fitWorld(); // ... or on the world if not
-      }
-      this.hasBeenResetOnce = true;
-    }
-  },
-  /**
-   * Execute a reset only if none is planned already
-   */
-  planReset() {
-    if (!this.resetPlanned) {
-      this.resetPlanned = true;
-      setTimeout(() => {
-        this.reset();
-        this.resetPlanned = false;
-      })
-    }
-  },
-  dispatchSelect(event: CustomEvent): void {
-    const target = event.target as Element;
-    const resource = target['options'].resource;
-    this.element.dispatchEvent(
-      new CustomEvent('resourceSelect', { detail: { resource: resource } })
-    );
-    this.goToNext(resource);
-  },
-
-  /**
-   * Override listMixin method: initialize a marker on the map
-   * @param resourceId: id of the resource to display
-   * @param groupClass: class of the group of markers
-   */
-  async appendChildElt(resourceId: string, groupClass: string) {
-    const resource = await store.getData(resourceId, this.context);
-    if (!this.subscriptions.get(resourceId)) {
-      this.subscriptions.set(resourceId, PubSub.subscribe(resourceId, () => this.updateDOM()))
-    }
-    if (!resource) return;
-    const lat = await resource['lat'];
-    const lng = await resource['lng'];
-
-    if (lat && lng) {
-      const icon = L.divIcon({ // create the icon, doc here: https://leafletjs.com/reference-1.6.0.html#icon
-        className: 'sib-custom-marker ' + groupClass, // default class used for styling
-        iconSize: [8, 8],
-        iconAnchor: [12, 34],
-        popupAnchor: [0,-34]
-      });
-
-      // create a marker, doc here: https://leafletjs.com/reference-1.6.0.html#marker
-      const marker = L.marker(
-        [lat.toString(), lng.toString()], 
-        {resource, icon} as MarkerOptions
-      );
-      if(this.clustering === null) marker.addTo(this.map);
-      else this.markersCluster.addLayer(marker);
-      marker.on('click', this.dispatchSelect.bind(this));
-
-      if (this.fields !== null) { // show popups only if fields attribute
-        marker.bindPopup(() => this.getPopupContent(resourceId), { minWidth: 150 }) // re-generate popup solid-display
-      }
-
-      this.markers.push(marker);
-    }
-  },
-  /**
-   * Generate the solid-display of the popup
-   * @param resourceId: id of the popup clicked
-   */
-  getPopupContent(resourceId: string) {
-    const attributes:{[key:string]: string} = {};
-
-    for (let attr of this.element.attributes) {
-      //copy widget and value attributes
-      if (
-        attr.name.startsWith('value-') ||
-        attr.name.startsWith('label-') ||
-        attr.name.startsWith('widget-') ||
-        attr.name.startsWith('class-') ||
-        attr.name.startsWith('multiple-') ||
-        attr.name.startsWith('editable-') ||
-        attr.name.startsWith('action-') ||
-        attr.name.startsWith('default-') ||
-        attr.name == 'extra-context'
-      )
-        attributes[attr.name] = attr.value;
-      if (attr.name.startsWith('child-'))
-        attributes[attr.name.replace(/^child-/, '')] = attr.value;
-    }
-
-    const div = document.createElement('div');
-    const template = html`
-      <solid-display
-        fields="${ifDefined(this.fields)}"
-        data-src="${resourceId}"
-        ...=${spread(attributes)}
-      ></solid-display>
-    `;
-    render(template, div);
-    return div.querySelector('solid-display');
-  },
-  /**
-   * Override widgetMixin method: empty the map
-   */
-  empty(): void {
-    if (!this.map) return;
-    if (this.markersCluster) this.map.removeLayer(this.markersCluster);
-    for (let marker of this.markers) this.map.removeLayer(marker);
-    if(this.clustering !== null) {
-      this.markersCluster = L.markerClusterGroup();
-      this.map.addLayer(this.markersCluster);
-    }
-    this.markers = [];
-  },
-  /**
-   * Override groupMixin method
-   * @param groupName: value of the group
-   */
-  renderGroup(groupName: string) {
-    const sanitizedGroupName = encodeURIComponent(groupName.toLowerCase()).replace(/%[0-9A-F]{2}/gi, '');
-    const div = document.createElement('div'); // used to pass group info to renderDOM
-    div.dataset.groupClass = 'group-' + sanitizedGroupName;
-    return div;
-  },
-  /**
-   * Override listMixin method: display all the resources
-   * @param resources
-   * @param listPostProcessors
-   * @param div
-   * @param context
-   */
-  async renderDOM(resources: object[], listPostProcessors: Function[], div: HTMLElement, context: string) {
-    const groupClass = div.dataset.groupClass || ''; // get the group class from the useless div element
-    await Promise.all(resources.map(resource => this.appendChildElt(resource['@id'], groupClass)))
-    this.planReset();
-
-    const nextProcessor = listPostProcessors.shift();
-    if(nextProcessor) await nextProcessor(resources, listPostProcessors, div, context);
-  }
-};
-
-Sib.register(SolidMap);
\ No newline at end of file
diff --git a/src/components/solid-member-add.ts b/src/components/solid-member-add.ts
index b58d4c90bb307249137bece7b8848669cab431f2..75846c17ed142851c9dd85a974ccf2f5076750d2 100644
--- a/src/components/solid-member-add.ts
+++ b/src/components/solid-member-add.ts
@@ -1,13 +1,13 @@
-import { Sib } from '../libs/Sib';
-import { base_context, store } from '../libs/store/store';
-import { NextMixin } from '../mixins/nextMixin';
-import { ValidationMixin } from '../mixins/validationMixin';
+import { Sib } from '../libs/Sib.ts';
+import { base_context, store } from '../libs/store/store.ts';
+import { NextMixin } from '../mixins/nextMixin.ts';
+import { ValidationMixin } from '../mixins/validationMixin.ts';
 
-import { html, render } from 'lit-html';
-import { ContextMixin } from '../mixins/contextMixin';
-import { newWidgetFactory } from '../new-widgets/new-widget-factory';
-import { StoreMixin } from '../mixins/storeMixin';
-import { ifDefined } from 'lit-html/directives/if-defined';
+import { html, render } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { ContextMixin } from '../mixins/contextMixin.ts';
+import { StoreMixin } from '../mixins/storeMixin.ts';
+import { newWidgetFactory } from '../new-widgets/new-widget-factory.ts';
 
 export const SolidMemberAdd = {
   name: 'solid-member-add',
@@ -30,11 +30,11 @@ export const SolidMemberAdd = {
     },
     classSubmitButton: {
       type: String,
-      default: undefined
+      default: undefined,
     },
     orderAsc: {
       type: String,
-      default: undefined
+      default: undefined,
     },
   },
   initialState: {
@@ -53,45 +53,56 @@ export const SolidMemberAdd = {
       });
     }
   },
-  async addMember(e: Event): Promise<void> {
+  addMember(e: Event) {
     if (!this.dataSrc || !this.resourceId) return;
     e.preventDefault();
     this.performAction(); // In validationMixin, method defining what to do according to the present attributes
   },
   async addMembership() {
     this.currentMembers.push(JSON.parse(this.dataTargetSrc));
-    let currentRes = {
-      "@context": this.context,
-      "user_set": this.currentMembers
-    }
+    const currentRes = {
+      '@context': this.context,
+      user_set: this.currentMembers,
+    };
 
     return store.patch(currentRes, this.resourceId).then(response => {
       if (!response) {
-        console.warn(`Error while adding user ${this.dataTargetSrc} to group ${this.resourceId}`);
+        console.warn(
+          `Error while adding user ${this.dataTargetSrc} to group ${this.resourceId}`,
+        );
         return;
       }
 
       this.goToNext(null);
-      const eventData = { detail: { resource: { "@id": this.dataSrc } }, bubbles: true };
+      const eventData = {
+        detail: { resource: { '@id': this.dataSrc } },
+        bubbles: true,
+      };
       this.element.dispatchEvent(new CustomEvent('save', eventData));
       this.element.dispatchEvent(new CustomEvent('memberAdded', eventData)); // Deprecated. To remove in 0.15
       this.planRender();
-    })
+    });
   },
-  validateModal() { // Send method to validationMixin, used by the dialog modal and performAction method
+  validateModal() {
+    // Send method to validationMixin, used by the dialog modal and performAction method
     return this.addMembership();
   },
   changeSelectedUser(e: Event) {
     if (!e.target || !(e.target as HTMLElement).firstElementChild) return;
 
     //FIXME: disgusting way to get the @id of the autocomplete slimselect widget value
-    this.dataTargetSrc = ((e.target as HTMLElement).firstElementChild as HTMLSelectElement)?.value;
+    this.dataTargetSrc = (
+      (e.target as HTMLElement).firstElementChild as HTMLSelectElement
+    )?.value;
   },
   async populate(): Promise<void> {
     if (!this.resource) return;
 
     // Check if current user is member of this group ?
-    let memberPredicate = store.getExpandedPredicate('user_set', base_context);
+    const memberPredicate = store.getExpandedPredicate(
+      'user_set',
+      base_context,
+    );
     // Here we now retrieve an array of proxy, when we would like an array of @ids only
     this.currentMembers = await this.resource[memberPredicate];
 
@@ -99,9 +110,11 @@ export const SolidMemberAdd = {
       this.currentMembers = [this.currentMembers];
     }
     // In each item in this.currentMembers, I'd like to return only their @id and store it in this.currentMembers
-    this.currentMembers = this.currentMembers.map(member => { return {"@id": member['@id'] } });
+    this.currentMembers = this.currentMembers.map(member => {
+      return { '@id': member['@id'] };
+    });
 
-    let button = html`
+    const button = html`
       <solid-ac-checker data-src="${this.dataSrc}"
         permission="acl:Write"
       >
@@ -127,7 +140,7 @@ export const SolidMemberAdd = {
       </solid-ac-checker>
       `;
     render(button, this.element);
-  }
+  },
 };
 
-Sib.register(SolidMemberAdd);
\ No newline at end of file
+Sib.register(SolidMemberAdd);
diff --git a/src/components/solid-member-delete.ts b/src/components/solid-member-delete.ts
index 9e90c1ba0f6d322f5284b17c7c3c95cc08525e2b..39e2f764fd5e5965d254d805fa64b76c57fb757c 100644
--- a/src/components/solid-member-delete.ts
+++ b/src/components/solid-member-delete.ts
@@ -1,11 +1,12 @@
-import { Sib } from '../libs/Sib';
-import { base_context, store } from '../libs/store/store';
-import { NextMixin } from '../mixins/nextMixin';
-import { ValidationMixin } from '../mixins/validationMixin';
-import { ifDefined } from 'lit-html/directives/if-defined';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { Sib } from '../libs/Sib.ts';
+import { base_context, store } from '../libs/store/store.ts';
+import { NextMixin } from '../mixins/nextMixin.ts';
+import { ValidationMixin } from '../mixins/validationMixin.ts';
 
-import { html, render } from 'lit-html';
-import { ContextMixin } from '../mixins/contextMixin';
+import { html, render } from 'lit';
+import { trackRenderAsync } from '../logger.ts';
+import { ContextMixin } from '../mixins/contextMixin.ts';
 
 export const SolidMemberDelete = {
   name: 'solid-member-delete',
@@ -33,12 +34,12 @@ export const SolidMemberDelete = {
       callback: function (newValue: string, oldValue: string) {
         if (newValue !== oldValue) {
           this.planRender();
-        } 
+        }
       },
     },
     dataUnknownMember: {
       type: String,
-      default: "Given user is not a member of this group",
+      default: 'Given user is not a member of this group',
       callback: function (newValue: string, oldValue: string) {
         if (newValue !== oldValue) this.planRender();
       },
@@ -62,20 +63,23 @@ export const SolidMemberDelete = {
     if (!this.resource) return;
 
     // Check if current user is member of this group ?
-    let memberPredicate = store.getExpandedPredicate('user_set', base_context);
+    const memberPredicate = store.getExpandedPredicate(
+      'user_set',
+      base_context,
+    );
     this.currentMembers = await this.resource[memberPredicate];
 
     if (!Array.isArray(this.currentMembers)) {
       this.currentMembers = [this.currentMembers];
     }
 
-    this.currentMembers = this.currentMembers.map((member) => {
-      return { "@id": member['@id'] };
+    this.currentMembers = this.currentMembers.map(member => {
+      return { '@id': member['@id'] };
     });
 
     // Check if current user is member of this group
     this.isMember = this.currentMembers
-      ? this.currentMembers.some((member) => member['@id'] === this.dataTargetSrc)
+      ? this.currentMembers.some(member => member['@id'] === this.dataTargetSrc)
       : false;
   },
   planRender() {
@@ -87,45 +91,50 @@ export const SolidMemberDelete = {
       });
     }
   },
-  async removeMember(e: Event): Promise<void> {
+  removeMember(e: Event) {
     e.stopPropagation();
     if (!this.dataSrc) return;
     this.performAction(); // In validationMixin, method defining what to do according to the present attributes
   },
   async deleteMembership() {
-    let userSet = this.currentMembers.filter((value) => {
+    const userSet = this.currentMembers.filter(value => {
       const userId = value['@id'];
-      if (userId == this.dataTargetSrc) 
-        return false;
-      else return true;
+      if (userId === this.dataTargetSrc) return false;
+      return true;
     });
 
-    let currentRes = {
-      "@context": this.context,
-      "user_set": userSet
-    }
+    const currentRes = {
+      '@context': this.context,
+      user_set: userSet,
+    };
     return store.patch(currentRes, this.dataSrc).then(response => {
       if (!response) {
-        console.warn(`Error while removing user ${this.dataTargetSrc} from group ${this.dataSrc}`);
+        console.warn(
+          `Error while removing user ${this.dataTargetSrc} from group ${this.dataSrc}`,
+        );
         return;
       }
       this.goToNext(null);
-      const eventData = { detail: { resource: { "@id": this.dataSrc } }, bubbles: true };
+      const eventData = {
+        detail: { resource: { '@id': this.dataSrc } },
+        bubbles: true,
+      };
       this.element.dispatchEvent(new CustomEvent('save', eventData));
       this.element.dispatchEvent(new CustomEvent('memberRemoved', eventData)); // Deprecated. To remove in 0.15
       this.planRender();
-    })
+    });
   },
-  validateModal() { // Send method to validationMixin, used by the dialog modal and performAction method
+  validateModal() {
+    // Send method to validationMixin, used by the dialog modal and performAction method
     return this.deleteMembership();
   },
   update() {
     this.render();
   },
-  async render(): Promise<void> {
+  render: trackRenderAsync(async function (): Promise<void> {
     // await this.replaceAttributesData(false);
     await this.populate();
-    let button = html``
+    let button = html``;
     if (this.isMember) {
       button = html`
         <solid-ac-checker data-src="${this.dataSrc}"
@@ -134,18 +143,16 @@ export const SolidMemberDelete = {
             >
           <button
             @click=${this.removeMember.bind(this)}>
-              ${this.dataLabel || this.t("solid-delete-member.button")}
+              ${this.dataLabel || this.t('solid-delete-member.button')}
           </button>
           ${this.getModalDialog()}
         </solid-ac-checker>
         `;
     } else {
-      button = html`
-        <span>${this.dataUnknownMember || this.t("solid-member-unknown.span")}</span>
-      `;
+      button = html`<span>${this.dataUnknownMember || this.t('solid-member-unknown.span')}</span>`;
     }
     render(button, this.element);
-  }
+  }, 'SolidMemberDelete:render'),
 };
 
-Sib.register(SolidMemberDelete);
\ No newline at end of file
+Sib.register(SolidMemberDelete);
diff --git a/src/components/solid-membership.ts b/src/components/solid-membership.ts
index 0e898e90f77fe859d15dcc4193a91abd8888ded9..af719c70535e75f825d918a77112ebd0db27775e 100644
--- a/src/components/solid-membership.ts
+++ b/src/components/solid-membership.ts
@@ -1,11 +1,12 @@
-import { Sib } from '../libs/Sib';
-import { base_context, store } from '../libs/store/store';
-import { NextMixin } from '../mixins/nextMixin';
-import { ValidationMixin } from '../mixins/validationMixin';
+import { Sib } from '../libs/Sib.ts';
+import { base_context, store } from '../libs/store/store.ts';
+import { NextMixin } from '../mixins/nextMixin.ts';
+import { ValidationMixin } from '../mixins/validationMixin.ts';
 
-import { html, render } from 'lit-html';
-import { ContextMixin } from '../mixins/contextMixin';
-import { ifDefined } from 'lit-html/directives/if-defined';
+import { html, render } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { trackRenderAsync } from '../logger.ts';
+import { ContextMixin } from '../mixins/contextMixin.ts';
 
 export const SolidMembership = {
   name: 'solid-membership',
@@ -20,7 +21,7 @@ export const SolidMembership = {
     },
     dataTargetSrc: {
       type: String,
-      default: null
+      default: null,
     },
     dataLeaveLabel: {
       type: String,
@@ -39,7 +40,7 @@ export const SolidMembership = {
     classSubmitButton: {
       type: String,
       default: undefined,
-    }
+    },
   },
   initialState: {
     renderPlanned: false,
@@ -51,13 +52,11 @@ export const SolidMembership = {
     if (!store.session) return;
 
     // Retrieve the current user from the current store authenticated session
-    let currentUserSession = await store.session;
+    const currentUserSession = await store.session;
     if (!currentUserSession) return;
 
-    if (!this.dataTargetSrc)
-      this.userId = await currentUserSession.webId;
-    else
-      this.userId = this.dataTargetSrc;
+    if (!this.dataTargetSrc) this.userId = await currentUserSession.webId;
+    else this.userId = this.dataTargetSrc;
 
     if (!this.userId) return;
 
@@ -66,18 +65,23 @@ export const SolidMembership = {
     if (!this.resource) return;
 
     // Check if current user is member of this group ?
-    let memberPredicate = store.getExpandedPredicate('user_set', base_context);
+    const memberPredicate = store.getExpandedPredicate(
+      'user_set',
+      base_context,
+    );
     this.currentMembers = await this.resource[memberPredicate];
 
     if (!Array.isArray(this.currentMembers)) {
       this.currentMembers = [this.currentMembers];
     }
 
-    this.currentMembers = this.currentMembers.map(member => { return {"@id": member['@id'] } });
+    this.currentMembers = this.currentMembers.map(member => {
+      return { '@id': member['@id'] };
+    });
 
     // Check if current user is member of this group
     this.isMember = this.currentMembers
-      ? this.currentMembers.some((member) => member['@id'] === this.userId)
+      ? this.currentMembers.some(member => member['@id'] === this.userId)
       : false;
   },
   planRender() {
@@ -89,92 +93,101 @@ export const SolidMembership = {
       });
     }
   },
-  async changeMembership(e: Event): Promise<void> {
+  changeMembership(e: Event) {
     e.stopPropagation();
     if (!this.dataSrc) return;
     this.performAction(); // In validationMixin, method defining what to do according to the present attributes
   },
   async joinGroup() {
-    this.currentMembers.push({"@id": this.userId});
-    let currentRes = {
-      "@context": this.context,
-      "user_set": this.currentMembers
-    }
+    this.currentMembers.push({ '@id': this.userId });
+    const currentRes = {
+      '@context': this.context,
+      user_set: this.currentMembers,
+    };
     return store.patch(currentRes, this.dataSrc).then(response => {
       if (!response) {
-        console.warn(`Error while joining group ${this.dataSrc} for user ${this.userId}`);
+        console.warn(
+          `Error while joining group ${this.dataSrc} for user ${this.userId}`,
+        );
         return;
       }
       this.goToNext(null);
-      const eventData = { detail: { resource: { "@id": this.dataSrc } }, bubbles: true };
+      const eventData = {
+        detail: { resource: { '@id': this.dataSrc } },
+        bubbles: true,
+      };
       this.element.dispatchEvent(new CustomEvent('save', eventData));
       this.element.dispatchEvent(new CustomEvent('memberAdded', eventData)); // Deprecated. To remove in 0.15
       this.planRender();
     });
   },
   async leaveGroup() {
-    let userSet = this.currentMembers.filter((value) => {
+    const userSet = this.currentMembers.filter(value => {
       const userId = value['@id'];
-      if (userId == this.userId) 
-        return false;
-      else return true;
+      if (userId === this.userId) return false;
+      return true;
     });
 
-    let currentRes = {
-      "@context": this.context,
-      "user_set": userSet
-    }
+    const currentRes = {
+      '@context': this.context,
+      user_set: userSet,
+    };
     return store.patch(currentRes, this.dataSrc).then(response => {
       if (!response) {
-        console.warn(`Error while leaving group ${this.dataSrc} for user ${this.userId}`);
+        console.warn(
+          `Error while leaving group ${this.dataSrc} for user ${this.userId}`,
+        );
         return;
       }
       this.goToNext(null);
-      const eventData = { detail: { resource: { "@id": this.dataSrc } }, bubbles: true };
+      const eventData = {
+        detail: { resource: { '@id': this.dataSrc } },
+        bubbles: true,
+      };
       this.element.dispatchEvent(new CustomEvent('save', eventData));
       this.element.dispatchEvent(new CustomEvent('memberRemoved', eventData)); // Deprecated. To remove in 0.15
       this.planRender();
-    })
+    });
   },
   switchMembership() {
     if (this.isMember) {
       return this.leaveGroup();
-    } else {
-      return this.joinGroup();
     }
+    return this.joinGroup();
   },
-  validateModal() { // Send method to validationMixin, used by the dialog modal and performAction method
+  validateModal() {
+    // Send method to validationMixin, used by the dialog modal and performAction method
     return this.switchMembership();
   },
   update() {
     this.render();
   },
-  async render(): Promise<void> {
+  render: trackRenderAsync(async function (): Promise<void> {
     await this.populate();
     let button = html``;
     if (this.isMember) {
       button = html`
-        <solid-ac-checker data-src="${this.dataSrc}"
-              permission="acl:Read"
-              class=${ifDefined(`${this.classSubmitButton ?  'leave ' + this.classSubmitButton: 'leave'}`)}
-            >
-          <button @click=${this.changeMembership.bind(this)}>${this.dataLeaveLabel || this.t("solid-leave-group.button")}</button>
-          ${this.getModalDialog()}
-        </solid-ac-checker>
-        `;
+          <solid-ac-checker data-src="${this.dataSrc}"
+                permission="acl:Read"
+                class=${ifDefined(`${this.classSubmitButton ? `leave ${this.classSubmitButton}` : 'leave'}`)}
+              >
+            <button @click=${this.changeMembership.bind(this)}>${this.dataLeaveLabel || this.t('solid-leave-group.button')}</button>
+            ${this.getModalDialog()}
+          </solid-ac-checker>
+          `;
     } else {
       button = html`
-        <solid-ac-checker data-src="${this.dataSrc}"
-              permission="acl:Read"
-              class=${ifDefined(`${this.classSubmitButton ?  'join ' + this.classSubmitButton: 'join'}`)}
-            >
-          <button @click=${this.changeMembership.bind(this)}>${this.dataJoinLabel || this.t("solid-join-group.button")}</button>
-          ${this.getModalDialog()}
-        </solid-ac-checker>
-        `;
+          <solid-ac-checker data-src="${this.dataSrc}"
+                permission="acl:Read"
+                class=${ifDefined(`${this.classSubmitButton ? `join ${this.classSubmitButton}` : 'join'}`)}
+              >
+            <button @click=${this.changeMembership.bind(this)}>${this.dataJoinLabel || this.t('solid-join-group.button')}</button>
+            ${this.getModalDialog()}
+          </solid-ac-checker>
+          `;
     }
     render(button, this.element);
-  }
+  }, 'SolidMembership:render'),
 };
 
-Sib.register(SolidMembership);
\ No newline at end of file
+Sib.register(SolidMembership);
diff --git a/src/components/solid-table.ts b/src/components/solid-table.ts
index 519733c805d5fc98c62b3985c284273ab7cade24..0718f5fd81e3762d95791aff303cd8276b0803ee 100644
--- a/src/components/solid-table.ts
+++ b/src/components/solid-table.ts
@@ -1,21 +1,23 @@
-import type { Resource } from '../mixins/interfaces';
-import { Sib } from '../libs/Sib';
-import { store } from '../libs/store/store';
-import { WidgetMixin } from '../mixins/widgetMixin';
-import { ListMixin } from '../mixins/listMixin';
-import { StoreMixin } from '../mixins/storeMixin';
-import { PaginateMixin } from '../mixins/paginateMixin';
-import { FilterMixin } from '../mixins/filterMixin';
-import { CounterMixin } from '../mixins/counterMixin';
-import { SorterMixin } from '../mixins/sorterMixin';
-import { GrouperMixin } from '../mixins/grouperMixin';
-import { FederationMixin } from '../mixins/federationMixin';
-import { HighlighterMixin } from '../mixins/highlighterMixin';
-import { RequiredMixin } from '../mixins/requiredMixin';
+import { Sib } from '../libs/Sib.ts';
+import { store } from '../libs/store/store.ts';
+import { CounterMixin } from '../mixins/counterMixin.ts';
+import { FederationMixin } from '../mixins/federationMixin.ts';
+import { FilterMixin } from '../mixins/filterMixin.ts';
+import { GrouperMixin } from '../mixins/grouperMixin.ts';
+import { HighlighterMixin } from '../mixins/highlighterMixin.ts';
+import type { Resource } from '../mixins/interfaces.ts';
+import { ListMixin } from '../mixins/listMixin.ts';
+import { PaginateMixin } from '../mixins/paginateMixin.ts';
+import { RequiredMixin } from '../mixins/requiredMixin.ts';
+import { SorterMixin } from '../mixins/sorterMixin.ts';
+import { StoreMixin } from '../mixins/storeMixin.ts';
+import { WidgetMixin } from '../mixins/widgetMixin.ts';
 
-import { html, render } from 'lit-html';
-import { until } from 'lit-html/directives/until';
-import { spread } from '../libs/lit-helpers';
+import { html, render } from 'lit';
+import { until } from 'lit/directives/until.js';
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+import { spread } from '../libs/lit-helpers.ts';
+import { trackRenderAsync } from '../logger.ts';
 
 export const SolidTable = {
   name: 'solid-table',
@@ -46,6 +48,9 @@ export const SolidTable = {
       default: null,
     },
   },
+  initialState: {
+    resources: [],
+  },
   get parentElement(): string {
     return 'table';
   },
@@ -57,8 +62,11 @@ export const SolidTable = {
   },
   get selectedLines() {
     if (this.selectable === null) return [];
-    return (Array.from(this.element.querySelectorAll('input[data-selection]:checked')) as Element[])
-      .map(e => e?.closest('[data-resource]')?.getAttribute('data-resource'));
+    return (
+      Array.from(
+        this.element.querySelectorAll('input[data-selection]:checked'),
+      ) as Element[]
+    ).map(e => e?.closest('[data-resource]')?.getAttribute('data-resource'));
   },
   /**
    * Select all lines
@@ -66,7 +74,11 @@ export const SolidTable = {
    */
   selectAll(e) {
     if (this.selectable === null) return;
-    for (const checkbox of Array.from(this.element.querySelectorAll('input[data-selection]') as HTMLInputElement[])) {
+    for (const checkbox of Array.from(
+      this.element.querySelectorAll(
+        'input[data-selection]',
+      ) as HTMLInputElement[],
+    )) {
       checkbox.checked = e.target.checked;
     }
   },
@@ -75,7 +87,11 @@ export const SolidTable = {
    */
   unselectAll(): void {
     if (this.selectable === null) return;
-    for (const checkbox of Array.from(this.element.querySelectorAll('input[data-selection]') as HTMLInputElement[])) {
+    for (const checkbox of Array.from(
+      this.element.querySelectorAll(
+        'input[data-selection]',
+      ) as HTMLInputElement[],
+    )) {
       checkbox.checked = false;
     }
   },
@@ -86,7 +102,9 @@ export const SolidTable = {
   selectLines(lines: string[]) {
     if (this.selectable === null || lines.length === 0) return;
     for (const line of lines) {
-      const checkbox = this.element.querySelector(`[data-resource="${line}"] input[data-selection]`);
+      const checkbox = this.element.querySelector(
+        `[data-resource="${line}"] input[data-selection]`,
+      );
       if (checkbox) checkbox.checked = true;
     }
   },
@@ -95,13 +113,15 @@ export const SolidTable = {
    * @param field
    * @param resource
    */
-  async createCellWidget(field: string, resource: Resource) {
+  createCellWidget(field: string, resource: Resource) {
     // if regular widget
-    if (!this.element.hasAttribute('editable-' + field)) return this.createWidgetTemplate(field, resource, true);
+    if (!this.element.hasAttribute(`editable-${field}`))
+      return this.createWidgetTemplate(field, resource, true);
 
     // if editable widget
     const attributes = {};
-    const formWidgetAttributes = [ // attributes to give to the form widget
+    const formWidgetAttributes = [
+      // attributes to give to the form widget
       'range',
       'enum',
       'placeholder',
@@ -113,16 +133,19 @@ export const SolidTable = {
       'max',
       'pattern',
       'title',
-      'widget'
+      'widget',
     ];
-    for (let attr of formWidgetAttributes) this.addToAttributes(`${attr}-${field}`, `${attr}-${field}`,  attributes)
+    for (const attr of formWidgetAttributes)
+      this.addToAttributes(`${attr}-${field}`, `${attr}-${field}`, attributes);
 
-    const formAttributes = [ // attributes to give to the form
+    const formAttributes = [
+      // attributes to give to the form
       'class',
       'submit-button',
-      'next'
+      'next',
     ];
-    for (let attr of formAttributes) this.addToAttributes(`${attr}-${field}`, attr,  attributes)
+    for (const attr of formAttributes)
+      this.addToAttributes(`${attr}-${field}`, attr, attributes);
 
     return html`
       <solid-form
@@ -139,18 +162,12 @@ export const SolidTable = {
    * @param fields
    */
   getHeader(fields: string[]) {
-    let template = html`
+    const template = html`
       <tr>
-        ${this.selectable !== null ? html`
-        <th>
-          <input type="checkbox" @change="${this.selectAll.bind(this)}" />
-        </th>` : ''}
-        ${fields.map((field: string) => html`
-          <th>
-            ${this.element.hasAttribute('label-'+field) ? this.element.getAttribute('label-'+field) : field}
-        </th>`)}
+        ${this.selectable !== null ? html`<th><input type="checkbox" @change="${this.selectAll.bind(this)}" /></th>` : ''}
+        ${fields.map((field: string) => html`<th>${this.element.hasAttribute(`label-${field}`) ? this.element.getAttribute(`label-${field}`) : field}</th>`)}
       </tr>
-    `
+    `;
     return template;
   },
   /**
@@ -160,15 +177,12 @@ export const SolidTable = {
    */
   async getChildTemplate(resourceId: string, fields) {
     const resource = await store.getData(resourceId, this.context);
-    let template = html`
+    const template = html`
       <tr data-resource="${resourceId}">
-        ${this.selectable !== null ? html`
-        <td>
-          <input type="checkbox" data-selection />
-        </td>` : ''}
+        ${this.selectable !== null ? html`<td><input type="checkbox" data-selection /></td>` : ''}
         ${fields.map((field: string) => html`<td>${until(this.createCellWidget(field, resource))}</td>`)}
       </tr>
-    `
+    `;
     return template;
   },
 
@@ -179,10 +193,7 @@ export const SolidTable = {
   async appendSingleElt(parent: HTMLElement): Promise<void> {
     const fields = await this.getFields();
 
-    const template = html`
-      ${this.header !== null ? this.getHeader(fields) : ''}
-      ${until(this.getChildTemplate(this.resource['@id'], fields))}
-    `;
+    const template = html`${this.header !== null ? this.getHeader(fields) : ''}${until(this.getChildTemplate(this.resource['@id'], fields))}`;
     render(template, parent);
   },
 
@@ -195,21 +206,18 @@ export const SolidTable = {
    * @param div
    * @param context
    */
-  async renderDOM(
+  renderDOM: trackRenderAsync(async function (
     resources: object[],
-    listPostProcessors: Function[],
+    listPostProcessors: PostProcessorRegistry,
     div: HTMLElement,
     context: string,
   ) {
     const selectedLines = [...this.selectedLines]; // save selected lines before moving them
     const fields = await this.getFields();
     const childTemplates = await Promise.all(
-      resources.map(r => r ? this.getChildTemplate(r['@id'], fields) : null)
+      resources.map(r => (r ? this.getChildTemplate(r['@id'], fields) : null)),
     );
-    const template = html`
-      ${this.header !== null ? this.getHeader(fields) : ''}
-      ${childTemplates}
-    `; // create a child template for each resource
+    const template = html`${this.header !== null ? this.getHeader(fields) : ''}${childTemplates}`; // create a child template for each resource
     render(template, div);
 
     // Re-select the right lines
@@ -218,13 +226,8 @@ export const SolidTable = {
 
     const nextProcessor = listPostProcessors.shift();
     if (nextProcessor)
-      await nextProcessor(
-        resources,
-        listPostProcessors,
-        div,
-        context
-      );
-  },
+      await nextProcessor(resources, listPostProcessors, div, context);
+  }, 'SolidTable:renderDom'),
 };
 
 Sib.register(SolidTable);
diff --git a/src/components/solid-widget.ts b/src/components/solid-widget.ts
index 09a2853d40ee898bcac95647fbcf01f2151aed4f..cad09985431f9b338fdc84ca2ab6fa8b79c90ba2 100644
--- a/src/components/solid-widget.ts
+++ b/src/components/solid-widget.ts
@@ -1,11 +1,11 @@
-import { Sib } from '../libs/Sib';
-import { StoreMixin } from '../mixins/storeMixin';
-import { BaseWidgetMixin } from '../new-widgets/baseWidgetMixin';
-import { FormMixin } from '../new-widgets/templatesDependencies/formMixin';
-import { ActionMixin } from '../new-widgets/attributeMixins/actionMixin';
-import { evalTemplateString } from '../libs/helpers';
-import { html, render } from 'lit-html';
-import { unsafeHTML } from 'lit-html/directives/unsafe-html';
+import { html, render } from 'lit';
+import { unsafeHTML } from 'lit/directives/unsafe-html.js';
+import { Sib } from '../libs/Sib.ts';
+import { evalTemplateString } from '../libs/helpers.ts';
+import { StoreMixin } from '../mixins/storeMixin.ts';
+import { ActionMixin } from '../new-widgets/attributeMixins/actionMixin.ts';
+import { BaseWidgetMixin } from '../new-widgets/baseWidgetMixin.ts';
+import { FormMixin } from '../new-widgets/templatesDependencies/formMixin.ts';
 
 export const SolidWidget = {
   name: 'solid-widget',
@@ -13,35 +13,33 @@ export const SolidWidget = {
   attributes: {
     name: {
       type: String,
-      default: "",
-      required: true
-    }
+      default: '',
+      required: true,
+    },
   },
   attached(): void {
     if (!this.name) return;
     const template = this.template;
     const newWidget = {
       name: this.name,
-      use: [
-        BaseWidgetMixin,
-        StoreMixin,
-        FormMixin,
-        ActionMixin
-      ],
+      use: [BaseWidgetMixin, StoreMixin, FormMixin, ActionMixin],
       attributes: {
         label: {
           type: String,
           default: '',
           callback: function (newValue: string) {
             this.addToAttributes(newValue, 'label');
-          }
+          },
         },
       },
       get template() {
-        return () => this.evalTemplate(template).then((tpl: string) => html`${unsafeHTML(tpl)}`)
+        return () =>
+          this.evalTemplate(template).then(
+            (tpl: string) => html`${unsafeHTML(tpl)}`,
+          );
       },
       evalTemplate(template: string) {
-        const tpl =  evalTemplateString(template, {
+        const tpl = evalTemplateString(template, {
           name: this.name,
           value: this.value || this.resource || '',
           src: this.src,
@@ -54,14 +52,16 @@ export const SolidWidget = {
         render(await template, this.element);
       },
       // For form widgets, handle nested solid-form
+      // TODO: type custom elements
       getValueFromElement(element: any) {
-        if (element.tagName === "SOLID-FORM") return element.component.value; // nested solid-form
-        else if (element.component) return element.component.getValue(); // form widget
+        if (element.tagName === 'SOLID-FORM') return element.component.value; // nested solid-form
+        if (element.component) return element.component.getValue(); // form widget
         return element.value; // input
       },
-      updateDOM() { // override StoreMixin method to launch render when resource fetched
+      updateDOM() {
+        // override StoreMixin method to launch render when resource fetched
         this.planRender();
-      }
+      },
     };
 
     Sib.register(newWidget); // and register component
@@ -72,7 +72,7 @@ export const SolidWidget = {
   get childTemplate(): string | null {
     const child = this.element.querySelector('template[data-range]');
     return child ? child.innerHTML : null;
-  }
+  },
 };
 
-Sib.register(SolidWidget);
\ No newline at end of file
+Sib.register(SolidWidget);
diff --git a/src/index.ts b/src/index.ts
index bc7b32ce4a7ab1c6716ea4243d738e33227f8d34..28f6c5c40e42b551d819badef4828f92e651ceb9 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,55 +1,54 @@
-import "./libs/polyfills.js";
+import './libs/polyfills.js';
+import { SolidAcChecker } from './components/solid-ac-checker.ts';
+import { SolidDelete } from './components/solid-delete.ts';
 // Components
-import { SolidDisplay } from './components/solid-display';
-import { SolidForm } from './components/solid-form';
-import { SolidFormSearch } from './components/solid-form-search';
-import { SolidWidget } from './components/solid-widget';
-import { SolidAcChecker } from './components/solid-ac-checker';
-import { SolidDelete } from './components/solid-delete';
-import { SolidLang } from './components/solid-lang';
-import { SolidTable } from './components/solid-table';
-import { SolidMap } from './components/solid-map';
-import { SolidMembership } from './components/solid-membership';
-import { SolidMemberDelete } from './components/solid-member-delete';
-import { SolidMemberAdd } from './components/solid-member-add';
+import { SolidDisplay } from './components/solid-display.ts';
+import { SolidFormSearch } from './components/solid-form-search.ts';
+import { SolidForm } from './components/solid-form.ts';
+import { SolidLang } from './components/solid-lang.ts';
+import { SolidMemberAdd } from './components/solid-member-add.ts';
+import { SolidMemberDelete } from './components/solid-member-delete.ts';
+import { SolidMembership } from './components/solid-membership.ts';
+import { SolidTable } from './components/solid-table.ts';
+import { SolidWidget } from './components/solid-widget.ts';
 
 // Mixins
-import { CounterMixin } from './mixins/counterMixin';
-import { FederationMixin } from './mixins/federationMixin';
-import { FilterMixin } from './mixins/filterMixin';
-import { GrouperMixin } from './mixins/grouperMixin';
-import { HighlighterMixin } from './mixins/highlighterMixin';
-import { ListMixin } from './mixins/listMixin';
-import { NextMixin } from './mixins/nextMixin';
-import { PaginateMixin } from './mixins/paginateMixin';
-import { RequiredMixin } from './mixins/requiredMixin';
-import { SorterMixin } from './mixins/sorterMixin';
-import { StoreMixin } from './mixins/storeMixin';
-import { TranslationMixin } from './mixins/translationMixin';
-import { ValidationMixin } from './mixins/validationMixin';
-import { WidgetMixin } from './mixins/widgetMixin';
+import { CounterMixin } from './mixins/counterMixin.ts';
+import { FederationMixin } from './mixins/federationMixin.ts';
+import { FilterMixin } from './mixins/filterMixin.ts';
+import { GrouperMixin } from './mixins/grouperMixin.ts';
+import { HighlighterMixin } from './mixins/highlighterMixin.ts';
+import { ListMixin } from './mixins/listMixin.ts';
+import { NextMixin } from './mixins/nextMixin.ts';
+import { PaginateMixin } from './mixins/paginateMixin.ts';
+import { RequiredMixin } from './mixins/requiredMixin.ts';
+import { SorterMixin } from './mixins/sorterMixin.ts';
+import { StoreMixin } from './mixins/storeMixin.ts';
+import { TranslationMixin } from './mixins/translationMixin.ts';
+import { ValidationMixin } from './mixins/validationMixin.ts';
+import { WidgetMixin } from './mixins/widgetMixin.ts';
 
+import * as AttributeMixins from './new-widgets/attributeMixins/index.ts';
+import { BaseWidgetMixin } from './new-widgets/baseWidgetMixin.ts';
+import * as CallbackMixins from './new-widgets/callbackMixins/index.ts';
 // New widgets system
-import { newWidgetFactory } from './new-widgets/new-widget-factory';
-import { BaseWidgetMixin } from './new-widgets/baseWidgetMixin';
-import * as AttributeMixins from './new-widgets/attributeMixins';
-import * as CallbackMixins from './new-widgets/callbackMixins';
-import * as TemplateAdditionMixins from './new-widgets/templateAdditionMixins';
-import * as Templates from './new-widgets/templates';
-import * as TemplatesDependenciesMixins from './new-widgets/templatesDependencies';
+import { newWidgetFactory } from './new-widgets/new-widget-factory.ts';
+import * as TemplateAdditionMixins from './new-widgets/templateAdditionMixins/index.ts';
+import * as Templates from './new-widgets/templates/index.ts';
+import * as TemplatesDependenciesMixins from './new-widgets/templatesDependencies/index.ts';
 
+import { Sib } from './libs/Sib.ts';
+import * as Helpers from './libs/helpers.ts';
 // Libs
-import { store, base_context as baseContext } from './libs/store/store';
-import { Sib } from './libs/Sib';
-import SolidTemplateElement from './solid-template-element';
-import { widgetFactory } from './widgets/widget-factory';
-import * as Helpers from './libs/helpers';
+import { base_context as baseContext, store } from './libs/store/store.ts';
+import SolidTemplateElement from './solid-template-element.ts';
+import { widgetFactory } from './widgets/widget-factory.ts';
 
 // lit-html
-import { html, render } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
-import { until } from 'lit-html/directives/until';
-import { unsafeHTML } from 'lit-html/directives/unsafe-html';
+import { html, render } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { unsafeHTML } from 'lit/directives/unsafe-html.js';
+import { until } from 'lit/directives/until.js';
 
 export {
   // Components
@@ -61,11 +60,9 @@ export {
   SolidDelete,
   SolidLang,
   SolidTable,
-  SolidMap,
   SolidMembership,
   SolidMemberDelete,
   SolidMemberAdd,
-
   // Mixins
   CounterMixin,
   FederationMixin,
@@ -81,14 +78,12 @@ export {
   TranslationMixin,
   ValidationMixin,
   WidgetMixin,
-
   // New widgets system
   AttributeMixins,
   CallbackMixins,
   TemplateAdditionMixins,
   TemplatesDependenciesMixins,
   Templates,
-
   // Libs
   store,
   Sib,
@@ -98,11 +93,10 @@ export {
   BaseWidgetMixin,
   Helpers,
   baseContext,
-
   // lit-html
   html,
   render,
   ifDefined,
   until,
-  unsafeHTML
-}
\ No newline at end of file
+  unsafeHTML,
+};
diff --git a/src/libs/Component.ts b/src/libs/Component.ts
index e655a190b121a10725782304e8ec84d151dc6ee2..21e4b49d51294adec5b0b2c091c0e26fc2567233 100644
--- a/src/libs/Component.ts
+++ b/src/libs/Component.ts
@@ -1,15 +1,18 @@
-import type { ComponentInterface } from "./interfaces.js";
+import { Profiler } from '../logger.ts';
+import type { ComponentInterface } from './interfaces.js';
 
 export abstract class Component implements ComponentInterface {
   public element: HTMLElement;
+  public profiler: Profiler;
 
   constructor(element: HTMLElement) {
     this.element = element;
+    this.profiler = new Profiler();
   }
 
   created() {}
   attached() {}
   detached() {}
 
-  attributesCallback(_key: string, _value: any, _oldValue: any):void {}
+  attributesCallback(_key: string, _value: unknown, _oldValue: unknown): void {}
 }
diff --git a/src/libs/ComponentFactory.ts b/src/libs/ComponentFactory.ts
index 3f0228ea1dbea7de05f82711f9ecb240370bae78..373cdf7ea285a21f667e8c8c3c8fc724a720aaae 100644
--- a/src/libs/ComponentFactory.ts
+++ b/src/libs/ComponentFactory.ts
@@ -1,56 +1,78 @@
-import { Compositor } from './Compositor';
-import { Component } from './Component';
+import { Component } from './Component.ts';
+import { Compositor } from './Compositor.ts';
 import type {
-  MixinStaticInterface,
+  AccessorStaticInterface,
+  ArrayOfHooksInterface,
   AttributesDefinitionInterface,
   ComponentConstructorInterface,
-  ArrayOfHooksInterface,
-  AccessorStaticInterface
-} from './interfaces';
+  MixinStaticInterface,
+} from './interfaces.ts';
 
-export class ComponentFactory {
-  public static build(component: MixinStaticInterface): ComponentConstructorInterface {
-    const { initialState, attributes, methods, hooks, accessors, name } = Compositor.merge(component, Compositor.mergeMixin(component));
+export const ComponentFactory = {
+  build(component: MixinStaticInterface): ComponentConstructorInterface {
+    const { initialState, attributes, methods, hooks, accessors, name } =
+      Compositor.merge(component, Compositor.mergeMixin(component));
 
     let componentConstructor = class extends Component {};
 
-    componentConstructor = ComponentFactory.bindInitialState(componentConstructor, initialState);
-    componentConstructor = ComponentFactory.bindAttributes(componentConstructor, attributes);
-    componentConstructor = ComponentFactory.bindMethods(componentConstructor, methods);
-    componentConstructor = ComponentFactory.bindAccessors(componentConstructor, accessors);
-    componentConstructor = ComponentFactory.bindHooks(componentConstructor, hooks);
+    componentConstructor = ComponentFactory.bindInitialState(
+      componentConstructor,
+      initialState,
+    );
+    componentConstructor = ComponentFactory.bindAttributes(
+      componentConstructor,
+      attributes,
+    );
+    componentConstructor = ComponentFactory.bindMethods(
+      componentConstructor,
+      methods,
+    );
+    componentConstructor = ComponentFactory.bindAccessors(
+      componentConstructor,
+      accessors,
+    );
+    componentConstructor = ComponentFactory.bindHooks(
+      componentConstructor,
+      hooks,
+    );
 
     Reflect.defineProperty(componentConstructor, 'name', {
       value: name,
     });
 
     return componentConstructor;
-  }
-
-  protected static bindInitialState(componentConstructor: ComponentConstructorInterface, initialState: object | undefined):any {
+  },
+  bindInitialState(
+    componentConstructor: ComponentConstructorInterface,
+    initialState?: object,
+  ): ComponentConstructorInterface {
     if (initialState) {
-      Reflect.ownKeys(initialState).forEach(key => {
+      for (const key of Reflect.ownKeys(initialState)) {
         Reflect.defineProperty(componentConstructor.prototype, key, {
           enumerable: true,
           writable: true,
           value: initialState[key],
         });
-      });
+      }
     }
 
     return componentConstructor;
-  }
-
-  protected static bindAttributes(componentConstructor: ComponentConstructorInterface, attributes: AttributesDefinitionInterface | undefined): ComponentConstructorInterface {
+  },
+  bindAttributes(
+    componentConstructor: ComponentConstructorInterface,
+    attributes?: AttributesDefinitionInterface,
+  ): ComponentConstructorInterface {
     if (attributes) {
-      const attributesList = Reflect.ownKeys(attributes).map(key => String(key));
+      const attributesList = Reflect.ownKeys(attributes).map(key =>
+        String(key),
+      );
       const attributesCallback = {};
 
-      attributesList.forEach(key => {
+      for (const key of attributesList) {
         const { default: def, type, required, callback } = attributes[key];
 
-        let fromType;
-        let toType;
+        let fromType: (value: string) => unknown;
+        let toType: (value: unknown) => unknown;
 
         switch (type) {
           case String:
@@ -75,7 +97,9 @@ export class ComponentFactory {
             break;
         }
 
-        const attribute = key.replace(/([a-z0-9])([A-Z0-9])/g, '$1-$2').toLowerCase();
+        const attribute = key
+          .replace(/([a-z0-9])([A-Z0-9])/g, '$1-$2')
+          .toLowerCase();
 
         Reflect.defineProperty(componentConstructor.prototype, key, {
           enumerable: true,
@@ -107,43 +131,61 @@ export class ComponentFactory {
         if (callback && typeof callback === 'function') {
           attributesCallback[key] = callback;
         }
-      });
+      }
 
       Reflect.defineProperty(componentConstructor, 'observedAttributes', {
-        get: () => attributesList.map(attr => attr.replace(/([a-z0-9])([A-Z0-9])/g, '$1-$2').toLowerCase()),
+        get: () =>
+          attributesList.map(attr =>
+            attr.replace(/([a-z0-9])([A-Z0-9])/g, '$1-$2').toLowerCase(),
+          ),
       });
 
-      Reflect.defineProperty(componentConstructor.prototype, 'attributesCallback', {
-        value: function(key, newValue, oldValue) {
-          if (key in attributesCallback) {
-            Reflect.apply(attributesCallback[key], this, [newValue, oldValue]);
-          }
-        }
-      });
+      Reflect.defineProperty(
+        componentConstructor.prototype,
+        'attributesCallback',
+        {
+          value: function (key, newValue, oldValue) {
+            if (key in attributesCallback) {
+              Reflect.apply(attributesCallback[key], this, [
+                newValue,
+                oldValue,
+              ]);
+            }
+          },
+        },
+      );
 
-      Reflect.defineProperty(componentConstructor.prototype, 'attributesCallback', attributesCallback);
+      Reflect.defineProperty(
+        componentConstructor.prototype,
+        'attributesCallback',
+        attributesCallback,
+      );
     }
     return componentConstructor;
-  }
-
-  protected static bindAccessors(componentConstructor: ComponentConstructorInterface, accessors: AccessorStaticInterface): ComponentConstructorInterface {
+  },
+  bindAccessors(
+    componentConstructor: ComponentConstructorInterface,
+    accessors?: AccessorStaticInterface,
+  ): ComponentConstructorInterface {
     if (accessors) {
-      Object.keys(accessors).forEach(property => {
+      for (const property of Object.keys(accessors)) {
         Reflect.defineProperty(componentConstructor.prototype, property, {
           get: function () {
-            return Reflect.apply(accessors[property].get, this, [])
+            return Reflect.apply(accessors[property].get, this, []);
           },
           set: function (value) {
-            return Reflect.apply(accessors[property].set, this, [value])
-          }
+            return Reflect.apply(accessors[property].set, this, [value]);
+          },
         });
-      });
+      }
     }
     return componentConstructor;
-  }
-
-  protected static bindMethods(componentConstructor: ComponentConstructorInterface, methods: Map<string, Function>): ComponentConstructorInterface {
-    methods.forEach((method, methodName: string) => {
+  },
+  bindMethods(
+    componentConstructor: ComponentConstructorInterface,
+    methods: Map<string, Function>,
+  ): ComponentConstructorInterface {
+    methods.forEach((method, methodName) => {
       Reflect.defineProperty(componentConstructor.prototype, methodName, {
         value: function (...args) {
           return Reflect.apply(method, this, args);
@@ -151,32 +193,34 @@ export class ComponentFactory {
       });
     });
     return componentConstructor;
-  }
-
-  protected static bindHooks(componentConstructor: ComponentConstructorInterface, hooks: ArrayOfHooksInterface): ComponentConstructorInterface {
+  },
+  bindHooks(
+    componentConstructor: ComponentConstructorInterface,
+    hooks: ArrayOfHooksInterface,
+  ): ComponentConstructorInterface {
     Reflect.defineProperty(componentConstructor.prototype, 'created', {
-      value: function() {
-        hooks.created.forEach(hook => {
+      value: function () {
+        for (const hook of hooks.created) {
           Reflect.apply(hook, this, []);
-        });
+        }
       },
     });
 
     Reflect.defineProperty(componentConstructor.prototype, 'attached', {
-      value: function() {
-        hooks.attached.forEach(hook => {
+      value: function () {
+        for (const hook of hooks.attached) {
           Reflect.apply(hook, this, []);
-        });
+        }
       },
     });
 
     Reflect.defineProperty(componentConstructor.prototype, 'detached', {
-      value: function() {
-        hooks.detached.forEach(hook => {
+      value: function () {
+        for (const hook of hooks.detached) {
           Reflect.apply(hook, this, []);
-        });
+        }
       },
     });
     return componentConstructor;
-  }
-}
+  },
+};
diff --git a/src/libs/Compositor.ts b/src/libs/Compositor.ts
index 829e2698da85ec2d7b5e68db39726ce059c7d0e7..b0a07842d2f399d458d7339433fccd65c8a2f525 100644
--- a/src/libs/Compositor.ts
+++ b/src/libs/Compositor.ts
@@ -1,44 +1,43 @@
 import type {
-  MixinStaticInterface,
-  ComponentStaticInterface,
-  AttributesDefinitionInterface,
+  AccessorStaticInterface,
   ArrayOfHooksInterface,
-  AccessorStaticInterface
-} from './interfaces';
+  AttributesDefinitionInterface,
+  ComponentStaticInterface,
+  MixinStaticInterface,
+} from './interfaces.ts';
 
 const HOOKS = ['created', 'attached', 'detached'];
-const API = [
-  'name',
-  'use',
-  'attributes',
-  'initialState',
-  ...HOOKS,
-];
+const API = ['name', 'use', 'attributes', 'initialState', ...HOOKS];
 
-export class Compositor {
-  public static merge(component: MixinStaticInterface, mixins: MixinStaticInterface[]): ComponentStaticInterface {
+export const Compositor = {
+  merge(
+    component: MixinStaticInterface,
+    mixins: MixinStaticInterface[],
+  ): ComponentStaticInterface {
     return {
       name: component.name,
-      attributes: Compositor.mergeAttributes([ component, ...mixins ]),
-      initialState: Compositor.mergeInitialState([ component, ...mixins ]),
-      methods: Compositor.mergeMethods([ component, ...mixins]),
-      accessors: Compositor.mergeAccessors([ component, ...mixins]),
-      hooks: Compositor.mergeHooks([ component, ...mixins ]),
+      attributes: Compositor.mergeAttributes([component, ...mixins]),
+      initialState: Compositor.mergeInitialState([component, ...mixins]),
+      methods: Compositor.mergeMethods([component, ...mixins]),
+      accessors: Compositor.mergeAccessors([component, ...mixins]),
+      hooks: Compositor.mergeHooks([component, ...mixins]),
     };
-  }
-
-  public static mergeMixin(component: MixinStaticInterface): MixinStaticInterface[] {
-    function deepMergeMixin(mixinAccumulator: Map<MixinStaticInterface, MixinStaticInterface>, currentMixin: MixinStaticInterface) {
+  },
+  mergeMixin(component: MixinStaticInterface): MixinStaticInterface[] {
+    function deepMergeMixin(
+      mixinAccumulator: Map<MixinStaticInterface, MixinStaticInterface>,
+      currentMixin: MixinStaticInterface,
+    ) {
       const { use: currentMixins } = currentMixin;
       if (currentMixins) {
-        currentMixins.forEach(mix => {
+        for (const mix of currentMixins) {
           if (!mixinAccumulator.has(mix)) {
             mixinAccumulator.set(mix, mix);
             deepMergeMixin(mixinAccumulator, mix);
           } else {
             console.warn(`Duplicate mixin import (${mix.name})`);
           }
-        });
+        }
       }
     }
 
@@ -46,88 +45,75 @@ export class Compositor {
     deepMergeMixin(mixins, component);
 
     return Array.from(mixins.values());
-  }
-
-  public static mergeAttributes(mixins: MixinStaticInterface[]): AttributesDefinitionInterface {
+  },
+  mergeAttributes(
+    mixins: MixinStaticInterface[],
+  ): AttributesDefinitionInterface {
     let attributes = {};
 
-    mixins.forEach(mixin => {
-      if (!!mixin.attributes) {
-        attributes = {...mixin.attributes, ...attributes };
+    for (const mixin of mixins) {
+      if (mixin.attributes) {
+        attributes = { ...mixin.attributes, ...attributes };
       }
-    });
+    }
 
     return attributes;
-  }
+  },
+  mergeInitialState(mixins: MixinStaticInterface[]) {
+    let initialState: any = {};
 
-  public static mergeInitialState(mixins: MixinStaticInterface[]): any {
-    let initialState = {};
-
-    mixins.forEach(mixin => {
-      if (!!mixin.initialState) {
-        initialState = {...mixin.initialState, ...initialState };
-      }
-    });
+    for (const mixin of mixins) {
+      if (!mixin.initialState) continue;
+      initialState = { ...mixin.initialState, ...initialState };
+    }
 
     return initialState;
-  }
-
-  public static mergeHooks(mixins: MixinStaticInterface[]): ArrayOfHooksInterface {
+  },
+  mergeHooks(mixins: MixinStaticInterface[]): ArrayOfHooksInterface {
     const hooks = {
       created: [],
       attached: [],
       detached: [],
     };
-    mixins
-      .reverse()
-      .forEach(mixin => {
-        HOOKS.forEach(hookName => {
-          if(!!mixin[hookName] && typeof mixin[hookName] === 'function') {
-            hooks[hookName].push(mixin[hookName]);
-          }
-        });
-      });
-    
+    for (const mixin of mixins.reverse()) {
+      for (const hookName of HOOKS) {
+        if (!!mixin[hookName] && typeof mixin[hookName] === 'function') {
+          hooks[hookName].push(mixin[hookName]);
+        }
+      }
+    }
 
     return hooks;
-  }
-
-  public static mergeMethods(mixins: MixinStaticInterface[]): Map<any, any> {
+  },
+  mergeMethods(mixins: MixinStaticInterface[]): Map<any, any> {
     const methods = new Map();
 
-    mixins.reverse().forEach(mixin => {
-      const keys = Reflect
-        .ownKeys(mixin)
-        .filter(key => (
-          typeof key === 'string' &&
-          API.indexOf(key) < 0 &&
-          !Object.getOwnPropertyDescriptor(mixin, key)!.get &&
-          !Object.getOwnPropertyDescriptor(mixin, key)!.set &&
-          typeof mixin[key] === 'function'));
-
-      keys.forEach(key => {
+    for (const mixin of mixins.reverse()) {
+      for (const key of Reflect.ownKeys(mixin)) {
+        if (typeof key !== 'string') continue;
+        if (API.includes(key)) continue;
+        const descriptor = Object.getOwnPropertyDescriptor(mixin, key);
+        if (descriptor?.get || descriptor?.set) continue;
+        if (typeof mixin[key] !== 'function') continue;
         methods.set(key, mixin[key]);
-      });
-    });
+      }
+    }
     return methods;
-  }
-
-  public static mergeAccessors(mixins: MixinStaticInterface[]): AccessorStaticInterface {
+  },
+  mergeAccessors(mixins: MixinStaticInterface[]): AccessorStaticInterface {
     const accessors = {};
-    mixins.reverse().forEach(mixin => {
-      Reflect
-      .ownKeys(mixin)
-      .filter(key => (
-        typeof key === 'string' &&
-        API.indexOf(key) < 0 &&
-        (Object.getOwnPropertyDescriptor(mixin, key)!.get || Object.getOwnPropertyDescriptor(mixin, key)!.set)
-      ))
-      .forEach(prop => {
+    for (const mixin of mixins.reverse()) {
+      for (const prop of Reflect.ownKeys(mixin)) {
+        if (typeof prop !== 'string') continue;
+        if (API.includes(prop)) continue;
+        const descriptor = Object.getOwnPropertyDescriptor(mixin, prop);
+        if (!descriptor) continue;
+        if (!descriptor.get && !descriptor.set) continue;
         accessors[prop] = { ...accessors[prop] };
-        if (Reflect.getOwnPropertyDescriptor(mixin, prop)!.get) accessors[prop].get = Reflect.getOwnPropertyDescriptor(mixin, prop)!.get;
-        if (Reflect.getOwnPropertyDescriptor(mixin, prop)!.set) accessors[prop].set = Reflect.getOwnPropertyDescriptor(mixin, prop)!.set;
-      });
-    });
+        if (descriptor.get) accessors[prop].get = descriptor.get;
+        if (descriptor.set) accessors[prop].set = descriptor.set;
+      }
+    }
     return accessors;
-  }
-}
+  },
+};
diff --git a/src/libs/PostProcessorRegistry.ts b/src/libs/PostProcessorRegistry.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ef855e17b13ef66017cdd02e8134ddd75df8f289
--- /dev/null
+++ b/src/libs/PostProcessorRegistry.ts
@@ -0,0 +1,76 @@
+export type PostProcessor = {
+  name: string;
+  fn: Function;
+};
+
+export class PostProcessorRegistry {
+  private currentPostProcessors: PostProcessor[];
+
+  constructor(currentPostProcessors: PostProcessor[] = []) {
+    this.currentPostProcessors = [...currentPostProcessors];
+  }
+
+  public attach(callback: Function, callbackName: string): void {
+    this.currentPostProcessors.push({ name: callbackName, fn: callback });
+  }
+
+  public getPostProcessors(): PostProcessor[] {
+    return this.currentPostProcessors;
+  }
+
+  public printCurrentCallbacks(): void {
+    if (this.currentPostProcessors.length === 0) {
+      console.log('No post-processors registered.');
+    } else {
+      console.log('Registered post-processors:');
+      for (const postProcessor of this.currentPostProcessors) {
+        console.log(`- ${postProcessor.name}`);
+      }
+    }
+  }
+
+  public getFormattedCallbacks(): string {
+    if (this.currentPostProcessors.length === 0) {
+      return 'No post-processors registered.';
+    }
+    let formattedText = 'Registered post-processors:\n';
+    for (const postProcessor of this.currentPostProcessors) {
+      formattedText += `- ${postProcessor.name}\n`;
+    }
+    return formattedText.trim();
+  }
+
+  static printFormattedCallbacks(
+    currentPostProcessors: PostProcessor[],
+  ): string {
+    if (currentPostProcessors.length === 0) {
+      return 'No post-processors registered.';
+    }
+    let formattedText = 'Registered post-processors:\n';
+    for (const postProcessor of currentPostProcessors) {
+      formattedText += `- ${postProcessor.name}\n`;
+    }
+    return formattedText.trim();
+  }
+
+  public whichCallbackExecutedNext(): string {
+    if (this.currentPostProcessors.length === 0) {
+      return 'No post-processors registered.';
+    }
+    return `Next post-processor to be executed is: ${this.currentPostProcessors[0].name}`;
+  }
+
+  public deepCopy(): PostProcessorRegistry {
+    const copy = new PostProcessorRegistry(this.currentPostProcessors);
+    return copy;
+  }
+
+  public shift(): Function | undefined {
+    const res = this.currentPostProcessors.shift();
+
+    if (res) {
+      return res.fn;
+    }
+    return undefined;
+  }
+}
diff --git a/src/libs/Sib.ts b/src/libs/Sib.ts
index c11e6804357c2c0416e103b19e758b51314e15e6..2f45ac29612342796e7e45f74eb0730073d51f36 100644
--- a/src/libs/Sib.ts
+++ b/src/libs/Sib.ts
@@ -1,54 +1,46 @@
-import { ComponentFactory } from "./ComponentFactory.js";
-import { defineComponent } from "./helpers.js";
+import { ComponentFactory } from './ComponentFactory.js';
+import { defineComponent } from './helpers.js';
 import type {
-    ComponentConstructorInterface,
-    ComponentInterface,
-    MixinStaticInterface
-} from "./interfaces.js";
-
-export class Sib {
-    public static register(componentDefinition: MixinStaticInterface):void {
-        const component = ComponentFactory.build(componentDefinition);
-        const cls = this.toElement(component);
-        defineComponent(component.name, cls);
-    }
-
-    protected static toElement(component: ComponentConstructorInterface): typeof HTMLElement {
-        return class extends HTMLElement {
-            private _component: ComponentInterface | null = null;
-
-            constructor() {
-                super();
-                this.component = new component(this);
-                this.component.created();
-            }
-
-            get component(): ComponentInterface {
-                if (this._component === null) {
-                    throw new Error('No component found');
-                }
-                return this._component;
-            }
-            set component(component: ComponentInterface) {
-                this._component = component;
-            }
-
-            static get observedAttributes() {
-                return (<any>component).observedAttributes;
-            }
-
-            attributeChangedCallback(name, oldValue, newValue) {
-                const attr = name.replace(/([a-z0-9])-([a-z0-9])/g, (_c, p1, p2) => `${p1}${p2.toUpperCase()}`);
-                this.component.attributesCallback(attr, newValue, oldValue);
-            }
-
-            connectedCallback() {
-                this.component.attached();
-            }
-
-            disconnectedCallback() {
-                this.component.detached();
-            }
-        }
-    }
-}
+  ComponentConstructorInterface,
+  ComponentInterface,
+  MixinStaticInterface,
+} from './interfaces.js';
+
+export const Sib = {
+  register(componentDefinition: MixinStaticInterface): void {
+    const component = ComponentFactory.build(componentDefinition);
+    const cls = Sib.toElement(component);
+    defineComponent(component.name, cls);
+  },
+  toElement(component: ComponentConstructorInterface): typeof HTMLElement {
+    return class extends HTMLElement {
+      private component: ComponentInterface;
+
+      constructor() {
+        super();
+        this.component = new component(this);
+        this.component.created();
+      }
+
+      static get observedAttributes() {
+        return (<any>component).observedAttributes;
+      }
+
+      attributeChangedCallback(name, oldValue, newValue) {
+        const attr = name.replace(
+          /([a-z0-9])-([a-z0-9])/g,
+          (_c, p1, p2) => `${p1}${p2.toUpperCase()}`,
+        );
+        this.component.attributesCallback(attr, newValue, oldValue);
+      }
+
+      connectedCallback() {
+        this.component.attached();
+      }
+
+      disconnectedCallback() {
+        this.component.detached();
+      }
+    };
+  },
+};
diff --git a/src/libs/async-query-selector-types.ts b/src/libs/async-query-selector-types.ts
index 5bfd0121b3f637a397c8f675805d9705cb3acb53..d6ff9d56b0eb616545e8016bf80062651ebacf3d 100644
--- a/src/libs/async-query-selector-types.ts
+++ b/src/libs/async-query-selector-types.ts
@@ -2,50 +2,46 @@ export type AsyncQuerySelectorType = {
   <K extends keyof HTMLElementTagNameMap>(
     selectors: K,
     parent?: ParentNode,
-  ): Promise<HTMLElementTagNameMap[K]>
+  ): Promise<HTMLElementTagNameMap[K]>;
   <K extends keyof SVGElementTagNameMap>(
     selectors: K,
     parent?: ParentNode,
-  ): Promise<SVGElementTagNameMap[K]>
-  //@ts-ignore
+  ): Promise<SVGElementTagNameMap[K]>;
   <K extends keyof MathMLElementTagNameMap>(
     selectors: K,
     parent?: ParentNode,
-  //@ts-ignore
-  ): Promise<MathMLElementTagNameMap[K]>
+  ): Promise<MathMLElementTagNameMap[K]>;
   /** @deprecated */
   <K extends keyof HTMLElementDeprecatedTagNameMap>(
     selectors: K,
     parent?: ParentNode,
-  ): Promise<HTMLElementDeprecatedTagNameMap[K]>
+  ): Promise<HTMLElementDeprecatedTagNameMap[K]>;
   <E extends Element = Element>(
     selectors: string,
     parent?: ParentNode,
-  ): Promise<E>
-}
+  ): Promise<E>;
+};
 
 export type AsyncQuerySelectorAllType = {
   <K extends keyof HTMLElementTagNameMap>(
     selectors: K,
     parent?: ParentNode,
-  ): AsyncIterable<HTMLElementTagNameMap[K]>
+  ): AsyncIterable<HTMLElementTagNameMap[K]>;
   <K extends keyof SVGElementTagNameMap>(
     selectors: K,
     parent?: ParentNode,
-  ): AsyncIterable<SVGElementTagNameMap[K]>
-  //@ts-ignore
+  ): AsyncIterable<SVGElementTagNameMap[K]>;
   <K extends keyof MathMLElementTagNameMap>(
     selectors: K,
     parent?: ParentNode,
-  //@ts-ignore
-  ): AsyncIterable<MathMLElementTagNameMap[K]>
+  ): AsyncIterable<MathMLElementTagNameMap[K]>;
   /** @deprecated */
   <K extends keyof HTMLElementDeprecatedTagNameMap>(
     selectors: K,
     parent?: ParentNode,
-  ): AsyncIterable<HTMLElementDeprecatedTagNameMap[K]>
+  ): AsyncIterable<HTMLElementDeprecatedTagNameMap[K]>;
   <E extends Element = Element>(
     selectors: string,
     parent?: ParentNode,
-  ): AsyncIterable<E>
-}
+  ): AsyncIterable<E>;
+};
diff --git a/src/libs/filter.ts b/src/libs/filter.ts
index 6082d904bac63a9fcfdb3e25d4b0ffe8a371b21a..755298e46cd28c6cab32058545cf7550b431bb26 100644
--- a/src/libs/filter.ts
+++ b/src/libs/filter.ts
@@ -1,5 +1,10 @@
-import { parseFieldsString, findClosingBracketMatchIndex, compare, uniqID } from "./helpers";
-import type { Query, SearchQuery } from "./interfaces";
+import {
+  compare,
+  findClosingBracketMatchIndex,
+  parseFieldsString,
+  uniqID,
+} from './helpers.ts';
+import type { Query, SearchQuery } from './interfaces.ts';
 
 /**
  * Check if the field is a set
@@ -9,9 +14,9 @@ import type { Query, SearchQuery } from "./interfaces";
  */
 const isSet = (field: string, fields: string): boolean => {
   if (!fields) return false;
-  let foundSets = fields.match(getSetRegexp(field));
+  const foundSets = fields.match(getSetRegexp(field));
   return foundSets ? foundSets.length > 0 : false;
-}
+};
 /**
  * Get the list of fields in the set
  * @param field - set name to get
@@ -21,32 +26,33 @@ const isSet = (field: string, fields: string): boolean => {
 const getSet = (field: string, fields: string): string[] => {
   const setString = fields.match(getSetRegexp(field));
   if (!setString) return [];
-  const firstSetBracket = fields.indexOf(setString[0]) + (setString[0].length) - 1;
+  const firstSetBracket =
+    fields.indexOf(setString[0]) + setString[0].length - 1;
   const lastSetBracket = findClosingBracketMatchIndex(fields, firstSetBracket);
   const set = fields.substring(firstSetBracket + 1, lastSetBracket);
   return parseFieldsString(set);
-}
+};
 const getSetRegexp = (field: string) => {
-  return new RegExp(`(^|\\,|\\(|\\s)\\s*${field}\\s*\\(`, 'g')
-}
+  return new RegExp(`(^|\\,|\\(|\\s)\\s*${field}\\s*\\(`, 'g');
+};
 /**
  * Check if the field is a special search field
  * @param field - field to test
  * @param searchForm - current search form
  * @returns true if the field is a special search field
  */
-const isSearchField = (field: string, searchForm: any) => {
-  return searchForm.hasAttribute('search-' + field);
-}
+const isSearchField = (field: string, searchForm: Element) => {
+  return searchForm.hasAttribute(`search-${field}`);
+};
 /**
  * Get the fields targetted by a search field
  * @param field - search field to get
  * @param searchForm - current search form
  * @returns a list of fields targetted by the current search field
  */
-const getSearchField = (field: string, searchForm: any): string[] => {
-  return parseFieldsString(searchForm.getAttribute('search-' + field));
-}
+const getSearchField = (field: string, searchForm: Element): string[] => {
+  return parseFieldsString(searchForm.getAttribute(`search-${field}`) || '');
+};
 
 /**
  * Throw or simply return value
@@ -58,7 +64,7 @@ const orThrow = (throwOn: boolean | undefined, ret: boolean) => {
   if (throwOn === true && ret) throw true;
   if (throwOn === false && !ret) throw false;
   return ret;
-}
+};
 
 /**
  * Compare a value to the query
@@ -67,30 +73,39 @@ const orThrow = (throwOn: boolean | undefined, ret: boolean) => {
  * @param throwOn - should function throw error on True or False
  * @returns true if value matches, throw error otherwise
  */
-const matchValue = async (val: any, query: Query, throwOn?: boolean): Promise<boolean> => {
+const matchValue = async (
+  val: any,
+  query: Query,
+  throwOn?: boolean,
+): Promise<boolean> => {
   const subject = await val;
   if (subject == null && query.value === '') return orThrow(throwOn, true); // filter not set and subject not existing -> ignore filter
-  if (subject == null)  return orThrow(throwOn, false); // return false; // property does not exist on resource
-  if (query.list) { // Filter on a container
-    if(query.value.length === 0) return orThrow(throwOn, true);
-    for(const v of query.value) {
-      if (await matchValue(subject, { type: query.type, value: v, list: false })) { // do not throw here, we need the result
+  if (subject == null) return orThrow(throwOn, false); // return false; // property does not exist on resource
+  if (query.list) {
+    // Filter on a container
+    if (query.value.length === 0) return orThrow(throwOn, true);
+    for (const v of query.value) {
+      if (
+        await matchValue(subject, { type: query.type, value: v, list: false })
+      ) {
+        // do not throw here, we need the result
         return orThrow(throwOn, true);
       }
     }
     return orThrow(throwOn, false);
   }
   if (subject.isContainer?.()) {
-    let ret: any = Promise.resolve(query.value === ''); // if no query, return a match
+    let ret: boolean | Promise<boolean> = Promise.resolve(query.value === ''); // if no query, return a match
     for (const value of subject['ldp:contains']) {
-      ret = await ret || await matchValue(value, query); // do not throw here, we need the result
+      ret = (await ret) || (await matchValue(value, query)); // do not throw here, we need the result
       if (ret) return orThrow(throwOn, true);
     }
     return orThrow(throwOn, await ret);
-  } else if(Array.isArray(subject)) {
-    let ret: any = Promise.resolve(query.value === ''); // if no query, return a match
+  }
+  if (Array.isArray(subject)) {
+    let ret: boolean | Promise<boolean> = Promise.resolve(query.value === ''); // if no query, return a match
     for (const value of subject) {
-      ret = await ret || await matchValue(value, query); // do not throw here, we need the result
+      ret = (await ret) || (await matchValue(value, query)); // do not throw here, we need the result
       if (ret) {
         return true;
       }
@@ -99,7 +114,7 @@ const matchValue = async (val: any, query: Query, throwOn?: boolean): Promise<bo
   }
 
   return orThrow(throwOn, compare[query.type](subject, query.value));
-}
+};
 
 /**
  * Cache properties of a filter to avoid repeated parsing
@@ -112,15 +127,17 @@ const cacheFieldsProps = (
   cacheKey: string,
   filter: string,
   fields: string,
-  searchForm: any
+  searchForm: any,
 ) => {
   if (!window.cachePropsSearchFilter[cacheKey]) {
     window.cachePropsSearchFilter[cacheKey] = {
       setFields: isSet(filter, fields) ? getSet(filter, fields) : null,
-      setSearchFields: isSearchField(filter, searchForm) ? getSearchField(filter, searchForm) : null
-    }
+      setSearchFields: isSearchField(filter, searchForm)
+        ? getSearchField(filter, searchForm)
+        : null,
+    };
   }
-}
+};
 
 /**
  * Allow to traverse a multi-depth path to filter on resources of a given type
@@ -129,18 +146,22 @@ const cacheFieldsProps = (
  * @param targetedType The type of resources we are looking for
  * @returns The list of all resources ids found of given type
  */
-const traversePath = async (resource: object, path: string[], targetedType: string): Promise<object[]> => {
+const traversePath = async (
+  resource: object,
+  path: string[],
+  targetedType: string,
+): Promise<object[]> => {
   let result: object[] = [];
   let currentRes: any;
   let remainingPath: string[] = path;
-  if (!path.length) return [];
+  if (path.length === 0) return [];
 
   // Split and get first item
   try {
     currentRes = await resource[path[0]];
     const lastPath1El = path.shift();
 
-    if(lastPath1El) remainingPath = path;
+    if (lastPath1El) remainingPath = path;
 
     if (currentRes && remainingPath.length > 1) {
       result = await traversePath(currentRes, remainingPath, targetedType); // Await the result of traversePath
@@ -156,9 +177,9 @@ const traversePath = async (resource: object, path: string[], targetedType: stri
           }
           if (!Array.isArray(targetsRes)) targetsRes = [targetsRes];
 
-          for(const targetRes of targetsRes) {
-            if (!result.some(item => item["@id"] === targetRes["@id"])) {
-              result.push({"@id": targetRes["@id"]});
+          for (const targetRes of targetsRes) {
+            if (!result.some(item => item['@id'] === targetRes['@id'])) {
+              result.push({ '@id': targetRes['@id'] });
             }
           }
         }
@@ -170,8 +191,7 @@ const traversePath = async (resource: object, path: string[], targetedType: stri
   }
   // console.log(`TraversePath result for ${resource['@id']} : `, await result);
   return result;
-}
-
+};
 
 /**
  * Check if one resource match one filter
@@ -191,7 +211,7 @@ const matchFilter = async (
   fieldsAttr: string,
   searchForm: any,
   filterId: string,
-  throwOn: boolean
+  throwOn: boolean,
 ) => {
   let fields: string[] | null = null;
 
@@ -202,9 +222,11 @@ const matchFilter = async (
     fields = window.cachePropsSearchFilter[cacheKey].setFields;
   } else if (window.cachePropsSearchFilter[cacheKey].setSearchFields !== null) {
     fields = window.cachePropsSearchFilter[cacheKey].setSearchFields;
-  } else { // search on 1 field
+  } else {
+    // search on 1 field
     //FIXME: Better assumption that just using ldp:contains does the job ?
-    if (!(await resource[filter]) && filter.includes('ldp:contains')) { // nested field
+    if (!(await resource[filter]) && filter.includes('ldp:contains')) {
+      // nested field
       // console.log(`No ${filter} found for ${resource['@id']} and ${filter} is a nested field. Trying to traverse path.`);
       const path1: string[] = filter.split('.');
       const targetedType = path1[path1.length - 1];
@@ -214,33 +236,40 @@ const matchFilter = async (
       targetIds = await traversePath(resource, path1, targetedType);
       // console.log(`TargetIds : ${targetIds} found for ${await resource['name']} : ${resource['@id']}`);
 
-      if (!Array.isArray(targetIds) || targetIds.length === 0 && query.value !== '') {
+      if (
+        !Array.isArray(targetIds) ||
+        (targetIds.length === 0 && query.value !== '')
+      ) {
         // console.log(`No targetIds found for ${resource['@id']} returning false`);
-        throw throwOn ? false : true;
+        throw !throwOn;
       }
 
       // console.log(`Do we have a match for ${resource['@id']} ?`, match);
-      return await matchValue(targetIds, query, throwOn);;
+      return await matchValue(targetIds, query, throwOn);
     }
     return matchValue(resource[filter], query, throwOn);
   }
 
   // search on multiple fields
   try {
-    await Promise.all((fields || []).map(field =>
-      matchFilter(
-        resource,
-        field,
-        query,
-        fieldsAttr,
-        searchForm,
-        filterId,
-        true // stop searching when 1 filter is true (= OR)
-      )
-    ));
-  } catch (e) { return true; }
+    await Promise.all(
+      (fields || []).map(field =>
+        matchFilter(
+          resource,
+          field,
+          query,
+          fieldsAttr,
+          searchForm,
+          filterId,
+          true, // stop searching when 1 filter is true (= OR)
+        ),
+      ),
+    );
+  } catch {
+    return true;
+  }
   throw false;
-}
+};
 
 /**
  * Check if one resource match all the filters
@@ -258,25 +287,29 @@ const matchFilters = async (
   filterNames: string[],
   fields: string,
   searchForm: any,
-  filterId: string
+  filterId: string,
 ): Promise<boolean> => {
   // return true if all filters values are contained in the corresponding field of the resource
   try {
-    await Promise.all(filterNames.map(async (filter) => {
-        let match = await matchFilter(
+    await Promise.all(
+      filterNames.map(async filter => {
+        const match = await matchFilter(
           resource,
           filter,
           filters[filter],
           fields,
           searchForm,
           filterId,
-          false // stop searching when 1 filter is false (= AND)
+          false, // stop searching when 1 filter is false (= AND)
         );
         return match;
-    }));
-  } catch (e) { return false; }
+      }),
+    );
+  } catch (_e) {
+    return false;
+  }
   return true;
-}
+};
 
 /**
  * Check which resources match the filters
@@ -286,29 +319,29 @@ const matchFilters = async (
  * @param searchForm - searchForm component
  * @returns resources filtered
  */
-const searchInResources = async (
+const searchInResources = (
   resources: object[],
   filters: SearchQuery,
   fields: string,
-  searchForm: any
+  searchForm: any,
 ) => {
   // Optim: use cache to do these things only once
   const filterNames = Object.keys(filters);
   const filterId = uniqID();
   window.cachePropsSearchFilter = {};
-  return Promise.all(resources.map(async (resource) => {
-    let match = await matchFilters(
-      resource,
-      filters,
-      filterNames,
-      fields,
-      searchForm,
-      filterId
-    );
-    return match;
-  }));
-}
-
-export {
-  searchInResources
+  return Promise.all(
+    resources.map(async resource => {
+      const match = await matchFilters(
+        resource,
+        filters,
+        filterNames,
+        fields,
+        searchForm,
+        filterId,
+      );
+      return match;
+    }),
+  );
 };
+
+export { searchInResources };
diff --git a/src/libs/helpers.ts b/src/libs/helpers.ts
index 2eea9a0f7fbe3e9ed154d04be80a58f2872a2ca5..adf004efb7efca41d16e7aaab2b0c5d2c11dec94 100644
--- a/src/libs/helpers.ts
+++ b/src/libs/helpers.ts
@@ -1,7 +1,7 @@
-import Fuse from "fuse.js";
+import Fuse from 'fuse.js';
 
 function uniqID(): string {
-  return '_' + (Math.random() * Math.pow(36, 20)).toString(36).slice(0, 10);
+  return `_${(Math.random() * 36 ** 20).toString(36).slice(0, 10)}`;
 }
 
 function stringToDom(html: string): DocumentFragment {
@@ -10,22 +10,25 @@ function stringToDom(html: string): DocumentFragment {
   return template.content;
 }
 
-async function evalTemplateString(str: string, variables: {[key:string]:any} = {}) {
+const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
+async function evalTemplateString(
+  str: string,
+  variables: { [key: string]: unknown } = {},
+) {
   const keys = Object.keys(variables);
   const values = keys.map(key => variables[key]);
   try {
-    const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor
-    const func = AsyncFunction.call(null, ...keys, 'return `' + str + '`');
+    const func = AsyncFunction.call(null, ...keys, `return \`${str}\``);
     return await func(...values);
   } catch (e) {
     console.log(e);
-    throw new SyntaxError('`' + str + '`');
+    throw new SyntaxError(`\`${str}\``);
   }
 }
 
 function importCSS(...stylesheets: string[]) {
-  const linksElements: HTMLLinkElement[] = []; 
-  for(let url of stylesheets) {
+  const linksElements: HTMLLinkElement[] = [];
+  for (let url of stylesheets) {
     url = relativeSource(url);
     let link = Array.from(document.head.querySelectorAll('link')).find(
       link => link.href === url,
@@ -36,38 +39,38 @@ function importCSS(...stylesheets: string[]) {
     link.href = url;
     document.head.appendChild(link);
     linksElements.push(link);
-  };
+  }
   return linksElements;
 }
 /**
  * @param id an uniq id to avoid import a style twice
  * @param importer a callback returning this `import()` promise
  * @returns the style element
- * 
+ *
  * typical use:
  * ```js
- * importInlineCSS('bootstrap', () => import('./css/bootstrap.css?inline')) 
+ * importInlineCSS('bootstrap', () => import('./css/bootstrap.css?inline'))
  * // adding '?inline' lets Vite convert css to js
  * ```
  */
 
 function importInlineCSS(
   id: string,
-  importer: string | (() => string | Promise<string | { default: string }>)
+  importer: string | (() => string | Promise<string | { default: string }>),
 ) {
   id = `sib-inline-css-${id}`;
   let style = document.head.querySelector<HTMLStyleElement>(`style#${id}`);
   if (style) return style;
-  style = document.createElement("style");
+  style = document.createElement('style');
   style.id = id;
   document.head.appendChild(style);
   (async () => {
     let textContent: string;
-    if (typeof importer === "string") textContent = importer;
+    if (typeof importer === 'string') textContent = importer;
     else {
       const imported = await importer();
-      if (typeof imported === "string") textContent = imported;
-      else textContent = imported.default || "";
+      if (typeof imported === 'string') textContent = imported;
+      else textContent = imported.default || '';
     }
     style.textContent = textContent;
   })();
@@ -91,11 +94,11 @@ function importJS(...plugins: string[]): HTMLScriptElement[] {
 function relativeSource(source: string) {
   if (!source.match(/^\..?\//)) return new URL(source, document.baseURI).href;
   const e = new Error();
-  if(!e.stack) return source;
+  if (!e.stack) return source;
   const f2 = e.stack.split('\n').filter(l => l.includes(':'))[2];
-  let line = f2.match(/[a-z]+:.*$/);
+  const line = f2.match(/[a-z]+:.*$/);
   if (!line) return source;
-  const calledFile = line[0].replace(/(\:[0-9]+){2}\)?$/,'');
+  const calledFile = line[0].replace(/(\:[0-9]+){2}\)?$/, '');
   source = new URL(source, calledFile).href;
   return source;
 }
@@ -103,17 +106,17 @@ function relativeSource(source: string) {
 function loadScript(source: string) {
   source = relativeSource(source);
   return new Promise(resolve => {
-    var script = document.createElement('script');
-    var head = document.querySelector('head');
+    const script = document.createElement('script');
+    const head = document.querySelector('head');
     script.async = true;
     script.onload = () => setTimeout(resolve, 0);
     script.src = source;
-    if(head) head.appendChild(script);
+    if (head) head.appendChild(script);
   });
 }
 
 function domIsReady(): Promise<void> {
-  return new Promise(function(resolve) {
+  return new Promise(resolve => {
     if (document.readyState === 'complete') {
       resolve();
     } else {
@@ -122,43 +125,48 @@ function domIsReady(): Promise<void> {
   });
 }
 
-function setDeepProperty(obj: {[index:string]:any}, path: string[], value: any) {
+function setDeepProperty(
+  obj: { [index: string]: any },
+  path: string[],
+  value: any,
+) {
   const name = path.shift();
   if (name) {
     if (!(name in obj)) obj[name] = {};
-    if (path.length) setDeepProperty(obj[name], path, value);
+    if (path.length > 0) setDeepProperty(obj[name], path, value);
     else obj[name] = value;
   }
 }
 
 function parseFieldsString(fields: string): string[] {
   if (!fields) return [];
-  let fieldsArray: string[];
-
   // remove all sets from fields
-  while(fields.indexOf('(') > 0){
-    let firstBracket = fields.indexOf('(');
-    let noset = fields.substring(firstBracket, findClosingBracketMatchIndex(fields, firstBracket)+1)
-    fields = fields.replace(noset, '')
+  while (fields.indexOf('(') > 0) {
+    const firstBracket = fields.indexOf('(');
+    const noset = fields.substring(
+      firstBracket,
+      findClosingBracketMatchIndex(fields, firstBracket) + 1,
+    );
+    fields = fields.replace(noset, '');
   }
 
   const re = /((^\s*|,)\s*)(("(\\"|[^"])*")|('(\\'|[^'])*')|[^,]*)/gm; // match , not inside quotes
-  fieldsArray = fields.match(re) || []; // separate fields
+  const fieldsArray = fields.match(re) || []; // separate fields
   if (!fieldsArray) return [];
-  return fieldsArray.map(a => a.replace(/^[\s,]+/, '')) // remove commas and spaces
+  return fieldsArray.map(a => a.replace(/^[\s,]+/, '')); // remove commas and spaces
 }
 
 function findClosingBracketMatchIndex(str: string, pos: number) {
-  if (str[pos] != '(') throw new Error("No '(' at index " + pos);
+  if (str[pos] !== '(') throw new Error(`No '(' at index ${pos}`);
   let depth = 1;
   for (let i = pos + 1; i < str.length; i++) {
     switch (str[i]) {
-    case '(':
-      depth++;
-      break;
-    case ')':
-      if (--depth == 0) return i;
-      break;
+      case '(':
+        depth++;
+        break;
+      case ')':
+        if (--depth === 0) return i;
+        break;
     }
   }
   return -1;
@@ -168,7 +176,9 @@ function defineComponent(tagName: string, componentClass: typeof HTMLElement) {
   if (!customElements.get(tagName)) {
     customElements.define(tagName, componentClass);
   } else {
-    console.warn(`Warning: the component "${tagName}" has already been loaded in another version of sib-core.`)
+    console.warn(
+      `Warning: the component "${tagName}" has already been loaded in another version of sib-core.`,
+    );
   }
 }
 
@@ -182,8 +192,9 @@ function fuzzyCompare(subject: string, search: string) {
 
 const compare: { [k: string]: (subject: any, query: any) => boolean } = {
   string(subject: string, query: string) {
-    if(query === '') return true;
-    if(subject.toString().toLowerCase().includes(String(query).toLowerCase())) return true;
+    if (query === '') return true;
+    if (subject.toString().toLowerCase().includes(String(query).toLowerCase()))
+      return true;
     return fuzzyCompare(subject, query);
   },
   boolean(subject: boolean, query: boolean) {
@@ -204,46 +215,49 @@ const compare: { [k: string]: (subject: any, query: any) => boolean } = {
   },
   resource(subject, query) {
     // dropdown default ' - ' option return an empty string
-    if(query === '') return true;
+    if (query === '') return true;
     if (!query['@id']) return false;
-    const ret = (subject['@id'] === query['@id']);
+    const ret = subject['@id'] === query['@id'];
     return ret;
-  }
+  },
 };
 
-function generalComparator(a, b, order = 'asc') {
-  let comparison = 0;
-
+function generalComparator(
+  a: unknown,
+  b: unknown,
+  order: 'asc' | 'desc' = 'asc',
+): number {
+  if (order === 'desc') return generalComparator(b, a);
+  if (a == null && b == null) return 0;
+  if (a === b || Object.is(a, b)) return 0;
   if (typeof a === 'boolean' && typeof b === 'boolean') {
-      comparison = (a === b) ? 0 : a ? 1 : -1;
-  } else if (!isNaN(a) && !isNaN(b)) {
-      comparison = Number(a) - Number(b);
-  } else if (Array.isArray(a) && Array.isArray(b)) {
-    comparison = a.length - b.length;
-  }  else if (!isNaN(Date.parse(a)) && !isNaN(Date.parse(b))) {
-      const dateA = new Date(a);
-      const dateB = new Date(a);
-      comparison =  dateA.getTime() - dateB.getTime();
-  } else if (typeof a === 'object' && typeof b === 'object') {
-      const aKeys = Object.keys(a);
-      const bKeys = Object.keys(b);
-      comparison = aKeys.length - bKeys.length;
-  } else if (a == null || b == null) {
-      comparison = a == null ? (b == null ? 0 : -1) : (b == null ? 1 : 0);
-  } else {
-      comparison = a.toString().localeCompare(b.toString());
+    return a === b ? 0 : a ? 1 : -1;
   }
-
-  if (order === 'desc') {
-      comparison = comparison * -1;
+  if (!Number.isNaN(Number(a)) && !Number.isNaN(Number(b))) {
+    return Number(a) - Number(b);
   }
-  return comparison;
-};
-
+  if (Array.isArray(a) && Array.isArray(b)) {
+    return a.length - b.length;
+  }
+  const dateA = Date.parse(String(a));
+  const dateB = Date.parse(String(b));
+  if (!Number.isNaN(dateA) && !Number.isNaN(dateB)) {
+    return dateA - dateB;
+  }
+  if (a && b && typeof a === 'object' && typeof b === 'object') {
+    const aKeys = Object.keys(a);
+    const bKeys = Object.keys(b);
+    return aKeys.length - bKeys.length;
+  }
+  if (a == null) return -1;
+  if (b == null) return 1;
+  return String(a).localeCompare(String(b));
+}
 
 function transformArrayToContainer(resource: object) {
   const newValue = { ...resource };
-  for (let predicate of Object.keys(newValue)) { // iterate over all properties
+  for (const predicate of Object.keys(newValue)) {
+    // iterate over all properties
     const predicateValue = newValue[predicate];
     if (!predicateValue || typeof predicateValue !== 'object') continue; // undefined or literal, do nothing
     if (['permissions', '@context'].includes(predicate)) continue; // do not transform permissions and context
@@ -253,58 +267,67 @@ function transformArrayToContainer(resource: object) {
       newValue[predicate] = transformArrayToContainer(resource[predicate]);
     }
 
-    if (Array.isArray(predicateValue) && predicateValue['@id']) { // Do not systematically transform arrays to containers
+    if (Array.isArray(predicateValue) && predicateValue['@id']) {
+      // Do not systematically transform arrays to containers
       newValue[predicate] = {
         '@id': predicateValue['@id'],
-        'ldp:contains': [...predicateValue]
+        'ldp:contains': [...predicateValue],
       };
-      newValue[predicate]['ldp:contains'].forEach((childPredicate: any, index: number) => { // but check all nested resources
-        newValue[predicate]['ldp:contains'][index] = transformArrayToContainer(childPredicate);
-      });
+      newValue[predicate]['ldp:contains'].forEach(
+        (childPredicate: any, index: number) => {
+          // but check all nested resources
+          newValue[predicate]['ldp:contains'][index] =
+            transformArrayToContainer(childPredicate);
+        },
+      );
     }
   }
   return newValue;
 }
 
 export default class AsyncIterableBuilder<Type> {
-  readonly #values: Promise<{ value: Type; done: boolean }>[] = []
-  #resolve!: (value: { value: Type; done: boolean }) => void
-  readonly iterable: AsyncIterable<Type>
-  readonly next: (value: Type, done?: boolean) => void
+  readonly #values: Promise<{ value: Type; done: boolean }>[] = [];
+  #resolve!: (value: { value: Type; done: boolean }) => void;
+  readonly iterable: AsyncIterable<Type>;
+  readonly next: (value: Type, done?: boolean) => void;
 
   constructor() {
-    this.#nextPromise()
-    this.iterable = this.#createIterable()
-    this.next = this.#next.bind(this)
+    this.#nextPromise();
+    this.iterable = this.#createIterable();
+    this.next = this.#next.bind(this);
   }
 
   async *#createIterable() {
     for (let index = 0; ; index++) {
-      const { value, done } = await this.#values[index]
-      delete this.#values[index]
-      yield value
-      if (done) return
+      const { value, done } = await this.#values[index];
+      delete this.#values[index];
+      yield value;
+      if (done) return;
     }
   }
 
-  #next(value: Type, done: boolean = false) {
-    this.#resolve({ value, done })
-    this.#nextPromise()
+  #next(value: Type, done = false) {
+    this.#resolve({ value, done });
+    this.#nextPromise();
   }
 
   #nextPromise() {
-    this.#values.push(new Promise(resolve => (this.#resolve = resolve)))
+    this.#values.push(
+      new Promise(resolve => {
+        this.#resolve = resolve;
+      }),
+    );
   }
 }
 
-import {
+import type {
   AsyncQuerySelectorAllType,
   AsyncQuerySelectorType,
-} from './async-query-selector-types';
+} from './async-query-selector-types.ts';
 
 const asyncQuerySelector: AsyncQuerySelectorType = (
   selector: string,
-  parent: ParentNode = document
+  parent: ParentNode = document,
 ) =>
   new Promise<Element>(resolve => {
     const element = parent.querySelector(selector);
@@ -324,7 +347,7 @@ const asyncQuerySelector: AsyncQuerySelectorType = (
 
 const asyncQuerySelectorAll: AsyncQuerySelectorAllType = (
   selector: string,
-  parent: ParentNode = document
+  parent: ParentNode = document,
 ) => {
   const delivered = new WeakSet<Element>();
   const { next, iterable } = new AsyncIterableBuilder<Element>();
diff --git a/src/libs/interfaces.ts b/src/libs/interfaces.ts
index 54e839b2fbf4356ffb14d7cd920500632c8238cf..144ae01b44a728e7714202748c595e8b12b45115 100644
--- a/src/libs/interfaces.ts
+++ b/src/libs/interfaces.ts
@@ -1,9 +1,11 @@
+import type { Profiler } from '../logger.ts';
+
 export interface AccessorStaticInterface {
   [key: string]: {
     get: Function;
     set: Function;
-  }
-};
+  };
+}
 
 export interface ArrayOfHooksInterface {
   created: HookInterface[];
@@ -11,9 +13,10 @@ export interface ArrayOfHooksInterface {
   detached: HookInterface[];
 }
 
-export interface AttributeChangedCallbackInterface {
-  (newValue: any, oldValue: any): void;
-};
+export type AttributeChangedCallbackInterface = (
+  newValue: any,
+  oldValue: any,
+) => void;
 
 export interface AttributeDefinitionInterface {
   type?: any;
@@ -26,24 +29,29 @@ export interface AttributesDefinitionInterface {
   [key: string]: AttributeDefinitionInterface;
 }
 
-export type ComponentConstructorInterface = new (element: HTMLElement) => ComponentInterface;
+export type ComponentConstructorInterface = new (
+  element: HTMLElement,
+) => ComponentInterface;
 
 export interface ComponentInterface {
+  profiler: Profiler;
   element: HTMLElement;
-  created():void;
-  attached():void;
-  detached():void;
+  created(): void;
+  attached(): void;
+  detached(): void;
 
-  attributesCallback(key: string, value: any, oldValue: any):void;
+  attributesCallback(key: string, value: any, oldValue: any): void;
 }
 
-export interface ComponentStaticInterface extends HasAttributesDefinitionInterface, HasInitialStateInterface {
-  name: String;
+export interface ComponentStaticInterface
+  extends HasAttributesDefinitionInterface,
+    HasInitialStateInterface {
+  name: string;
 
   hooks: ArrayOfHooksInterface;
   methods: Map<string, Function>;
   accessors: AccessorStaticInterface;
-};
+}
 
 export interface HasAttributesDefinitionInterface {
   attributes?: AttributesDefinitionInterface | undefined;
@@ -63,30 +71,32 @@ export interface HasMixinsInterface {
   use?: MixinStaticInterface[] | undefined;
 }
 
-export interface HookInterface {
-  (): void;
-};
+export type HookInterface = () => void;
 
-export interface MixinStaticInterface extends HasAttributesDefinitionInterface, HasMixinsInterface, HasInitialStateInterface, HasHooksInterface {
-  name: String;
-};
+export interface MixinStaticInterface
+  extends HasAttributesDefinitionInterface,
+    HasMixinsInterface,
+    HasInitialStateInterface,
+    HasHooksInterface {
+  name: string;
+}
 
 export interface LocationResourceInterface {
   lat?: HookInterface;
   lng?: HookInterface;
 }
 export interface Query {
-  value: any
-  type: "boolean" | "number" | "range" | "resource" | "string";
-  list: boolean
+  value: any;
+  type: 'boolean' | 'number' | 'range' | 'resource' | 'string';
+  list: boolean;
 }
 
 export interface SearchQuery {
-  [key: string]: Query
+  [key: string]: Query;
 }
 
 export interface FilterEventOptions {
   value: string;
   inputLabel: string;
   type: string;
-}
\ No newline at end of file
+}
diff --git a/src/libs/lit-helpers.ts b/src/libs/lit-helpers.ts
index 90d61adb5ee36c656366b5c012bf5402a6a3a4f6..3d953992f78ff36357db7ca6bd93154174b739ab 100644
--- a/src/libs/lit-helpers.ts
+++ b/src/libs/lit-helpers.ts
@@ -2,167 +2,220 @@
  * Spread function from open-wc/lit-helpers
  * More informations here: https://open-wc.org/developing/lit-helpers.html
  */
-import {html, TemplateResult, directive, noChange } from 'lit-html';
+
+import {
+  type AttributePart,
+  type BooleanAttributePart,
+  type ChildPart,
+  type ElementPart,
+  type EventPart,
+  type PropertyPart,
+  type TemplateResult,
+  html,
+  noChange,
+} from 'lit';
+
+import {
+  Directive,
+  type PartInfo,
+  PartType,
+  directive,
+} from 'lit/directive.js';
+
+type SpreadPartType =
+  | ChildPart
+  | AttributePart
+  | BooleanAttributePart
+  | EventPart
+  | PropertyPart
+  | ElementPart;
 
 const prevCache = new WeakMap();
-export const spread = directive((spreadData) => (part) => {
-  const prevData = prevCache.get(part);
-  if (prevData === spreadData) {
-    return;
+
+class SpreadDirective extends Directive {
+  spreadData: any;
+
+  constructor(partInfo: PartInfo) {
+    super(partInfo);
+    this.spreadData = null;
   }
-  prevCache.set(part, spreadData);
-
-  if (spreadData) {
-    for (const key in spreadData) {
-      const value = spreadData[key];
-      if (value === noChange) continue;
-
-      const prefix = key[0];
-      const { element } = part.committer;
-
-      if (prefix === '@') {
-        const prevHandler = prevData && prevData[key];
-        if (!prevHandler || prevHandler !== value) {
-          const name = key.slice(1);
-          if (prevHandler) element.removeEventListener(name, prevHandler);
-          element.addEventListener(name, value);
-        }
-        continue;
-      }
-      if (prefix === '.') {
-        if (!prevData || prevData[key] !== value) {
-          element[key.slice(1)] = value;
-        }
-        continue;
-      }
-      if (prefix === '?') {
-        if (!prevData || prevData[key] !== value) {
-          const name = key.slice(1);
-          if (value) {
-            element.setAttribute(name, '');
-          } else {
-            element.removeAttribute(name);
-          }
-        }
-        continue;
-      }
-      if (!prevData || prevData[key] !== value) {
-        if (value != null) {
-          element.setAttribute(key, String(value));
-        } else {
-          element.removeAttribute(key);
-        }
-      }
-    }
+
+  render(spreadData: any) {
+    this.spreadData = spreadData;
+    return noChange;
   }
 
-  if (prevData) {
-    for (const key in prevData) {
-      if (!spreadData || !(key in spreadData)) {
+  override update(part: SpreadPartType, [spreadData]: any) {
+    const prevData = prevCache.get(part);
+
+    if (prevData === spreadData) {
+      return noChange;
+    }
+
+    let element: HTMLElement;
+    prevCache.set(part, spreadData);
+
+    if (part.type === PartType.ATTRIBUTE || part.type === PartType.PROPERTY) {
+      element = part.element;
+    } else {
+      console.warn(
+        'Unsupported part type or missing element, skipping update.',
+      );
+      return noChange;
+    }
+
+    if (spreadData) {
+      for (const key in spreadData) {
+        const value = spreadData[key];
+        if (value === noChange) continue;
+
         const prefix = key[0];
-        const { element } = part.committer;
 
+        // Handle event listeners (e.g., @click)
         if (prefix === '@') {
-          element.removeEventListener(key.slice(1), prevData[key]);
+          const prevHandler = prevData?.[key];
+          if (!prevHandler || prevHandler !== value) {
+            const name = key.slice(1); // Extract event name
+            if (prevHandler) element.removeEventListener(name, prevHandler);
+            element.addEventListener(name, value);
+          }
           continue;
         }
+
+        // Handle properties (e.g., .value)
         if (prefix === '.') {
-          element[key.slice(1)] = undefined;
+          if (!prevData || prevData[key] !== value) {
+            element[key.slice(1)] = value;
+          }
           continue;
         }
+
+        // Handle boolean attributes (e.g., ?disabled)
         if (prefix === '?') {
-          element.removeAttribute(key.slice(1));
+          const attrName = key.slice(1); // Extract attribute name
+          if (!prevData || prevData[key] !== value) {
+            if (value) {
+              element.setAttribute(attrName, '');
+            } else {
+              element.removeAttribute(attrName);
+            }
+          }
           continue;
         }
-        element.removeAttribute(key);
+
+        // Handle regular attributes (e.g., class, id)
+        if (!prevData || prevData[key] !== value) {
+          if (value != null) {
+            element.setAttribute(key, String(value));
+          } else {
+            element.removeAttribute(key);
+          }
+        }
+      }
+    }
+
+    // Remove any old attributes or event listeners no longer in spreadData
+    if (prevData) {
+      for (const key in prevData) {
+        if (!spreadData || !(key in spreadData)) {
+          const prefix = key[0];
+
+          if (prefix === '@') {
+            element.removeEventListener(key.slice(1), prevData[key]);
+            continue;
+          }
+          if (prefix === '.') {
+            element[key.slice(1)] = undefined;
+            continue;
+          }
+          if (prefix === '?') {
+            element.removeAttribute(key.slice(1));
+            continue;
+          }
+          element.removeAttribute(key);
+        }
       }
     }
+
+    return noChange;
   }
-});
+}
 
+export const spread = directive(SpreadDirective);
 
 interface CachedNeedlessValue {
-    value: any;
-    index: number;
+  value: any;
+  index: number;
 }
 
 interface CachedTemplateStrings {
-    strings: string[];
-    needlessValues: CachedNeedlessValue[];
+  strings: TemplateStringsArray;
+  needlessValues: CachedNeedlessValue[];
 }
 
-function dropIndices(arr: any[], needlessValues: CachedNeedlessValue[]): any[] {
-    const newArr: any[] = [];
-    let j = 0;
+const templateStringsCache = new WeakMap<
+  TemplateStringsArray,
+  CachedTemplateStrings[]
+>();
 
-    for (let i = 0, n = arr.length; i < n; ++i) {
-        if (needlessValues[j].index === i) {
-            ++j;
-        } else {
-            newArr.push(arr[i]);
-        }
+function filterOutNeedlessValues(
+  arr: any[],
+  needlessValues: CachedNeedlessValue[],
+): any[] {
+  return arr.filter((_, i) => !needlessValues.some(nv => nv.index === i));
+}
+
+export function preHTML(
+  strings: TemplateStringsArray,
+  ...values: any[]
+): TemplateResult {
+  let cachedStrings = templateStringsCache.get(strings);
+
+  if (cachedStrings) {
+    for (const cached of cachedStrings) {
+      const { needlessValues } = cached;
+      const isSame = needlessValues.every(nv => values[nv.index] === nv.value);
+
+      if (isSame) {
+        // Return cached template result if values match
+        return html(
+          cached.strings,
+          ...filterOutNeedlessValues(values, needlessValues),
+        );
+      }
     }
+  }
 
-    return newArr;
-}
+  // No match found, so we need to create new template strings and cache them
+  const needlessValues: CachedNeedlessValue[] = [];
+  const newStrings: string[] = [];
 
-const templateStringsCache = new WeakMap<TemplateStringsArray, CachedTemplateStrings[]>();
-
-// Convert dynamic tags to template strings
-// example: <${'div'}>${'this is example'}</${'div'}> => <div>${'this is example'}</div>
-export function preHTML(strings: TemplateStringsArray, ...values: any[]): TemplateResult {
-    // check cache !important return equal link at first argument
-    let cachedStrings = templateStringsCache.get(strings) as CachedTemplateStrings[];
-    if (cachedStrings) {
-        for (let i = 0, n = cachedStrings.length; i < n; ++i) {
-            const needlessValues = cachedStrings[i].needlessValues;
-            let isSame = true;
-            for (let ii = 0, nn = needlessValues.length; ii < nn; ++ii) {
-                if (values[needlessValues[ii].index] !== needlessValues[ii].value) {
-                    isSame = false;
-                    break;
-                }
-            }
+  for (let i = 0; i < strings.length; i++) {
+    let str = strings[i];
 
-            if (isSame) {
-                return html(
-                    cachedStrings[i].strings as any,
-                    ...dropIndices(values, needlessValues)
-                );
-            }
-        }
+    while (str.endsWith('<') || (str.length >= 2 && str.endsWith('</'))) {
+      needlessValues.push({ value: values[i], index: i });
+      str += values[i] + strings[++i];
     }
 
-    const needlessValues: CachedNeedlessValue[] = [];
-    const newStrings: string[] = [];
-
-    let str: string;
-    for (let i = 0, n = strings.length; i < n; ++i) {
-        str = strings[i];
-
-        while (
-            str[str.length - 1] === '<' // open tag
-            || (str[str.length - 2] === '<' && str[str.length - 1] === '/') // close tag
-        ) {
-            needlessValues.push({
-                value: values[i],
-                index: i,
-            });
-            str += values[i] + strings[++i];
-        }
+    newStrings.push(str);
+  }
 
-        newStrings.push(str);
-    }
+  // Convert newStrings back to TemplateStringsArray type
+  const finalStrings = Object.assign([...newStrings], { raw: strings.raw });
 
-    if (!cachedStrings) {
-        cachedStrings = [];
-        templateStringsCache.set(strings, cachedStrings);
-    }
+  if (!cachedStrings) {
+    cachedStrings = [];
+    templateStringsCache.set(strings, cachedStrings);
+  }
 
-    cachedStrings.push({
-        strings: newStrings,
-        needlessValues,
-    });
+  cachedStrings.push({
+    strings: finalStrings as TemplateStringsArray,
+    needlessValues,
+  });
 
-    return html(newStrings as any, ...dropIndices(values, needlessValues));
-}
\ No newline at end of file
+  return html(
+    finalStrings as TemplateStringsArray,
+    ...filterOutNeedlessValues(values, needlessValues),
+  );
+}
diff --git a/src/libs/polyfills.ts b/src/libs/polyfills.ts
index 6ad45348f625a6f90531f9dcb537ba32dfc2cbfc..f79eb489520b09186714c6b77f5a1468412e2295 100644
--- a/src/libs/polyfills.ts
+++ b/src/libs/polyfills.ts
@@ -3,11 +3,11 @@ if (!('flat' in Array.prototype)) {
   Object.defineProperty(Array.prototype, 'flat', {
     configurable: true,
     value: function flat(this: any[], depth = 1) {
-      depth = isNaN(depth) ? 1 : Number(depth);
+      depth = Number.isNaN(depth) ? 1 : Number(depth);
       if (depth === 0) return Array.prototype.slice.call(this);
       return Array.prototype.reduce.call<any, any[], any[]>(
         this,
-        function(acc:any[], cur: any) {
+        (acc: any[], cur: any) => {
           if (Array.isArray(cur)) {
             acc.push.apply(acc, flat.call(cur, depth - 1));
           } else {
@@ -24,7 +24,7 @@ if (!('flat' in Array.prototype)) {
 
 // Element.prototype.toggleAttribute
 if (!Element.prototype.toggleAttribute) {
-  Element.prototype.toggleAttribute = function(name, force = undefined) {
+  Element.prototype.toggleAttribute = function (name, force = undefined) {
     if (force !== undefined) force = !!force;
 
     if (this.hasAttribute(name)) {
@@ -40,4 +40,4 @@ if (!Element.prototype.toggleAttribute) {
   };
 }
 
-export {}
+export {};
diff --git a/src/libs/store/custom-getter.ts b/src/libs/store/custom-getter.ts
index 15d7457312776584b29e996e46e0f084a85530c4..317b09bef84af61e15f7712491a61371f39390cd 100644
--- a/src/libs/store/custom-getter.ts
+++ b/src/libs/store/custom-getter.ts
@@ -1,316 +1,387 @@
 import JSONLDContextParser from 'jsonld-context-parser';
-import { store } from './store';
-import type { Resource } from '../../mixins/interfaces';
+import type { Resource } from '../../mixins/interfaces.ts';
+import { store } from './store.ts';
 
 const ContextParser = JSONLDContextParser.ContextParser;
 
-
 export class CustomGetter {
-    resource: any; // content of the requested resource
-    resourceId: string;
-    clientContext: object; // context given by the app
-    serverContext: object; // context given by the server
-    parentId: string; // id of the parent resource, used to get the absolute url of the current resource
-    containerTypes: string[]; // types of resources interpreted as containers
-    serverPagination: object; // pagination attributes to give to server
-    serverSearch: object; // search attributes to give to server
-
-    constructor(
-        resourceId: string,
-        resource: object,
-        clientContext: object,
-        serverContext: object,
-        parentId: string = "",
-        serverPagination: object = {},
-        serverSearch: object = {}) {
-        this.clientContext = clientContext;
-        this.serverContext = serverContext;
-        this.parentId = parentId;
-        this.resource = resource;
-        this.resourceId = resourceId;
-        this.serverPagination = serverPagination;
-        this.serverSearch = serverSearch;
-
-        this.containerTypes = [
-            this.getExpandedPredicate("ldp:Container"),
-            this.getExpandedPredicate("ldp:BasicContainer"),
-            this.getExpandedPredicate("ldp:DirectContainer"),
-            this.getExpandedPredicate("ldp:IndirectContainer"),
-            this.getExpandedPredicate("sib:federatedContainer"),
-        ];
-    }
-
-    /**
-     * Get the property of a resource for a given path
-     * Which means that if the resource is not complete, it will fetch it
-     * And that we handle the `.` notation, traversing the path recursively
-     * @param path: string
-     */
-    async get(path: any) {    
-        if (!path) return;
-
-        // Specific case where the predicates is a full IRI, avoid splitting it on the dot notation
-        try {
-            let isUrl = new URL(path);
-            // My goal is to be able to solve user['circles.ldp:contains'] on the fly
-            // If we do not check the url protocol, then it is considered valid
-            if (!isUrl.protocol.startsWith('http')) throw new Error('Not a valid HTTP url');
-            // If the path is a HTTP-scheme based URL, we need to fetch the resource directly
-            if (isUrl) {
-              let resources = this.resource[this.getExpandedPredicate(path)];
-              if (!resources) return undefined;
-              if (!Array.isArray(resources)) resources = [resources]; // convert to array if compacted to 1 resource
-
-              let result = resources ? resources.map((res: object) => {
-                  let resource: any = store.get(res['@id']);
-                  if (resource) return resource;
-
-                  // if not in cache, generate the basic resource
-                  resource = new CustomGetter(res['@id'], { '@id': res['@id'] }, this.clientContext, this.serverContext, this.parentId).getProxy()
-                  store.cacheResource(res['@id'], resource); // put it in cache
-                  return resource; // and return it
-              }) : [];
-
-              return result;
-            }
-        } catch (e) {
-            if (!path.split) return undefined;
-
-            // Split the path on each dots
-            const path1: string[] = path.split('.');
-
-            // Intermediate path var to request each resource individually until the path traversal is completed
-            const path2: string[] = [];
-
-            // Actual value found from the store, if any
-            let value: any;
-
-            if (!this.isFullResource()) { // if resource is not complete, fetch it first
-                await this.getResource(this.resourceId, {...this.clientContext, ...this.serverContext}, this.parentId);
-            }
-
-            // If the path contains dot, we need to traverse the path recursively
-            // We do that by poping one element from path1 at each step and affecting it to path2
-            // Trying to get the value from it
-            while (true) {
-                value = await this.resource[this.getExpandedPredicate(path1[0])];
-
-                if (path1.length <= 1) break; // no dot path
-                const lastPath1El = path1.pop();
-                if(lastPath1El) path2.unshift(lastPath1El);
-            }
-
-            if (path2.length === 0) { // end of the path
-                if (!value || !value['@id']) return this.getLiteralValue(value); // no value or not a resource
-                return await this.getResource(value['@id'], {...this.clientContext, ...this.serverContext}, this.parentId || this.resourceId); // return complete resource
-            }
-            if (!value || !value['@id']) return undefined;
-
-            let resource = await this.getResource(value['@id'], {...this.clientContext, ...this.serverContext}, this.parentId || this.resourceId);
-            store.subscribeResourceTo(this.resourceId, value['@id']);
-            return resource ? await resource[path2.join('.')] : undefined; // return value
-        }
-    }
-
-    /**
-     * Return value depending of the current language
-     * @param value
-     * @returns
-     */
-    getLiteralValue(value: any): string|string[]|null {
-        if (typeof value === "object") { // value object: https://www.w3.org/TR/json-ld11/#value-objects
-            if (value['@value']) { // 1 language
-                return value['@value'];
-            } else if (Array.isArray(value)) {
-                if (value.length === 0) return null;
-                if(Array.isArray(value[0])) { // multiple languages
-                    const ln = store._getLanguage();
-                    let translatedValue = value.find(v => v['@language'] && v['@language'] === ln); // find current language
-                    if (!translatedValue) translatedValue = value.find(v => v['@language'] && v['@language'] === 'en'); // default to en
-                    return translatedValue ? (translatedValue['@value'] || null) : null; // return value when no translated value is found
-                }
-                return value;
-            }
-        }
-        return value; // simple value
-    }
-
-
-    /**
-     * Cache resource in the store, and return the created proxy
-     * @param id
-     * @param context
-     * @param iriParent
-     */
-    async getResource(id: string, context: object, iriParent: string, forceFetch: boolean = false): Promise<Resource | null> {
-        if (id.startsWith('_:b')) return store.get(id + iriParent); // anonymous node = get from cache
-        return store.getData(id, context, iriParent, undefined ,forceFetch);
-    }
-
-
-    /**
-     * Return true if the resource is a container
-     */
-    isContainer(): boolean {
-        if (this.resource["@type"]) { // @type is an array
-            if (Array.isArray(this.resource["@type"]))
-                return this.containerTypes.some(type => this.resource["@type"].includes(type));
-            return this.containerTypes.includes(this.resource["@type"]);    
-        } else if (this.resource["type"]) {
-            if (Array.isArray(this.resource["type"]))
-                return this.containerTypes.some(type => this.resource["type"].includes(type));
-            return this.containerTypes.includes(this.resource["type"]);
-        }
-
-        return false;
-    }
-
-    /**
-     * Return true if the given key in the current resource in an array
-     */
-    isArray(): boolean {
-        if (Array.isArray(this.resource))
-            return true;
-
-        return false;
-    }
-
-
-    /**
-     * Get all properties of a resource
-     */
-    getProperties(): string[] {
-        return Object.keys(this.resource).map(prop => this.getCompactedPredicate(prop));
-    }
-
-    /**
-     * Get children of container as objects
-     */
-    getChildren(predicateName : string): object[] {
-        return this.resource[this.getExpandedPredicate(predicateName)] || [];
-    }
-
-    /**
-     * Get children of container as Proxys
-     */
-    getLdpContains(): CustomGetter[]|null {
-        let children = this.resource[this.getExpandedPredicate("ldp:contains")];
-        if (!children) return null;
-        if (!Array.isArray(children)) children = [children]; // convert to array if compacted to 1 resource
-
-        let result = children ? children.map((res: object) => {
-            let resource: any = store.get(res['@id']);
-            if (resource) return resource;
-
-            // if not in cache, generate the basic resource
-            resource = new CustomGetter(res['@id'], { '@id': res['@id'] }, this.clientContext, this.serverContext, this.parentId).getProxy()
-            store.cacheResource(res['@id'], resource); // put it in cache
-            return resource; // and return it
-        }) : [];
+  resource: any; // content of the requested resource
+  resourceId: string;
+  clientContext: object; // context given by the app
+  serverContext: object; // context given by the server
+  parentId: string; // id of the parent resource, used to get the absolute url of the current resource
+  containerTypes: string[]; // types of resources interpreted as containers
+  serverPagination: object; // pagination attributes to give to server
+  serverSearch: object; // search attributes to give to server
+
+  constructor(
+    resourceId: string,
+    resource: object,
+    clientContext: object,
+    serverContext: object,
+    parentId = '',
+    serverPagination: object = {},
+    serverSearch: object = {},
+  ) {
+    this.clientContext = clientContext;
+    this.serverContext = serverContext;
+    this.parentId = parentId;
+    this.resource = resource;
+    this.resourceId = resourceId;
+    this.serverPagination = serverPagination;
+    this.serverSearch = serverSearch;
+
+    this.containerTypes = [
+      this.getExpandedPredicate('ldp:Container'),
+      this.getExpandedPredicate('ldp:BasicContainer'),
+      this.getExpandedPredicate('ldp:DirectContainer'),
+      this.getExpandedPredicate('ldp:IndirectContainer'),
+      this.getExpandedPredicate('sib:federatedContainer'),
+    ];
+  }
+
+  /**
+   * Get the property of a resource for a given path
+   * Which means that if the resource is not complete, it will fetch it
+   * And that we handle the `.` notation, traversing the path recursively
+   * @param path: string
+   */
+  async get(path: any) {
+    if (!path) return;
+
+    // Specific case where the predicates is a full IRI, avoid splitting it on the dot notation
+    try {
+      const isUrl = new URL(path);
+      // My goal is to be able to solve user['circles.ldp:contains'] on the fly
+      // If we do not check the url protocol, then it is considered valid
+      if (!isUrl.protocol.startsWith('http'))
+        throw new Error('Not a valid HTTP url');
+      // If the path is a HTTP-scheme based URL, we need to fetch the resource directly
+      if (isUrl) {
+        let resources = this.resource[this.getExpandedPredicate(path)];
+        if (!resources) return undefined;
+        if (!Array.isArray(resources)) resources = [resources]; // convert to array if compacted to 1 resource
+
+        const result = resources
+          ? resources.map((res: object) => {
+              let resource: any = store.get(res['@id']);
+              if (resource) return resource;
+
+              // if not in cache, generate the basic resource
+              resource = new CustomGetter(
+                res['@id'],
+                { '@id': res['@id'] },
+                this.clientContext,
+                this.serverContext,
+                this.parentId,
+              ).getProxy();
+              store.cacheResource(res['@id'], resource); // put it in cache
+              return resource; // and return it
+            })
+          : [];
 
         return result;
+      }
+    } catch {
+      if (!path.split) return undefined;
+
+      // Split the path on each dots
+      const path1: string[] = path.split('.');
+
+      // Intermediate path var to request each resource individually until the path traversal is completed
+      const path2: string[] = [];
+
+      // Actual value found from the store, if any
+      let value: any;
+
+      if (!this.isFullResource()) {
+        // if resource is not complete, fetch it first
+        await this.getResource(
+          this.resourceId,
+          { ...this.clientContext, ...this.serverContext },
+          this.parentId,
+        );
+      }
+
+      // If the path contains dot, we need to traverse the path recursively
+      // We do that by poping one element from path1 at each step and affecting it to path2
+      // Trying to get the value from it
+      while (true) {
+        value = await this.resource[this.getExpandedPredicate(path1[0])];
+
+        if (path1.length <= 1) break; // no dot path
+        const lastPath1El = path1.pop();
+        if (lastPath1El) path2.unshift(lastPath1El);
+      }
+
+      if (path2.length === 0) {
+        // end of the path
+        if (!value || !value['@id']) return this.getLiteralValue(value); // no value or not a resource
+        return await this.getResource(
+          value['@id'],
+          { ...this.clientContext, ...this.serverContext },
+          this.parentId || this.resourceId,
+        ); // return complete resource
+      }
+      if (!value || !value['@id']) return undefined;
+
+      const resource = await this.getResource(
+        value['@id'],
+        { ...this.clientContext, ...this.serverContext },
+        this.parentId || this.resourceId,
+      );
+      store.subscribeResourceTo(this.resourceId, value['@id']);
+      return resource ? await resource[path2.join('.')] : undefined; // return value
     }
-
-
-    merge(resource: CustomGetter) {
-        this.resource = { ...this.getResourceData(), ...resource.getResourceData() }
+  }
+
+  /**
+   * Return value depending of the current language
+   * @param value
+   * @returns
+   */
+  getLiteralValue(value: any): string | string[] | null {
+    if (typeof value !== 'object') return value;
+    // value object: https://www.w3.org/TR/json-ld11/#value-objects
+    if (value['@value']) return value['@value']; // 1 language
+    if (!Array.isArray(value)) return value;
+    if (value.length === 0) return null;
+    if (!Array.isArray(value[0])) return value;
+    // multiple languages
+    const ln = store._getLanguage();
+    let translatedValue = value.find(
+      v => v['@language'] && v['@language'] === ln,
+    ); // find current language
+    if (!translatedValue)
+      translatedValue = value.find(
+        v => v['@language'] && v['@language'] === 'en',
+      ); // default to en
+    return translatedValue?.['@value'] ?? null; // return value when no translated value is found
+  }
+
+  /**
+   * Cache resource in the store, and return the created proxy
+   * @param id
+   * @param context
+   * @param iriParent
+   */
+  async getResource(
+    id: string,
+    context: object,
+    iriParent: string,
+    forceFetch = false,
+  ): Promise<Resource | null> {
+    if (id.startsWith('_:b')) return await store.get(id + iriParent); // anonymous node = get from cache
+    return store.getData(id, context, iriParent, undefined, forceFetch);
+  }
+
+  /**
+   * Return true if the resource is a container
+   */
+  isContainer(): boolean {
+    if (this.resource['@type']) {
+      // @type is an array
+      if (Array.isArray(this.resource['@type']))
+        return this.containerTypes.some(type =>
+          this.resource['@type'].includes(type),
+        );
+      return this.containerTypes.includes(this.resource['@type']);
     }
-
-    getResourceData(): object { return this.resource }
-
-    /**
-     * return true resource seems complete
-     * @param prop
-     */
-    isFullResource(): boolean {
-      let propertiesKeys = Object.keys(this.resource).filter(p => !p.startsWith('@'));
-      if (this.resource['@id'].startsWith('_:b')) return true; // anonymous node = considered as always full
-
-      if (propertiesKeys.length === 1 && propertiesKeys[0] === this.getExpandedPredicate('permissions'))
-        return false; // If only the permissions are present, then the resource is not complete
-      else if (propertiesKeys.length > 0) return true;
-
+    if (!this.resource.type) return false;
+
+    if (Array.isArray(this.resource.type))
+      return this.containerTypes.some(type =>
+        this.resource.type.includes(type),
+      );
+    return this.containerTypes.includes(this.resource.type);
+  }
+
+  /**
+   * Return true if the given key in the current resource in an array
+   */
+  isArray(): boolean {
+    if (Array.isArray(this.resource)) return true;
+
+    return false;
+  }
+
+  /**
+   * Get all properties of a resource
+   */
+  getProperties(): string[] {
+    return Object.keys(this.resource).map(prop =>
+      this.getCompactedPredicate(prop),
+    );
+  }
+
+  /**
+   * Get children of container as objects
+   */
+  getChildren(predicateName: string): object[] {
+    return this.resource[this.getExpandedPredicate(predicateName)] || [];
+  }
+
+  /**
+   * Get children of container as Proxys
+   */
+  getLdpContains(): CustomGetter[] | null {
+    let children = this.resource[this.getExpandedPredicate('ldp:contains')];
+    if (!children) return null;
+    if (!Array.isArray(children)) children = [children]; // convert to array if compacted to 1 resource
+
+    const result = children
+      ? children.map((res: object) => {
+          let resource: any = store.get(res['@id']);
+          if (resource) return resource;
+
+          // if not in cache, generate the basic resource
+          resource = new CustomGetter(
+            res['@id'],
+            { '@id': res['@id'] },
+            this.clientContext,
+            this.serverContext,
+            this.parentId,
+          ).getProxy();
+          store.cacheResource(res['@id'], resource); // put it in cache
+          return resource; // and return it
+        })
+      : [];
+
+    return result;
+  }
+
+  merge(resource: CustomGetter) {
+    this.resource = {
+      ...this.getResourceData(),
+      ...resource.getResourceData(),
+    };
+  }
+
+  getResourceData(): object {
+    return this.resource;
+  }
+
+  /**
+   * return true resource seems complete
+   * @param prop
+   */
+  isFullResource(): boolean {
+    const propertiesKeys = Object.keys(this.resource).filter(
+      p => !p.startsWith('@'),
+    );
+    if (this.resource['@id'].startsWith('_:b')) return true; // anonymous node = considered as always full
+
+    if (
+      propertiesKeys.length === 1 &&
+      propertiesKeys[0] === this.getExpandedPredicate('permissions')
+    )
       return false;
+    if (propertiesKeys.length > 0) return true;
+
+    return false;
+  }
+
+  /**
+   * Get permissions of a resource
+   * @param resourceId
+   * @returns
+   */
+  async getPermissions(): Promise<string[]> {
+    let permissions = this.resource[this.getExpandedPredicate('permissions')];
+    if (!permissions) {
+      // if no permission, re-fetch data from store
+      await this.getResource(
+        this.resourceId,
+        { ...this.clientContext, ...this.serverContext },
+        this.parentId,
+        true,
+      );
+      permissions = this.resource[this.getExpandedPredicate('permissions')];
     }
 
-    /**
-     * Get permissions of a resource
-     * @param resourceId
-     * @returns 
-     */
-    async getPermissions(): Promise<string[]> {
-        let permissions = this.resource[this.getExpandedPredicate("permissions")];
-        if (!permissions) { // if no permission, re-fetch data from store
-            await this.getResource(
-                this.resourceId,
-                { ...this.clientContext, ...this.serverContext },
-                this.parentId,
-                true
-            );
-            permissions = this.resource[this.getExpandedPredicate("permissions")];
+    if (!Array.isArray(permissions)) permissions = [permissions]; // convert to array if compacted to 1 resource
+
+    return permissions ? permissions : [];
+  }
+
+  /**
+   * returns compacted @type of resource
+   */
+  getType(): string {
+    return this.resource['@type']
+      ? this.getCompactedIri(this.resource['@type'])
+      : '';
+  }
+
+  /**
+   * Remove the resource from the cache
+   */
+  clearCache(): void {
+    store.clearCache(this.resourceId);
+  }
+
+  getExpandedPredicate(property: string) {
+    return ContextParser.expandTerm(
+      property,
+      { ...this.clientContext, ...this.serverContext },
+      true,
+    );
+  }
+  getCompactedPredicate(property: string) {
+    return ContextParser.compactIri(
+      property,
+      { ...this.clientContext, ...this.serverContext },
+      true,
+    );
+  }
+  getCompactedIri(id: string) {
+    return ContextParser.compactIri(id, {
+      ...this.clientContext,
+      ...this.serverContext,
+    });
+  }
+  toString() {
+    return this.getCompactedIri(this.resource['@id']);
+  }
+  [Symbol.toPrimitive]() {
+    return this.getCompactedIri(this.resource['@id']);
+  }
+
+  /**
+   * Returns a Proxy which handles the different get requests
+   */
+  getProxy() {
+    return new Proxy(this, {
+      get: (resource, property) => {
+        if (!this.resource) return undefined;
+        if (typeof resource[property] === 'function')
+          return resource[property].bind(resource);
+
+        switch (property) {
+          case '@id':
+            if (this.resource['@id'])
+              return this.getCompactedIri(this.resource['@id']);
+            console.log(this.resource, this.resource['@id']);
+            return;
+          case '@type':
+            return this.resource['@type']; // return synchronously
+          case 'properties':
+            return this.getProperties();
+          case 'ldp:contains':
+            return this.getLdpContains(); // returns standard arrays synchronously
+          case 'permissions':
+            return this.getPermissions(); // get expanded permissions
+          case 'clientContext':
+            return this.clientContext; // get saved client context to re-fetch easily a resource
+          case 'serverContext':
+            return this.serverContext; // get saved client context to re-fetch easily a resource
+          case 'then':
+            return;
+          default:
+            // FIXME: missing 'await'
+            return resource.get(property);
         }
-
-        if (!Array.isArray(permissions)) permissions = [permissions]; // convert to array if compacted to 1 resource
-
-        return permissions ? permissions : [];
-    }
-
-    /**
-     * returns compacted @type of resource
-     */
-    getType(): string {
-        return this.resource['@type'] ? this.getCompactedIri(this.resource['@type']) : '';
-    }
-
-    /**
-     * Remove the resource from the cache
-     */
-    clearCache(): void {
-        store.clearCache(this.resourceId);
-    }
-
-    getExpandedPredicate(property: string) { return ContextParser.expandTerm(property, { ...this.clientContext, ...this.serverContext }, true) }
-    getCompactedPredicate(property: string) { return ContextParser.compactIri(property, { ...this.clientContext, ...this.serverContext }, true) }
-    getCompactedIri(id: string) { return ContextParser.compactIri(id, { ...this.clientContext, ...this.serverContext }) }
-    toString() { return this.getCompactedIri(this.resource['@id']) }
-    [Symbol.toPrimitive]() { return this.getCompactedIri(this.resource['@id']) }
-
-
-    /**
-     * Returns a Proxy which handles the different get requests
-     */
-    getProxy() {
-        return new Proxy(this, {
-            get: (resource, property) => {
-                if (!this.resource) return undefined;
-                if (typeof resource[property] === 'function') return resource[property].bind(resource);
-
-                switch (property) {
-                    case '@id':
-                        if (this.resource['@id'])
-                            return this.getCompactedIri(this.resource['@id']); // Compact @id if possible
-                        else
-                            console.log(this.resource, this.resource['@id']);
-                        return;
-                    case '@type':
-                        return this.resource['@type']; // return synchronously
-                    case 'properties':
-                        return this.getProperties();
-                    case 'ldp:contains':
-                        return this.getLdpContains(); // returns standard arrays synchronously
-                    case 'permissions':
-                        return this.getPermissions(); // get expanded permissions
-                    case 'clientContext':
-                        return this.clientContext; // get saved client context to re-fetch easily a resource
-                    case 'serverContext':
-                        return this.serverContext; // get saved client context to re-fetch easily a resource
-                    case 'then':
-                        return;
-                    default:
-                        // FIXME: missing 'await'
-                        return resource.get(property)
-                }
-            }
-        })
-    }
-}
\ No newline at end of file
+      },
+    });
+  }
+}
diff --git a/src/libs/store/server-pagination.ts b/src/libs/store/server-pagination.ts
index 4edcc9d87b1df0d542b2e3a6c162d41c84195884..3222a343813716163581662f134cd59f8e16f663 100644
--- a/src/libs/store/server-pagination.ts
+++ b/src/libs/store/server-pagination.ts
@@ -1,24 +1,29 @@
 export interface ServerPaginationOptions {
-    offset: number;
-    limit: number;
+  offset: number;
+  limit: number;
 }
 
 export function formatAttributesToServerPaginationOptions(
-    elementAttributes: { name: string, value: number }[]
+  elementAttributes: { name: string; value: number }[],
 ): ServerPaginationOptions | undefined {
-    const attributes = new Map(Array.from(elementAttributes).map(({ name, value }) => [name, value]))
-    const limit = attributes.get('limit');
-    const offset = attributes.get('offset');
-    if (!offset || !limit) return;
-    return {
-        limit: limit,
-        offset: offset,
-    }
+  const attributes = new Map(
+    Array.from(elementAttributes).map(({ name, value }) => [name, value]),
+  );
+  const limit = attributes.get('limit');
+  const offset = attributes.get('offset');
+  if (!offset || !limit) return;
+  return {
+    limit: limit,
+    offset: offset,
+  };
 }
 
-export function appendServerPaginationToIri(iri: string, options: ServerPaginationOptions): string {
-    const first = iri.includes('?') ? '&' : '?';
-    const limit = options.limit;
-    const offset = options.offset;
-    return `${iri}${first}limit=${limit}&offset=${offset}`;
-}
\ No newline at end of file
+export function appendServerPaginationToIri(
+  iri: string,
+  options: ServerPaginationOptions,
+): string {
+  const first = iri.includes('?') ? '&' : '?';
+  const limit = options.limit;
+  const offset = options.offset;
+  return `${iri}${first}limit=${limit}&offset=${offset}`;
+}
diff --git a/src/libs/store/server-search.ts b/src/libs/store/server-search.ts
index 2ca9e85b563a1a7278603fed17689a4a612ab18b..51b797564c3e056c8e17579c189d25c3e244724d 100644
--- a/src/libs/store/server-search.ts
+++ b/src/libs/store/server-search.ts
@@ -5,22 +5,27 @@ export interface ServerSearchOptions {
 }
 
 export function formatAttributesToServerSearchOptions(
-  elementAttributes: Iterable<Attr>
+  elementAttributes: Iterable<Attr>,
 ): Partial<ServerSearchOptions> {
-  const attributes = new Map(Array.from(elementAttributes).map(({ name, value }) => [name, value]));
-  const fields = attributes.get('server-search-fields')?.split(",").map((field) => field.trim());
+  const attributes = new Map(
+    Array.from(elementAttributes).map(({ name, value }) => [name, value]),
+  );
+  const fields = attributes
+    .get('server-search-fields')
+    ?.split(',')
+    .map(field => field.trim());
   const value = attributes.get('server-search-value')?.trim();
   const method = attributes.get('server-search-method')?.trim();
   return {
     fields: fields && fields.length > 0 ? fields : undefined,
     value: value ? value : undefined,
-    method: method ? method : undefined
-  }
+    method: method ? method : undefined,
+  };
 }
 
 export function mergeServerSearchOptions(
   attributesOptions?: Partial<ServerSearchOptions>,
-  dynamicOptions?: Partial<ServerSearchOptions>
+  dynamicOptions?: Partial<ServerSearchOptions>,
 ): ServerSearchOptions | undefined {
   const fields = attributesOptions?.fields ?? dynamicOptions?.fields;
   const value = dynamicOptions?.value ?? attributesOptions?.value;
@@ -29,10 +34,13 @@ export function mergeServerSearchOptions(
   return { fields, value, method };
 }
 
-export function appendServerSearchToIri(iri: string, options: ServerSearchOptions): string {
+export function appendServerSearchToIri(
+  iri: string,
+  options: ServerSearchOptions,
+): string {
   const first = iri.includes('?') ? '&' : '?';
   const fields = options.fields.map(encodeURIComponent).join(',');
   const value = encodeURIComponent(options.value);
   const method = encodeURIComponent(options.method ?? 'ibasic');
   return `${iri}${first}search-fields=${fields}&search-terms=${value}&search-method=${method}`;
-}
\ No newline at end of file
+}
diff --git a/src/libs/store/store.ts b/src/libs/store/store.ts
index c632f8506c412fc09c3c13ff29ec34655bc9a255..03342e7a0cd8fbacbd449d5fd383c00954b01d54 100644
--- a/src/libs/store/store.ts
+++ b/src/libs/store/store.ts
@@ -1,51 +1,50 @@
 import JSONLDContextParser from 'jsonld-context-parser';
-//@ts-ignore
-import PubSub from 'https://cdn.skypack.dev/pubsub-js';
+import PubSub from 'pubsub-js';
 
 import jsonld from 'jsonld';
-import { CustomGetter } from './custom-getter';
+import { CustomGetter } from './custom-getter.ts';
 
-import type { Resource } from '../../mixins/interfaces';
-import type { ServerSearchOptions } from './server-search';
-import { appendServerSearchToIri } from './server-search';
+import type { Resource } from '../../mixins/interfaces.ts';
+import type { ServerSearchOptions } from './server-search.ts';
+import { appendServerSearchToIri } from './server-search.ts';
 
-import type { ServerPaginationOptions } from './server-pagination';
-import { appendServerPaginationToIri } from './server-pagination';
+import type { ServerPaginationOptions } from './server-pagination.ts';
+import { appendServerPaginationToIri } from './server-pagination.ts';
 
 const ContextParser = JSONLDContextParser.ContextParser;
 const myParser = new ContextParser();
 
 export const base_context = {
-  '@vocab': "https://cdn.startinblox.com/owl#",
-  foaf: "http://xmlns.com/foaf/0.1/",
-  doap: "http://usefulinc.com/ns/doap#",
-  ldp: "http://www.w3.org/ns/ldp#",
-  rdfs: "http://www.w3.org/2000/01/rdf-schema#",
-  rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
-  xsd: "http://www.w3.org/2001/XMLSchema#",
-  geo: "http://www.w3.org/2003/01/geo/wgs84_pos#",
-  acl: "http://www.w3.org/ns/auth/acl#",
-  hd: "http://cdn.startinblox.com/owl/ttl/vocab.ttl#",
-  sib: "http://cdn.startinblox.com/owl/ttl/vocab.ttl#",
-  name: "rdfs:label",
-  deadline: "xsd:dateTime",
-  lat: "geo:lat",
-  lng: "geo:long",
-  jabberID: "foaf:jabberID",
-  permissions: "acl:accessControl",
-  mode: "acl:mode",
-  view: "acl:Read",
-  change: "acl:Write",
-  add: "acl:Append",
-  delete: "acl:Delete",
-  control: "acl:Control"
+  '@vocab': 'https://cdn.startinblox.com/owl#',
+  foaf: 'http://xmlns.com/foaf/0.1/',
+  doap: 'http://usefulinc.com/ns/doap#',
+  ldp: 'http://www.w3.org/ns/ldp#',
+  rdfs: 'http://www.w3.org/2000/01/rdf-schema#',
+  rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
+  xsd: 'http://www.w3.org/2001/XMLSchema#',
+  geo: 'http://www.w3.org/2003/01/geo/wgs84_pos#',
+  acl: 'http://www.w3.org/ns/auth/acl#',
+  hd: 'http://cdn.startinblox.com/owl/ttl/vocab.ttl#',
+  sib: 'http://cdn.startinblox.com/owl/ttl/vocab.ttl#',
+  name: 'rdfs:label',
+  deadline: 'xsd:dateTime',
+  lat: 'geo:lat',
+  lng: 'geo:long',
+  jabberID: 'foaf:jabberID',
+  permissions: 'acl:accessControl',
+  mode: 'acl:mode',
+  view: 'acl:Read',
+  change: 'acl:Write',
+  add: 'acl:Append',
+  delete: 'acl:Delete',
+  control: 'acl:Control',
 };
 
-class Store {
+export class Store {
   cache: Map<string, any>;
   subscriptionIndex: Map<string, any>; // index of all the containers per resource
   subscriptionVirtualContainersIndex: Map<string, any>; // index of all the containers per resource
-  loadingList: Set<String>;
+  loadingList: Set<string>;
   headers: object;
   fetch: Promise<any> | undefined;
   session: Promise<any> | undefined;
@@ -55,7 +54,11 @@ class Store {
     this.subscriptionIndex = new Map();
     this.subscriptionVirtualContainersIndex = new Map();
     this.loadingList = new Set();
-    this.headers = {'Accept': 'application/ld+json', 'Content-Type': 'application/ld+json', 'Cache-Control': 'must-revalidate'};
+    this.headers = {
+      Accept: 'application/ld+json',
+      'Content-Type': 'application/ld+json',
+      'Cache-Control': 'must-revalidate',
+    };
     this.fetch = this.storeOptions.fetchMethod;
     this.session = this.storeOptions.session;
   }
@@ -70,7 +73,7 @@ class Store {
    * @param serverPagination - Server pagination options
    * @param serverSearch - Server search options
    * @param predicateName - predicate name if we target a specific predicate from the resource, useful for arrays
-   * 
+   *
    * @returns The fetched resource
    *
    * @async
@@ -78,28 +81,35 @@ class Store {
   async getData(
     id: string,
     context: any = {},
-    parentId = "",
+    parentId = '',
     localData?: object,
-    forceFetch: boolean = false,
+    forceFetch = false,
     serverPagination?: ServerPaginationOptions,
-    serverSearch?: ServerSearchOptions
-  ): Promise<Resource|null> {
+    serverSearch?: ServerSearchOptions,
+  ): Promise<Resource | null> {
     let key = id;
     if (serverPagination) {
-      key = appendServerPaginationToIri(key, serverPagination)
+      key = appendServerPaginationToIri(key, serverPagination);
     }
 
     if (serverSearch) {
-      key = appendServerSearchToIri(key, serverSearch)
+      key = appendServerSearchToIri(key, serverSearch);
     }
 
-    if (localData == null && this.cache.has(key) && !this.loadingList.has(key)) {
+    if (
+      localData == null &&
+      this.cache.has(key) &&
+      !this.loadingList.has(key)
+    ) {
       const resource = this.get(key);
-      if (resource && resource.isFullResource?.() && !forceFetch) return resource; // if resource is not complete, re-fetch it
+      if (resource?.isFullResource?.() && !forceFetch) return await resource; // if resource is not complete, re-fetch it
     }
 
-    return new Promise(async (resolve) => {
-      document.addEventListener('resourceReady', this.resolveResource(key, resolve));
+    return new Promise(async resolve => {
+      document.addEventListener(
+        'resourceReady',
+        this.resolveResource(key, resolve),
+      );
 
       if (this.loadingList.has(key)) return;
       this.loadingList.add(key);
@@ -107,25 +117,57 @@ class Store {
       // Generate proxy
       const clientContext = await myParser.parse(context);
       let resource: any = null;
-      if(this._isLocalId(id)) {
-        if(localData == null) localData = {};
-        localData["@id"] = id;
+      if (this._isLocalId(id)) {
+        if (localData == null) localData = {};
+        localData['@id'] = id;
         resource = localData;
-      } else try {
-        resource = localData || await this.fetchData(id, clientContext, parentId, serverPagination, serverSearch);
-      } catch (error) { console.error(error) }
+      } else
+        try {
+          resource =
+            localData ||
+            (await this.fetchData(
+              id,
+              clientContext,
+              parentId,
+              serverPagination,
+              serverSearch,
+            ));
+        } catch (error) {
+          console.error(error);
+        }
       if (!resource) {
         this.loadingList.delete(key);
-        document.dispatchEvent(new CustomEvent('resourceReady', { detail: { id: key, resource: null, fetchedResource: null } }));
+        document.dispatchEvent(
+          new CustomEvent('resourceReady', {
+            detail: { id: key, resource: null, fetchedResource: null },
+          }),
+        );
         return;
       }
 
-      const serverContext = await myParser.parse([resource['@context'] || base_context]);
+      const serverContext = await myParser.parse([
+        resource['@context'] || base_context,
+      ]);
       // const resourceProxy = new CustomGetter(key, resource, clientContext, serverContext, parentId ? parentId : key, serverPagination, serverSearch).getProxy();
       // Cache proxy
-      await this.cacheGraph(resource, clientContext, serverContext, parentId ? parentId : key, serverPagination, serverSearch);
+      await this.cacheGraph(
+        resource,
+        clientContext,
+        serverContext,
+        parentId ? parentId : key,
+        serverPagination,
+        serverSearch,
+      );
       this.loadingList.delete(key);
-      document.dispatchEvent(new CustomEvent('resourceReady', { detail: { id: key, resource: this.get(key), fetchedResource: resource } }));
+      document.dispatchEvent(
+        new CustomEvent('resourceReady', {
+          detail: {
+            id: key,
+            resource: this.get(key),
+            fetchedResource: resource,
+          },
+        }),
+      );
     });
   }
 
@@ -133,14 +175,14 @@ class Store {
     let authenticated = false;
     if (this.session) authenticated = await this.session;
 
-    if (this.fetch && authenticated) { // authenticated
-      return this.fetch.then(fn => fn(iri, options))
-    } else { // anonymous
-      if (options.headers) options.headers = this._convertHeaders(options.headers);
-      return fetch(iri, options).then(function(response) {
-        return response;
-      });
+    if (this.fetch && authenticated) {
+      // authenticated
+      return this.fetch.then(fn => fn(iri, options));
     }
+    // anonymous
+    if (options.headers)
+      options.headers = this._convertHeaders(options.headers);
+    return fetch(iri, options).then(response => response);
   }
 
   /**
@@ -155,21 +197,21 @@ class Store {
   async fetchData(
     id: string,
     context = {},
-    parentId = "",
+    parentId = '',
     serverPagination?: ServerPaginationOptions,
-    serverSearch?: ServerSearchOptions
+    serverSearch?: ServerSearchOptions,
   ) {
     let iri = this._getAbsoluteIri(id, context, parentId);
-    if (serverPagination) iri = appendServerPaginationToIri(iri, serverPagination);
+    if (serverPagination)
+      iri = appendServerPaginationToIri(iri, serverPagination);
     if (serverSearch) iri = appendServerSearchToIri(iri, serverSearch);
 
     const headers = {
       ...this.headers,
-      'accept-language': this._getLanguage()
+      'accept-language': this._getLanguage(),
       // 'Prefer' : 'return=representation; max-triple-count="100"' // Commenting out for now as it raises CORS errors
     };
 
-
     /**
      * Fetch data with authentication if available (sib-auth)
      * @param iri - iri to call
@@ -179,14 +221,14 @@ class Store {
     return this.fetchAuthn(iri, {
       method: 'GET',
       headers: headers,
-      credentials: 'include'
-    }).then((response) => {
+      credentials: 'include',
+    }).then(response => {
       if (!response.ok) return;
       return response.json();
-    })
+    });
   }
 
-    /**
+  /**
    * Cache the whole graph
    * @param resource - graph fetched
    * @param clientContext - context of the client app
@@ -201,7 +243,7 @@ class Store {
     parentContext: object,
     parentId: string,
     serverPagination?: ServerPaginationOptions,
-    serverSearch?: ServerSearchOptions
+    serverSearch?: ServerSearchOptions,
   ) {
     // Flatten and compact the graph, which is an issue with large containers having child permissions serialized
     // Because
@@ -211,11 +253,13 @@ class Store {
     // So either we do not modify the key of the blank nodes to force them into the cache
     // Either we modify it by adding the parentId and we end up with
     // a lot of cached permissions objects associated with the container top resource (like xxxxx/circles/)
-    const flattenedResources = await jsonld.flatten(resource);
-    const compactedResources: any[] = await Promise.all(flattenedResources.map(r => jsonld.compact(r, {})))
-    for (let resource of compactedResources) {
-      let id = resource['@id'] || resource['id'];
-      let key = resource['@id'] || resource['id'];
+    const flattenedResources: any = await jsonld.flatten(resource);
+    const compactedResources: any[] = await Promise.all(
+      flattenedResources.map(r => jsonld.compact(r, {})),
+    );
+    for (const resource of compactedResources) {
+      const id = resource['@id'] || resource.id;
+      let key = resource['@id'] || resource.id;
 
       if (!key) console.log('No key or id for resource:', resource);
       if (key === '/') key = parentId;
@@ -225,17 +269,34 @@ class Store {
       // Using a dedicated method in the custom-getter.
 
       // We have to add the server search and pagination attributes again here to the resource cache key
-      if (key === id && resource['@type'] == this.getExpandedPredicate("ldp:Container", clientContext)) { // Add only pagination and search params to the original resource
-        if (serverPagination) key = appendServerPaginationToIri(key, serverPagination);
+      if (
+        key === id &&
+        resource['@type'] ===
+          this.getExpandedPredicate('ldp:Container', clientContext)
+      ) {
+        // Add only pagination and search params to the original resource
+        if (serverPagination)
+          key = appendServerPaginationToIri(key, serverPagination);
         if (serverSearch) key = appendServerSearchToIri(key, serverSearch);
       }
 
-      const resourceProxy = new CustomGetter(key, resource, clientContext, parentContext, parentId, serverPagination, serverSearch).getProxy();
-      if (resourceProxy.isContainer()) this.subscribeChildren(resourceProxy, id);
-
-      if (this.get(key)) { // if already cached, merge data
+      const resourceProxy = new CustomGetter(
+        key,
+        resource,
+        clientContext,
+        parentContext,
+        parentId,
+        serverPagination,
+        serverSearch,
+      ).getProxy();
+      if (resourceProxy.isContainer())
+        this.subscribeChildren(resourceProxy, id);
+
+      if (this.get(key)) {
+        // if already cached, merge data
         this.cache.get(key).merge(resourceProxy);
-      } else {  // else, put in cache
+      } else {
+        // else, put in cache
         this.cacheResource(key, resourceProxy);
       }
     }
@@ -263,14 +324,16 @@ class Store {
         method: method,
         headers: this.headers,
         body: JSON.stringify(resource),
-        credentials: 'include'
+        credentials: 'include',
       });
 
     const resourceProxy = store.get(id);
-    const clientContext = resourceProxy ? {...resourceProxy.clientContext, ...resource['@context']} : resource['@context']
+    const clientContext = resourceProxy
+      ? { ...resourceProxy.clientContext, ...resource['@context'] }
+      : resource['@context'];
     this.clearCache(id);
     await this.getData(id, clientContext, '', resource);
-    return {ok: true}
+    return { ok: true };
   }
 
   /**
@@ -279,11 +342,11 @@ class Store {
    */
   subscribeChildren(container: CustomGetter, containerId: string) {
     if (!container['ldp:contains']) return;
-    for (let res of container['ldp:contains']) {
-      this.subscribeResourceTo(containerId, res['@id'] || res['id']);
+    for (const res of container['ldp:contains']) {
+      this.subscribeResourceTo(containerId, res['@id'] || res.id);
     }
   }
-  
+
   /**
    * Update a resource
    * @param method - can be POST, PUT or PATCH
@@ -292,27 +355,39 @@ class Store {
    * @returns void
    */
   async _updateResource(method: string, resource: object, id: string) {
-    if (!['POST', 'PUT', 'PATCH', '_LOCAL'].includes(method)) throw new Error('Error: method not allowed');
+    if (!['POST', 'PUT', 'PATCH', '_LOCAL'].includes(method))
+      throw new Error('Error: method not allowed');
 
     const context = await myParser.parse([resource['@context'] || {}]); // parse context before expandTerm
     const expandedId = this._getExpandedId(id, context);
-    return this._fetch(method, resource, id).then(async(response) => {
+    return this._fetch(method, resource, id).then(async response => {
       if (response.ok) {
-        if(method !== '_LOCAL') {
+        if (method !== '_LOCAL') {
           this.clearCache(expandedId);
         } // clear cache
-        this.getData(expandedId, resource['@context']).then(async () => { // re-fetch data
+        this.getData(expandedId, resource['@context']).then(async () => {
+          // re-fetch data
           const nestedResources = await this.getNestedResources(resource, id);
-          const resourcesToRefresh = this.subscriptionVirtualContainersIndex.get(expandedId) || [];
-          const resourcesToNotify = this.subscriptionIndex.get(expandedId) || [];
-
-          return this.refreshResources([...nestedResources, ...resourcesToRefresh]) // refresh related resources
-            .then(resourceIds => this.notifyResources([expandedId, ...resourceIds, ...resourcesToNotify])); // notify components
+          const resourcesToRefresh =
+            this.subscriptionVirtualContainersIndex.get(expandedId) || [];
+          const resourcesToNotify =
+            this.subscriptionIndex.get(expandedId) || [];
+
+          return this.refreshResources([
+            ...nestedResources,
+            ...resourcesToRefresh,
+          ]) // refresh related resources
+            .then(resourceIds =>
+              this.notifyResources([
+                expandedId,
+                ...resourceIds,
+                ...resourcesToNotify,
+              ]),
+            ); // notify components
         });
         return response.headers?.get('Location') || null;
-      } else {
-        throw response;
       }
+      throw response;
     });
   }
 
@@ -323,18 +398,25 @@ class Store {
    */
   async refreshResources(resourceIds: string[]) {
     resourceIds = [...new Set(resourceIds.filter(id => this.cache.has(id)))]; // remove duplicates and not cached resources
-    const resourceWithContexts = resourceIds.map(resourceId => ({ "id": resourceId, "context": store.get(resourceId)?.clientContext }));
+    const resourceWithContexts = resourceIds.map(resourceId => ({
+      id: resourceId,
+      context: store.get(resourceId)?.clientContext,
+    }));
     for (const resource of resourceWithContexts) {
       if (!this._isLocalId(resource.id)) this.clearCache(resource.id);
     }
-    await Promise.all(resourceWithContexts.map(({ id, context }) => this.getData(id, context || base_context)))
+    await Promise.all(
+      resourceWithContexts.map(({ id, context }) =>
+        this.getData(id, context || base_context),
+      ),
+    );
     return resourceIds;
   }
   /**
    * Notifies all components for a list of ids
    * @param resourceIds -
    */
-  async notifyResources(resourceIds: string[]) {
+  notifyResources(resourceIds: string[]) {
     resourceIds = [...new Set(resourceIds)]; // remove duplicates
     for (const id of resourceIds) PubSub.publish(id);
   }
@@ -344,16 +426,18 @@ class Store {
    * @param resource - object
    * @param id - string
    */
-  async getNestedResources(resource: object, id: string) {
+  getNestedResources(resource: object, id: string) {
     const cachedResource = store.get(id);
     if (!cachedResource || cachedResource.isContainer?.()) return [];
-    let nestedProperties:any[] = [];
+    const nestedProperties: any[] = [];
     const excludeKeys = ['@context'];
-    for (let p of Object.keys(resource)) {
-      if (resource[p]
-        && typeof resource[p] === 'object'
-        && !excludeKeys.includes(p)
-        && resource[p]['@id']) {
+    for (const p of Object.keys(resource)) {
+      if (
+        resource[p] &&
+        typeof resource[p] === 'object' &&
+        !excludeKeys.includes(p) &&
+        resource[p]['@id']
+      ) {
         nestedProperties.push(resource[p]['@id']);
       }
     }
@@ -366,7 +450,11 @@ class Store {
    *
    * @returns Resource (Proxy) if in the cache, null otherwise
    */
-  get(id: string, serverPagination?: ServerPaginationOptions, serverSearch?: ServerSearchOptions): Resource | null {
+  get(
+    id: string,
+    serverPagination?: ServerPaginationOptions,
+    serverSearch?: ServerSearchOptions,
+  ): Resource | null {
     if (serverPagination) {
       id = appendServerPaginationToIri(id, serverPagination);
     }
@@ -378,7 +466,6 @@ class Store {
     return this.cache.get(id) || null;
   }
 
-
   /**
    * Removes a resource from the cache
    * @param id - id of the resource to remove from the cache
@@ -388,9 +475,10 @@ class Store {
       // For federation, clear each source
       const resource = this.cache.get(id);
       if (resource['@type'] === 'ldp:Container') {
-        resource['ldp:contains'].forEach((child: object) => {
-          if (child && child['@type'] === 'ldp:Container') this.cache.delete(child['@id'])
-        })
+        for (const child of resource['ldp:contains']) {
+          if (child && child['@type'] === 'ldp:Container')
+            this.cache.delete(child['@id']);
+        }
       }
 
       this.cache.delete(id);
@@ -404,7 +492,7 @@ class Store {
    *
    * @returns id of the posted resource
    */
-  async setLocalData(resource: object, id: string): Promise<string | null> {
+  setLocalData(resource: object, id: string): Promise<string | null> {
     return this._updateResource('_LOCAL', resource, id);
   }
 
@@ -415,7 +503,7 @@ class Store {
    *
    * @returns id of the posted resource
    */
-  async post(resource: object, id: string): Promise<string | null> {
+  post(resource: object, id: string): Promise<string | null> {
     return this._updateResource('POST', resource, id);
   }
 
@@ -426,7 +514,7 @@ class Store {
    *
    * @returns id of the edited resource
    */
-  async put(resource: object, id: string): Promise<string | null> {
+  put(resource: object, id: string): Promise<string | null> {
     return this._updateResource('PUT', resource, id);
   }
 
@@ -437,7 +525,7 @@ class Store {
    *
    * @returns id of the edited resource
    */
-  async patch(resource: object, id: string): Promise<string | null> {
+  patch(resource: object, id: string): Promise<string | null> {
     return this._updateResource('PATCH', resource, id);
   }
 
@@ -453,14 +541,16 @@ class Store {
     const deleted = await this.fetchAuthn(expandedId, {
       method: 'DELETE',
       headers: this.headers,
-      credentials: 'include'
+      credentials: 'include',
     });
 
-    const resourcesToNotify = this.subscriptionIndex.get(expandedId) || [];
-    const resourcesToRefresh = this.subscriptionVirtualContainersIndex.get(expandedId) || [];
+    const resourcesToNotify = this.subscriptionIndex.get(expandedId) || [];
+    const resourcesToRefresh =
+      this.subscriptionVirtualContainersIndex.get(expandedId) || [];
 
-    this.refreshResources([...resourcesToNotify, ...resourcesToRefresh])
-      .then(resourceIds => this.notifyResources(resourceIds));
+    this.refreshResources([...resourcesToNotify, ...resourcesToRefresh]).then(
+      resourceIds => this.notifyResources(resourceIds),
+    );
 
     return deleted;
   }
@@ -472,14 +562,16 @@ class Store {
    */
   _convertHeaders(headersObject: object): Headers {
     const headers = new Headers();
-    for (const [key, value] of Object.entries(headersObject)){
+    for (const [key, value] of Object.entries(headersObject)) {
       headers.set(key, value as string);
     }
     return headers;
   }
 
   _getExpandedId(id: string, context: object) {
-    return (context && Object.keys(context)) ? ContextParser.expandTerm(id, context) : id;
+    return context && Object.keys(context)
+      ? ContextParser.expandTerm(id, context)
+      : id;
   }
 
   /**
@@ -489,9 +581,8 @@ class Store {
    * @returns The fully expanded term
    */
   getExpandedPredicate(property: string, context: object | null) {
-    if (!context)
-      return ContextParser.expandTerm(property, base_context, true)
-    return ContextParser.expandTerm(property, context, true)
+    if (!context) return ContextParser.expandTerm(property, base_context, true);
+    return ContextParser.expandTerm(property, context, true);
   }
 
   /**
@@ -501,9 +592,8 @@ class Store {
    * @returns The compacted term
    */
   getCompactedIri(property: string, context: object | null) {
-    if (!context)
-      return ContextParser.compactIri(property, base_context, true)
-    return ContextParser.compactIri(property, context, true)
+    if (!context) return ContextParser.compactIri(property, base_context, true);
+    return ContextParser.compactIri(property, context, true);
   }
 
   /**
@@ -521,8 +611,11 @@ class Store {
    * @param nestedResourceId - id of the resource which will change
    */
   subscribeResourceTo(resourceId: string, nestedResourceId: string) {
-    const existingSubscriptions = this.subscriptionIndex.get(nestedResourceId) || [];
-    this.subscriptionIndex.set(nestedResourceId, [...new Set([...existingSubscriptions, resourceId])])
+    const existingSubscriptions =
+      this.subscriptionIndex.get(nestedResourceId) || [];
+    this.subscriptionIndex.set(nestedResourceId, [
+      ...new Set([...existingSubscriptions, resourceId]),
+    ]);
   }
 
   /**
@@ -530,9 +623,15 @@ class Store {
    * @param virtualContainerId - id of the container which needs to be updated
    * @param nestedResourceId - id of the resource which will change
    */
-  subscribeVirtualContainerTo(virtualContainerId: string, nestedResourceId: string) {
-    const existingSubscriptions = this.subscriptionVirtualContainersIndex.get(nestedResourceId) || [];
-    this.subscriptionVirtualContainersIndex.set(nestedResourceId, [...new Set([...existingSubscriptions, virtualContainerId])])
+  subscribeVirtualContainerTo(
+    virtualContainerId: string,
+    nestedResourceId: string,
+  ) {
+    const existingSubscriptions =
+      this.subscriptionVirtualContainersIndex.get(nestedResourceId) || [];
+    this.subscriptionVirtualContainersIndex.set(nestedResourceId, [
+      ...new Set([...existingSubscriptions, virtualContainerId]),
+    ]);
   }
 
   /**
@@ -543,8 +642,9 @@ class Store {
    */
   _getAbsoluteIri(id: string, context: object, parentId: string): string {
     let iri = ContextParser.expandTerm(id, context); // expand if reduced ids
-    if (parentId && !parentId.startsWith('store://local')) { // and get full URL from parent caller for local files
-      let parentIri = new URL(parentId, document.location.href).href;
+    if (parentId && !parentId.startsWith('store://local')) {
+      // and get full URL from parent caller for local files
+      const parentIri = new URL(parentId, document.location.href).href;
       iri = new URL(iri, parentIri).href;
     } else {
       iri = new URL(iri, document.location.href).href;
@@ -563,7 +663,9 @@ class Store {
    * Return language of the users
    */
   _getLanguage() {
-    return localStorage.getItem('language') || window.navigator.language.slice(0,2);
+    return (
+      localStorage.getItem('language') || window.navigator.language.slice(0, 2)
+    );
   }
 
   /**
@@ -574,10 +676,10 @@ class Store {
     localStorage.setItem('language', selectedLanguageCode);
   }
 
-  resolveResource = function(id: string, resolve) {
-    const handler = function(event) {
+  resolveResource = (id: string, resolve) => {
+    const handler = event => {
       if (event.detail.id === id) {
-        if(event.detail.resource) {
+        if (event.detail.resource) {
           resolve(event.detail.resource);
         } else {
           resolve(event.detail.fetchedResource);
@@ -595,18 +697,18 @@ if (window.sibStore) {
   store = window.sibStore;
 } else {
   const sibAuth = document.querySelector('sib-auth');
-  const storeOptions: StoreOptions = {}
+  const storeOptions: StoreOptions = {};
 
   if (sibAuth) {
     const sibAuthDefined = customElements.whenDefined(sibAuth.localName);
-    storeOptions.session = sibAuthDefined.then(() => (sibAuth as any).session)
-    storeOptions.fetchMethod = sibAuthDefined.then(() => (sibAuth as any).getFetch())
+    storeOptions.session = sibAuthDefined.then(() => (sibAuth as any).session);
+    storeOptions.fetchMethod = sibAuthDefined.then(() =>
+      (sibAuth as any).getFetch(),
+    );
   }
 
   store = new Store(storeOptions);
   window.sibStore = store;
 }
 
-export {
-  store
-};
+export { store };
diff --git a/src/locales/en.json b/src/locales/en.json
index 723755c3fe341dba83739c491b8fe022d9c5baf2..c75d4106575d6c6038133fa0324bf7e349bcd3b1 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -1,11 +1,11 @@
 {
-    "autocompletion.placeholder": "Select a value",
-    "autocompletion.searchPlaceholder": "Search",
-    "autocompletion.searchText": "No result",
-    "solid-delete.button": "Delete",
-    "solid-form.submit-button": "Submit",
-    "solid-form.validation-error": "A validation error occurred.",
-    "validation.message": "Please, confirm your choice",
-    "validation.submit-text": "Yes",
-    "validation.cancel-text": "Cancel"
-}
\ No newline at end of file
+  "autocompletion.placeholder": "Select a value",
+  "autocompletion.searchPlaceholder": "Search",
+  "autocompletion.searchText": "No result",
+  "solid-delete.button": "Delete",
+  "solid-form.submit-button": "Submit",
+  "solid-form.validation-error": "A validation error occurred.",
+  "validation.message": "Please, confirm your choice",
+  "validation.submit-text": "Yes",
+  "validation.cancel-text": "Cancel"
+}
diff --git a/src/locales/fr.json b/src/locales/fr.json
index d1c9c5fda9aedce0eb20c3894cdcbe8f418d83c0..e2d66bf1c70628b3e7c3d58a82779fc50aa2505b 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -1,11 +1,11 @@
 {
-    "autocompletion.placeholder": "Sélectionner une valeur",
-    "autocompletion.searchPlaceholder": "Rechercher",
-    "autocompletion.searchText": "Aucun résultat",
-    "solid-delete.button": "Supprimer",
-    "solid-form.submit-button": "Envoyer",
-    "solid-form.validation-error": "Erreur de validation.",
-    "validation.message": "Merci de confirmer votre choix",
-    "validation.submit-text": "Oui",
-    "validation.cancel-text": "Annuler"
-}
\ No newline at end of file
+  "autocompletion.placeholder": "Sélectionner une valeur",
+  "autocompletion.searchPlaceholder": "Rechercher",
+  "autocompletion.searchText": "Aucun résultat",
+  "solid-delete.button": "Supprimer",
+  "solid-form.submit-button": "Envoyer",
+  "solid-form.validation-error": "Erreur de validation.",
+  "validation.message": "Merci de confirmer votre choix",
+  "validation.submit-text": "Oui",
+  "validation.cancel-text": "Annuler"
+}
diff --git a/src/logger.ts b/src/logger.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5a3f1cdb81336d32e7ab7094aa391b3c324ab45b
--- /dev/null
+++ b/src/logger.ts
@@ -0,0 +1,203 @@
+import log from 'loglevel';
+
+const colors = {
+  reset: '\x1b[0m',
+  trace: '\x1b[38;2;169;169;169m', // Gray
+  debug: '\x1b[38;2;0;0;255m', // Blue
+  info: '\x1b[38;2;0;128;0m', // Green
+  warn: '\x1b[38;2;218;165;32m', // Yellow
+  error: '\x1b[38;2;255;0;0m', // Red
+};
+
+function formatMessage(level: log.LogLevelNames, messages: unknown[]) {
+  const timestamp = new Date().toISOString();
+  const color = colors[level] || colors.reset;
+
+  // Convert each message to a string, including objects
+  const formattedMessages = messages
+    .map(msg => {
+      if (typeof msg === 'object') {
+        try {
+          return JSON.stringify(msg, null, 2);
+        } catch {
+          return String(msg);
+        }
+      }
+      return String(msg);
+    })
+    .join(' ');
+
+  return `${color}[${timestamp}] ${formattedMessages}${colors.reset}`;
+}
+
+const originalFactory = log.methodFactory;
+
+log.methodFactory = (methodName, logLevel, loggerName) => {
+  const rawMethod = originalFactory(methodName, logLevel, loggerName);
+  return (...messages) => {
+    rawMethod(formatMessage(methodName, messages));
+  };
+};
+
+// Manage the DEBUG environment variable
+if (import.meta.env?.VITE_DEBUG === 'True') {
+  log.setLevel('debug');
+} else {
+  log.setLevel('warn');
+}
+
+// Async HOF to log render times and time execution
+export function trackRenderAsync(fn: Function, context?: string) {
+  return async function (...args: unknown[]) {
+    let componentName = context
+      ? context
+      : this.name
+        ? this.name
+        : this.constructor.name;
+    if (this.element.id) {
+      componentName += ` (id: ${this.element.id})`;
+    } else if (this.dataSrc) {
+      componentName += ` (data-src: ${this.dataSrc})`;
+    } else if (this.resourceId) {
+      componentName += ` (resourceId: ${this.resourceId})`;
+    }
+
+    const startTime = performance.now();
+    const result = await fn.apply(this, args);
+    const endTime = performance.now();
+    const renderTime = endTime - startTime;
+
+    if (this.profiler) {
+      this.profiler.updateStats(componentName, renderTime);
+      this.profiler.printStats();
+    } else {
+      log.debug(
+        `Component ${componentName} rendered in ${renderTime.toFixed(2)} ms`,
+      );
+    }
+
+    return result;
+  };
+}
+
+// HOF to log render times and time execution
+export function trackRender(fn: Function, context?: string) {
+  return function (...args: unknown[]) {
+    let componentName = context
+      ? context
+      : this.name
+        ? this.name
+        : this.constructor.name;
+
+    if (this.element.id) {
+      componentName += ` (id: ${this.element.id})`;
+    } else if (this.dataSrc) {
+      componentName += ` (data-src: ${this.dataSrc})`;
+    } else if (this.resourceId) {
+      componentName += ` (resourceId: ${this.resourceId})`;
+    }
+
+    const startTime = performance.now();
+    const result = fn.apply(this, args);
+    const endTime = performance.now();
+    const renderTime = endTime - startTime;
+
+    if (this.profiler) {
+      this.profiler.updateStats(componentName, renderTime);
+      this.profiler.printStats();
+    } else {
+      log.debug(
+        `Component ${componentName} rendered in ${renderTime.toFixed(2)} ms`,
+      );
+    }
+
+    return result;
+  };
+}
+
+export type PerformanceMetrics = {
+  renderCount: number; // Combien de fois le composant a été rendu
+  totalExecutionTime: number; // Temps total d'exécution (en ms)
+  lastExecutionTime: number; // Temps d'exécution lors du dernier rendu
+  averageExecutionTime: number;
+  minExecutionTime: number;
+  maxExecutionTime: number;
+};
+
+export class Profiler {
+  private stats: { [componentName: string]: PerformanceMetrics } = {};
+
+  constructor() {
+    this.stats = {};
+  }
+
+  private getOrCreateStats(componentName: string): PerformanceMetrics {
+    if (!this.stats[componentName]) {
+      this.stats[componentName] = {
+        renderCount: 0,
+        totalExecutionTime: 0,
+        lastExecutionTime: 0,
+        averageExecutionTime: 0,
+        minExecutionTime: Number.POSITIVE_INFINITY,
+        maxExecutionTime: 0,
+      };
+    }
+    return this.stats[componentName];
+  }
+
+  public getStats(componentName: string): PerformanceMetrics | undefined {
+    return this.stats[componentName];
+  }
+
+  public updateStats(componentName: string, renderTime: number): void {
+    const stats = this.getOrCreateStats(componentName);
+    stats.renderCount++;
+    stats.lastExecutionTime = renderTime;
+    stats.totalExecutionTime += renderTime;
+    stats.averageExecutionTime = stats.totalExecutionTime / stats.renderCount;
+    stats.minExecutionTime = Math.min(stats.minExecutionTime, renderTime);
+    stats.maxExecutionTime = Math.max(stats.maxExecutionTime, renderTime);
+  }
+
+  private formatTime(time: number): string {
+    if (time >= 1000) {
+      return `${(time / 1000).toFixed(2)} seconds`;
+    }
+    return `${time.toFixed(2)} ms`;
+  }
+
+  private formatComponentStats(
+    componentName: string,
+    stats: PerformanceMetrics,
+  ): string {
+    return (
+      `\nComponent: ${componentName}\n` +
+      `  Render Count: ${stats.renderCount}\n` +
+      `  Total Execution Time: ${this.formatTime(stats.totalExecutionTime)}\n` +
+      `  Last Execution Time: ${this.formatTime(stats.lastExecutionTime)}\n` +
+      `  Average Execution Time: ${this.formatTime(stats.averageExecutionTime)}\n` +
+      `  Min Execution Time: ${this.formatTime(stats.minExecutionTime)}\n` +
+      `  Max Execution Time: ${this.formatTime(stats.maxExecutionTime)}\n`
+    );
+  }
+
+  public printStats(componentName: string): void {
+    let output = 'Component Performance Stats:\n';
+
+    if (componentName) {
+      const stats = this.stats[componentName];
+      if (!stats) {
+        output += `Component ${componentName} not found.\n`;
+      } else {
+        output += this.formatComponentStats(componentName, stats);
+      }
+    } else {
+      for (const [name, stats] of Object.entries(this.stats)) {
+        output += this.formatComponentStats(name, stats);
+      }
+    }
+    log.debug(output);
+  }
+}
+
+export { log as logger };
diff --git a/src/mixins/attributeBinderMixin.ts b/src/mixins/attributeBinderMixin.ts
index 21c0b3c7f8fdcad527193027e6e62a1676f89932..e7db4d1d354ad6c9606d78eecc0d3f9fadd22448 100644
--- a/src/mixins/attributeBinderMixin.ts
+++ b/src/mixins/attributeBinderMixin.ts
@@ -1,11 +1,11 @@
-import { base_context, store } from '../libs/store/store';
-import type { Resource } from './interfaces';
+import { base_context, store } from '../libs/store/store.ts';
+import type { Resource } from './interfaces.ts';
 
 const AttributeBinderMixin = {
   name: 'attribute-binder-mixin',
   use: [],
   initialState: {
-    bindedAttributes: null
+    bindedAttributes: null,
   },
   created() {
     this.bindedAttributes = {};
@@ -14,7 +14,7 @@ const AttributeBinderMixin = {
    * Reset attributes values
    */
   resetAttributesData() {
-    for (let attr of Object.keys(this.bindedAttributes)) {
+    for (const attr of Object.keys(this.bindedAttributes)) {
       this.element.setAttribute(attr, this.bindedAttributes[attr]);
     }
   },
@@ -25,25 +25,24 @@ const AttributeBinderMixin = {
   async replaceAttributesData(reset = true) {
     if (reset) this.resetAttributesData();
 
-    const oldAttributes: any = Array.from(this.element.attributes) // transform NamedNodeMap in object
-      .reduce((obj: any, attr: any) => {
-        
-        // Keep only attributes starting with `store://...`
-        if (!attr.value.match(/^store:\/\/(resource|container|user)/)) return { ...obj }
+    const oldAttributes: Record<string, string> = {};
+    for (const attr of (this.element as Element).attributes) {
+      if (!attr.value.match(/^store:\/\/(resource|container|user)/)) continue;
 
-        // Save attr for reset later
-        if (!this.bindedAttributes[attr.name]) this.bindedAttributes[attr.name] = attr.value;
+      if (!this.bindedAttributes[attr.name])
+        this.bindedAttributes[attr.name] = attr.value;
 
-        return {
-          ...obj,
-          [attr.name]: attr.value, // add "key: value"
-        };
-      }, {});
+      oldAttributes[attr.name] = attr.value;
+    }
 
-    const newAttributes = await this.transformAttributes({ ...oldAttributes }, this.resource); // generate new attributes
+    const newAttributes = await this.transformAttributes(
+      { ...oldAttributes },
+      this.resource,
+    ); // generate new attributes
 
-    for (let attr of Object.keys(newAttributes)) { // set attributes on element
-      if (oldAttributes[attr] == newAttributes[attr]) continue; // only if it changed
+    for (const attr of Object.keys(newAttributes)) {
+      // set attributes on element
+      if (oldAttributes[attr] === newAttributes[attr]) continue; // only if it changed
       this.element.setAttribute(attr, newAttributes[attr]);
     }
   },
@@ -55,29 +54,38 @@ const AttributeBinderMixin = {
    * @returns - object representing attributes of an element with resolved values
    */
   async transformAttributes(attributes: object, resource: Resource) {
-    const isContainer = resource && resource.isContainer?.();
+    const isContainer = resource?.isContainer?.();
 
-    for (let attr of Object.keys(attributes)) {
+    for (const attr of Object.keys(attributes)) {
       const value = attributes[attr];
       // Avoid error if value is a number
       if (typeof value === 'string') {
         // Replace attribute value
-        if (!isContainer && resource && value.startsWith('store://resource')) { // RESOURCE
-          let path = value.replace('store://resource.', '');
+        if (!isContainer && resource && value.startsWith('store://resource')) {
+          // RESOURCE
+          const path = value.replace('store://resource.', '');
           attributes[attr] = resource ? await resource[path] : '';
-        } else if (isContainer && resource && value.startsWith('store://container')) { // CONTAINER
-          let path = value.replace('store://container.', '');
+        } else if (
+          isContainer &&
+          resource &&
+          value.startsWith('store://container')
+        ) {
+          // CONTAINER
+          const path = value.replace('store://container.', '');
           attributes[attr] = resource ? await resource[path] : '';
-        } else if (value.startsWith('store://user')) { // USER
+        } else if (value.startsWith('store://user')) {
+          // USER
           // retry until sibAuth is defined
           const userId = await this.retry(this.getUser.bind(this));
           // TODO: Using this.context makes no sense here. Use same-attribute-context="context-id" instead?
-          const user = userId && userId['@id'] ? await store.getData(userId['@id'], this.context || base_context) : null;
+          const user = userId?.['@id']
+            ? await store.getData(userId['@id'], this.context || base_context)
+            : null;
           if (!user) {
             attributes[attr] = '';
             continue;
           }
-          let path = value.replace('store://user.', '');
+          const path = value.replace('store://user.', '');
           attributes[attr] = user ? await user[path] : '';
         }
       }
@@ -91,7 +99,7 @@ const AttributeBinderMixin = {
    */
   async getUser() {
     const sibAuth: any = document.querySelector('sib-auth');
-    return sibAuth.getUser();
+    return await sibAuth.getUser();
   },
 
   /**
@@ -104,17 +112,17 @@ const AttributeBinderMixin = {
   async retry(fn: Function, ms = 200, maxRetries = 5) {
     return new Promise((resolve, reject) => {
       let retries = 0;
-      fn().then(resolve).catch(() => {
-        setTimeout(() => {
-          ++retries;
-          if (retries == maxRetries) return reject();
-          this.retry(fn, ms).then(resolve);
-        }, ms);
-      });
+      fn()
+        .then(resolve)
+        .catch(() => {
+          setTimeout(() => {
+            ++retries;
+            if (retries >= maxRetries) return reject();
+            this.retry(fn, ms).then(resolve);
+          }, ms);
+        });
     });
-  }
-}
+  },
+};
 
-export {
-  AttributeBinderMixin
-}
\ No newline at end of file
+export { AttributeBinderMixin };
diff --git a/src/mixins/contextMixin.ts b/src/mixins/contextMixin.ts
index 310408a4068425bc7dc65c75308c45e0aef65495..0e071f425999077c81118bb705c9f51a957f5583 100644
--- a/src/mixins/contextMixin.ts
+++ b/src/mixins/contextMixin.ts
@@ -1,4 +1,4 @@
-import { base_context } from '../libs/store/store';
+import { base_context } from '../libs/store/store.ts';
 
 const ContextMixin = {
   name: 'store-mixin',
@@ -6,22 +6,22 @@ const ContextMixin = {
   attributes: {
     extraContext: {
       type: String,
-      default: null
+      default: null,
     },
   },
   get context(): object {
     return { ...base_context, ...this.extra_context };
   },
   get extra_context(): object {
-    let extraContextElement = this.extraContext ?
-    document.getElementById(this.extraContext) : // take element extra context first
-    document.querySelector('[data-default-context]'); // ... or look for a default extra context
+    const extraContextElement = this.extraContext
+      ? document.getElementById(this.extraContext)
+      : // take element extra context first
+        document.querySelector('[data-default-context]'); // ... or look for a default extra context
 
-    if (extraContextElement) return JSON.parse(extraContextElement.textContent || "{}");
+    if (extraContextElement)
+      return JSON.parse(extraContextElement.textContent || '{}');
     return {};
   },
 };
 
-export {
-  ContextMixin
-}
\ No newline at end of file
+export { ContextMixin };
diff --git a/src/mixins/counterMixin.ts b/src/mixins/counterMixin.ts
index ab6cc4829342ec5c4d6c72badd6e757dfc9966f3..994ea0e973467a0e86326bad656bdb40ea15e115 100644
--- a/src/mixins/counterMixin.ts
+++ b/src/mixins/counterMixin.ts
@@ -1,6 +1,7 @@
-import { html } from 'lit-html';
-import { unsafeHTML } from 'lit-html/directives/unsafe-html';
-import { evalTemplateString } from '../libs/helpers';
+import { html } from 'lit';
+import { unsafeHTML } from 'lit/directives/unsafe-html.js';
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+import { evalTemplateString } from '../libs/helpers.ts';
 
 const CounterMixin = {
   name: 'counter-mixin',
@@ -8,7 +9,7 @@ const CounterMixin = {
   attributes: {
     counterTemplate: {
       type: String,
-      default: null
+      default: null,
     },
   },
   initialState: {
@@ -16,19 +17,29 @@ const CounterMixin = {
     parentCounterDiv: null,
   },
   attached() {
-    this.listPostProcessors.push(this.countResources.bind(this));
+    this.listPostProcessors.attach(
+      this.countResources.bind(this),
+      'CounterMixin:countResources',
+    );
   },
-  async countResources(resources: object[], listPostProcessors: Function[], div: HTMLElement, context: string) {
+  async countResources(
+    resources: object[],
+    listPostProcessors: PostProcessorRegistry,
+    div: HTMLElement,
+    context: string,
+  ) {
     if (this.counterTemplate) {
       this.initParentCounterDiv(div);
-      this.renderCallbacks.push({ // add counter template to render callback
+      this.renderCallbacks.push({
+        // add counter template to render callback
         template: await this.renderCounter(resources.length),
-        parent: this.parentCounterDiv
+        parent: this.parentCounterDiv,
       });
     }
 
     const nextProcessor = listPostProcessors.shift();
-    if (nextProcessor) await nextProcessor(resources, listPostProcessors, div, context);
+    if (nextProcessor)
+      await nextProcessor(resources, listPostProcessors, div, context);
   },
   /**
    * Create the parent div of the counter in the component.
@@ -50,9 +61,7 @@ const CounterMixin = {
       throw e;
     }
     return html`${unsafeHTML(htmlCounter)}`;
-  }
-}
+  },
+};
 
-export {
-  CounterMixin
-}
\ No newline at end of file
+export { CounterMixin };
diff --git a/src/mixins/federationMixin.ts b/src/mixins/federationMixin.ts
index 0a06bcdac51f3560baf04c4efffcb8a041a88175..b4afb9ee18d0960bae3c6e31dcab539283bdffaf 100644
--- a/src/mixins/federationMixin.ts
+++ b/src/mixins/federationMixin.ts
@@ -1,22 +1,33 @@
-import { store } from '../libs/store/store';
-import type { Resource } from './interfaces';
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+import { store } from '../libs/store/store.ts';
+import type { Resource } from './interfaces.ts';
 
 const FederationMixin = {
   name: 'federation-mixin',
   use: [],
   initialState: {
-    containerFetched: null
+    containerFetched: null,
   },
   attached(): void {
-    this.listPostProcessors.push(this.fetchSources.bind(this));
+    this.listPostProcessors.attach(
+      this.fetchSources.bind(this),
+      'FederationMixin:fetchSources',
+    );
   },
-  async fetchSources(resources: Resource[], listPostProcessors: Function[], div: HTMLElement, context: string) {
+  async fetchSources(
+    resources: Resource[],
+    listPostProcessors: PostProcessorRegistry,
+    div: HTMLElement,
+    context: string,
+  ) {
     this.containerFetched = [];
     let newResources: Resource[] = await this.getResources(resources);
     newResources = [...new Set(newResources)]; // remove possible duplicates
 
+    this.resources = [...newResources]; // Create a new array to avoid unintended reference issues
     const nextProcessor = listPostProcessors.shift();
-    if(nextProcessor) await nextProcessor(newResources, listPostProcessors, div, context);
+    if (nextProcessor)
+      await nextProcessor(newResources, listPostProcessors, div, context);
   },
   async getResources(resources: Resource[]): Promise<Resource[]> {
     if (!resources && this.resources) resources = this.resources;
@@ -25,18 +36,21 @@ const FederationMixin = {
 
     const getChildResources = async (res: Resource) => {
       if (!res) return;
-      if (res.isContainer?.()) { // if this is a container
+      if (res.isContainer?.()) {
+        // if this is a container
         const containerId = res['@id'];
-        if (!this.containerFetched.includes(containerId)) { // prevent from including twice the same source
+        if (!this.containerFetched.includes(containerId)) {
+          // prevent from including twice the same source
           this.containerFetched.push(containerId);
 
           const resourcesFetched = await this.fetchSource(containerId); // fetch the resources of this container
-          if (resourcesFetched) newResources.push(...(await this.getResources(resourcesFetched))); // Add content of source to array...
+          if (resourcesFetched)
+            newResources.push(...(await this.getResources(resourcesFetched))); // Add content of source to array...
         }
       } else {
         newResources.push(res); // Or resource directly if not a container
       }
-    }
+    };
 
     // Special case for list support, if there is only one item it is serialized as an object, not an array
     if (!Array.isArray(resources)) resources = [resources];
@@ -46,14 +60,13 @@ const FederationMixin = {
 
   async fetchSource(containerId: string): Promise<Resource[] | null> {
     const cachedContainer = store.get(containerId); // find container in cache
-    if (!cachedContainer || cachedContainer['ldp:contains'] === null) { // if container not fetched
+    if (!cachedContainer || cachedContainer['ldp:contains'] === null) {
+      // if container not fetched
       store.clearCache(containerId); // empty cache
     }
     const container = await store.getData(containerId, this.context); // and fetch it
     return container ? container['ldp:contains'] : null;
   },
-}
+};
 
-export {
-  FederationMixin
-}
\ No newline at end of file
+export { FederationMixin };
diff --git a/src/mixins/filterMixin.ts b/src/mixins/filterMixin.ts
index 9a8c1cbabc71205a25697c520e271c1a035f7b80..e4b4d4ebe5191d32a0172b4cdab387e7dadedb9f 100644
--- a/src/mixins/filterMixin.ts
+++ b/src/mixins/filterMixin.ts
@@ -1,6 +1,7 @@
-import type { SearchQuery } from '../libs/interfaces';
-import { searchInResources } from '../libs/filter';
-import type { ServerSearchOptions } from '../libs/store/server-search';
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+import { searchInResources } from '../libs/filter.ts';
+import type { SearchQuery } from '../libs/interfaces.ts';
+import type { ServerSearchOptions } from '../libs/store/server-search.ts';
 
 const FilterMixin = {
   name: 'filter-mixin',
@@ -11,23 +12,27 @@ const FilterMixin = {
   attributes: {
     searchFields: {
       type: String,
-      default: null
+      default: null,
     },
     filteredBy: {
       type: String,
       default: null,
       callback(newValue: string) {
         // if we change search form, re-populate
-        if (newValue && this.searchForm && newValue !== this.searchForm.getAttribute('id')) {
+        if (
+          newValue &&
+          this.searchForm &&
+          newValue !== this.searchForm.getAttribute('id')
+        ) {
           this.searchForm.component.detach(this);
           this.searchForm = null;
           this.populate();
         }
-      }
+      },
     },
     filteredOn: {
       type: String, // 'server' | 'client'
-      default: 'client'
+      default: 'client',
     },
   },
   created() {
@@ -35,17 +40,22 @@ const FilterMixin = {
     this.element.addEventListener('populate', () => {
       if (!window.document.contains(this.element)) return;
       this.searchForm?.component.updateAutoRanges();
-    })
+    });
   },
   attached(): void {
     const filteredBy = this.filteredBy;
     if (this.isFilteredOnServer() && filteredBy) {
-      this.searchForm = document.getElementById(filteredBy)
+      this.searchForm = document.getElementById(filteredBy);
       if (!this.searchForm) throw `#${filteredBy} is not in DOM`;
       // this.searchForm.component.attach(this); // is it necessary?
-      this.searchForm.addEventListener('formChange', () => this.onServerSearchChange());
+      this.searchForm.addEventListener('formChange', () =>
+        this.onServerSearchChange(),
+      );
     } else {
-      this.listPostProcessors.push(this.filterCallback.bind(this));
+      this.listPostProcessors.attach(
+        this.filterCallback.bind(this),
+        'FilterMixin:filterCallback',
+      );
     }
   },
   get filters(): SearchQuery {
@@ -71,15 +81,21 @@ const FilterMixin = {
       const fields = Object.keys(filters);
       const value = (Object.values(filters) as { value: string }[])
         .map(({ value }) => value)
-        .filter((value) => !!value)
-        .join(' ').trim();
+        .filter(value => !!value)
+        .join(' ')
+        .trim();
       if (fields.length > 0 && value) {
         return { fields, value };
       }
     }
     return;
   },
-  async filterCallback(resources: object[], listPostProcessors: Function[], div: HTMLElement, context: string): Promise<void> {
+  async filterCallback(
+    resources: object[],
+    listPostProcessors: PostProcessorRegistry,
+    div: HTMLElement,
+    context: string,
+  ): Promise<void> {
     if (this.filteredBy || this.searchFields) {
       if (!this.searchCount.has(context)) this.searchCount.set(context, 1);
       if (!this.searchForm) await this.createFilter(context);
@@ -87,13 +103,19 @@ const FilterMixin = {
         resources,
         this.filters,
         this.fields,
-        this.searchForm
+        this.searchForm,
       );
-      this.resources = resources = resources.filter((_v, index) => filteredResources[index]);
+      resources = resources.filter((_v, index) => filteredResources[index]);
+      this.resources = [...resources];
     }
-
     const nextProcessor = listPostProcessors.shift();
-    if (nextProcessor) await nextProcessor(resources, listPostProcessors, div, context + (this.searchCount.get(context) || ''));
+    if (nextProcessor)
+      await nextProcessor(
+        resources,
+        listPostProcessors,
+        div,
+        context + (this.searchCount.get(context) || ''),
+      );
   },
   async filterList(context: string): Promise<void> {
     this.searchCount.set(context, this.searchCount.get(context) + 1);
@@ -109,8 +131,10 @@ const FilterMixin = {
       const nextArrayOfObjects = await obj[field];
       if (!nextArrayOfObjects) continue;
 
-      if (typeof nextArrayOfObjects !== "object") {
-        console.warn(`The format value of ${field} is not suitable with auto-range-[field] attribute`);
+      if (typeof nextArrayOfObjects !== 'object') {
+        console.warn(
+          `The format value of ${field} is not suitable with auto-range-[field] attribute`,
+        );
         continue;
       }
 
@@ -130,10 +154,10 @@ const FilterMixin = {
   async createFilter(context: string): Promise<void> {
     const filteredBy = this.filteredBy;
     if (filteredBy != null) {
-      this.searchForm = document.getElementById(filteredBy)
+      this.searchForm = document.getElementById(filteredBy);
       if (!this.searchForm) throw `#${filteredBy} is not in DOM`;
     } else {
-      this.searchForm = document.createElement(`solid-form-search`);
+      this.searchForm = document.createElement('solid-form-search');
     }
     this.searchForm.component.attach(this);
     this.searchForm.addEventListener('formChange', () => {
@@ -145,21 +169,19 @@ const FilterMixin = {
 
     //pass attributes to search form
     const searchAttributes = Array.from((this.element as Element).attributes)
-      .filter(attr => attr['name'].startsWith('search-'))
+      .filter(attr => attr.name.startsWith('search-'))
       .map(attr => ({
-        name: attr['name'].replace('search-', ''),
-        value: attr['value'],
+        name: attr.name.replace('search-', ''),
+        value: attr.value,
       }));
 
-    searchAttributes.forEach(({ name, value }) => {
+    for (const { name, value } of searchAttributes) {
       this.searchForm.setAttribute(name, value);
-    });
+    }
 
     this.element.insertBefore(this.searchForm, this.element.firstChild);
     await this.searchForm.component.populate();
   },
-}
+};
 
-export {
-  FilterMixin
-}
\ No newline at end of file
+export { FilterMixin };
diff --git a/src/mixins/grouperMixin.ts b/src/mixins/grouperMixin.ts
index ee8442281a0b8375a05e616579b87b600d5d57c3..85264d1dba7114750ad4583df074413bf61ec619 100644
--- a/src/mixins/grouperMixin.ts
+++ b/src/mixins/grouperMixin.ts
@@ -1,4 +1,5 @@
-import { generalComparator } from "../libs/helpers";
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+import { generalComparator } from '../libs/helpers.ts';
 
 const GrouperMixin = {
   name: 'grouper-mixin',
@@ -10,60 +11,68 @@ const GrouperMixin = {
     },
     groupWidget: {
       type: String,
-      default: 'solid-group-default'
+      default: 'solid-group-default',
     },
     groupClass: {
       type: String,
-      default: ''
+      default: '',
     },
     orderGroupAsc: {
       type: Boolean,
-      default: null
+      default: null,
     },
     orderGroupDesc: {
       type: Boolean,
-      default: null
+      default: null,
     },
   },
   attached() {
-    this.listPostProcessors.push(this.groupResources.bind(this));
+    this.listPostProcessors.attach(
+      this.groupResources.bind(this),
+      'GrouperMixin:groupResources',
+    );
   },
-  async groupResources(resources: object[], listPostProcessors: Function[], div: HTMLElement, context: string) {
+  async groupResources(
+    resources: object[],
+    listPostProcessors: PostProcessorRegistry,
+    div: HTMLElement,
+    context: string,
+  ) {
     const nextProcessor = listPostProcessors.shift();
     if (this.groupBy) {
-      let groups = {};
-      for (let resource of resources) {
+      const groups = {};
+      for (const resource of resources) {
         const valueGroup = await resource[this.groupBy];
         if (valueGroup == null) continue;
         if (!groups[valueGroup]) groups[valueGroup] = { resources: [] }; // if no group yet, we create one...
-        groups[valueGroup].resources.push(resource) // ...and push corresponding resource into it
+        groups[valueGroup].resources.push(resource); // ...and push corresponding resource into it
       }
 
       let sortedKeys = Object.keys(groups);
       if (this.orderGroupAsc !== null || this.orderGroupDesc !== null) {
-        const order = this.orderGroupDesc !== null ? 'desc' : 'asc'
+        const order = this.orderGroupDesc !== null ? 'desc' : 'asc';
         sortedKeys = Object.keys(groups).sort((a, b) => {
-            return generalComparator(a, b, order);
+          return generalComparator(a, b, order);
         });
       }
 
       // For each group, get group widget and call next processors
-      const parents = sortedKeys.map(g => ({ group: g, parent: this.renderGroup(g, div) }));
-      for (let { group, parent } of parents) {
-        if (nextProcessor) await nextProcessor(
-          groups[group].resources, // give only resources from group
-          [...listPostProcessors], // copy post processors
-          parent, // parent is group widget
-          context + "_" + group
-        );
+      const parents = sortedKeys.map(g => ({
+        group: g,
+        parent: this.renderGroup(g, div),
+      }));
+      for (const { group, parent } of parents) {
+        if (nextProcessor)
+          await nextProcessor(
+            groups[group].resources, // give only resources from group
+            listPostProcessors.deepCopy(), // copy post processors
+            parent, // parent is group widget
+            `${context}_${group}`,
+          );
       }
     } else {
-      if (nextProcessor) await nextProcessor(
-        resources,
-        listPostProcessors,
-        div,
-        context
-      );
+      if (nextProcessor)
+        await nextProcessor(resources, listPostProcessors, div, context);
     }
   },
   /**
@@ -71,7 +80,9 @@ const GrouperMixin = {
    * @param groupName
    */
   renderGroup(groupName: string, div: HTMLElement) {
-    let groupElt = this.element.querySelector(`${this.groupWidget}[value="${groupName}"]`);
+    let groupElt = this.element.querySelector(
+      `${this.groupWidget}[value="${groupName}"]`,
+    );
     if (!groupElt) {
       groupElt = document.createElement(this.groupWidget);
       groupElt.setAttribute('value', groupName);
@@ -80,9 +91,7 @@ const GrouperMixin = {
       div.appendChild(groupElt); // and append it to the parent div
     }
     return groupElt.querySelector('[data-content]') || groupElt; // return the node where to insert content
-  }
-}
+  },
+};
 
-export {
-  GrouperMixin
-}
\ No newline at end of file
+export { GrouperMixin };
diff --git a/src/mixins/highlighterMixin.ts b/src/mixins/highlighterMixin.ts
index fce1050e237bb60262465025f85b3708bc2e2fd2..a01d321ca22460a10db8d22ff7b0c6e13c104b69 100644
--- a/src/mixins/highlighterMixin.ts
+++ b/src/mixins/highlighterMixin.ts
@@ -1,37 +1,48 @@
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+
 const HighlighterMixin = {
   name: 'highlighter-mixin',
   use: [],
   attached(): void {
-    this.listPostProcessors.push(this.hightlightCallback.bind(this));
+    this.listPostProcessors.attach(
+      this.hightlightCallback.bind(this),
+      'HighlighterMixin:hightlightCallback',
+    );
   },
-  async hightlightCallback(resources: object[], listPostProcessors: Function[], div: HTMLElement, context: string): Promise<void> {
-    for (let attr of this.element.attributes) {
+  async hightlightCallback(
+    resources: object[],
+    listPostProcessors: PostProcessorRegistry,
+    div: HTMLElement,
+    context: string,
+  ): Promise<void> {
+    for (const attr of this.element.attributes) {
       if (attr.name.startsWith('highlight-')) {
         const field = attr.name.split('highlight-')[1];
-        resources = await Promise.all(resources.map(async (resource) => ({
-          sortingKey: await resource[field], // fetch sorting value
-          proxy: resource // and keep proxy
-        })));
-        resources = this.sortHighlighted(resources, "sortingKey", attr.value); // highlight element
+        resources = await Promise.all(
+          resources.map(async resource => ({
+            sortingKey: await resource[field], // fetch sorting value
+            proxy: resource, // and keep proxy
+          })),
+        );
+        resources = this.sortHighlighted(resources, 'sortingKey', attr.value); // highlight element
         resources = resources.map(resource => (<any>resource).proxy); // and re-transform in arra of resources
       }
     }
-
+    this.resources = [...resources];
     const nextProcessor = listPostProcessors.shift();
-    if (nextProcessor) await nextProcessor(resources, listPostProcessors, div, context);
+    if (nextProcessor)
+      await nextProcessor(resources, listPostProcessors, div, context);
   },
 
   sortHighlighted(resources, field, value) {
-    for (let [index, res] of resources.entries()) {
-      if (res[field] && res[field] == value) {
+    for (const [index, res] of resources.entries()) {
+      if (res[field] && res[field] === value) {
         // put the current element at the beginning of the array
         resources.splice(0, 0, resources.splice(index, 1)[0]); // TODO : test with sort
       }
     }
-    return resources
-  }
-}
+    return resources;
+  },
+};
 
-export {
-  HighlighterMixin
-}
\ No newline at end of file
+export { HighlighterMixin };
diff --git a/src/mixins/interfaces.ts b/src/mixins/interfaces.ts
index 1ed067a48ab7a47db3ec12924af8eff1a4b11b2b..0fca9342b6e0d2ddc18bc667fdf1d0efa441dfba 100644
--- a/src/mixins/interfaces.ts
+++ b/src/mixins/interfaces.ts
@@ -1,20 +1,20 @@
 export enum WidgetType {
-  CUSTOM = "custom",
-  USER = "user",
-  NATIVE = "native",
+  CUSTOM = 'custom',
+  USER = 'user',
+  NATIVE = 'native',
 }
 
 export interface WidgetInterface {
-  tagName: String
-  type: WidgetType
+  tagName: string;
+  type: WidgetType;
 }
 
 export interface Resource {
-  '@id': string
-  clientContext: object
-  isContainer: Function
-  isArray: Function
-  isFullResource: Function
-  properties: string[],
-  serverPagination: object
-}
\ No newline at end of file
+  '@id': string;
+  clientContext: object;
+  isContainer: Function;
+  isArray: Function;
+  isFullResource: Function;
+  properties: string[];
+  serverPagination: object;
+}
diff --git a/src/mixins/listMixin.ts b/src/mixins/listMixin.ts
index 2103a566924d89023819d6dd2d7e2d43837b7bbd..77a309984626990d82a85385cf17fbd8c90ca17d 100644
--- a/src/mixins/listMixin.ts
+++ b/src/mixins/listMixin.ts
@@ -1,6 +1,7 @@
-import { html, render } from 'lit-html';
-import { preHTML } from '../libs/lit-helpers';
-import { ifDefined } from 'lit-html/directives/if-defined';
+import { html, render } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+import { preHTML } from '../libs/lit-helpers.ts';
 
 const ListMixin = {
   name: 'list-mixin',
@@ -17,77 +18,95 @@ const ListMixin = {
   },
   initialState: {
     // Processors functions to execute on the list before rendering
-    listPostProcessors: [],
+    listPostProcessors: new PostProcessorRegistry(),
     // Rendering to execute after all the processors have been executed
     renderCallbacks: [],
   },
   created() {
-    this.listPostProcessors = [];
+    this.listPostProcessors = new PostProcessorRegistry();
     this.renderCallbacks = [];
   },
   appendSingleElt(parent: HTMLElement): void {
     this.appendChildElt(this.resource['@id'], parent);
   },
   setElementAttribute(attr: 'resource' | 'container') {
-    const containerAttribute = "solid-container";
-    const resourceAttribute = "solid-resource";
-    if (attr === "resource") {
+    const containerAttribute = 'solid-container';
+    const resourceAttribute = 'solid-resource';
+    if (attr === 'resource') {
       this.element.removeAttribute(containerAttribute);
-      this.element.setAttribute(resourceAttribute, "");
+      this.element.setAttribute(resourceAttribute, '');
     } else {
       this.element.removeAttribute(resourceAttribute);
-      this.element.setAttribute(containerAttribute, "")
+      this.element.setAttribute(containerAttribute, '');
     }
   },
   async populate(): Promise<void> {
+    const listPostProcessorsCopy = this.listPostProcessors.deepCopy();
     const div = this.div;
     if (!this.resource) return;
 
     // Not a container but a single resource
-    if (!this.resource.isContainer?.() && !this.arrayField && !this.predicateName) {
-      this.setElementAttribute("resource");
+    if (
+      !this.resource.isContainer?.() &&
+      !this.arrayField &&
+      !this.predicateName
+    ) {
+      this.setElementAttribute('resource');
       this.appendSingleElt(div);
       return;
     }
 
     if (this.resource.isContainer?.()) {
-      this.setElementAttribute("container");
-      const listPostProcessors = [...this.listPostProcessors];
+      this.setElementAttribute('container');
       this.renderCallbacks = [];
-      listPostProcessors.push(this.renderDOM.bind(this));
-      listPostProcessors.push(this.handleEmptyWidget.bind(this));
+      listPostProcessorsCopy.attach(
+        this.renderDOM.bind(this),
+        'ListMixin:renderDOM',
+      );
+      listPostProcessorsCopy.attach(
+        this.handleEmptyWidget.bind(this),
+        'ListMixin:handleEmptyWidget',
+      );
 
       // Execute the first post-processor of the list
-      const nextProcessor = listPostProcessors.shift();
+      const nextProcessor = listPostProcessorsCopy.shift();
+
       await nextProcessor(
         this.resource['ldp:contains'],
-        listPostProcessors,
+        listPostProcessorsCopy,
         div,
         this.dataSrc,
       );
-    } else if (this.arrayField && this.predicateName && this.resource[this.predicateName]) {
-      this.setElementAttribute("container");
-      const listPostProcessors = [...this.listPostProcessors];
+    } else if (
+      this.arrayField &&
+      this.predicateName &&
+      this.resource[this.predicateName]
+    ) {
+      this.setElementAttribute('container');
       this.renderCallbacks = [];
-      listPostProcessors.push(this.renderDOM.bind(this));
-      listPostProcessors.push(this.handleEmptyWidget.bind(this));
+      listPostProcessorsCopy.attach(
+        this.renderDOM.bind(this),
+        'ListMixin:renderDOM',
+      );
+      listPostProcessorsCopy.attach(
+        this.handleEmptyWidget.bind(this),
+        'ListMixin:handleEmptyWidget',
+      );
 
       // Execute the first post-processor of the list
-      const nextProcessor = listPostProcessors.shift();
+      const nextProcessor = listPostProcessorsCopy.shift();
       await nextProcessor(
         await this.resource[this.predicateName],
-        listPostProcessors,
+        listPostProcessorsCopy,
         div,
         this.dataSrc,
       );
-
     }
     // Execute the render callbacks
     for (const renderCallback of this.renderCallbacks) {
       // Render the template in the given parent element
       render(renderCallback.template, renderCallback.parent);
     }
-
   },
 
   /**
@@ -99,24 +118,19 @@ const ListMixin = {
    */
   async renderDOM(
     resources: object[],
-    listPostProcessors: Function[],
+    listPostProcessors: PostProcessorRegistry,
     div: HTMLElement,
     context: string,
   ) {
     // Create child components
-    for (let resource of resources) {
+    for (const resource of resources) {
       if (!resource) continue;
       this.appendChildElt(resource['@id'], div);
     }
 
     const nextProcessor = listPostProcessors.shift();
     if (nextProcessor)
-      await nextProcessor(
-        resources,
-        listPostProcessors,
-        div,
-        context
-      );
+      await nextProcessor(resources, listPostProcessors, div, context);
   },
 
   /**
@@ -128,30 +142,26 @@ const ListMixin = {
    */
   async handleEmptyWidget(
     resources: object[],
-    listPostProcessors: Function[],
+    listPostProcessors: PostProcessorRegistry,
     div: HTMLElement,
     context: string,
   ) {
     if (this.emptyWidget) {
-      const emptyWidgetTemplate = preHTML`
-        <${this.emptyWidget} value=${ifDefined(this.emptyValue)}></${this.emptyWidget}>
-      `
+      const emptyWidgetTemplate = preHTML`<${this.emptyWidget} value=${ifDefined(this.emptyValue)}></${this.emptyWidget}>`;
       if (!this.emptyWrapper) {
-        this.emptyWrapper = document.createElement('span')
-        this.element.appendChild(this.emptyWrapper)
+        this.emptyWrapper = document.createElement('span');
+        this.element.appendChild(this.emptyWrapper);
       }
-      
-      render(resources.length > 0 ? html`` : emptyWidgetTemplate, this.emptyWrapper);
+
+      render(
+        resources.length > 0 ? html`` : emptyWidgetTemplate,
+        this.emptyWrapper,
+      );
     }
 
     const nextProcessor = listPostProcessors.shift();
     if (nextProcessor)
-      await nextProcessor(
-        resources,
-        listPostProcessors,
-        div,
-        context
-      );
+      await nextProcessor(resources, listPostProcessors, div, context);
   },
 };
 
diff --git a/src/mixins/nextMixin.ts b/src/mixins/nextMixin.ts
index d3663f734c97a664289bdab8753bc00fd1970802..eab388cefae210b8f86cba8b4419f7b8c186acef 100644
--- a/src/mixins/nextMixin.ts
+++ b/src/mixins/nextMixin.ts
@@ -1,4 +1,4 @@
-import type { Resource } from "./interfaces.js";
+import type { Resource } from './interfaces.js';
 
 const NextMixin = {
   name: 'next-mixin',
@@ -6,7 +6,7 @@ const NextMixin = {
   attributes: {
     next: {
       type: String,
-      default:''
+      default: '',
     },
   },
 
@@ -20,9 +20,7 @@ const NextMixin = {
         }),
       );
     }
-  }
-}
+  },
+};
 
-export {
-  NextMixin
-}
\ No newline at end of file
+export { NextMixin };
diff --git a/src/mixins/paginateMixin.ts b/src/mixins/paginateMixin.ts
index da421034e0e3dee6d195ca62613c14d4f48bec00..f68be13f2b6f7344d386ecef6d7200b13ebd5e6a 100644
--- a/src/mixins/paginateMixin.ts
+++ b/src/mixins/paginateMixin.ts
@@ -1,4 +1,5 @@
-import { html, TemplateResult } from "lit-html";
+import { type TemplateResult, html } from 'lit';
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
 
 const PaginateMixin = {
   name: 'paginate-mixin',
@@ -6,12 +7,12 @@ const PaginateMixin = {
   attributes: {
     paginateBy: {
       type: Number,
-      default: 0
+      default: 0,
     },
     paginateLoop: {
       type: String,
-      default: null
-    }
+      default: null,
+    },
   },
   initialState: {
     currentPage: [],
@@ -20,23 +21,40 @@ const PaginateMixin = {
     this.currentPage = [];
   },
   attached(): void {
-    this.listPostProcessors.push(this.paginateCallback.bind(this));
+    this.listPostProcessors.attach(
+      this.paginateCallback.bind(this),
+      'PaginateMixin:paginateCallback',
+    );
   },
-  async paginateCallback(resources: object[], listPostProcessors: Function[], div: HTMLElement, context: string) {
+  async paginateCallback(
+    resources: object[],
+    listPostProcessors: PostProcessorRegistry,
+    div: HTMLElement,
+    context: string,
+  ) {
     if (this.paginateBy > 0) {
       if (!this.currentPage[context]) this.currentPage[context] = 1;
       const parentDiv = this.initParentPaginationDiv(div, context);
       this.renderCallbacks.push({
-        template: this.renderPaginationNav(this.getPageCount(resources.length),context,div),
-        parent: parentDiv
+        template: this.renderPaginationNav(
+          this.getPageCount(resources.length),
+          context,
+          div,
+        ),
+        parent: parentDiv,
       });
 
-      const firstElementIndex = (this.getCurrentPage(context) - 1) * this.paginateBy;
-      resources = resources.slice(firstElementIndex, firstElementIndex + this.paginateBy);
+      const firstElementIndex =
+        (this.getCurrentPage(context) - 1) * this.paginateBy;
+      resources = resources.slice(
+        firstElementIndex,
+        firstElementIndex + this.paginateBy,
+      );
     }
 
     const nextProcessor = listPostProcessors.shift();
-    if (nextProcessor) await nextProcessor(resources, listPostProcessors, div,context);
+    if (nextProcessor)
+      await nextProcessor(resources, listPostProcessors, div, context);
   },
   getNavElement(div: HTMLElement) {
     const insertNode = div.parentNode || div;
@@ -78,7 +96,11 @@ const PaginateMixin = {
    * @param pageCount
    * @param context
    */
-  renderPaginationNav(pageCount: number, context: string, div: HTMLElement): TemplateResult {
+  renderPaginationNav(
+    pageCount: number,
+    context: string,
+    div: HTMLElement,
+  ): TemplateResult {
     this.getNavElement(div).toggleAttribute('hidden', pageCount <= 1);
     const currentPage = this.getCurrentPage(context);
 
@@ -91,15 +113,13 @@ const PaginateMixin = {
       <button
         data-id="next"
         ?disabled=${!this.shouldLoop() && currentPage >= pageCount}
-        @click=${ () => this.setCurrentPage(currentPage + 1, context, pageCount)}
+        @click=${() => this.setCurrentPage(currentPage + 1, context, pageCount)}
       >→</button>
       <span>
         <span data-id="current">${currentPage}</span> / <span data-id="count">${String(pageCount)}</span>
       </span>
     `;
   },
-}
+};
 
-export {
-  PaginateMixin
-}
\ No newline at end of file
+export { PaginateMixin };
diff --git a/src/mixins/requiredMixin.ts b/src/mixins/requiredMixin.ts
index 819da65b19ba9c3b934a87ae7300d876d8250523..6e648cfa19dd52fba6d7979967b697d4492a1d2e 100644
--- a/src/mixins/requiredMixin.ts
+++ b/src/mixins/requiredMixin.ts
@@ -1,35 +1,52 @@
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+
 const RequiredMixin = {
   name: 'required-mixin',
   use: [],
   attached(): void {
-    this.listPostProcessors.push(this.requiredResources.bind(this));
+    this.listPostProcessors.attach(
+      this.requiredResources.bind(this),
+      'RequiredMixin:requiredResources',
+    );
   },
-  async requiredResources(resources: object[], listPostProcessors: Function[], div: HTMLElement, context: string): Promise<void> {
+  async requiredResources(
+    resources: object[],
+    listPostProcessors: PostProcessorRegistry,
+    div: HTMLElement,
+    context: string,
+  ): Promise<void> {
     const displays: any[] = [];
-    const requiredFields = Array.from((this.element as Element).attributes).filter(attr => attr.name.startsWith('required-'))
+    const requiredFields = Array.from((this.element as Element).attributes)
+      .filter(attr => attr.name.startsWith('required-'))
       .map(attr => {
-        return (attr.value !== '' ? attr.value : attr['name'].replace('required-', ''));
-    });
+        return attr.value !== ''
+          ? attr.value
+          : attr.name.replace('required-', '');
+      });
 
-    if (requiredFields.length) {
-      for (let resource of resources) {
+    if (requiredFields.length > 0) {
+      for (const resource of resources) {
         let hasProps = true;
-        for(let field of requiredFields) {
+        for (const field of requiredFields) {
           // Retrieve resource from store
-          let res = await resource[field];
-          if (!res || res == null) {
+          const res = await resource[field];
+          if (!res) {
             hasProps = false;
-            continue;
+            break;
           }
         }
         if (hasProps) displays.push(resource);
       }
     }
     const nextProcessor = listPostProcessors.shift();
-    if (nextProcessor) await nextProcessor(requiredFields.length ? displays : resources, listPostProcessors, div, context);
-  }
-}
+    if (nextProcessor)
+      await nextProcessor(
+        requiredFields.length > 0 ? displays : resources,
+        listPostProcessors,
+        div,
+        context,
+      );
+  },
+};
 
-export {
-  RequiredMixin
-}
+export { RequiredMixin };
diff --git a/src/mixins/serverPaginationMixin.ts b/src/mixins/serverPaginationMixin.ts
index 235fd4222843de2d8f3d3f1f1bfec90323a28188..67391554f01ca5e563d740e887e1f88a216b3835 100644
--- a/src/mixins/serverPaginationMixin.ts
+++ b/src/mixins/serverPaginationMixin.ts
@@ -1,4 +1,4 @@
-import { html, render } from "lit-html";
+import { html, render } from 'lit';
 
 const ServerPaginationMixin = {
   name: 'server-pagination-mixin',
@@ -6,20 +6,20 @@ const ServerPaginationMixin = {
   attributes: {
     limit: {
       type: Number,
-      default: undefined
+      default: undefined,
     },
     offset: {
       type: Number,
-      default: undefined
+      default: undefined,
     },
     pageCount: {
       type: Number,
-      default: 1000
+      default: 1000,
     },
     pageNumber: {
       type: Number,
-      default: 0
-    }
+      default: 0,
+    },
   },
   initialState: {
     currentOffset: [],
@@ -29,20 +29,20 @@ const ServerPaginationMixin = {
     if (this.limit) {
       this.setCurrentOffset(this.resourceId, 0);
       const parentDiv = this.initServerPaginationDiv(this.div);
-    
+
       this.renderCallbacks.push({
         template: this.renderServerPaginationNav(this.resourceId, parentDiv),
-        parent: parentDiv
+        parent: parentDiv,
       });
     }
   },
 
   getCurrentOffset(resourceId: string, limit: number) {
-    return this.currentOffset[resourceId + "#p" + limit];
+    return this.currentOffset[`${resourceId}#p${limit}`];
   },
 
   async setCurrentOffset(resourceId: string, offset: number): Promise<void> {
-    let index = resourceId + "#p" + this.limit;
+    const index = `${resourceId}#p${this.limit}`;
     this.currentOffset[index] = this.offset = offset;
     this.pageNumber = Number(this.offset / this.limit);
     this.currentPage[resourceId] = this.pageNumber;
@@ -51,7 +51,7 @@ const ServerPaginationMixin = {
   },
 
   async decreaseCurrentOffset(resourceId: string): Promise<void> {
-    let index = resourceId + "#p" + this.limit;
+    const index = `${resourceId}#p${this.limit}`;
     this.currentOffset[index] = this.offset = this.offset - this.limit;
     this.currentPage[index] = this.offset / this.limit;
     this.pageNumber = this.offset / this.limit;
@@ -61,7 +61,7 @@ const ServerPaginationMixin = {
   },
 
   async increaseCurrentOffset(resourceId: string): Promise<void> {
-    let index = resourceId + "#p" + this.limit;
+    const index = `${resourceId}#p${this.limit}`;
     this.currentOffset[index] = this.offset = this.offset + this.limit;
     this.currentPage[index] = this.offset / this.limit;
 
@@ -69,15 +69,16 @@ const ServerPaginationMixin = {
     await this.fetchData(this.dataSrc);
   },
 
-  async updateNavButtons(resourceId: string, index: string, variance: number) {
-    this.element.querySelector("[data-id='prev']").disabled = this.currentOffset[index] <= 0;
-    // this.element.querySelector("[data-id='next']").disabled = await this.resource['ldp:contains'].length == 0;
-    this.element.querySelector("[data-id='current']").innerText = this.getCurrentServedPage(resourceId, variance);
-
+  updateNavButtons(resourceId: string, index: string, variance: number) {
+    this.element.querySelector("[data-id='prev']").disabled =
+      this.currentOffset[index] <= 0;
+    // this.element.querySelector("[data-id='next']").disabled = await this.resource['ldp:contains'].length === 0;
+    this.element.querySelector("[data-id='current']").innerText =
+      this.getCurrentServedPage(resourceId, variance);
   },
 
   getServerNavElement(div: HTMLElement) {
-    if(div) {
+    if (div) {
       const insertNode = div.parentNode || div;
       return insertNode.querySelector(`nav[data-id="nav"]`);
     }
@@ -95,7 +96,7 @@ const ServerPaginationMixin = {
    * Find nav element or create it if not existing
    * @param div - insert nav next to this div
    */
-   initServerPaginationDiv(div: HTMLElement) {
+  initServerPaginationDiv(div: HTMLElement) {
     let nav = this.getServerNavElement(div);
     if (!nav) {
       nav = document.createElement('nav');
@@ -112,10 +113,11 @@ const ServerPaginationMixin = {
   renderServerPaginationNav(resourceId: string, div: HTMLElement): void {
     if (this.limit) {
       const currentOffset = this.getCurrentOffset(resourceId, this.limit);
-      var currentPageNumber = this.getCurrentServedPage(resourceId, 1);
+      const currentPageNumber = this.getCurrentServedPage(resourceId, 1);
       const pageCount = Math.ceil(this.pageCount / this.limit);
 
-      render(html`
+      render(
+        html`
         <button
           data-id="prev"
           ?disabled=${currentOffset <= 0}
@@ -127,15 +129,15 @@ const ServerPaginationMixin = {
         <button
           data-id="next"
           ?disabled=${currentOffset >= (pageCount - 1) * this.limit}
-          @click=${ () => this.increaseCurrentOffset(resourceId)}
+          @click=${() => this.increaseCurrentOffset(resourceId)}
         >→</button>
         <span>
         </span>
-      `, div);
+      `,
+        div,
+      );
     }
   },
-}
+};
 
-export {
-  ServerPaginationMixin
-}
\ No newline at end of file
+export { ServerPaginationMixin };
diff --git a/src/mixins/sorterMixin.ts b/src/mixins/sorterMixin.ts
index 0734226d27a33c5b052f57637d215cedbc516c1b..a565739ec95c874a0e593a418e72c9c555a22db1 100644
--- a/src/mixins/sorterMixin.ts
+++ b/src/mixins/sorterMixin.ts
@@ -1,40 +1,49 @@
+import type { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+
 const SorterMixin = {
   name: 'sorter-mixin',
   use: [],
   attributes: {
     orderBy: {
       type: String,
-      default: null
+      default: null,
     },
     orderAsc: {
       type: String,
-      default: null
+      default: null,
     },
     orderDesc: {
       type: String,
-      default: null
+      default: null,
     },
     orderByRandom: {
       type: String,
-      default: null
+      default: null,
     },
     sortedBy: {
-      type:String,
+      type: String,
       default: null,
       callback(newValue: string) {
         // if we change search form, re-populate
-        if (newValue && this.sortForm && newValue !== this.sortForm.getAttribute('id')) {
+        if (
+          newValue &&
+          this.sortForm &&
+          newValue !== this.sortForm.getAttribute('id')
+        ) {
           this.sortForm = null;
           this.populate();
         }
-      }
-    }
+      },
+    },
   },
   initialState: {
-    randomOrder: null
+    randomOrder: null,
   },
   attached(): void {
-    this.listPostProcessors.push(this.orderCallback.bind(this));
+    this.listPostProcessors.attach(
+      this.orderCallback.bind(this),
+      'SorterMixin:orderCallback',
+    );
   },
   created(): void {
     this.randomOrder = [];
@@ -50,7 +59,12 @@ const SorterMixin = {
     });
   },
 
-  async orderCallback(resources: object[], listPostProcessors: Function[], div: HTMLElement, context: string) {    
+  async orderCallback(
+    resources: object[],
+    listPostProcessors: PostProcessorRegistry,
+    div: HTMLElement,
+    context: string,
+  ) {
     if (this.orderBy) this.orderAsc = this.orderBy; // retrocompatibility. remove in 0.15
     let sortingKey = '';
     let orderValueToSort = '';
@@ -65,66 +79,75 @@ const SorterMixin = {
       if (sortedBy != null) {
         if (!this.sortForm) {
           this.sortForm = document.getElementById(sortedBy);
-          if (!this.sortForm) throw `#${sortedBy} is not in DOM`; 
+          if (!this.sortForm) throw `#${sortedBy} is not in DOM`;
           this.linkSorterForm();
         }
         if (!this.sortForm.component.value.field) {
-          console.warn('The attribute field does not exist')
-        } else { 
-          sortingKey = this.sortForm.component.value.field['value'];
+          console.warn('The attribute field does not exist');
+        } else {
+          sortingKey = this.sortForm.component.value.field.value;
         }
         const orderField = this.sortForm.component.value.order;
-        orderValueToSort = orderField && orderField.value ? orderField.value : 'asc';
+        orderValueToSort = orderField?.value ? orderField.value : 'asc';
       }
     }
     // sorting data according to the defined value of sortingKey
     if (sortingKey) {
       let orderToSort = true; // set 'asc' by default
-      if (this.orderDesc || orderValueToSort == "desc") orderToSort = false;
-      resources = (await Promise.all(resources.map(async (resource) => ({
-        sortingKey: await resource[sortingKey], // fetch sorting value
-        proxy: resource // and keep proxy
-      }))))
-      .sort(this.sortValuesByKey("sortingKey", orderToSort)) // sort this array
-      .map(r => r.proxy) // re-create array
+      if (this.orderDesc || orderValueToSort === 'desc') orderToSort = false;
+      resources = (
+        await Promise.all(
+          resources.map(async resource => ({
+            sortingKey: await resource[sortingKey], // fetch sorting value
+            proxy: resource, // and keep proxy
+          })),
+        )
+      )
+        .sort(this.sortValuesByKey('sortingKey', orderToSort)) // sort this array
+        .map(r => r.proxy); // re-create array
     }
     // if order-by-random attribute
     else if (this.isRandomSorted()) {
       resources = this.shuffleResources(resources); // shuffle resources
     }
 
+    this.resources = [...resources];
     const nextProcessor = listPostProcessors.shift();
-    if(nextProcessor) await nextProcessor(resources, listPostProcessors, div, context);
+    if (nextProcessor)
+      await nextProcessor(resources, listPostProcessors, div, context);
   },
   isRandomSorted(): boolean {
     return this.orderByRandom !== null;
   },
   sortValuesByKey(key: string, asc: boolean): Function {
-    return function (a: object, b: object): number {
-      if (!a.hasOwnProperty(key)) return 1;
-      if (!b.hasOwnProperty(key)) return -1;
+    return (a: object, b: object): number => {
+      if (!Object.hasOwn(a, key)) return 1;
+      if (!Object.hasOwn(b, key)) return -1;
 
       const varA = a[key];
       const varB = b[key];
 
       let comparison = 0;
       if (typeof varA === 'string' && typeof varB === 'string') {
-        comparison = varA.localeCompare(varB, undefined, { sensitivity: 'base' });
+        comparison = varA.localeCompare(varB, undefined, {
+          sensitivity: 'base',
+        });
         comparison = asc ? comparison : -comparison;
       } else {
         if (varA > varB) comparison = asc ? 1 : -1;
         else if (varA < varB) comparison = asc ? -1 : 1;
       }
       return comparison;
-    }
+    };
   },
   shuffleResources(array: object[]): object[] {
     let currentIndex = array.length;
     let temporaryValue: object;
     let randomIndex: number;
-    if (this.randomOrder.length !== array.length) { // if no random order existing
-      this.randomOrder = [ ...Array(array.length).keys() ]; // generate array of indexes
-      while (0 !== currentIndex) {
+    if (this.randomOrder.length !== array.length) {
+      // if no random order existing
+      this.randomOrder = [...Array(array.length).keys()]; // generate array of indexes
+      while (currentIndex !== 0) {
         randomIndex = Math.floor(Math.random() * currentIndex);
         currentIndex -= 1;
         temporaryValue = this.randomOrder[currentIndex];
@@ -133,9 +156,7 @@ const SorterMixin = {
       }
     }
     return this.randomOrder.map((i: number) => array[i]); // rebuild array with random order
-  }
-}
+  },
+};
 
-export {
-  SorterMixin
-}
\ No newline at end of file
+export { SorterMixin };
diff --git a/src/mixins/storeMixin.ts b/src/mixins/storeMixin.ts
index 0d8956f58c5dd199185bd2442479bca940468af6..07432fde2f9354270ec812d1c8c1311bcd42c55a 100644
--- a/src/mixins/storeMixin.ts
+++ b/src/mixins/storeMixin.ts
@@ -1,10 +1,13 @@
-import { store } from '../libs/store/store';
-import { formatAttributesToServerSearchOptions, mergeServerSearchOptions } from '../libs/store/server-search';
-import { AttributeBinderMixin } from './attributeBinderMixin';
-import type { Resource } from './interfaces';
-import { ContextMixin } from './contextMixin';
-import { ServerPaginationMixin } from './serverPaginationMixin';
-import { formatAttributesToServerPaginationOptions } from '../libs/store/server-pagination';
+import { formatAttributesToServerPaginationOptions } from '../libs/store/server-pagination.ts';
+import {
+  formatAttributesToServerSearchOptions,
+  mergeServerSearchOptions,
+} from '../libs/store/server-search.ts';
+import { store } from '../libs/store/store.ts';
+import { AttributeBinderMixin } from './attributeBinderMixin.ts';
+import { ContextMixin } from './contextMixin.ts';
+import type { Resource } from './interfaces.ts';
+import { ServerPaginationMixin } from './serverPaginationMixin.ts';
 
 const StoreMixin = {
   name: 'store-mixin',
@@ -15,40 +18,45 @@ const StoreMixin = {
       default: null,
       callback: function (value: boolean) {
         if (value === null) this.fetchData(this.dataSrc);
-      }
+      },
     },
     dataSrc: {
       type: String,
       default: null,
       callback: async function (value: string) {
-        const filteredOnServer = this.element.attributes['filtered-on']?.value === 'server';
-        const limited = this.element.attributes['limit']?.value !== undefined;
-        
+        const filteredOnServer =
+          this.element.attributes['filtered-on']?.value === 'server';
+        const limited = this.element.attributes.limit?.value !== undefined;
+
         if (this.noRender === null && !filteredOnServer && !limited) {
           await this.fetchData(value);
         } else if (this.noRender === null && !filteredOnServer) {
-          this.resourceId = value
+          this.resourceId = value;
         }
       },
     },
     loaderId: {
       type: String,
-      default: ''
+      default: '',
     },
     nestedField: {
       type: String,
-      default: null
+      default: null,
     },
     arrayField: {
       type: String,
       default: null,
       callback: function (value: boolean) {
-        if (value) this.predicateName = store.getExpandedPredicate(this.arrayField, this.context);
-      }
+        if (value)
+          this.predicateName = store.getExpandedPredicate(
+            this.arrayField,
+            this.context,
+          );
+      },
     },
     predicateName: {
       type: String,
-      default: null
+      default: null,
     },
   },
   initialState: {
@@ -62,12 +70,14 @@ const StoreMixin = {
   detached() {
     if (this.subscription) PubSub.unsubscribe(this.subscription);
   },
-  get resource(): Resource|null{
-    let id = this.resourceId;
-    const serverPagination = formatAttributesToServerPaginationOptions(this.element.attributes)
+  get resource(): Resource | null {
+    const id = this.resourceId;
+    const serverPagination = formatAttributesToServerPaginationOptions(
+      this.element.attributes,
+    );
     const serverSearch = mergeServerSearchOptions(
       formatAttributesToServerSearchOptions(this.element.attributes),
-      this.getDynamicServerSearch?.() // from `filterMixin`
+      this.getDynamicServerSearch?.(), // from `filterMixin`
     );
 
     return id ? store.get(id, serverPagination, serverSearch) : null;
@@ -78,7 +88,7 @@ const StoreMixin = {
   async fetchData(value: string) {
     this.empty();
     if (this.subscription) PubSub.unsubscribe(this.subscription);
-    if (!value || value == "undefined") return;
+    if (!value || value === 'undefined') return;
 
     this.resourceId = value;
     if (this.nestedField) {
@@ -100,15 +110,28 @@ const StoreMixin = {
 
     this.updateNavigateSubscription();
 
-    this.subscription = PubSub.subscribe(this.resourceId, this.updateDOM.bind(this));
-    const serverPagination = formatAttributesToServerPaginationOptions(this.element.attributes);
+    this.subscription = PubSub.subscribe(
+      this.resourceId,
+      this.updateDOM.bind(this),
+    );
+    const serverPagination = formatAttributesToServerPaginationOptions(
+      this.element.attributes,
+    );
     const dynamicServerSearch = this.getDynamicServerSearch?.(); // from `filterMixin`
     const serverSearch = mergeServerSearchOptions(
       formatAttributesToServerSearchOptions(this.element.attributes),
-      dynamicServerSearch
+      dynamicServerSearch,
     );
     const forceRefetch = !!dynamicServerSearch;
-    this.resources = await store.getData(this.resourceId, this.context, undefined, undefined, forceRefetch, serverPagination, serverSearch);
+    await store.getData(
+      this.resourceId,
+      this.context,
+      undefined,
+      undefined,
+      forceRefetch,
+      serverPagination,
+      serverSearch,
+    );
 
     this.updateDOM();
   },
@@ -116,24 +139,26 @@ const StoreMixin = {
   toggleLoaderHidden(toggle: boolean): void {
     if (this.loader) this.loader.toggleAttribute('hidden', toggle);
   },
-  updateNavigateSubscription() { },
+  updateNavigateSubscription() {},
   async updateDOM(): Promise<void> {
     this.toggleLoaderHidden(false); // brings a loader out if the attribute is set
     this.empty();
     await this.replaceAttributesData();
     await this.populate();
-    setTimeout(() => ( // Brings the dispatchEvent at the end of the queue
-      this.element.dispatchEvent(new CustomEvent('populate', { detail: { resource: {"@id": this.dataSrc} } })))
+    setTimeout(() =>
+      // Brings the dispatchEvent at the end of the queue
+      this.element.dispatchEvent(
+        new CustomEvent('populate', {
+          detail: { resource: { '@id': this.dataSrc } },
+        }),
+      ),
     );
     this.toggleLoaderHidden(true);
   },
-  empty():void {
-  },
+  empty(): void {},
   update() {
     if (this.noRender === null) this.updateDOM();
-  }
+  },
 };
 
-export {
-  StoreMixin
-}
\ No newline at end of file
+export { StoreMixin };
diff --git a/src/mixins/translationMixin.ts b/src/mixins/translationMixin.ts
index c23c1706c1812181db290825ab558791bf58935d..6ba822a2ee649c26697b6c7ae3829fa86b0b57f3 100644
--- a/src/mixins/translationMixin.ts
+++ b/src/mixins/translationMixin.ts
@@ -1,10 +1,10 @@
-import { store } from "../libs/store/store";
+import { store } from '../libs/store/store.ts';
 
 const TranslationMixin = {
   name: 'translation-mixin',
   use: [],
   initialState: {
-    translationData:{}
+    translationData: {},
   },
   created() {
     this.getLang();
@@ -15,12 +15,16 @@ const TranslationMixin = {
    * @returns - object: {key: translation}
    */
   async getTranslationModule(langCode: string) {
-    const translationsModules = { // define modules in a static way, snowpack does not support dynamic strings here
+    const translationsModules = {
+      // define modules in a static way, snowpack does not support dynamic strings here
       en: () => import('../locales/en.json'),
       fr: () => import('../locales/fr.json'),
     };
-    if (!translationsModules[langCode]) { // set default to EN if the file does not exist
-      console.warn(`${langCode}.json translation file may not exist, English is setted by default`);
+    if (!translationsModules[langCode]) {
+      // set default to EN if the file does not exist
+      console.warn(
+        `${langCode}.json translation file may not exist, English is setted by default`,
+      );
       langCode = 'en';
     }
     const module = await translationsModules[langCode]();
@@ -31,16 +35,18 @@ const TranslationMixin = {
    */
   getLang() {
     const languageStorage = store._getLanguage();
-    if(languageStorage) {
-      if (window.fetchTranslationPromise === undefined) { // if translation data are not already fetched
-        window.fetchTranslationPromise = this.getTranslationModule(languageStorage);
+    if (languageStorage) {
+      if (window.fetchTranslationPromise === undefined) {
+        // if translation data are not already fetched
+        window.fetchTranslationPromise =
+          this.getTranslationModule(languageStorage);
       }
       window.fetchTranslationPromise.then(res => {
         if (res) {
           this.translationData = res; // stock data in object passed to traduction method below
           this.update(); // update the rendering in components and widgets
         }
-      })
+      });
     }
   },
   /**
@@ -50,9 +56,7 @@ const TranslationMixin = {
    */
   t(tradKey: string) {
     return this.translationData[tradKey] || '';
-  }
-}
+  },
+};
 
-export {
-  TranslationMixin
-}
\ No newline at end of file
+export { TranslationMixin };
diff --git a/src/mixins/validationMixin.ts b/src/mixins/validationMixin.ts
index cd56edffd3c7c1aec9c29f669a9e52d46925bfb7..770ad3259f8e19ebde5adcd8c114f18b6fe0bf27 100644
--- a/src/mixins/validationMixin.ts
+++ b/src/mixins/validationMixin.ts
@@ -1,9 +1,9 @@
-import dialogPolyfill from 'dialog-polyfill'
-import { html } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
-import { uniqID } from '../libs/helpers';
-import { TranslationMixin } from './translationMixin';
-import { preHTML } from '../libs/lit-helpers';
+import dialogPolyfill from 'dialog-polyfill';
+import { html } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { uniqID } from '../libs/helpers.ts';
+import { preHTML } from '../libs/lit-helpers.ts';
+import { TranslationMixin } from './translationMixin.ts';
 
 const ValidationMixin = {
   name: 'validation-mixin',
@@ -11,89 +11,95 @@ const ValidationMixin = {
   attributes: {
     confirmationMessage: {
       type: String,
-      default: null
+      default: null,
     },
     confirmationType: {
       type: String,
-      default: null
+      default: null,
     },
     confirmationSubmitText: {
       type: String,
-      default: null
+      default: null,
     },
     confirmationCancelText: {
       type: String,
-      default: null
+      default: null,
     },
     confirmationSubmitClass: {
       type: String,
-      default: undefined
+      default: undefined,
     },
     confirmationCancelClass: {
       type: String,
-      default: undefined
+      default: undefined,
     },
     confirmationWidget: {
       type: String,
-      default: undefined
-    }
+      default: undefined,
+    },
   },
   created() {
     this.dialogID = uniqID();
   },
   showModal() {
-    var dialog: any = document.getElementById(this.dialogID);
+    const dialog: any = document.getElementById(this.dialogID);
     dialogPolyfill.registerDialog(dialog);
     return dialog.showModal();
   },
   performAction() {
     // Console warning if conf-type attr not filled AND conf-message filled
-    if (this.element.hasAttribute('confirmation-message') && !this.confirmationType) console.warn('confirmation-type attribute is missing.');
+    if (
+      this.element.hasAttribute('confirmation-message') &&
+      !this.confirmationType
+    )
+      console.warn('confirmation-type attribute is missing.');
     // Data directly submitted OR confirm dialog modal displayed
-    if ((!this.confirmationType) || (this.confirmationType == "confirm" && confirm(this.confirmationMessage || this.t("validation.message")))) this.validateModal();
+    if (
+      !this.confirmationType ||
+      (this.confirmationType === 'confirm' &&
+        confirm(this.confirmationMessage || this.t('validation.message')))
+    )
+      this.validateModal();
     // Customisable dialog modal opened
-    if (this.confirmationType == "dialog") {
+    if (this.confirmationType === 'dialog') {
       this.showModal();
     }
   },
   getModalDialog() {
-    if (this.confirmationType == 'dialog') {
-      const quitDialog = () => {
-        var dialog: any = document.getElementById(this.dialogID);
-        if (dialog == null) return;
-        dialog.close();
-      }
-      const confirmChoice = () => {
-        this.validateModal();
-        quitDialog();
+    if (this.confirmationType !== 'dialog') return '';
+    const quitDialog = () => {
+      const dialog: any = document.getElementById(this.dialogID);
+      if (dialog == null) return;
+      dialog.close();
+    };
+    const confirmChoice = () => {
+      this.validateModal();
+      quitDialog();
+    };
+    return html`
+      <dialog id="${this.dialogID}">
+      ${
+        this.confirmationWidget
+          ? preHTML`<${this.confirmationWidget} value=${this.resourceId}></${this.confirmationWidget}>`
+          : html`<p>${this.confirmationMessage || this.t('validation.message')}</p>`
       }
-      return html`
-        <dialog id="${this.dialogID}">
-        ${this.confirmationWidget ? preHTML`
-          <${this.confirmationWidget} value=${this.resourceId}></${this.confirmationWidget}>
-        ` : html`
-          <p>${this.confirmationMessage || this.t("validation.message")}</p>
-        `}
-          <div>
-            <button
-              @click=${confirmChoice} 
-              class=${ifDefined(this.confirmationSubmitClass)}
-            >
-            ${this.confirmationSubmitText || this.t("validation.submit-text")}
-            </button>
-            <button
-              @click=${quitDialog}
-              class=${ifDefined(this.confirmationCancelClass)}
-            >
-            ${this.confirmationCancelText || this.t("validation.cancel-text")}
-            </button>
-          </div>
-        </dialog>
-      `
-    } else return '';
+        <div>
+          <button
+            @click=${confirmChoice} 
+            class=${ifDefined(this.confirmationSubmitClass)}
+          >
+          ${this.confirmationSubmitText || this.t('validation.submit-text')}
+          </button>
+          <button
+            @click=${quitDialog}
+            class=${ifDefined(this.confirmationCancelClass)}
+          >
+          ${this.confirmationCancelText || this.t('validation.cancel-text')}
+          </button>
+        </div>
+      </dialog>
+    `;
   },
-}
+};
 
-export {
-  ValidationMixin
-}
\ No newline at end of file
+export { ValidationMixin };
diff --git a/src/mixins/widgetMixin.ts b/src/mixins/widgetMixin.ts
index 96f0771f8ac689869344dafb9901baa426e5204c..ca46eef7d26f2555ec357dfab94913f606021045 100644
--- a/src/mixins/widgetMixin.ts
+++ b/src/mixins/widgetMixin.ts
@@ -1,9 +1,16 @@
-import { spread, preHTML } from '../libs/lit-helpers';
-import { parseFieldsString, findClosingBracketMatchIndex } from '../libs/helpers';
-import { newWidgetFactory } from '../new-widgets/new-widget-factory';
-import { WidgetInterface, WidgetType, Resource } from './interfaces';
-import { html, render, TemplateResult } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
+import { type TemplateResult, html, render } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import {
+  findClosingBracketMatchIndex,
+  parseFieldsString,
+} from '../libs/helpers.ts';
+import { preHTML, spread } from '../libs/lit-helpers.ts';
+import { newWidgetFactory } from '../new-widgets/new-widget-factory.ts';
+import {
+  type Resource,
+  type WidgetInterface,
+  WidgetType,
+} from './interfaces.ts';
 
 const WidgetMixin = {
   name: 'widget-mixin',
@@ -12,17 +19,18 @@ const WidgetMixin = {
     fields: {
       type: String,
       default: undefined,
-    }
+    },
   },
   initialState: {
     nameWidgets: null,
-    _div: null
+    _div: null,
   },
   created(): void {
     this.nameWidgets = [];
   },
   attached(): void {
-    if (!this.dataSrc && !this.resource && this.noRender === null) this.populate();
+    if (!this.dataSrc && !this.resource && this.noRender === null)
+      this.populate();
   },
   get parentElement(): string {
     return 'div';
@@ -34,39 +42,45 @@ const WidgetMixin = {
     return this._div;
   },
   set div(value) {
-    this._div = value
+    this._div = value;
   },
   get widgets() {
-    return this.nameWidgets.map((name: string) => this.element.querySelector(`[name="${name}"]`));
+    return this.nameWidgets.map((name: string) =>
+      this.element.querySelector(`[name="${name}"]`),
+    );
   },
   /**
    * Return field list of the component
    */
-  async getFields(): Promise<string[]>{ // TODO : improve code
+  async getFields(): Promise<string[]> {
+    // TODO : improve code
     const attr = this.fields;
     if (attr === '') return [];
     if (attr) return parseFieldsString(attr);
 
     let resource = this.resource as Resource;
-    if (resource && resource.isContainer?.()) { // If container, keep the 1rst resource
-      for (let res of resource['ldp:contains']) {
+    if (resource?.isContainer?.()) {
+      // If container, keep the 1rst resource
+      for (const res of resource['ldp:contains']) {
         resource = res;
         break;
       }
-    } else if (resource && this.arrayField && this.predicateName) { // if array, keep the 1rst resource
-      for (let res of resource[this.predicateName]) {
+    } else if (resource && this.arrayField && this.predicateName) {
+      // if array, keep the 1rst resource
+      for (const res of resource[this.predicateName]) {
         resource = res;
         break;
       }
     }
 
-    if (!this.dataSrc) console.error(new Error('You must provide a "fields" attribute'));
-    if(!resource) return [];
+    if (!this.dataSrc)
+      console.error(new Error('You must provide a "fields" attribute'));
+    if (!resource) return [];
 
-    let fields: string[] = [];
+    const fields: string[] = [];
     for (const prop of resource.properties) {
-      if ((!prop.startsWith('@') && !(prop === "permissions"))) {
-        if (!this.isAlias(prop) && await resource[prop]) fields.push(prop);
+      if (!prop.startsWith('@') && !(prop === 'permissions')) {
+        if (!this.isAlias(prop) && (await resource[prop])) fields.push(prop);
         else if (this.isAlias(prop)) fields.push(prop);
       }
     }
@@ -77,7 +91,7 @@ const WidgetMixin = {
    * @param field - string
    */
   getAction(field: string): string {
-    const action = this.element.getAttribute('action-' + field);
+    const action = this.element.getAttribute(`action-${field}`);
     return action;
   },
   /**
@@ -85,14 +99,14 @@ const WidgetMixin = {
    * @param field - string
    */
   editable(field: string): string {
-    return this.element.hasAttribute('editable-' + field);
+    return this.element.hasAttribute(`editable-${field}`);
   },
   /**
    * Return regexp to check if "field" is a set
    * @param field - string
    */
   getSetRegexp(field: string) {
-    return new RegExp(`(^|\\,|\\(|\\s)\\s*${field}\\s*\\(`, 'g')
+    return new RegExp(`(^|\\,|\\(|\\s)\\s*${field}\\s*\\(`, 'g');
   },
   /**
    * Return fields contained in set "field"
@@ -101,8 +115,12 @@ const WidgetMixin = {
   getSet(field: string): string[] {
     const setString = this.fields.match(this.getSetRegexp(field));
     if (!setString) return [];
-    const firstSetBracket = this.fields.indexOf(setString[0]) + (setString[0].length) - 1;
-    const lastSetBracket = findClosingBracketMatchIndex(this.fields, firstSetBracket);
+    const firstSetBracket =
+      this.fields.indexOf(setString[0]) + setString[0].length - 1;
+    const lastSetBracket = findClosingBracketMatchIndex(
+      this.fields,
+      firstSetBracket,
+    );
     const set = this.fields.substring(firstSetBracket + 1, lastSetBracket);
     return parseFieldsString(set);
   },
@@ -112,7 +130,7 @@ const WidgetMixin = {
    */
   isSet(field: string): boolean {
     if (!this.fields) return false;
-    let foundSets = this.fields.match(this.getSetRegexp(field));
+    const foundSets = this.fields.match(this.getSetRegexp(field));
     return foundSets ? foundSets.length > 0 : false;
   },
   /**
@@ -120,7 +138,7 @@ const WidgetMixin = {
    * @param field - string
    */
   isString(field: string): boolean {
-    return field.startsWith('\'') || field.startsWith('\"');
+    return field.startsWith("'") || field.startsWith('"');
   },
   /**
    * Return true if "field" is an alias (contains " as ")
@@ -138,22 +156,35 @@ const WidgetMixin = {
   async fetchValue(field: string, resource: Resource) {
     if (resource && !resource.isContainer?.()) {
       let fieldValue = await resource[field];
-      if (fieldValue === null || fieldValue === undefined || fieldValue === '') {
-        let expandedPredicate = sibStore.getExpandedPredicate(field, this.context);
+      if (
+        fieldValue === null ||
+        fieldValue === undefined ||
+        fieldValue === ''
+      ) {
+        const expandedPredicate = sibStore.getExpandedPredicate(
+          field,
+          this.context,
+        );
         fieldValue = await resource[expandedPredicate];
       }
 
-      if (fieldValue === null || fieldValue === undefined || fieldValue === '') return undefined;
+      if (fieldValue === null || fieldValue === undefined || fieldValue === '')
+        return undefined;
       if (Array.isArray(fieldValue) && !fieldValue['ldp:contains']) {
         return JSON.stringify(fieldValue);
-      // Dumb edge case because if the array bears only one item, when compacted the array translates into one object
-      } else if (
+        // Dumb edge case because if the array bears only one item, when compacted the array translates into one object
+      }
+      if (
         typeof fieldValue === 'object' &&
-        fieldValue['@id'] && 1 === Object.keys(fieldValue).length) {
+        fieldValue['@id'] &&
+        Object.keys(fieldValue).length === 1
+      ) {
         return JSON.stringify([fieldValue]);
       }
     }
-    return resource && !resource.isContainer?.() ? await resource[field] : undefined;
+    return resource && !resource.isContainer?.()
+      ? await resource[field]
+      : undefined;
   },
   /**
    * Return the value of the field
@@ -165,8 +196,8 @@ const WidgetMixin = {
       return this.getAction(escapedField);
     }
 
-    if (this.element.hasAttribute('value-' + field)) {
-      return this.element.getAttribute('value-' + field);
+    if (this.element.hasAttribute(`value-${field}`)) {
+      return this.element.getAttribute(`value-${field}`);
     }
 
     if (this.isAlias(field)) {
@@ -174,11 +205,17 @@ const WidgetMixin = {
       return await this.fetchValue(alias[0], resource);
     }
 
-    let resourceValue = await this.fetchValue(field, resource);
+    const resourceValue = await this.fetchValue(field, resource);
     // Empty value
-    if (resourceValue === undefined || resourceValue === '' || resourceValue === null) // If null or empty, return field default value
-      return this.element.hasAttribute('default-' + field) ?
-        this.element.getAttribute('default-' + field) : '';
+    if (
+      resourceValue === undefined ||
+      resourceValue === '' ||
+      resourceValue === null
+    )
+      // If null or empty, return field default value
+      return this.element.hasAttribute(`default-${field}`)
+        ? this.element.getAttribute(`default-${field}`)
+        : '';
 
     return resourceValue;
   },
@@ -188,9 +225,13 @@ const WidgetMixin = {
    * @param tagName - string
    */
   widgetFromTagName(tagName: string) {
-    let type = tagName.startsWith('solid') ? WidgetType.CUSTOM : WidgetType.USER;
-    if (!customElements.get(tagName)) { // component does not exist
-      if (tagName.startsWith('solid')) newWidgetFactory(tagName); // solid- -> create it
+    let type = tagName.startsWith('solid')
+      ? WidgetType.CUSTOM
+      : WidgetType.USER;
+    if (!customElements.get(tagName)) {
+      // component does not exist
+      if (tagName.startsWith('solid'))
+        newWidgetFactory(tagName); // solid- -> create it
       else type = WidgetType.NATIVE; // or use a native tag
     }
     return { tagName, type }; // return tagName
@@ -200,23 +241,26 @@ const WidgetMixin = {
    * @param field - string
    * @param isSet - boolean
    */
-  getWidget(field: string, isSet: boolean = false): WidgetInterface {
+  getWidget(field: string, isSet = false): WidgetInterface {
     if (this.isAlias(field)) field = field.split(' as ')[1];
-    const widget = this.element.getAttribute('widget-' + field);
+    const widget = this.element.getAttribute(`widget-${field}`);
 
     if (widget) return this.widgetFromTagName(widget);
     if (this.getAction(field)) return this.widgetFromTagName('solid-action');
 
-    return !isSet ? this.widgetFromTagName(this.defaultWidget) : this.widgetFromTagName(this.defaultSetWidget);
+    return !isSet
+      ? this.widgetFromTagName(this.defaultWidget)
+      : this.widgetFromTagName(this.defaultSetWidget);
   },
   /**
    * Return multiple widget if "field" is a multiple, false if it's not
    * @param field - string
    */
-  multiple(field: string): WidgetInterface|null {
-    const attribute = 'multiple-' + field;
+  multiple(field: string): WidgetInterface | null {
+    const attribute = `multiple-${field}`;
     if (!this.element.hasAttribute(attribute)) return null;
-    const widget = this.element.getAttribute(attribute) || this.defaultMultipleWidget;
+    const widget =
+      this.element.getAttribute(attribute) || this.defaultMultipleWidget;
     return this.widgetFromTagName(widget);
   },
   /**
@@ -236,7 +280,7 @@ const WidgetMixin = {
    * @param resource - Resource
    */
   widgetAttributes(field: string, resource: Resource): object {
-    const attrs = { name: field };
+    const attrs: Record<string, string> = { name: field };
     if (this.isAlias(field)) field = field.split(' as ')[1];
     const escapedField = this.getEscapedField(field);
 
@@ -247,12 +291,13 @@ const WidgetMixin = {
       'widget',
       'add-label',
       'remove-label',
-      'next', 
+      'next',
       'empty-widget',
       'add-class',
-      'remove-class'
+      'remove-class',
     ];
-    for (let attr of multipleAttributes) this.addToAttributes(`multiple-${escapedField}-${attr}`, attr, attrs)
+    for (const attr of multipleAttributes)
+      this.addToAttributes(`multiple-${escapedField}-${attr}`, attr, attrs);
 
     // transfer all [attr]-[field] attributes as [attr] attribute for widget [field]
     const defaultAttributes = [
@@ -261,7 +306,7 @@ const WidgetMixin = {
       'label',
       'placeholder',
       'class',
-      /* 'widget', */,
+      /* 'widget', */
       'required',
       'editable',
       'autocomplete',
@@ -286,72 +331,95 @@ const WidgetMixin = {
       'search-placeholder',
       'link-text',
       'target-src',
-      'data-label'
+      'data-label',
     ];
-    for (let attr of defaultAttributes) this.addToAttributes(`${attr}-${escapedField}`, attr,  attrs)
+    for (const attr of defaultAttributes)
+      this.addToAttributes(`${attr}-${escapedField}`, attr, attrs);
 
-    const addableAttributes: Attr[] = (Array.from(this.element.attributes) as Attr[]).filter((a: Attr) => a.name.startsWith(`addable-${escapedField}`));
-    for (let attr of addableAttributes) this.addToAttributes(attr.name, attr.name.replace(`addable-${escapedField}`, 'addable'), attrs)
+    const addableAttributes: Attr[] = (
+      Array.from(this.element.attributes) as Attr[]
+    ).filter((a: Attr) => a.name.startsWith(`addable-${escapedField}`));
+    for (const attr of addableAttributes)
+      this.addToAttributes(
+        attr.name,
+        attr.name.replace(`addable-${escapedField}`, 'addable'),
+        attrs,
+      );
 
-    const resourceId = resource ? resource!['@id'] : null;
-    if (this.multiple(escapedField)) attrs['widget'] = this.getWidget(escapedField).tagName;
-    if (this.getAction(escapedField) && resourceId) attrs['src'] = this.element.getAttribute('src-' + escapedField) || resourceId;
-    if (this.editable(escapedField) && resourceId) attrs['value-id'] = resourceId;
+    const resourceId = resource?.['@id'] ?? null;
+    if (this.multiple(escapedField))
+      attrs.widget = this.getWidget(escapedField).tagName;
+    if (this.getAction(escapedField) && resourceId)
+      attrs.src =
+        this.element.getAttribute(`src-${escapedField}`) || resourceId;
+    if (this.editable(escapedField) && resourceId)
+      attrs['value-id'] = resourceId;
     return attrs;
   },
   /**
    * Creates and return a widget for field + add it to the widget list
    * @param field - string
    */
-  async createWidgetTemplate(field: string, resource = null, transformAttributes = false): Promise<TemplateResult> {
+  async createWidgetTemplate(
+    field: string,
+    resource = null,
+    transformAttributes = false,
+  ): Promise<TemplateResult> {
     if (this.isString(field)) return this.createString(field); // field is a static string
     if (this.isSet(field)) return await this.createSet(field);
 
     const currentResource = resource || this.resource;
     let attributes = this.widgetAttributes(field, currentResource);
     const escapedField = this.getEscapedField(field);
-    const widgetMeta = this.multiple(escapedField) || this.getWidget(escapedField);
+    const widgetMeta =
+      this.multiple(escapedField) || this.getWidget(escapedField);
     let tagName = widgetMeta.tagName;
-    let widgetTemplate = html``;
+    let widgetTemplate: TemplateResult = html``;
 
     // Set attributes
-    let value = await this.getValue(field, currentResource);
-    if (widgetMeta.type === WidgetType.NATIVE) { // native widget (ie: h1)
-      widgetTemplate = preHTML`
-        <${tagName}
-          name="${ifDefined(attributes.name)}"
-          class="${ifDefined(attributes.class)}"
-        >${value}</${tagName}>
-      `;
-    } else { // custom widget (ie: solid-display-value)
+    const value = await this.getValue(field, currentResource);
+    if (widgetMeta.type === WidgetType.NATIVE) {
+      // native widget (ie: h1)
+      widgetTemplate = preHTML`<${tagName} name="${ifDefined(attributes.name)}" class="${ifDefined(attributes.class)}">${value}</${tagName}>`;
+    } else {
+      // custom widget (ie: solid-display-value)
       // Check if value is defined, and if the default widget is needed
-      if ((value === null || value === '') && this.element.hasAttribute('default-widget-' + field)) {
-        tagName = this.element.getAttribute('default-widget-' + field);
+      if (
+        (value === null || value === '') &&
+        this.element.hasAttribute(`default-widget-${field}`)
+      ) {
+        tagName = this.element.getAttribute(`default-widget-${field}`);
       }
       // Set attributes to the widget
       // setAttribute set a string. Make sure null values are empty
       if (value === null || value === undefined) attributes.value = '';
-      if (widgetMeta.type === WidgetType.USER) { // if value is a resource and solid-widget used, set data-src
+      if (widgetMeta.type === WidgetType.USER) {
+        // if value is a resource and solid-widget used, set data-src
         if (value['@id']) {
           attributes['data-src'] = value['@id'];
         } else {
           try {
-            let isUrl = new URL(value);
+            const isUrl = new URL(value);
             if (isUrl) attributes['data-src'] = value;
-          } catch (e) {}
+          } catch {}
 
           // in any case, set value attribute
-          attributes['value'] = value;
+          attributes.value = value;
         }
-      } else { // otherwise, set value attribute
-        attributes['value'] = value;
+      } else {
+        // otherwise, set value attribute
+        attributes.value = value;
       }
 
       // Subscribe widgets if they show a resource
-      if (value && value['@id']) attributes['auto-subscribe'] = value['@id'];
+      if (value?.['@id']) attributes['auto-subscribe'] = value['@id'];
 
       // Transform store://XXX attributes
-      if (transformAttributes) attributes = await this.transformAttributes(attributes, currentResource);
+      if (transformAttributes)
+        attributes = await this.transformAttributes(
+          attributes,
+          currentResource,
+        );
 
       widgetTemplate = preHTML`<${tagName} ...=${spread(attributes)}></${tagName}>`;
     }
@@ -360,7 +428,8 @@ const WidgetMixin = {
     return widgetTemplate;
   },
   defineAttribute(widget: HTMLElement, attribute: string, value: any) {
-    if (widget.getAttribute(attribute) !== value) { // if attribute is different than previous one
+    if (widget.getAttribute(attribute) !== value) {
+      // if attribute is different than previous one
       widget.setAttribute(attribute, value); // set it
     }
   },
@@ -373,55 +442,59 @@ const WidgetMixin = {
 
     // Get set attributes
     const attrs = { name: field };
-    const setAttributes = [
-      'class',
-      'label'
-    ];
-    for (let attr of setAttributes) this.addToAttributes(`${attr}-${field}`, attr, attrs);
+    const setAttributes = ['class', 'label'];
+    for (const attr of setAttributes)
+      this.addToAttributes(`${attr}-${field}`, attr, attrs);
 
     // Create widget if not already existing
-    let widget = this.element.querySelector(`${setWidget.tagName}[name="${field}"]`);
+    let widget = this.element.querySelector(
+      `${setWidget.tagName}[name="${field}"]`,
+    );
     let initializing = false; // used to render widget only first time
     if (!widget) {
       widget = document.createElement(setWidget.tagName);
       initializing = true;
     }
-    for (let name of Object.keys(attrs)) {
+    for (const name of Object.keys(attrs)) {
       this.defineAttribute(widget, name, attrs[name], setWidget.type);
     }
     if (widget.component && initializing) widget.component.render();
-    let setFields = this.getSet(field);
+    const setFields = this.getSet(field);
     // Catch widget for the set if all these fields are empty
-    if (this.element.hasAttribute('empty-' + field)) {
+    if (this.element.hasAttribute(`empty-${field}`)) {
       let hasOnlyEmpty = true;
-      for(let field of setFields) {
-        let value: string = await this.getValue(field, this.resource);
-        if (value !== '') { // if one not empty
+      for (const field of setFields) {
+        const value: string = await this.getValue(field, this.resource);
+        if (value !== '') {
+          // if one not empty
           hasOnlyEmpty = false;
-          continue; // break loop
+          break;
         }
-      };
-      if(hasOnlyEmpty) { // if only empty values, return empty-widget
+      }
+      if (hasOnlyEmpty) {
+        // if only empty values, return empty-widget
         const attributes = this.widgetAttributes(field, this.resource);
         const tagName = this.element.getAttribute(`empty-${field}`);
         const valueSet = this.element.getAttribute(`empty-${field}-value`);
         if (valueSet) attributes.value = valueSet;
         return preHTML`<${tagName} ...=${spread(attributes)}></${tagName}>`;
-      };
+      }
     }
-    if (!setFields.length) {
-      console.warn(`Set with name ${field} has not been generated due to being empty`)
+    if (setFields.length === 0) {
+      console.warn(
+        `Set with name ${field} has not been generated due to being empty`,
+      );
     }
     // Render template
-    const widgetsTemplate = await Promise.all(setFields.map((field: string) => this.createWidgetTemplate(field)));
+    const widgetsTemplate = await Promise.all(
+      setFields.map((field: string) => this.createWidgetTemplate(field)),
+    );
     const template = html`${widgetsTemplate}`;
     render(template, widget.querySelector('[data-content]') || widget);
     return widget;
   },
   createString(value: string): TemplateResult {
-    return html`
-      <span>${value.slice(1, -1).replace(/\\(['"])/g, '$1')}</span>
-    `;
+    return html`<span>${value.slice(1, -1).replace(/\\(['"])/g, '$1')}</span>`;
   },
   /**
    * Returns field name without starting "@"
@@ -429,9 +502,7 @@ const WidgetMixin = {
    */
   getEscapedField(field: string): string {
     return field.startsWith('@') ? field.slice(1, field.length) : field;
-  }
-}
+  },
+};
 
-export {
-  WidgetMixin
-}
\ No newline at end of file
+export { WidgetMixin };
diff --git a/src/new-widgets/attributeMixins/actionMixin.ts b/src/new-widgets/attributeMixins/actionMixin.ts
index a50058cd0a73fbf572abff5768d85b154c634a91..6a5e25f4c15cf6692e630718101bbb8054ac5258 100644
--- a/src/new-widgets/attributeMixins/actionMixin.ts
+++ b/src/new-widgets/attributeMixins/actionMixin.ts
@@ -6,18 +6,16 @@ const ActionMixin = {
       default: '',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'src');
-      }
+      },
     },
     targetSrc: {
       type: String,
       default: '',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'target-src');
-      }
+      },
     },
   },
-}
+};
 
-export {
-  ActionMixin
-}
\ No newline at end of file
+export { ActionMixin };
diff --git a/src/new-widgets/attributeMixins/blankMixin.ts b/src/new-widgets/attributeMixins/blankMixin.ts
index 0ecac831ca83318dc8cd6ae317d43e7f1591fba7..5e3569cdbbba3d70e2dc0e70105cd343c3bb38d0 100644
--- a/src/new-widgets/attributeMixins/blankMixin.ts
+++ b/src/new-widgets/attributeMixins/blankMixin.ts
@@ -1,10 +1,8 @@
 const BlankMixin = {
   name: 'blank-mixin',
   created() {
-    this.listAttributes['target'] = '_blank';
-  }
-}
+    this.listAttributes.target = '_blank';
+  },
+};
 
-export {
-  BlankMixin
-}
\ No newline at end of file
+export { BlankMixin };
diff --git a/src/new-widgets/attributeMixins/index.ts b/src/new-widgets/attributeMixins/index.ts
index 0106ad776d97bbded1f09f6502f678ba121cfbdf..7032f711f9ced0e2f1a8d8f3b3af80a4ae748d1a 100644
--- a/src/new-widgets/attributeMixins/index.ts
+++ b/src/new-widgets/attributeMixins/index.ts
@@ -1,11 +1,11 @@
-import { MultipleMixin } from './multipleMixin';
-import { ActionMixin } from './actionMixin';
-import { BlankMixin } from './blankMixin';
-import { MailtoMixin } from './mailtoMixin';
-import { TelMixin } from './telMixin';
-import { PlaceholderMixin } from './placeholderMixin';
-import { BooleanMixin } from './booleanMixin';
-import { NumberMixin } from './numberMixin';
+import { ActionMixin } from './actionMixin.ts';
+import { BlankMixin } from './blankMixin.ts';
+import { BooleanMixin } from './booleanMixin.ts';
+import { MailtoMixin } from './mailtoMixin.ts';
+import { MultipleMixin } from './multipleMixin.ts';
+import { NumberMixin } from './numberMixin.ts';
+import { PlaceholderMixin } from './placeholderMixin.ts';
+import { TelMixin } from './telMixin.ts';
 
 const attributeDirectory = {
   multiple: MultipleMixin,
@@ -16,7 +16,7 @@ const attributeDirectory = {
   placeholder: PlaceholderMixin,
   bool: BooleanMixin,
   num: NumberMixin,
-}
+};
 
 export {
   attributeDirectory,
@@ -26,4 +26,4 @@ export {
   MailtoMixin,
   TelMixin,
   PlaceholderMixin,
-}
+};
diff --git a/src/new-widgets/attributeMixins/mailtoMixin.ts b/src/new-widgets/attributeMixins/mailtoMixin.ts
index 618264e425e8480a11d5235fb0eea374b11e91aa..b500c742fce8327fecaaa6cc638410a57f3e4978 100644
--- a/src/new-widgets/attributeMixins/mailtoMixin.ts
+++ b/src/new-widgets/attributeMixins/mailtoMixin.ts
@@ -1,10 +1,8 @@
 const MailtoMixin = {
   name: 'mailto-mixin',
   created() {
-    this.listAttributes['mailto'] = 'mailto:';
-  }
-}
+    this.listAttributes.mailto = 'mailto:';
+  },
+};
 
-export {
-  MailtoMixin
-}
\ No newline at end of file
+export { MailtoMixin };
diff --git a/src/new-widgets/attributeMixins/multipleMixin.ts b/src/new-widgets/attributeMixins/multipleMixin.ts
index 90e0e01fb79dc15a088a0b1f040ce4a446000cd2..45bab1ea4ca60e4084198f892911074d75246af2 100644
--- a/src/new-widgets/attributeMixins/multipleMixin.ts
+++ b/src/new-widgets/attributeMixins/multipleMixin.ts
@@ -6,25 +6,23 @@ const MultipleMixin = {
       default: '',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'fields');
-      }
+      },
     },
     next: {
       type: String,
       default: '',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'next');
-      }
+      },
     },
     emptyWidget: {
       type: String,
       default: '',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'emptyWidget');
-      }
-    }
+      },
+    },
   },
-}
+};
 
-export {
-  MultipleMixin
-}
\ No newline at end of file
+export { MultipleMixin };
diff --git a/src/new-widgets/attributeMixins/placeholderMixin.ts b/src/new-widgets/attributeMixins/placeholderMixin.ts
index 301bcb7019d058863416c2b46e9a8cd1e70be1c4..aee2ef30ef763f0f1c4b229cd11105866ac0445b 100644
--- a/src/new-widgets/attributeMixins/placeholderMixin.ts
+++ b/src/new-widgets/attributeMixins/placeholderMixin.ts
@@ -6,14 +6,13 @@ const PlaceholderMixin = {
       default: '',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'placeholder');
-      }
+      },
     },
   },
   attached() {
-    this.listAttributes['placeholder'] = this.placeholder || this.label || this.name || '';
-  }
-}
+    this.listAttributes.placeholder =
+      this.placeholder || this.label || this.name || '';
+  },
+};
 
-export {
-  PlaceholderMixin
-}
\ No newline at end of file
+export { PlaceholderMixin };
diff --git a/src/new-widgets/attributeMixins/telMixin.ts b/src/new-widgets/attributeMixins/telMixin.ts
index 26a9a1e02d197cdb1d0317020232003ff3c7e296..3582ace3756de0804b870ab87b0c8cb6ed3b9cd9 100644
--- a/src/new-widgets/attributeMixins/telMixin.ts
+++ b/src/new-widgets/attributeMixins/telMixin.ts
@@ -1,10 +1,8 @@
 const TelMixin = {
   name: 'tel-mixin',
   created() {
-    this.listAttributes['tel'] = 'tel:';
-  }
-}
+    this.listAttributes.tel = 'tel:';
+  },
+};
 
-export {
-  TelMixin
-}
\ No newline at end of file
+export { TelMixin };
diff --git a/src/new-widgets/baseWidgetMixin.ts b/src/new-widgets/baseWidgetMixin.ts
index a5cb6195445e93dd029de73247a54f2283237722..b93c369a04c682829bb1cbad5cea4e484e3bb2fa 100644
--- a/src/new-widgets/baseWidgetMixin.ts
+++ b/src/new-widgets/baseWidgetMixin.ts
@@ -1,6 +1,10 @@
-import type { Template } from './interfaces';
+import type PubSubType from 'pubsub-js';
+import { PostProcessorRegistry } from '../libs/PostProcessorRegistry.ts';
+import type { Template } from './interfaces.ts';
 
-import {render} from 'lit-html';
+import { render } from 'lit';
+
+declare const PubSub: typeof PubSubType;
 
 const BaseWidgetMixin = {
   name: 'widget-mixin',
@@ -11,21 +15,21 @@ const BaseWidgetMixin = {
       default: '',
       callback: function () {
         this.planRender();
-      }
+      },
     },
     name: {
       type: String,
       default: '',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'name');
-      }
+      },
     },
     label: {
       type: String,
       default: null,
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'label');
-      }
+      },
     },
     autoSubscribe: {
       type: String,
@@ -33,24 +37,24 @@ const BaseWidgetMixin = {
       callback: function (newValue: string) {
         if (this.subscription) PubSub.unsubscribe(this.subscription);
         this.subscribe(newValue);
-      }
+      },
     },
   },
   initialState: {
-    listValueTransformations: [],
-    listTemplateAdditions: [],
+    listValueTransformations: new PostProcessorRegistry(),
+    listTemplateAdditions: new PostProcessorRegistry(),
     listAttributes: {},
-    listCallbacks: [],
+    listCallbacks: new PostProcessorRegistry(),
     renderPlanned: false,
   },
   get template() {
-    return null
+    return null;
   },
   created() {
-    this.listValueTransformations = [];
+    this.listValueTransformations = new PostProcessorRegistry();
     this.listAttributes = {};
-    this.listTemplateAdditions = [];
-    this.listCallbacks = [];
+    this.listTemplateAdditions = new PostProcessorRegistry();
+    this.listCallbacks = new PostProcessorRegistry();
     this.subscription = null;
   },
   attached() {
@@ -69,28 +73,36 @@ const BaseWidgetMixin = {
     }
   },
   render() {
-    const listValueTransformations = [...this.listValueTransformations];
-    listValueTransformations.push(this.renderTemplate.bind(this));
-
-    const nextProcessor = listValueTransformations.shift();
-    nextProcessor(this.value, listValueTransformations);
+    const listValueTransformationsCopy =
+      this.listValueTransformations.deepCopy();
+    listValueTransformationsCopy.attach(
+      this.renderTemplate.bind(this),
+      'BaseWidgetMixin:renderTemplate',
+    );
+    const nextProcessor = listValueTransformationsCopy.shift();
+    nextProcessor(this.value, listValueTransformationsCopy);
 
     // Callbacks
-    const listCallbacks = [...this.listCallbacks];
-    if (listCallbacks.length) {
-      const nextCallback = listCallbacks.shift();
-      nextCallback(this.value, listCallbacks);
+    const listCallbacksCopy = this.listCallbacks.deepCopy();
+    const nextCallback = listCallbacksCopy.shift();
+    if (nextCallback) {
+      nextCallback(this.value, listCallbacksCopy);
     }
 
-    this.element.dispatchEvent(new CustomEvent('widgetRendered', { bubbles: true }));
+    this.element.dispatchEvent(
+      new CustomEvent('widgetRendered', { bubbles: true }),
+    );
   },
   renderTemplate(value: string) {
     const template: Template = this.template(value, { ...this.listAttributes });
-    const listTemplateAdditions = [...this.listTemplateAdditions];
-    listTemplateAdditions.push(this.templateToDOM.bind(this));
+    const listTemplateAdditionsCopy = this.listTemplateAdditions.deepCopy();
+    listTemplateAdditionsCopy.attach(
+      this.templateToDOM.bind(this),
+      'BaseWidgetMixin:templateToDOM',
+    );
 
-    const nextProcessor = listTemplateAdditions.shift();
-    nextProcessor(template, listTemplateAdditions);
+    const nextProcessor = listTemplateAdditionsCopy.shift();
+    nextProcessor(template, listTemplateAdditionsCopy);
   },
   templateToDOM(template: Template) {
     render(template, this.element);
@@ -106,9 +118,7 @@ const BaseWidgetMixin = {
   },
   update() {
     this.planRender();
-  }
-}
+  },
+};
 
-export {
-  BaseWidgetMixin
-}
\ No newline at end of file
+export { BaseWidgetMixin };
diff --git a/src/new-widgets/callbackMixins/autocompletionMixin.ts b/src/new-widgets/callbackMixins/autocompletionMixin.ts
index 2bf8f68f7ff6f0107d7317964073cef728e0db04..ac7c156a620490a9d02c5b7c924db95877b5498f 100644
--- a/src/new-widgets/callbackMixins/autocompletionMixin.ts
+++ b/src/new-widgets/callbackMixins/autocompletionMixin.ts
@@ -1,6 +1,11 @@
-import { fuzzyCompare, importInlineCSS } from '../../libs/helpers';
 import SlimSelect from 'slim-select';
-import { TranslationMixin } from '../../mixins/translationMixin';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
+import {
+  asyncQuerySelector,
+  fuzzyCompare,
+  importInlineCSS,
+} from '../../libs/helpers.ts';
+import { TranslationMixin } from '../../mixins/translationMixin.ts';
 
 const AutocompletionMixin = {
   name: 'autocompletion-mixin',
@@ -11,83 +16,73 @@ const AutocompletionMixin = {
       default: null,
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'searchText');
-      }
+      },
     },
     searchPlaceholder: {
       type: String,
       default: null,
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'searchPlaceholder');
-      }
+      },
     },
   },
   initialState: {
     slimSelect: null,
-    mutationObserver: null
+    mutationObserver: null,
   },
   created() {
-    importInlineCSS('slimselect', () => import('./slimselect.css?inline'))
+    importInlineCSS(
+      'slimselect-base',
+      () => import('slim-select/styles?inline'),
+    );
+    importInlineCSS(
+      'slimselect-local',
+      () => import('./slimselect.css?inline'),
+    );
 
     this.slimSelect = null;
     this.addToAttributes(true, 'autocomplete');
-    this.listCallbacks.push(this.addCallback.bind(this));
+    this.listCallbacks.attach(
+      this.addCallback.bind(this),
+      'AutocompletionMixin:addCallback',
+    );
   },
   detached() {
     if (this.slimSelect) this.slimSelect.destroy();
     if (this.mutationObserver) this.mutationObserver.disconnect();
   },
-  addCallback(value: string, listCallbacks: Function[]) {
+  addCallback(value: string, listCallbacks: PostProcessorRegistry) {
     if (this.slimSelect) return;
-    let select = this.element.querySelector('select');
-    if (select) {
+    asyncQuerySelector('select:has(option)', this.element).then(select => {
       this.initSlimSelect(select);
-    } else {
-      // if no select available, wait for one and init slimSelect
-      new MutationObserver((_m, observer) => {
-        const select = this.element.querySelector('select');
-        if (select) {
-          this.initSlimSelect(select);
-          observer.disconnect(); // then disconnect mutationObserver
-        }
-      }).observe(this.element, {
-        childList: true,
-        characterData: true,
-        subtree: true,
-      });
-    }
+    });
     const nextProcessor = listCallbacks.shift();
     if (nextProcessor) nextProcessor(value, listCallbacks);
   },
-  initSlimSelect(select: Element) {
-    const slimSelect = new SlimSelect({ select });
-    this.slimSelect = slimSelect;
-    select.addEventListener('change', () => {
-      this.slimSelect.render();
-      this.element.dispatchEvent(new Event('input', { bubbles: true }));
+  async initSlimSelect(select: Element) {
+    await new Promise(resolve => setTimeout(resolve, 500));
+    const slimSelect = new SlimSelect({
+      select,
+      settings: {
+        placeholderText:
+          this.placeholder || this.t('autocompletion.placeholder'),
+        searchText: this.searchText || this.t('autocompletion.searchText'),
+        searchPlaceholder:
+          this.searchPlaceholder || this.t('autocompletion.searchPlaceholder'),
+        contentLocation: this.element,
+      },
+      events: {
+        searchFilter: (option, filterValue) =>
+          fuzzyCompare(option.text, filterValue),
+      },
     });
-    this.element.addEventListener('input', (e:Event) => {
-      if(e.target !== this.element) {
+    this.slimSelect = slimSelect;
+    this.element.addEventListener('input', (e: Event) => {
+      if (e.target !== this.element) {
         // avoid update search result when search in slimSelect suggestions
         e.stopPropagation();
       }
     });
-
-    // when data changes, re-build slimSelect
-    if (this.mutationObserver) this.mutationObserver.disconnect();
-    this.mutationObserver = new MutationObserver(() => {
-      this.slimSelect.destroy();
-      this.slimSelect = new SlimSelect({
-        select,
-        placeholder: this.placeholder || this.t("autocompletion.placeholder"),
-        searchText: this.searchText || this.t("autocompletion.searchText"),
-        searchPlaceholder: this.searchPlaceholder || this.t("autocompletion.searchPlaceholder"),
-        searchFilter: (option, filterValue) => fuzzyCompare(option.text, filterValue),
-      });
-    }).observe(select, {
-      childList: true,
-      characterData: true,
-      subtree: true,
-    });
   },
 };
 
diff --git a/src/new-widgets/callbackMixins/index.ts b/src/new-widgets/callbackMixins/index.ts
index eca6ff7a57ee688c1923592b461143cdb639f423..162a8adaa57c61513a78ec187d3637af45e7848e 100644
--- a/src/new-widgets/callbackMixins/index.ts
+++ b/src/new-widgets/callbackMixins/index.ts
@@ -1,13 +1,9 @@
-import { AutocompletionMixin } from './autocompletionMixin';
-import { RichtextMixin } from './richtextMixin';
+import { AutocompletionMixin } from './autocompletionMixin.ts';
+import { RichtextMixin } from './richtextMixin.ts';
 
 const callbackDirectory = {
   autocompletion: AutocompletionMixin,
   richtext: RichtextMixin,
-}
+};
 
-export {
-  callbackDirectory,
-  AutocompletionMixin,
-  RichtextMixin,
-}
+export { callbackDirectory, AutocompletionMixin, RichtextMixin };
diff --git a/src/new-widgets/callbackMixins/richtextMixin.ts b/src/new-widgets/callbackMixins/richtextMixin.ts
index ae044c756c9955463e69429dabb59fb549ff773e..59afdcc1f65d66fd2cdb9799ffefacdd369d70b4 100644
--- a/src/new-widgets/callbackMixins/richtextMixin.ts
+++ b/src/new-widgets/callbackMixins/richtextMixin.ts
@@ -1,6 +1,7 @@
+import MarkdownIt from 'markdown-it';
 import Quill from 'quill';
 
-import markdownToDelta from "markdown-to-quill-delta";
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.js';
 import { importInlineCSS } from '../../libs/helpers.js';
 
 const RichtextMixin = {
@@ -10,54 +11,69 @@ const RichtextMixin = {
   },
 
   created() {
-    importInlineCSS('quill', () => import('quill/dist/quill.snow.css?inline'))
+    importInlineCSS('quill', () => import('quill/dist/quill.snow.css?inline'));
 
     this.quill = null;
-    this.listCallbacks.push(this.addCallback.bind(this));
+    this.listCallbacks.attach(
+      this.addCallback.bind(this),
+      'RichtextMixin:addCallback',
+    );
   },
   getPlaceHolderValue() {
-    return this.element.hasAttribute('placeholder') ? this.element.getAttribute('placeholder') : '';
+    return this.element.hasAttribute('placeholder')
+      ? this.element.getAttribute('placeholder')
+      : '';
   },
-  addCallback(value: string, listCallbacks: Function[]) {
+  addCallback(value: string, listCallbacks: PostProcessorRegistry) {
     if (this.quill == null) {
-      var toolbarOptions = [
+      const toolbarOptions = [
         ['bold', 'italic'],
         ['blockquote'],
-        [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
-        [{ 'list': 'ordered' }, { 'list': 'bullet' }],
+        [{ header: [1, 2, 3, 4, 5, 6, false] }],
+        [{ list: 'ordered' }, { list: 'bullet' }],
         ['link'],
-        ['clean']
+        ['clean'],
       ];
-      const richtext = this.element.querySelector('[data-richtext]');
-      this.quill = new Quill(
-        richtext,
-        {
-          modules: { toolbar: toolbarOptions },
-          placeholder: this.getPlaceHolderValue(),
-          theme: 'snow'
-        }
-      );
+      const richtext = this.element.querySelector(
+        '[data-richtext]',
+      ) as HTMLElement;
+      this.quill = new Quill(richtext, {
+        modules: { toolbar: toolbarOptions },
+        placeholder: this.getPlaceHolderValue(),
+        theme: 'snow',
+      });
     }
 
-    const ops = markdownToDelta(this.value);
-    this.quill.setContents(ops);
+    const mdParser = new MarkdownIt({
+      html: true,
+    });
+
+    const formattedValue = this.value.replace(/\r\n|\n/g, '<br>');
+    const html = mdParser.render(formattedValue); // Convert Markdown to HTML
+    const delta = this.quill.clipboard.convert({ html }); // Convert HTML to Delta
+
+    this.quill.setContents(delta);
     if (this.isRequired()) {
-      this.createHiddenRequiredInput()
-      this.quill.on('text-change', this.onTextChange.bind(this))
+      this.createHiddenRequiredInput();
+      this.quill.on('text-change', this.onTextChange.bind(this));
     }
 
     const nextProcessor = listCallbacks.shift();
     if (nextProcessor) nextProcessor(value, listCallbacks);
   },
   isRequired() {
-    return Array.from(this.element.attributes).some(attr => (attr as Attr).name === 'required')
+    return Array.from(this.element.attributes).some(
+      attr => (attr as Attr).name === 'required',
+    );
   },
   createHiddenRequiredInput() {
     const attributeName = this.getAttributeValue('name');
-    this.hiddenInput = document.querySelector(`input[name="${attributeName + '-hidden'}"]`) as HTMLInputElement;
+    this.hiddenInput = document.querySelector(
+      `input[name="${`${attributeName}-hidden`}"]`,
+    ) as HTMLInputElement;
 
     if (!this.hiddenInput) {
-      this.hiddenInput = this.createHiddenInput(attributeName + '-hidden');
+      this.hiddenInput = this.createHiddenInput(`${attributeName}-hidden`);
       this.element.appendChild(this.hiddenInput);
       this.addInvalidEventListener();
     }
@@ -73,14 +89,18 @@ const RichtextMixin = {
     return input;
   },
   getAttributeValue(attributeName: string): string {
-    const attribute = Array.from(this.element.attributes).find(attr => (attr as Attr).name === attributeName) as Attr;
+    const attribute = Array.from(this.element.attributes).find(
+      attr => (attr as Attr).name === attributeName,
+    ) as Attr;
     return attribute ? attribute.value : '';
   },
   displayCustomErrorMessage(message: string) {
     const richtext = this.element.querySelector('[data-richtext]');
 
     if (richtext) {
-      let errorMessageElement = richtext.querySelector('.required-error-message') as HTMLDivElement;
+      let errorMessageElement = richtext.querySelector(
+        '.required-error-message',
+      ) as HTMLDivElement;
 
       if (!errorMessageElement) {
         errorMessageElement = document.createElement('div');
@@ -93,25 +113,24 @@ const RichtextMixin = {
     }
   },
   addInvalidEventListener() {
-    this.hiddenInput.addEventListener("invalid", (e) => {
+    (this.hiddenInput as HTMLInputElement).addEventListener('invalid', e => {
       e.preventDefault();
       this.displayCustomErrorMessage('Please fill out this field.');
     });
   },
   onTextChange() {
-    this.hiddenInput.value = this.quill.getText();
+    (this.hiddenInput as HTMLInputElement).value = this.quill.getText();
     this.removeErrorMessageAndStyling();
   },
   removeErrorMessageAndStyling() {
     // Remove any previously displayed error message and error styling
     const richtext = this.element.querySelector('[data-richtext]');
-    let errorMessageElement = richtext.querySelector('.required-error-message') as HTMLDivElement;
-    if (errorMessageElement)
-      errorMessageElement.remove()
+    const errorMessageElement = richtext.querySelector(
+      '.required-error-message',
+    ) as HTMLDivElement;
+    if (errorMessageElement) errorMessageElement.remove();
     richtext.classList.remove('error-border-richtext');
   },
-}
+};
 
-export {
-  RichtextMixin
-}
\ No newline at end of file
+export { RichtextMixin };
diff --git a/src/new-widgets/callbackMixins/slimselect.css b/src/new-widgets/callbackMixins/slimselect.css
index 3a795bad302fb57f80a51fbe11f0324172997b68..07a93c5308c9c1c7430f11b07b9be2d814ce3a59 100644
--- a/src/new-widgets/callbackMixins/slimselect.css
+++ b/src/new-widgets/callbackMixins/slimselect.css
@@ -1,2 +1,339 @@
-.ss-main{position:relative;display:inline-block;user-select:none;color:#666;width:100%}.ss-main .ss-single-selected{display:flex;cursor:pointer;width:100%;height:30px;padding:6px;border:1px solid #dcdee2;border-radius:4px;background-color:#fff;outline:0;box-sizing:border-box;transition:background-color .2s}.ss-main .ss-single-selected.ss-disabled{background-color:#dcdee2;cursor:not-allowed}.ss-main .ss-single-selected.ss-open-above{border-top-left-radius:0px;border-top-right-radius:0px}.ss-main .ss-single-selected.ss-open-below{border-bottom-left-radius:0px;border-bottom-right-radius:0px}.ss-main .ss-single-selected .placeholder{display:flex;flex:1 1 100%;align-items:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;width:calc(100% - 30px);line-height:1em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ss-main .ss-single-selected .placeholder *{display:flex;align-items:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:auto}.ss-main .ss-single-selected .placeholder .ss-disabled{color:#dedede}.ss-main .ss-single-selected .ss-deselect{display:flex;align-items:center;justify-content:flex-end;flex:0 1 auto;margin:0 6px 0 6px;font-weight:bold}.ss-main .ss-single-selected .ss-deselect.ss-hide{display:none}.ss-main .ss-single-selected .ss-arrow{display:flex;align-items:center;justify-content:flex-end;flex:0 1 auto;margin:0 6px 0 6px}.ss-main .ss-single-selected .ss-arrow span{border:solid #666;border-width:0 2px 2px 0;display:inline-block;padding:3px;transition:transform .2s, margin .2s}.ss-main .ss-single-selected .ss-arrow span.arrow-up{transform:rotate(-135deg);margin:3px 0 0 0}.ss-main .ss-single-selected .ss-arrow span.arrow-down{transform:rotate(45deg);margin:-3px 0 0 0}.ss-main .ss-multi-selected{display:flex;flex-direction:row;cursor:pointer;min-height:30px;width:100%;padding:0 0 0 3px;border:1px solid #dcdee2;border-radius:4px;background-color:#fff;outline:0;box-sizing:border-box;transition:background-color .2s}.ss-main .ss-multi-selected.ss-disabled{background-color:#dcdee2;cursor:not-allowed}.ss-main .ss-multi-selected.ss-disabled .ss-values .ss-disabled{color:#666}.ss-main .ss-multi-selected.ss-disabled .ss-values .ss-value .ss-value-delete{cursor:not-allowed}.ss-main .ss-multi-selected.ss-open-above{border-top-left-radius:0px;border-top-right-radius:0px}.ss-main .ss-multi-selected.ss-open-below{border-bottom-left-radius:0px;border-bottom-right-radius:0px}.ss-main .ss-multi-selected .ss-values{display:flex;flex-wrap:wrap;justify-content:flex-start;flex:1 1 100%;width:calc(100% - 30px)}.ss-main .ss-multi-selected .ss-values .ss-disabled{display:flex;padding:4px 5px;margin:2px 0px;line-height:1em;align-items:center;width:100%;color:#dedede;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@keyframes scaleIn{0%{transform:scale(0);opacity:0}100%{transform:scale(1);opacity:1}}@keyframes scaleOut{0%{transform:scale(1);opacity:1}100%{transform:scale(0);opacity:0}}.ss-main .ss-multi-selected .ss-values .ss-value{display:flex;user-select:none;align-items:center;font-size:12px;padding:3px 5px;margin:3px 5px 3px 0px;color:#fff;background-color:#5897fb;border-radius:4px;animation-name:scaleIn;animation-duration:.2s;animation-timing-function:ease-out;animation-fill-mode:both}.ss-main .ss-multi-selected .ss-values .ss-value.ss-out{animation-name:scaleOut;animation-duration:.2s;animation-timing-function:ease-out}.ss-main .ss-multi-selected .ss-values .ss-value .ss-value-delete{margin:0 0 0 5px;cursor:pointer}.ss-main .ss-multi-selected .ss-add{display:flex;flex:0 1 3px;margin:9px 12px 0 5px}.ss-main .ss-multi-selected .ss-add .ss-plus{display:flex;justify-content:center;align-items:center;background:#666;position:relative;height:10px;width:2px;transition:transform .2s}.ss-main .ss-multi-selected .ss-add .ss-plus:after{background:#666;content:"";position:absolute;height:2px;width:10px;left:-4px;top:4px}.ss-main .ss-multi-selected .ss-add .ss-plus.ss-cross{transform:rotate(45deg)}.ss-content{position:absolute;width:100%;margin:-1px 0 0 0;box-sizing:border-box;border:solid 1px #dcdee2;z-index:1010;background-color:#fff;transform-origin:center top;transition:transform .2s, opacity .2s;opacity:0;transform:scaleY(0)}.ss-content.ss-open{display:block;opacity:1;transform:scaleY(1)}.ss-content .ss-search{display:flex;flex-direction:row;padding:8px 8px 6px 8px}.ss-content .ss-search.ss-hide{height:0px;opacity:0;padding:0px 0px 0px 0px;margin:0px 0px 0px 0px}.ss-content .ss-search.ss-hide input{height:0px;opacity:0;padding:0px 0px 0px 0px;margin:0px 0px 0px 0px}.ss-content .ss-search input{display:inline-flex;font-size:inherit;line-height:inherit;flex:1 1 auto;width:100%;min-width:0px;height:30px;padding:6px 8px;margin:0;border:1px solid #dcdee2;border-radius:4px;background-color:#fff;outline:0;text-align:left;box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-appearance:textfield}.ss-content .ss-search input::placeholder{color:#8a8a8a;vertical-align:middle}.ss-content .ss-search input:focus{box-shadow:0 0 5px #5897fb}.ss-content .ss-search .ss-addable{display:inline-flex;justify-content:center;align-items:center;cursor:pointer;font-size:22px;font-weight:bold;flex:0 0 30px;height:30px;margin:0 0 0 8px;border:1px solid #dcdee2;border-radius:4px;box-sizing:border-box}.ss-content .ss-addable{padding-top:0px}.ss-content .ss-list{max-height:200px;overflow-x:hidden;overflow-y:auto;text-align:left}.ss-content .ss-list .ss-optgroup .ss-optgroup-label{padding:6px 10px 6px 10px;font-weight:bold}.ss-content .ss-list .ss-optgroup .ss-option{padding:6px 6px 6px 25px}.ss-content .ss-list .ss-optgroup-label-selectable{cursor:pointer}.ss-content .ss-list .ss-optgroup-label-selectable:hover{color:#fff;background-color:#5897fb}.ss-content .ss-list .ss-option{padding:6px 10px 6px 10px;cursor:pointer;user-select:none}.ss-content .ss-list .ss-option *{display:inline-block}.ss-content .ss-list .ss-option:hover,.ss-content .ss-list .ss-option.ss-highlighted{color:#fff;background-color:#5897fb}.ss-content .ss-list .ss-option.ss-disabled{cursor:not-allowed;color:#dedede;background-color:#fff}.ss-content .ss-list .ss-option:not(.ss-disabled).ss-option-selected{color:#666;background-color:rgba(88,151,251,0.1)}.ss-content .ss-list .ss-option.ss-hide{display:none}.ss-content .ss-list .ss-option .ss-search-highlight{background-color:#fffb8c}
-
+.ss-main {
+  position: relative;
+  display: inline-block;
+  user-select: none;
+  color: #666;
+  width: 100%;
+}
+.ss-main .ss-single-selected {
+  display: flex;
+  cursor: pointer;
+  width: 100%;
+  height: 30px;
+  padding: 6px;
+  border: 1px solid #dcdee2;
+  border-radius: 4px;
+  background-color: #fff;
+  outline: 0;
+  box-sizing: border-box;
+  transition: background-color .2s;
+}
+.ss-main .ss-single-selected.ss-disabled {
+  background-color: #dcdee2;
+  cursor: not-allowed;
+}
+.ss-main .ss-single-selected.ss-open-above {
+  border-top-left-radius: 0px;
+  border-top-right-radius: 0px;
+}
+.ss-main .ss-single-selected.ss-open-below {
+  border-bottom-left-radius: 0px;
+  border-bottom-right-radius: 0px;
+}
+.ss-main .ss-single-selected .placeholder {
+  display: flex;
+  flex: 1 1 100%;
+  align-items: center;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  text-align: left;
+  width: calc(100% - 30px);
+  line-height: 1em;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.ss-main .ss-single-selected .placeholder * {
+  display: flex;
+  align-items: center;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  width: auto;
+}
+.ss-main .ss-single-selected .placeholder .ss-disabled {
+  color: #dedede;
+}
+.ss-main .ss-single-selected .ss-deselect {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  flex: 0 1 auto;
+  margin: 0 6px 0 6px;
+  font-weight: bold;
+}
+.ss-main .ss-single-selected .ss-deselect.ss-hide {
+  display: none;
+}
+.ss-main .ss-single-selected .ss-arrow {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  flex: 0 1 auto;
+  margin: 0 6px 0 6px;
+}
+.ss-main .ss-single-selected .ss-arrow span {
+  border: solid #666;
+  border-width: 0 2px 2px 0;
+  display: inline-block;
+  padding: 3px;
+  transition: transform .2s, margin .2s;
+}
+.ss-main .ss-single-selected .ss-arrow span.arrow-up {
+  transform: rotate(-135deg);
+  margin: 3px 0 0 0;
+}
+.ss-main .ss-single-selected .ss-arrow span.arrow-down {
+  transform: rotate(45deg);
+  margin: -3px 0 0 0;
+}
+.ss-main .ss-multi-selected {
+  display: flex;
+  flex-direction: row;
+  cursor: pointer;
+  min-height: 30px;
+  width: 100%;
+  padding: 0 0 0 3px;
+  border: 1px solid #dcdee2;
+  border-radius: 4px;
+  background-color: #fff;
+  outline: 0;
+  box-sizing: border-box;
+  transition: background-color .2s;
+}
+.ss-main .ss-multi-selected.ss-disabled {
+  background-color: #dcdee2;
+  cursor: not-allowed;
+}
+.ss-main .ss-multi-selected.ss-disabled .ss-values .ss-disabled {
+  color: #666;
+}
+.ss-main .ss-multi-selected.ss-disabled .ss-values .ss-value .ss-value-delete {
+  cursor: not-allowed;
+}
+.ss-main .ss-multi-selected.ss-open-above {
+  border-top-left-radius: 0px;
+  border-top-right-radius: 0px;
+}
+.ss-main .ss-multi-selected.ss-open-below {
+  border-bottom-left-radius: 0px;
+  border-bottom-right-radius: 0px;
+}
+.ss-main .ss-multi-selected .ss-values {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: flex-start;
+  flex: 1 1 100%;
+  width: calc(100% - 30px);
+}
+.ss-main .ss-multi-selected .ss-values .ss-disabled {
+  display: flex;
+  padding: 4px 5px;
+  margin: 2px 0px;
+  line-height: 1em;
+  align-items: center;
+  width: 100%;
+  color: #dedede;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+@keyframes scaleIn {
+  0% {
+    transform: scale(0);
+    opacity: 0;
+  }
+  100% {
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@keyframes scaleOut {
+  0% {
+    transform: scale(1);
+    opacity: 1;
+  }
+  100% {
+    transform: scale(0);
+    opacity: 0;
+  }
+}
+.ss-main .ss-multi-selected .ss-values .ss-value {
+  display: flex;
+  user-select: none;
+  align-items: center;
+  font-size: 12px;
+  padding: 3px 5px;
+  margin: 3px 5px 3px 0px;
+  color: #fff;
+  background-color: #5897fb;
+  border-radius: 4px;
+  animation-name: scaleIn;
+  animation-duration: .2s;
+  animation-timing-function: ease-out;
+  animation-fill-mode: both;
+}
+.ss-main .ss-multi-selected .ss-values .ss-value.ss-out {
+  animation-name: scaleOut;
+  animation-duration: .2s;
+  animation-timing-function: ease-out;
+}
+.ss-main .ss-multi-selected .ss-values .ss-value .ss-value-delete {
+  margin: 0 0 0 5px;
+  cursor: pointer;
+}
+.ss-main .ss-multi-selected .ss-add {
+  display: flex;
+  flex: 0 1 3px;
+  margin: 9px 12px 0 5px;
+}
+.ss-main .ss-multi-selected .ss-add .ss-plus {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background: #666;
+  position: relative;
+  height: 10px;
+  width: 2px;
+  transition: transform .2s;
+}
+.ss-main .ss-multi-selected .ss-add .ss-plus:after {
+  background: #666;
+  content: "";
+  position: absolute;
+  height: 2px;
+  width: 10px;
+  left: -4px;
+  top: 4px;
+}
+.ss-main .ss-multi-selected .ss-add .ss-plus.ss-cross {
+  transform: rotate(45deg);
+}
+.ss-content {
+  position: absolute;
+  width: 100%;
+  margin: -1px 0 0 0;
+  box-sizing: border-box;
+  border: solid 1px #dcdee2;
+  z-index: 1010;
+  background-color: #fff;
+  transform-origin: center top;
+  transition: transform .2s, opacity .2s;
+  opacity: 0;
+  transform: scaleY(0);
+}
+.ss-content.ss-open {
+  display: block;
+  opacity: 1;
+  transform: scaleY(1);
+}
+.ss-content .ss-search {
+  display: flex;
+  flex-direction: row;
+  padding: 8px 8px 6px 8px;
+}
+.ss-content .ss-search.ss-hide {
+  height: 0px;
+  opacity: 0;
+  padding: 0px 0px 0px 0px;
+  margin: 0px 0px 0px 0px;
+}
+.ss-content .ss-search.ss-hide input {
+  height: 0px;
+  opacity: 0;
+  padding: 0px 0px 0px 0px;
+  margin: 0px 0px 0px 0px;
+}
+.ss-content .ss-search input {
+  display: inline-flex;
+  font-size: inherit;
+  line-height: inherit;
+  flex: 1 1 auto;
+  width: 100%;
+  min-width: 0px;
+  height: 30px;
+  padding: 6px 8px;
+  margin: 0;
+  border: 1px solid #dcdee2;
+  border-radius: 4px;
+  background-color: #fff;
+  outline: 0;
+  text-align: left;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -webkit-appearance: textfield;
+}
+.ss-content .ss-search input::placeholder {
+  color: #8a8a8a;
+  vertical-align: middle;
+}
+.ss-content .ss-search input:focus {
+  box-shadow: 0 0 5px #5897fb;
+}
+.ss-content .ss-search .ss-addable {
+  display: inline-flex;
+  justify-content: center;
+  align-items: center;
+  cursor: pointer;
+  font-size: 22px;
+  font-weight: bold;
+  flex: 0 0 30px;
+  height: 30px;
+  margin: 0 0 0 8px;
+  border: 1px solid #dcdee2;
+  border-radius: 4px;
+  box-sizing: border-box;
+}
+.ss-content .ss-addable {
+  padding-top: 0px;
+}
+.ss-content .ss-list {
+  max-height: 200px;
+  overflow-x: hidden;
+  overflow-y: auto;
+  text-align: left;
+}
+.ss-content .ss-list .ss-optgroup .ss-optgroup-label {
+  padding: 6px 10px 6px 10px;
+  font-weight: bold;
+}
+.ss-content .ss-list .ss-optgroup .ss-option {
+  padding: 6px 6px 6px 25px;
+}
+.ss-content .ss-list .ss-optgroup-label-selectable {
+  cursor: pointer;
+}
+.ss-content .ss-list .ss-optgroup-label-selectable:hover {
+  color: #fff;
+  background-color: #5897fb;
+}
+.ss-content .ss-list .ss-option {
+  padding: 6px 10px 6px 10px;
+  cursor: pointer;
+  user-select: none;
+}
+.ss-content .ss-list .ss-option * {
+  display: inline-block;
+}
+.ss-content .ss-list .ss-option:hover,
+.ss-content .ss-list .ss-option.ss-highlighted {
+  color: #fff;
+  background-color: #5897fb;
+}
+.ss-content .ss-list .ss-option.ss-disabled {
+  cursor: not-allowed;
+  color: #dedede;
+  background-color: #fff;
+}
+.ss-content .ss-list .ss-option:not(.ss-disabled).ss-option-selected {
+  color: #666;
+  background-color: rgba(88, 151, 251, 0.1);
+}
+.ss-content .ss-list .ss-option.ss-hide {
+  display: none;
+}
+.ss-content .ss-list .ss-option .ss-search-highlight {
+  background-color: #fffb8c;
+}
diff --git a/src/new-widgets/interfaces.ts b/src/new-widgets/interfaces.ts
index e638fc9a090cb18b4fb4a1eb1da216e183032da1..01e77e40a8c5d63710202e8e68a4b6126c54da5a 100644
--- a/src/new-widgets/interfaces.ts
+++ b/src/new-widgets/interfaces.ts
@@ -1,11 +1,11 @@
-import type { MixinStaticInterface } from '../libs/interfaces';
+import type { MixinStaticInterface } from '../libs/interfaces.ts';
 
 export interface Template {
-  template: Function
-  dependencies: MixinStaticInterface[]
+  template: Function;
+  dependencies: MixinStaticInterface[];
 }
 
 export interface WidgetMixinsInterface {
-  templateMixin: Template
-  mixins: MixinStaticInterface[]
-}
\ No newline at end of file
+  templateMixin: Template;
+  mixins: MixinStaticInterface[];
+}
diff --git a/src/new-widgets/new-widget-factory.ts b/src/new-widgets/new-widget-factory.ts
index a3dda0d0d6a99e2cb865f9d14c3a273efd2bfbf6..4f8a4ac403ed5d9b6b3dd4da8dc6286acce3c09f 100644
--- a/src/new-widgets/new-widget-factory.ts
+++ b/src/new-widgets/new-widget-factory.ts
@@ -1,12 +1,18 @@
-import { Sib } from '../libs/Sib';
-import { BaseWidgetMixin } from './baseWidgetMixin';
-import type { Template, WidgetMixinsInterface } from './interfaces';
-import type { MixinStaticInterface } from '../libs/interfaces';
-import { defaultTemplates, displayTemplates, formTemplates, setTemplates, groupTemplates } from './templates/index';
-import { valueTransformationDirectory } from './valueTransformationMixins/index';
-import { templateAdditionDirectory } from './templateAdditionMixins/index';
-import { attributeDirectory } from './attributeMixins/index';
-import { callbackDirectory } from './callbackMixins/index';
+import { Sib } from '../libs/Sib.ts';
+import type { MixinStaticInterface } from '../libs/interfaces.ts';
+import { attributeDirectory } from './attributeMixins/index.ts';
+import { BaseWidgetMixin } from './baseWidgetMixin.ts';
+import { callbackDirectory } from './callbackMixins/index.ts';
+import type { Template, WidgetMixinsInterface } from './interfaces.ts';
+import { templateAdditionDirectory } from './templateAdditionMixins/index.ts';
+import {
+  defaultTemplates,
+  displayTemplates,
+  formTemplates,
+  groupTemplates,
+  setTemplates,
+} from './templates/index.ts';
+import { valueTransformationDirectory } from './valueTransformationMixins/index.ts';
 
 const valueTransformationKeys = Object.keys(valueTransformationDirectory);
 const attributeKeys = Object.keys(attributeDirectory);
@@ -19,13 +25,16 @@ const callbackKeys = Object.keys(callbackDirectory);
  */
 export const newWidgetFactory = (tagName: string) => {
   let widgetMixins: WidgetMixinsInterface;
-  try { widgetMixins = getWidgetMixins(tagName) } // get mixins and template
-  catch (e) {
+  try {
+    widgetMixins = getWidgetMixins(tagName);
+  } catch (e) {
+    // get mixins and template
     console.error(e);
     return;
   }
 
-  const newWidget = { // compose widget
+  const newWidget = {
+    // compose widget
     name: tagName,
     use: [
       ...widgetMixins.mixins,
@@ -93,8 +102,8 @@ function getWidgetMixins(tagName: string): WidgetMixinsInterface {
       ...templateAdditions,
       ...(template.dependencies || []),
       ...callbacks,
-    ]
-  }
+    ],
+  };
 }
 
 // create default widgets
@@ -102,4 +111,4 @@ newWidgetFactory('solid-form-dropdown');
 newWidgetFactory('solid-form-multicheckbox');
 newWidgetFactory('solid-form-file-label');
 newWidgetFactory('solid-action');
-newWidgetFactory('solid-group-default');
\ No newline at end of file
+newWidgetFactory('solid-group-default');
diff --git a/src/new-widgets/templateAdditionMixins/addableMixin.ts b/src/new-widgets/templateAdditionMixins/addableMixin.ts
index 5c396a8ed9d53f83ed0b458133d781991cbdf9e3..fb1c571d23b9a424ee54adc524eb513a6c5b8091 100644
--- a/src/new-widgets/templateAdditionMixins/addableMixin.ts
+++ b/src/new-widgets/templateAdditionMixins/addableMixin.ts
@@ -1,20 +1,32 @@
-import { spread } from '../../libs/lit-helpers';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
+import { spread } from '../../libs/lit-helpers.ts';
 
-import { html } from 'lit-html';
+import { html } from 'lit';
 
 const AddableMixin = {
   name: 'addable-mixin',
   created() {
-    this.listTemplateAdditions.push(this.addableValue.bind(this));
+    this.listTemplateAdditions.attach(
+      this.addableValue.bind(this),
+      'AddableMixin:addableValue',
+    );
   },
   getAddableAttributes() {
-    const addableAttr = (Array.from(this.element.attributes) as Attr[]).filter((a: Attr) => a.name.startsWith('addable-'));
+    const addableAttr = (Array.from(this.element.attributes) as Attr[]).filter(
+      (a: Attr) => a.name.startsWith('addable-'),
+    );
     const cleanAddableAttr: { [key: string]: string } = {};
-    for (let attr of addableAttr) cleanAddableAttr[attr.name.replace('addable-', '')] = attr.value;
-    if (!cleanAddableAttr.hasOwnProperty('data-src')) cleanAddableAttr['data-src'] = this.range;
+    for (const attr of addableAttr)
+      cleanAddableAttr[attr.name.replace('addable-', '')] = attr.value;
+    if (!Object.hasOwn(cleanAddableAttr, 'data-src'))
+      cleanAddableAttr['data-src'] = this.range;
     return cleanAddableAttr;
   },
-  addableValue(template, listTemplateAdditions: Function[], attributes: object) {
+  addableValue(
+    template,
+    listTemplateAdditions: PostProcessorRegistry,
+    attributes: object,
+  ) {
     const addables = this.getAddableAttributes(attributes);
     const newTemplate = html`
       ${template}
@@ -24,9 +36,7 @@ const AddableMixin = {
 
     const nextProcessor = listTemplateAdditions.shift();
     if (nextProcessor) nextProcessor(newTemplate, listTemplateAdditions);
-  }
-}
+  },
+};
 
-export {
-  AddableMixin
-}
\ No newline at end of file
+export { AddableMixin };
diff --git a/src/new-widgets/templateAdditionMixins/index.ts b/src/new-widgets/templateAdditionMixins/index.ts
index ad7207675746851f952d07e5c3e97a632e12fa32..8e874eeee853c914432d9932d2c8d34a1c183c7b 100644
--- a/src/new-widgets/templateAdditionMixins/index.ts
+++ b/src/new-widgets/templateAdditionMixins/index.ts
@@ -1,6 +1,6 @@
-import { LabelMixin } from './labelMixin';
-import { LabelLastMixin } from './labelLastMixin';
-import { AddableMixin } from './addableMixin';
+import { AddableMixin } from './addableMixin.ts';
+import { LabelLastMixin } from './labelLastMixin.ts';
+import { LabelMixin } from './labelMixin.ts';
 
 /**
  * DOM Additions
@@ -9,11 +9,6 @@ const templateAdditionDirectory = {
   label: LabelMixin,
   labellast: LabelLastMixin,
   addable: AddableMixin,
-}
+};
 
-export {
-  templateAdditionDirectory,
-  LabelMixin,
-  LabelLastMixin,
-  AddableMixin,
-}
+export { templateAdditionDirectory, LabelMixin, LabelLastMixin, AddableMixin };
diff --git a/src/new-widgets/templateAdditionMixins/labelLastMixin.ts b/src/new-widgets/templateAdditionMixins/labelLastMixin.ts
index b917a6c5def8609b2c7cd6e31e35857392580b33..aabea616ca3f7d5f34a9b84fb3b77e650c5535a4 100644
--- a/src/new-widgets/templateAdditionMixins/labelLastMixin.ts
+++ b/src/new-widgets/templateAdditionMixins/labelLastMixin.ts
@@ -1,21 +1,20 @@
-import { html } from 'lit-html';
+import { html } from 'lit';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
 
 const LabelLastMixin = {
   name: 'label-last-mixin',
   created() {
-    this.listTemplateAdditions.push(this.addLabelLast.bind(this));
+    this.listTemplateAdditions.attach(
+      this.addLabelLast.bind(this),
+      'LabelLastMixin:addLabelLast',
+    );
   },
-  addLabelLast(template, listTemplateAdditions: Function[]) {
-    const newTemplate = html`
-      ${template}
-      <label>${this.label || this.name}</label>
-    `;
+  addLabelLast(template, listTemplateAdditions: PostProcessorRegistry) {
+    const newTemplate = html`${template}<label>${this.label || this.name}</label>`;
 
     const nextProcessor = listTemplateAdditions.shift();
-    if(nextProcessor) nextProcessor(newTemplate, listTemplateAdditions);
-  }
-}
+    if (nextProcessor) nextProcessor(newTemplate, listTemplateAdditions);
+  },
+};
 
-export {
-  LabelLastMixin
-}
\ No newline at end of file
+export { LabelLastMixin };
diff --git a/src/new-widgets/templateAdditionMixins/labelMixin.ts b/src/new-widgets/templateAdditionMixins/labelMixin.ts
index 7230dd454bdcc6427b6875552e52d297cce8e023..d607425b398b5aed2e03d374fe8bf5092f954a90 100644
--- a/src/new-widgets/templateAdditionMixins/labelMixin.ts
+++ b/src/new-widgets/templateAdditionMixins/labelMixin.ts
@@ -1,23 +1,22 @@
-import { html } from 'lit-html';
-import { uniqID } from '../../libs/helpers';
+import { html } from 'lit';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
+import { uniqID } from '../../libs/helpers.ts';
 
 const LabelMixin = {
   name: 'label-mixin',
   created() {
-    this.listAttributes['id'] = uniqID();    
-    this.listTemplateAdditions.push(this.addLabel.bind(this));
+    this.listAttributes.id = uniqID();
+    this.listTemplateAdditions.attach(
+      this.addLabel.bind(this),
+      'LabelMixin:addLabel',
+    );
   },
-  addLabel(template, listTemplateAdditions: Function[]) {
-    const newTemplate = html`
-      <label for="${this.listAttributes['id']}">${this.label || this.name}</label>
-      ${template}
-    `;
+  addLabel(template, listTemplateAdditions: PostProcessorRegistry) {
+    const newTemplate = html`<label for="${this.listAttributes.id}">${this.label || this.name}</label>${template}`;
 
     const nextProcessor = listTemplateAdditions.shift();
-    if(nextProcessor) nextProcessor(newTemplate, listTemplateAdditions);
-  }
-}
+    if (nextProcessor) nextProcessor(newTemplate, listTemplateAdditions);
+  },
+};
 
-export {
-  LabelMixin
-}
\ No newline at end of file
+export { LabelMixin };
diff --git a/src/new-widgets/templates/defaultTemplatesDirectory.ts b/src/new-widgets/templates/defaultTemplatesDirectory.ts
index 53cd49932724f73edd8c87f28e4ee9b1d0ad5fdc..1bcdbed6db21812f3eef2180d6fb739e95fdbc64 100644
--- a/src/new-widgets/templates/defaultTemplatesDirectory.ts
+++ b/src/new-widgets/templates/defaultTemplatesDirectory.ts
@@ -1,6 +1,6 @@
-import { html } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
-import { LinkTextMixin } from '../templatesDependencies/linkTextMixin';
+import { html } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { LinkTextMixin } from '../templatesDependencies/linkTextMixin.ts';
 
 export const defaultTemplates = {
   action: {
@@ -11,10 +11,10 @@ export const defaultTemplates = {
         id=${ifDefined(attributes.id)}
         link-text=${ifDefined(attributes.linkText)}
       >
-        ${attributes.linkText == null ? (attributes.name || '') : attributes.linkText}
+        ${attributes.linkText == null ? attributes.name || '' : attributes.linkText}
       </solid-link>
     `,
-    dependencies: [LinkTextMixin]
+    dependencies: [LinkTextMixin],
   },
   multiple: {
     template: (value: string, attributes: any) => html`
@@ -25,6 +25,6 @@ export const defaultTemplates = {
         empty-widget=${ifDefined(attributes.emptyWidget)}
       ></solid-display>
     `,
-    dependencies: []
+    dependencies: [],
   },
-}
+};
diff --git a/src/new-widgets/templates/displayTemplatesDirectory.ts b/src/new-widgets/templates/displayTemplatesDirectory.ts
index f815bb592ea1935dd46a06ef68e9e63366f99ff6..3de48ca356e1f0edd62ecb9f6873e7dd5a0f2954 100644
--- a/src/new-widgets/templates/displayTemplatesDirectory.ts
+++ b/src/new-widgets/templates/displayTemplatesDirectory.ts
@@ -1,31 +1,25 @@
-import { EditableMixin } from '../templatesDependencies/editableMixin';
-import { AltMixin } from '../templatesDependencies/altMixin';
-import { LinkTextMixin } from '../templatesDependencies/linkTextMixin';
+import { AltMixin } from '../templatesDependencies/altMixin.ts';
+import { EditableMixin } from '../templatesDependencies/editableMixin.ts';
+import { LinkTextMixin } from '../templatesDependencies/linkTextMixin.ts';
 
-import { html } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
+import { html } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
 
 export const displayTemplates = {
   value: {
     template: (value: string) => html`${value}`,
-    dependencies: []
+    dependencies: [],
   },
   div: {
-    template: (value: string, attributes: any) => html`
-      <div
-        name=${ifDefined(attributes.name)}
-        ?data-editable=${attributes.editable}
-      >
-        ${value}
-      </div>
-    `,
-    dependencies: [ EditableMixin ]
+    template: (value: string, attributes: any) =>
+      html`<div name=${ifDefined(attributes.name)} ?data-editable=${attributes.editable}>${value}</div>`,
+    dependencies: [EditableMixin],
   },
   link: {
     template: (value: string, attributes: any) => html`
       <a
         name=${ifDefined(attributes.name)}
-        href=${(attributes.mailto || attributes.tel || '')+(value || '#')}
+        href=${(attributes.mailto || attributes.tel || '') + (value || '#')}
         target=${ifDefined(attributes.target)}
         ?data-editable=${attributes.editable}
         id=${ifDefined(attributes.id)}
@@ -34,7 +28,7 @@ export const displayTemplates = {
         ${attributes.linkText || value || ''}
       </a>
     `,
-    dependencies: [ EditableMixin,  LinkTextMixin ]
+    dependencies: [EditableMixin, LinkTextMixin],
   },
   img: {
     template: (value: string, attributes: any) => html`
@@ -45,12 +39,11 @@ export const displayTemplates = {
         style="max-width: 100%; max-height: 100%;"
       />
     `,
-    dependencies: [AltMixin]
+    dependencies: [AltMixin],
   },
   boolean: {
-    template: (value: string, attributes: any) => html`
-      ${value === 'true' ? html`<label>${attributes.label || attributes.name || ''}</label>` : ''}
-    `,
-    dependencies: []
+    template: (value: string, attributes: any) =>
+      html`${value === 'true' ? html`<label>${attributes.label || attributes.name || ''}</label>` : ''}`,
+    dependencies: [],
   },
-}
+};
diff --git a/src/new-widgets/templates/formTemplatesDirectory.ts b/src/new-widgets/templates/formTemplatesDirectory.ts
index be8d15e7b5846cfc17951d3cb4b260f63a2165cb..599f389d47ad9a463e8a2c2c85fcc0a8173444e0 100644
--- a/src/new-widgets/templates/formTemplatesDirectory.ts
+++ b/src/new-widgets/templates/formTemplatesDirectory.ts
@@ -1,22 +1,22 @@
-import { FormMixin } from '../templatesDependencies/formMixin';
-import { FormCheckboxMixin } from '../templatesDependencies/formCheckboxMixin';
-import { FormMinMaxMixin } from '../templatesDependencies/formMinMaxMixin';
-import { FormNumberMixin } from '../templatesDependencies/formNumberMixin';
-import { FormDropdownMixin } from '../templatesDependencies/formDropdownMixin';
-import { FormCheckboxesMixin } from '../templatesDependencies/formCheckboxesMixin';
-import { FormRadioMixin } from '../templatesDependencies/formRadioMixin';
-import { FormFileMixin } from '../templatesDependencies/formFileMixin';
-import { MultipleFormMixin } from '../templatesDependencies/multipleFormMixin';
-import { MultipleselectFormMixin } from '../templatesDependencies/multipleselectFormMixin';
-import { RangeMixin } from '../templatesDependencies/rangeMixin';
-import { FilterRangeFormMixin } from '../templatesDependencies/filterRangeFormMixin';
-import { ValueRichtextMixin } from '../templatesDependencies/valueRichtextMixin';
-import { PatternMixin } from '../templatesDependencies/patternMixin';
-import { FormStepMixin } from '../templatesDependencies/formStepMixin';
-import { FormLengthMixin } from '../templatesDependencies/formLengthMixin';
+import { FilterRangeFormMixin } from '../templatesDependencies/filterRangeFormMixin.ts';
+import { FormCheckboxMixin } from '../templatesDependencies/formCheckboxMixin.ts';
+import { FormCheckboxesMixin } from '../templatesDependencies/formCheckboxesMixin.ts';
+import { FormDropdownMixin } from '../templatesDependencies/formDropdownMixin.ts';
+import { FormFileMixin } from '../templatesDependencies/formFileMixin.ts';
+import { FormLengthMixin } from '../templatesDependencies/formLengthMixin.ts';
+import { FormMinMaxMixin } from '../templatesDependencies/formMinMaxMixin.ts';
+import { FormMixin } from '../templatesDependencies/formMixin.ts';
+import { FormNumberMixin } from '../templatesDependencies/formNumberMixin.ts';
+import { FormRadioMixin } from '../templatesDependencies/formRadioMixin.ts';
+import { FormStepMixin } from '../templatesDependencies/formStepMixin.ts';
+import { MultipleFormMixin } from '../templatesDependencies/multipleFormMixin.ts';
+import { MultipleselectFormMixin } from '../templatesDependencies/multipleselectFormMixin.ts';
+import { PatternMixin } from '../templatesDependencies/patternMixin.ts';
+import { RangeMixin } from '../templatesDependencies/rangeMixin.ts';
+import { ValueRichtextMixin } from '../templatesDependencies/valueRichtextMixin.ts';
 
-import { html } from 'lit-html';
-import { ifDefined } from 'lit-html/directives/if-defined';
+import { html } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
 
 export const formTemplates = {
   text: {
@@ -37,7 +37,7 @@ export const formTemplates = {
         @change=${attributes.onChange}
       />
     `,
-    dependencies: [ FormMixin, PatternMixin, FormLengthMixin ]
+    dependencies: [FormMixin, PatternMixin, FormLengthMixin],
   },
   textarea: {
     template: (value: string, attributes: any) => html`
@@ -53,7 +53,7 @@ export const formTemplates = {
         @change=${attributes.onChange}
       >${value}</textarea>
     `,
-    dependencies: [ FormMixin, FormLengthMixin ]
+    dependencies: [FormMixin, FormLengthMixin],
   },
   checkbox: {
     template: (value: string, attributes: any) => html`
@@ -69,7 +69,7 @@ export const formTemplates = {
         <div>${attributes.label || attributes.name}</div>
       </label>
     `,
-    dependencies: [ FormCheckboxMixin, FormMixin ]
+    dependencies: [FormCheckboxMixin, FormMixin],
   },
   date: {
     template: (_value: string, attributes: any) => html`
@@ -84,7 +84,7 @@ export const formTemplates = {
         @change=${attributes.onChange}
       />
     `,
-    dependencies: [ FormMixin ]
+    dependencies: [FormMixin],
   },
   rangedate: {
     template: (_value: string, attributes: any) => html`
@@ -103,7 +103,7 @@ export const formTemplates = {
         value=${ifDefined(attributes.endValue)}
       />
     `,
-    dependencies: [ FilterRangeFormMixin, FormMixin ]
+    dependencies: [FilterRangeFormMixin, FormMixin],
   },
   number: {
     template: (value: string, attributes: any) => html`
@@ -121,7 +121,7 @@ export const formTemplates = {
         @change=${attributes.onChange}
       />
     `,
-    dependencies: [ FormNumberMixin, FormMinMaxMixin, FormMixin, FormStepMixin ]
+    dependencies: [FormNumberMixin, FormMinMaxMixin, FormMixin, FormStepMixin],
   },
   rangenumber: {
     template: (_value: string, attributes: any) => html`
@@ -140,7 +140,7 @@ export const formTemplates = {
         value=${ifDefined(attributes.endValue)}
       />
     `,
-    dependencies: [ FilterRangeFormMixin, FormNumberMixin, FormMixin ]
+    dependencies: [FilterRangeFormMixin, FormNumberMixin, FormMixin],
   },
   hidden: {
     template: (value: string, attributes: any) => html`
@@ -152,7 +152,7 @@ export const formTemplates = {
         @change=${attributes.onChange}
       />
     `,
-    dependencies: [ FormMixin ]
+    dependencies: [FormMixin],
   },
   dropdown: {
     template: (value: string, attributes: any) => html`
@@ -165,37 +165,46 @@ export const formTemplates = {
         autocomplete=${ifDefined(attributes.autocomplete)}
         @change=${attributes.onChange}
       >
-        ${!(attributes.multiple || attributes.autocomplete) ? html`
-        <option value="" ?selected=${value === ""}>
+        ${
+          !(attributes.multiple || attributes.autocomplete)
+            ? html`
+        <option value="" ?selected=${value === ''}>
           ${attributes.placeholder || '-'}
         </option>
-        ` : ''}
-        ${(attributes.range || []).map(el => html`
+        `
+            : ''
+        }
+        ${(attributes.range || []).map(
+          el => html`
           <option
             value=${el.value}
             ?selected=${!attributes.multiple ? value === el.selectedValue : attributes.values.includes(el.selectedValue)}
           >
             ${el.label}
           </option>
-        `)}
-        ${Object.entries(attributes.enum || []).map(([key, val]) => html`
+        `,
+        )}
+        ${Object.entries(attributes.enum || []).map(
+          ([key, val]) => html`
           <option
             value="${key}"
             ?selected=${!attributes.multiple ? value === key : attributes.values.includes(key)}
           >
             ${val}
           </option>
-        `)}
+        `,
+        )}
       </select>
     `,
-    dependencies: [ FormDropdownMixin, FormMixin, RangeMixin ]
+    dependencies: [FormDropdownMixin, FormMixin, RangeMixin],
   },
   radio: {
     template: (value: string, attributes: any) => html`
       <div
         name=${ifDefined(attributes.name)}
       >
-        ${(attributes.range || []).map(el => html`
+        ${(attributes.range || []).map(
+          el => html`
           <label>
             <input
               type="radio"
@@ -205,8 +214,10 @@ export const formTemplates = {
               ?checked=${value === el.selectedValue}
             > <span>${el.label}</span>
           </label>
-        `)}
-        ${Object.entries(attributes.enum || []).map(([key, val]) => html`
+        `,
+        )}
+        ${Object.entries(attributes.enum || []).map(
+          ([key, val]) => html`
           <label>
             <input
               type="radio"
@@ -216,16 +227,18 @@ export const formTemplates = {
               ?checked=${value === key}
             > <span>${val}</span>
           </label>
-        `)}
+        `,
+        )}
     `,
-    dependencies: [ FormRadioMixin, FormMixin, RangeMixin ]
+    dependencies: [FormRadioMixin, FormMixin, RangeMixin],
   },
   multicheckbox: {
     template: (_value: string, attributes: any) => html`
       <div
         name=${ifDefined(attributes.name)}
       >
-        ${(attributes.range || []).map(el => html`
+        ${(attributes.range || []).map(
+          el => html`
           <label>
             <input
               type="checkbox"
@@ -233,18 +246,20 @@ export const formTemplates = {
               ?checked=${attributes.values.includes(el.selectedValue)}
             /> <span>${el.label}</span>
           </label>
-        `)}
-        ${Object.entries(attributes.enum || [])
-          .map(([key, val]) => html`
+        `,
+        )}
+        ${Object.entries(attributes.enum || []).map(
+          ([key, val]) => html`
           <label>
             <input type="checkbox"
               value="${key}"
             /> <span>${val}</span>
           </label>
-        `)}
+        `,
+        )}
       </select>
     `,
-    dependencies: [ FormCheckboxesMixin, FormMixin, RangeMixin ]
+    dependencies: [FormCheckboxesMixin, FormMixin, RangeMixin],
   },
   checkboxes: {
     template: (_value: string, attributes: any) => html`
@@ -261,19 +276,21 @@ export const formTemplates = {
         ?required=${attributes.required}
       ></solid-form-multicheckbox>
     `,
-    dependencies: [ MultipleselectFormMixin, FormMixin, RangeMixin ]
+    dependencies: [MultipleselectFormMixin, FormMixin, RangeMixin],
   },
   multiple: {
     template: (_value: string, attributes: any) => html`
-      ${(attributes.children || []).map((child, index) => html`
+      ${(attributes.children || []).map(
+        (child, index) => html`
         <div data-index=${attributes.name + index}>
           ${child}
           <button type="button" class=${ifDefined(attributes.removeClass)} @click=${() => attributes.removeItem(index)}>${attributes.removeLabel}</button>
         </div>
-      `)}
+      `,
+      )}
       <button type="button" class=${ifDefined(attributes.addClass)} @click=${attributes.addItem}>${attributes.addLabel}</button>
     `,
-    dependencies: [ MultipleFormMixin, FormMixin ]
+    dependencies: [MultipleFormMixin, FormMixin],
   },
   multipleselect: {
     template: (_value: string, attributes: any) => html`
@@ -291,7 +308,7 @@ export const formTemplates = {
         multiple
       ></solid-form-dropdown>
     `,
-    dependencies: [ MultipleselectFormMixin, FormMixin, RangeMixin ]
+    dependencies: [MultipleselectFormMixin, FormMixin, RangeMixin],
   },
   file: {
     template: (value: string, attributes: any) => html`
@@ -303,6 +320,11 @@ export const formTemplates = {
           name=${ifDefined(attributes.name)}
           value=${value || ''}
         >
+        <a
+          href=${value || ''}
+          ?hidden=${value === ''}
+        >${value !== '' ? decodeURI(value.split('/').pop() as string) : ''}</a>
+
         <input
           type="file"
           id=${ifDefined(attributes.id)}
@@ -316,7 +338,7 @@ export const formTemplates = {
         <span>${attributes.output}</span>
       </div>
     `,
-    dependencies: [ FormFileMixin, FormMixin ]
+    dependencies: [FormFileMixin, FormMixin],
   },
   image: {
     template: (value: string, attributes: any) => html`
@@ -346,7 +368,7 @@ export const formTemplates = {
         <span>${attributes.output}</span>
       </div>
     `,
-    dependencies: [ FormFileMixin, FormMixin ]
+    dependencies: [FormFileMixin, FormMixin],
   },
   richtext: {
     template: (_value: string, attributes: any) => html`
@@ -356,7 +378,7 @@ export const formTemplates = {
         data-holder
       ></div>
     `,
-    dependencies: [ ValueRichtextMixin, FormMixin ]
+    dependencies: [ValueRichtextMixin, FormMixin],
   },
   color: {
     template: (_value: string, attributes: any) => html`
@@ -371,7 +393,7 @@ export const formTemplates = {
         @change=${attributes.onChange}
       />
     `,
-    dependencies: [ FormMixin ]
+    dependencies: [FormMixin],
   },
   email: {
     template: (value: string, attributes: any) => html`
@@ -380,7 +402,7 @@ export const formTemplates = {
         placeholder=${ifDefined(attributes.placeholder)}
         id=${ifDefined(attributes.id)}
         name=${ifDefined(attributes.name)}
-        value=${value || ''}
+        value=${value || ''}
         ?required=${attributes.required}
         data-holder
         maxlength=${ifDefined(attributes.maxlength)}
@@ -388,7 +410,7 @@ export const formTemplates = {
         @change=${attributes.onChange}
       />
     `,
-    dependencies: [ FormMixin, FormLengthMixin ]
+    dependencies: [FormMixin, FormLengthMixin],
   },
   password: {
     template: (value: string, attributes: any) => html`
@@ -397,7 +419,7 @@ export const formTemplates = {
         placeholder=${ifDefined(attributes.placeholder)}
         id=${ifDefined(attributes.id)}
         name=${ifDefined(attributes.name)}
-        value=${value || ''}
+        value=${value || ''}
         ?required=${attributes.required}
         pattern=${ifDefined(attributes.pattern)}
         title=${ifDefined(attributes.title)}
@@ -407,7 +429,7 @@ export const formTemplates = {
         @change=${attributes.onChange}
       />
     `,
-    dependencies: [ FormMixin, PatternMixin, FormLengthMixin ]
+    dependencies: [FormMixin, PatternMixin, FormLengthMixin],
   },
   time: {
     template: (value: string, attributes: any) => html`
@@ -425,6 +447,6 @@ export const formTemplates = {
         @change=${attributes.onChange}
       />
     `,
-    dependencies: [ FormMixin, FormMinMaxMixin, FormStepMixin ]
+    dependencies: [FormMixin, FormMinMaxMixin, FormStepMixin],
   },
-}
+};
diff --git a/src/new-widgets/templates/groupTemplatesDirectory.ts b/src/new-widgets/templates/groupTemplatesDirectory.ts
index bb88ebd1a781c1837db7cde5d0de2e6869a3cb2a..77799cb5b76884fa2d7e0f9bfe06158edaacf182 100644
--- a/src/new-widgets/templates/groupTemplatesDirectory.ts
+++ b/src/new-widgets/templates/groupTemplatesDirectory.ts
@@ -1,12 +1,10 @@
-import { html } from 'lit-html';
-import { SetMixin } from '../templatesDependencies/setMixin';
+import { html } from 'lit';
+import { SetMixin } from '../templatesDependencies/setMixin.ts';
 
 export const groupTemplates = {
   default: {
-    template: (value: string) => html`
-      <span>${value}</span>
-      <div data-content></div>
-    `,
-    dependencies: [SetMixin]
+    template: (value: string) =>
+      html`<span>${value}</span><div data-content></div>`,
+    dependencies: [SetMixin],
   },
-}
\ No newline at end of file
+};
diff --git a/src/new-widgets/templates/index.ts b/src/new-widgets/templates/index.ts
index 288fcd3b6b04a02a7f3c057eee48a022d40d7e97..e05514ebc6351d73cdee60aaee6c7225d372b6a4 100644
--- a/src/new-widgets/templates/index.ts
+++ b/src/new-widgets/templates/index.ts
@@ -1,13 +1,13 @@
-import { defaultTemplates } from './defaultTemplatesDirectory';
-import { displayTemplates } from './displayTemplatesDirectory';
-import { formTemplates } from './formTemplatesDirectory';
-import { setTemplates } from './setTemplatesDirectory';
+import { defaultTemplates } from './defaultTemplatesDirectory.ts';
+import { displayTemplates } from './displayTemplatesDirectory.ts';
+import { formTemplates } from './formTemplatesDirectory.ts';
 import { groupTemplates } from './groupTemplatesDirectory.js';
+import { setTemplates } from './setTemplatesDirectory.ts';
 
 export {
   defaultTemplates,
   displayTemplates,
   formTemplates,
   setTemplates,
-  groupTemplates
-}
+  groupTemplates,
+};
diff --git a/src/new-widgets/templates/setTemplatesDirectory.ts b/src/new-widgets/templates/setTemplatesDirectory.ts
index 61ae761b05427c6b21b64999f3691b42613e006b..155b8d8c94e1f2862da497c638dc65cd9e9e917c 100644
--- a/src/new-widgets/templates/setTemplatesDirectory.ts
+++ b/src/new-widgets/templates/setTemplatesDirectory.ts
@@ -1,17 +1,17 @@
-import { html } from 'lit-html';
-import { SetMixin } from '../templatesDependencies/setMixin';
+import { html } from 'lit';
+import { SetMixin } from '../templatesDependencies/setMixin.ts';
 
 export const setTemplates = {
   default: {
     template: () => html``,
-    dependencies: [ SetMixin ]
+    dependencies: [SetMixin],
   },
   div: {
     template: () => html`<div data-content></div>`,
-    dependencies: [ SetMixin ]
+    dependencies: [SetMixin],
   },
   ul: {
     template: () => html`<ul data-content></ul>`,
-    dependencies: [ SetMixin ]
-  }
-}
\ No newline at end of file
+    dependencies: [SetMixin],
+  },
+};
diff --git a/src/new-widgets/templatesDependencies/altMixin.ts b/src/new-widgets/templatesDependencies/altMixin.ts
index 3e517c3ce9f60a4775d7c31fd1d5b09f192e3812..1d0a1821ee8ae82da34793e817cce5216390aafe 100644
--- a/src/new-widgets/templatesDependencies/altMixin.ts
+++ b/src/new-widgets/templatesDependencies/altMixin.ts
@@ -1,15 +1,13 @@
 const AltMixin = {
   name: 'alt-mixin',
-  attributes : {
-    alt : {
+  attributes: {
+    alt: {
       type: String,
       callback: function (newValue: string) {
-        this.addToAttributes(newValue, 'alt')
-      }
+        this.addToAttributes(newValue, 'alt');
+      },
     },
   },
-}
+};
 
-export {
-  AltMixin
-}
\ No newline at end of file
+export { AltMixin };
diff --git a/src/new-widgets/templatesDependencies/editableMixin.ts b/src/new-widgets/templatesDependencies/editableMixin.ts
index 9137d86de8f87428f8b9863920e557631a8f9ff2..1ef096dc17d0a9c54e73541de2a7d21959eb644f 100644
--- a/src/new-widgets/templatesDependencies/editableMixin.ts
+++ b/src/new-widgets/templatesDependencies/editableMixin.ts
@@ -1,37 +1,43 @@
-import { StoreMixin } from '../../mixins/storeMixin';
-import { store } from '../../libs/store/store';
+import { store } from '../../libs/store/store.ts';
+import { StoreMixin } from '../../mixins/storeMixin.ts';
 
-import { html } from 'lit-html';
+import { html } from 'lit';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
 
 const EditableMixin = {
   name: 'editable-mixin',
-  use: [ StoreMixin ], // used to get context
+  use: [StoreMixin], // used to get context
   attributes: {
     editable: {
       type: Boolean,
       default: null,
       callback: function (newValue: boolean) {
-        if (newValue !== null) this.listAttributes['editable'] = true;
-      }
+        if (newValue !== null) this.listAttributes.editable = true;
+      },
     },
     valueId: {
       type: String,
-      default: ''
-    }
+      default: '',
+    },
+    buttonLabel: {
+      type: String,
+      default: 'Modifier',
+    },
   },
   created() {
-    this.listTemplateAdditions.push(this.addEditButton.bind(this));
+    this.listTemplateAdditions.attach(
+      this.addEditButton.bind(this),
+      'EditableMixin:addEditButton',
+    );
   },
-  addEditButton(template, listTemplateAdditions: Function[]) {
+  addEditButton(template, listTemplateAdditions: PostProcessorRegistry) {
     let newTemplate: any = null;
     if (this.editable !== null) {
-      newTemplate = html`
-        ${template}
-        <button @click=${this.activateEditableField.bind(this)}>Modifier</button>
-      `;
+      newTemplate = html`${template}<button @click=${this.activateEditableField.bind(this)}>${this.buttonLabel}</button>`;
     }
     const nextProcessor = listTemplateAdditions.shift();
-    if(nextProcessor) nextProcessor(newTemplate || template, listTemplateAdditions);
+    if (nextProcessor)
+      nextProcessor(newTemplate || template, listTemplateAdditions);
   },
   activateEditableField(e: Event): void {
     const editableField = this.element.querySelector('[data-editable]');
@@ -43,7 +49,9 @@ const EditableMixin = {
     editButton.toggleAttribute('disabled', true);
 
     // Save on focusout
-    editableField.addEventListener('focusout', () => this.save(editableField, editButton));
+    editableField.addEventListener('focusout', () =>
+      this.save(editableField, editButton),
+    );
   },
   save(editableField: HTMLElement, editButton: HTMLElement) {
     editableField.toggleAttribute('contenteditable', false);
@@ -59,8 +67,6 @@ const EditableMixin = {
 
     store.patch(resource, this.valueId);
   },
-}
+};
 
-export {
-  EditableMixin
-}
\ No newline at end of file
+export { EditableMixin };
diff --git a/src/new-widgets/templatesDependencies/filterRangeFormMixin.ts b/src/new-widgets/templatesDependencies/filterRangeFormMixin.ts
index 63c4b8683b83f1fb707d963868a0471dd12ff14d..9d03620ffc3bb0887626166cdf958f27009392b4 100644
--- a/src/new-widgets/templatesDependencies/filterRangeFormMixin.ts
+++ b/src/new-widgets/templatesDependencies/filterRangeFormMixin.ts
@@ -3,36 +3,36 @@ const FilterRangeFormMixin = {
   attributes: {
     startValue: {
       type: String,
-      default:'',
+      default: '',
       callback: function (value: string) {
-        this.addToAttributes(this.getDefaultValue(value), "startValue")
-      }
+        this.addToAttributes(this.getDefaultValue(value), 'startValue');
+      },
     },
     endValue: {
       type: String,
-      default:'',
+      default: '',
       callback: function (value: string) {
-        this.addToAttributes(this.getDefaultValue(value), "endValue")
-      }
-    }
+        this.addToAttributes(this.getDefaultValue(value), 'endValue');
+      },
+    },
   },
   getDefaultValue(value) {
-    if (value == "today") return new Date().toISOString().split("T")[0];
+    if (value === 'today') return new Date().toISOString().split('T')[0];
     return value;
   },
   getValue() {
     if (!this.dataHolder) return [];
-    if (this.dataHolder.length !== 2) this.showDataHolderError(2, this.dataHolder.length);
-    return [ // we expect 2 values, one min and one max
+    if (this.dataHolder.length !== 2)
+      this.showDataHolderError(2, this.dataHolder.length);
+    return [
+      // we expect 2 values, one min and one max
       this.getValueFromElement(this.dataHolder[0]),
-      this.getValueFromElement(this.dataHolder[1])
-    ]
+      this.getValueFromElement(this.dataHolder[1]),
+    ];
   },
   get type() {
     return 'range';
   },
-}
+};
 
-export {
-  FilterRangeFormMixin
-}
\ No newline at end of file
+export { FilterRangeFormMixin };
diff --git a/src/new-widgets/templatesDependencies/formCheckboxMixin.ts b/src/new-widgets/templatesDependencies/formCheckboxMixin.ts
index 0d7d906b91af9fac59c975685ea2ec61f28e84bc..5b6fcb1ae530de26efc95114e4803182b10e39c6 100644
--- a/src/new-widgets/templatesDependencies/formCheckboxMixin.ts
+++ b/src/new-widgets/templatesDependencies/formCheckboxMixin.ts
@@ -6,8 +6,6 @@ const FormCheckboxMixin = {
   get type() {
     return 'boolean';
   },
-}
+};
 
-export {
-  FormCheckboxMixin
-}
\ No newline at end of file
+export { FormCheckboxMixin };
diff --git a/src/new-widgets/templatesDependencies/formCheckboxesMixin.ts b/src/new-widgets/templatesDependencies/formCheckboxesMixin.ts
index 76c8d7e5c02c20d893446e4271d7c65b9a4e569b..cd175681010ddd1343c2bf8b665f1461fc71bc91 100644
--- a/src/new-widgets/templatesDependencies/formCheckboxesMixin.ts
+++ b/src/new-widgets/templatesDependencies/formCheckboxesMixin.ts
@@ -7,38 +7,40 @@ const FormCheckboxesMixin = {
       callback: function (value: string) {
         if (!value) return;
         try {
-          this.listAttributes['values'] = JSON.parse(value);
+          this.listAttributes.values = JSON.parse(value);
         } catch (e) {
           console.error(e);
-          this.listAttributes['values'] = [];
+          this.listAttributes.values = [];
         }
         this.render();
         this.element.dispatchEvent(new Event('change'));
-      }
+      },
     },
   },
   created() {
-    this.listAttributes['values'] = [];
+    this.listAttributes.values = [];
   },
   getValue() {
-    const options = Array.from(this.element.querySelectorAll('input')) as HTMLInputElement[];
+    const options = Array.from(
+      this.element.querySelectorAll('input'),
+    ) as HTMLInputElement[];
     return options
       .filter(el => el.checked)
       .map(el => {
         if (!el.value) return null;
         let value = el.value;
-        try { value = JSON.parse(el.value) } catch (e) { }
+        try {
+          value = JSON.parse(el.value);
+        } catch {}
         return value;
-      })
+      });
   },
   get type() {
-    return  this.enum === ''? 'resource' : 'string';
+    return this.enum === '' ? 'resource' : 'string';
   },
   get multiple() {
     return true;
-  }
-}
+  },
+};
 
-export {
-  FormCheckboxesMixin
-}
\ No newline at end of file
+export { FormCheckboxesMixin };
diff --git a/src/new-widgets/templatesDependencies/formDropdownMixin.ts b/src/new-widgets/templatesDependencies/formDropdownMixin.ts
index a43b70acdd7387f85a4c57e508c7091933e35d4d..e850778b8b2e41a0c6b75b9a256df6d9ccd984c1 100644
--- a/src/new-widgets/templatesDependencies/formDropdownMixin.ts
+++ b/src/new-widgets/templatesDependencies/formDropdownMixin.ts
@@ -1,38 +1,41 @@
 const FormDropdownMixin = {
   name: 'form-dropdown-mixin',
   attributes: {
-    values: { // used to set more than 1 value, for multiple select
+    values: {
+      // used to set more than 1 value, for multiple select
       type: String,
       default: '',
-      callback: function(value) {
+      callback: function (value) {
         if (value) {
           try {
-            this.listAttributes['values'] = JSON.parse(value);
+            this.listAttributes.values = JSON.parse(value);
           } catch (e) {
             console.error(e);
-            this.listAttributes['values'] = [];
+            this.listAttributes.values = [];
           }
           this.render(); // use render to make sure the dispatch always happen after
           this.dispatchChange();
         }
-      }
+      },
     },
     dataId: {
       type: String,
       default: '',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'id');
-      }
+      },
     },
   },
   created() {
-    this.listAttributes['values'] = [];
-    if (this.listAttributes['value'] &&
-      !(JSON.parse(this.listAttributes['value']['@id'])) && Array.isArray(JSON.parse(this.listAttributes['value']))
+    this.listAttributes.values = [];
+    if (
+      this.listAttributes.value &&
+      !JSON.parse(this.listAttributes.value['@id']) &&
+      Array.isArray(JSON.parse(this.listAttributes.value))
     ) {
-      this.listAttributes['values'] = this.listAttributes['value'];
+      this.listAttributes.values = this.listAttributes.value;
     }
-    if (this.multiple) this.listAttributes['multiple'] = true;
+    if (this.multiple) this.listAttributes.multiple = true;
   },
   dispatchChange() {
     if (!this.element.querySelector('select')) return;
@@ -40,23 +43,27 @@ const FormDropdownMixin = {
   },
   getValue() {
     if (!this.dataHolder) return ''; // no value
-    if (!this.multiple) { // simple select
-      if (this.dataHolder.length > 1) this.showDataHolderError(1, this.dataHolder.length);
+    if (!this.multiple) {
+      // simple select
+      if (this.dataHolder.length > 1)
+        this.showDataHolderError(1, this.dataHolder.length);
       return this.getValueFromElement(this.dataHolder[0]);
     }
 
     // multiple select
-    const options = Array.from(this.element.querySelectorAll('option')) as HTMLOptionElement[];
-    return options.filter(el => el.selected).map(el => el.value ? JSON.parse(el.value) : null)
+    const options = Array.from(
+      this.element.querySelectorAll('option'),
+    ) as HTMLOptionElement[];
+    return options
+      .filter(el => el.selected)
+      .map(el => (el.value ? JSON.parse(el.value) : null));
   },
   get type() {
-    return  this.enum === ''? 'resource' : 'string';
+    return this.enum === '' ? 'resource' : 'string';
   },
   get multiple() {
     return this.element.hasAttribute('multiple');
-  }
-}
+  },
+};
 
-export {
-  FormDropdownMixin
-}
\ No newline at end of file
+export { FormDropdownMixin };
diff --git a/src/new-widgets/templatesDependencies/formFileMixin.ts b/src/new-widgets/templatesDependencies/formFileMixin.ts
index 7b594b8ba8cfe00872236fb36e7f8bda64f19768..4699689bf6fda708d0f7b69d3c769610e1e73382 100644
--- a/src/new-widgets/templatesDependencies/formFileMixin.ts
+++ b/src/new-widgets/templatesDependencies/formFileMixin.ts
@@ -1,25 +1,29 @@
-import { store } from "../../libs/store/store";
+import { store } from '../../libs/store/store.ts';
 
 const FormFileMixin = {
   name: 'form-file-mixin',
   attributes: {
     uploadUrl: {
       type: String,
-      default: ''
+      default: '',
     },
   },
   initialState: {
-    initialValue: ''
+    initialValue: '',
   },
   created() {
-    this.listAttributes['output'] = '';
-    this.listAttributes['resetButtonHidden'] = true;
-    this.listAttributes['selectFile'] = this.selectFile.bind(this);
-    this.listAttributes['resetFile'] = this.resetFile.bind(this);
+    this.listAttributes.output = '';
+    this.listAttributes.resetButtonHidden = true;
+    this.listAttributes.selectFile = this.selectFile.bind(this);
+    this.listAttributes.resetFile = this.resetFile.bind(this);
   },
   attached() {
-    this.element.closest('form').addEventListener('reset', this.resetFormFile.bind(this))
-    this.element.closest('solid-form').addEventListener('populate', this.onPopulate.bind(this))
+    this.element
+      .closest('form')
+      .addEventListener('reset', this.resetFormFile.bind(this));
+    this.element
+      .closest('solid-form')
+      .addEventListener('populate', this.onPopulate.bind(this));
   },
   onPopulate() {
     const dataHolder = this.element.querySelector('input[data-holder]');
@@ -28,10 +32,10 @@ const FormFileMixin = {
   },
   resetFormFile(e) {
     if (e.target && (e.target as HTMLElement).contains(this.element)) {
-      if (this.initialValue !== "")  {
+      if (this.initialValue !== '') {
         this.value = this.initialValue;
       }
-      this.listAttributes['resetButtonHidden'] = true;
+      this.listAttributes.resetButtonHidden = true;
       this.planRender();
       const dataHolder = this.element.querySelector('input[data-holder]');
       dataHolder.value = this.value;
@@ -46,23 +50,24 @@ const FormFileMixin = {
     }
 
     const filePicker = this.element.querySelector('input[type="file"]');
-    if (filePicker.files!.length < 1) return;
+    if (filePicker.files?.length === 0) return;
 
     const dataHolder = this.element.querySelector('input[data-holder]');
-    this.listAttributes['output'] = '⏳';
+    this.listAttributes.output = '⏳';
     this.planRender();
 
-    const file = filePicker.files![0];
+    const file = filePicker.files?.[0];
     const formData = new FormData();
     formData.append('file', file);
-    store.fetchAuthn(this.uploadUrl, {
-      method: 'POST',
-      body: formData,
-    })
-      .then(response => this.updateFile(dataHolder, response) )
+    store
+      .fetchAuthn(this.uploadUrl, {
+        method: 'POST',
+        body: formData,
+      })
+      .then(response => this.updateFile(dataHolder, response))
       .catch(error => {
-        this.listAttributes['fileValue'] = '';
-        this.listAttributes['output'] = 'upload error';
+        this.listAttributes.fileValue = '';
+        this.listAttributes.output = 'upload error';
         this.planRender();
         console.error(error);
       });
@@ -71,11 +76,11 @@ const FormFileMixin = {
   updateFile(dataHolder: HTMLInputElement, response: Response) {
     const location = response.headers.get('location');
     if (location == null) {
-      this.listAttributes['output'] = 'header location not found!';
+      this.listAttributes.output = 'header location not found!';
     } else {
       this.value = location;
-      this.listAttributes['output'] = '';
-      this.listAttributes['resetButtonHidden'] = false;
+      this.listAttributes.output = '';
+      this.listAttributes.resetButtonHidden = false;
 
       dataHolder.value = location;
       dataHolder.dispatchEvent(new Event('change'));
@@ -90,18 +95,16 @@ const FormFileMixin = {
     const filePicker = this.element.querySelector('input[type="file"]');
     const dataHolder = this.element.querySelector('input[data-holder]');
 
-    if (filePicker && dataHolder ) {
+    if (filePicker && dataHolder) {
       filePicker.value = dataHolder.value = '';
     }
 
-    this.listAttributes['fileValue'] = '';
-    this.listAttributes['output'] = '';
-    this.listAttributes['resetButtonHidden'] = true;
+    this.listAttributes.fileValue = '';
+    this.listAttributes.output = '';
+    this.listAttributes.resetButtonHidden = true;
     dataHolder.dispatchEvent(new Event('change'));
     this.planRender();
-  }
-}
+  },
+};
 
-export {
-  FormFileMixin
-}
+export { FormFileMixin };
diff --git a/src/new-widgets/templatesDependencies/formLengthMixin.ts b/src/new-widgets/templatesDependencies/formLengthMixin.ts
index 9121410f526da5bc9e6a0dc16145a2cb6a2d3a9c..628796b68033bbd3bd520d45fcfcff0d301cf0fe 100644
--- a/src/new-widgets/templatesDependencies/formLengthMixin.ts
+++ b/src/new-widgets/templatesDependencies/formLengthMixin.ts
@@ -5,17 +5,15 @@ const FormLengthMixin = {
       type: Number,
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'maxlength');
-      }
+      },
     },
     minlength: {
       type: Number,
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'minlength');
-      }
+      },
     },
   },
-}
+};
 
-export {
-  FormLengthMixin
-}
\ No newline at end of file
+export { FormLengthMixin };
diff --git a/src/new-widgets/templatesDependencies/formMinMaxMixin.ts b/src/new-widgets/templatesDependencies/formMinMaxMixin.ts
index f83c8794630d1eb8f7c52a4d412082367b3250ad..fe964c2a11584e61d3fe0c8c20bd87485a356cf2 100644
--- a/src/new-widgets/templatesDependencies/formMinMaxMixin.ts
+++ b/src/new-widgets/templatesDependencies/formMinMaxMixin.ts
@@ -1,21 +1,19 @@
 const FormMinMaxMixin = {
   name: 'form-min-max-mixin',
-  attributes : {
-    min : {
+  attributes: {
+    min: {
       type: Number,
       callback: function (newValue: number) {
         this.addToAttributes(newValue, 'min');
-      }
+      },
     },
-    max : {
+    max: {
       type: Number,
       callback: function (newValue: number) {
         this.addToAttributes(newValue, 'max');
-      }
+      },
     },
-  }
-}
+  },
+};
 
-export {
-  FormMinMaxMixin
-}
\ No newline at end of file
+export { FormMinMaxMixin };
diff --git a/src/new-widgets/templatesDependencies/formMixin.ts b/src/new-widgets/templatesDependencies/formMixin.ts
index 65bbd892b0ce804e00dc4ce04674d1ce8c5c4ea8..5c3dcbb11426dc3b8b5a577e4c82e8062f2f65d6 100644
--- a/src/new-widgets/templatesDependencies/formMixin.ts
+++ b/src/new-widgets/templatesDependencies/formMixin.ts
@@ -5,19 +5,19 @@ const FormMixin = {
       type: Boolean,
       default: false,
       callback: function () {
-        this.listAttributes['required'] = true;
-      }
+        this.listAttributes.required = true;
+      },
     },
     autocomplete: {
       type: String,
       default: '',
-      callback:function (value: string) {
-        this.addToAttributes(value, "autocomplete");
-      }
+      callback: function (value: string) {
+        this.addToAttributes(value, 'autocomplete');
+      },
     },
   },
   attached() {
-    this.listAttributes['onChange'] = this.onChange.bind(this);
+    this.listAttributes.onChange = this.onChange.bind(this);
   },
   onChange(e: Event) {
     e.preventDefault();
@@ -26,7 +26,8 @@ const FormMixin = {
   },
   getValue() {
     if (!this.dataHolder || this.dataHolder.length === 0) return this.value;
-    if (this.dataHolder.length > 1) this.showDataHolderError(1, this.dataHolder.length);
+    if (this.dataHolder.length > 1)
+      this.showDataHolderError(1, this.dataHolder.length);
     return this.getValueFromElement(this.dataHolder[0]);
   },
   get type() {
@@ -36,23 +37,31 @@ const FormMixin = {
     return false;
   },
   get dataHolder(): Element[] | null {
-    const dataHolders = Array.from((this.element as Element).querySelectorAll('[data-holder]'));
+    const dataHolders = Array.from(
+      (this.element as Element).querySelectorAll('[data-holder]'),
+    );
     const widgetDataHolders = dataHolders.filter(element => {
-      const dataHolderAncestor = element.parentElement ? element.parentElement.closest('[data-holder]') : null;
+      const dataHolderAncestor = element.parentElement
+        ? element.parentElement.closest('[data-holder]')
+        : null;
       // get the dataHolder of the widget only if no dataHolder ancestor in the current widget
-      return dataHolderAncestor === this.element || !dataHolderAncestor || !this.element.contains(dataHolderAncestor)
+      return (
+        dataHolderAncestor === this.element ||
+        !dataHolderAncestor ||
+        !this.element.contains(dataHolderAncestor)
+      );
     });
 
-    return widgetDataHolders.length ? widgetDataHolders : null;
+    return widgetDataHolders.length > 0 ? widgetDataHolders : null;
   },
   getValueFromElement(element: any) {
     return element.component ? element.component.getValue() : element.value;
   },
   showDataHolderError(expected: number, found: number) {
-    console.warn(`Expected ${expected} data-holder element in ${this.element.tagName}. Found ${found}`);
-  }
-}
+    console.warn(
+      `Expected ${expected} data-holder element in ${this.element.tagName}. Found ${found}`,
+    );
+  },
+};
 
-export {
-  FormMixin
-}
\ No newline at end of file
+export { FormMixin };
diff --git a/src/new-widgets/templatesDependencies/formNumberMixin.ts b/src/new-widgets/templatesDependencies/formNumberMixin.ts
index b682676712f89377f2ead0b9d656d1c433e6acc3..3949343efa734faff57a9e81c09df9121085d0db 100644
--- a/src/new-widgets/templatesDependencies/formNumberMixin.ts
+++ b/src/new-widgets/templatesDependencies/formNumberMixin.ts
@@ -3,11 +3,9 @@ const FormNumberMixin = {
   getValueFromElement(element: any) {
     return element.value ? Number(element.value) : '';
   },
-  get type () {
-    return 'number'
+  get type() {
+    return 'number';
   },
-}
+};
 
-export {
-  FormNumberMixin
-}
\ No newline at end of file
+export { FormNumberMixin };
diff --git a/src/new-widgets/templatesDependencies/formRadioMixin.ts b/src/new-widgets/templatesDependencies/formRadioMixin.ts
index 29bea1d67580f92d936bf7b4a46af2d212af31b9..d672b80a88a07326926ed68b40b33aa32accfb96 100644
--- a/src/new-widgets/templatesDependencies/formRadioMixin.ts
+++ b/src/new-widgets/templatesDependencies/formRadioMixin.ts
@@ -1,16 +1,16 @@
-import { uniqID } from '../../libs/helpers';
+import { uniqID } from '../../libs/helpers.ts';
 
 const FormRadioMixin = {
   name: 'form-radio-mixin',
   created() {
-    this.listAttributes['id'] = uniqID();
+    this.listAttributes.id = uniqID();
   },
   getValue() {
-    const checkedElement = this.element.querySelector('input[type=radio]:checked') as HTMLInputElement;
+    const checkedElement = this.element.querySelector(
+      'input[type=radio]:checked',
+    ) as HTMLInputElement;
     return checkedElement ? checkedElement.value : '';
   },
-}
+};
 
-export {
-  FormRadioMixin
-}
\ No newline at end of file
+export { FormRadioMixin };
diff --git a/src/new-widgets/templatesDependencies/formStepMixin.ts b/src/new-widgets/templatesDependencies/formStepMixin.ts
index 292d2fc477b0e61694f561f4ec31d19d75d0d962..9ba7f9ea9467edf289fc9dcfd8288917606aaa2b 100644
--- a/src/new-widgets/templatesDependencies/formStepMixin.ts
+++ b/src/new-widgets/templatesDependencies/formStepMixin.ts
@@ -1,15 +1,13 @@
 const FormStepMixin = {
   name: 'form-time-mixin',
-  attributes : {
-    step : {
+  attributes: {
+    step: {
       type: Number,
       callback: function (newValue: number) {
         this.addToAttributes(newValue, 'step');
-      }
+      },
     },
   },
-}
+};
 
-export {
-  FormStepMixin
-}
\ No newline at end of file
+export { FormStepMixin };
diff --git a/src/new-widgets/templatesDependencies/index.ts b/src/new-widgets/templatesDependencies/index.ts
index df477f3057045ab0ad03135a2e8695d5ad4716f5..6f4d7c222559d1a5236e8b5b8e4656ee31aba5eb 100644
--- a/src/new-widgets/templatesDependencies/index.ts
+++ b/src/new-widgets/templatesDependencies/index.ts
@@ -1,47 +1,46 @@
-import { AltMixin } from './altMixin';
-import { EditableMixin } from './editableMixin';
-import { FilterRangeFormMixin } from './filterRangeFormMixin';
-import { FormCheckboxesMixin } from './formCheckboxesMixin';
-import { FormCheckboxMixin } from './formCheckboxMixin';
-import { FormDropdownMixin } from './formDropdownMixin';
-import { FormFileMixin } from './formFileMixin';
-import { FormLengthMixin } from './formLengthMixin';
-import { FormMinMaxMixin } from './formMinMaxMixin';
-import { FormMixin } from './formMixin';
-import { FormNumberMixin } from './formNumberMixin';
-import { FormRadioMixin } from './formRadioMixin';
-import { FormStepMixin } from './formStepMixin';
-import { LinkTextMixin } from './linkTextMixin';
-import { MultipleFormMixin } from './multipleFormMixin';
-import { MultipleselectFormMixin } from './multipleselectFormMixin';
-import { PatternMixin } from './patternMixin';
-import { RangeMixin } from './rangeMixin';
-import { SetMixin } from './setMixin';
-import { ValueRichtextMixin } from './valueRichtextMixin';
-
+import { AltMixin } from './altMixin.ts';
+import { EditableMixin } from './editableMixin.ts';
+import { FilterRangeFormMixin } from './filterRangeFormMixin.ts';
+import { FormCheckboxMixin } from './formCheckboxMixin.ts';
+import { FormCheckboxesMixin } from './formCheckboxesMixin.ts';
+import { FormDropdownMixin } from './formDropdownMixin.ts';
+import { FormFileMixin } from './formFileMixin.ts';
+import { FormLengthMixin } from './formLengthMixin.ts';
+import { FormMinMaxMixin } from './formMinMaxMixin.ts';
+import { FormMixin } from './formMixin.ts';
+import { FormNumberMixin } from './formNumberMixin.ts';
+import { FormRadioMixin } from './formRadioMixin.ts';
+import { FormStepMixin } from './formStepMixin.ts';
+import { LinkTextMixin } from './linkTextMixin.ts';
+import { MultipleFormMixin } from './multipleFormMixin.ts';
+import { MultipleselectFormMixin } from './multipleselectFormMixin.ts';
+import { PatternMixin } from './patternMixin.ts';
+import { RangeMixin } from './rangeMixin.ts';
+import { SetMixin } from './setMixin.ts';
+import { ValueRichtextMixin } from './valueRichtextMixin.ts';
 
 /**
  * Template Depenedices Additions
  */
 export {
-    AltMixin,
-    EditableMixin,
-    FilterRangeFormMixin,
-    FormCheckboxesMixin,
-    FormCheckboxMixin,
-    FormDropdownMixin,
-    FormFileMixin,
-    FormLengthMixin,
-    FormMinMaxMixin,
-    FormMixin,
-    FormNumberMixin,
-    FormRadioMixin,
-    FormStepMixin,
-    LinkTextMixin,
-    MultipleFormMixin,
-    MultipleselectFormMixin,
-    PatternMixin,
-    RangeMixin,
-    SetMixin,
-    ValueRichtextMixin
-}
+  AltMixin,
+  EditableMixin,
+  FilterRangeFormMixin,
+  FormCheckboxesMixin,
+  FormCheckboxMixin,
+  FormDropdownMixin,
+  FormFileMixin,
+  FormLengthMixin,
+  FormMinMaxMixin,
+  FormMixin,
+  FormNumberMixin,
+  FormRadioMixin,
+  FormStepMixin,
+  LinkTextMixin,
+  MultipleFormMixin,
+  MultipleselectFormMixin,
+  PatternMixin,
+  RangeMixin,
+  SetMixin,
+  ValueRichtextMixin,
+};
diff --git a/src/new-widgets/templatesDependencies/linkTextMixin.ts b/src/new-widgets/templatesDependencies/linkTextMixin.ts
index dd8ad35624bd63d8ee1bd33185ad3ec424629645..48bb6150a453195e4d719f5110ad984959bc6546 100644
--- a/src/new-widgets/templatesDependencies/linkTextMixin.ts
+++ b/src/new-widgets/templatesDependencies/linkTextMixin.ts
@@ -6,11 +6,9 @@ const LinkTextMixin = {
       default: '',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'linkText');
-      }
+      },
     },
   },
-}
+};
 
-export {
-  LinkTextMixin
-}
\ No newline at end of file
+export { LinkTextMixin };
diff --git a/src/new-widgets/templatesDependencies/multipleFormMixin.ts b/src/new-widgets/templatesDependencies/multipleFormMixin.ts
index 83e5d27fb135a07deceffe77835523ef84a57b1b..f921743fbb6b2c347c5de65bfd50961b9572092d 100644
--- a/src/new-widgets/templatesDependencies/multipleFormMixin.ts
+++ b/src/new-widgets/templatesDependencies/multipleFormMixin.ts
@@ -1,111 +1,122 @@
-import { StoreMixin } from '../../mixins/storeMixin';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
+import { StoreMixin } from '../../mixins/storeMixin.ts';
 
 const MultipleFormMixin = {
   name: 'multiple-form-mixin',
-  use: [ StoreMixin ],
+  use: [StoreMixin],
   attributes: {
     widget: {
       type: String,
-      default: 'solid-form-text'
+      default: 'solid-form-text',
     },
     addLabel: {
       type: String,
       default: '+',
-      callback: function(value) {
-        if (value !== this.listAttributes['addLabel']) this.listAttributes['addLabel'] = value;
+      callback: function (value) {
+        if (value !== this.listAttributes.addLabel)
+          this.listAttributes.addLabel = value;
         this.planRender();
-      }
+      },
     },
     removeLabel: {
       type: String,
       default: '×',
-      callback: function(value) {
-        if (value !== this.listAttributes['removeLabel']) this.listAttributes['removeLabel'] = value;
+      callback: function (value) {
+        if (value !== this.listAttributes.removeLabel)
+          this.listAttributes.removeLabel = value;
         this.planRender();
-      }
+      },
     },
     range: {
       type: String,
       default: '',
-      
     },
     addClass: {
       type: String,
       default: undefined,
-      callback: function(value) {
-        if (value !== this.listAttributes['addClass']) this.listAttributes['addClass'] = value;
+      callback: function (value) {
+        if (value !== this.listAttributes.addClass)
+          this.listAttributes.addClass = value;
         this.planRender();
-      }
+      },
     },
     removeClass: {
       type: String,
       default: undefined,
-      callback: function(value) {
-        if (value !== this.listAttributes['removeClass']) this.listAttributes['removeClass'] = value;
+      callback: function (value) {
+        if (value !== this.listAttributes.removeClass)
+          this.listAttributes.removeClass = value;
         this.planRender();
-      }
-    }
+      },
+    },
   },
   created() {
-    this.listValueTransformations.push(this.setDataSrc.bind(this));
+    this.listValueTransformations.attach(
+      this.setDataSrc.bind(this),
+      'MultipleFormMixin:setDataSrc',
+    );
 
-    this.listAttributes['children'] = [];
-    this.listAttributes['addLabel'] = this.addLabel;
-    this.listAttributes['removeLabel'] = this.removeLabel;
-    this.listAttributes['addClass'] = this.addClass;
-    this.listAttributes['removeClass'] = this.removeClass;
-    this.listAttributes['addItem'] = () => {
+    this.listAttributes.children = [];
+    this.listAttributes.addLabel = this.addLabel;
+    this.listAttributes.removeLabel = this.removeLabel;
+    this.listAttributes.addClass = this.addClass;
+    this.listAttributes.removeClass = this.removeClass;
+    this.listAttributes.addItem = () => {
       this.insertWidget();
       this.planRender();
     };
-    this.listAttributes['removeItem'] = (index) => {
-      this.element.querySelector(`[data-index="${this.name + index}"]`).remove();
-      this.element.dispatchEvent(new Event('change', {bubbles: true}));
+    this.listAttributes.removeItem = index => {
+      this.element
+        .querySelector(`[data-index="${this.name + index}"]`)
+        .remove();
+      this.element.dispatchEvent(new Event('change', { bubbles: true }));
     };
   },
-  setDataSrc(value: string, listValueTransformations: Function[]) {
+  setDataSrc(value: string, listValueTransformations: PostProcessorRegistry) {
     if (value && value !== this.dataSrc) {
       try {
         if (Array.isArray(JSON.parse(value))) {
           this.setValue(JSON.parse(value));
         }
-      } catch (ex) {
+      } catch {
         //FIXME: Awful trick to handle both resource @ids as value and serialized arrays values
         this.dataSrc = value;
       }
     }
 
     const nextProcessor = listValueTransformations.shift();
-    if(nextProcessor) nextProcessor(value, listValueTransformations);
+    if (nextProcessor) nextProcessor(value, listValueTransformations);
   },
   populate() {
     if (!this.resource || !this.resource['ldp:contains']) return;
 
-    this.listAttributes['children'] = []; // reset list
+    this.listAttributes.children = []; // reset list
 
     // set value in form
-    for (let resource of this.resource['ldp:contains']) { // for each resource
+    for (const resource of this.resource['ldp:contains']) {
+      // for each resource
       this.insertWidget(resource['@id']); // create a widget
     }
     this.planRender();
   },
-  insertWidget(value: string = '') {
+  insertWidget(value = '') {
     if (!this.widget) return;
     const widget = document.createElement(this.widget);
     const attributes = {
       'data-holder': true,
-      'name': this.name,
-      'value': value,
-      'range': this.range
+      name: this.name,
+      value: value,
+      range: this.range,
     };
-    for (let name of Object.keys(attributes)) {
-      if (typeof attributes[name] === "boolean") widget.toggleAttribute(name, attributes[name]);
+    for (const name of Object.keys(attributes)) {
+      if (typeof attributes[name] === 'boolean')
+        widget.toggleAttribute(name, attributes[name]);
       else widget.setAttribute(name, attributes[name]);
     }
-    this.listAttributes['children'].push(widget);
+    this.listAttributes.children.push(widget);
   },
   empty() {
-    this.listAttributes['children'] = [];
+    this.listAttributes.children = [];
     this.planRender();
   },
   getValue() {
@@ -113,7 +124,7 @@ const MultipleFormMixin = {
     // Was returning an array of functions, now returns an array of values.
     // Not sure about the tests results in that context
     return Array.from(this.dataHolder).map((element: any) => {
-      let elValue = this.getValueFromElement(element);
+      const elValue = this.getValueFromElement(element);
       return elValue;
     });
   },
@@ -122,10 +133,7 @@ const MultipleFormMixin = {
   },
   get multiple() {
     return true;
-  }
-
-}
+  },
+};
 
-export {
-  MultipleFormMixin
-}
\ No newline at end of file
+export { MultipleFormMixin };
diff --git a/src/new-widgets/templatesDependencies/multipleselectFormMixin.ts b/src/new-widgets/templatesDependencies/multipleselectFormMixin.ts
index 79f3c6261b789dc963073894c05a697c848cf3fb..dce7ad4a92db859ec68c3d7bb4528c2876658d4f 100644
--- a/src/new-widgets/templatesDependencies/multipleselectFormMixin.ts
+++ b/src/new-widgets/templatesDependencies/multipleselectFormMixin.ts
@@ -1,61 +1,74 @@
-import { StoreMixin } from '../../mixins/storeMixin';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
+import type { Resource } from '../../mixins/interfaces.ts';
+import { StoreMixin } from '../../mixins/storeMixin.ts';
 
 const MultipleselectFormMixin = {
   name: 'multipleselect-form-mixin',
-  use: [ StoreMixin ],
+  use: [StoreMixin],
   attributes: {
-    range: { // range attribute is passed to the solid-dropdown
+    range: {
+      // range attribute is passed to the solid-dropdown
       type: String,
       default: '',
-      callback: function(value) {
-        if (value && value !== this.listAttributes['range']) this.listAttributes['range'] = value;
-      }
+      callback: function (value: string) {
+        if (value && value !== this.listAttributes.range)
+          this.listAttributes.range = value;
+      },
     },
-    enum: { // enum attribute is passed to the solid-dropdown
+    enum: {
+      // enum attribute is passed to the solid-dropdown
       type: String,
       default: '',
-      callback: function (value) {
-        if (value && value !== this.listAttributes['enum']) this.listAttributes['enum'] = value;
-      }
+      callback: function (value: string) {
+        if (value && value !== this.listAttributes.enum)
+          this.listAttributes.enum = value;
+      },
     },
     orderAsc: {
       type: String,
       default: 'name',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'orderAsc');
-      }
+      },
     },
     orderDesc: {
       type: String,
       default: 'name',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'orderDesc');
-      }
-    }
+      },
+    },
   },
   created() {
-    this.listValueTransformations.push(this.setDataSrc.bind(this));
+    this.listValueTransformations.attach(
+      this.setDataSrc.bind(this),
+      'MultipleselectFormMixin:setDataSrc',
+    );
   },
-  setDataSrc(value: string, listValueTransformations: Function[]) {
+  setDataSrc(value: string, listValueTransformations: PostProcessorRegistry) {
     if (value && value !== this.dataSrc) {
       try {
-        let values = JSON.parse(value);
+        const values = JSON.parse(value);
         if (values && Array.isArray(values)) {
           this.setValue(values);
         } else {
           this.setValue([value]);
         }
-      } catch (ex) {
+      } catch {
         this.dataSrc = value;
-        this.setValue([ {"@id": value}]);
+        this.setValue([{ '@id': value }]);
       }
     }
 
     const nextProcessor = listValueTransformations.shift();
-    if(nextProcessor) nextProcessor(value, listValueTransformations);
+    if (nextProcessor) nextProcessor(value, listValueTransformations);
   },
   populate() {
-    if (!this.resource || (!this.resource['ldp:contains'] && !Array.isArray(this.resource))) return;
+    if (
+      !this.resource ||
+      (!this.resource['ldp:contains'] && !Array.isArray(this.resource))
+    )
+      return;
     this.setValue(this.resource['ldp:contains']);
 
     // TODO: Rationalize or clean this commented code
@@ -65,11 +78,12 @@ const MultipleselectFormMixin = {
 
     this.planRender();
   },
-  setValue(values: string[]) { // set the values to the dropdown
-    this.listAttributes['values'] = JSON.stringify(values.map(r => r['@id']));
+  setValue(values: Resource[]) {
+    // set the values to the dropdown
+    this.listAttributes.values = JSON.stringify(values.map(r => r['@id']));
   },
   empty() {
-    this.listAttributes['values'] = [];
+    this.listAttributes.values = [];
     this.planRender();
   },
   get type() {
@@ -78,8 +92,6 @@ const MultipleselectFormMixin = {
   get multiple() {
     return true;
   },
-}
+};
 
-export {
-  MultipleselectFormMixin
-}
\ No newline at end of file
+export { MultipleselectFormMixin };
diff --git a/src/new-widgets/templatesDependencies/patternMixin.ts b/src/new-widgets/templatesDependencies/patternMixin.ts
index b2748ff9b0c147e0369f370ee16c9025fb3139a3..e9f4944f8d9f72ae8cf5f23760a6445fb1824206 100644
--- a/src/new-widgets/templatesDependencies/patternMixin.ts
+++ b/src/new-widgets/templatesDependencies/patternMixin.ts
@@ -1,21 +1,19 @@
 const PatternMixin = {
   name: 'pattern-mixin',
-  attributes : {
-    pattern : {
+  attributes: {
+    pattern: {
       type: String,
       callback: function (newValue: string) {
-        this.addToAttributes(newValue, 'pattern')
-      }
+        this.addToAttributes(newValue, 'pattern');
+      },
     },
-    title : {
+    title: {
       type: String,
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'title');
-      }
+      },
     },
   },
-}
+};
 
-export {
-  PatternMixin
-}
\ No newline at end of file
+export { PatternMixin };
diff --git a/src/new-widgets/templatesDependencies/rangeMixin.ts b/src/new-widgets/templatesDependencies/rangeMixin.ts
index 826765f374669c014f5ddfc070b76e842669f6cc..d7b9a2ab86fa893fe73e3bf3f319ce1709f97497 100644
--- a/src/new-widgets/templatesDependencies/rangeMixin.ts
+++ b/src/new-widgets/templatesDependencies/rangeMixin.ts
@@ -1,92 +1,86 @@
-import { base_context, store } from '../../libs/store/store';
-import { StoreMixin } from '../../mixins/storeMixin';
-import { SorterMixin } from '../../mixins/sorterMixin';
-import { FederationMixin } from '../../mixins/federationMixin';
-import type { Resource } from '../../mixins/interfaces';
+import { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
+import { base_context, store } from '../../libs/store/store.ts';
+import { FederationMixin } from '../../mixins/federationMixin.ts';
+import type { Resource } from '../../mixins/interfaces.ts';
+import { SorterMixin } from '../../mixins/sorterMixin.ts';
+import { StoreMixin } from '../../mixins/storeMixin.ts';
 
 const RangeMixin = {
   name: 'range-mixin',
-  use: [
-    StoreMixin,
-    SorterMixin,
-    FederationMixin
-  ],
+  use: [StoreMixin, SorterMixin, FederationMixin],
   attributes: {
     range: {
       type: String,
       default: '',
       callback: function (value: string) {
         if (value !== this.dataSrc) this.dataSrc = value;
-      }
+      },
     },
     enum: {
       type: String,
       default: '',
       callback: function (value: string) {
         if (value !== null) {
-          const optional = value.trim().split(",");
-          let key;
-          let keyValue;
+          const optional = value.trim().split(',');
           const list = {};
 
-          optional.forEach(element => {
-            if (element.includes("=")) {
-              const option = element.trim().split("=");
-              key = option[1].trim();
-              keyValue = option[0].trim();
+          for (const element of optional) {
+            if (element.includes('=')) {
+              const option = element.trim().split('=');
+              const key = option[1].trim();
+              const keyValue = option[0].trim();
               list[key] = keyValue;
             } else {
               const elem = element.trim();
               list[elem] = elem;
             }
-          });
+          }
           this.addToAttributes(list, 'enum');
-        };
-      }
+        }
+      },
     },
     optionLabel: {
       type: String,
       default: 'name',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'optionLabel');
-      }
+      },
     },
     optionValue: {
       type: String,
       default: '@id',
       callback: function (newValue: string) {
         this.addToAttributes(newValue, 'optionValue');
-      }
-    }
+      },
+    },
   },
   initialState: {
-    listPostProcessors: [],
+    listPostProcessors: new PostProcessorRegistry(),
   },
   created() {
-    this.listPostProcessors = [];
-    this.listAttributes['optionLabel'] = this.optionLabel;
-    this.listAttributes['optionValue'] = this.optionValue;
+    this.listPostProcessors = new PostProcessorRegistry();
+    this.listAttributes.optionLabel = this.optionLabel;
+    this.listAttributes.optionValue = this.optionValue;
   },
   async populate() {
     const resources = this.resource ? this.resource['ldp:contains'] : [];
-    const listPostProcessors = [...this.listPostProcessors];
-    listPostProcessors.push(this.setRangeAttribute.bind(this));
-
-    const nextProcessor = listPostProcessors.shift();
-    await nextProcessor(
-      resources,
-      listPostProcessors,
-      null,
-      this.dataSrc,
+    const listPostProcessorsCopy = this.listPostProcessors.deepCopy();
+    listPostProcessorsCopy.attach(
+      this.setRangeAttribute.bind(this),
+      'RangeMixin:setRangeAttribute',
     );
+
+    const nextProcessor = listPostProcessorsCopy.shift();
+    await nextProcessor(resources, listPostProcessorsCopy, null, this.dataSrc);
   },
-  async setRangeAttribute(
-    resources: Resource[]
-  ) {
+  async setRangeAttribute(resources: Resource[]) {
     if (resources) {
       // process resources to create the template
       const getRangeValue = async (resource: Resource) => {
-        let res = await store.getData(resource['@id'], this.context || base_context);
+        let res = await store.getData(
+          resource['@id'],
+          this.context || base_context,
+        );
         //TODO: handle properly the fact that the res could be null
         if (res === null) {
           res = resource;
@@ -94,32 +88,32 @@ const RangeMixin = {
 
         //TODO: this splitting and expanding is disgusting, please find another solution !!
         const selectedValue = await resource[this.optionValue]; // value used for selected options
-        const value = (this.optionValue.includes('@id') || selectedValue['@id']) ?
-          `{"@id": "${selectedValue}"}` : //  resource
-          selectedValue; // literal
+        const value =
+          this.optionValue.includes('@id') || selectedValue['@id']
+            ? `{"@id": "${selectedValue}"}`
+            : //  resource
+              selectedValue; // literal
 
         //TODO: this splitting and expanding is disgusting, please find another solution !!
-        let labelProperty = this.optionLabel.split(/[.]+/).pop()
+        const labelProperty = this.optionLabel.split(/[.]+/).pop();
         const label = await res[labelProperty]; // label of the option
-        return { value, label, selectedValue }
-      }
+        return { value, label, selectedValue };
+      };
 
-      this.listAttributes['range'] = await Promise.all(
-        resources.filter(el => el !== null).map(r => getRangeValue(r))
+      this.listAttributes.range = await Promise.all(
+        resources.filter(el => el !== null).map(r => getRangeValue(r)),
       );
     }
 
     this.planRender();
   },
   empty() {
-    this.listAttributes['range'] = [];
+    this.listAttributes.range = [];
     this.planRender();
   },
   get type() {
-    return  this.enum === ''? 'resource' : 'string';
-  }
-}
+    return this.enum === '' ? 'resource' : 'string';
+  },
+};
 
-export {
-  RangeMixin
-}
\ No newline at end of file
+export { RangeMixin };
diff --git a/src/new-widgets/templatesDependencies/setMixin.ts b/src/new-widgets/templatesDependencies/setMixin.ts
index 4505df53fc9bff9844c054d8d6838cf1ffc6faee..712472d80f3376cd00a6656bff8ece6e5ab36f1b 100644
--- a/src/new-widgets/templatesDependencies/setMixin.ts
+++ b/src/new-widgets/templatesDependencies/setMixin.ts
@@ -4,9 +4,7 @@ const SetMixin = {
    * For sets and group widgets, remove auto rendering
    * function to allow only manual renders
    */
-  planRender() { },
-}
+  planRender() {},
+};
 
-export {
-  SetMixin
-}
\ No newline at end of file
+export { SetMixin };
diff --git a/src/new-widgets/templatesDependencies/valueRichtextMixin.ts b/src/new-widgets/templatesDependencies/valueRichtextMixin.ts
index 740a12ae62bb865861fb260b5ad98d30e94ebf4e..c1389df40de7e97d4485db2f01d29ed953de302d 100644
--- a/src/new-widgets/templatesDependencies/valueRichtextMixin.ts
+++ b/src/new-widgets/templatesDependencies/valueRichtextMixin.ts
@@ -1,13 +1,11 @@
 import qdtm from 'quill-delta-to-markdown';
 const ValueRichtextMixin = {
   name: 'valuerichtext-mixin',
-  
+
   getValue() {
     const markdown = qdtm.deltaToMarkdown(this.quill.getContents().ops);
     return markdown;
   },
-}
+};
 
-export {
-  ValueRichtextMixin
-}
\ No newline at end of file
+export { ValueRichtextMixin };
diff --git a/src/new-widgets/valueTransformationMixins/autolinkMixin.ts b/src/new-widgets/valueTransformationMixins/autolinkMixin.ts
index 1ffeb16fad862086bc7c2a2afeaf0fcab04c13d5..148d8061ef9afd8b9d8e813e88bc760a393a1152 100644
--- a/src/new-widgets/valueTransformationMixins/autolinkMixin.ts
+++ b/src/new-widgets/valueTransformationMixins/autolinkMixin.ts
@@ -1,16 +1,24 @@
-import {Autolinker} from 'autolinker';
+import { Autolinker } from 'autolinker';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
 
 const AutolinkMixin = {
   name: 'autolink-mixin',
   created() {
-    this.listValueTransformations.push(this.transformValue.bind(this));
+    this.listValueTransformations.attach(
+      this.transformValue.bind(this),
+      'AutolinkMixin:transformValue',
+    );
   },
-  transformValue(value: string, listValueTransformations: Function[]) {
+  transformValue(
+    value: string,
+    listValueTransformations: PostProcessorRegistry,
+  ) {
     const template = document.createElement('template');
-    template.innerHTML =  Autolinker.link(value);
+    template.innerHTML = Autolinker.link(value);
 
     const nextProcessor = listValueTransformations.shift();
-    if (nextProcessor) nextProcessor(template.content, listValueTransformations);
+    if (nextProcessor)
+      nextProcessor(template.content, listValueTransformations);
   },
 };
 
diff --git a/src/new-widgets/valueTransformationMixins/dateMixin.ts b/src/new-widgets/valueTransformationMixins/dateMixin.ts
index 0ac4961c580569fa47bf802adba9aba76e020177..5150b76db0c5c6863c3fb17e1d5d08c3fe7e2ebb 100644
--- a/src/new-widgets/valueTransformationMixins/dateMixin.ts
+++ b/src/new-widgets/valueTransformationMixins/dateMixin.ts
@@ -1,35 +1,41 @@
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
+
 const DateMixin = {
   name: 'date-mixin',
   created() {
-    this.listValueTransformations.push(this.transformValue.bind(this));
+    this.listValueTransformations.attach(
+      this.transformValue.bind(this),
+      'DateMixin:transformValue',
+    );
   },
-  transformValue(value: string, listValueTransformations: Function[]) {
+  transformValue(
+    value: string,
+    listValueTransformations: PostProcessorRegistry,
+  ) {
     try {
       // workaround for giving a specific-formatted value to the form widget
-      this.listAttributes['originalValue'] = this.formatDateForInput(value);
-    } catch (e) {
+      this.listAttributes.originalValue = this.formatDateForInput(value);
+    } catch {
       console.warn('Invalid date format for widget', this.name);
-      this.listAttributes['originalValue'] = '';
+      this.listAttributes.originalValue = '';
     }
     const newValue = value ? new Date(value).toLocaleDateString() : value;
 
     const nextProcessor = listValueTransformations.shift();
-    if(nextProcessor) nextProcessor(newValue, listValueTransformations);
+    if (nextProcessor) nextProcessor(newValue, listValueTransformations);
   },
   formatDateForInput(date: string) {
-    let d = new Date(date);
-    if (isNaN(d.getTime())) throw new Error('Invalid date');
+    const d = new Date(date);
+    if (Number.isNaN(d.getTime())) throw new Error('Invalid date');
     let month = `${d.getMonth() + 1}`;
     let day = `${d.getDate()}`;
-    let year = d.getFullYear();
+    const year = d.getFullYear();
 
     if (month.length < 2) month = `0${month}`;
     if (day.length < 2) day = `0${day}`;
 
     return [year, month, day].join('-');
-  }
-}
+  },
+};
 
-export {
-  DateMixin
-}
\ No newline at end of file
+export { DateMixin };
diff --git a/src/new-widgets/valueTransformationMixins/dateTimeMixin.ts b/src/new-widgets/valueTransformationMixins/dateTimeMixin.ts
index de6872f747ab4f0241eea440a1400e1a893de034..b09c979c7532044a9e6ecea5612313eb433f2675 100644
--- a/src/new-widgets/valueTransformationMixins/dateTimeMixin.ts
+++ b/src/new-widgets/valueTransformationMixins/dateTimeMixin.ts
@@ -1,16 +1,22 @@
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
+
 const DateTimeMixin = {
   name: 'date-time-mixin',
   created() {
-    this.listValueTransformations.push(this.transformValue.bind(this));
+    this.listValueTransformations.attach(
+      this.transformValue.bind(this),
+      'DateTimeMixin:transformValue',
+    );
   },
-  transformValue(value: string, listValueTransformations: Function[]) {
+  transformValue(
+    value: string,
+    listValueTransformations: PostProcessorRegistry,
+  ) {
     const newValue = value ? new Date(value).toLocaleString() : value;
 
     const nextProcessor = listValueTransformations.shift();
-    if(nextProcessor) nextProcessor(newValue, listValueTransformations);
-  }
-}
+    if (nextProcessor) nextProcessor(newValue, listValueTransformations);
+  },
+};
 
-export {
-  DateTimeMixin
-}
\ No newline at end of file
+export { DateTimeMixin };
diff --git a/src/new-widgets/valueTransformationMixins/index.ts b/src/new-widgets/valueTransformationMixins/index.ts
index eeabf92aadde10b133e2073d73d2f34ce96d7413..16dba1dfb3213806fcd55df289329c6464527bf0 100644
--- a/src/new-widgets/valueTransformationMixins/index.ts
+++ b/src/new-widgets/valueTransformationMixins/index.ts
@@ -1,9 +1,9 @@
-import { DateMixin } from './dateMixin';
-import { DateTimeMixin } from './dateTimeMixin';
-import { MultilineMixin } from './multilineMixin';
+import { AutolinkMixin } from './autolinkMixin.ts';
+import { DateMixin } from './dateMixin.ts';
+import { DateTimeMixin } from './dateTimeMixin.ts';
 import { MarkdownMixin } from './markdownMixin.js';
-import { OembedMixin } from './oembedMixin';
-import { AutolinkMixin } from './autolinkMixin';
+import { MultilineMixin } from './multilineMixin.ts';
+import { OembedMixin } from './oembedMixin.ts';
 
 const valueTransformationDirectory = {
   date: DateMixin,
@@ -11,8 +11,8 @@ const valueTransformationDirectory = {
   multiline: MultilineMixin,
   markdown: MarkdownMixin,
   oembed: OembedMixin,
-  autolink: AutolinkMixin
-}
+  autolink: AutolinkMixin,
+};
 
 export {
   valueTransformationDirectory,
@@ -21,5 +21,5 @@ export {
   MultilineMixin,
   MarkdownMixin,
   OembedMixin,
-  AutolinkMixin
-}
+  AutolinkMixin,
+};
diff --git a/src/new-widgets/valueTransformationMixins/markdownMixin.ts b/src/new-widgets/valueTransformationMixins/markdownMixin.ts
index def05d0a6943c219b6397cff456e405e07371145..7b2382b544277a66c3e6d46ab791bf6f3645b4de 100644
--- a/src/new-widgets/valueTransformationMixins/markdownMixin.ts
+++ b/src/new-widgets/valueTransformationMixins/markdownMixin.ts
@@ -1,14 +1,21 @@
-import { unsafeHTML } from 'lit-html/directives/unsafe-html';
+import { unsafeHTML } from 'lit/directives/unsafe-html.js';
 
 import markdownit from 'markdown-it';
 import mila from 'markdown-it-link-attributes';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
 
 const MarkdownMixin = {
   name: 'markdown-mixin',
   created() {
-    this.listValueTransformations.push(this.transformValue.bind(this));
+    this.listValueTransformations.attach(
+      this.transformValue.bind(this),
+      'MarkdownMixin:transformValue',
+    );
   },
-  transformValue(value: string, listValueTransformations: Function[]) {
+  transformValue(
+    value: string,
+    listValueTransformations: PostProcessorRegistry,
+  ) {
     let newValue: any = '';
     if (value) {
       const md = markdownit({
@@ -21,7 +28,7 @@ const MarkdownMixin = {
         attrs: {
           target: '_blank',
           rel: 'noopener',
-        }
+        },
       });
 
       const html = md.render(value);
@@ -29,10 +36,8 @@ const MarkdownMixin = {
     }
 
     const nextProcessor = listValueTransformations.shift();
-    if(nextProcessor) nextProcessor(newValue, listValueTransformations);
-  }
-}
+    if (nextProcessor) nextProcessor(newValue, listValueTransformations);
+  },
+};
 
-export {
-  MarkdownMixin
-}
\ No newline at end of file
+export { MarkdownMixin };
diff --git a/src/new-widgets/valueTransformationMixins/multilineMixin.ts b/src/new-widgets/valueTransformationMixins/multilineMixin.ts
index 6c97b4753a85d9dbbe0f832d67e8286a75034a34..c6cee1fb5e3e396e6b703760abeecfb1e2caaed8 100644
--- a/src/new-widgets/valueTransformationMixins/multilineMixin.ts
+++ b/src/new-widgets/valueTransformationMixins/multilineMixin.ts
@@ -1,18 +1,23 @@
-import { unsafeHTML } from 'lit-html/directives/unsafe-html';
+import { unsafeHTML } from 'lit/directives/unsafe-html.js';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
 
 const MultilineMixin = {
   name: 'multiline-mixin',
   created() {
-    this.listValueTransformations.push(this.transformValue.bind(this));
+    this.listValueTransformations.attach(
+      this.transformValue.bind(this),
+      'MultilineMixin:transformValue',
+    );
   },
-  transformValue(value: string, listValueTransformations: Function[]) {
-    const newValue = value ? unsafeHTML(value.replace(/\n/g, "<br/>")) : value;
+  transformValue(
+    value: string,
+    listValueTransformations: PostProcessorRegistry,
+  ) {
+    const newValue = value ? unsafeHTML(value.replace(/\n/g, '<br/>')) : value;
 
     const nextProcessor = listValueTransformations.shift();
-    if(nextProcessor) nextProcessor(newValue, listValueTransformations);
-  }
-}
+    if (nextProcessor) nextProcessor(newValue, listValueTransformations);
+  },
+};
 
-export {
-  MultilineMixin
-}
\ No newline at end of file
+export { MultilineMixin };
diff --git a/src/new-widgets/valueTransformationMixins/oembedMixin.ts b/src/new-widgets/valueTransformationMixins/oembedMixin.ts
index 8a8c08fc2b3feea9d36d9277cf73d8180e597fb5..27ad92dba0e893682564ad78c6dfe0889694eec4 100644
--- a/src/new-widgets/valueTransformationMixins/oembedMixin.ts
+++ b/src/new-widgets/valueTransformationMixins/oembedMixin.ts
@@ -1,26 +1,31 @@
-import { unsafeHTML } from 'lit-html/directives/unsafe-html';
+import { unsafeHTML } from 'lit/directives/unsafe-html.js';
+import type { PostProcessorRegistry } from '../../libs/PostProcessorRegistry.ts';
 
 const OembedMixin = {
   name: 'oembed-mixin',
-  initialState : {
+  initialState: {
     existingOembed: null,
   },
   created(): void {
-    this.listValueTransformations.push(this.transformValue.bind(this));
+    this.listValueTransformations.attach(
+      this.transformValue.bind(this),
+      'OembedMixin:transformValue',
+    );
   },
-  async transformValue(value: string, listValueTransformations: Function[]) {
+  async transformValue(
+    value: string,
+    listValueTransformations: PostProcessorRegistry,
+  ) {
     if (!value) return;
     if (this.existingOembed == null) {
       const response = await fetch(this.value);
       this.existingOembed = await response.json();
     }
     const newValue = unsafeHTML(this.existingOembed.html);
-      
+
     const nextProcessor = listValueTransformations.shift();
-    if(nextProcessor) nextProcessor(newValue, listValueTransformations);
-  }
-}
+    if (nextProcessor) nextProcessor(newValue, listValueTransformations);
+  },
+};
 
-export {
-  OembedMixin
-}
\ No newline at end of file
+export { OembedMixin };
diff --git a/src/solid-template-element.ts b/src/solid-template-element.ts
index 6130290801a370bf5c3f9aecf4e6896845c35f56..bf9d2560857a15e60a7c41d7cee33004376e4aef 100644
--- a/src/solid-template-element.ts
+++ b/src/solid-template-element.ts
@@ -5,23 +5,22 @@ export default class SolidTemplateElement extends HTMLElement {
   strings = {};
   translationsPath = null;
   translationsFetched = false;
-  props : {[key:string]:any} = {}
+  props: { [key: string]: unknown } = {};
   constructor() {
     super();
     this.initProps();
   }
   static get observedAttributes() {
-    return Object.values(this.propsDefinition);
+    return Object.values(SolidTemplateElement.propsDefinition);
   }
 
-  static get propsDefinition():{[key:string]:any} {
-    return {
-    };
+  static get propsDefinition(): { [key: string]: unknown } {
+    return {};
   }
 
   initProps() {
-    this.props = {}
-    for(let key in this.constructor.propsDefinition) {
+    this.props = {};
+    for (const key in this.constructor.propsDefinition) {
       this.props[key] = undefined;
     }
   }
@@ -30,20 +29,29 @@ export default class SolidTemplateElement extends HTMLElement {
     const declaredAttributes: string[] = [];
 
     // Get props values
-    for(let key in this.constructor.propsDefinition) {
+    for (const key in this.constructor.propsDefinition) {
       const def = this.constructor.propsDefinition[key];
-      if (typeof def === "string") {
-        this.props[key] = this.hasAttribute(def) ? this.getAttribute(def) : undefined;
+      if (typeof def === 'string') {
+        this.props[key] = this.hasAttribute(def)
+          ? this.getAttribute(def)
+          : undefined;
         declaredAttributes.push(def);
-      } else if (typeof def === "object" && def.attribute && typeof def.attribute === "string") {
-        this.props[key] = this.hasAttribute(def.attribute) ? this.getAttribute(def.attribute) : def.default || undefined;
+      } else if (
+        typeof def === 'object' &&
+        def.attribute &&
+        typeof def.attribute === 'string'
+      ) {
+        this.props[key] = this.hasAttribute(def.attribute)
+          ? this.getAttribute(def.attribute)
+          : def.default || undefined;
         declaredAttributes.push(def.attribute);
       }
     }
 
     // Add attributes to props
-    for (let attr of this.attributes) {
-      if (!declaredAttributes.includes(attr.name)) { // if attribute not in propsDefinition
+    for (const attr of this.attributes) {
+      if (!declaredAttributes.includes(attr.name)) {
+        // if attribute not in propsDefinition
         this.props[this._camelize(attr.name)] = attr.value || undefined; // add it to props
       }
     }
@@ -62,19 +70,21 @@ export default class SolidTemplateElement extends HTMLElement {
    */
   async fetchLocaleStrings() {
     if (this.translationsFetched) return;
-    const filesToFetch:any[] = [];
-    if (this.translationsPath) // fetch component translations
+    const filesToFetch: unknown[] = [];
+    if (this.translationsPath)
+      // fetch component translations
       filesToFetch.push(this.fetchTranslationFile(this.translationsPath));
 
     const extraTranslationsPath = this.getAttribute('extra-translations-path');
-    if (extraTranslationsPath) // fetch developer translations
+    if (extraTranslationsPath)
+      // fetch developer translations
       filesToFetch.push(this.fetchTranslationFile(extraTranslationsPath));
 
     // merge all translations
     return Promise.all(filesToFetch).then(res => {
       this.translationsFetched = true;
       this.strings = Object.assign({}, ...res);
-    })
+    });
   }
 
   /**
@@ -84,19 +94,31 @@ export default class SolidTemplateElement extends HTMLElement {
     const ln = this.getLocale();
     const fullPath = `${path}/${ln}.json`;
     return fetch(fullPath)
-      .then((result) => {
+      .then(result => {
         if (result.ok) {
-          return result.json() // parse content
-            .catch(e => console.error(`Error while parsing the translation file: ${fullPath}`));
+          return result
+            .json() // parse content
+            .catch(() =>
+              console.error(
+                `Error while parsing the translation file: ${fullPath}`,
+              ),
+            );
         }
-      }).catch(e => console.error(`Error while retrieving the translation file: ${fullPath}`));
+      })
+      .catch(() =>
+        console.error(
+          `Error while retrieving the translation file: ${fullPath}`,
+        ),
+      );
   }
 
   /**
    * Returns current locale of app
    */
   getLocale() {
-    return localStorage.getItem('language') || window.navigator.language.slice(0, 2);
+    return (
+      localStorage.getItem('language') || window.navigator.language.slice(0, 2)
+    );
   }
 
   /**
@@ -107,8 +129,7 @@ export default class SolidTemplateElement extends HTMLElement {
     return this.strings[key] || key;
   }
 
-  attributeChangedCallback()
-  {
+  attributeChangedCallback() {
     this.updateProps();
     this.planRender();
   }
@@ -131,10 +152,11 @@ export default class SolidTemplateElement extends HTMLElement {
     }
   }
 
-  renderCallback() { }
+  renderCallback() {}
 
   render() {
-    this.fetchLocaleStrings().finally(() => { // render even if some errors occurred
+    this.fetchLocaleStrings().finally(() => {
+      // render even if some errors occurred
       this.innerHTML = this.template(this.props);
       this.renderCallback();
     });
@@ -145,6 +167,6 @@ export default class SolidTemplateElement extends HTMLElement {
   }
 
   _camelize(str) {
-    return str.replace(/\W+(.)/g, (match, chr) => chr.toUpperCase());
+    return str.replace(/\W+(.)/g, (_match, chr) => chr.toUpperCase());
   }
 }
diff --git a/src/solid.d.ts b/src/solid.d.ts
index 78626222dd32568e60ca5eb8be049e0af3010419..fc9ef8f46699264177c4e8e1292eac0d1f18be68 100644
--- a/src/solid.d.ts
+++ b/src/solid.d.ts
@@ -1 +1 @@
-declare var solid: any;
+declare let solid: unknown;
diff --git a/src/store.d.ts b/src/store.d.ts
index 53e696f57a33b7cf0e62f3c32b47ed5b1c7e3ac5..3190a1f81a6666fdffe77ba5deb530317c1e9a81 100644
--- a/src/store.d.ts
+++ b/src/store.d.ts
@@ -1,6 +1,6 @@
-declare var sibStore: any;
+declare let sibStore: import('./libs/store/store').Store;
 
 interface StoreOptions {
-  fetchMethod?: Promise<any>
-  session?: Promise<any>
+  fetchMethod?: Promise<any>;
+  session?: Promise<any>;
 }
diff --git a/src/style/default-theme.css b/src/style/default-theme.css
deleted file mode 100644
index da97c8749d3bd976ff5a7f237ce26fd5648e632d..0000000000000000000000000000000000000000
--- a/src/style/default-theme.css
+++ /dev/null
@@ -1,24 +0,0 @@
-/*==== SOLID-MAP ====*/
-/* map custom marker */
-.sib-custom-marker {
-  position: absolute;
-  top: 40%;
-  left: 50%;
-  margin-left: 115px;
-  border-radius: 50%;
-  border: 8px solid #1c78c9;
-  width: 8px;
-  height: 8px;
-}
-.sib-custom-marker::after {
-  position: absolute;
-  content: '';
-  width: 0px;
-  height: 0px;
-  bottom: -30px;
-  left: -6px;
-  border: 10px solid transparent;
-  border-top-width: 17px;
-  border-top-style: solid;
-  border-top-color: inherit;
-}
\ No newline at end of file
diff --git a/src/widgets/baseWidget.ts b/src/widgets/baseWidget.ts
index 1f0a0c030639b855d12b2c2b073e915426faa1e2..50553b821e68d87ca1d6253ac7ecc7bf6c5cb304 100644
--- a/src/widgets/baseWidget.ts
+++ b/src/widgets/baseWidget.ts
@@ -1,5 +1,5 @@
-import { evalTemplateString } from '../libs/helpers';
-import { store } from '../libs/store/store';
+import { evalTemplateString } from '../libs/helpers.ts';
+import { store } from '../libs/store/store.ts';
 
 export class BaseWidget extends HTMLElement {
   private src: string | undefined;
@@ -16,9 +16,9 @@ export class BaseWidget extends HTMLElement {
     this.render();
   }
   disconnectedCallback(): void {
-    this._subscriptions.forEach((subscription) => {
+    for (const subscription of this._subscriptions.values()) {
       PubSub.unsubscribe(subscription);
-    })
+    }
   }
   async render() {
     this.innerHTML = await evalTemplateString(this.template, {
@@ -27,12 +27,12 @@ export class BaseWidget extends HTMLElement {
       label: this.label,
       placeholder: this.placeholder,
       value: this.value,
-      id: (this._value && this._value['@id']) || '',
+      id: this._value?.['@id'] || '',
       escapedValue: this.escapedValue,
       range: await this.htmlRange,
       multiple: this.multiple,
-      editable: this.editable === '' ? true : false,
-      required: this.required === '' ? true : false
+      editable: this.editable === '',
+      required: this.required === '',
     });
 
     this.addEditButtons();
@@ -42,27 +42,30 @@ export class BaseWidget extends HTMLElement {
     return this.hasAttribute('label') ? this.getAttribute('label') : this.name;
   }
   set label(label: string | null) {
-    if(label != null) this.setAttribute('label', label);
+    if (label != null) this.setAttribute('label', label);
     this.render();
   }
   get placeholder(): string | null {
-    return this.hasAttribute('placeholder') ? this.getAttribute('placeholder') : this.label;
+    return this.hasAttribute('placeholder')
+      ? this.getAttribute('placeholder')
+      : this.label;
   }
   set placeholder(placeholder: string | null) {
-    if(placeholder != null) this.setAttribute('placeholder', placeholder);
+    if (placeholder != null) this.setAttribute('placeholder', placeholder);
     this.render();
   }
   get name(): string | null {
     return this.getAttribute('name');
   }
   set name(name: string | null) {
-    if(name) this.setAttribute('name', name);
+    if (name) this.setAttribute('name', name);
     this.render();
   }
   get value() {
     if (this.dataHolder) {
-      let values = this.dataHolder.map(element => {
-        if (element instanceof HTMLInputElement && element.type == "checkbox") return element.checked;
+      const values = this.dataHolder.map(element => {
+        if (element instanceof HTMLInputElement && element.type === 'checkbox')
+          return element.checked;
         // if value is defined, push it in the array
         return this.getValueHolder(element).value;
       });
@@ -73,12 +76,12 @@ export class BaseWidget extends HTMLElement {
   }
   set value(value) {
     this._value = value; // ... store `value` in the widget
-    if (this._value == null || this._value == undefined) return;
+    if (this._value == null) return;
 
     if (this.dataHolder && this.dataHolder.length === 1) {
       // if one dataHolder in the widget...
       const element = this.getValueHolder(this.dataHolder[0]);
-      if (element.type == "checkbox") {
+      if (element.type === 'checkbox') {
         element.checked = value;
       } else {
         element.value = value; // ... set `value` to the dataHolder element
@@ -87,41 +90,47 @@ export class BaseWidget extends HTMLElement {
       if (element.dispatchEvent) element.dispatchEvent(new Event('change')); // trigger change manually
     } else if (this.dataHolder && this.dataHolder.length > 1) {
       // if multiple dataHolder in the widget ...
-      this.dataHolder.forEach(
-        (el, index) => {
-          const element = this.getValueHolder(el);
-          if (element.type == "checkbox") {
-            element.checked = value ? value[index] : ''
-          } else {
-            element.value = value ? value[index] : ''
-          }
-          element.dispatchEvent(new Event('change')); // trigger change manually
-        },
-      ); // ... set each `value` to each dataHolder element
+      this.dataHolder.forEach((el, index) => {
+        const element = this.getValueHolder(el);
+        if (element.type === 'checkbox') {
+          element.checked = value ? value[index] : '';
+        } else {
+          element.value = value ? value[index] : '';
+        }
+        element.dispatchEvent(new Event('change')); // trigger change manually
+      }); // ... set each `value` to each dataHolder element
     }
 
     this.render();
   }
-  get ['each-label'](): string{
+  get 'each-label'(): string {
     return this.getAttribute('each-label') || '';
   }
-  set ['each-label'](label: string) {
+  set 'each-label'(label: string) {
     this.setAttribute('each-label', label);
   }
-  set ['add-label'](label: string) {
+  set 'add-label'(label: string) {
     this.setAttribute('add-label', label);
   }
-  set ['remove-label'](label: string) {
+  set 'remove-label'(label: string) {
     this.setAttribute('remove-label', label);
   }
   get dataHolder(): Element[] | null {
-    const widgetDataHolders = Array.from(this.querySelectorAll('[data-holder]')).filter(element => {
-      const dataHolderAncestor = element.parentElement ? element.parentElement.closest('[data-holder]') : null;
+    const widgetDataHolders = Array.from(
+      this.querySelectorAll('[data-holder]'),
+    ).filter(element => {
+      const dataHolderAncestor = element.parentElement
+        ? element.parentElement.closest('[data-holder]')
+        : null;
       // get the dataHolder of the widget only if no dataHolder ancestor in the current widget
-      return dataHolderAncestor === this || !dataHolderAncestor || !this.contains(dataHolderAncestor)
+      return (
+        dataHolderAncestor === this ||
+        !dataHolderAncestor ||
+        !this.contains(dataHolderAncestor)
+      );
     });
 
-    return widgetDataHolders.length ? widgetDataHolders : null;
+    return widgetDataHolders.length > 0 ? widgetDataHolders : null;
   }
   get template(): string {
     return '';
@@ -130,7 +139,7 @@ export class BaseWidget extends HTMLElement {
     return '';
   }
   get escapedValue(): string {
-    return ('' + this.value)
+    return `${this.value}`
       .replace(/&/g, '&amp;')
       .replace(/'/g, '&apos;')
       .replace(/"/g, '&quot;');
@@ -147,26 +156,36 @@ export class BaseWidget extends HTMLElement {
   }
   set range(range) {
     (async () => {
-      this._listen(range, async () => this._range = await store.getData(range, this.context));
+      this._listen(range, async () => {
+        this._range = await store.getData(range, this.context);
+      });
       this._range = await store.getData(range, this.context);
       this.render();
     })();
   }
   async fetchSources(resource: any) {
     if (!resource || !resource['ldp:contains']) return null;
-    let resources: any[] = [];
+    const resources: any[] = [];
     let index = 0;
     for (let res of resource['ldp:contains']) {
-      if (!res) { // child not in cache yet
+      if (!res) {
+        // child not in cache yet
         try {
           const resourceId = resource.getChildren('ldp:contains')[index]['@id'];
-          res = await store.getData(resourceId, this.context)
-        } catch (e) { continue; }
+          res = await store.getData(resourceId, this.context);
+        } catch {
+          continue;
+        }
       }
-      if (res.isContainer?.()) { // if nested container
-        let resourcesFromContainer = await store.getData(res['@id'], this.context); // fetch the datas
+      if (res.isContainer?.()) {
+        // if nested container
+        const resourcesFromContainer = await store.getData(
+          res['@id'],
+          this.context,
+        ); // fetch the datas
         this._listen(res['@id']);
-        if (resourcesFromContainer) resources.push(...resourcesFromContainer['ldp:contains']);
+        if (resourcesFromContainer)
+          resources.push(...resourcesFromContainer['ldp:contains']);
       } else {
         resources.push(res);
       }
@@ -175,35 +194,35 @@ export class BaseWidget extends HTMLElement {
     return resources;
   }
 
-  get htmlRange(): Promise<string | undefined> {
-    return (async () => {
-      let htmlRange = '';
-      const rangeResources = await this.range;
-      if (!rangeResources) return;
-      for await (let element of rangeResources) {
-        element = await store.getData(element['@id'], this.context); // fetch the resource to display the name
-        this._listen(element['@id']);
+  async htmlRange(): Promise<string | undefined> {
+    let htmlRange = '';
+    const rangeResources = await this.range;
+    if (!rangeResources) return;
+    for await (let element of rangeResources) {
+      element = await store.getData(element['@id'], this.context); // fetch the resource to display the name
+      this._listen(element['@id']);
 
-        let selected: boolean;
-        if (this._value && this._value.isContainer && this._value.isContainer()) { // selected options for multiple select
-          selected = false;
-          for await (let value of this._value["ldp:contains"]) {
-            if (value['@id'] == element['@id']) {
-              selected = true;
-              break;
-            }
+      let selected: boolean;
+      if (this._value?.isContainer?.()) {
+        // selected options for multiple select
+        selected = false;
+        for await (const value of this._value['ldp:contains']) {
+          if (value['@id'] === element['@id']) {
+            selected = true;
+            break;
           }
-        } else { // selected options for simple dropdowns
-          selected = this._value ? this._value['@id'] == element['@id'] : false;
         }
-        htmlRange += await evalTemplateString(this.childTemplate, {
-          name: await element.name,
-          id: element['@id'],
-          selected: selected
-        });
+      } else {
+        // selected options for simple dropdowns
+        selected = this._value ? this._value['@id'] === element['@id'] : false;
       }
-      return htmlRange || '';
-    })();
+      htmlRange += await evalTemplateString(this.childTemplate, {
+        name: await element.name,
+        id: element['@id'],
+        selected: selected,
+      });
+    }
+    return htmlRange || '';
   }
   getValueHolder(element) {
     return element.component ? element.component : element;
@@ -215,10 +234,13 @@ export class BaseWidget extends HTMLElement {
 
   _listen(id: string, callback: Function = () => {}) {
     if (!this._subscriptions.get(id)) {
-      this._subscriptions.set(id, PubSub.subscribe(id, async () => {
-        await callback();
-        this.render();
-      }))
+      this._subscriptions.set(
+        id,
+        PubSub.subscribe(id, async () => {
+          await callback();
+          this.render();
+        }),
+      );
     }
   }
 
@@ -229,18 +251,24 @@ export class BaseWidget extends HTMLElement {
     if (editableField) {
       // Add edit button
       const editButton = document.createElement('button');
-      editButton.innerText = "Modifier";
-      editButton.onclick = () => this.activateEditableField(editableField, editButton);
+      editButton.innerText = 'Modifier';
+      editButton.onclick = () =>
+        this.activateEditableField(editableField, editButton);
       editableField.insertAdjacentElement('afterend', editButton);
 
       // Save on focusout
-      editableField.addEventListener('focusout', () => this.save(editableField, editButton));
+      editableField.addEventListener('focusout', () =>
+        this.save(editableField, editButton),
+      );
     }
   }
-  activateEditableField(editableField: HTMLElement, editButton: HTMLButtonElement): void {
+  activateEditableField(
+    editableField: HTMLElement,
+    editButton: HTMLButtonElement,
+  ): void {
     editableField.setAttribute('contenteditable', 'true');
     editableField.focus();
-    editButton.setAttribute("disabled", "disabled");
+    editButton.setAttribute('disabled', 'disabled');
   }
   /**
    * Dispatch change events of data holders from the current widget
@@ -248,24 +276,24 @@ export class BaseWidget extends HTMLElement {
   initChangeEvents(): void {
     if (this.dataHolder) {
       const event = new Event('change', { bubbles: true });
-      this.dataHolder.forEach(element => {
+      for (const element of this.dataHolder) {
         element.addEventListener('change', e => {
           e.preventDefault();
           e.stopPropagation();
           this.dispatchEvent(event);
         });
-      });
+      }
     }
   }
   save(editableField: HTMLElement, editButton: HTMLButtonElement): void {
     editableField.setAttribute('contenteditable', 'false');
-    editButton.removeAttribute("disabled");
+    editButton.removeAttribute('disabled');
 
     if (!this.name) return;
     const resource = {};
     resource[this.name] = editableField.innerText;
     resource['@context'] = this.context;
 
-    if(this.resourceId && resource) store.patch(resource, this.resourceId)
+    if (this.resourceId && resource) store.patch(resource, this.resourceId);
   }
 }
diff --git a/src/widgets/widget-factory.ts b/src/widgets/widget-factory.ts
index 01e4acc9264f2921d2c9c0d475013ae712627ff7..718433ee491dd78e6a4c0ca09262767de719ee4b 100644
--- a/src/widgets/widget-factory.ts
+++ b/src/widgets/widget-factory.ts
@@ -1,23 +1,23 @@
-import { BaseWidget } from './baseWidget';
-import { defineComponent } from '../libs/helpers';
+import { defineComponent } from '../libs/helpers.ts';
+import { BaseWidget } from './baseWidget.ts';
 
 export const widgetFactory = (
   tagName: string,
   customTemplate: string,
-  childTemplate: string = '',
+  childTemplate = '',
   callback?: (element: Element) => void,
 ) => {
   const registered = customElements.get(tagName);
   if (registered) return registered;
   const cls = class extends BaseWidget {
-    async render() {
+    override async render() {
       await super.render();
       if (callback) callback(this);
     }
-    get template(): string {
+    override get template(): string {
       return customTemplate;
     }
-    get childTemplate(): string {
+    override get childTemplate(): string {
       return childTemplate;
     }
   };
diff --git a/src/window.d.ts b/src/window.d.ts
index cbc4eb286e5ef6837aa447655c6b07e574612db2..3f370e97ef659af2faf1ef4372ae33be08e31cde 100644
--- a/src/window.d.ts
+++ b/src/window.d.ts
@@ -1,9 +1,11 @@
-declare var PubSub: any;
-declare var markdownit: any;
-declare var fetchTranslationPromise: Promise;
-declare var cachePropsSearchFilter: {
-  [key: string]: {
-    setFields: string[] | null
-    setSearchFields: string[] | null
+export declare global {
+  interface Window {
+    fetchTranslationPromise: Promise;
+    cachePropsSearchFilter: {
+      [key: string]: {
+        setFields: string[] | null;
+        setSearchFields: string[] | null;
+      };
+    };
   }
-};
+}
diff --git a/tsconfig.json b/tsconfig.json
index 645ec74062d534af6d1c7214eca4859a5c5e1a49..6d6b34a6ca8eb02d62bd2df6e0302d2a586271c9 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,26 +1,24 @@
 {
   "compilerOptions": {
-    "target": "es2018",
+    "target": "es2022",
     "module": "ESNext",
-    "moduleResolution": "node",
+    "moduleResolution": "Bundler",
+    "isolatedModules": true,
+    "moduleDetection": "force",
     "allowJs": true,
-    "jsx": "preserve",
     "noEmit": true,
-    "declaration": false,
-    "declarationMap": false,
+    "allowImportingTsExtensions": true,
     "esModuleInterop": true,
     "composite": false,
     "strict": true,
     "noImplicitAny": false,
-    "strictNullChecks": true,
-    "strictFunctionTypes": true,
-    "strictPropertyInitialization": true,
     "noImplicitThis": false,
-    "alwaysStrict": true,
+    "noImplicitOverride": true,
     "noUnusedLocals": true,
     "noUnusedParameters": true,
     "noImplicitReturns": true,
     "noFallthroughCasesInSwitch": true,
+    "verbatimModuleSyntax": true,
     "resolveJsonModule": true,
     "baseUrl": "./",
     "paths": {
@@ -29,6 +27,5 @@
     "skipLibCheck": true,
     "types": ["cypress"]
   },
-  "include": ["./src/**/*", "./cypress/**/*"],
-  "exclude": ["./node_modules/", "./cypress.config.ts"]
+  "include": ["./src/**/*", "./cypress/**/*"]
 }
diff --git a/vite.config.ts b/vite.config.ts
index 3447be027372b75e74f68bfbf0f5d517747aeb67..d6bb5745e9d1a3b2519e73551a0aa9248b1c3ba0 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,4 +1,4 @@
-import { resolve } from 'path';
+import { resolve } from 'node:path';
 import { defineConfig } from 'vite';
 
 export default defineConfig({
@@ -12,10 +12,7 @@ export default defineConfig({
     },
     rollupOptions: {
       preserveEntrySignatures: 'strict',
-      input: [
-        './src/index.ts',
-        './src/libs/helpers.ts',
-      ],
+      input: ['./src/index.ts', './src/libs/helpers.ts'],
       output: {
         dir: 'dist',
         entryFileNames: '[name].js',
@@ -23,5 +20,6 @@ export default defineConfig({
     },
     outDir: 'dist',
     minify: false,
+    reportCompressedSize: false,
   },
 });