diff --git a/.gitignore b/.gitignore
index 59338092c39143201cbd8a4861ad2333d073cb6a..85fd6cd2f0bc12505ffe5d05e0ea2ffda583b0a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
 node_modules
-demo/dist
+toolkit-showcase/dist
 .idea
 yarn-error.log
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1e53802cf015a62aac49125751b618890e1c74d7..29402570ca77777b8bc61a72a3ad3f89732cbfa0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,7 +7,7 @@ cache:
 
 stages:
   - test
-  - publish
+  - deploy
 
 test:
   stage: test
@@ -16,11 +16,19 @@ test:
     - yarn install
     - yarn run test
 
+linting:
+  stage: test
+  allow_failure: true
+  script:
+    - yarn config set cache-folder "$CI_PROJECT_DIR/_yarn_cache"
+    - yarn install
+    - yarn run lint
+
 publish:
-  stage: publish
+  stage: deploy
   only:
     refs:
-      - publish
+      - deploy
       - master
   script:
     # https://www.npmjs.com/settings/dbp-deploy/tokens
@@ -31,3 +39,45 @@ publish:
     - yarn install
     - yarn run build
     - yarn run publish
+
+.deploy_defaults: &deploy_defaults
+  except:
+    - schedules
+  stage: deploy
+  script:
+    # Add ssh key
+    - mkdir -p ~/.ssh
+    - echo "${DEPLOY_KEY}" | tr -d '\r' > ~/.ssh/id_rsa
+    - chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_rsa
+    - ssh-keyscan -t rsa "${DEPLOY_HOST}" >> ~/.ssh/known_hosts
+    # Deploy
+    - cd toolkit-showcase
+    - dep deploy "${CI_ENVIRONMENT_NAME}"
+    - echo "Deployed to ${CI_ENVIRONMENT_URL}"
+    # Simple health check
+    - curl --max-time 10 --retry 3 --output /dev/null --silent --show-error --fail --location "${CI_ENVIRONMENT_URL}"
+
+deploy_demo:
+  only:
+    refs:
+      - demo
+  environment:
+    name: demo
+    url: https://frontend-demo.tugraz.at/apps/demo
+  variables:
+    DEPLOY_HOST: mw01-dev.tugraz.at
+    DEPLOY_KEY: "$DEPLOY_SSH_KEY"
+  <<: *deploy_defaults
+
+deploy_development:
+  only:
+    refs:
+      - master
+  environment:
+    name: development
+    url: https://mw-frontend-dev.tugraz.at/apps/demo
+  variables:
+    DEPLOY_HOST: mw01-dev.tugraz.at
+    DEPLOY_KEY: "$DEPLOY_SSH_KEY"
+  <<: *deploy_defaults
+
diff --git a/eslint.common.json b/eslint.common.json
new file mode 100644
index 0000000000000000000000000000000000000000..d19714d1a49e1c8f1e83cd9d7fef0d3e3f9d9bf1
--- /dev/null
+++ b/eslint.common.json
@@ -0,0 +1,26 @@
+{
+    "env": {
+        "browser": true,
+        "es6": true,
+        "mocha": true
+    },
+    "extends": ["eslint:recommended", "plugin:jsdoc/recommended"],
+    "globals": {
+        "Atomics": "readonly",
+        "SharedArrayBuffer": "readonly"
+    },
+    "parser": "babel-eslint",
+    "parserOptions": {
+        "ecmaVersion": 2018,
+        "sourceType": "module"
+    },
+    "rules": {
+        "no-unused-vars": ["error", { "args": "none" }],
+        "semi": [2, "always"],
+        "jsdoc/require-jsdoc": 0,
+        "jsdoc/require-param-description": 0,
+        "jsdoc/require-returns": 0,
+        "jsdoc/require-param-type": 0,
+        "jsdoc/require-returns-description": 0
+    }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 45f7a0360f25116d1ee38dee3e0784eec37187b6..ce4dbed6ee0fef89956d1d45385f3b3b6e86c138 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
   "scripts": {
     "test": "lerna run test",
     "build": "lerna run build",
+    "lint": "lerna run lint",
     "publish": "lerna publish from-package --yes"
   },
   "author": "",
diff --git a/packages/app-shell/.eslintrc.json b/packages/app-shell/.eslintrc.json
index 1ccd30a3fee0b4867a0172e746714eb0083fb07d..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f 100644
--- a/packages/app-shell/.eslintrc.json
+++ b/packages/app-shell/.eslintrc.json
@@ -1,25 +1,3 @@
 {
-    "env": {
-        "browser": true,
-        "es6": true,
-        "mocha": true
-    },
-    "extends": ["eslint:recommended", "plugin:jsdoc/recommended"],
-    "globals": {
-        "Atomics": "readonly",
-        "SharedArrayBuffer": "readonly"
-    },
-    "parser": "babel-eslint",
-    "parserOptions": {
-        "ecmaVersion": 2018,
-        "sourceType": "module"
-    },
-    "rules": {
-        "no-unused-vars": ["error", { "args": "none" }],
-        "semi": [2, "always"],
-        "jsdoc/require-jsdoc": 0,
-        "jsdoc/require-param-description": 0,
-        "jsdoc/require-returns": 0,
-        "jsdoc/require-param-type": 0
-    }
+    "extends": "./../../eslint.common.json"
 }
\ No newline at end of file
diff --git a/packages/app-shell/package.json b/packages/app-shell/package.json
index 8cfef7a46774129c1b01076f836f597f6522d31b..14154fa96162e6786d5836f7188ceb27205d8683 100644
--- a/packages/app-shell/package.json
+++ b/packages/app-shell/package.json
@@ -1,9 +1,14 @@
 {
   "name": "@dbp-toolkit/app-shell",
   "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/app-shell",
-  "version": "0.1.4",
+  "version": "0.1.5",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/app-shell"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
diff --git a/packages/auth/.eslintrc.json b/packages/auth/.eslintrc.json
index 1ccd30a3fee0b4867a0172e746714eb0083fb07d..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f 100644
--- a/packages/auth/.eslintrc.json
+++ b/packages/auth/.eslintrc.json
@@ -1,25 +1,3 @@
 {
-    "env": {
-        "browser": true,
-        "es6": true,
-        "mocha": true
-    },
-    "extends": ["eslint:recommended", "plugin:jsdoc/recommended"],
-    "globals": {
-        "Atomics": "readonly",
-        "SharedArrayBuffer": "readonly"
-    },
-    "parser": "babel-eslint",
-    "parserOptions": {
-        "ecmaVersion": 2018,
-        "sourceType": "module"
-    },
-    "rules": {
-        "no-unused-vars": ["error", { "args": "none" }],
-        "semi": [2, "always"],
-        "jsdoc/require-jsdoc": 0,
-        "jsdoc/require-param-description": 0,
-        "jsdoc/require-returns": 0,
-        "jsdoc/require-param-type": 0
-    }
+    "extends": "./../../eslint.common.json"
 }
\ No newline at end of file
diff --git a/packages/auth/package.json b/packages/auth/package.json
index c6e37231a50fcb5823b85d5ae5d93a113e1d602a..bbff974585492dea0e89b96e1c26db284b2bcf5c 100644
--- a/packages/auth/package.json
+++ b/packages/auth/package.json
@@ -1,9 +1,14 @@
 {
   "name": "@dbp-toolkit/auth",
   "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/auth",
-  "version": "0.1.3",
+  "version": "0.1.4",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/auth"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
diff --git a/packages/auth/src/login-button.js b/packages/auth/src/login-button.js
index ad6ea09fe2f0678c493e22a8c1f1a272908117d3..435916e4ee5478e3da90863987a98d666ac8e734 100644
--- a/packages/auth/src/login-button.js
+++ b/packages/auth/src/login-button.js
@@ -52,6 +52,17 @@ let loginSVG = `
 </svg>
 `;
 
+let loggingInSVG = `
+<svg
+   viewBox="0 0 100 100"
+   y="0px"
+   x="0px"
+   id="icon"
+   role="img"
+   version="1.1">
+</svg>
+`;
+
 export class LoginButton extends ScopedElementsMixin(LitElement) {
 
     constructor() {
@@ -77,6 +88,7 @@ export class LoginButton extends ScopedElementsMixin(LitElement) {
 
         this._bus = new EventBus();
         this._bus.subscribe('auth-update', (data) => {
+            console.log(data);
             this._loginData = data;
         });
     }
@@ -153,7 +165,17 @@ export class LoginButton extends ScopedElementsMixin(LitElement) {
     }
 
     render() {
-        if (this._loginData.status === LoginStatus.LOGGED_IN) {
+        if (this._loginData.status === LoginStatus.LOGGING_IN) {
+            // try to keep the layout the same to avoid layout shifts
+            return html`
+                <a href="#">
+                    <div class="login-box login-button">
+                        <div class="icon">${unsafeHTML(loggingInSVG)}</div>
+                        <div class="label">&#8203;</div>
+                    </div>
+                </a>
+            `;
+        } else if (this._loginData.status === LoginStatus.LOGGED_IN) {
             return html`
                 <a href="#" @click="${this._onLogoutClicked}">
                     <div class="login-box login-button">
diff --git a/packages/check-in-place-select/.eslintignore b/packages/check-in-place-select/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..7b596da7b5a30a2b742e9bc9bc8002606940e18a
--- /dev/null
+++ b/packages/check-in-place-select/.eslintignore
@@ -0,0 +1,3 @@
+/vendor/**
+/dist/**
+/*.js
\ No newline at end of file
diff --git a/packages/check-in-place-select/.eslintrc.json b/packages/check-in-place-select/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/check-in-place-select/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/check-in-place-select/README.md b/packages/check-in-place-select/README.md
index 81f53f09910d46f35479d504626fa2130d7ff27e..b1ba6574f8ad04b37749fb6fbe130f4739351e53 100644
--- a/packages/check-in-place-select/README.md
+++ b/packages/check-in-place-select/README.md
@@ -1,9 +1,16 @@
 # Check-in place select web component
 
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/check-in-place-select
+```
+
 ## Usage
 
 ```html
 <dbp-check-in-place-select></dbp-check-in-place-select>
+<script type="module" src="node_modules/@dbp-toolkit/check-in-place-select/dist/dbp-check-in-place-select.js"></script>
 ```
 
 ## Attributes
diff --git a/packages/check-in-place-select/package.json b/packages/check-in-place-select/package.json
index 23aa0a5e9aec6a588e5754b18b76ed5c726bca76..78374980255edffc3949317bdb473ffe32a1c820 100644
--- a/packages/check-in-place-select/package.json
+++ b/packages/check-in-place-select/package.json
@@ -4,7 +4,11 @@
   "version": "0.1.0",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
-  "private": true,
+  "repository": {
+    "type": "git",
+    "url": "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/check-in-place-select"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
@@ -27,7 +31,9 @@
     "rollup-plugin-copy": "^3.1.0",
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/auth": "^0.1.0",
@@ -49,6 +55,7 @@
     "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "npm run build-test && karma start --singleRun"
+    "test": "npm run build-test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/check-in-place-select/src/check-in-place-select.js b/packages/check-in-place-select/src/check-in-place-select.js
index d2a2594896e49ab03c178bf7b7fd5c2583b43667..ae3d9eea80860342e8d3b57604145dd3845b1790 100644
--- a/packages/check-in-place-select/src/check-in-place-select.js
+++ b/packages/check-in-place-select/src/check-in-place-select.js
@@ -1,6 +1,6 @@
 import {findObjectInApiResults} from './utils.js';
-import select2LangDe from './i18n/de/select2'
-import select2LangEn from './i18n/en/select2'
+import select2LangDe from './i18n/de/select2';
+import select2LangEn from './i18n/en/select2';
 import JSONLD from '@dbp-toolkit/common/jsonld';
 import {css, html, LitElement} from 'lit-element';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
@@ -124,6 +124,8 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(LitElement) {
 
     /**
      * Initializes the Select2 selector
+     *
+     * @param ignorePreset
      */
     initSelect2(ignorePreset = false) {
         const that = this;
diff --git a/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js b/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js
index 8ecb7ab98e9abeadf054c53ddcc0f3f5538e263c..539baa5028726c382c2169ff5e0961e659d6001f 100644
--- a/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js
+++ b/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js
@@ -6,7 +6,7 @@ import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth';
 import * as commonUtils from '@dbp-toolkit/common/utils';
 import * as commonStyles from '@dbp-toolkit/common/styles';
 
-class CheckInPlaceSelectDemo extends ScopedElementsMixin(LitElement) {
+export class CheckInPlaceSelectDemo extends ScopedElementsMixin(LitElement) {
     constructor() {
         super();
         this.lang = 'de';
@@ -15,9 +15,9 @@ class CheckInPlaceSelectDemo extends ScopedElementsMixin(LitElement) {
 
     static get scopedElements() {
         return {
-          'dbp-auth-keycloak': AuthKeycloak,
           'dbp-login-button': LoginButton,
           'dbp-check-in-place-select': CheckInPlaceSelect,
+          'dbp-auth-keycloak': AuthKeycloak,
         };
     }
 
@@ -49,9 +49,11 @@ class CheckInPlaceSelectDemo extends ScopedElementsMixin(LitElement) {
     }
 
     getAuthComponentHtml() {
-        return this.noAuth ? html`` : html`
+        return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html`
             <div class="container">
-                <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
+                <dbp-auth-keycloak lang="${this.lang}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html"
+                                   url="https://auth-dev.tugraz.at/auth" realm="tugraz"
+                                   client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
                 <dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
             </div>
         `;
diff --git a/packages/check-in-place-select/src/i18n/de/select2.js b/packages/check-in-place-select/src/i18n/de/select2.js
index 487734d315bddea78931e81907b44033bceb504e..bef156f0f506c91c494fa5fc1c7a7b49a8a97d9c 100644
--- a/packages/check-in-place-select/src/i18n/de/select2.js
+++ b/packages/check-in-place-select/src/i18n/de/select2.js
@@ -43,4 +43,4 @@ export default function () {
             return 'Entferne alle Gegenstände';
         }
     };
-};
+}
diff --git a/packages/check-in-place-select/src/i18n/en/select2.js b/packages/check-in-place-select/src/i18n/en/select2.js
index 12ba14cc3c6a8af6a9c24a7366aef7ca739f3509..d172d72ef06e17651dda4d2f6d73ef49e50cf845 100644
--- a/packages/check-in-place-select/src/i18n/en/select2.js
+++ b/packages/check-in-place-select/src/i18n/en/select2.js
@@ -47,4 +47,4 @@ export default function () {
             return 'Remove all items';
         }
     };
-};
+}
diff --git a/packages/common/.eslintrc.json b/packages/common/.eslintrc.json
index dcb3daa3e43a01208a022e30711870901c24f1f0..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f 100644
--- a/packages/common/.eslintrc.json
+++ b/packages/common/.eslintrc.json
@@ -1,25 +1,3 @@
 {
-    "env": {
-        "browser": true,
-        "es6": true,
-        "mocha": true
-    },
-    "globals": {
-        "Atomics": "readonly",
-        "SharedArrayBuffer": "readonly"
-    },
-    "parser": "babel-eslint",
-    "parserOptions": {
-        "ecmaVersion": 2018,
-        "sourceType": "module"
-    },
-    "rules": {
-        "no-unused-vars": ["error", { "args": "none" }],
-        "semi": [2, "always"],
-        "jsdoc/require-jsdoc": 0,
-        "jsdoc/require-param-description": 0,
-        "jsdoc/require-returns": 0,
-        "jsdoc/require-returns-description": 0,
-        "jsdoc/require-param-type": 0
-    }
+    "extends": "./../../eslint.common.json"
 }
\ No newline at end of file
diff --git a/packages/common/README.md b/packages/common/README.md
index 30fa025bf80b669dceb93a05480e165d581fbc3d..70e9ac52f34cda4d48686a7c60c1585a62b180fb 100644
--- a/packages/common/README.md
+++ b/packages/common/README.md
@@ -1,5 +1,11 @@
 # Common Code
 
+You can install these components via npm:
+
+```bash
+npm i @dbp-toolkit/common
+```
+
 ## Icon Web Component
 
 For valid icon names see: [LineIcons](https://lineicons.com/icons/)
diff --git a/packages/common/package.json b/packages/common/package.json
index 22069d6b5fc3c2458f7e17730995673e9f47af7e..af3a4f9c3cf4ef1c1ebfa9498858129f406cf354 100644
--- a/packages/common/package.json
+++ b/packages/common/package.json
@@ -1,9 +1,14 @@
 {
   "name": "@dbp-toolkit/common",
   "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/common",
-  "version": "0.1.0",
+  "version": "0.1.2",
   "module": "index.js",
   "license": "LGPL-2.1-or-later",
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/common"
+  },
   "devDependencies": {
     "@rollup/plugin-commonjs": "^16.0.0",
     "@rollup/plugin-json": "^4.1.0",
diff --git a/packages/common/utils.js b/packages/common/utils.js
index fb31adb97ed00f544c6d35c6575d9301e1ee4aef..e89776e6658e3e83068dad1ad14b15bae46138dc 100644
--- a/packages/common/utils.js
+++ b/packages/common/utils.js
@@ -212,7 +212,7 @@ export const getAssetURL = (pkg, path) => {
         // assume it is a full path
         fullPath = pkg;
     } else {
-        fullPath = 'local/' + pkg + '/' + path
+        fullPath = 'local/' + pkg + '/' + path;
     }
     return new URL(fullPath, new URL('..', import.meta.url).href).href;
 };
@@ -292,27 +292,27 @@ export async function asyncArrayForEach(array, callback) {
  * Attempts to determine the mime type of a file or blob
  *
  * @param file
- * @returns {Promise<unknown>}
+ * @returns {Promise<string>}
  */
 export async function getMimeTypeOfFile(file) {
     const getMimeType = (signature) => {
         switch (signature) {
             case '89504E47':
-                return 'image/png'
+                return 'image/png';
             case '47494638':
-                return 'image/gif'
+                return 'image/gif';
             case '25504446':
-                return 'application/pdf'
+                return 'application/pdf';
             case 'FFD8FFDB':
             case 'FFD8FFE0':
             case 'FFD8FFE1':
-                return 'image/jpeg'
+                return 'image/jpeg';
             case '504B0304':
-                return 'application/zip'
+                return 'application/zip';
             default:
-                return 'Unknown filetype'
+                return 'Unknown filetype';
         }
-    }
+    };
 
     return await new Promise((resolve) => {
         let fileReader = new FileReader();
@@ -323,15 +323,15 @@ export async function getMimeTypeOfFile(file) {
                 let bytes = [];
 
                 uint.forEach((byte) => {
-                    bytes.push(byte.toString(16))
-                })
+                    bytes.push(byte.toString(16));
+                });
 
                 const hex = bytes.join('').toUpperCase();
                 const mimeType = getMimeType(hex);
 
                 resolve(mimeType);
             }
-        }
+        };
 
         fileReader.readAsArrayBuffer(file.slice(0, 4));
     });
diff --git a/packages/data-table-view/.eslintignore b/packages/data-table-view/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..c139ed4c11bae3aeb416c866e2a9aa248930c65f
--- /dev/null
+++ b/packages/data-table-view/.eslintignore
@@ -0,0 +1,4 @@
+/vendor/**
+/dist/**
+*.conf.js
+*.config.js
\ No newline at end of file
diff --git a/packages/data-table-view/.eslintrc.json b/packages/data-table-view/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/data-table-view/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/data-table-view/package.json b/packages/data-table-view/package.json
index 40c00e6248fa497e8e7f43b3f1bd8dbca80d55e1..40d518d622639483d094f003baef254875d32d5c 100644
--- a/packages/data-table-view/package.json
+++ b/packages/data-table-view/package.json
@@ -4,7 +4,11 @@
   "version": "0.1.0",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
-  "private": true,
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/data-table-view"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
@@ -26,7 +30,9 @@
     "rollup-plugin-copy": "^3.1.0",
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/auth": "^0.1.0",
@@ -55,6 +61,7 @@
     "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "npm run build-test && karma start --singleRun"
+    "test": "npm run build-test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/data-table-view/src/data-table-view.js b/packages/data-table-view/src/data-table-view.js
index 565c38b8c567b0223333436a08c7526387c5c1a6..834a211e647355609e87b8f4c7a0593edeee6f54 100644
--- a/packages/data-table-view/src/data-table-view.js
+++ b/packages/data-table-view/src/data-table-view.js
@@ -227,12 +227,12 @@ export class DataTableView extends LitElement {
 
         changedProperties.forEach((oldValue, propName) => {
             if (propName === "lang") {
-                i18n.changeLanguage(this.lang).catch(e => { console.log(e)});
+                i18n.changeLanguage(this.lang).catch(e => { console.log(e);});
                 languageChange = true;
             }
         });
 
-        this.updateComplete.then(this.set_datatable(this.data, languageChange)).catch(e => { console.log(e)});
+        this.updateComplete.then(this.set_datatable(this.data, languageChange)).catch(e => { console.log(e);});
         super.update(changedProperties);
     }
 
diff --git a/packages/data-table-view/src/dbp-data-table-view-demo.js b/packages/data-table-view/src/dbp-data-table-view-demo.js
index 22260e9c27779997339890c17cb489d2bb8ea1fa..810e968cb5b19f43c7fc590eea2d4aba7eb7ca29 100644
--- a/packages/data-table-view/src/dbp-data-table-view-demo.js
+++ b/packages/data-table-view/src/dbp-data-table-view-demo.js
@@ -135,9 +135,11 @@ export class DataTableViewDemo extends ScopedElementsMixin(LitElement) {
     }
 
     getAuthComponentHtml() {
-        return this.noAuth ? html`` : html`
-            <div class="content">
-                <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
+        return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html`
+            <div class="container">
+                <dbp-auth-keycloak lang="${this.lang}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html"
+                                   url="https://auth-dev.tugraz.at/auth" realm="tugraz"
+                                   client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
                 <dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
             </div>
         `;
diff --git a/packages/file-handling/.eslintignore b/packages/file-handling/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..e21b62712b8be6bf7a20f04647df3eaf6f20b96c
--- /dev/null
+++ b/packages/file-handling/.eslintignore
@@ -0,0 +1,5 @@
+/vendor/**
+/dist/**
+*.conf.js
+*.config.js
+src/micromodal.es.js
\ No newline at end of file
diff --git a/packages/file-handling/.eslintrc.json b/packages/file-handling/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/file-handling/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/file-handling/package.json b/packages/file-handling/package.json
index 18afa75811285c71cc7229988473039cd9dd6fab..f111c09720ecb0f3d03600ee03ebe46a23720f3d 100644
--- a/packages/file-handling/package.json
+++ b/packages/file-handling/package.json
@@ -1,9 +1,14 @@
 {
   "name": "@dbp-toolkit/file-handling",
   "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/file-handling",
-  "version": "0.1.5",
+  "version": "0.1.6",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/file-handling"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
@@ -24,7 +29,9 @@
     "rollup-plugin-copy": "^3.1.0",
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/common": "^0.1.0",
@@ -50,6 +57,7 @@
     "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "npm run build-test && karma start --singleRun"
+    "test": "npm run build-test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/file-handling/src/dbp-nextcloud-file-picker.js b/packages/file-handling/src/dbp-nextcloud-file-picker.js
index fae40521448ff22c43f05087736c32617e1a9e3d..201ffe9f4c6f024b61acb93f1e063626cd583180 100644
--- a/packages/file-handling/src/dbp-nextcloud-file-picker.js
+++ b/packages/file-handling/src/dbp-nextcloud-file-picker.js
@@ -140,7 +140,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                             if (typeof cell.getValue() === 'undefined') {
                                 return "";
                             }
-                            const [fileMainType, fileSubType] = cell.getValue().split('/');
+                            const [, fileSubType] = cell.getValue().split('/');
                             return fileSubType;
                         }},
                     {title: i18n.t('nextcloud-file-picker.last-modified'), responsive: 3, widthGrow:1, minWidth: 100, field: "lastmod",sorter: (a, b, aRow, bRow, column, dir, sorterParams) => {
@@ -258,7 +258,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
     /**
      * check mime type of row
      *
-     * @param row.getDatat(), mimetypes
+     * @param data
+     * @param filterParams
      */
     checkFileType(data, filterParams) {
         if (typeof data.mime === 'undefined') {
@@ -300,11 +301,9 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                     this.loginWindow.close();
                 }
 
-                const apiUrl = this.webDavUrl + "/" + data.loginName;
                 // see https://github.com/perry-mitchell/webdav-client/blob/master/API.md#module_WebDAV.createClient
-
                 this.webDavClient = createClient(
-                    apiUrl,
+                    data.webdavUrl || this.webDavUrl + "/" + data.loginName,
                     {
                         username: data.loginName,
                         password: data.token
@@ -406,7 +405,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                 this.activeDirectoryACL = '';
             }
         } else {
-            this.activeDirectoryRights = 'SGDNVCK'
+            this.activeDirectoryRights = 'SGDNVCK';
         }
         this.loadDirectory(file.filename);
         event.preventDefault();
@@ -447,7 +446,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             }).catch(error => {
                 console.error(error.message);
                 this.loading = false;
-                this.statusText = html`<span class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`;;
+                this.statusText = html`<span class="error"> ${i18n.t('nextcloud-file-picker.webdav-error', {error: error.message})} </span>`;
         });
     }
 
@@ -485,7 +484,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
         this.statusText = i18n.t('nextcloud-file-picker.upload-to', {path: directory});
         this.fileList = files;
         this.forAll = false;
-        this.setRepeatForAllConflicts()
+        this.setRepeatForAllConflicts();
         this.uploadFile(directory);
     }
 
@@ -512,7 +511,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             let that = this;
             this.loading = true;
             this.statusText = i18n.t('nextcloud-file-picker.upload-to', {path: path});
-            let contents = await this.webDavClient
+            await this.webDavClient
                     .putFileContents(path, file,  { overwrite: false, onUploadProgress: progress => {
                             /* console.log(`Uploaded ${progress.loaded} bytes of ${progress.total}`);*/
                         }}).then(function() {
@@ -593,7 +592,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
 
         let that = this;
         // https://github.com/perry-mitchell/webdav-client#putfilecontents
-        let contents = await this.webDavClient
+        await this.webDavClient
             .putFileContents(path, file, {
                 overwrite: overwrite, onUploadProgress: progress => {
                     /*console.log(`Uploaded ${progress.loaded} bytes of ${progress.total}`);*/
@@ -631,7 +630,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
      * R = Share, S = Shared Folder, M = Group folder or external source, G = Read, D = Delete, NV / NVW = Write, CK = Create
      *
      * @param file
-     * @return number
+     * @returns {number}
      */
     checkRights(file) {
 
@@ -700,7 +699,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
     /**
      * Open the replace Modal Dialog with gui where forbidden actions are disabled
      *
-     * @param file, directory
+     * @param file
+     * @param directory
      */
     replaceModalDialog(file, directory) {
         this.uploadFileObject = file;
@@ -847,8 +847,6 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
             this._('#add-folder-button').setAttribute("title", i18n.t('nextcloud-file-picker.add-folder-close'));
             this._('#new-folder').focus();
         }
-
-        let that = this;
     }
 
     /**
@@ -1519,7 +1517,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                                 <span style="word-break: break-all;">${this.replaceFilename}</span>
                                 ${i18n.t('nextcloud-file-picker.replace-title-2')}.
                             </h2>
-                            <button title="${i18n.t('file-sink.modal-close')}" class="modal-close"  aria-label="Close modal" @click="${() => {this.closeDialog()}}">
+                            <button title="${i18n.t('file-sink.modal-close')}" class="modal-close"  aria-label="Close modal" @click="${() => {this.closeDialog();}}">
                                 <dbp-icon title="${i18n.t('file-sink.modal-close')}" name="close" class="close-icon"></dbp-icon>
                             </button> 
                         </header>
diff --git a/packages/file-handling/src/file-sink.js b/packages/file-handling/src/file-sink.js
index 3b9736c3b27a3a6c9e696ccd6f239cc59cbf1fb3..3af358ae63ab5a6511ca20dfb3bad61048496b48 100644
--- a/packages/file-handling/src/file-sink.js
+++ b/packages/file-handling/src/file-sink.js
@@ -208,7 +208,7 @@ export class FileSink extends ScopedElementsMixin(DBPLitElement) {
                             </div>
                         </nav>
                             <div class="modal-header">
-                                <button title="${i18n.t('file-sink.modal-close')}" class="modal-close"  aria-label="Close modal" @click="${() => { this.closeDialog()}}">
+                                <button title="${i18n.t('file-sink.modal-close')}" class="modal-close"  aria-label="Close modal" @click="${() => { this.closeDialog();}}">
                                         <dbp-icon title="${i18n.t('file-sink.modal-close')}" name="close" class="close-icon"></dbp-icon>
                                 </button> 
                                 <p class="modal-context"> ${this.context}</p>
diff --git a/packages/file-handling/src/file-source.js b/packages/file-handling/src/file-source.js
index c38d41418610209afbf653689815b308b84eb575..bee797dd90f61a0b25f5f28faceac1ea82edfc7f 100644
--- a/packages/file-handling/src/file-source.js
+++ b/packages/file-handling/src/file-source.js
@@ -7,7 +7,7 @@ import {Icon, MiniSpinner} from '@dbp-toolkit/common';
 import * as commonStyles from '@dbp-toolkit/common/styles';
 import {NextcloudFilePicker} from "./dbp-nextcloud-file-picker";
 import {classMap} from 'lit-html/directives/class-map.js';
-import MicroModal from './micromodal.es'
+import MicroModal from './micromodal.es';
 import * as fileHandlingStyles from './styles';
 
 function mimeTypesToAccept(mimeTypes) {
@@ -113,13 +113,13 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
         this.updateComplete.then(() => {
             this.dropArea = this._('#dropArea');
             ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
-                this.dropArea.addEventListener(eventName, this.preventDefaults, false)
+                this.dropArea.addEventListener(eventName, this.preventDefaults, false);
             });
             ['dragenter', 'dragover'].forEach(eventName => {
-                this.dropArea.addEventListener(eventName, this.highlight.bind(this), false)
+                this.dropArea.addEventListener(eventName, this.highlight.bind(this), false);
             });
             ['dragleave', 'drop'].forEach(eventName => {
-                this.dropArea.addEventListener(eventName, this.unhighlight.bind(this), false)
+                this.dropArea.addEventListener(eventName, this.unhighlight.bind(this), false);
             });
             this.dropArea.addEventListener('drop', this.handleDrop.bind(this), false);
             this._('#fileElem').addEventListener('change', this.handleChange.bind(this));
@@ -132,11 +132,11 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
     }
 
     highlight(e) {
-        this.dropArea.classList.add('highlight')
+        this.dropArea.classList.add('highlight');
     }
 
     unhighlight(e) {
-        this.dropArea.classList.remove('highlight')
+        this.dropArea.classList.remove('highlight');
     }
 
     handleDrop(e) {
@@ -177,7 +177,7 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
 
         await commonUtils.asyncArrayForEach(files, async (file) => {
             if (file.size === 0) {
-                console.log('file \'' + file.name + '\' has size=0 and is denied!')
+                console.log('file \'' + file.name + '\' has size=0 and is denied!');
                 return;
             }
 
@@ -238,7 +238,7 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
      * Decompress files synchronously
      *
      * @param file
-     * @returns {Promise<[]>}
+     * @returns {Promise<Array>}
      */
     async decompressZIP(file) {
         // see: https://stuk.github.io/jszip/
@@ -299,7 +299,9 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
             await response.json().then((json) => {
                 data.json = json;
             });
-        } catch (e) {}
+        } catch (e) {
+            //
+        }
 
         if (sendFile) {
             data.file = file;
@@ -422,7 +424,7 @@ export class FileSource extends ScopedElementsMixin(DBPLitElement) {
                             
                         </nav>
                         <div class="modal-header">
-                            <button title="${i18n.t('file-source.modal-close')}" class="modal-close"  aria-label="Close modal"  @click="${() => {this.closeDialog()}}">
+                            <button title="${i18n.t('file-source.modal-close')}" class="modal-close"  aria-label="Close modal"  @click="${() => {this.closeDialog();}}">
                                     <dbp-icon name="close" class="close-icon"></dbp-icon>
                             </button>
                        
diff --git a/packages/file-handling/src/styles.js b/packages/file-handling/src/styles.js
index 274b9bb45dd07a33ed59b8107a8cf31b05862fa2..720bdd2d38724c096f5b95e7b0defdd4880fc2d3 100644
--- a/packages/file-handling/src/styles.js
+++ b/packages/file-handling/src/styles.js
@@ -1,4 +1,4 @@
-import {css, unsafeCSS, CSSResult} from 'lit-element';
+import {css} from 'lit-element';
 
 export function getFileHandlingCss() {
     // language=css
diff --git a/packages/font-source-sans-pro/README.md b/packages/font-source-sans-pro/README.md
index 7135312e735598b94706ac94624c37000d0b7a9a..3115e0e119be20c2d40ba09b4f5379ee8e500598 100644
--- a/packages/font-source-sans-pro/README.md
+++ b/packages/font-source-sans-pro/README.md
@@ -1,5 +1,11 @@
 # Subsetted Version of Sans Source Pro 2
 
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/font-source-sans-pro
+```
+
 ## FAQ
 
 * Why?
diff --git a/packages/font-source-sans-pro/package.json b/packages/font-source-sans-pro/package.json
index dfce5904aa6a83af4b86f6ab8ff429a1cca955a8..1bed988bc859ef15fa7ad45d3e377cd04be6891a 100644
--- a/packages/font-source-sans-pro/package.json
+++ b/packages/font-source-sans-pro/package.json
@@ -1,8 +1,13 @@
 {
   "name": "@dbp-toolkit/font-source-sans-pro",
-  "version": "0.1.0",
+  "version": "0.1.2",
   "author": "",
   "license": "OFL-1.1",
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/font-source-sans-pro"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
diff --git a/packages/knowledge-base-web-page-element-view/.eslintignore b/packages/knowledge-base-web-page-element-view/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..7b596da7b5a30a2b742e9bc9bc8002606940e18a
--- /dev/null
+++ b/packages/knowledge-base-web-page-element-view/.eslintignore
@@ -0,0 +1,3 @@
+/vendor/**
+/dist/**
+/*.js
\ No newline at end of file
diff --git a/packages/knowledge-base-web-page-element-view/.eslintrc.json b/packages/knowledge-base-web-page-element-view/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/knowledge-base-web-page-element-view/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/knowledge-base-web-page-element-view/README.md b/packages/knowledge-base-web-page-element-view/README.md
index 7fd89f823306480933cd93e27b5a1f704f7aa020..93086003f1770e11bf3634dedee9dd9b6f73a80e 100644
--- a/packages/knowledge-base-web-page-element-view/README.md
+++ b/packages/knowledge-base-web-page-element-view/README.md
@@ -1,9 +1,16 @@
 # KnowledgeBaseWebPageElementView Web Component
 
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/knowledge-base-web-page-element-view
+```
+
 ## Usage
 
 ```html
 <dbp-knowledge-base-web-page-element-view></dbp-knowledge-base-web-page-element-view>
+<script type="module" src="node_modules/@dbp-toolkit/knowledge-base-web-page-element-view/dist/dbp-knowledge-base-web-page-element-view.js"></script>
 ```
 
 ## Attributes
diff --git a/packages/knowledge-base-web-page-element-view/package.json b/packages/knowledge-base-web-page-element-view/package.json
index 25317ff898b91bd02b284a20fe6ab73a347c3c00..58a755480cffcadb6fbf74babea7e357c8dda84f 100644
--- a/packages/knowledge-base-web-page-element-view/package.json
+++ b/packages/knowledge-base-web-page-element-view/package.json
@@ -4,7 +4,11 @@
   "version": "0.1.0",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
-  "private": true,
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/knowledge-base-web-page-element-view"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
@@ -26,7 +30,9 @@
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-postcss": "^3.1.2",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/auth": "^0.1.0",
@@ -48,6 +54,7 @@
     "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "npm run build-test && karma start --singleRun"
+    "test": "npm run build-test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js
index 809ccbe0d12106ec31b6ff3da8575bf54a5ca8cb..b7ca2271c44851fc4b65d04e196acbcf84f2e945 100644
--- a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js
+++ b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js
@@ -63,14 +63,15 @@ export class KnowledgeBaseWebPageElementViewDemo extends ScopedElementsMixin(Lit
     }
 
     getAuthComponentHtml() {
-        return this.noAuth ? html`` : html`
-            <div class="content">
-                <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
+        return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html`
+            <div class="container">
+                <dbp-auth-keycloak lang="${this.lang}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html"
+                                   url="https://auth-dev.tugraz.at/auth" realm="tugraz"
+                                   client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
                 <dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
             </div>
         `;
     }
-
     render() {
         return html`
             <section class="section">
diff --git a/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js b/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js
index a8bc5df0bcc2104b8a60e462a2ee52bbfcfead9b..a82c51a0605452c314e32c6d2b2be34226001846 100644
--- a/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js
+++ b/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js
@@ -125,7 +125,7 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(LitElem
             switch(propName) {
                 case "lang":
                 case "value":
-                case "entry-point-url":
+                case "entry-point-url": {
                     this.html = '';
                     const img = this._('#A2');
                     if (img !== null) {
@@ -136,6 +136,7 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(LitElem
                         div.style.display = 'none';
                     }
                     break;
+                }
                 case "text":
                     this.class = this.text !== '' ? 'has-text' : '';
                     break;
diff --git a/packages/language-select/.eslintignore b/packages/language-select/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..7b596da7b5a30a2b742e9bc9bc8002606940e18a
--- /dev/null
+++ b/packages/language-select/.eslintignore
@@ -0,0 +1,3 @@
+/vendor/**
+/dist/**
+/*.js
\ No newline at end of file
diff --git a/packages/language-select/.eslintrc.json b/packages/language-select/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/language-select/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/language-select/README.md b/packages/language-select/README.md
index 087ba18284b02382b3adc77b6f571191aab95ec5..5ae55265c42fe2a998aa085f397c6ecc0f47c311 100644
--- a/packages/language-select/README.md
+++ b/packages/language-select/README.md
@@ -10,7 +10,7 @@ npm i @dbp-toolkit/language-select
 
 ```html
 <dbp-language-select></dbp-language-select>
-<script type="module" src="node_modules/@dbp-toolkit/app-shell/dist/dbp-language-select.js"></script>
+<script type="module" src="node_modules/@dbp-toolkit/language-select/dist/dbp-language-select.js"></script>
 ```
 
 ## Local development
diff --git a/packages/language-select/package.json b/packages/language-select/package.json
index 54b45f3f3eba7fab1fa3bc9e3b7abcd31658b15a..19509f3c314b2b564b789782b61d83181de55e02 100644
--- a/packages/language-select/package.json
+++ b/packages/language-select/package.json
@@ -1,9 +1,14 @@
 {
   "name": "@dbp-toolkit/language-select",
   "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/language-select",
-  "version": "0.1.1",
+  "version": "0.1.2",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/language-select"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
@@ -24,7 +29,9 @@
     "rollup-plugin-copy": "^3.1.0",
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/common": "^0.1.0",
@@ -43,6 +50,7 @@
     "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "npm run build-test && karma start --singleRun"
+    "test": "npm run build-test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/language-select/src/language-select.js b/packages/language-select/src/language-select.js
index f337483fa82b47905a2a343d2ca4b6522f9c145b..661e603126331353474c240fa34846c25b927ba0 100644
--- a/packages/language-select/src/language-select.js
+++ b/packages/language-select/src/language-select.js
@@ -106,7 +106,7 @@ export class LanguageSelect extends LitElement {
     }
 
     onExternalChange(e) {
-        this.lang = e.detail.lang
+        this.lang = e.detail.lang;
     }
 
     connectedCallback() {
diff --git a/packages/matomo/.eslintignore b/packages/matomo/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..7b596da7b5a30a2b742e9bc9bc8002606940e18a
--- /dev/null
+++ b/packages/matomo/.eslintignore
@@ -0,0 +1,3 @@
+/vendor/**
+/dist/**
+/*.js
\ No newline at end of file
diff --git a/packages/matomo/.eslintrc.json b/packages/matomo/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/matomo/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/matomo/README.md b/packages/matomo/README.md
index c9cebb873491b1d5148c7a77495efa6791b426e5..3b76df2a187624c9071c4b8fca8e3486ac300a0b 100644
--- a/packages/matomo/README.md
+++ b/packages/matomo/README.md
@@ -1,9 +1,16 @@
 # Matomo Web Component
 
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/matomo
+```
+
 ## Usage
 
 ```html
 <dbp-matomo></dbp-matomo>
+<script type="module" src="node_modules/@dbp-toolkit/matomo/dist/dbp-matomo.js"></script>
 ```
 
 ## Attributes
diff --git a/packages/matomo/package.json b/packages/matomo/package.json
index 090450509bbca1b851b127e303ccf2faf789bef4..a95d83e913a4da0af76c4e84fa272355c04a7729 100644
--- a/packages/matomo/package.json
+++ b/packages/matomo/package.json
@@ -4,7 +4,11 @@
   "version": "0.1.0",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
-  "private": true,
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/matomo"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
@@ -26,7 +30,9 @@
     "rollup-plugin-copy": "^3.1.0",
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/auth": "^0.1.0",
@@ -45,6 +51,7 @@
     "watch": "rollup -c --watch",
     "watch-local": "yarn run watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "rollup -c --environment BUILD:test && karma start --singleRun"
+    "test": "rollup -c --environment BUILD:test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/matomo/src/dbp-matomo-demo.js b/packages/matomo/src/dbp-matomo-demo.js
index 3f4f9c27093629e530b5921169beacd1d486a6fb..9e7e82e9d8dbf38f687fb276fb18bb8cef528932 100644
--- a/packages/matomo/src/dbp-matomo-demo.js
+++ b/packages/matomo/src/dbp-matomo-demo.js
@@ -14,6 +14,7 @@ export class MatomoDemo extends ScopedElementsMixin(LitElement) {
         this.lang = 'de';
         this.matomoUrl = '';
         this.matomoSiteId = -1;
+        this.noAuth = false;
     }
 
     static get scopedElements() {
@@ -29,6 +30,7 @@ export class MatomoDemo extends ScopedElementsMixin(LitElement) {
             lang: { type: String },
             matomoUrl: { type: String, attribute: "matomo-url" },
             matomoSiteId: { type: Number, attribute: "matomo-site-id" },
+            noAuth: { type: Boolean, attribute: 'no-auth' },
         };
     }
 
@@ -62,15 +64,26 @@ export class MatomoDemo extends ScopedElementsMixin(LitElement) {
         ];
     }
 
+    getAuthComponentHtml() {
+        return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html`
+            <div class="container">
+                <dbp-auth-keycloak lang="${this.lang}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html"
+                                   url="https://auth-dev.tugraz.at/auth" realm="tugraz"
+                                   client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
+                <dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
+            </div>
+        `;
+    }
+
     render() {
+
         return html`
             <section class="section">
                 <div class="container">
                     <h1 class="title">Matomo-Demo</h1>
                 </div>
                 <div class="container">
-                    <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
-                    <dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
+                    ${ this.getAuthComponentHtml() }
                     <dbp-matomo endpoint="${this.matomoUrl}" site-id="${this.matomoSiteId}"></dbp-matomo>
                 </div>
                 <div class="container">
diff --git a/packages/matomo/src/matomo.js b/packages/matomo/src/matomo.js
index d15f22658ec3626c5a2fe9b531aad5f40306ddea..8e189c7283e1d4d07d3b4a0d4198ecc3d9e9646b 100644
--- a/packages/matomo/src/matomo.js
+++ b/packages/matomo/src/matomo.js
@@ -1,9 +1,11 @@
-import {i18n} from './i18n.js';
-import {LitElement} from "lit-element";
 import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element';
 import {EventBus} from '@dbp-toolkit/common';
 import buildInfo from 'consts:buildinfo';
 
+function pushEvent(event) {
+    window._paq = window._paq || [];
+    window._paq.push(event);
+}
 
 export class MatomoElement extends DBPLitElement {
 
@@ -53,16 +55,15 @@ export class MatomoElement extends DBPLitElement {
             }
             console.log('add matomo...');
 
-            window._paq = window._paq || [];
-            _paq.push(['setCustomVariable', 1, "GitCommit", buildInfo.info, "visit"]);
-            _paq.push(['enableHeartBeatTimer']);
-            _paq.push(['disableCookies']);
-            _paq.push(['trackPageView']);
-            _paq.push(['enableLinkTracking']);
+            pushEvent(['setCustomVariable', 1, "GitCommit", buildInfo.info, "visit"]);
+            pushEvent(['enableHeartBeatTimer']);
+            pushEvent(['disableCookies']);
+            pushEvent(['trackPageView']);
+            pushEvent(['enableLinkTracking']);
 
             (function (endpoint, siteId) {
-                _paq.push(['setTrackerUrl', endpoint+'matomo.php']);
-                _paq.push(['setSiteId', siteId]);
+                pushEvent(['setTrackerUrl', endpoint+'matomo.php']);
+                pushEvent(['setSiteId', siteId]);
 
                 var g = document.createElement('script');
                 var s = document.getElementsByTagName('script')[0];
@@ -75,27 +76,31 @@ export class MatomoElement extends DBPLitElement {
 
             // track changed locations
             window.addEventListener('locationchanged', function(e) {
-                _paq.push(['setReferrerUrl', e.detail.referrerUrl]);
-                _paq.push(['setCustomUrl', location.href]);
-                // _paq.push(['setDocumentTitle', '']);
-                _paq.push(['trackPageView']);
+                pushEvent(['setReferrerUrl', e.detail.referrerUrl]);
+                pushEvent(['setCustomUrl', location.href]);
+                // pushEvent(['setDocumentTitle', '']);
+                pushEvent(['trackPageView']);
 
                 // make Matomo aware of newly added content
                 var content = document.getElementById('content');
-                _paq.push(['MediaAnalytics::scanForMedia', content]);
-                _paq.push(['FormAnalytics::scanForForms', content]);
-                _paq.push(['trackContentImpressionsWithinNode', content]);
+                pushEvent(['MediaAnalytics::scanForMedia', content]);
+                pushEvent(['FormAnalytics::scanForForms', content]);
+                pushEvent(['trackContentImpressionsWithinNode', content]);
             });
 
             // track errors
             window.addEventListener('error', function(e) {
-                _paq.push(['trackEvent', 'Error', e.error.message + '\n' + e.error.stack]);
+                pushEvent(['trackEvent', 'Error', e.error.message + '\n' + e.error.stack]);
+            });
+
+            window.addEventListener('unhandledrejection', function(e) {
+                pushEvent(['trackEvent', 'UnhandledRejection', e.reason]);
             });
 
             this.isRunning = true;
             if (this.lastEvent.length > 0) {
                 console.log('MatomoElement* (' + this.isRunning + '): ' + this.lastEvent[1] + ', ' + this.lastEvent[2]);
-                _paq.push(this.lastEvent);
+                pushEvent(this.lastEvent);
                 this.lastEvent = [];
             }
             return;
@@ -111,7 +116,7 @@ export class MatomoElement extends DBPLitElement {
         console.log('MatomoElement  (' + this.isRunning + '): ' + action + ', ' + message);
         const event = ['trackEvent', action, message];
         if (this.isRunning) {
-            _paq.push(event);
+            pushEvent(event);
         } else {
             this.lastEvent = event;
         }
diff --git a/packages/notification/.eslintignore b/packages/notification/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..7b596da7b5a30a2b742e9bc9bc8002606940e18a
--- /dev/null
+++ b/packages/notification/.eslintignore
@@ -0,0 +1,3 @@
+/vendor/**
+/dist/**
+/*.js
\ No newline at end of file
diff --git a/packages/notification/.eslintrc.json b/packages/notification/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/notification/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/notification/README.md b/packages/notification/README.md
index d843ea650fec5d036355703ce03b30aa91bafc47..ffe39c35a49debe1f31a88080442e847602a0148 100644
--- a/packages/notification/README.md
+++ b/packages/notification/README.md
@@ -1,9 +1,16 @@
 # Notification Web Component
 
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/notification
+```
+
 ## Usage
 
 ```html
 <dbp-notification></dbp-notification>
+<script type="module" src="node_modules/@dbp-toolkit/notification/dist/dbp-notification.js"></script>
 ```
 
 ## Attributes
diff --git a/packages/notification/package.json b/packages/notification/package.json
index a0305f0e3f49581c6342381e96362fd99835e435..9a2c562dae275a118db7d60acdf8e86db52e036e 100644
--- a/packages/notification/package.json
+++ b/packages/notification/package.json
@@ -1,10 +1,14 @@
 {
   "name": "@dbp-toolkit/notification",
   "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/notification",
-  "version": "0.1.0",
+  "version": "0.1.1",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
-  "private": true,
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/notification"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
@@ -26,7 +30,9 @@
     "rollup-plugin-copy": "^3.1.0",
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/common": "^0.1.0",
@@ -45,6 +51,7 @@
     "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "npm run build-test && karma start --singleRun"
+    "test": "npm run build-test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/notification/src/notification.js b/packages/notification/src/notification.js
index c08d2163fbbe71980cd0d2cf6d8607eb3be3277c..51247ff8103153c0da64e49ed1075839ebd85e36 100644
--- a/packages/notification/src/notification.js
+++ b/packages/notification/src/notification.js
@@ -1,8 +1,7 @@
 import {i18n} from './i18n';
-import {createUUID} from './utils'
+import {createUUID} from './utils';
 import {css, html} from 'lit-element';
 import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element';
-import * as commonUtils from '@dbp-toolkit/common/utils';
 import * as commonStyles from '@dbp-toolkit/common/styles';
 
 /**
@@ -28,7 +27,7 @@ export class Notification extends DBPLitElement {
         i18n.changeLanguage(this.lang);
         const that = this;
 
-        const listener = window.addEventListener("dbp-notification-send", (e) => {
+        window.addEventListener("dbp-notification-send", (e) => {
             if (typeof e.detail === 'undefined') {
                 return;
             }
diff --git a/packages/person-profile/.eslintignore b/packages/person-profile/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..7b596da7b5a30a2b742e9bc9bc8002606940e18a
--- /dev/null
+++ b/packages/person-profile/.eslintignore
@@ -0,0 +1,3 @@
+/vendor/**
+/dist/**
+/*.js
\ No newline at end of file
diff --git a/packages/person-profile/.eslintrc.json b/packages/person-profile/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/person-profile/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/person-profile/README.md b/packages/person-profile/README.md
index c390152ada4ce9df3f2dddd7006c97b765006cc5..a648602907601e01f9c3a44e31b9a8534337bbfb 100644
--- a/packages/person-profile/README.md
+++ b/packages/person-profile/README.md
@@ -1,9 +1,16 @@
 # Person Profile Web Component
 
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/person-profile
+```
+
 ## Usage
 
 ```html
 <dbp-person-profile></dbp-person-profile>
+<script type="module" src="node_modules/@dbp-toolkit/person-profile/dist/dbp-person-profile.js"></script>
 ```
 
 ## Attributes
diff --git a/packages/person-profile/package.json b/packages/person-profile/package.json
index 6989356cab0466dc005ece7598af0e59afc04bd4..c064f0cf4ed8b0003b7fbf37c3dd8f5408f9add7 100644
--- a/packages/person-profile/package.json
+++ b/packages/person-profile/package.json
@@ -4,7 +4,11 @@
   "version": "0.1.0",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
-  "private": true,
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/person-profile"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
@@ -26,7 +30,9 @@
     "rollup-plugin-copy": "^3.1.0",
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/auth": "^0.1.0",
@@ -48,6 +54,7 @@
     "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "npm run build-test && karma start --singleRun"
+    "test": "npm run build-test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/person-profile/src/dbp-person-profile-demo.js b/packages/person-profile/src/dbp-person-profile-demo.js
index 3ca67f51a3cf54f1f41e9c42750139e8b57c9a32..40369cff010ac569811f1b88dfaabf43defbeeb3 100644
--- a/packages/person-profile/src/dbp-person-profile-demo.js
+++ b/packages/person-profile/src/dbp-person-profile-demo.js
@@ -66,13 +66,13 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) {
     }
 
     getAuthComponentHtml() {
-        return this.noAuth ? html`` : html`
-            <header>
-                <div class="container">
-                    <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
-                    <dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
-                </div>
-            </header>
+        return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html`
+            <div class="container">
+                <dbp-auth-keycloak lang="${this.lang}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html"
+                                   url="https://auth-dev.tugraz.at/auth" realm="tugraz"
+                                   client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
+                <dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
+            </div>
         `;
     }
 
diff --git a/packages/person-profile/src/person-profile.js b/packages/person-profile/src/person-profile.js
index fbd433562cddbe08ac7d5215da5b6e954ccf5b4a..9fd3d4df12b92a6ae23d7bcd70c8fbb12d9aae60 100644
--- a/packages/person-profile/src/person-profile.js
+++ b/packages/person-profile/src/person-profile.js
@@ -41,13 +41,14 @@ export class PersonProfile extends DBPLitElement {
                 case "lang":
                     i18n.changeLanguage(this.lang);
                     break;
-                case "entryPointUrl":
+                case "entryPointUrl": {
                     const that = this;
 
                     JSONLD.initialize(this.entryPointUrl, function (jsonld) {
                         that.jsonld = jsonld;
                     }, {}, that.lang);
                     break;
+                }
                 case 'value':
                     if (this.value !== '') {
                         const apiUrl = this.entryPointUrl + '/people/' + this.value;
diff --git a/packages/person-select/.eslintignore b/packages/person-select/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..7b596da7b5a30a2b742e9bc9bc8002606940e18a
--- /dev/null
+++ b/packages/person-select/.eslintignore
@@ -0,0 +1,3 @@
+/vendor/**
+/dist/**
+/*.js
\ No newline at end of file
diff --git a/packages/person-select/.eslintrc.json b/packages/person-select/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/person-select/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/person-select/README.md b/packages/person-select/README.md
index e32ddf36eccd883b115704d729f37a53a3c9d9f4..24fc8e2428254fe93f34c1de282b8850be7752d6 100644
--- a/packages/person-select/README.md
+++ b/packages/person-select/README.md
@@ -1,9 +1,16 @@
 # Person Select Web Component
 
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/person-select
+```
+
 ## Usage
 
 ```html
 <dbp-person-select></dbp-person-select>
+<script type="module" src="node_modules/@dbp-toolkit/person-select/dist/dbp-person-select.js"></script>
 ```
 
 ## Attributes
diff --git a/packages/person-select/package.json b/packages/person-select/package.json
index f3da70f12558b022e3e5fd8fac7132f919e63eda..cb983e55d499e4682a262ea7a1422b75500be53f 100644
--- a/packages/person-select/package.json
+++ b/packages/person-select/package.json
@@ -4,7 +4,11 @@
   "version": "0.1.0",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
-  "private": true,
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/person-select"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
@@ -27,7 +31,9 @@
     "rollup-plugin-copy": "^3.1.0",
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/auth": "^0.1.0",
@@ -49,6 +55,7 @@
     "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "npm run build-test && karma start --singleRun"
+    "test": "npm run build-test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/person-select/src/dbp-person-select-demo.js b/packages/person-select/src/dbp-person-select-demo.js
index 99a87292697ed1613a846dfa2843502c7a20bb9d..ff61f2a0e735e204c0c7d35a6e8e32a6ff57d29a 100644
--- a/packages/person-select/src/dbp-person-select-demo.js
+++ b/packages/person-select/src/dbp-person-select-demo.js
@@ -49,9 +49,11 @@ export class PersonSelectDemo extends ScopedElementsMixin(LitElement) {
     }
 
     getAuthComponentHtml() {
-        return this.noAuth ? html`` : html`
+        return this.noAuth ? html`<dbp-login-button lang="${this.lang}" show-image></dbp-login-button>` : html`
             <div class="container">
-                <dbp-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
+                <dbp-auth-keycloak lang="${this.lang}" silent-check-sso-redirect-uri="/dist/silent-check-sso.html"
+                                   url="https://auth-dev.tugraz.at/auth" realm="tugraz"
+                                   client-id="auth-dev-mw-frontend-local" load-person try-login></dbp-auth-keycloak>
                 <dbp-login-button lang="${this.lang}" show-image></dbp-login-button>
             </div>
         `;
diff --git a/packages/person-select/src/i18n/de/select2.js b/packages/person-select/src/i18n/de/select2.js
index 487734d315bddea78931e81907b44033bceb504e..bef156f0f506c91c494fa5fc1c7a7b49a8a97d9c 100644
--- a/packages/person-select/src/i18n/de/select2.js
+++ b/packages/person-select/src/i18n/de/select2.js
@@ -43,4 +43,4 @@ export default function () {
             return 'Entferne alle Gegenstände';
         }
     };
-};
+}
diff --git a/packages/person-select/src/i18n/en/select2.js b/packages/person-select/src/i18n/en/select2.js
index 12ba14cc3c6a8af6a9c24a7366aef7ca739f3509..d172d72ef06e17651dda4d2f6d73ef49e50cf845 100644
--- a/packages/person-select/src/i18n/en/select2.js
+++ b/packages/person-select/src/i18n/en/select2.js
@@ -47,4 +47,4 @@ export default function () {
             return 'Remove all items';
         }
     };
-};
+}
diff --git a/packages/person-select/src/person-select.js b/packages/person-select/src/person-select.js
index d91dd9ce2e0e5df55227f6cc19dcb756638a3a82..91bd3d52248b307b12aab807c025fc7592afdeb3 100644
--- a/packages/person-select/src/person-select.js
+++ b/packages/person-select/src/person-select.js
@@ -1,8 +1,8 @@
 import $ from 'jquery';
 import {findObjectInApiResults} from './utils.js';
 import select2 from 'select2';
-import select2LangDe from './i18n/de/select2'
-import select2LangEn from './i18n/en/select2'
+import select2LangDe from './i18n/de/select2';
+import select2LangEn from './i18n/en/select2';
 import JSONLD from '@dbp-toolkit/common/jsonld';
 import {css, html, LitElement} from 'lit-element';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
@@ -115,6 +115,8 @@ export class PersonSelect extends ScopedElementsMixin(LitElement) {
 
     /**
      * Initializes the Select2 selector
+     *
+     * @param ignorePreset
      */
     initSelect2(ignorePreset = false) {
         const that = this;
diff --git a/packages/provider/.eslintignore b/packages/provider/.eslintignore
new file mode 100644
index 0000000000000000000000000000000000000000..7b596da7b5a30a2b742e9bc9bc8002606940e18a
--- /dev/null
+++ b/packages/provider/.eslintignore
@@ -0,0 +1,3 @@
+/vendor/**
+/dist/**
+/*.js
\ No newline at end of file
diff --git a/packages/provider/.eslintrc.json b/packages/provider/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f
--- /dev/null
+++ b/packages/provider/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": "./../../eslint.common.json"
+}
\ No newline at end of file
diff --git a/packages/provider/README.md b/packages/provider/README.md
index 6ad4dd3869c6226209483cc362a7377fb5653aee..706d8934aa3ce573df6d20111432a8eeb944d80f 100644
--- a/packages/provider/README.md
+++ b/packages/provider/README.md
@@ -2,10 +2,17 @@
 
 [GitLab Repository](git@gitlab.tugraz.at:dbp/web-components/toolkit.git)
 
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/provider
+```
+
 ## Usage
 
 ```html
 <provider></provider>
+<script type="module" src="node_modules/@dbp-toolkit/provider/dist/dbp-provider.js"></script>
 ```
 
 ## Attributes
diff --git a/packages/provider/package.json b/packages/provider/package.json
index 647487ff6afa808a98af31fa11798e17bcd6cb63..ed9f5b6b357bf32ea3c1ab3f1aeb7bbb2214ed48 100644
--- a/packages/provider/package.json
+++ b/packages/provider/package.json
@@ -1,9 +1,15 @@
 {
   "name": "@dbp-toolkit/provider",
+  "homepage": "https://gitlab.tugraz.at/dbp/web-components/toolkit/-/tree/master/packages/provider",
   "version": "0.1.0",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
   "private": true,
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/provider"
+  },
   "devDependencies": {
     "@rollup/plugin-commonjs": "^16.0.0",
     "@rollup/plugin-json": "^4.1.0",
@@ -22,7 +28,9 @@
     "rollup-plugin-copy": "^3.1.0",
     "rollup-plugin-delete": "^2.0.0",
     "rollup-plugin-serve": "^1.0.1",
-    "rollup-plugin-terser": "^7.0.2"
+    "rollup-plugin-terser": "^7.0.2",
+    "eslint": "^7.3.1",
+    "eslint-plugin-jsdoc": "^30.6.4"
   },
   "dependencies": {
     "@dbp-toolkit/auth": "^0.1.0",
@@ -41,6 +49,7 @@
     "watch": "rollup -c --watch",
     "watch-local": "yarn run watch",
     "watch-dev": "rollup -c --watch --environment BUILD:development",
-    "test": "rollup -c --environment BUILD:test && karma start --singleRun"
+    "test": "rollup -c --environment BUILD:test && karma start --singleRun",
+    "lint": "eslint ."
   }
 }
diff --git a/packages/provider/src/provider.js b/packages/provider/src/provider.js
index 99066cf2443fa1c92b2549e59a4bfe050ab22918..49249d3905c0afa7c73631bcbafab2a43c3bde9d 100644
--- a/packages/provider/src/provider.js
+++ b/packages/provider/src/provider.js
@@ -72,7 +72,7 @@ export class Provider extends HTMLElement {
                     if (item.sender === sender && item.name === name) {
                         const index = that.callbackStore.indexOf(item);
                         that.callbackStore.splice(index, 1);
-                        console.log('Provider(' + that.id() + ') eventListener for name "' + name + '" removed.')
+                        console.log('Provider(' + that.id() + ') eventListener for name "' + name + '" removed.');
                     }
                 });
 
diff --git a/packages/qr-code-scanner/.eslintrc.json b/packages/qr-code-scanner/.eslintrc.json
index 1ccd30a3fee0b4867a0172e746714eb0083fb07d..806e1095014e8e6b81f1e79ecd2fbfd93a37c64f 100644
--- a/packages/qr-code-scanner/.eslintrc.json
+++ b/packages/qr-code-scanner/.eslintrc.json
@@ -1,25 +1,3 @@
 {
-    "env": {
-        "browser": true,
-        "es6": true,
-        "mocha": true
-    },
-    "extends": ["eslint:recommended", "plugin:jsdoc/recommended"],
-    "globals": {
-        "Atomics": "readonly",
-        "SharedArrayBuffer": "readonly"
-    },
-    "parser": "babel-eslint",
-    "parserOptions": {
-        "ecmaVersion": 2018,
-        "sourceType": "module"
-    },
-    "rules": {
-        "no-unused-vars": ["error", { "args": "none" }],
-        "semi": [2, "always"],
-        "jsdoc/require-jsdoc": 0,
-        "jsdoc/require-param-description": 0,
-        "jsdoc/require-returns": 0,
-        "jsdoc/require-param-type": 0
-    }
+    "extends": "./../../eslint.common.json"
 }
\ No newline at end of file
diff --git a/packages/qr-code-scanner/README.md b/packages/qr-code-scanner/README.md
index ad33771ed9786ef2aa5be93e80025ef40d430925..318d03bb534cc79a69e09c580a96d3f82c541982 100644
--- a/packages/qr-code-scanner/README.md
+++ b/packages/qr-code-scanner/README.md
@@ -1,5 +1,11 @@
 # QR code Scanner Web Component
 
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/qr-code-scanner
+```
+
 ## Requirements
 - Https
 
@@ -7,6 +13,7 @@
 
 ```html
 <dbp-qr-code-scanner></dbp-qr-code-scanner>
+<script type="module" src="node_modules/@dbp-toolkit/qr-code-scanner/dist/dbp-qr-code-scanner.js"></script>
 ```
 
 The QR code Scanner Web Component uses a camera device, which you can select(if you have more than one).
diff --git a/packages/qr-code-scanner/package.json b/packages/qr-code-scanner/package.json
index a5701d3da7d4cd1d1b0fd16c05bee587c2188836..3bcfb17410995095061bc3f35e736f7e74363e25 100644
--- a/packages/qr-code-scanner/package.json
+++ b/packages/qr-code-scanner/package.json
@@ -4,7 +4,11 @@
   "version": "0.1.0",
   "main": "src/index.js",
   "license": "LGPL-2.1-or-later",
-  "private": true,
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/qr-code-scanner"
+  },
   "publishConfig": {
     "registry": "https://registry.npmjs.org",
     "access": "public"
diff --git a/packages/typescript-example/.gitignore b/packages/typescript-example/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e62f92aa809c7345cb05914d7143b0322ab6d725
--- /dev/null
+++ b/packages/typescript-example/.gitignore
@@ -0,0 +1,5 @@
+dist
+node_modules
+.idea
+npm-debug.log
+package-lock.json
diff --git a/packages/typescript-example/LICENSE b/packages/typescript-example/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..4362b49151d7b34ef83b3067a8f9c9f877d72a0e
--- /dev/null
+++ b/packages/typescript-example/LICENSE
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/packages/typescript-example/README.md b/packages/typescript-example/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3e05bb4d070b919c1e94f3e849aec1e2a8bd9f4e
--- /dev/null
+++ b/packages/typescript-example/README.md
@@ -0,0 +1,11 @@
+# Typescript Example Web Component
+
+This web component is just an example for how to write one using typescript.
+While we don't use typescript in our other components we want our dev/build
+pipeline to support it.
+
+You can install this component via npm:
+
+```bash
+npm i @dbp-toolkit/typescript-example
+```
diff --git a/packages/typescript-example/assets/index.html b/packages/typescript-example/assets/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..f2028df86b5b56f18cae1beb9fa3df866b3675d8
--- /dev/null
+++ b/packages/typescript-example/assets/index.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <script type="module" src="dbp-typescript-example-demo.js"></script>
+    <style>
+    body {
+        font-family: sans;
+    }
+    </style>
+</head>
+
+<body>
+    <dbp-typescript-example-demo></dbp-typescript-example-demo>
+</body>
+</html>
diff --git a/packages/typescript-example/karma.conf.js b/packages/typescript-example/karma.conf.js
new file mode 100644
index 0000000000000000000000000000000000000000..ca038af2286e2ad631f1c58d7216fbe4054e4199
--- /dev/null
+++ b/packages/typescript-example/karma.conf.js
@@ -0,0 +1 @@
+module.exports = require('../../karma.common.conf.js');
diff --git a/packages/typescript-example/package.json b/packages/typescript-example/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..0c9ec6c775d0f89b34024b02721cea7614b5064a
--- /dev/null
+++ b/packages/typescript-example/package.json
@@ -0,0 +1,48 @@
+{
+  "name": "@dbp-toolkit/typescript-example",
+  "version": "0.1.1",
+  "main": "src/index.js",
+  "license": "LGPL-2.1-or-later",
+  "repository": {
+    "type" : "git",
+    "url" : "https://gitlab.tugraz.at/dbp/web-components/toolkit.git",
+    "directory": "packages/typescript-example"
+  },
+  "publishConfig": {
+    "registry": "https://registry.npmjs.org",
+    "access": "public"
+  },
+  "devDependencies": {
+    "@rollup/plugin-commonjs": "^16.0.0",
+    "@rollup/plugin-json": "^4.1.0",
+    "@rollup/plugin-node-resolve": "^10.0.0",
+    "@types/mocha": "^8.2.0",
+    "chai": "^4.2.0",
+    "karma": "^5.1.0",
+    "karma-chrome-launcher": "^3.0.0",
+    "karma-firefox-launcher": "^2.1.0",
+    "karma-mocha": "^2.0.1",
+    "mocha": "^8.0.1",
+    "rollup": "^2.33.3",
+    "rollup-plugin-consts": "^1.0.1",
+    "rollup-plugin-copy": "^3.1.0",
+    "rollup-plugin-delete": "^2.0.0",
+    "rollup-plugin-serve": "^1.0.1",
+    "rollup-plugin-terser": "^7.0.2",
+    "rollup-plugin-typescript2": "^0.29.0",
+    "ts-lit-plugin": "^1.2.1",
+    "tslib": "^2.0.3",
+    "typescript": "^4.1.2"
+  },
+  "dependencies": {
+    "@dbp-toolkit/common": "^0.1.0",
+    "@open-wc/scoped-elements": "^1.3.2",
+    "lit-element": "^2.3.1"
+  },
+  "scripts": {
+    "clean": "rm dist/*",
+    "build": "rollup -c",
+    "watch": "rollup -c --watch",
+    "test": "rollup -c --environment BUILD:test && karma start --singleRun"
+  }
+}
diff --git a/packages/typescript-example/rollup.config.js b/packages/typescript-example/rollup.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..4773e8a89798c400c733cbfb06e1164d9cf68b43
--- /dev/null
+++ b/packages/typescript-example/rollup.config.js
@@ -0,0 +1,50 @@
+import glob from 'glob';
+import resolve from '@rollup/plugin-node-resolve';
+import commonjs from '@rollup/plugin-commonjs';
+import copy from 'rollup-plugin-copy';
+import {terser} from "rollup-plugin-terser";
+import json from '@rollup/plugin-json';
+import serve from 'rollup-plugin-serve';
+import consts from 'rollup-plugin-consts';
+import del from 'rollup-plugin-delete';
+import typescript from 'rollup-plugin-typescript2';
+
+const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
+console.log("build: " + build);
+
+export default {
+    input: (build != 'test') ? ['src/dbp-typescript-example.ts', 'src/dbp-typescript-example-demo.ts'] : glob.sync('test/**/*.ts'),
+    output: {
+        dir: 'dist',
+        entryFileNames: '[name].js',
+        chunkFileNames: 'shared/[name].[hash].[format].js',
+        format: 'esm',
+        sourcemap: true
+    },
+    onwarn: function (warning, warn) {
+        // ignore chai warnings
+        if (warning.code === 'CIRCULAR_DEPENDENCY') {
+            return;
+        }
+        warn(warning);
+    },
+    plugins: [
+        del({
+            targets: 'dist/*'
+        }),
+        consts({
+            environment: build,
+        }),
+        resolve(),
+        commonjs(),
+        json(),
+        typescript(),
+        (build !== 'local' && build !== 'test') ? terser() : terser(),
+        copy({
+            targets: [
+                {src: 'assets/index.html', dest: 'dist'},
+            ],
+        }),
+        (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
+    ]
+};
diff --git a/packages/typescript-example/src/dbp-typescript-example-demo.ts b/packages/typescript-example/src/dbp-typescript-example-demo.ts
new file mode 100644
index 0000000000000000000000000000000000000000..30dc002f5791975a4068ae8f2d61187ad9980d6c
--- /dev/null
+++ b/packages/typescript-example/src/dbp-typescript-example-demo.ts
@@ -0,0 +1,22 @@
+// @ts-nocheck
+import {html, LitElement} from 'lit-element';
+import {TypeScriptExample} from './typescript-example';
+import * as commonUtils from '@dbp-toolkit/common/utils';
+import { ScopedElementsMixin } from '@open-wc/scoped-elements';
+
+export class TypeScriptExampleDemo extends ScopedElementsMixin(LitElement) {
+
+    static get scopedElements() {
+        return {
+          'dbp-typescript-example': TypeScriptExample,
+        };
+    }
+
+    render() {
+        return html`
+            <dbp-typescript-example lang="de"></dbp-typescript-example>
+        `;
+    }
+}
+
+commonUtils.defineCustomElement('dbp-typescript-example-demo', TypeScriptExampleDemo);
diff --git a/packages/typescript-example/src/dbp-typescript-example.ts b/packages/typescript-example/src/dbp-typescript-example.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5637280cbafa201b8a2cdaebe0b9f2cbe9497a51
--- /dev/null
+++ b/packages/typescript-example/src/dbp-typescript-example.ts
@@ -0,0 +1,4 @@
+import * as commonUtils from '@dbp-toolkit/common/utils';
+import {TypeScriptExample} from './typescript-example';
+
+commonUtils.defineCustomElement('dbp-typescript-example', TypeScriptExample);
diff --git a/packages/typescript-example/src/i18n.ts b/packages/typescript-example/src/i18n.ts
new file mode 100644
index 0000000000000000000000000000000000000000..498d9f037b0a5ca481ec8de5df24640900285808
--- /dev/null
+++ b/packages/typescript-example/src/i18n.ts
@@ -0,0 +1,6 @@
+import {createInstance} from '@dbp-toolkit/common/i18next.js';
+
+import de from './i18n/de/translation.json';
+import en from './i18n/en/translation.json';
+
+export const i18n = createInstance({en: en, de: de}, 'de', 'en');
\ No newline at end of file
diff --git a/packages/typescript-example/src/i18n/de/translation.json b/packages/typescript-example/src/i18n/de/translation.json
new file mode 100644
index 0000000000000000000000000000000000000000..dcf5d832a1e6010fdbcbda76b507d5ee91396ab2
--- /dev/null
+++ b/packages/typescript-example/src/i18n/de/translation.json
@@ -0,0 +1,3 @@
+{
+  "hello-world": "Hallo Welt"
+}
diff --git a/packages/typescript-example/src/i18n/en/translation.json b/packages/typescript-example/src/i18n/en/translation.json
new file mode 100644
index 0000000000000000000000000000000000000000..29468fe3108dfb1acd2c7bf2953e150e0b02b40c
--- /dev/null
+++ b/packages/typescript-example/src/i18n/en/translation.json
@@ -0,0 +1,4 @@
+{
+    "hello-world": "Hello World"
+  }
+  
\ No newline at end of file
diff --git a/packages/typescript-example/src/index.ts b/packages/typescript-example/src/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dbcc5d08855225a2103a96b7577e266d84313012
--- /dev/null
+++ b/packages/typescript-example/src/index.ts
@@ -0,0 +1 @@
+// no content
\ No newline at end of file
diff --git a/packages/typescript-example/src/typescript-example.ts b/packages/typescript-example/src/typescript-example.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d57aff5b779c769d7d7b006aecadb8ea7b4aa86f
--- /dev/null
+++ b/packages/typescript-example/src/typescript-example.ts
@@ -0,0 +1,33 @@
+import {html,LitElement,property} from 'lit-element';
+import {i18n} from './i18n';
+
+export class TypeScriptExample extends LitElement {
+
+    private _i18n: any;
+
+    constructor() {
+        super();
+
+        this._i18n = i18n.cloneInstance();
+    }
+
+    @property({type: String})
+    lang = '';
+
+    update(changedProperties) {
+        changedProperties.forEach((oldValue, propName) => {
+            switch (propName) {
+                case "lang":
+                    this._i18n.changeLanguage(this.lang);
+                    break;
+            }
+        });
+        super.update(changedProperties);
+    }
+
+    render() {
+        return html`
+            <h3>${this._i18n.t('hello-world')}</h3>
+        `;
+    }
+}
\ No newline at end of file
diff --git a/packages/typescript-example/test/unit.ts b/packages/typescript-example/test/unit.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c487d54323d3dae48c564a10ce512be4e918af57
--- /dev/null
+++ b/packages/typescript-example/test/unit.ts
@@ -0,0 +1,21 @@
+import {assert} from 'chai';
+
+import '../src/dbp-typescript-example';
+
+suite('dbp-language-select basics', () => {
+  let node
+
+  setup(async () => {
+    node = document.createElement('dbp-typescript-example');
+    document.body.appendChild(node);
+    await node.updateComplete;
+  });
+
+  teardown(() => {
+    node.remove();
+  });
+
+  test('should render', () => {
+    assert.isNotNull(node.shadowRoot);
+  });
+});
\ No newline at end of file
diff --git a/packages/typescript-example/tsconfig.json b/packages/typescript-example/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..d33cea24ce38f4d54a45e14f302896bdd235c8be
--- /dev/null
+++ b/packages/typescript-example/tsconfig.json
@@ -0,0 +1,22 @@
+{
+  "compilerOptions": {
+    "target": "ESNext",
+    "module": "ESNext",
+    "lib": ["ESNext", "dom", "dom.iterable"],
+    "sourceMap": true,
+    "outDir": "./dist",
+    "rootDir": "./",
+    "moduleResolution": "node",
+    "experimentalDecorators": true,
+    "allowSyntheticDefaultImports": true,
+    "resolveJsonModule": true,
+    "plugins": [
+      {
+        "name": "ts-lit-plugin",
+        "strict": true
+      }
+    ]
+  },
+  "include": ["src/**/*.ts", "test/**/*.ts"],
+  "exclude": []
+}
\ No newline at end of file
diff --git a/demo/.gitignore b/toolkit-showcase/.gitignore
similarity index 100%
rename from demo/.gitignore
rename to toolkit-showcase/.gitignore
diff --git a/demo/README.md b/toolkit-showcase/README.md
similarity index 97%
rename from demo/README.md
rename to toolkit-showcase/README.md
index 01efd9d42b33b0a014d157e205618137993d24b8..65d449d3011c262c36ba94b267462650b98c7466 100644
--- a/demo/README.md
+++ b/toolkit-showcase/README.md
@@ -1,4 +1,4 @@
-# Frontend Toolkit Demo
+# Frontend Toolkit Showcase
 
 ## Setup
 
diff --git a/demo/assets/.htaccess.ejs b/toolkit-showcase/assets/.htaccess.ejs
similarity index 100%
rename from demo/assets/.htaccess.ejs
rename to toolkit-showcase/assets/.htaccess.ejs
diff --git a/demo/assets/Makefile b/toolkit-showcase/assets/Makefile
similarity index 100%
rename from demo/assets/Makefile
rename to toolkit-showcase/assets/Makefile
diff --git a/demo/assets/check-in-place-select.metadata.json b/toolkit-showcase/assets/check-in-place-select.metadata.json
similarity index 100%
rename from demo/assets/check-in-place-select.metadata.json
rename to toolkit-showcase/assets/check-in-place-select.metadata.json
diff --git a/demo/assets/common.metadata.json b/toolkit-showcase/assets/common.metadata.json
similarity index 100%
rename from demo/assets/common.metadata.json
rename to toolkit-showcase/assets/common.metadata.json
diff --git a/demo/assets/data-table-view.metadata.json b/toolkit-showcase/assets/data-table-view.metadata.json
similarity index 100%
rename from demo/assets/data-table-view.metadata.json
rename to toolkit-showcase/assets/data-table-view.metadata.json
diff --git a/demo/assets/dbp-toolkit-demo.html.ejs b/toolkit-showcase/assets/dbp-toolkit-showcase.html.ejs
similarity index 100%
rename from demo/assets/dbp-toolkit-demo.html.ejs
rename to toolkit-showcase/assets/dbp-toolkit-showcase.html.ejs
diff --git a/demo/assets/dbp-toolkit-demo.topic.metadata.json.ejs b/toolkit-showcase/assets/dbp-toolkit-showcase.topic.metadata.json.ejs
similarity index 83%
rename from demo/assets/dbp-toolkit-demo.topic.metadata.json.ejs
rename to toolkit-showcase/assets/dbp-toolkit-showcase.topic.metadata.json.ejs
index 9ce40533449ca6f0c93fa68815d258561f92759d..1d5236f9b5122863afc8805bee685d8783e83c77 100644
--- a/demo/assets/dbp-toolkit-demo.topic.metadata.json.ejs
+++ b/toolkit-showcase/assets/dbp-toolkit-showcase.topic.metadata.json.ejs
@@ -1,17 +1,17 @@
 {
   "name": {
-    "de": "Toolkit Demo",
-    "en": "Toolkit Demo"
+    "de": "Toolkit Showcase",
+    "en": "Toolkit Showcase"
   },
   "short_name": {
-    "de": "Toolkit Demo",
-    "en": "Toolkit Demo"
+    "de": "Toolkit Showcase",
+    "en": "Toolkit Showcase"
   },
   "description": {
     "de": "Mit dieser Applikation die Funktion der DBP Web Components testen",
     "en": "With this application you can test the function of the DBP web components"
   },
-  "routing_name": "toolkit-demo",
+  "routing_name": "toolkit-showcase",
   "activities": [
     {"path": "person-select.metadata.json"},
     {"path": "knowledge-base-web-page-element-view.metadata.json"},
diff --git a/demo/assets/file-handling.metadata.json b/toolkit-showcase/assets/file-handling.metadata.json
similarity index 100%
rename from demo/assets/file-handling.metadata.json
rename to toolkit-showcase/assets/file-handling.metadata.json
diff --git a/demo/assets/icon-192.png b/toolkit-showcase/assets/icon-192.png
similarity index 100%
rename from demo/assets/icon-192.png
rename to toolkit-showcase/assets/icon-192.png
diff --git a/demo/assets/icon-512.png b/toolkit-showcase/assets/icon-512.png
similarity index 100%
rename from demo/assets/icon-512.png
rename to toolkit-showcase/assets/icon-512.png
diff --git a/demo/assets/knowledge-base-web-page-element-view.metadata.json b/toolkit-showcase/assets/knowledge-base-web-page-element-view.metadata.json
similarity index 100%
rename from demo/assets/knowledge-base-web-page-element-view.metadata.json
rename to toolkit-showcase/assets/knowledge-base-web-page-element-view.metadata.json
diff --git a/demo/assets/language-select.metadata.json b/toolkit-showcase/assets/language-select.metadata.json
similarity index 100%
rename from demo/assets/language-select.metadata.json
rename to toolkit-showcase/assets/language-select.metadata.json
diff --git a/demo/assets/logo.svg b/toolkit-showcase/assets/logo.svg
similarity index 100%
rename from demo/assets/logo.svg
rename to toolkit-showcase/assets/logo.svg
diff --git a/demo/assets/manifest.json b/toolkit-showcase/assets/manifest.json
similarity index 51%
rename from demo/assets/manifest.json
rename to toolkit-showcase/assets/manifest.json
index 6e1b9c8a1e81cf59793c1b66ae4e738c23959034..ceb665e95345c5f4a69b726bd03d6fe74892e045 100644
--- a/demo/assets/manifest.json
+++ b/toolkit-showcase/assets/manifest.json
@@ -1,15 +1,15 @@
 {
-  "short_name": "Toolkit Demo",
-  "name": "Toolkit Demo",
-  "start_url": "./dbp-toolkit-demo.html",
+  "short_name": "Toolkit Showcase",
+  "name": "Toolkit Showcase",
+  "start_url": "./dbp-toolkit-showcase.html",
   "icons": [
     {
-      "src": "local/dbp-toolkit-demo/icon-192.png",
+      "src": "local/dbp-toolkit-showcase/icon-192.png",
       "type": "image/png",
       "sizes": "192x192"
     },
     {
-      "src": "local/dbp-toolkit-demo/icon-512.png",
+      "src": "local/dbp-toolkit-showcase/icon-512.png",
       "type": "image/png",
       "sizes": "512x512"
     }
diff --git a/demo/assets/matomo.metadata.json b/toolkit-showcase/assets/matomo.metadata.json
similarity index 100%
rename from demo/assets/matomo.metadata.json
rename to toolkit-showcase/assets/matomo.metadata.json
diff --git a/demo/assets/notification.metadata.json b/toolkit-showcase/assets/notification.metadata.json
similarity index 100%
rename from demo/assets/notification.metadata.json
rename to toolkit-showcase/assets/notification.metadata.json
diff --git a/demo/assets/person-profile.metadata.json b/toolkit-showcase/assets/person-profile.metadata.json
similarity index 100%
rename from demo/assets/person-profile.metadata.json
rename to toolkit-showcase/assets/person-profile.metadata.json
diff --git a/demo/assets/person-select.metadata.json b/toolkit-showcase/assets/person-select.metadata.json
similarity index 100%
rename from demo/assets/person-select.metadata.json
rename to toolkit-showcase/assets/person-select.metadata.json
diff --git a/demo/assets/qr-code-scanner.metadata.json b/toolkit-showcase/assets/qr-code-scanner.metadata.json
similarity index 100%
rename from demo/assets/qr-code-scanner.metadata.json
rename to toolkit-showcase/assets/qr-code-scanner.metadata.json
diff --git a/demo/assets/silent-check-sso.html b/toolkit-showcase/assets/silent-check-sso.html
similarity index 100%
rename from demo/assets/silent-check-sso.html
rename to toolkit-showcase/assets/silent-check-sso.html
diff --git a/toolkit-showcase/deploy.php b/toolkit-showcase/deploy.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab2a3619b83567a69e924913facec50c37b168fe
--- /dev/null
+++ b/toolkit-showcase/deploy.php
@@ -0,0 +1,68 @@
+<?php
+namespace Deployer;
+
+require 'recipe/common.php';
+require 'recipe/rsync.php';
+
+// Global config
+set('allow_anonymous_stats', false);
+
+set('rsync',[
+    'exclude'      => [
+        '.git',
+        'deploy.php',
+    ],
+    'exclude-file' => false,
+    'include'      => [],
+    'include-file' => false,
+    'filter'       => [],
+    'filter-file'  => false,
+    'filter-perdir'=> false,
+    'flags'        => 'rz',
+    'options'      => ['delete'],
+    'timeout'      => 60,
+]);
+
+set('rsync_src', __DIR__ . '/dist');
+set('rsync_dest','{{release_path}}');
+
+// Hosts
+host('demo')
+    ->stage('demo')
+    ->hostname('mw@mw01-dev.tugraz.at')
+    ->set('deploy_path', '/home/mw/demo/deploy/apps/demo');
+
+host('development')
+    ->stage('development')
+    ->hostname('mw@mw01-dev.tugraz.at')
+    ->set('deploy_path', '/home/mw/dev/deploy/apps/demo');
+
+// Demo build task
+task('build-demo', function () {
+    runLocally("yarn install");
+    runLocally("yarn run build-demo");
+})->onStage('demo');
+
+// Demo dev task
+task('build-development', function () {
+    runLocally("yarn install");
+    runLocally("yarn run build-dev");
+})->onStage('development');
+
+
+// Deploy task
+task('deploy', [
+    'deploy:info',
+    'build-demo',
+    'build-development',
+    'deploy:prepare',
+    'deploy:lock',
+    'deploy:release',
+    'rsync',
+    'deploy:shared',
+    'deploy:symlink',
+    'deploy:unlock',
+    'cleanup',
+    'success',
+]);
+after('deploy:failed', 'deploy:unlock');
diff --git a/demo/package.json b/toolkit-showcase/package.json
similarity index 97%
rename from demo/package.json
rename to toolkit-showcase/package.json
index 850d3ec84a6963ab86186b6f888f3c2153630b01..44a702b608da31331df6e5737b0c9190e4239050 100644
--- a/demo/package.json
+++ b/toolkit-showcase/package.json
@@ -1,7 +1,7 @@
 {
-  "name": "dbp-toolkit-demo",
+  "name": "dbp-toolkit-showcase",
   "version": "0.1.0",
-  "main": "src/toolkit-demo.js",
+  "main": "src/toolkit-showcase.js",
   "license": "LGPL-2.1-or-later",
   "private": true,
   "workspaces": [
diff --git a/demo/rollup.config.js b/toolkit-showcase/rollup.config.js
similarity index 93%
rename from demo/rollup.config.js
rename to toolkit-showcase/rollup.config.js
index 2f09787a6f41d04d5f9269728fb27fb8ccd8c83e..f8b3eb6803550425043731ab5d8e3f1000d0e6c2 100644
--- a/demo/rollup.config.js
+++ b/toolkit-showcase/rollup.config.js
@@ -62,7 +62,7 @@ switch (build) {
     pdfAsQualifiedlySigningServer = 'sig-dev.tugraz.at';
     break;
   case 'development':
-    basePath = '/apps/toolkit-demo/';
+    basePath = '/apps/demo/';
     entryPointURL = 'https://mw-dev.tugraz.at';
     // "/pers" can't go here because it's not allowed in the "Content-Security-Policy"
     nextcloudBaseURL = 'https://nc-dev.tugraz.at';
@@ -71,9 +71,23 @@ switch (build) {
     nextcloudWebDavURL = nextcloudBaseURL + '/pers/remote.php/dav/files';
     keyCloakServer = 'auth-dev.tugraz.at';
     keyCloakBaseURL = 'https://' + keyCloakServer + '/auth';
+    keyCloakClientId = 'demo-dev_tugraz_at-DEMO';
+    pdfAsQualifiedlySigningServer = 'sig-dev.tugraz.at';
+    break;
+  case 'demo':
+    basePath = '/apps/demo/';
+    entryPointURL = 'https://api-demo.tugraz.at';
+    // "/pers" can't go here because it's not allowed in the "Content-Security-Policy"
+    nextcloudBaseURL = 'https://nc-dev.tugraz.at';
+    // "/index.php" is needed to don't get a "This origin is not allowed!" because the "target-origin" get parameter can't be read
+    nextcloudWebAppPasswordURL = nextcloudBaseURL + '/pers/index.php/apps/webapppassword';
+    nextcloudWebDavURL = nextcloudBaseURL + '/pers/remote.php/dav/files';
+    keyCloakServer = 'auth-test.tugraz.at';
+    keyCloakBaseURL = 'https://' + keyCloakServer + '/auth';
     keyCloakClientId = 'auth-dev-mw-frontend';
     pdfAsQualifiedlySigningServer = 'sig-dev.tugraz.at';
     break;
+
   default:
     console.error('Unknown build environment: ' + build);
     process.exit(1);
@@ -206,7 +220,7 @@ Dependencies:
 `},
           thirdParty: {
             allow: {
-              test: '(MIT OR BSD-3-Clause OR Apache-2.0 OR LGPL-2.1-or-later)',
+              test: '(MIT OR BSD-3-Clause OR Apache-2.0 OR LGPL-2.1-or-later OR 0BSD)',
               failOnUnlicensed: true,
               failOnViolation: true,
             },
diff --git a/toolkit-showcase/src/dbp-check-in-place-select-demo-activity.js b/toolkit-showcase/src/dbp-check-in-place-select-demo-activity.js
new file mode 100644
index 0000000000000000000000000000000000000000..00d009a1861eebfd87685a7870bd30e46f44770e
--- /dev/null
+++ b/toolkit-showcase/src/dbp-check-in-place-select-demo-activity.js
@@ -0,0 +1,57 @@
+import {css, html, LitElement} from 'lit-element';
+import {ScopedElementsMixin} from '@open-wc/scoped-elements';
+import {CheckInPlaceSelectDemo} from '@dbp-toolkit/check-in-place-select/src/dbp-check-in-place-select-demo';
+import * as commonUtils from '@dbp-toolkit/common/utils';
+import * as commonStyles from '@dbp-toolkit/common/styles';
+import {unsafeHTML} from 'lit-html/directives/unsafe-html.js';
+import readme from '@dbp-toolkit/check-in-place-select/README.md';
+import highlightCSSPath from 'highlight.js/styles/default.css';
+import * as demoStyles from "./styles";
+
+class DbpActivityNameDemoActivity extends ScopedElementsMixin(LitElement) {
+    static get scopedElements() {
+        return {
+            'dbp-check-in-place-select-demo': CheckInPlaceSelectDemo,
+        };
+    }
+
+    static get properties() {
+        return {
+        };
+    }
+
+    connectedCallback() {
+        super.connectedCallback();
+
+        this.updateComplete.then(()=>{
+        });
+    }
+
+    static get styles() {
+        // language=css
+        return [
+            commonStyles.getThemeCSS(),
+            commonStyles.getGeneralCSS(),
+            demoStyles.getDemoCSS(),
+            css`
+            h1.title {margin-bottom: 1em;}
+            div.container {margin-bottom: 1.5em;}
+
+            #demo{
+                display: block;
+                padding-top: 50px;
+            }
+            
+            `
+        ];
+    }
+
+    render() {
+        return html`                
+                ${unsafeHTML(readme)}
+                <dbp-check-in-place-select-demo id="demo" lang="en" no-auth></dbp-check-in-place-select-demo>
+        `;
+    }
+}
+
+commonUtils.defineCustomElement('dbp-check-in-place-select-demo-activity', DbpActivityNameDemoActivity);
diff --git a/demo/src/dbp-common-demo-activity.js b/toolkit-showcase/src/dbp-common-demo-activity.js
similarity index 100%
rename from demo/src/dbp-common-demo-activity.js
rename to toolkit-showcase/src/dbp-common-demo-activity.js
diff --git a/demo/src/dbp-data-table-view-demo-activity.js b/toolkit-showcase/src/dbp-data-table-view-demo-activity.js
similarity index 94%
rename from demo/src/dbp-data-table-view-demo-activity.js
rename to toolkit-showcase/src/dbp-data-table-view-demo-activity.js
index cbde21a7100201790c5af690576e08b51f665d86..8d723ef2895d0aee70ee8d0347ced5750a337dc0 100644
--- a/demo/src/dbp-data-table-view-demo-activity.js
+++ b/toolkit-showcase/src/dbp-data-table-view-demo-activity.js
@@ -50,7 +50,7 @@ class DbpActivityNameDemoActivity extends ScopedElementsMixin(LitElement) { //TO
         return html`
 
                 ${unsafeHTML(readme)}
-                <dbp-data-table-view-demo id="demo" lang="en"></dbp-data-table-view-demo>
+                <dbp-data-table-view-demo id="demo" lang="en" no-auth></dbp-data-table-view-demo>
         `;
     }
 }
diff --git a/demo/src/dbp-demo-template.js b/toolkit-showcase/src/dbp-demo-template.js
similarity index 100%
rename from demo/src/dbp-demo-template.js
rename to toolkit-showcase/src/dbp-demo-template.js
diff --git a/demo/src/dbp-file-handling-demo-activity.js b/toolkit-showcase/src/dbp-file-handling-demo-activity.js
similarity index 100%
rename from demo/src/dbp-file-handling-demo-activity.js
rename to toolkit-showcase/src/dbp-file-handling-demo-activity.js
diff --git a/demo/src/dbp-knowledge-base-web-page-element-view-demo-activity.js b/toolkit-showcase/src/dbp-knowledge-base-web-page-element-view-demo-activity.js
similarity index 95%
rename from demo/src/dbp-knowledge-base-web-page-element-view-demo-activity.js
rename to toolkit-showcase/src/dbp-knowledge-base-web-page-element-view-demo-activity.js
index 26e7aa9c35dab393f6cdd47a95cb25fc7676f870..f7549313d520c86918a95b6947ca70050bfeb604 100644
--- a/demo/src/dbp-knowledge-base-web-page-element-view-demo-activity.js
+++ b/toolkit-showcase/src/dbp-knowledge-base-web-page-element-view-demo-activity.js
@@ -49,7 +49,7 @@ class KnowledgeBaseWebPageElementViewDemoActivity extends ScopedElementsMixin(Li
     render() {
         return html`
                 ${unsafeHTML(readme)}
-                <dbp-knowledge-base-web-page-element-view-demo id="demo" lang="en"></dbp-knowledge-base-web-page-element-view-demo>
+                <dbp-knowledge-base-web-page-element-view-demo id="demo" lang="en" no-auth></dbp-knowledge-base-web-page-element-view-demo>
         `;
     }
 }
diff --git a/demo/src/dbp-language-select-demo-activity.js b/toolkit-showcase/src/dbp-language-select-demo-activity.js
similarity index 100%
rename from demo/src/dbp-language-select-demo-activity.js
rename to toolkit-showcase/src/dbp-language-select-demo-activity.js
diff --git a/demo/src/dbp-matomo-demo-activity.js b/toolkit-showcase/src/dbp-matomo-demo-activity.js
similarity index 92%
rename from demo/src/dbp-matomo-demo-activity.js
rename to toolkit-showcase/src/dbp-matomo-demo-activity.js
index 4a99489577825b8f9e485aad2c1d417a16df742e..07a3b648f640ff4ca27f7068c2ec5acd4715f069 100644
--- a/demo/src/dbp-matomo-demo-activity.js
+++ b/toolkit-showcase/src/dbp-matomo-demo-activity.js
@@ -48,8 +48,8 @@ class DbpMatomoDemoActivity extends ScopedElementsMixin(LitElement) {
 
     render() {
         return html`
-               ${unsafeHTML(readme)}
-                <dbp-matomo-demo id="demo" lang="en"></dbp-matomo-demo>
+               ${unsafeHTML(readme)} 
+                <dbp-matomo-demo id="demo" lang="en" no-auth></dbp-matomo-demo>
         `;
     }
 }
diff --git a/demo/src/dbp-notification-demo-activity.js b/toolkit-showcase/src/dbp-notification-demo-activity.js
similarity index 100%
rename from demo/src/dbp-notification-demo-activity.js
rename to toolkit-showcase/src/dbp-notification-demo-activity.js
diff --git a/demo/src/dbp-person-profile-demo-activity.js b/toolkit-showcase/src/dbp-person-profile-demo-activity.js
similarity index 94%
rename from demo/src/dbp-person-profile-demo-activity.js
rename to toolkit-showcase/src/dbp-person-profile-demo-activity.js
index dcb570acfa230c221afc9a526501d1770ee2dfac..715a1ac53babb462a395d0e2bd620bf9a5b5f91b 100644
--- a/demo/src/dbp-person-profile-demo-activity.js
+++ b/toolkit-showcase/src/dbp-person-profile-demo-activity.js
@@ -49,7 +49,7 @@ class DbpPersonProfileDemoActivity extends ScopedElementsMixin(LitElement) {
     render() {
         return html`
                 ${unsafeHTML(readme)}
-                <dbp-person-profile-demo id="demo" lang="en"></dbp-person-profile-demo>
+                <dbp-person-profile-demo id="demo" lang="en" no-auth></dbp-person-profile-demo>
 
         `;
     }
diff --git a/demo/src/dbp-person-select-demo-activity.js b/toolkit-showcase/src/dbp-person-select-demo-activity.js
similarity index 94%
rename from demo/src/dbp-person-select-demo-activity.js
rename to toolkit-showcase/src/dbp-person-select-demo-activity.js
index a0bb3dc307813e12dc84fb387f35c53527b4b511..41ffb9bb71dea1d4ee2fa72cc6707cbefb581af8 100644
--- a/demo/src/dbp-person-select-demo-activity.js
+++ b/toolkit-showcase/src/dbp-person-select-demo-activity.js
@@ -49,7 +49,7 @@ class DbpPersonSelectDemoActivity extends ScopedElementsMixin(LitElement) {
     render() {
         return html`
             ${unsafeHTML(readme)}
-            <dbp-person-select-demo id="demo" lang="en"></dbp-person-select-demo>
+            <dbp-person-select-demo id="demo" lang="en" no-auth></dbp-person-select-demo>
         `;
     }
 }
diff --git a/demo/src/dbp-qr-code-scanner-demo-activity.js b/toolkit-showcase/src/dbp-qr-code-scanner-demo-activity.js
similarity index 100%
rename from demo/src/dbp-qr-code-scanner-demo-activity.js
rename to toolkit-showcase/src/dbp-qr-code-scanner-demo-activity.js
diff --git a/demo/src/dbp-toolkit-demo.js b/toolkit-showcase/src/dbp-toolkit-showcase.js
similarity index 61%
rename from demo/src/dbp-toolkit-demo.js
rename to toolkit-showcase/src/dbp-toolkit-showcase.js
index 42a9c8bb9f6f86d19a653bfcd1ffd92ce46d5a33..89c224bbe6053071aa7471c359d34a10ab82f2b7 100644
--- a/demo/src/dbp-toolkit-demo.js
+++ b/toolkit-showcase/src/dbp-toolkit-showcase.js
@@ -1,4 +1,4 @@
 import {AppShell} from '@dbp-toolkit/app-shell';
 import * as commonUtils from '@dbp-toolkit/common/utils';
 
-commonUtils.defineCustomElement('dbp-toolkit-demo', AppShell);
+commonUtils.defineCustomElement('dbp-toolkit-showcase', AppShell);
diff --git a/demo/src/styles.js b/toolkit-showcase/src/styles.js
similarity index 100%
rename from demo/src/styles.js
rename to toolkit-showcase/src/styles.js
diff --git a/demo/yarn.lock b/toolkit-showcase/yarn.lock
similarity index 100%
rename from demo/yarn.lock
rename to toolkit-showcase/yarn.lock
diff --git a/yarn.lock b/yarn.lock
index 04cf9db946227329677791a1ba40c348c78a0d2d..7a521a20b0541803d8f0d427334206f4eee79c13 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -60,7 +60,7 @@
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.5.tgz#b4af32ddd473c0bfa643bd7ff0728b8e71b81ea0"
   integrity sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==
 
-"@babel/runtime@^7.12.0":
+"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.0":
   version "7.12.5"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e"
   integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==
@@ -1181,6 +1181,11 @@
   resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
   integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==
 
+"@types/mocha@^8.2.0":
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.0.tgz#3eb56d13a1de1d347ecb1957c6860c911704bc44"
+  integrity sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ==
+
 "@types/node@*":
   version "14.14.8"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.8.tgz#2127bd81949a95c8b7d3240f3254352d72563aec"
@@ -2852,6 +2857,15 @@ di@^0.0.1:
   resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
   integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=
 
+didyoumean2@4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/didyoumean2/-/didyoumean2-4.1.0.tgz#f813cb7c82c249443e599be077f76e88f24b85e4"
+  integrity sha512-qTBmfQoXvhKO75D/05C8m+fteQmn4U46FWYiLhXtZQInzitXLWY0EQ/2oKnpAz9g2lQWW8jYcLcT+hPJGT+kig==
+  dependencies:
+    "@babel/runtime" "^7.10.2"
+    leven "^3.1.0"
+    lodash.deburr "^4.1.0"
+
 diff@4.0.2:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
@@ -3517,6 +3531,15 @@ finalhandler@1.1.2:
     statuses "~1.5.0"
     unpipe "~1.0.0"
 
+find-cache-dir@^3.3.1:
+  version "3.3.1"
+  resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880"
+  integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==
+  dependencies:
+    commondir "^1.0.1"
+    make-dir "^3.0.2"
+    pkg-dir "^4.1.0"
+
 find-up@5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
@@ -3547,7 +3570,7 @@ find-up@^3.0.0:
   dependencies:
     locate-path "^3.0.0"
 
-find-up@^4.1.0:
+find-up@^4.0.0, find-up@^4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
   integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
@@ -3621,7 +3644,7 @@ from2@^2.1.0:
     inherits "^2.0.1"
     readable-stream "^2.0.0"
 
-fs-extra@^8.1.0:
+fs-extra@8.1.0, fs-extra@^8.1.0:
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
   integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
@@ -4986,6 +5009,11 @@ lerna@^3.22.1:
     import-local "^2.0.0"
     npmlog "^4.1.2"
 
+leven@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
+  integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
+
 levn@^0.4.1:
   version "0.4.1"
   resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
@@ -5006,6 +5034,20 @@ lines-and-columns@^1.1.6:
   resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
   integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
 
+lit-analyzer@1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/lit-analyzer/-/lit-analyzer-1.2.1.tgz#725331a4019ae870dd631d4dd709d39a237161ea"
+  integrity sha512-OEARBhDidyaQENavLbzpTKbEmu5rnAI+SdYsH4ia1BlGlLiqQXoym7uH1MaRPtwtUPbkhUfT4OBDZ+74VHc3Cg==
+  dependencies:
+    chalk "^2.4.2"
+    didyoumean2 "4.1.0"
+    fast-glob "^2.2.6"
+    parse5 "5.1.0"
+    ts-simple-type "~1.0.5"
+    vscode-css-languageservice "4.3.0"
+    vscode-html-languageservice "3.1.0"
+    web-component-analyzer "~1.1.1"
+
 lit-element@^2.1.0, lit-element@^2.3.1:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-2.4.0.tgz#b22607a037a8fc08f5a80736dddf7f3f5d401452"
@@ -5104,6 +5146,11 @@ lodash.clonedeep@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
   integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
 
+lodash.deburr@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/lodash.deburr/-/lodash.deburr-4.1.0.tgz#ddb1bbb3ef07458c0177ba07de14422cb033ff9b"
+  integrity sha1-3bG7s+8HRYwBd7oH3hRCLLAz/5s=
+
 lodash.get@^4.4.2:
   version "4.4.2"
   resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
@@ -5221,7 +5268,7 @@ make-dir@^2.1.0:
     pify "^4.0.1"
     semver "^5.6.0"
 
-make-dir@^3.0.0:
+make-dir@^3.0.0, make-dir@^3.0.2:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
   integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
@@ -6144,6 +6191,11 @@ parse-url@^5.0.0:
     parse-path "^4.0.0"
     protocols "^1.4.0"
 
+parse5@5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2"
+  integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==
+
 parse5@^6.0.0:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
@@ -6310,6 +6362,13 @@ pkg-dir@^3.0.0:
   dependencies:
     find-up "^3.0.0"
 
+pkg-dir@^4.1.0:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
+  integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
+  dependencies:
+    find-up "^4.0.0"
+
 posix-character-classes@^0.1.0:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
@@ -7113,6 +7172,13 @@ resolve-url@^0.2.1:
   resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
   integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
 
+resolve@1.17.0:
+  version "1.17.0"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
+  integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
+  dependencies:
+    path-parse "^1.0.6"
+
 resolve@^1.10.0, resolve@^1.12.0, resolve@^1.16.1, resolve@^1.17.0:
   version "1.19.0"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c"
@@ -7251,6 +7317,17 @@ rollup-plugin-terser@^7.0.2:
     serialize-javascript "^4.0.0"
     terser "^5.0.0"
 
+rollup-plugin-typescript2@^0.29.0:
+  version "0.29.0"
+  resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.29.0.tgz#b7ad83f5241dbc5bdf1e98d9c3fca005ffe39e1a"
+  integrity sha512-YytahBSZCIjn/elFugEGQR5qTsVhxhUwGZIsA9TmrSsC88qroGo65O5HZP/TTArH2dm0vUmYWhKchhwi2wL9bw==
+  dependencies:
+    "@rollup/pluginutils" "^3.1.0"
+    find-cache-dir "^3.3.1"
+    fs-extra "8.1.0"
+    resolve "1.17.0"
+    tslib "2.0.1"
+
 rollup-pluginutils@^2.8.2:
   version "2.8.2"
   resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
@@ -8174,12 +8251,29 @@ trim-off-newlines@^1.0.0:
   resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3"
   integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM=
 
+ts-lit-plugin@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/ts-lit-plugin/-/ts-lit-plugin-1.2.1.tgz#7fca17a454645c14911917fa7f17ade582fa3056"
+  integrity sha512-k/Me+aT1N9ckC/KuJCAlAJgCHFezOxuOGOzBE0q42xnKbJnUMNl08WqWF6C7OKecCPHIMRk5Wj5o6MDsmt9+qA==
+  dependencies:
+    lit-analyzer "1.2.1"
+
+ts-simple-type@~1.0.5:
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/ts-simple-type/-/ts-simple-type-1.0.7.tgz#03930af557528dd40eaa121913c7035a0baaacf8"
+  integrity sha512-zKmsCQs4dZaeSKjEA7pLFDv7FHHqAFLPd0Mr//OIJvu8M+4p4bgSFJwZSEBEg3ec9W7RzRz1vi8giiX0+mheBQ==
+
+tslib@2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e"
+  integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==
+
 tslib@^1.9.0, tslib@^1.9.3:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
   integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
 
-tslib@^2.0.0:
+tslib@^2.0.0, tslib@^2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c"
   integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==
@@ -8241,6 +8335,16 @@ typedarray@^0.0.6:
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
   integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
+typescript@^3.8.3:
+  version "3.9.7"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa"
+  integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==
+
+typescript@^4.1.2:
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9"
+  integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==
+
 ua-parser-js@0.7.22:
   version "0.7.22"
   resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.22.tgz#960df60a5f911ea8f1c818f3747b99c6e177eae3"
@@ -8509,6 +8613,46 @@ void-elements@^2.0.0:
   resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
   integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
 
+vscode-css-languageservice@4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.3.0.tgz#40c797d664ab6188cace33cfbb19b037580a9318"
+  integrity sha512-BkQAMz4oVHjr0oOAz5PdeE72txlLQK7NIwzmclfr+b6fj6I8POwB+VoXvrZLTbWt9hWRgfvgiQRkh5JwrjPJ5A==
+  dependencies:
+    vscode-languageserver-textdocument "^1.0.1"
+    vscode-languageserver-types "3.16.0-next.2"
+    vscode-nls "^4.1.2"
+    vscode-uri "^2.1.2"
+
+vscode-html-languageservice@3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-3.1.0.tgz#265b53bda595e6947b16b0fb8c604e1e58685393"
+  integrity sha512-QAyRHI98bbEIBCqTzZVA0VblGU40na0txggongw5ZgTj9UVsVk5XbLT16O9OTcbqBGSqn0oWmFDNjK/XGIDcqg==
+  dependencies:
+    vscode-languageserver-textdocument "^1.0.1"
+    vscode-languageserver-types "3.16.0-next.2"
+    vscode-nls "^4.1.2"
+    vscode-uri "^2.1.2"
+
+vscode-languageserver-textdocument@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz#178168e87efad6171b372add1dea34f53e5d330f"
+  integrity sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==
+
+vscode-languageserver-types@3.16.0-next.2:
+  version "3.16.0-next.2"
+  resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.2.tgz#940bd15c992295a65eae8ab6b8568a1e8daa3083"
+  integrity sha512-QjXB7CKIfFzKbiCJC4OWC8xUncLsxo19FzGVp/ADFvvi87PlmBSCAtZI5xwGjF5qE0xkLf0jjKUn3DzmpDP52Q==
+
+vscode-nls@^4.1.2:
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167"
+  integrity sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==
+
+vscode-uri@^2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c"
+  integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==
+
 wcwidth@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
@@ -8516,6 +8660,16 @@ wcwidth@^1.0.0:
   dependencies:
     defaults "^1.0.3"
 
+web-component-analyzer@~1.1.1:
+  version "1.1.6"
+  resolved "https://registry.yarnpkg.com/web-component-analyzer/-/web-component-analyzer-1.1.6.tgz#d9bd904d904a711c19ba6046a45b60a7ee3ed2e9"
+  integrity sha512-1PyBkb/jijDEVE+Pnk3DTmVHD8takipdvAwvZv1V8jIidsSIJ5nhN87Gs+4dpEb1vw48yp8dnbZKkvMYJ+C0VQ==
+  dependencies:
+    fast-glob "^3.2.2"
+    ts-simple-type "~1.0.5"
+    typescript "^3.8.3"
+    yargs "^15.3.1"
+
 webdav@^3.6.1:
   version "3.6.1"
   resolved "https://registry.yarnpkg.com/webdav/-/webdav-3.6.1.tgz#ab01f8067faf748abe3938720dcaeb39836d78e3"