update odlux and featureaggregator

v2 update odlux and featureaggregator bundles

Issue-ID: SDNC-1008
Signed-off-by: herbert <herbert.eiselt@highstreet-technologies.com>
Change-Id: I0018d7bfa3a0e6896c1b210b539a574af9808e22
Signed-off-by: herbert <herbert.eiselt@highstreet-technologies.com>
diff --git a/sdnr/wt/odlux/framework/.babelrc b/sdnr/wt/odlux/framework/.babelrc
new file mode 100644
index 0000000..3d8cd12
--- /dev/null
+++ b/sdnr/wt/odlux/framework/.babelrc
@@ -0,0 +1,17 @@
+{
+  "presets": [
+    ["@babel/preset-react"],
+    ["@babel/preset-env", {
+      "targets": {
+        "chrome": "66"
+      },
+      "spec": true,
+      "loose": false,
+      "modules": false,
+      "debug": false,
+      "useBuiltIns": "usage",
+      "forceAllTransforms": true
+    }]
+  ],
+  "plugins": []
+}
diff --git a/sdnr/wt/odlux/framework/LICENSE b/sdnr/wt/odlux/framework/LICENSE
new file mode 100644
index 0000000..3556ffa
--- /dev/null
+++ b/sdnr/wt/odlux/framework/LICENSE
@@ -0,0 +1,13 @@
+/*
+ * ============LICENSE_START=============================================================================================================
+ * Copyright (c) 2018 highstreet-technolgies.
+ * ===================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * ============LICENSE_END===============================================================================================================
+ * 
+ */
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/package.json b/sdnr/wt/odlux/framework/package.json
new file mode 100644
index 0000000..d0fe49b
--- /dev/null
+++ b/sdnr/wt/odlux/framework/package.json
@@ -0,0 +1,49 @@
+{

+  "name": "@odlux/framework",

+  "version": "0.1.4",

+  "description": "A react based modular UI framework",

+  "main": "index.js",

+  "scripts": {

+    "start": "webpack-dev-server --env debug",

+    "prebuild": "rimraf dist",

+    "build": "webpack --env release --config webpack.vendor.js && webpack --env release --config webpack.config.js && webpack --env release --config webpack.runner.js",

+    "build:run": "webpack --env release --config webpack.runner.js",

+    "build:dev": "webpack --env debug --config webpack.config.js",

+    "vendor:dev": "webpack --env debug --config webpack.vendor.js"

+  },

+  "repository": {

+    "type": "git",

+    "url": "https://git.mfico.de/highstreet-technologies/odlux.git"

+  },

+  "keywords": [

+    "reactjs",

+    "redux",

+    "ui",

+    "framework"

+  ],

+  "author": "Matthias Fischer",

+  "license": "Apache-2.0",

+  "peerDependencies": {

+    "@types/node": "11.9.5",

+    "@types/react": "16.9.11",

+    "@types/react-dom": "16.9.4",

+    "@types/react-router-dom": "4.3.1",

+    "@material-ui/core": "4.6.1",

+    "@material-ui/icons": "4.5.1",

+    "@types/classnames": "2.2.6",

+    "@types/flux": "3.1.8",

+    "@types/jquery": "3.3.10",

+    "jquery": "3.3.1",

+    "react": "16.11.0",

+    "react-dom": "16.11.0",

+    "react-router-dom": "4.3.1",

+    "@fortawesome/react-fontawesome": "0.1.3",

+    "@fortawesome/fontawesome-svg-core": "1.2.12",

+    "@fortawesome/free-solid-svg-icons": "5.6.3",

+    "jsonwebtoken": "8.3.0",

+    "@types/jsonwebtoken": "7.2.8"

+  },

+  "dependencies": {

+    "http-server": "^0.11.1"

+  }

+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/pom.xml b/sdnr/wt/odlux/framework/pom.xml
new file mode 100644
index 0000000..4671017
--- /dev/null
+++ b/sdnr/wt/odlux/framework/pom.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" 
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+	<parent>
+		<groupId>org.onap.ccsdk.parent</groupId>
+		<artifactId>odlparent</artifactId>
+		<version>1.5.1-SNAPSHOT</version>
+		<relativePath/>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.onap.ccsdk.features.sdnr.wt</groupId>
+	<artifactId>sdnr-wt-odlux-framework</artifactId>
+	<version>0.7.0-SNAPSHOT</version>
+	<packaging>jar</packaging>
+	<name>sdnr-wt-odlux-framework</name>
+	<properties>
+		<buildtime>${maven.build.timestamp}</buildtime>
+		<distversion>ONAP Frankfurt (Neon, mdsal ${odl.mdsal.version})</distversion>
+		<buildno>36.1a30021(19/12/12)</buildno>
+		<odlux.version>ONAP SDN-R | ONF Wireless for ${distversion} - Build: ${buildtime} ${buildno} ${project.version}</odlux.version>
+	</properties>
+	<licenses>
+		<license>
+			<name>Apache License, Version 2.0</name>
+			<url>http://www.apache.org/licenses/LICENSE-2.0</url>
+		</license>
+	</licenses>
+
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-clean-plugin</artifactId>
+				<configuration>
+					<filesets>
+						<fileset>
+							<directory>dist</directory>
+							<followSymlinks>false</followSymlinks>
+						</fileset>
+						<fileset>
+							<directory>node</directory>
+							<followSymlinks>false</followSymlinks>
+						</fileset>
+						<fileset>
+							<directory>node_modules</directory>
+							<followSymlinks>false</followSymlinks>
+						</fileset>
+						<fileset>
+							<directory>../node_modules</directory>
+							<followSymlinks>false</followSymlinks>
+						</fileset>
+						<!-- eclipse bug build bin folder in basedir -->
+						<fileset>
+							<directory>bin</directory>
+							<followSymlinks>false</followSymlinks>
+						</fileset>
+					</filesets>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>de.jacks-it-lab</groupId>
+				<artifactId>frontend-maven-plugin</artifactId>
+				<version>1.7.1</version>
+				<executions>
+					<execution>
+						<id>install node and yarn</id>
+						<goals>
+							<goal>install-node-and-yarn</goal>
+						</goals>
+						<!-- optional: default phase is "generate-resources" -->
+						<phase>initialize</phase>
+						<configuration>
+							<nodeVersion>v10.16.3</nodeVersion>
+							<yarnVersion>v1.19.0</yarnVersion>
+						</configuration>
+					</execution>
+					<execution>
+						<id>clear cache</id>
+						<goals>
+							<goal>yarn</goal>
+						</goals>
+						<phase>initialize</phase>
+						<configuration>
+							<arguments>cache clean</arguments>
+							<installDirectory>${project.basedir}</installDirectory>
+							<workingDirectory>${project.basedir}/../</workingDirectory>
+						</configuration>
+					</execution>
+					<execution>
+						<id>install lerna</id>
+						<goals>
+							<goal>yarn</goal>
+						</goals>
+						<phase>initialize</phase>
+						<configuration>
+							<arguments>add lerna@3.13.1 -W --exact</arguments>
+							<installDirectory>${project.basedir}</installDirectory>
+							<workingDirectory>${project.basedir}/../</workingDirectory>
+						</configuration>
+					</execution>
+					<execution>
+						<id>exec lerna bootstrap</id>
+						<goals>
+							<goal>lerna</goal>
+						</goals>
+						<phase>initialize</phase>
+						<configuration>
+							<lernaInheritsProxyConfigFromMaven>false</lernaInheritsProxyConfigFromMaven>
+							<arguments>bootstrap</arguments>
+							<installDirectory>${project.basedir}</installDirectory>
+							<workingDirectory>${project.basedir}/../</workingDirectory>
+						</configuration>
+					</execution>
+					<execution>
+						<id>yarn build</id>
+						<goals>
+							<goal>yarn</goal>
+						</goals>
+						<configuration>
+							<arguments>run build</arguments>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>com.google.code.maven-replacer-plugin</groupId>
+				<artifactId>replacer</artifactId>
+				<version>1.5.2</version>
+				<executions>
+					<execution>
+						<id>replace version</id>
+						<phase>prepare-package</phase>
+						<goals>
+							<goal>replace</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<basedir>${project.build.directory}/classes/odlux</basedir>
+					<includes>
+						<include>app.js</include>
+					</includes>
+					<replacements>
+						<replacement>
+							<token>##odlux.version##</token>
+							<value>${odlux.version}</value>
+						</replacement>
+					</replacements>
+				</configuration>
+			</plugin>
+		</plugins>
+		<resources>
+			<resource>
+				<directory>dist</directory>
+				<targetPath>odlux</targetPath>
+			</resource>
+		</resources>
+	</build>
+</project>
diff --git a/sdnr/wt/odlux/framework/src/actions/authentication.ts b/sdnr/wt/odlux/framework/src/actions/authentication.ts
new file mode 100644
index 0000000..b281000
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/actions/authentication.ts
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action } from '../flux/action';
+import { AuthToken } from '../models/authentication';
+
+export class UpdateAuthentication extends Action {
+
+  constructor (public bearerToken: AuthToken | null) {
+    super();
+  }
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/actions/errorActions.ts b/sdnr/wt/odlux/framework/src/actions/errorActions.ts
new file mode 100644
index 0000000..ddb0d57
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/actions/errorActions.ts
@@ -0,0 +1,42 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action } from '../flux/action';
+
+import { ErrorInfo } from '../models/errorInfo';
+export { ErrorInfo } from '../models/errorInfo';
+
+export class AddErrorInfoAction extends Action {
+
+  constructor(public errorInfo: ErrorInfo) {
+    super();
+  }
+}
+
+export class RemoveErrorInfoAction extends Action {
+
+  constructor(public errorInfo: ErrorInfo) {
+    super();
+  }
+}
+
+export class ClearErrorInfoAction extends Action {
+
+  constructor() {
+    super();
+  }
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/actions/menuAction.ts b/sdnr/wt/odlux/framework/src/actions/menuAction.ts
new file mode 100644
index 0000000..ec07965
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/actions/menuAction.ts
@@ -0,0 +1,31 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { Action } from '../flux/action';
+
+export class MenuAction extends Action {
+    constructor(public isOpen: boolean) {
+        super();
+    }
+}
+
+export class MenuClosedByUser extends Action {
+    constructor(public isClosed: boolean) {
+        super();
+    }
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/actions/navigationActions.ts b/sdnr/wt/odlux/framework/src/actions/navigationActions.ts
new file mode 100644
index 0000000..6951b97
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/actions/navigationActions.ts
@@ -0,0 +1,64 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action } from "../flux/action";
+
+export abstract class NavigationAction extends Action { }
+
+export class NavigateToApplication<TState = { }> extends NavigationAction {
+ 
+  constructor(public applicationName: string, public href?: string, public state?: TState, public replace: boolean = false ) {
+    super();
+    
+  }
+}
+
+export class PushAction<TState = { }> extends NavigationAction {
+  constructor(public href: string, public state?: TState) {
+    super();
+
+  }
+}
+
+export class ReplaceAction<TState = { }> extends NavigationAction {
+  constructor(public href: string, public state?: TState) {
+    super();
+
+  }
+}
+
+export class GoAction extends NavigationAction {
+  constructor(public index: number) {
+    super();
+
+  }
+}
+
+export class GoBackAction extends NavigationAction {
+
+}
+
+export class GoForwardeAction extends NavigationAction {
+
+}
+
+export class LocationChanged extends NavigationAction {
+  constructor(public pathname: string, public search: string, public hash: string ) {
+    super();
+    
+  }
+} 
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/actions/snackbarActions.ts b/sdnr/wt/odlux/framework/src/actions/snackbarActions.ts
new file mode 100644
index 0000000..32e2b26
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/actions/snackbarActions.ts
@@ -0,0 +1,37 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action } from '../flux/action';
+import { SnackbarItem } from '../models/snackbarItem';
+import { Omit } from '@material-ui/core';
+
+export class AddSnackbarNotification extends Action {
+
+  constructor(notification: Omit<SnackbarItem, 'key' >) {
+    super();
+
+    this.notification = { ...notification, key: (new Date().getTime() + Math.random()) }
+  }
+
+  public notification: SnackbarItem
+}
+
+export class RemoveSnackbarNotification extends Action {
+  constructor(public key: number) {
+    super();
+  }
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/actions/titleActions.ts b/sdnr/wt/odlux/framework/src/actions/titleActions.ts
new file mode 100644
index 0000000..4bcfe29
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/actions/titleActions.ts
@@ -0,0 +1,27 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action } from '../flux/action';
+
+import { IconType } from '../models/iconDefinition';
+
+export class SetTitleAction extends Action {
+
+  constructor(public title: string, public icon?: IconType, public appId?: string) {
+    super();
+  }
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/actions/websocketAction.ts b/sdnr/wt/odlux/framework/src/actions/websocketAction.ts
new file mode 100644
index 0000000..8512d59
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/actions/websocketAction.ts
@@ -0,0 +1,8 @@
+import { Action } from "../flux/action";
+
+
+export class SetWebsocketAction extends Action {
+    constructor(public isConnected: boolean) {
+        super();
+    }
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/app.css b/sdnr/wt/odlux/framework/src/app.css
new file mode 100644
index 0000000..356f36d
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/app.css
@@ -0,0 +1,6 @@
+html, body, #app {
+  height: 100%;
+  padding: 0px;
+  margin: 0px;
+  font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/app.tsx b/sdnr/wt/odlux/framework/src/app.tsx
new file mode 100644
index 0000000..85b0dfb
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/app.tsx
@@ -0,0 +1,108 @@
+/**

+ * ============LICENSE_START========================================================================

+ * ONAP : ccsdk feature sdnr wt odlux

+ * =================================================================================================

+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.

+ * =================================================================================================

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

+ * in compliance with the License. You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License

+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

+ * or implied. See the License for the specific language governing permissions and limitations under

+ * the License.

+ * ============LICENSE_END==========================================================================

+ */

+/******************************************************************************

+ * Copyright 2018 highstreet technologies GmbH

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ *****************************************************************************/

+

+import * as React from 'react';

+import * as ReactDOM from 'react-dom';

+

+import { MuiThemeProvider } from '@material-ui/core/styles';

+

+import { Frame } from './views/frame';

+

+import { AddErrorInfoAction } from './actions/errorActions';

+

+import { applicationStoreCreator } from './store/applicationStore';

+import { ApplicationStoreProvider } from './flux/connect';

+

+import { startHistoryListener } from './middleware/navigation';

+import { startRestService } from './services/restService';

+

+

+import theme from './design/default';

+import '!style-loader!css-loader!./app.css';

+import { ReplaceAction } from './actions/navigationActions';

+import { startForceLogoutService } from './services/forceLogoutService';

+import { startNotificationService } from './services/notificationService';

+

+declare module '@material-ui/core/styles/createMuiTheme' {

+

+  interface IDesign {

+    id: string,

+    name: string,

+    url: string,        // image url of a company logo, which will be presented in the ui header

+    height: number,     // image height [px] as delivered by the url

+    width: number,      // image width [px] as delivered by the url

+    logoHeight: number  // height in [px] of the logo (see url) within the ui header

+  }

+

+  interface Theme {

+    design?: IDesign

+  }

+  interface ThemeOptions {

+    design?: IDesign

+  }

+}

+

+export const runApplication = () => {

+  const applicationStore = applicationStoreCreator();

+

+  window.onerror = function (msg: string, url: string, line: number, col: number, error: Error) {

+    // Note that col & error are new to the HTML 5 spec and may not be

+    // supported in every browser.  It worked for me in Chrome.

+    var extra = !col ? '' : '\ncolumn: ' + col;

+    extra += !error ? '' : '\nerror: ' + error;

+

+    // You can view the information in an alert to see things working like this:

+    applicationStore.dispatch(new AddErrorInfoAction({ error, message: msg, url, line, col, info: { extra } }));

+

+    var suppressErrorAlert = true;

+    // If you return true, then error alerts (like in older versions of

+    // Internet Explorer) will be suppressed.

+    return suppressErrorAlert;

+  };

+

+  startRestService(applicationStore);

+  startHistoryListener(applicationStore);

+  startForceLogoutService(applicationStore);

+  startNotificationService(applicationStore);

+

+  const App = (): JSX.Element => (

+    <ApplicationStoreProvider applicationStore={applicationStore} >

+      <MuiThemeProvider theme={theme}>

+        <Frame />

+      </MuiThemeProvider>

+    </ApplicationStoreProvider>

+  );

+

+  ReactDOM.render(<App />, document.getElementById('app'));

+

+};

diff --git a/sdnr/wt/odlux/framework/src/assets/images/defaultLogo.svg b/sdnr/wt/odlux/framework/src/assets/images/defaultLogo.svg
new file mode 100644
index 0000000..bd9ddf5
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/assets/images/defaultLogo.svg
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   viewBox="0 0 350.6536 109.43979"
+   height="109.43979"
+   width="350.65359"
+   xml:space="preserve"
+   version="1.1"
+   id="svg2"
+   class="style-svg replaced-svg"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="htlogo_white.svg"><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1440"
+     inkscape:window-height="796"
+     id="namedview50"
+     showgrid="false"
+     inkscape:zoom="3.0651398"
+     inkscape:cx="123.67512"
+     inkscape:cy="44.346735"
+     inkscape:window-x="-8"
+     inkscape:window-y="1072"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g12" /><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6"><linearGradient
+       id="linearGradient58"
+       spreadMethod="pad"
+       gradientTransform="matrix(700.116,-254.822,-254.822,-700.116,227.808,857.597)"
+       gradientUnits="userSpaceOnUse"
+       y2="0"
+       x2="1"
+       y1="0"
+       x1="0"><stop
+         id="stop60"
+         offset="0"
+         style="stop-opacity:1;stop-color:#45a0de" /><stop
+         id="stop62"
+         offset="0.509804"
+         style="stop-opacity:1;stop-color:#2da247" /><stop
+         id="stop64"
+         offset="1"
+         style="stop-opacity:1;stop-color:#f4f01f" /></linearGradient></defs><g
+     transform="matrix(1.25,0,0,-1.25,-25.640145,137.40654)"
+     id="g10"><g
+       transform="scale(0.1,0.1)"
+       id="g12"><path
+         id="path14"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1089.71,559.016 c 0,-19.914 9.13,-38.637 47.77,-38.637 l 11.28,0 c 44.64,0 47.04,19.441 47.04,43.922 l 0,13.437 -16.8,0 0,-9.121 c 0,-25.679 -4.32,-31.437 -31.68,-31.437 l -6.48,0 c -22.57,0 -30.49,6.961 -30.49,29.758 l 0,60.96 81.85,0 0,16.801 -81.85,0 0,29.039 -20.64,0 0,-29.039 -26.88,0 0,-16.801 26.88,0 0,-68.882" /><path
+         id="path16"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1215.44,570.543 c 0,-45.125 30.72,-50.164 57.6,-50.164 l 37.44,0 c 38.39,0 61.68,8.398 61.68,36.48 l 0,2.403 -20.64,0 c -1.2,-18.719 -11.76,-22.082 -37.68,-22.082 l -28.32,0 c -36.01,0 -49.44,7.199 -49.44,35.039 l 0,7.683 136.08,0 0,13.676 c 0,43.68 -26.64,53.043 -63.6,53.043 l -33.12,0 c -29.28,0 -60,-5.047 -60,-49.441 l 0,-26.637 z m 136.08,26.156 -115.44,0 c 1.92,27.84 9.6,33.121 42.24,33.121 l 30.24,0 c 33.6,0 42.96,-12.48 42.96,-24.965 l 0,-8.156" /><path
+         id="path18"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1399.01,569.82 c 0,-44.402 32.88,-49.441 51.36,-49.441 l 46.56,0 c 38.4,0 53.76,12.004 53.76,42.965 l 0,3.594 -19.2,0 0,-4.079 c 0,-19.921 -16.08,-25.679 -35.28,-25.679 l -34.8,0 c -24.96,0 -41.76,6.242 -41.76,33.601 l 0,25.68 c 0,30.477 18.24,33.359 37.68,33.359 l 37.92,0 c 20.64,0 34.08,-4.8 34.08,-25.203 l 0,-2.879 19.2,0 0,3.364 c 0,25.918 -15.12,41.519 -53.52,41.519 l -34.56,0 c -30.24,0 -61.44,-5.047 -61.44,-49.441 l 0,-27.36" /><path
+         id="path20"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1582.36,522.301 20.65,0 0,69.597 c 0,28.805 11.03,37.922 59.28,37.922 l 5.27,0 c 40.08,0 45.12,-11.761 45.12,-29.757 l 0,-77.762 20.64,0 0,82.801 c 0,22.078 -12.24,41.519 -50.88,41.519 l -29.52,0 c -25.68,0 -41.76,-4.078 -49.44,-23.043 l -0.47,0 0,72.481 -20.65,0 0,-173.758" /><path
+         id="path22"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1772.14,522.301 20.65,0 0,69.597 c 0,28.805 11.03,37.922 59.28,37.922 l 5.28,0 c 40.08,0 45.12,-11.761 45.12,-29.757 l 0,-77.762 20.64,0 0,82.801 c 0,22.078 -12.25,41.519 -50.88,41.519 l -30.97,0 c -25.67,0 -41.76,-4.078 -49.43,-23.043 l -0.49,0 0,21.121 -19.2,0 0,-122.398" /><path
+         id="path24"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2102.09,571.258 c 0,-28.559 -16.79,-34.078 -40.8,-34.078 l -42,0 c -23.99,0 -40.8,5.519 -40.8,34.078 l 0,24.484 c 0,28.559 16.81,34.078 40.8,34.078 l 42,0 c 24.01,0 40.8,-5.519 40.8,-34.078 l 0,-24.484 z m -144.25,-1.195 c 0,-40.321 28.57,-49.684 67.69,-49.684 l 29.52,0 c 39.12,0 67.69,9.363 67.69,49.684 l 0,26.875 c 0,40.32 -28.57,49.683 -67.69,49.683 l -29.52,0 c -39.12,0 -67.69,-9.363 -67.69,-49.683 l 0,-26.875" /><path
+         id="path26"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2160.42,522.301 20.6484,0 0,173.758 -20.6484,0 0,-173.758 z" /><path
+         id="path28"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2362.98,571.258 c 0,-28.559 -16.8,-34.078 -40.8,-34.078 l -41.99,0 c -24.01,0 -40.8,5.519 -40.8,34.078 l 0,24.484 c 0,28.559 16.79,34.078 40.8,34.078 l 41.99,0 c 24,0 40.8,-5.519 40.8,-34.078 l 0,-24.484 z m -144.24,-1.195 c 0,-40.321 28.56,-49.684 67.68,-49.684 l 29.52,0 c 39.12,0 67.69,9.363 67.69,49.684 l 0,26.875 c 0,40.32 -28.57,49.683 -67.69,49.683 l -29.52,0 c -39.12,0 -67.68,-9.363 -67.68,-49.683 l 0,-26.875" /><path
+         id="path30"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2569.4,644.699 -19.21,0 0,-21.84 -0.48,0 c -6.47,19.918 -22.08,23.762 -37.68,23.762 l -43.92,0 c -23.04,0 -55.2,-5.047 -55.2,-49.441 l 0,-20.399 c 0,-31.445 17.04,-48.965 51.36,-48.965 l 42.48,0 c 28.8,0 37.2,7.442 41.52,18.965 l 0.47,0 0,-18.242 c 0,-33.121 -16.31,-33.598 -57.12,-33.598 l -20.14,0 c -19.21,0 -35.53,4.559 -35.53,20.395 l 0,3.363 -19.2,0 0,-4.082 c 0,-15.601 10.08,-36.476 48,-36.476 l 46.56,0 c 25.68,0 58.09,7.441 58.09,44.402 l 0,122.156 z M 2548.74,577.5 c 0,-21.117 -10.79,-32.883 -40.31,-32.883 l -39.84,0 c -25.2,0 -35.28,8.645 -35.04,36.723 l 0,22.558 c 0.24,20.157 15.36,25.922 36.48,25.922 l 42,0 c 29.04,0 37.2,-14.64 36.71,-37.437 l 0,-14.883" /><path
+         id="path32"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2611.1,673.5 20.64,0 0,22.559 -20.64,0 0,-22.559 z m 0,-151.199 20.64,0 0,122.398 -20.64,0 0,-122.398" /><path
+         id="path34"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2667.98,570.543 c 0,-45.125 30.71,-50.164 57.6,-50.164 l 37.44,0 c 38.39,0 61.68,8.398 61.68,36.48 l 0,2.403 -20.64,0 c -1.21,-18.719 -11.76,-22.082 -37.69,-22.082 l -28.31,0 c -36.01,0 -49.44,7.199 -49.44,35.039 l 0,7.683 136.08,0 0,13.676 c 0,43.68 -26.64,53.043 -63.6,53.043 l -33.12,0 c -29.29,0 -60,-5.047 -60,-49.441 l 0,-26.637 z m 136.08,26.156 -115.44,0 c 1.91,27.84 9.6,33.121 42.24,33.121 l 30.24,0 c 33.6,0 42.96,-12.48 42.96,-24.965 l 0,-8.156" /><path
+         id="path36"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2852.5,557.098 c 0,-36.719 28.57,-36.719 59.05,-36.719 l 37.92,0 c 25.2,0 56.88,1.195 56.88,35.519 l 0,0.485 c 0,33.117 -21.11,36.238 -52.08,36.238 l -54.48,0 c -21.59,0 -24.96,5.762 -24.96,15.84 l 0,4.559 c 0,13.918 6.48,16.8 35.99,16.8 l 36.01,0 c 22.56,0 35.04,-0.48 35.04,-19.203 l 0,-1.195 19.2,0 0,6.476 c 0,17.286 -6.48,30.723 -53.04,30.723 l -31.68,0 c -50.88,0 -62.16,-11.039 -62.16,-30.957 l 0,-7.203 c 0,-23.281 10.8,-32.641 39.85,-32.641 l 63.59,0 c 24.72,0 28.08,-6.48 28.08,-18.238 l 0,-0.961 c 0,-18.238 -9.84,-19.441 -40.8,-19.441 l -44.17,0 c -21.11,0 -29.03,6.242 -29.03,21.359 l 0,6 -19.21,0 0,-7.441" /><path
+         id="path38"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1078.67,762.301 20.65,0 0,69.597 c 0,28.805 11.03,37.922 59.28,37.922 l 5.28,0 c 40.08,0 45.12,-11.761 45.12,-29.757 l 0,-77.762 20.64,0 0,82.801 c 0,22.078 -12.24,41.519 -50.88,41.519 l -29.52,0 c -25.68,0 -41.76,-4.078 -49.44,-23.043 l -0.48,0 0,72.481 -20.65,0 0,-173.758" /><path
+         id="path40"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1271.34,913.5 20.64,0 0,22.559 -20.64,0 0,-22.559 z m 0,-151.199 20.64,0 0,122.398 -20.64,0 0,-122.398" /><path
+         id="path42"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1484.7,884.699 -19.19,0 0,-21.84 -0.49,0 c -6.48,19.918 -22.08,23.762 -37.68,23.762 l -43.92,0 c -23.04,0 -55.2,-5.047 -55.2,-49.441 l 0,-20.399 c 0,-31.445 17.04,-48.965 51.36,-48.965 l 42.48,0 c 28.8,0 37.2,7.442 41.52,18.965 l 0.48,0 0,-18.242 c 0,-33.121 -16.32,-33.598 -57.12,-33.598 l -20.16,0 c -19.2,0 -35.52,4.559 -35.52,20.395 l 0,3.363 -19.2,0 0,-4.082 c 0,-15.601 10.08,-36.476 48,-36.476 l 46.56,0 c 25.68,0 58.08,7.441 58.08,44.402 l 0,122.156 z M 1464.06,817.5 c 0,-21.117 -10.8,-32.883 -40.32,-32.883 l -39.84,0 c -25.2,0 -35.27,8.645 -35.04,36.723 l 0,22.558 c 0.24,20.157 15.36,25.922 36.48,25.922 l 42,0 c 29.04,0 37.2,-14.64 36.72,-37.437 l 0,-14.883" /><path
+         id="path44"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1523.52,762.301 20.65,0 0,69.597 c 0,28.805 11.04,37.922 59.28,37.922 l 5.28,0 c 40.08,0 45.11,-11.761 45.11,-29.757 l 0,-77.762 20.65,0 0,82.801 c 0,22.078 -12.24,41.519 -50.88,41.519 l -29.52,0 c -25.68,0 -41.76,-4.078 -49.44,-23.043 l -0.48,0 0,72.481 -20.65,0 0,-173.758" /><path
+         id="path46"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1708.75,797.098 c 0,-36.719 28.57,-36.719 59.04,-36.719 l 37.93,0 c 25.19,0 56.87,1.195 56.87,35.519 l 0,0.485 c 0,33.117 -21.11,36.238 -52.08,36.238 l -54.47,0 c -21.61,0 -24.96,5.762 -24.96,15.84 l 0,4.559 c 0,13.918 6.47,16.8 35.99,16.8 l 36.01,0 c 22.56,0 35.04,-0.48 35.04,-19.203 l 0,-1.195 19.2,0 0,6.476 c 0,17.286 -6.49,30.723 -53.04,30.723 l -31.69,0 c -50.88,0 -62.16,-11.039 -62.16,-30.957 l 0,-7.203 c 0,-23.281 10.8,-32.641 39.84,-32.641 l 63.6,0 c 24.72,0 28.09,-6.48 28.09,-18.238 l 0,-0.961 c 0,-18.238 -9.85,-19.441 -40.8,-19.441 l -44.17,0 c -21.12,0 -29.04,6.242 -29.04,21.359 l 0,6 -19.2,0 0,-7.441" /><path
+         id="path48"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 1907.92,799.016 c 0,-19.914 9.12,-38.637 47.77,-38.637 l 11.28,0 c 44.64,0 47.04,19.441 47.04,43.922 l 0,13.437 -16.81,0 0,-9.121 c 0,-25.679 -4.32,-31.437 -31.67,-31.437 l -6.48,0 c -22.56,0 -30.48,6.961 -30.48,29.758 l 0,60.96 81.84,0 0,16.801 -81.84,0 0,29.039 -20.65,0 0,-29.039 -26.87,0 0,-16.801 26.87,0 0,-68.882" /><path
+         id="path50"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2040.85,762.301 20.64,0 0,77.762 c 0,15.835 10.55,29.757 32.4,29.757 l 12.71,0 c 36.72,0 42.97,-4.8 42.97,-35.043 l 0,-5.277 19.19,0 0,14.641 c 0,30 -12.71,42.48 -51.35,42.48 l -19.45,0 c -14.16,0 -29.75,-3.844 -37.43,-19.683 l -0.49,0 0,17.761 -19.19,0 0,-122.398" /><path
+         id="path52"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2187.69,810.543 c 0,-45.125 30.72,-50.164 57.6,-50.164 l 37.44,0 c 38.4,0 61.68,8.398 61.68,36.48 l 0,2.403 -20.65,0 C 2322.57,780.543 2312,777.18 2286.09,777.18 l -28.32,0 c -36,0 -49.45,7.199 -49.45,35.039 l 0,7.683 136.09,0 0,13.676 c 0,43.68 -26.64,53.043 -63.61,53.043 l -33.11,0 c -29.28,0 -60,-5.047 -60,-49.441 l 0,-26.637 z m 136.07,26.156 -115.44,0 c 1.93,27.84 9.6,33.121 42.25,33.121 l 30.23,0 c 33.61,0 42.96,-12.48 42.96,-24.965 l 0,-8.156" /><path
+         id="path54"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2371.26,810.543 c 0,-45.125 30.73,-50.164 57.6,-50.164 l 37.44,0 c 38.4,0 61.68,8.398 61.68,36.48 l 0,2.403 -20.64,0 c -1.19,-18.719 -11.76,-22.082 -37.68,-22.082 l -28.32,0 c -36.01,0 -49.44,7.199 -49.44,35.039 l 0,7.683 136.08,0 0,13.676 c 0,43.68 -26.64,53.043 -63.59,53.043 l -33.13,0 c -29.27,0 -60,-5.047 -60,-49.441 l 0,-26.637 z m 136.08,26.156 -115.44,0 c 1.92,27.84 9.6,33.121 42.24,33.121 l 30.25,0 c 33.59,0 42.95,-12.48 42.95,-24.965 l 0,-8.156" /><path
+         id="path56"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 2571.4,799.016 c 0,-19.914 9.11,-38.637 47.75,-38.637 l 11.28,0 c 44.64,0 47.04,19.441 47.04,43.922 l 0,13.437 -16.8,0 0,-9.121 c 0,-25.679 -4.31,-31.437 -31.67,-31.437 l -6.49,0 c -22.56,0 -30.48,6.961 -30.48,29.758 l 0,60.96 81.84,0 0,16.801 -81.84,0 0,29.039 -20.63,0 0,-29.039 -26.89,0 0,-16.801 26.89,0 0,-68.882" /><path
+         id="path66"
+         style="fill:url(#linearGradient58);fill-opacity:1;fill-rule:evenodd;stroke:none"
+         d="m 414.316,403.621 c -16.695,10.117 -53.621,35.262 -67.011,51.457 -12.836,8.742 -24.672,17.988 -35.45,27.621 -9.265,7.731 -17.839,16.301 -25.644,25.723 -1.172,1.41 -2.32,2.836 -3.441,4.273 -9.063,10.887 -16.875,22.106 -23.372,33.524 -7.628,13.414 -12.269,22.301 -17.019,40.851 -3.981,19.496 -5.234,32.43 -5.082,47.832 -28.332,58.625 -36.563,123.481 -18.883,186.891 13.09,46.949 38.906,86.59 73.777,118.02 7.528,17.125 16.887,33.05 28.067,47.488 10.691,16.629 20.637,30.769 49.383,49.629 27.644,18.15 77.902,31.47 117.879,30.93 18.476,13.53 40.089,20.71 64.839,24.74 47.262,5.39 79.168,2.22 116.493,-6.39 18.808,-4.33 45.027,-17.46 45.027,-17.46 -54.891,19.82 -87.711,22.51 -144.391,17.57 25.133,-8.53 54.653,-29.87 77.192,-58.13 44.23,28.77 86.351,35.13 116.25,19.84 l -4.11,-0.96 c -25.644,13.11 -58.992,5.79 -97.121,-20.08 91.344,7.4 169.336,-18.14 219.184,-78.318 l 0.125,-2.223 c -45.715,55.191 -120.848,79.461 -205.059,73.911 84.348,-25.176 153.828,-74.512 200.754,-135.11 63.703,-70.281 91.414,-159.559 66.129,-250.23 -15.387,-55.18 -48.344,-101.879 -92.93,-137.551 -2.129,-4.223 -14.382,-26.391 -21.718,-33.938 -13.5,-16.859 -30.008,-31.453 -49.657,-43.25 -26.961,-16.179 -56.652,-25.742 -87.773,-29.222 -3.781,-0.762 -7.613,-1.473 -11.484,-2.129 -11.52,-8.075 -25.625,-14.414 -41.614,-18.914 -6.265,-1.801 -12.777,-3.301 -19.418,-4.543 -36.254,-6.082 -81.039,-4.164 -124.425,7.011 -28.528,7.356 -55.516,18.207 -79.497,31.137 z m 337.618,279.375 -0.184,6.477 c 33.586,2.617 63.285,10.574 94.199,21.816 0,0 -50.402,-10.492 -94.547,-12.828 -0.718,16.012 -1.964,32.266 -3.761,48.687 l -0.34,3.075 c 13.105,37.785 22.176,70.148 22.176,70.148 -6.387,-20.391 -14.071,-41.488 -23.02,-63.016 -5.875,47.676 -16.012,92.579 -29.309,133.036 30.336,-10.758 58.536,-22.903 84.047,-36.328 53.414,-88.161 79.442,-183.672 73.118,-265.227 -4.391,-29.281 -13.012,-56.602 -25.758,-80.918 l -0.825,-0.684 c 0.918,9.688 0.629,19.559 -0.792,29.524 -0.165,-9.938 -1.122,-20.363 -2.911,-31.317 l -0.238,-1.398 c -36.898,-29.387 -82.035,-51.129 -131.93,-63.566 0.157,1.562 9.618,28.707 13.27,43.371 3.305,9.632 6.336,19.73 9.074,30.238 5.145,3.516 10.246,7.141 15.305,10.863 0,0 -5.188,-3.039 -14.551,-7.949 12.02,47.359 18.184,102.902 17.055,162.344 53.453,-42.227 87.926,-93.524 94.926,-142.586 1.113,67.512 -34.336,112.504 -95.004,146.238 z M 333.047,859.52 c -10.301,17.363 -17.945,33.175 -20.547,50.64 10.129,5.113 20.969,9.75 32.434,13.887 22.472,6.043 47.168,10.066 73.519,12.086 l -5.664,-4.117 C 382.016,909.348 355.977,886.105 333.047,859.52 Z m -20.945,53.605 c -1.668,13.578 -0.848,27.012 2.687,40.047 13.629,11.637 28.422,22.25 44.195,31.73 28.508,14.231 57.403,23.548 90.801,30.188 -8.578,-16.223 -19.293,-41.961 -28.226,-74.18 -29.555,-3.914 -52.071,-8.015 -76.625,-16.863 -11.555,-3.106 -22.52,-6.746 -32.832,-10.922 z m 348.73,95.825 c 18.594,-27.942 37.102,-64.559 50.938,-103.044 30.394,-11.972 58.132,-26.027 82.953,-41.59 l -3.489,5.422 c -35.339,54.348 -75.664,98.797 -120.496,132.012 50.84,-32.992 96.559,-79.105 134.168,-136.93 2.684,-4.117 5.285,-8.254 7.809,-12.402 10.969,-7.645 21.273,-15.586 30.898,-23.777 52.621,-35.407 88.274,-77.661 99.668,-125.266 -0.133,63.387 -24.105,127.047 -66.343,181.59 -51.118,56.394 -127.426,101.137 -216.106,123.985 z m 50.363,-345.43 c -23.25,-42.028 -48.918,-80.93 -75.531,-115.211 24.883,-14.922 45.047,-32.543 58.422,-51.286 15.269,6.786 27.965,13.024 37.336,17.86 6.832,43.519 8.812,100.844 4.648,173.199 -4.679,-0.559 -8.5,-0.398 -13.082,-0.754 -3.621,-7.969 -8.105,-17.148 -11.793,-23.808 z m -307.539,95.351 c -24.816,-2.672 -43.742,-6.769 -64.582,-13.402 17.864,8.511 37.91,15.195 59.688,19.832 -28.746,19.629 -51.621,41.957 -67.949,65.793 -18.45,-22.781 -34.235,-46.406 -47.02,-70.227 2.09,-12.176 4.801,-24.461 8.125,-36.797 13.629,8.61 29.48,15.77 47.156,21.399 -17.113,-8.156 -32.226,-17.985 -44.941,-29.293 4.719,-16.25 14.672,-42.125 23.359,-61.703 14.754,-12.203 39.66,-30.582 57.074,-41.969 9.215,33.777 17.274,58.293 33.485,94.824 -2.485,21.758 -4.395,51.543 -4.395,51.543 z M 613.887,373.906 c 13.918,2.422 26.574,6.153 37.629,11.035 l 0.75,0.332 c 2.812,1.266 5.519,2.602 8.113,4.016 -43.27,0.524 -88.383,11.902 -132.074,32.734 14.156,-16.507 28.933,-29.168 43.867,-37.355 26.258,-2.254 51.816,-2.172 76.109,-0.031 -21.16,-3.254 -43.258,-5.032 -65.879,-4.867 10.524,-4.297 21.075,-6.325 31.485,-5.864 z m 79.144,26.282 c 28.856,3.609 56.262,12.652 81.074,27.55 25.086,15.063 45.735,35.051 61.825,58.731 -36.25,-25.774 -79.078,-44.801 -125.723,-55.922 l -0.363,-1.356 c -3.047,-10.918 -8.809,-20.609 -16.813,-29.003 z m -147.797,24.066 c 43.317,-18.582 87.555,-27.516 129.371,-25.621 10.231,8.133 17.657,17.84 21.668,28.851 -47.679,-9.605 -98.953,-11.078 -151.039,-3.23 z m -46.187,634.796 c -9.406,-8.19 -17.121,-16.69 -23.402,-30.59 44.066,9.86 84.668,12.07 132.925,5.93 -37.882,15.93 -72.554,24.28 -109.523,24.66 z m 131.582,-28.07 c -28.652,33.59 -65.481,54.73 -95.899,47.25 -10.156,-3.17 -16.96,-7.05 -25.121,-11.99 38.176,-2.87 73.696,-15.34 121.02,-35.26 z M 571.035,708.031 c 13.711,-3.531 26.285,-7.843 38.695,-10.492 -24.523,1.531 -66.074,7.684 -86.843,12.742 -38.117,9.282 -54.282,16.27 -84.098,31.43 -5.652,-11.711 -10.98,-23.336 -15.98,-34.844 4.886,-40.812 12.664,-79.394 22.64,-114.832 33.672,2.77 70.922,-0.226 107.047,-9.531 27.527,-7.094 53.047,-17.301 75.242,-29.617 26.407,33.894 52.102,72.609 75.555,115.004 3.164,5.714 7.234,12.988 10.238,18.691 -33.445,1.5 -56.398,3.75 -103.801,10.957 36.25,-2.266 109.875,1.176 109.875,1.176 -37.574,16.551 -82.113,30.308 -131.773,43.094 -48.844,12.582 -96.305,18.644 -139.715,18.726 l -1.582,-3.601 c 36.336,-20.719 77.582,-36.817 124.5,-48.903 z m -254.148,-73.84 c -19.922,17.575 -32.805,29.309 -49.817,49.231 -7.968,-12.262 -11.718,-21.731 -14.937,-36.039 -1.153,-5.129 -2.219,-10.285 -3.129,-15.457 18.773,-36.582 45.68,-70.598 79.277,-99.985 5.547,13.598 16.114,25.075 30.332,34.286 -5.121,7.039 -10.097,14.265 -14.906,21.664 -13.184,20.269 -17.164,25.371 -26.82,46.3 z m 108.781,-52.16 10.262,-5.273 -2.106,6.859 c -1.621,-0.234 -6.562,-1.316 -8.156,-1.586 z M 274.469,695.734 c 6.469,-6.199 20.172,-21.121 27.304,-27.211 -3.793,9.981 -11.925,30.747 -14.937,40.735 -3.656,-3.699 -9.203,-9.547 -12.367,-13.524 z m -48.09,118.813 c -4.387,-18.231 -4.055,-36.277 0.418,-54.02 -2.961,5.801 -5.379,11.559 -7.195,17.254 -4.196,-42.461 3.519,-87.199 20.277,-127.246 0.488,2.547 1.344,10.11 2.047,14.195 2.453,15.508 4.5,26.016 8.16,42.129 -11.617,16.539 -18.949,36.438 -23.289,53.668 6.652,-13.035 16.047,-26.269 27.484,-39.457 5.008,15.985 11.407,32 19.157,47.875 -6.043,41.114 -5.258,81.02 2.285,117.629 -25.407,-20 -42.684,-44.324 -49.344,-72.027 z m 709.922,-170 c 7.422,59.746 -26.321,127.641 -92.688,184.094 -8.418,5.664 -17.269,11.152 -26.527,16.461 50.605,-86.379 68.984,-178.438 57.273,-256.524 -1.992,-25.672 -7.187,-49.973 -15.75,-72.219 36.059,32.825 62.625,73.719 75.758,120.797 0.684,2.457 1.328,4.922 1.934,7.391 z M 288.707,901.691 c 4.258,2.336 8.668,4.547 13.223,6.653 -0.895,10.953 -0.469,21.957 1.328,32.918 -5.895,-12.508 -10.746,-25.746 -14.551,-39.571 z m -40.098,-30.046 c 8.368,8.699 18.09,16.539 29.02,23.503 2.473,10.395 5.512,20.497 9.109,30.262 -14.898,-16.504 -27.73,-34.504 -38.129,-53.765 z m -2.246,-260.403 c 1.266,-16.219 5.2,-31.91 10.817,-46.492 12.215,-27.102 33.175,-50.285 59.043,-73.496 4.597,-3.379 9.289,-6.559 14.054,-9.535 -5.996,13.586 -7.953,27.398 -4.929,40.883 -32.395,27.742 -58.981,59.703 -78.493,94.207 -0.195,-1.852 -0.359,-3.711 -0.492,-5.567 z m 30.75,136.61 c -5.777,-11.817 -11.312,-25.586 -15.55,-37.36 2.093,-2.242 3.324,-4.086 5.527,-6.324 4.711,4.633 11.34,10.539 16.988,14.609 -2.691,9.723 -5.012,19.418 -6.965,29.075 z m 137.813,166.109 c -30.09,-22.957 -50.508,-39.84 -73.742,-66.703 17.101,-24.082 32.175,-42.192 61.769,-63.039 0.129,59.617 5.953,98.562 11.973,129.742 z m 63.347,42.805 c -5.769,-3.34 -11.503,-6.809 -17.207,-10.414 8.411,0.515 16.961,0.828 25.625,0.937 -3.015,3.121 -5.82,6.285 -8.418,9.477 z m 5.891,16.363 c 41.988,22.187 80.035,37.611 122.715,46.381 -48.469,6.85 -88.973,8.11 -133.481,0.79 -2.347,-15.62 1.137,-32.628 10.766,-47.171 z m -47.473,-25.246 c 11.52,7.613 21.438,13.832 33.282,20.383 -7.852,12.394 -11.328,23.336 -12.668,35.564 -7.832,-17.58 -14.629,-33.74 -20.614,-55.947 z m -77.476,36.734 c 29.711,17.853 59.988,30.823 95.445,39.893 0,0 14.356,22.66 25.043,34.4 -40.375,-4.82 -65.492,-11.69 -98.254,-28.31 -22.383,-11.36 -37.285,-24.19 -50.422,-43.116 -6.414,-9.73 -10.398,-19.398 -13.824,-28.066 13.11,9.375 27.156,17.781 42.012,25.199 z m -78.559,-201.64 c 11.453,21.168 25.301,41.996 41.426,62.089 -10.82,19.153 -17.516,39.094 -19.762,59.239 -5.382,-3.043 -10.527,-6.235 -15.429,-9.567 -8.5,-34.457 -10.645,-72.351 -6.235,-111.761 z M 688.488,485.801 c -48.293,-26.285 -98.433,-43.637 -147,-51.828 54.532,-8.883 108.055,-7.297 157.36,3.226 2.632,15.403 -1.121,32.106 -10.36,48.602 z m 45.766,228.554 c -2.285,-5.847 -4.633,-11.621 -7.024,-17.242 l 1.067,-0.707 7.168,0.512 c -0.367,5.715 -0.766,11.523 -1.211,17.437 z M 725.172,483.59 c 2.152,8.66 4.066,17.965 5.711,27.953 -10.805,-7.273 -21.766,-14.078 -32.84,-20.406 8.266,-13.121 13.172,-26.696 14.043,-40.196 4.742,10.161 9.109,21.075 13.086,32.649 z M 512.363,445.281 c 37.364,25.75 77.864,62.559 111.164,102.242 -20.925,12.305 -45.597,22.641 -73.281,29.778 -36.816,9.48 -72.16,11.66 -102.891,8.097 0.922,-3.14 4.317,-13.179 5.274,-16.273 39.855,-18.266 82.976,-33.98 82.976,-33.98 -27.621,6.031 -53.914,12.203 -79.226,21.687 15.574,-47.457 55.98,-111.648 55.984,-111.551 z m -67.359,-31.867 c 13.047,3.754 26.023,8.07 39.937,15.262 -40.523,-0.938 -67.214,2.875 -101.777,14.558 22.129,-12.675 35.953,-20.589 61.84,-29.82 z m -30.75,0.816 c 4.848,-2.921 11.637,-2.921 15.141,-2.453 -12.45,4.793 -18.77,7.582 -32.567,14.325 7.016,-5.438 9.473,-7.309 17.426,-11.872 z m -45.274,75.879 c 0.313,-10.523 2.223,-20.601 4.047,-29.406 29.856,-11.246 60.684,-16.226 92.512,-17.066 -35.039,11.902 -67.43,27.664 -96.559,46.472 z m 4.266,56.989 c -2.637,-16.524 -4.094,-32 -4.328,-46.207 33.539,-22.34 71.766,-40.559 113.723,-53.27 -39.629,25.649 -76.993,59.184 -109.395,99.477 z m 2.574,14.547 -0.496,-2.629 c 32.727,-41.637 74.149,-80.024 118.262,-107.895 -19.68,31.887 -38.766,66.445 -53.27,112.07 -8.562,3.965 -22.011,9.454 -30.23,13.563 -17.523,-4.359 -22,-6.926 -34.266,-15.109 z m 6.129,29.183 c -1.758,-9.969 -1.23,-6.445 -2.926,-13.933 9.282,3.906 7.297,3.8 18.157,6.308 -8.414,4.363 -7.239,3.117 -15.231,7.625 z m 29.731,89.004 c -12.203,-29.008 -17.723,-48.094 -25.524,-74.707 15.016,-8.785 18.176,-11.496 30.379,-18.172 4.27,0.656 10.77,2.508 15.188,2.969 -8.993,33.039 -14.309,54.793 -20.043,89.91 z m 147.05,250.07 c -4.3,-5.285 -7.832,-9.629 -12.117,-15.191 37.313,-22.055 80.684,-32.52 80.684,-32.52 -8.387,1.184 -12.859,1.758 -27.449,4.938 -21.16,5.004 -43.539,10.957 -59.344,19.957 -25.684,-33.961 -51.887,-72.035 -75.234,-114.242 -3.782,-6.824 -7.454,-13.641 -11.028,-20.449 41.949,2.105 88,-2.434 135.844,-14.754 49.012,-12.629 93.297,-32.336 130.805,-56.379 4.316,8.605 8.441,17.176 12.382,25.699 -0.507,6.207 -1.062,12.519 -1.644,18.941 -5.008,54.649 -15.656,105.219 -30.172,149.618 -23.234,7.691 -47.613,14.589 -72.91,20.656 -24.172,5.789 -46.348,10.308 -69.817,13.726 z m 84.836,82.848 c -21.144,-15.355 -51.222,-43.402 -75.105,-70.973 21.824,-2.793 42.984,-6.07 65.398,-11.441 21.641,-5.188 42.313,-11.375 61.961,-18.434 -15.25,39.45 -34.152,75 -52.254,100.848 z m -90.449,-68.551 c 24.438,27.528 49.297,50.981 73.449,69.341 -46.043,-9 -90.203,-24.47 -136.121,-49.919 4.145,-4.953 8.61,-11.98 13.539,-16.676 17.067,-0.222 31.352,-0.894 49.133,-2.746 z m -18.551,-22.453 c 3.032,3.727 4.895,6.617 7.946,10.219 -9.293,1.176 -15.43,1.633 -24.543,2.426 5.972,-4.868 10.304,-8.231 16.597,-12.645 z M 436.363,773.141 c 4.457,8.707 9.321,17.078 14.285,25.707 22.571,39.211 49.93,80.941 77.497,115.609 -10.946,6.875 -20.879,14.125 -29.618,21.676 -17.609,1.097 -34.793,1.469 -51.425,1.097 -5.895,-3.98 -10.344,-7.226 -16.145,-11.488 -9.559,-44.469 -14.918,-94.359 -12.781,-151.203 l 3.16,-2.148 c 5.012,0.707 9.871,0.246 15.027,0.75 z M 419.77,736.914 c 1.832,3.973 3.699,7.957 5.601,11.945 -2.273,1.278 -4.519,2.563 -6.738,3.864 0.324,-5.235 0.703,-10.504 1.137,-15.809 z M 365.832,571.656 c 1.977,11.266 2.617,13.098 5.559,25.016 -17.149,10.098 -22.774,13.883 -37.493,24.617 7.684,-15.121 7.758,-13.68 17.375,-28.473 4.707,-7.234 9.563,-14.293 14.559,-21.16 z m -5.91,-64.59 c -0.125,13.739 0.82,28.489 2.793,44.063 -8.481,-8.254 -14.43,-17.691 -17.313,-28.047 -0.41,-1.473 -0.757,-2.949 -1.035,-4.445 5.051,-3.961 10.242,-7.817 15.555,-11.571 z m 4.719,-43.027 c -2.293,9.727 -3.739,20.383 -4.368,31.852 -5.75,3.929 -11.371,7.968 -16.851,12.129 0.098,-13.27 4.816,-27.082 13.492,-40.618 2.559,-1.168 5.137,-2.293 7.727,-3.363 z m 89.195,-61.324 c -4.52,-0.969 -8.941,-1.621 -13.266,-1.957 16.895,-7.879 35.582,-14.621 55.731,-19.813 29.906,-7.703 58.527,-10.898 84.375,-10.238 -6.406,2.5 -12.75,5.773 -19.008,9.762 -22.934,1.386 -46.266,4.855 -69.586,10.863 -13.176,3.395 -25.93,7.203 -38.246,11.383 z m 55.227,24.047 c -15.844,-10.192 -27.801,-15.782 -42.344,-20.543 9.496,-3.114 19.203,-5.957 29.117,-8.508 19.066,-4.914 38.074,-8.527 56.816,-10.949 -13.984,10.609 -31.91,25.652 -43.589,40 z M 631.309,542.75 c -29.774,-37.652 -60.614,-69.477 -90.477,-93.41 54.66,9.137 105.574,27.234 143.426,43.41 -11.699,17.816 -29.731,35.137 -52.949,50" /><path
+         id="path68"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1095.13,368.133 21.29,0 62.34,-124.289 0.38,0 0,124.289 13.43,0 0,-138.867 -21.29,0 -62.34,124.289 -0.38,0 0,-124.289 -13.43,0 0,138.867" /><path
+         id="path70"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1270.6,287.574 c 0,20.715 -0.38,29.918 -22.25,29.918 -21.86,0 -22.25,-9.203 -22.25,-29.918 l 44.5,0 z m -44.5,-12.277 0,-9.016 c 0,-21.289 3.64,-27.426 20.52,-27.426 19.76,0 23.98,0.387 23.98,19.567 l 12.27,0 0,-3.649 c 0,-19.558 -4.79,-27.039 -34.14,-27.039 -32.22,0 -36.06,10.739 -36.06,50.446 0,40.468 6.53,50.441 36.06,50.441 29.35,0 34.14,-11.894 34.14,-38.555 l 0,-14.769 -56.77,0" /><path
+         id="path72"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1306.45,315.961 -10.17,0 0,11.125 10.17,0 0,22.637 12.27,0 0,-22.637 31.65,0 0,-11.125 -31.65,0 0,-65.406 c 0,-8.055 2.49,-11.7 10.55,-11.7 9.21,0 13.24,1.731 13.24,23.399 l 11.12,0 c 0,-31.258 -9.97,-34.52 -24.17,-34.52 -18.03,0 -23.01,5.563 -23.01,20.137 l 0,68.09" /><path
+         id="path74"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1358.22,327.086 12.09,0 19.37,-85.352 0.38,0 18.41,85.352 17.65,0 18.41,-85.543 0.39,0 19.37,85.543 12.08,0 -23.21,-97.82 -17.83,0 -17.84,85.543 -0.39,0 -17.83,-85.543 -17.84,0 -23.21,97.82" /><path
+         id="path76"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1522.18,238.855 c 19.57,0 22.63,2.879 22.63,39.325 0,36.437 -3.06,39.312 -22.63,39.312 -19.56,0 -22.63,-2.875 -22.63,-39.312 0,-36.446 3.07,-39.325 22.63,-39.325 z m 0,89.766 c 32.23,0 36.06,-11.508 36.06,-50.441 0,-40.477 -4.22,-50.446 -36.06,-50.446 -31.84,0 -36.06,9.969 -36.06,50.446 0,38.933 3.84,50.441 36.06,50.441" /><path
+         id="path78"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1576.82,327.086 12.28,0 0,-11.891 0.38,0 c 4.6,9.399 10.36,13.426 22.64,13.426 15.53,0 22.63,-6.715 22.63,-26.277 l 0,-7.864 -11.12,0 c 0.19,18.028 -1.92,23.012 -15.93,23.012 -12.27,0.199 -18.6,-6.707 -18.6,-20.133 l 0,-68.093 -12.28,0 0,97.82" /><path
+         id="path80"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1665.42,275.297 -5.37,0 0,-46.031 -12.27,0 0,138.867 12.27,0 0,-80.559 5.75,0 28.97,39.512 15.15,0 -34.33,-45.266 39.51,-52.554 -16.31,0 -33.37,46.031" /><path
+         id="path82"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1787.76,259.57 c -0.38,-16.875 2.68,-20.715 20.91,-20.715 19.75,0 23.39,2.879 23.39,19.372 0,12.851 -1.33,13.812 -24.55,15.156 -24.55,1.344 -31.26,4.984 -31.26,26.66 0,20.523 3.84,28.578 32.99,28.578 28.59,0 34.14,-6.523 34.14,-27.047 l -12.27,0 c 0,14.965 -4.03,15.918 -22.44,15.918 -17.08,0 -20.14,-1.722 -20.14,-16.875 0,-13.812 1.73,-14.961 22.44,-16.109 28.96,-1.731 33.37,-4.031 33.37,-25.508 0,-23.02 -4.41,-31.266 -36.06,-31.266 -22.44,0 -32.8,2.684 -32.8,31.836 l 12.28,0" /><path
+         id="path84"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1898.8,238.855 c 19.56,0 22.63,2.879 22.63,39.325 0,36.437 -3.07,39.312 -22.63,39.312 -19.57,0 -22.63,-2.875 -22.63,-39.312 0,-36.446 3.06,-39.325 22.63,-39.325 z m 0,89.766 c 32.22,0 36.06,-11.508 36.06,-50.441 0,-40.477 -4.22,-50.446 -36.06,-50.446 -31.84,0 -36.06,9.969 -36.06,50.446 0,38.933 3.84,50.441 36.06,50.441" /><path
+         id="path86"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 1956.7,229.266 12.2813,0 0,138.867 -12.2813,0 0,-138.867 z" /><path
+         id="path88"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 2061.04,229.266 -12.28,0 0,12.664 -0.39,0 c -6.13,-10.555 -12.85,-14.196 -27.04,-14.196 -22.64,0 -28.77,11.313 -28.77,30.301 l 0,69.051 12.28,0 0,-66.172 c 0,-11.316 2.49,-22.059 18.6,-22.059 14.96,0 25.32,5.758 25.32,26.469 l 0,61.762 12.28,0 0,-97.82" /><path
+         id="path90"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 2084.61,315.961 -10.16,0 0,11.125 10.16,0 0,22.637 12.28,0 0,-22.637 31.65,0 0,-11.125 -31.65,0 0,-65.406 c 0,-8.055 2.49,-11.7 10.54,-11.7 9.21,0 13.24,1.731 13.24,23.399 l 11.12,0 c 0,-31.258 -9.97,-34.52 -24.16,-34.52 -18.03,0 -23.02,5.563 -23.02,20.137 l 0,68.09" /><path
+         id="path92"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 2148.47,327.086 12.28,0 0,-97.82 -12.28,0 0,97.82 z m 0,41.047 12.28,0 0,-16.301 -12.28,0 0,16.301" /><path
+         id="path94"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 2218.67,238.855 c 19.56,0 22.62,2.879 22.62,39.325 0,36.437 -3.06,39.312 -22.62,39.312 -19.58,0 -22.64,-2.875 -22.64,-39.312 0,-36.446 3.06,-39.325 22.64,-39.325 z m 0,89.766 c 32.21,0 36.05,-11.508 36.05,-50.441 0,-40.477 -4.22,-50.446 -36.05,-50.446 -31.85,0 -36.07,9.969 -36.07,50.446 0,38.933 3.84,50.441 36.07,50.441" /><path
+         id="path96"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 2273.3,327.086 12.28,0 0,-12.656 0.38,0 c 6.14,10.547 12.85,14.191 27.05,14.191 22.63,0 28.77,-11.316 28.77,-30.305 l 0,-69.05 -12.28,0 0,66.172 c 0,11.32 -2.5,22.054 -18.6,22.054 -14.96,0 -25.32,-5.75 -25.32,-26.461 l 0,-61.765 -12.28,0 0,97.82" /><path
+         id="path98"
+         style="fill:#e2e3e4;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 2374.17,259.57 c -0.38,-16.875 2.69,-20.715 20.91,-20.715 19.76,0 23.4,2.879 23.4,19.372 0,12.851 -1.34,13.812 -24.55,15.156 -24.55,1.344 -31.26,4.984 -31.26,26.66 0,20.523 3.84,28.578 32.99,28.578 28.58,0 34.14,-6.523 34.14,-27.047 l -12.28,0 c 0,14.965 -4.02,15.918 -22.44,15.918 -17.07,0 -20.14,-1.722 -20.14,-16.875 0,-13.812 1.73,-14.961 22.45,-16.109 28.96,-1.731 33.36,-4.031 33.36,-25.508 0,-23.02 -4.4,-31.266 -36.05,-31.266 -22.44,0 -32.8,2.684 -32.8,31.836 l 12.27,0" /></g></g></svg>
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/assets/images/defaultLogo.svg.d.ts b/sdnr/wt/odlux/framework/src/assets/images/defaultLogo.svg.d.ts
new file mode 100644
index 0000000..60e4856
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/assets/images/defaultLogo.svg.d.ts
@@ -0,0 +1,19 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+declare const path: string;
+export default path;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/common/event.ts b/sdnr/wt/odlux/framework/src/common/event.ts
new file mode 100644
index 0000000..9134879
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/common/event.ts
@@ -0,0 +1,81 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+
+/**
+  * Represents an event.
+  * Events enable a class or object to notify other classes or objects when something of interest occurs.
+  * The class that sends (or invokes) the event is called the publisher and the classes that receive (or handle) the event are called subscribers.
+  * 
+  * Objects can create an instances of an Events and offer that Events for other objects to attach to.
+  * Objects who want to be informed about an Event can attach a function (an event handler) to the event which is then called when the event is fired.
+  * 
+  * @template TEventArg Type of the event argument. Use void if the event does not has an argument.
+  */
+export class Event<TEventArg> {
+
+  /**
+   * Creates a new instance of the Event class.
+   */
+  constructor() {
+    this.eventHandlers = new Array<(arg: TEventArg) => void>();
+  }
+
+  /**
+   * Adds an event handler to this event, so that when the event is fired the given event handler function is called.
+   * 
+   * @param eventHandler The event handler function to add to this event.
+   * @throws {Error} Thrown if the given event handler function has already been added to this event.
+   */
+  public addHandler = (eventHandler: (arg: TEventArg) => void): void => {
+    if (this.eventHandlers.indexOf(eventHandler) > -1) {
+      throw new Error("The given event handler is already added to this event.");
+    }
+
+    this.eventHandlers.push(eventHandler);
+  }
+
+  /**
+   * Removes an event handler from this event, so that the given event handler function will not be called anymore when the event is fired.
+   * 
+   * @param eventHandler: The event handler function to remove.
+   * @throws {Error} Thrown if the given event handler function has not been added to this event before.
+   */
+  public removeHandler = (eventHandler: (arg: TEventArg) => void): void => {
+    const index = this.eventHandlers.indexOf(eventHandler);
+    if (!(index > -1)) {
+      throw new Error("The given event handler has not been added to this event yet.");
+    }
+
+    this.eventHandlers.splice(index, 1);
+  }
+
+  /**
+   * Invokes the event and calls all event handler functions currently registered on the event.
+   * 
+   * @param argument The argument for the event. The argument will be passed to all registered event handler functions.
+   */
+  public invoke = (argument?: TEventArg): void => {
+    this.eventHandlers.forEach((eventHandler: (arg?: TEventArg) => void, index: number, array: Array<(arg: TEventArg) => void>): void => {
+      eventHandler(argument);
+    });
+  }
+
+  private eventHandlers: Array<(arg?: TEventArg) => void>;
+
+}
diff --git a/sdnr/wt/odlux/framework/src/components/errorDisplay.tsx b/sdnr/wt/odlux/framework/src/components/errorDisplay.tsx
new file mode 100644
index 0000000..4cf63e9
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/errorDisplay.tsx
@@ -0,0 +1,126 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
+
+import Modal from '@material-ui/core/Modal';
+import Button from '@material-ui/core/Button';
+import Card from '@material-ui/core/Card';
+import CardActions from '@material-ui/core/CardActions';
+import CardContent from '@material-ui/core/CardContent';
+import Typography from '@material-ui/core/Typography';
+
+import { ClearErrorInfoAction, RemoveErrorInfoAction } from '../actions/errorActions';
+
+import connect, { Connect } from '../flux/connect';
+
+const styles = (theme: Theme) => createStyles({
+  modal: {
+    display: "flex",
+    alignItems: "center",
+    justifyContent: "center",
+  },
+  paper: {
+    width: theme.spacing(50),
+    backgroundColor: theme.palette.background.paper,
+    boxShadow: theme.shadows[5],
+    padding: theme.spacing(4),
+  },
+  card: {
+    minWidth: 275,
+  },
+  bullet: {
+    display: 'inline-block',
+    margin: '0 2px',
+    transform: 'scale(0.8)',
+  },
+  title: {
+    marginBottom: 16,
+    fontSize: 14,
+  },
+  pos: {
+    marginBottom: 12,
+  },
+});
+
+type ErrorDisplayProps = WithStyles<typeof styles> & Connect;
+
+// function getModalStyle() {
+//   const top = 50 + rand();
+//   const left = 50 + rand();
+
+//   return {
+//     top: `${ top }%`,
+//     left: `${ left }%`,
+//     transform: `translate(-${ top }%, -${ left }%)`,
+//   };
+// }
+
+/**
+ * Represents a compnent for formaing and displaying errors.
+ */
+class ErrorDisplayComponent extends React.Component<ErrorDisplayProps> {
+  constructor(props: ErrorDisplayProps) {
+    super(props);
+  }
+
+  render(): JSX.Element {
+    const { classes, state } = this.props;
+    const errorInfo = state.framework.applicationState.errors.length && state.framework.applicationState.errors[state.framework.applicationState.errors.length - 1];
+    return (
+      <Modal className={classes.modal}
+        aria-labelledby="simple-modal-title"
+        aria-describedby="simple-modal-description"
+        open={state.framework.applicationState.errors && state.framework.applicationState.errors.length > 0}
+        onClose={() => this.props.dispatch(new ClearErrorInfoAction())}
+      >
+        {errorInfo &&
+          <div className={classes.paper}>
+            <Card className={classes.card}>
+              <CardContent>
+                <Typography className={classes.title} color="textSecondary">
+                  {errorInfo.title != null ? errorInfo.title : "Something went wrong."}
+                </Typography>
+                <Typography variant="h5" component="h2">
+                  {errorInfo.error && errorInfo.error.toString()}
+                </Typography>
+                <Typography className={classes.pos} color="textSecondary">
+                  {errorInfo.message && errorInfo.message.toString()}
+                </Typography>
+                <Typography component="p">
+                  {errorInfo.info && errorInfo.info.componentStack && errorInfo.info.componentStack.split('\n').map(line => {
+                    return [line, <br />];
+                  })}
+                  {errorInfo.info && errorInfo.info.extra && errorInfo.info.extra.split('\n').map(line => {
+                    return [line, <br />];
+                  })}
+                </Typography>
+              </CardContent>
+              <CardActions>
+                <Button size="small" onClick={() => this.props.dispatch(new RemoveErrorInfoAction(errorInfo))} >Close</Button>
+              </CardActions>
+            </Card>
+          </div> || <div></div>
+        }
+      </Modal>
+    );
+  }
+}
+
+export const ErrorDisplay = withStyles(styles)(connect()(ErrorDisplayComponent));
+export default ErrorDisplay;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/logo.tsx b/sdnr/wt/odlux/framework/src/components/logo.tsx
new file mode 100644
index 0000000..470eb96
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/logo.tsx
@@ -0,0 +1,98 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+/******************************************************************************
+ * Copyright 2018 highstreet technologies GmbH
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *****************************************************************************/
+
+import * as React from 'react';
+import { withRouter, RouteComponentProps } from 'react-router-dom';
+
+import { WithStyles, withStyles, createStyles, Theme } from '@material-ui/core/styles'; // infra for styling
+
+
+import defaultLogo from '../assets/images/defaultLogo.svg';
+
+const styles = (theme: Theme) => createStyles({
+  headerLogo: {
+    backgroundImage: "url(" + (theme.design && theme.design.url || defaultLogo) + ")",
+    backgroundColor: theme.palette.primary.main,
+    backgroundRepeat: "no-repeat",
+    backgroundSize: "auto " + (theme.design && theme.design.logoHeight || 70) + "px",
+    height: theme.design && theme.design.logoHeight || 70,
+    width: theme.design ? theme.design.width / theme.design.height * theme.design.logoHeight : 220
+  }
+});
+
+type LogoProps = RouteComponentProps<{ id: string }> & WithStyles<typeof styles>;
+interface ILogoState {
+  windowWidth: number
+}
+
+class LogoComponent extends React.Component<LogoProps, ILogoState> {
+
+  private hideLogoWhenWindowWidthIsLower: number = 800;
+
+  constructor(props: LogoProps) {
+    super(props);
+    this.state = {
+      windowWidth: 0
+    };
+    this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
+  }
+
+  componentDidMount(): void {
+    this.updateWindowDimensions();
+    window.addEventListener('resize', this.updateWindowDimensions);
+  };
+  componentWillUnmount(): void {
+    window.removeEventListener('resize', this.updateWindowDimensions);
+  };
+  updateWindowDimensions(): void {
+    this.setState({ windowWidth: window.innerWidth });
+  }
+
+  render(): JSX.Element {
+    let div: JSX.Element = <div />;
+    if (this.state.windowWidth >= this.hideLogoWhenWindowWidthIsLower) {
+      div = <div className={this.props.classes.headerLogo} />;
+    } else {
+      console.info([
+        "Logo hidden, because browser window width (",
+        this.state.windowWidth,
+        "px) is lower thershold (",
+        this.hideLogoWhenWindowWidthIsLower,
+        "px)."].join(''));
+    }
+    return div;
+  }
+}
+
+export const Logo = withStyles(styles)(withRouter(LogoComponent));
+export default Logo;
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts b/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts
new file mode 100644
index 0000000..c051420
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-table/columnModel.ts
@@ -0,0 +1,54 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+

+import * as React from 'react';

+

+export enum ColumnType {

+  text,

+  numeric,

+  boolean,

+  custom

+}

+

+type CustomControl<TData> = {

+  className?: string;

+  style?: React.CSSProperties;

+  rowData: TData;

+}

+

+export type ColumnModel<TData> = {

+  title?: string;

+  disablePadding?: boolean;

+  width?: string | number;

+  className?: string;

+  style?: React.CSSProperties;

+  align?: 'inherit' | 'left' | 'center' | 'right' | 'justify';

+  disableSorting?: boolean;

+  disableFilter?: boolean;

+} & ({

+  property: string;

+  type: ColumnType.custom;

+  customControl: React.ComponentType<CustomControl<TData>>;

+} | {

+  property: keyof TData;

+  type: ColumnType.boolean;

+  labels?: { "true": string, "false": string };

+} | {

+    property: keyof TData;

+    type?: ColumnType.numeric | ColumnType.text;

+});
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/index.tsx b/sdnr/wt/odlux/framework/src/components/material-table/index.tsx
new file mode 100644
index 0000000..3e31c5e
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-table/index.tsx
@@ -0,0 +1,552 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
+
+import Table from '@material-ui/core/Table';
+import TableBody from '@material-ui/core/TableBody';
+import TableCell from '@material-ui/core/TableCell';
+import TablePagination from '@material-ui/core/TablePagination';
+import TableRow from '@material-ui/core/TableRow';
+import Paper from '@material-ui/core/Paper';
+import Checkbox from '@material-ui/core/Checkbox';
+
+import { TableToolbar } from './tableToolbar';
+import { EnhancedTableHead } from './tableHead';
+import { EnhancedTableFilter } from './tableFilter';
+
+import { ColumnModel, ColumnType } from './columnModel';
+import { Omit } from '@material-ui/core';
+import { SvgIconProps } from '@material-ui/core/SvgIcon/SvgIcon';
+import { replaceHyphen } from '../../utilities/yangHelper';
+import { string } from 'prop-types';
+export { ColumnModel, ColumnType } from './columnModel';
+
+type propType = string | number | null | undefined | (string | number)[];
+type dataType = { [prop: string]: propType };
+type resultType<TData = dataType> = { page: number, total: number, rows: TData[] };
+
+export type DataCallback<TData = dataType> = (page?: number, rowsPerPage?: number, orderBy?: string | null, order?: 'asc' | 'desc' | null, filter?: { [property: string]: string }) => resultType<TData> | Promise<resultType<TData>>;
+
+function desc(a: dataType, b: dataType, orderBy: string) {
+  if ((b[orderBy] || "") < (a[orderBy] || "")) {
+    return -1;
+  }
+  if ((b[orderBy] || "") > (a[orderBy] || "")) {
+    return 1;
+  }
+  return 0;
+}
+
+function stableSort(array: dataType[], cmp: (a: dataType, b: dataType) => number) {
+  const stabilizedThis = array.map((el, index) => [el, index]) as [dataType, number][];
+  stabilizedThis.sort((a, b) => {
+    const order = cmp(a[0], b[0]);
+    if (order !== 0) return order;
+    return a[1] - b[1];
+  });
+  return stabilizedThis.map(el => el[0]);
+}
+
+function getSorting(order: 'asc' | 'desc' | null, orderBy: string) {
+  return order === 'desc' ? (a: dataType, b: dataType) => desc(a, b, orderBy) : (a: dataType, b: dataType) => -desc(a, b, orderBy);
+}
+
+const styles = (theme: Theme) => createStyles({
+  root: {
+    width: '100%',
+    marginTop: theme.spacing(3),
+  },
+  table: {
+    minWidth: 1020,
+  },
+  tableWrapper: {
+    overflowX: 'auto',
+  },
+});
+
+export type MaterialTableComponentState<TData = {}> = {
+  order: 'asc' | 'desc';
+  orderBy: string | null;
+  selected: any[] | null;
+  rows: TData[];
+  total: number;
+  page: number;
+  rowsPerPage: number;
+  loading: boolean;
+  showFilter: boolean;
+  filter: { [property: string]: string };
+};
+
+export type TableApi = { forceRefresh?: () => Promise<void> };
+
+type MaterialTableComponentBaseProps<TData> = WithStyles<typeof styles> & {
+  columns: ColumnModel<TData>[];
+  idProperty: keyof TData | ((data: TData) => React.Key);
+  tableId?: string;
+  title?: string;
+  enableSelection?: boolean;
+  disableSorting?: boolean;
+  disableFilter?: boolean;
+  customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void }[];
+  onHandleClick?(event: React.MouseEvent<HTMLTableRowElement>, rowData: TData): void;
+};
+
+type MaterialTableComponentPropsWithRows<TData = {}> = MaterialTableComponentBaseProps<TData> & { rows: TData[]; asynchronus?: boolean; };
+type MaterialTableComponentPropsWithRequestData<TData = {}> = MaterialTableComponentBaseProps<TData> & { onRequestData: DataCallback; tableApi?: TableApi; };
+type MaterialTableComponentPropsWithExternalState<TData = {}> = MaterialTableComponentBaseProps<TData> & MaterialTableComponentState & {
+  onToggleFilter: () => void;
+  onFilterChanged: (property: string, filterTerm: string) => void;
+  onHandleChangePage: (page: number) => void;
+  onHandleChangeRowsPerPage: (rowsPerPage: number | null) => void;
+  onHandleRequestSort: (property: string) => void;
+};
+
+type MaterialTableComponentProps<TData = {}> =
+  MaterialTableComponentPropsWithRows<TData> |
+  MaterialTableComponentPropsWithRequestData<TData> |
+  MaterialTableComponentPropsWithExternalState<TData>;
+
+function isMaterialTableComponentPropsWithRows(props: MaterialTableComponentProps): props is MaterialTableComponentPropsWithRows {
+  return (props as MaterialTableComponentPropsWithRows).rows !== undefined && (props as MaterialTableComponentPropsWithRows).rows instanceof Array;
+}
+
+function isMaterialTableComponentPropsWithRequestData(props: MaterialTableComponentProps): props is MaterialTableComponentPropsWithRequestData {
+  return (props as MaterialTableComponentPropsWithRequestData).onRequestData !== undefined && (props as MaterialTableComponentPropsWithRequestData).onRequestData instanceof Function;
+}
+
+function isMaterialTableComponentPropsWithRowsAndRequestData(props: MaterialTableComponentProps): props is MaterialTableComponentPropsWithExternalState {
+  const propsWithExternalState = (props as MaterialTableComponentPropsWithExternalState)
+  return propsWithExternalState.onFilterChanged instanceof Function ||
+    propsWithExternalState.onHandleChangePage instanceof Function ||
+    propsWithExternalState.onHandleChangeRowsPerPage instanceof Function ||
+    propsWithExternalState.onToggleFilter instanceof Function ||
+    propsWithExternalState.onHandleRequestSort instanceof Function
+}
+
+class MaterialTableComponent<TData extends {} = {}> extends React.Component<MaterialTableComponentProps, MaterialTableComponentState> {
+
+  constructor(props: MaterialTableComponentProps) {
+    super(props);
+
+    const page = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.page : 0;
+    const rowsPerPage = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.rowsPerPage || 10 : 10;
+
+    this.state = {
+      filter: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.filter || {} : {},
+      showFilter: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.showFilter : false,
+      loading: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.loading : false,
+      order: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.order : 'asc',
+      orderBy: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.orderBy : null,
+      selected: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.selected : null,
+      rows: isMaterialTableComponentPropsWithRows(this.props) && this.props.rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) || [],
+      total: isMaterialTableComponentPropsWithRows(this.props) && this.props.rows.length || 0,
+      page,
+      rowsPerPage,
+    };
+
+    if (isMaterialTableComponentPropsWithRequestData(this.props)) {
+      this.update();
+
+      if (this.props.tableApi) {
+        this.props.tableApi.forceRefresh = () => this.update();
+      }
+    }
+  }
+  render(): JSX.Element {
+    const { classes, columns } = this.props;
+    const { rows, total: rowCount, order, orderBy, selected, rowsPerPage, page, showFilter, filter } = this.state;
+    const emptyRows = rowsPerPage - Math.min(rowsPerPage, rowCount - page * rowsPerPage);
+    const getId = typeof this.props.idProperty !== "function" ? (data: TData) => ((data as { [key: string]: any })[this.props.idProperty as any as string] as string | number) : this.props.idProperty;
+    const toggleFilter = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.onToggleFilter : () => { !this.props.disableFilter && this.setState({ showFilter: !showFilter }, this.update) }
+    return (
+      <Paper className={classes.root}>
+        <TableToolbar tableId={this.props.tableId} numSelected={selected && selected.length} title={this.props.title} customActionButtons={this.props.customActionButtons} onExportToCsv={this.exportToCsv}
+          onToggleFilter={toggleFilter} />
+        <div className={classes.tableWrapper}>
+          <Table className={classes.table} aria-labelledby="tableTitle">
+            <EnhancedTableHead
+              columns={columns}
+              numSelected={selected && selected.length}
+              order={order}
+              orderBy={orderBy}
+              onSelectAllClick={this.handleSelectAllClick}
+              onRequestSort={this.onHandleRequestSort}
+              rowCount={rows.length}
+              enableSelection={this.props.enableSelection}
+            />
+            <TableBody>
+              {showFilter && <EnhancedTableFilter columns={columns} filter={filter} onFilterChanged={this.onFilterChanged} enableSelection={this.props.enableSelection} /> || null}
+              {rows // may need ordering here
+                .map((entry: TData & { [key: string]: any }) => {
+                  const entryId = getId(entry);
+                  const isSelected = this.isSelected(entryId);
+                  return (
+                    <TableRow
+                      hover
+                      onClick={event => this.handleClick(event, entry, entryId)}
+                      role="checkbox"
+                      aria-checked={isSelected}
+                      tabIndex={-1}
+                      key={entryId}
+                      selected={isSelected}
+                    >
+                      {this.props.enableSelection
+                        ? <TableCell padding="checkbox" style={{ width: "50px" }}>
+                          <Checkbox checked={isSelected} />
+                        </TableCell>
+                        : null
+                      }
+                      {
+                        this.props.columns.map(
+                          col => {
+                            const style = col.width ? { width: col.width } : {};
+                            return (
+                              <TableCell key={col.property} align={col.type === ColumnType.numeric && !col.align ? "right" : col.align} style={style}>
+                                {col.type === ColumnType.custom && col.customControl
+                                  ? <col.customControl className={col.className} style={col.style} rowData={entry} />
+                                  : col.type === ColumnType.boolean
+                                    ? <span className={col.className} style={col.style}>{col.labels ? col.labels[entry[col.property] ? "true" : "false"] : String(entry[col.property])}</span>
+                                    : <span className={col.className} style={col.style}>{String(entry[col.property])}</span>
+                                }
+                              </TableCell>
+                            );
+                          }
+                        )
+                      }
+                    </TableRow>
+                  );
+                })}
+              {emptyRows > 0 && (
+                <TableRow style={{ height: 49 * emptyRows }}>
+                  <TableCell colSpan={this.props.columns.length} />
+                </TableRow>
+              )}
+            </TableBody>
+          </Table>
+        </div>
+        <TablePagination
+          rowsPerPageOptions={[5, 10, 20, 50]}
+          component="div"
+          count={rowCount}
+          rowsPerPage={rowsPerPage}
+          page={page}
+          backIconButtonProps={{
+            'aria-label': 'Previous Page',
+          }}
+          nextIconButtonProps={{
+            'aria-label': 'Next Page',
+          }}
+          onChangePage={this.onHandleChangePage}
+          onChangeRowsPerPage={this.onHandleChangeRowsPerPage}
+        />
+      </Paper>
+    );
+  }
+
+  static getDerivedStateFromProps(props: MaterialTableComponentProps, state: MaterialTableComponentState & { _rawRows: {}[] }): MaterialTableComponentState & { _rawRows: {}[] } {
+    if (isMaterialTableComponentPropsWithRowsAndRequestData(props)) {
+      return {
+        ...state,
+        rows: props.rows,
+        total: props.total,
+        orderBy: props.orderBy,
+        order: props.order,
+        filter: props.filter,
+        loading: props.loading,
+        showFilter: props.showFilter,
+        page: props.page,
+        rowsPerPage: props.rowsPerPage
+      }
+    } else if (isMaterialTableComponentPropsWithRows(props) && props.asynchronus && state._rawRows !== props.rows) {
+      const newState = MaterialTableComponent.updateRows(props, state);
+      return {
+        ...state,
+        ...newState,
+        _rawRows: props.rows || []
+      };
+    }
+    return state;
+  }
+
+  private static updateRows(props: MaterialTableComponentPropsWithRows, state: MaterialTableComponentState): { rows: {}[], total: number, page: number } {
+
+    const { page, rowsPerPage, order, orderBy, filter } = state;
+
+    try {
+      let data: dataType[] = props.rows || [];
+      let filtered = false;
+      if (state.showFilter) {
+        Object.keys(filter).forEach(prop => {
+          const exp = filter[prop];
+          filtered = filtered || exp !== undefined;
+          data = exp !== undefined ? data.filter((val) => {
+            const value = val[prop];
+
+            if (value) {
+
+              if (typeof exp === 'boolean') {
+                return value == exp;
+
+              } else if (typeof exp === 'string') {
+
+                const valueAsString = value.toString();
+                if (exp.length === 0) return value;
+
+                const regex = new RegExp("\\*", "g");
+                const regex2 = new RegExp("\\?", "g");
+
+                const countStar = (exp.match(regex) || []).length;
+                const countQuestionmarks = (exp.match(regex2) || []).length;
+
+                if (countStar > 0 || countQuestionmarks > 0) {
+                  let editableExpression = exp;
+
+                  if (!exp.startsWith('*')) {
+                    editableExpression = '^' + exp;
+                  }
+
+                  if (!exp.endsWith('*')) {
+                    editableExpression = editableExpression + '$';
+                  }
+
+                  const expressionAsRegex = editableExpression.replace(/\*/g, ".*").replace(/\?/g, ".");
+
+                  return valueAsString.match(new RegExp(expressionAsRegex, "g"));
+                }
+                else if (exp.includes('>=')) {
+                  return Number(valueAsString) >= Number(exp.replace('>=', ''));
+                } else if (exp.includes('<=')) {
+                  return Number(valueAsString) <= Number(exp.replace('<=', ''));
+                } else
+                  if (exp.includes('>')) {
+                    return Number(valueAsString) > Number(exp.replace('>', ''));
+                  } else if (exp.includes('<')) {
+                    return Number(valueAsString) < Number(exp.replace('<', ''));
+                  }
+              }
+            }
+
+            return (value == exp)
+          }) : data;
+        });
+      }
+
+      const rowCount = data.length;
+
+      if (page > 0 && rowsPerPage * page > rowCount) { //if result is smaller than the currently shown page, new search and repaginate
+        let newPage = Math.floor(rowCount / rowsPerPage);
+        return {
+          rows: data,
+          total: rowCount,
+          page: newPage
+        };
+      } else {
+        data = (orderBy && order
+          ? stableSort(data, getSorting(order, orderBy))
+          : data).slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
+
+        return {
+          rows: data,
+          total: rowCount,
+          page: page
+        };
+      }
+
+
+    } catch (e) {
+      console.error(e);
+      return {
+        rows: [],
+        total: 0,
+        page: page
+      }
+    }
+  }
+
+  private async update() {
+    if (isMaterialTableComponentPropsWithRequestData(this.props)) {
+      const response = await Promise.resolve(
+        this.props.onRequestData(
+          this.state.page, this.state.rowsPerPage, this.state.orderBy, this.state.order, this.state.showFilter && this.state.filter || {})
+      );
+      this.setState(response);
+    } else {
+      let updateResult = MaterialTableComponent.updateRows(this.props, this.state);
+      this.setState(updateResult);
+    }
+  }
+
+  private onFilterChanged = (property: string, filterTerm: string) => {
+    if (isMaterialTableComponentPropsWithRowsAndRequestData(this.props)) {
+      this.props.onFilterChanged(property, filterTerm);
+      return;
+    }
+    if (this.props.disableFilter) return;
+    const colDefinition = this.props.columns && this.props.columns.find(col => col.property === property);
+    if (colDefinition && colDefinition.disableFilter) return;
+
+    const filter = { ...this.state.filter, [property]: filterTerm };
+    this.setState({
+      filter
+    }, this.update);
+  };
+
+  private onHandleRequestSort = (event: React.SyntheticEvent, property: string) => {
+    if (isMaterialTableComponentPropsWithRowsAndRequestData(this.props)) {
+      this.props.onHandleRequestSort(property);
+      return;
+    }
+    if (this.props.disableSorting) return;
+    const colDefinition = this.props.columns && this.props.columns.find(col => col.property === property);
+    if (colDefinition && colDefinition.disableSorting) return;
+
+    const orderBy = this.state.orderBy === property && this.state.order === 'desc' ? null : property;
+    const order = this.state.orderBy === property && this.state.order === 'asc' ? 'desc' : 'asc';
+    this.setState({
+      order,
+      orderBy
+    }, this.update);
+  };
+
+  handleSelectAllClick: () => {};
+
+  private onHandleChangePage = (event: any | null, page: number) => {
+    if (isMaterialTableComponentPropsWithRowsAndRequestData(this.props)) {
+      this.props.onHandleChangePage(page);
+      return;
+    }
+    this.setState({
+      page
+    }, this.update);
+  };
+
+  private onHandleChangeRowsPerPage = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
+    if (isMaterialTableComponentPropsWithRowsAndRequestData(this.props)) {
+      this.props.onHandleChangeRowsPerPage(+(event && event.target.value));
+      return;
+    }
+    const rowsPerPage = +(event && event.target.value);
+    if (rowsPerPage && rowsPerPage > 0) {
+      this.setState({
+        rowsPerPage
+      }, this.update);
+    }
+  };
+
+  private isSelected(id: string | number): boolean {
+    let selected = this.state.selected || [];
+    const selectedIndex = selected.indexOf(id);
+    return (selectedIndex > -1);
+  }
+
+  private handleClick(event: any, rowData: TData, id: string | number): void {
+    if (this.props.onHandleClick instanceof Function) {
+      this.props.onHandleClick(event, rowData);
+      return;
+    }
+    if (!this.props.enableSelection) {
+      return;
+    }
+    let selected = this.state.selected || [];
+    const selectedIndex = selected.indexOf(id);
+    if (selectedIndex > -1) {
+      selected = [
+        ...selected.slice(0, selectedIndex),
+        ...selected.slice(selectedIndex + 1)
+      ];
+    } else {
+      selected = [
+        ...selected,
+        id
+      ];
+    }
+    this.setState({
+      selected
+    });
+  }
+
+
+  private exportToCsv = async () => {
+    let file;
+    let data: dataType[] | null = null;
+    let csv: string[] = [];
+
+    if (isMaterialTableComponentPropsWithRequestData(this.props)) {
+      // table with extra request handler 
+      this.setState({ loading: true });
+      const result = await Promise.resolve(
+        this.props.onRequestData(0, 1000, this.state.orderBy, this.state.order, this.state.showFilter && this.state.filter || {})
+      );
+      data = result.rows;
+      this.setState({ loading: true });
+    } else if (isMaterialTableComponentPropsWithRowsAndRequestData(this.props)) {
+      // table with generated handlers note: exports data shown on current page
+      data = this.props.rows;
+    }
+    else {
+      // table with local data
+      data = MaterialTableComponent.updateRows(this.props, this.state).rows;
+    }
+
+    if (data && data.length > 0) {
+      csv.push(this.props.columns.map(col => col.title || col.property).join(',') + "\r\n");
+      this.state.rows && this.state.rows.forEach((row: any) => {
+        csv.push(this.props.columns.map(col => row[col.property]).join(',') + "\r\n");
+      });
+      const properties = { type: "text/csv;charset=utf-8" }; // Specify the file's mime-type.
+      try {
+        // Specify the filename using the File constructor, but ...
+        file = new File(csv, "export.csv", properties);
+      } catch (e) {
+        // ... fall back to the Blob constructor if that isn't supported.
+        file = new Blob(csv, properties);
+      }
+    }
+    if (!file) return;
+    var reader = new FileReader();
+    reader.onload = function (e) {
+      const dataUri = reader.result as any;
+      const link = document.createElement("a");
+      if (typeof link.download === 'string') {
+        link.href = dataUri;
+        link.download = "export.csv";
+
+        //Firefox requires the link to be in the body
+        document.body.appendChild(link);
+
+        //simulate click
+        link.click();
+
+        //remove the link when done
+        document.body.removeChild(link);
+      } else {
+        window.open(dataUri);
+      }
+    }
+    reader.readAsDataURL(file);
+
+    // const url = URL.createObjectURL(file);
+    // window.location.replace(url);
+  }
+}
+
+export type MaterialTableCtorType<TData extends {} = {}> = new () => React.Component<Omit<MaterialTableComponentProps<TData>, 'classes'>>;
+
+export const MaterialTable = withStyles(styles)(MaterialTableComponent);
+export default MaterialTable;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx
new file mode 100644
index 0000000..737ea85
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx
@@ -0,0 +1,88 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import * as React from 'react';
+import { ColumnModel, ColumnType } from './columnModel';
+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
+
+
+import TableCell from '@material-ui/core/TableCell';
+import TableRow from '@material-ui/core/TableRow';
+import Input from '@material-ui/core/Input';
+import { Select, FormControl, InputLabel, MenuItem } from '@material-ui/core';
+
+
+const styles = (theme: Theme) => createStyles({
+  container: {
+    display: 'flex',
+    flexWrap: 'wrap',
+  },
+  input: {
+    margin: theme.spacing(1),
+  },
+});
+
+interface IEnhancedTableFilterComponentProps extends WithStyles<typeof styles> {
+  onFilterChanged: (property: string, filterTerm: string) => void;
+  filter: { [property: string]: string };
+  columns: ColumnModel<{}>[];
+  enableSelection?: boolean;
+}
+
+class EnhancedTableFilterComponent extends React.Component<IEnhancedTableFilterComponentProps> {
+  createFilterHandler = (property: string) => (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
+    this.props.onFilterChanged && this.props.onFilterChanged(property, event.target.value);
+  };
+
+  render() {
+    const { columns, filter, classes } = this.props;
+    return (
+      <TableRow>
+        {this.props.enableSelection
+          ? <TableCell padding="checkbox" style={{ width: "50px" }}>
+          </TableCell>
+          : null
+        }
+        {columns.map(col => {
+          const style = col.width ? { width: col.width } : {};
+          return (
+            <TableCell
+              key={col.property}
+              padding={col.disablePadding ? 'none' : 'default'}
+              style={style}
+            >
+              {col.disableFilter || (col.type === ColumnType.custom)
+                ? null
+                : (col.type === ColumnType.boolean)
+                  ? <Select className={classes.input} value={filter[col.property] !== undefined ? filter[col.property] : ''} onChange={this.createFilterHandler(col.property)} inputProps={{ name: `${col.property}-bool`, id: `${col.property}-bool` }} >
+                    <MenuItem value={undefined}>
+                      <em>None</em>
+                    </MenuItem>
+                    <MenuItem value={true as any as string}>{col.labels ? col.labels["true"] : "true"}</MenuItem>
+                    <MenuItem value={false as any as string}>{col.labels ? col.labels["false"] : "false"}</MenuItem>
+                  </Select>
+                  : <Input className={classes.input} inputProps={{ 'aria-label': 'Filter' }} value={filter[col.property] || ''} onChange={this.createFilterHandler(col.property)} />}
+            </TableCell>
+          );
+        }, this)}
+      </TableRow>
+    );
+  }
+}
+
+export const EnhancedTableFilter = withStyles(styles)(EnhancedTableFilterComponent);
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx
new file mode 100644
index 0000000..428f4cf
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-table/tableHead.tsx
@@ -0,0 +1,101 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import * as React from 'react';
+import { ColumnModel, ColumnType } from './columnModel';
+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
+
+import TableSortLabel from '@material-ui/core/TableSortLabel';
+import TableCell from '@material-ui/core/TableCell';
+import TableHead from '@material-ui/core/TableHead';
+import TableRow from '@material-ui/core/TableRow';
+import Checkbox from '@material-ui/core/Checkbox';
+import Tooltip from '@material-ui/core/Tooltip';
+
+interface IEnhancedTableHeadComponentProps {
+  numSelected: number | null;
+  onRequestSort: (event: React.SyntheticEvent, property: string) => void;
+  onSelectAllClick: () => void;
+  order: 'asc' | 'desc';
+  orderBy: string | null;
+  rowCount: number;
+  columns: ColumnModel<{}>[];
+  enableSelection?: boolean;
+}
+
+class EnhancedTableHeadComponent extends React.Component<IEnhancedTableHeadComponentProps> {
+  createSortHandler = (property: string) => (event: React.SyntheticEvent) => {
+    this.props.onRequestSort(event, property);
+  };
+
+  render() {
+    const { onSelectAllClick, order, orderBy, numSelected, rowCount, columns } = this.props;
+
+    return (
+      <TableHead>
+        <TableRow>
+          { this.props.enableSelection 
+           ? <TableCell padding="checkbox" style={ { width: "50px" } }>
+              <Checkbox
+                 indeterminate={ numSelected && numSelected > 0 && numSelected < rowCount || undefined }
+                 checked={ numSelected === rowCount }
+                 onChange={ onSelectAllClick }
+              />
+            </TableCell>
+          : null
+          }
+          { columns.map(col => {
+            const style = col.width ? { width: col.width } : {};
+            return (
+              <TableCell
+                key={ col.property }
+                align={ col.type === ColumnType.numeric ? 'right' : 'left' } 
+                padding={ col.disablePadding ? 'none' : 'default' }
+                sortDirection={ orderBy === (col.property) ? order : false }
+                style={ style }
+              >
+                { col.disableSorting || (col.type === ColumnType.custom)
+                  ? <TableSortLabel
+                    active={ false }
+                    direction={ undefined }
+                  >
+                    { col.title || col.property }
+                  </TableSortLabel>
+                  : <Tooltip
+                    title="Sort"
+                    placement={ col.type === ColumnType.numeric ? 'bottom-end' : 'bottom-start' }
+                    enterDelay={ 300 }
+                  >
+                    <TableSortLabel
+                      active={ orderBy === col.property }
+                      direction={ order || undefined }
+                      onClick={ this.createSortHandler(col.property) }
+                    >
+                      { col.title || col.property }
+                    </TableSortLabel>
+                  </Tooltip> }
+              </TableCell>
+            );
+          }, this) }
+        </TableRow>
+      </TableHead>
+    );
+  }
+}
+
+export const EnhancedTableHead = EnhancedTableHeadComponent;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx
new file mode 100644
index 0000000..a4080b5
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx
@@ -0,0 +1,149 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
+
+import IconButton from '@material-ui/core/IconButton';
+import Tooltip from '@material-ui/core/Tooltip';
+import Toolbar from '@material-ui/core/Toolbar';
+import Typography from '@material-ui/core/Typography';
+import DeleteIcon from '@material-ui/icons/Delete';
+import MoreIcon from '@material-ui/icons/MoreVert';
+import FilterListIcon from '@material-ui/icons/FilterList';
+import MenuItem from '@material-ui/core/MenuItem';
+import Menu from '@material-ui/core/Menu';
+import { lighten } from '@material-ui/core/styles/colorManipulator';
+import { SvgIconProps } from '@material-ui/core/SvgIcon/SvgIcon';
+
+const styles = (theme: Theme) => createStyles({
+  root: {
+    paddingRight: theme.spacing(1),
+  },
+  highlight:
+    theme.palette.type === 'light'
+      ? {
+        color: theme.palette.secondary.main,
+        backgroundColor: lighten(theme.palette.secondary.light, 0.85),
+      }
+      : {
+        color: theme.palette.text.primary,
+        backgroundColor: theme.palette.secondary.dark,
+      },
+  spacer: {
+    flex: '1 1 100%',
+  },
+  actions: {
+    color: theme.palette.text.secondary,
+    display: "flex",
+    flex: "auto",
+    flexDirection: "row"
+  },
+  title: {
+    flex: '0 0 auto',
+  },
+  menuButton: {
+    marginLeft: -12,
+    marginRight: 20,
+  },
+});
+
+interface ITableToolbarComponentProps extends WithStyles<typeof styles> {
+  numSelected: number | null;
+  title?: string;
+  tableId?: string;
+  customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void }[];
+  onToggleFilter: () => void;
+  onExportToCsv: () => void;
+}
+
+class TableToolbarComponent extends React.Component<ITableToolbarComponentProps, { anchorEl: EventTarget & HTMLElement | null }> {
+  constructor(props: ITableToolbarComponentProps) {
+    super(props);
+
+    this.state = {
+      anchorEl: null
+    };
+  }
+
+  private handleMenu = (event: React.MouseEvent<HTMLElement>) => {
+    this.setState({ anchorEl: event.currentTarget });
+  };
+
+  private handleClose = () => {
+    this.setState({ anchorEl: null });
+  };
+  render() {
+    const { numSelected, classes } = this.props;
+    const open = !!this.state.anchorEl;
+    const buttonPrefix = this.props.tableId !== undefined ? this.props.tableId + '-' : '';
+    return (
+      <Toolbar className={`${classes.root} ${numSelected && numSelected > 0 ? classes.highlight : ''} `} >
+        <div className={classes.title}>
+          {numSelected && numSelected > 0 ? (
+            <Typography color="inherit" variant="subtitle1">
+              {numSelected} selected
+          </Typography>
+          ) : (
+              <Typography variant="h5" id="tableTitle">
+                {this.props.title || null}
+              </Typography>
+            )}
+        </div>
+        <div className={classes.spacer} />
+        <div className={classes.actions}>
+          {this.props.customActionButtons
+            ? this.props.customActionButtons.map((action, ind) => (
+              <Tooltip key={`custom-action-${ind}`} title={action.tooltip}>
+                <IconButton aria-label={buttonPrefix + `custom-action-${ind}`} onClick={() => action.onClick()}>
+                  <action.icon />
+                </IconButton>
+              </Tooltip>
+            ))
+            : null}
+          {numSelected && numSelected > 0 ? (
+            <Tooltip title="Delete">
+              <IconButton aria-label={buttonPrefix + "delete"}>
+                <DeleteIcon />
+              </IconButton>
+            </Tooltip>
+          ) : (
+              <Tooltip title="Filter list">
+                <IconButton aria-label={buttonPrefix + "filter-list"} onClick={() => { this.props.onToggleFilter && this.props.onToggleFilter() }}>
+                  <FilterListIcon />
+                </IconButton>
+              </Tooltip>
+            )}
+          <Tooltip title="Actions">
+            <IconButton color="inherit"
+              aria-owns={open ? 'menu-appbar' : undefined}
+              aria-haspopup="true"
+              onClick={this.handleMenu} >
+              <MoreIcon />
+            </IconButton>
+          </Tooltip>
+          <Menu id="menu-appbar" anchorEl={this.state.anchorEl} anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
+            transformOrigin={{ vertical: 'top', horizontal: 'right' }} open={open} onClose={this.handleClose} >
+            <MenuItem onClick={this.props.onExportToCsv}>Export as CSV</MenuItem>
+          </Menu>
+        </div>
+      </Toolbar>
+    );
+  }
+};
+
+export const TableToolbar = withStyles(styles)(TableToolbarComponent);
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts b/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts
new file mode 100644
index 0000000..6e8902c
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts
@@ -0,0 +1,263 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action, IActionHandler } from '../../flux/action';
+import { Dispatch } from '../../flux/store';
+
+import { AddErrorInfoAction } from '../../actions/errorActions';
+import { IApplicationStoreState } from '../../store/applicationStore';
+
+import { DataCallback } from ".";
+export interface IExternalTableState<TData> {
+  order: 'asc' | 'desc';
+  orderBy: string | null;
+  selected: any[] | null;
+  rows: TData[];
+  total: number;
+  page: number;
+  rowsPerPage: number;
+  loading: boolean;
+  showFilter: boolean;
+  filter: { [property: string]: string };
+  preFilter: { [property: string]: string };
+}
+
+/** Create an actionHandler and actions for external table states. */
+export function createExternal<TData>(callback: DataCallback<TData>, selectState: (appState: IApplicationStoreState) => IExternalTableState<TData>) {
+
+  //#region Actions
+  abstract class TableAction extends Action { }
+
+
+  class RequestSortAction extends TableAction {
+    constructor(public orderBy: string) {
+      super();
+    }
+  }
+
+  class SetSelectedAction extends TableAction {
+    constructor(public selected: TData[] | null) {
+      super();
+    }
+  }
+
+  class SetPageAction extends TableAction {
+    constructor(public page: number) {
+      super();
+    }
+  }
+
+  class SetRowsPerPageAction extends TableAction {
+    constructor(public rowsPerPage: number) {
+      super();
+    }
+  }
+
+  class SetPreFilterChangedAction extends TableAction {
+    constructor(public preFilter: { [key: string]: string }) {
+      super();
+    }
+  }
+
+  class SetFilterChangedAction extends TableAction {
+    constructor(public filter: { [key: string]: string }) {
+      super();
+    }
+  }
+
+  class SetShowFilterAction extends TableAction {
+    constructor(public show: boolean) {
+      super();
+    }
+  }
+
+  class RefreshAction extends TableAction {
+    constructor() {
+      super();
+    }
+  }
+
+  class SetResultAction extends TableAction {
+    constructor(public result: { page: number, total: number, rows: TData[] }) {
+      super();
+    }
+  }
+
+  // #endregion
+
+  //#region Action Handler
+  const externalTableStateInit: IExternalTableState<TData> = {
+    order: 'asc',
+    orderBy: null,
+    selected: null,
+    rows: [],
+    total: 0,
+    page: 0,
+    rowsPerPage: 10,
+    loading: false,
+    showFilter: false,
+    filter: {},
+    preFilter: {}
+  };
+
+  const externalTableStateActionHandler: IActionHandler<IExternalTableState<TData>> = (state = externalTableStateInit, action) => {
+    if (!(action instanceof TableAction)) return state;
+    if (action instanceof RefreshAction) {
+      state = {
+        ...state,
+        loading: true
+      }
+    } else if (action instanceof SetResultAction) {
+      state = {
+        ...state,
+        loading: false,
+        rows: action.result.rows,
+        total: action.result.total,
+        page: action.result.page,
+      }
+    } else if (action instanceof RequestSortAction) {
+      state = {
+        ...state,
+        loading: true,
+        orderBy: state.orderBy === action.orderBy && state.order === 'desc' ? null : action.orderBy,
+        order: state.orderBy === action.orderBy && state.order === 'asc' ? 'desc' : 'asc',
+      }
+    } else if (action instanceof SetShowFilterAction) {
+      state = {
+        ...state,
+        loading: true,
+        showFilter: action.show
+      }
+    } else if (action instanceof SetPreFilterChangedAction) {
+      state = {
+        ...state,
+        loading: true,
+        preFilter: action.preFilter
+      }
+    } else if (action instanceof SetFilterChangedAction) {
+      state = {
+        ...state,
+        loading: true,
+        filter: action.filter
+      }
+    } else if (action instanceof SetPageAction) {
+      state = {
+        ...state,
+        loading: true,
+        page: action.page
+      }
+    } else if (action instanceof SetRowsPerPageAction) {
+      state = {
+        ...state,
+        loading: true,
+        rowsPerPage: action.rowsPerPage
+      }
+    }
+    return state;
+  }
+
+  //const createTableAction(tableAction)
+
+  //#endregion
+  const reloadAction = (dispatch: Dispatch, getAppState: () => IApplicationStoreState) => {
+    dispatch(new RefreshAction());
+    const ownState = selectState(getAppState());
+    const filter = { ...ownState.preFilter, ...(ownState.showFilter && ownState.filter || {}) };
+    Promise.resolve(callback(ownState.page, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)).then(result => {
+
+      if (ownState.page > 0 && ownState.rowsPerPage * ownState.page > result.total) { //if result is smaller than the currently shown page, new search and repaginate
+
+        let newPage = Math.floor(result.total / ownState.rowsPerPage);
+
+        Promise.resolve(callback(newPage, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)).then(result1 => {
+          dispatch(new SetResultAction(result1));
+        });
+
+
+      } else {
+        dispatch(new SetResultAction(result));
+      }
+
+
+    }).catch(error => new AddErrorInfoAction(error));
+  };
+
+  const createPreActions = (dispatch: Dispatch, skipRefresh: boolean = false) => {
+    return {
+      onPreFilterChanged: (preFilter: { [key: string]: string }) => {
+        dispatch(new SetPreFilterChangedAction(preFilter));
+        (!skipRefresh) && dispatch(reloadAction);
+      }
+    };
+  }
+
+  const createActions = (dispatch: Dispatch, skipRefresh: boolean = false) => {
+    return {
+      onRefresh: () => {
+        dispatch(reloadAction);
+      },
+      onHandleRequestSort: (orderBy: string) => {
+        dispatch((dispatch: Dispatch) => {
+          dispatch(new RequestSortAction(orderBy));
+          (!skipRefresh) && dispatch(reloadAction);
+        });
+      },
+      onToggleFilter: () => {
+        dispatch((dispatch: Dispatch, getAppState: () => IApplicationStoreState) => {
+          const { showFilter } = selectState(getAppState());
+          dispatch(new SetShowFilterAction(!showFilter));
+          (!skipRefresh) && dispatch(reloadAction);
+        });
+      },
+      onFilterChanged: (property: string, filterTerm: string) => {
+        dispatch((dispatch: Dispatch, getAppState: () => IApplicationStoreState) => {
+          let { filter } = selectState(getAppState());
+          filter = { ...filter, [property]: filterTerm };
+          dispatch(new SetFilterChangedAction(filter));
+          (!skipRefresh) && dispatch(reloadAction);
+        });
+      },
+      onHandleChangePage: (page: number) => {
+        dispatch((dispatch: Dispatch) => {
+          dispatch(new SetPageAction(page));
+          (!skipRefresh) && dispatch(reloadAction);
+        });
+      },
+      onHandleChangeRowsPerPage: (rowsPerPage: number | null) => {
+        dispatch((dispatch: Dispatch) => {
+          dispatch(new SetRowsPerPageAction(rowsPerPage || 10));
+          (!skipRefresh) && dispatch(reloadAction);
+        });
+      }
+      // selected:
+    };
+  };
+
+  const createProperties = (state: IApplicationStoreState) => {
+    return {
+      ...selectState(state)
+    }
+  }
+
+  return {
+    reloadAction: reloadAction,
+    createActions: createActions,
+    createProperties: createProperties,
+    createPreActions: createPreActions,
+    actionHandler: externalTableStateActionHandler
+  }
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/material-ui/index.ts b/sdnr/wt/odlux/framework/src/components/material-ui/index.ts
new file mode 100644
index 0000000..e0e3fc9
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-ui/index.ts
@@ -0,0 +1,22 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+export { ListItemLink } from './listItemLink';
+export { Panel } from './panel';
+export { ToggleButton, ToggleButtonClassKey } from './toggleButton';
+export { TreeView, ITreeItem, TreeViewCtorType} from './treeView';
+export { Loader } from './loader';
diff --git a/sdnr/wt/odlux/framework/src/components/material-ui/listItemLink.tsx b/sdnr/wt/odlux/framework/src/components/material-ui/listItemLink.tsx
new file mode 100644
index 0000000..1a7e58f
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-ui/listItemLink.tsx
@@ -0,0 +1,67 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';

+import { NavLink, Link, Route } from 'react-router-dom';

+

+import ListItem from '@material-ui/core/ListItem';

+import ListItemIcon from '@material-ui/core/ListItemIcon';

+import ListItemText from '@material-ui/core/ListItemText';

+

+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';

+

+const styles = (theme: Theme) => createStyles({

+  active: {

+    backgroundColor: theme.palette.action.selected

+  }

+});

+

+export interface IListItemLinkProps extends WithStyles<typeof styles> {

+  icon: JSX.Element | null;

+  primary: string | React.ComponentType;

+  secondary?: React.ComponentType;

+  to: string;

+  exact?: boolean;

+}

+

+export const ListItemLink = withStyles(styles)((props: IListItemLinkProps) => {

+  const { icon, primary: Primary, secondary: Secondary, classes, to, exact = false } = props;

+  const renderLink = (itemProps: any): JSX.Element => (<NavLink exact={ exact } to={ to } activeClassName={ classes.active } { ...itemProps } />);

+

+  return (

+       <>

+        <ListItem button component={ renderLink }>

+          { icon

+            ? <ListItemIcon>{ icon }</ListItemIcon>

+            : null

+          }

+        { typeof Primary === 'string'

+          ? <ListItemText primary={ Primary } style={{ padding: 0 }} /> 

+          : <Primary />

+          }

+        </ListItem>

+        { Secondary 

+          ? <Route exact={ exact } path={ to } component={ Secondary } />

+          : null

+        }

+      </>

+    );

+  }

+);

+

+export default ListItemLink;

+

diff --git a/sdnr/wt/odlux/framework/src/components/material-ui/loader.tsx b/sdnr/wt/odlux/framework/src/components/material-ui/loader.tsx
new file mode 100644
index 0000000..5ab2fd4
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-ui/loader.tsx
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+
+import * as React from "react";
+
+import { WithStyles, withStyles, createStyles, Theme } from '@material-ui/core/styles';
+
+const styles = (theme: Theme) => createStyles({
+  "@keyframes spin": {
+    "0%": { transform: "rotate(0deg)" },
+    "100%": { transform: "rotate(360deg)" },
+  },
+  loader: {
+    border: `16px solid ${theme.palette.grey.A200}`,
+    borderTop: `16px solid ${theme.palette.secondary.main}`,
+    borderRadius: "50%",
+    width: "120px",
+    height: "120px",
+    animation: "$spin 2s linear infinite",
+  }
+});
+
+const LoaderComponent: React.FC<WithStyles<typeof styles>> = (props) => {
+  return (
+    <div className={props.classes.loader} />
+  );
+};
+
+export const Loader = withStyles(styles)(LoaderComponent);
diff --git a/sdnr/wt/odlux/framework/src/components/material-ui/panel.tsx b/sdnr/wt/odlux/framework/src/components/material-ui/panel.tsx
new file mode 100644
index 0000000..378d485
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-ui/panel.tsx
@@ -0,0 +1,73 @@
+/**

+ * ============LICENSE_START========================================================================

+ * ONAP : ccsdk feature sdnr wt odlux

+ * =================================================================================================

+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.

+ * =================================================================================================

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

+ * in compliance with the License. You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License

+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

+ * or implied. See the License for the specific language governing permissions and limitations under

+ * the License.

+ * ============LICENSE_END==========================================================================

+ */

+import * as React from 'react';

+

+import { withStyles, Theme, WithStyles, createStyles } from '@material-ui/core/styles';

+

+import { ExpansionPanel, ExpansionPanelSummary, ExpansionPanelDetails, Typography, ExpansionPanelActions } from '@material-ui/core';

+

+import ExpandMoreIcon from '@material-ui/icons/ExpandMore';

+import { SvgIconProps } from '@material-ui/core/SvgIcon';

+

+const styles = (theme: Theme) => createStyles({

+  accordion: {

+    // background: theme.palette.secondary.dark,

+    // color: theme.palette.primary.contrastText

+  },

+  detail: {

+    // background: theme.palette.background.paper,

+    // color: theme.palette.text.primary,

+    position: "relative",

+    display: 'flex',

+    flexDirection: 'column'

+  },

+  text: {

+    // color: theme.palette.common.white,

+    // fontSize: "1rem"

+  },

+});

+

+type PanalProps = WithStyles<typeof styles> & {

+  activePanel: string | null,

+  panelId: string,

+  title: string,

+  customActionButtons?: JSX.Element[];

+  onToggle: (panelId: string | null) => void;

+}

+

+const PanelComponent: React.SFC<PanalProps> = (props) => {

+  const { classes, activePanel, onToggle } = props;

+  return (

+    <ExpansionPanel className={classes.accordion} expanded={activePanel === props.panelId} onChange={() => onToggle(props.panelId)} >

+      <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>

+        <Typography className={classes.text} >{props.title}</Typography>

+      </ExpansionPanelSummary>

+      <ExpansionPanelDetails className={classes.detail}>

+        {props.children}

+      </ExpansionPanelDetails>

+      {props.customActionButtons

+        ? <ExpansionPanelActions>

+          {props.customActionButtons}

+        </ExpansionPanelActions>

+        : null}

+    </ExpansionPanel>

+  );

+};

+

+export const Panel = withStyles(styles)(PanelComponent);

+export default Panel;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/material-ui/snackDisplay.tsx b/sdnr/wt/odlux/framework/src/components/material-ui/snackDisplay.tsx
new file mode 100644
index 0000000..437784c
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-ui/snackDisplay.tsx
@@ -0,0 +1,74 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+
+import { IApplicationStoreState } from '../../store/applicationStore';
+import { Connect, connect, IDispatcher } from '../../flux/connect';
+import { RemoveSnackbarNotification } from '../../actions/snackbarActions';
+
+import { WithSnackbarProps, withSnackbar } from 'notistack';
+
+const mapProps = (state: IApplicationStoreState) => ({
+  notifications: state.framework.applicationState.snackBars
+});
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+  removeSnackbar: (key: number) => {
+    dispatcher.dispatch(new RemoveSnackbarNotification(key));
+   }
+});
+
+type DisplaySnackbarsComponentProps = Connect<typeof mapProps, typeof mapDispatch> & WithSnackbarProps;
+
+class DisplaySnackbarsComponent extends React.Component<DisplaySnackbarsComponentProps> {
+  private displayed: number[] = [];
+
+  private storeDisplayed = (id: number) => {
+    this.displayed = [...this.displayed, id];
+  };
+
+  public shouldComponentUpdate({ notifications: newSnacks = [] }: DisplaySnackbarsComponentProps) {
+    
+    const { notifications: currentSnacks } = this.props;
+    let notExists = false;
+    for (let i = 0; i < newSnacks.length; i++) {
+      if (notExists) continue;
+      notExists = notExists || !currentSnacks.filter(({ key }) => newSnacks[i].key === key).length;
+    }
+    return notExists;
+  }
+
+  componentDidUpdate() {
+    const { notifications = [] } = this.props;
+
+    notifications.forEach(notification => {
+      if (this.displayed.includes(notification.key)) return;
+      const options = notification.options || {};
+      this.props.enqueueSnackbar(notification.message, options);
+      this.storeDisplayed(notification.key);
+      this.props.removeSnackbar(notification.key);
+    });
+  }
+
+  render() {
+    return null;
+  }
+}
+
+const DisplayStackbars = withSnackbar(connect(mapProps, mapDispatch)(DisplaySnackbarsComponent));
+export default DisplayStackbars;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/material-ui/toggleButton.tsx b/sdnr/wt/odlux/framework/src/components/material-ui/toggleButton.tsx
new file mode 100644
index 0000000..1a29d69
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-ui/toggleButton.tsx
@@ -0,0 +1,179 @@
+/**

+ * ============LICENSE_START========================================================================

+ * ONAP : ccsdk feature sdnr wt odlux

+ * =================================================================================================

+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.

+ * =================================================================================================

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

+ * in compliance with the License. You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License

+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

+ * or implied. See the License for the specific language governing permissions and limitations under

+ * the License.

+ * ============LICENSE_END==========================================================================

+ */

+

+import * as React from 'react';

+import classNames from 'classnames';

+import { withStyles, WithStyles, Theme, createStyles } from '@material-ui/core/styles';

+import { fade } from '@material-ui/core/styles/colorManipulator';

+import ButtonBase from '@material-ui/core/ButtonBase';

+

+

+export const styles = (theme: Theme) => createStyles({

+    /* Styles applied to the root element. */

+    root: {

+        ...theme.typography.button,

+        height: 32,

+        minWidth: 48,

+        margin: 0,

+        padding: `${theme.spacing(1 - 4)}px ${theme.spacing(1.5)}px`,

+        borderRadius: 2,

+        willChange: 'opacity',

+        color: fade(theme.palette.action.active, 0.38),

+        '&:hover': {

+            textDecoration: 'none',

+            // Reset on mouse devices

+            backgroundColor: fade(theme.palette.text.primary, 0.12),

+            '@media (hover: none)': {

+                backgroundColor: 'transparent',

+            },

+            '&$disabled': {

+                backgroundColor: 'transparent',

+            },

+        },

+        '&:not(:first-child)': {

+            borderTopLeftRadius: 0,

+            borderBottomLeftRadius: 0,

+        },

+        '&:not(:last-child)': {

+            borderTopRightRadius: 0,

+            borderBottomRightRadius: 0,

+        },

+    },

+    /* Styles applied to the root element if `disabled={true}`. */

+    disabled: {

+        color: fade(theme.palette.action.disabled, 0.12),

+    },

+    /* Styles applied to the root element if `selected={true}`. */

+    selected: {

+        color: theme.palette.action.active,

+        '&:after': {

+            content: '""',

+            display: 'block',

+            position: 'absolute',

+            overflow: 'hidden',

+            borderRadius: 'inherit',

+            width: '100%',

+            height: '100%',

+            left: 0,

+            top: 0,

+            pointerEvents: 'none',

+            zIndex: 0,

+            backgroundColor: 'currentColor',

+            opacity: 0.38,

+        },

+        '& + &:before': {

+            content: '""',

+            display: 'block',

+            position: 'absolute',

+            overflow: 'hidden',

+            width: 1,

+            height: '100%',

+            left: 0,

+            top: 0,

+            pointerEvents: 'none',

+            zIndex: 0,

+            backgroundColor: 'currentColor',

+            opacity: 0.12,

+        },

+    },

+    /* Styles applied to the `label` wrapper element. */

+    label: {

+        width: '100%',

+        display: 'inherit',

+        alignItems: 'inherit',

+        justifyContent: 'inherit',

+    },

+});

+

+export type ToggleButtonClassKey = 'disabled' | 'root' | 'label' | 'selected';

+

+interface IToggleButtonProps extends WithStyles<typeof styles> {

+    className?: string;

+    component?: React.ReactType<IToggleButtonProps>;

+    disabled?: boolean;

+    disableFocusRipple?: boolean;

+    disableRipple?: boolean;

+    selected?: boolean;

+    type?: string;

+    value?: any;

+    onClick?: (event: React.FormEvent<HTMLElement>, value?: any) => void;

+    onChange?: (event: React.FormEvent<HTMLElement>, value?: any) => void;

+}

+

+class ToggleButtonComponent extends React.Component<IToggleButtonProps> {

+    handleChange = (event: React.FormEvent<HTMLElement>) => {

+        const { onChange, onClick, value } = this.props;

+

+        event.stopPropagation();

+        if (onClick) {

+            onClick(event, value);

+            if (event.isDefaultPrevented()) {

+                return;

+            }

+        }

+

+        if (onChange) {

+            onChange(event, value);

+        }

+        event.preventDefault();

+    };

+

+    render() {

+        const {

+            children,

+            className: classNameProp,

+            classes,

+            disableFocusRipple,

+            disabled,

+            selected,

+            ...other

+        } = this.props;

+

+        const className = classNames(

+            classes.root,

+            {

+                [classes.disabled]: disabled,

+                [classes.selected]: selected,

+            },

+            classNameProp,

+        );

+

+        return (

+            <ButtonBase

+                className={className}

+                disabled={disabled}

+                focusRipple={!disableFocusRipple}

+                onClick={this.handleChange}

+                href="#"

+                {...other}

+            >

+                <span className={classes.label}>{children}</span>

+            </ButtonBase>

+        );

+    }

+    public static defaultProps = {

+        disabled: false,

+        disableFocusRipple: false,

+        disableRipple: false,

+    };

+

+    public static muiName = 'ToggleButton';

+}

+

+export const ToggleButton = withStyles(styles, { name: 'MuiToggleButton' })(ToggleButtonComponent);

+export default ToggleButton;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/material-ui/toggleButtonGroup.tsx b/sdnr/wt/odlux/framework/src/components/material-ui/toggleButtonGroup.tsx
new file mode 100644
index 0000000..6460e8a
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-ui/toggleButtonGroup.tsx
@@ -0,0 +1,36 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+import classNames from 'classnames';
+import { withStyles, WithStyles, Theme, createStyles } from '@material-ui/core/styles';
+
+export const styles = (theme: Theme) => createStyles({
+  /* Styles applied to the root element. */
+  root: { 
+    transition: theme.transitions.create('background,box-shadow'),
+    background: 'transparent',
+    borderRadius: 2,
+    overflow: 'hidden',
+  },
+  /* Styles applied to the root element if `selected={true}` or `selected="auto" and `value` set. */
+  selected: {
+    background: theme.palette.background.paper,
+    boxShadow: theme.shadows[2],
+  },
+});
+
diff --git a/sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx b/sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx
new file mode 100644
index 0000000..e4eb3a7
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx
@@ -0,0 +1,268 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+
+import { SvgIconProps } from '@material-ui/core/SvgIcon';
+import { List, ListItem, TextField, ListItemText, ListItemIcon, WithTheme, withTheme, Omit } from '@material-ui/core';
+
+import FileIcon from '@material-ui/icons/InsertDriveFile';
+import CloseIcon from '@material-ui/icons/ExpandLess';
+import OpenIcon from '@material-ui/icons/ExpandMore';
+import FolderIcon from '@material-ui/icons/Folder';
+
+export interface ITreeItem {
+  disabled?: boolean;
+  icon?: React.ComponentType<SvgIconProps>;
+}
+
+type TreeViewComponentState<TData extends ITreeItem = ITreeItem> = {
+  /** All indices of all expanded Items */
+  expandedItems: TData[];
+  /** The index of the active iten or undefined if no item is active. */
+  activeItem: undefined | TData;
+  /** The search term or undefined if search is corrently not active. */
+  searchTerm: undefined | string;
+}
+
+type TreeViewComponentBaseProps<TData extends ITreeItem = ITreeItem> = WithTheme & {
+  items: TData[];
+  contentProperty: keyof Omit<TData, keyof ITreeItem>;
+  childrenProperty: keyof Omit<TData, keyof ITreeItem>;
+  useFolderIcons?: boolean;
+  enableSearchBar?: boolean;
+  autoExpandFolder?: boolean;
+  style?: React.CSSProperties;
+  itemHeight?: number;
+  depthOffset?: number;
+}
+
+type TreeViewComponentWithInternalStateProps<TData extends ITreeItem = ITreeItem> = TreeViewComponentBaseProps<TData> & {
+  onItemClick?: (item: TData) => void;
+  onFolderClick?: (item: TData) => void;
+}
+
+type TreeViewComponentWithExternalStateProps<TData extends ITreeItem = ITreeItem> = TreeViewComponentBaseProps<TData> & TreeViewComponentState<TData> & {
+  onSearch: (searchTerm: string) => void;
+  onItemClick: (item: TData) => void;
+  onFolderClick: (item: TData) => void;
+}
+
+type TreeViewComponentProps<TData extends ITreeItem = ITreeItem> =
+  TreeViewComponentWithInternalStateProps<TData> |
+  TreeViewComponentWithExternalStateProps<TData>;
+
+function isTreeViewComponentWithExternalStateProps<TData extends ITreeItem = ITreeItem>(props: TreeViewComponentProps<TData>): props is TreeViewComponentWithExternalStateProps<TData> {
+  const propsWithExternalState = (props as TreeViewComponentWithExternalStateProps<TData>)
+  return (
+    propsWithExternalState.onSearch instanceof Function ||
+    propsWithExternalState.expandedItems !== undefined ||
+    propsWithExternalState.activeItem !== undefined ||
+    propsWithExternalState.searchTerm !== undefined
+  );
+}
+
+class TreeViewComponent<TData extends ITreeItem> extends React.Component<TreeViewComponentProps<TData>, TreeViewComponentState> {
+
+  /**
+    * Initializes a new instance.
+    */
+  constructor(props: TreeViewComponentProps<TData>) {
+    super(props);
+
+    this.state = {
+      expandedItems: [],
+      activeItem: undefined,
+      searchTerm: undefined
+    };
+  }
+
+  render(): JSX.Element {
+    this.itemIndex = 0;
+    const { searchTerm } = this.state;
+    const { children, items, enableSearchBar } = this.props;
+    const styles = {
+      root: {
+        padding: 0,
+        paddingBottom: 8,
+        paddingTop: children ? 0 : 8,
+        ...this.props.style
+      },
+      search: {
+        padding: `0px ${this.props.theme.spacing(1)}px`
+      }
+    };
+    return (
+      <div style={styles.root}>
+        {children}
+        {enableSearchBar && <TextField label={"Search"} fullWidth={true} style={styles.search} value={searchTerm} onChange={this.onChangeSearchText} /> || null}
+        <List>
+          {this.renderItems(items, searchTerm && searchTerm.toLowerCase())}
+        </List>
+      </div>
+    );
+  }
+
+  private itemIndex: number = 0;
+  private renderItems = (items: TData[], searchTerm: string | undefined, depth: number = 1) => {
+    return items.reduce((acc, item) => {
+
+      const children = this.props.childrenProperty && ((item as any)[this.props.childrenProperty] as TData[]);
+      const childrenJsx = children && this.renderItems(children, searchTerm, depth + 1);
+
+      const expanded = searchTerm
+        ? children && childrenJsx.length > 0
+        : !children
+          ? false
+          : this.state.expandedItems.indexOf(item) > -1;
+      const isFolder = children !== undefined;
+
+      const itemJsx = this.renderItem(item, searchTerm, depth, isFolder, expanded);
+      itemJsx && acc.push(itemJsx);
+
+      if (isFolder && expanded) {
+        acc.push(...childrenJsx);
+      }
+      return acc;
+
+    }, [] as JSX.Element[]);
+  }
+  private renderItem = (item: TData, searchTerm: string | undefined, depth: number, isFolder: boolean, expanded: boolean): JSX.Element | null => {
+    const styles = {
+      item: {
+        paddingLeft: (((this.props.depthOffset || 0) + depth) * this.props.theme.spacing(3)),
+        backgroundColor: this.state.activeItem === item ? this.props.theme.palette.action.selected : undefined,
+        height: this.props.itemHeight || undefined,
+        cursor: item.disabled ? 'not-allowed' : 'pointer',
+        color: item.disabled ? this.props.theme.palette.text.disabled : this.props.theme.palette.text.primary,
+        overflow: 'hidden',
+        transform: 'translateZ(0)',
+      }
+    };
+
+    const text = (item as any)[this.props.contentProperty] as string || ''; // need to keep track of search
+    const matchIndex = searchTerm ? text.toLowerCase().indexOf(searchTerm) : -1;
+    const searchTermLength = searchTerm && searchTerm.length || 0;
+
+    const handleClickCreator = (isIcon: boolean) => (event: React.SyntheticEvent) => {
+      if (item.disabled) return;
+      event.preventDefault();
+      event.stopPropagation();
+      if (isFolder && (this.props.autoExpandFolder || isIcon)) {
+        this.props.onFolderClick ? this.props.onFolderClick(item) : this.onFolderClick(item);
+      } else {
+        this.props.onItemClick ? this.props.onItemClick(item) : this.onItemClick(item);
+      }
+    };
+
+    return ((searchTerm && (matchIndex > -1 || expanded) || !searchTerm)
+      ? (
+        <ListItem key={`tree-list-${this.itemIndex++}`} style={styles.item} onClick={handleClickCreator(false)} button >
+
+          { // display the left icon
+            (this.props.useFolderIcons && <ListItemIcon>{isFolder ? <FolderIcon /> : <FileIcon />}</ListItemIcon>) ||
+            (item.icon && (<ListItemIcon><item.icon /></ListItemIcon>))}
+
+
+          { // highlight search result
+            matchIndex > -1
+              ? (<span>
+                {text.substring(0, matchIndex)}
+                <span
+                  style={{
+                    display: 'inline-block',
+                    backgroundColor: 'rgba(255,235,59,0.5)',
+                    padding: '3px',
+                  }}
+                >
+                  {text.substring(matchIndex, matchIndex + searchTermLength)}
+                </span>
+                {text.substring(matchIndex + searchTermLength)}
+              </span>)
+              : (<ListItemText primary={text} />)
+          }
+
+          { // display the right icon, depending on the state 
+            !isFolder ? null : expanded ? (<OpenIcon onClick={handleClickCreator(true)} />) : (<CloseIcon onClick={handleClickCreator(true)} />)}
+        </ListItem>
+      )
+      : null
+    );
+  }
+
+  private onFolderClick = (item: TData) => {
+    // toggle items with children
+    if (this.state.searchTerm) return;
+    const indexOfItemToToggle = this.state.expandedItems.indexOf(item);
+    if (indexOfItemToToggle === -1) {
+      this.setState({
+        expandedItems: [...this.state.expandedItems, item],
+      });
+    } else {
+      this.setState({
+        expandedItems: [
+          ...this.state.expandedItems.slice(0, indexOfItemToToggle),
+          ...this.state.expandedItems.slice(indexOfItemToToggle + 1),
+        ]
+      });
+    }
+  };
+
+  private onItemClick = (item: TData) => {
+    // activate items without children
+    this.setState({
+      activeItem: item,
+    });
+  };
+
+  private onChangeSearchText = (event: React.ChangeEvent<HTMLInputElement>) => {
+    event.preventDefault();
+    event.stopPropagation();
+
+    if (isTreeViewComponentWithExternalStateProps(this.props)) {
+      this.props.onSearch(event.target.value)
+    } else {
+      this.setState({
+        searchTerm: event.target.value
+      });
+    }
+  };
+
+  static getDerivedStateFromProps(props: TreeViewComponentProps, state: TreeViewComponentState): TreeViewComponentState {
+    if (isTreeViewComponentWithExternalStateProps(props)) {
+      return {
+        ...state,
+        expandedItems: props.expandedItems || [],
+        activeItem: props.activeItem,
+        searchTerm: props.searchTerm
+      };
+    }
+    return state;
+  }
+
+  public static defaultProps = {
+    useFolderIcons: false,
+    enableSearchBar: false,
+    autoExpandFolder: false,
+    depthOffset: 0
+  }
+}
+
+export type TreeViewCtorType<TData extends ITreeItem = ITreeItem> = new () => React.Component<Omit<TreeViewComponentProps<TData>, 'theme'>>;
+
+export const TreeView = withTheme(TreeViewComponent);
+export default TreeView;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx b/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx
new file mode 100644
index 0000000..00d43d9
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/navigationMenu.tsx
@@ -0,0 +1,142 @@
+/**

+ * ============LICENSE_START========================================================================

+ * ONAP : ccsdk feature sdnr wt odlux

+ * =================================================================================================

+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.

+ * =================================================================================================

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

+ * in compliance with the License. You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License

+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

+ * or implied. See the License for the specific language governing permissions and limitations under

+ * the License.

+ * ============LICENSE_END==========================================================================

+ */

+import * as React from 'react';

+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';

+

+import { faHome, faAddressBook } from '@fortawesome/free-solid-svg-icons';

+

+import Drawer from '@material-ui/core/Drawer';

+import List from '@material-ui/core/List';

+

+import Divider from '@material-ui/core/Divider';

+

+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

+

+import ListItemLink from '../components/material-ui/listItemLink';

+

+import connect, { Connect, IDispatcher } from '../flux/connect';

+import { MenuAction } from '../actions/menuAction';

+import * as classNames from 'classnames';

+

+const drawerWidth = 240;

+

+const styles = (theme: Theme) => createStyles({

+  drawerPaper: {

+    position: 'relative',

+    width: drawerWidth,

+  },

+  toolbar: theme.mixins.toolbar,

+  drawerOpen: {

+    width: drawerWidth,

+    transition: theme.transitions.create('width', {

+      easing: theme.transitions.easing.sharp,

+      duration: theme.transitions.duration.enteringScreen,

+    }),

+  },

+  drawerClose: {

+    transition: theme.transitions.create('width', {

+      easing: theme.transitions.easing.sharp,

+      duration: theme.transitions.duration.leavingScreen,

+    }),

+    overflowX: 'hidden',

+    width: theme.spacing(7) + 1,

+    [theme.breakpoints.up('sm')]: {

+      width: theme.spacing(9) + 1,

+    },

+  }

+});

+

+const tabletWidthBreakpoint = 768;

+

+export const NavigationMenu = withStyles(styles)(connect()(({ classes, state, dispatch }: WithStyles<typeof styles> & Connect & Connect) => {

+  const { user } = state.framework.authenticationState

+  const isOpen = state.framework.applicationState.isMenuOpen

+  const closedByUser = state.framework.applicationState.isMenuClosedByUser

+

+  const [responsive, setResponsive] = React.useState(false);

+

+  React.useEffect(() => {

+

+    function handleResize() {

+      if (user && user.isValid) {

+        if (window.innerWidth < tabletWidthBreakpoint && !responsive) {

+          setResponsive(true);

+          if (!closedByUser) {

+            console.log("responsive menu collapsed")

+            dispatch(new MenuAction(false));

+          }

+

+        } else if (window.innerWidth > tabletWidthBreakpoint && responsive) {

+          setResponsive(false);

+          if (!closedByUser) {

+            console.log("responsive menu restored")

+            dispatch(new MenuAction(true));

+          }

+

+        }

+      }

+    }

+    window.addEventListener("resize", handleResize);

+

+

+    return () => {

+      window.removeEventListener("resize", handleResize);

+    }

+  })

+

+  return (

+    <Drawer

+      variant="permanent"

+      className={

+        classNames({

+          [classes.drawerOpen]: isOpen,

+          [classes.drawerClose]: !isOpen

+        })

+      }

+      classes={{

+        paper: classes.drawerPaper,

+      }}

+    >

+      {user && user.isValid && <>

+        <div className={classes.toolbar} />

+        { /* https://fiffty.github.io/react-treeview-mui/ */}

+        <List component="nav">

+          <ListItemLink exact to="/" primary="Home" icon={<FontAwesomeIcon icon={faHome} />} />

+          <Divider />

+          {

+            state.framework.applicationRegistraion && Object.keys(state.framework.applicationRegistraion).map(key => {

+              const reg = state.framework.applicationRegistraion[key];

+              return reg && (

+                <ListItemLink

+                  key={reg.name}

+                  to={reg.path || `/${reg.name}`}

+                  primary={reg.menuEntry || reg.name}

+                  secondary={reg.subMenuEntry}

+                  icon={reg.icon && <FontAwesomeIcon icon={reg.icon} /> || null} />

+              ) || null;

+            }) || null

+          }

+          <Divider />

+          <ListItemLink to="/about" primary="About" icon={<FontAwesomeIcon icon={faAddressBook} />} />

+        </List>

+      </> || null

+      }

+    </Drawer>)

+}));

+

+export default NavigationMenu;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/routing/appFrame.tsx b/sdnr/wt/odlux/framework/src/components/routing/appFrame.tsx
new file mode 100644
index 0000000..e6af2eb
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/routing/appFrame.tsx
@@ -0,0 +1,55 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';

+

+import connect, { Connect } from '../../flux/connect';

+

+import { SetTitleAction } from '../../actions/titleActions';

+import { AddErrorInfoAction } from '../../actions/errorActions';

+

+import { IconType } from '../../models/iconDefinition';

+

+export interface IAppFrameProps  {

+  title: string;

+  icon?: IconType;

+  appId?: string

+}

+

+/**

+ * Represents a component to wich will embed each single app providing the

+ * functionality to update the title and implement an exeprion border.

+ */

+export class AppFrame extends React.Component<IAppFrameProps & Connect> {

+

+  public render(): JSX.Element {

+    return (

+      <div style={{ flex: "1", overflow: "auto", display: "flex", flexDirection: "column" }}>

+        { this.props.children }

+      </div>

+     )

+    }

+

+  public componentDidMount() {

+    this.props.dispatch(new SetTitleAction(this.props.title, this.props.icon, this.props.appId));

+  }

+  public componentDidCatch(error: Error | null, info: object) {

+    this.props.dispatch(new AddErrorInfoAction({ error, info }));

+  }

+}

+

+export default connect()(AppFrame);
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/components/titleBar.tsx b/sdnr/wt/odlux/framework/src/components/titleBar.tsx
new file mode 100644
index 0000000..7168ff4
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/components/titleBar.tsx
@@ -0,0 +1,208 @@
+/**

+ * ============LICENSE_START========================================================================

+ * ONAP : ccsdk feature sdnr wt odlux

+ * =================================================================================================

+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.

+ * =================================================================================================

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

+ * in compliance with the License. You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License

+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

+ * or implied. See the License for the specific language governing permissions and limitations under

+ * the License.

+ * ============LICENSE_END==========================================================================

+ */

+import * as React from 'react';

+import { withRouter, RouteComponentProps } from 'react-router-dom';

+

+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';

+import AppBar from '@material-ui/core/AppBar';

+import Toolbar from '@material-ui/core/Toolbar';

+import Typography from '@material-ui/core/Typography';

+import Button from '@material-ui/core/Button';

+import IconButton from '@material-ui/core/IconButton';

+import Block from '@material-ui/icons/Block';

+import Adjust from '@material-ui/icons/Adjust';

+import MenuIcon from '@material-ui/icons/Menu';

+import AccountCircle from '@material-ui/icons/AccountCircle';

+import MenuItem from '@material-ui/core/MenuItem';

+import Menu from '@material-ui/core/Menu';

+

+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

+import { faBan } from '@fortawesome/free-solid-svg-icons';

+import { faDotCircle } from '@fortawesome/free-solid-svg-icons';

+

+import { UpdateAuthentication } from '../actions/authentication';

+import { ReplaceAction } from '../actions/navigationActions';

+

+import connect, { Connect, IDispatcher } from '../flux/connect';

+import Logo from './logo';

+import { MenuAction, MenuClosedByUser } from '../actions/menuAction';

+

+const styles = (theme: Theme) => createStyles({

+  appBar: {

+    zIndex: theme.zIndex.drawer + 1,

+  },

+  grow: {

+    flexGrow: 1,

+  },

+  menuButton: {

+    marginLeft: -12,

+    marginRight: 20,

+  },

+  icon: {

+    marginLeft: 16,

+    marginRight: 8

+  },

+  connected: {

+    color: "green"

+  },

+  notConnected: {

+    color: "red"

+  },

+  notificationInfo: {

+    marginLeft: 5

+  }

+});

+

+const mapDispatch = (dispatcher: IDispatcher) => {

+  return {

+    logout: () => {

+      dispatcher.dispatch(new UpdateAuthentication(null));

+      dispatcher.dispatch(new ReplaceAction("/login"));

+    },

+    toggleMainMenu: (value: boolean, value2: boolean) => {

+      dispatcher.dispatch(new MenuAction(value));

+      dispatcher.dispatch(new MenuClosedByUser(value2))

+    }

+  }

+};

+

+type TitleBarProps = RouteComponentProps<{}> & WithStyles<typeof styles> & Connect<undefined, typeof mapDispatch>

+

+class TitleBarComponent extends React.Component<TitleBarProps, { anchorEl: HTMLElement | null }> {

+

+  constructor(props: TitleBarProps) {

+    super(props);

+    this.state = {

+      anchorEl: null

+    }

+

+  }

+  render(): JSX.Element {

+    const { classes, state, history, location } = this.props;

+    const open = !!this.state.anchorEl;

+    let toolbarElements: Array<JSX.Element>;

+    toolbarElements = [];

+

+    // create notificationInfo element

+    const notificationInfo = state.framework.applicationState.isWebsocketAvailable != undefined ?

+      (state.framework.applicationState.isWebsocketAvailable ?

+        <Typography variant="body1" className={classes.notificationInfo}>Notifications <FontAwesomeIcon className={classes.connected} icon={faDotCircle} />  |</Typography> : <Typography variant="body1" className={classes.notificationInfo}>Notifications <FontAwesomeIcon className={classes.notConnected} icon={faBan} /> |</Typography>)

+      : <Typography variant="body1" className={classes.notificationInfo}>Notifications N/A |</Typography>;

+

+

+    // add notificationInfo element before help

+    if (state.framework.applicationRegistraion) {

+      let isNotificationInfoAdded = false;

+      Object.keys(state.framework.applicationRegistraion).map(key => {

+        const reg = state.framework.applicationRegistraion[key];

+        if (reg && reg.statusBarElement) {

+          if (key === "help") {

+            isNotificationInfoAdded = true;

+            toolbarElements.push(notificationInfo);

+          }

+          toolbarElements.push(<reg.statusBarElement key={key} />);

+        }

+      });

+

+      // add notificationInfo in case help wasn't found

+      if (!isNotificationInfoAdded) {

+        toolbarElements.push(notificationInfo);

+      }

+    }

+

+    return (

+      <AppBar position="absolute" className={classes.appBar}>

+        <Toolbar>

+          <IconButton className={classes.menuButton} color="inherit" aria-label="Menu" onClick={this.toggleMainMenu}>

+            <MenuIcon />

+          </IconButton>

+          <Logo />

+          <Typography variant="h6" color="inherit" >

+            {state.framework.applicationState.icon

+              ? (<FontAwesomeIcon className={classes.icon} icon={state.framework.applicationState.icon} />)

+              : null}

+            {state.framework.applicationState.title}

+          </Typography>

+          <div className={classes.grow}></div>

+          {

+            // render toolbar

+            toolbarElements.map((item) => {

+              return item

+            })

+          }

+

+          {state.framework.authenticationState.user

+            ? (<div>

+              <Button aria-label="current user menu button"

+                aria-owns={open ? 'menu-appbar' : undefined}

+                aria-haspopup="true"

+                onClick={this.openMenu}

+                color="inherit"

+              >

+                <AccountCircle />

+                {state.framework.authenticationState.user.user}

+              </Button>

+              <Menu

+                id="menu-appbar"

+                anchorEl={this.state.anchorEl}

+                anchorOrigin={{

+                  vertical: 'top',

+                  horizontal: 'right',

+                }}

+                transformOrigin={{

+                  vertical: 'top',

+                  horizontal: 'right',

+                }}

+                open={open}

+                onClose={this.closeMenu}

+              >

+                {/* <MenuItem onClick={ this.closeMenu }>Profile</MenuItem> */}

+                <MenuItem onClick={() => {

+                  this.props.logout();

+                  this.closeMenu();

+                }}>Logout</MenuItem>

+              </Menu>

+            </div>)

+            : (<Button onClick={() => { history.push('/login') }} color="inherit" disabled={location.pathname == "/login"}>Login</Button>)}

+        </Toolbar>

+      </AppBar>

+    );

+  };

+

+  private toggleMainMenu = (event: React.MouseEvent<HTMLElement>) => {

+    console.log(this.props);

+    if (this.props.state.framework.authenticationState.user && this.props.state.framework.authenticationState.user.isValid) {

+      const isMainMenuOpen = this.props.state.framework.applicationState.isMenuOpen

+      const isClosedByUser = this.props.state.framework.applicationState.isMenuClosedByUser

+      this.props.toggleMainMenu(!isMainMenuOpen, !isClosedByUser);

+    }

+  }

+

+  private openMenu = (event: React.MouseEvent<HTMLElement>) => {

+    this.setState({ anchorEl: event.currentTarget });

+  };

+

+  private closeMenu = () => {

+    this.setState({ anchorEl: null });

+  };

+}

+

+//todo: ggf. https://github.com/acdlite/recompose verwenden zur Vereinfachung

+

+export const TitleBar = withStyles(styles)(withRouter(connect(undefined, mapDispatch)(TitleBarComponent)));

+export default TitleBar;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/design/default.ts b/sdnr/wt/odlux/framework/src/design/default.ts
new file mode 100644
index 0000000..542c436
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/design/default.ts
@@ -0,0 +1,80 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+/******************************************************************************
+ * Copyright 2018 highstreet technologies GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *****************************************************************************/
+
+import { createMuiTheme } from '@material-ui/core/styles';
+
+const theme = createMuiTheme({
+  design: {
+    id: "onap",
+    name: "Open Networking Automation Plattform (ONAP)",
+    url: "https://www.onap.org/wp-content/uploads/sites/20/2017/02/logo_onap_2017.png",
+    height: 49,
+    width: 229,
+    logoHeight: 32,
+  },
+  palette: {
+    primary: {
+      light: "#eeeeee",
+      main: "#ffffff",
+      dark: "#e0e0e0",
+      contrastText: "#07819B"
+    },
+    secondary: {
+      light: "rgba(7, 129, 155, 94)",
+      main: "rgba(7, 129, 155, 201)",
+      dark: "#07819B",
+      contrastText: "#ffffff"
+    },
+  },
+  overrides: { //temp fix for labels turning white after material new version (palette primary color)
+    MuiFormLabel: {
+      root: {
+        "&$focused": {
+          color: "rgba(143,143,143,1)"
+        }
+      },
+
+      focused: {}
+    },
+    MuiInput: {
+      underline: {
+
+        "&:after": {
+          borderBottom: "2px solid #444444"
+        }
+      }
+    }
+  },
+});
+
+export default theme;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/favicon.ico b/sdnr/wt/odlux/framework/src/favicon.ico
new file mode 100644
index 0000000..a8a5d31
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/favicon.ico
Binary files differ
diff --git a/sdnr/wt/odlux/framework/src/flux/action.ts b/sdnr/wt/odlux/framework/src/flux/action.ts
new file mode 100644
index 0000000..7689025
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/flux/action.ts
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+/**
+  * Represents an action in the odlux flux architecture.
+  */
+export abstract class Action { }
+
+export interface IActionHandler<TState, TAction extends Action = Action> {
+  (state: TState | undefined, action: TAction): TState;
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/flux/connect.ts b/sdnr/wt/odlux/framework/src/flux/connect.ts
new file mode 100644
index 0000000..f54e4e0
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/flux/connect.ts
@@ -0,0 +1,161 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+import * as PropTypes from 'prop-types';
+
+import { Dispatch } from '../flux/store';
+
+import { ApplicationStore, IApplicationStoreState } from '../store/applicationStore';
+
+interface IApplicationStoreContext {
+  applicationStore: ApplicationStore;
+}
+
+export interface IDispatcher {
+  dispatch: Dispatch;
+}
+
+interface IApplicationStoreProps {
+  state: IApplicationStoreState;
+}
+
+interface IDispatchProps {
+  dispatch: Dispatch;
+}
+
+type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
+
+type ComponentDecoratorInfer<TMergedProps> = {
+  <TProps>(wrappedComponent: React.ComponentType<TProps & TMergedProps>): React.ComponentClass<Omit<TProps & TMergedProps, keyof TMergedProps>>;
+};
+
+export type Connect<TMapProps extends ((...args: any) => any) | undefined = undefined, TMapDispatch extends ((...args: any) => any) | undefined = undefined> =
+  (TMapProps extends ((...args: any) => any) ? ReturnType<TMapProps> : IApplicationStoreProps) &
+  (TMapDispatch extends ((...args: any) => any) ? ReturnType<TMapDispatch> : IDispatchProps);
+
+export function connect(): ComponentDecoratorInfer<IApplicationStoreProps & IDispatchProps>;
+
+export function connect<TStateProps>(
+  mapStateToProps: (state: IApplicationStoreState) => TStateProps
+): ComponentDecoratorInfer<TStateProps & IDispatchProps>;
+
+export function connect<TStateProps, TDispatchProps>(
+  mapStateToProps: (state: IApplicationStoreState) => TStateProps,
+  mapDispatchToProps: (dispatcher: IDispatcher) => TDispatchProps
+): ComponentDecoratorInfer<TStateProps & TDispatchProps>;
+
+
+export function connect<TDispatchProps>(
+  mapStateToProps: undefined,
+  mapDispatchToProps: (dispatcher: IDispatcher) => TDispatchProps
+): ComponentDecoratorInfer<IApplicationStoreProps & TDispatchProps>;
+
+
+export function connect<TProps, TStateProps, TDispatchProps>(
+  mapStateToProps?: ((state: IApplicationStoreState) => TStateProps),
+  mapDispatchToProps?: ((dispatcher: IDispatcher) => TDispatchProps)
+):
+  ((WrappedComponent: React.ComponentType<TProps & (IApplicationStoreProps | TStateProps) & IDispatchProps>) => React.ComponentType<TProps>) {
+
+  const injectApplicationStore = (WrappedComponent: React.ComponentType<TProps & (IApplicationStoreProps | TStateProps) & IDispatchProps>): React.ComponentType<TProps> => {
+
+    class StoreAdapter extends React.Component<TProps, {}> {
+      public static contextTypes = { ...WrappedComponent.contextTypes, applicationStore: PropTypes.object.isRequired };
+      context: IApplicationStoreContext;
+
+      render(): JSX.Element {
+
+        if (isWrappedComponentIsVersion1(WrappedComponent)) {
+          const element = React.createElement(WrappedComponent, { ...(this.props as any), state: this.store.state, dispatch: this.store.dispatch.bind(this.store) });
+          return element;
+        } else if (mapStateToProps && isWrappedComponentIsVersion2(WrappedComponent)) {
+          const element = React.createElement(WrappedComponent, { ...(this.props as any), ...(mapStateToProps(this.store.state) as any), dispatch: this.store.dispatch.bind(this.store) });
+          return element;
+        } else if (mapStateToProps && mapDispatchToProps && isWrappedComponentIsVersion3(WrappedComponent)) {
+          const element = React.createElement(WrappedComponent, { ...(this.props as any), ...(mapStateToProps(this.store.state) as any), ...(mapDispatchToProps({ dispatch: this.store.dispatch.bind(this.store) }) as any) });
+          return element;
+        } else if (!mapStateToProps && mapDispatchToProps && isWrappedComponentIsVersion4(WrappedComponent)) {
+          const element = React.createElement(WrappedComponent, { ...(this.props as any), state: this.store.state, ...(mapDispatchToProps({ dispatch: this.store.dispatch.bind(this.store) }) as any) });
+          return element;
+        }
+        throw new Error("Invalid arguments in connect.");
+      }
+
+      componentDidMount(): void {
+        this.store && this.store.changed.addHandler(this.handleStoreChanged);
+      }
+
+      componentWillUnmount(): void {
+        this.store && this.store.changed.removeHandler(this.handleStoreChanged);
+      }
+
+      private get store(): ApplicationStore {
+        return this.context.applicationStore;
+      }
+
+      private handleStoreChanged = () => {
+        this.forceUpdate();
+      }
+    }
+
+    return StoreAdapter;
+  }
+
+
+  return injectApplicationStore;
+
+  /* inline methods */
+
+  function isWrappedComponentIsVersion1(wrappedComponent: any): wrappedComponent is React.ComponentType<TProps & IApplicationStoreProps & IDispatchProps> {
+    return !mapStateToProps && !mapDispatchToProps;
+  }
+
+  function isWrappedComponentIsVersion2(wrappedComponent: any): wrappedComponent is React.ComponentType<TProps & TStateProps & IDispatchProps> {
+    return !!mapStateToProps && !mapDispatchToProps;
+  }
+
+  function isWrappedComponentIsVersion3(wrappedComponent: any): wrappedComponent is React.ComponentType<TProps & TStateProps & TDispatchProps> {
+    return !!mapStateToProps && !!mapDispatchToProps;
+  }
+
+  function isWrappedComponentIsVersion4(wrappedComponent: any): wrappedComponent is React.ComponentType<TProps & TStateProps & TDispatchProps> {
+    return !mapStateToProps && !!mapDispatchToProps;
+  }
+}
+
+interface ApplicationStoreProviderProps extends React.Props<ApplicationStoreProvider> {
+  applicationStore: ApplicationStore;
+}
+
+export class ApplicationStoreProvider extends React.Component<ApplicationStoreProviderProps>
+  implements /* React.ComponentLifecycle<ApplicationStoreProviderProps, any>, */ React.ChildContextProvider<IApplicationStoreContext> {
+
+  public static childContextTypes = { applicationStore: PropTypes.object.isRequired };
+
+  getChildContext(): IApplicationStoreContext {
+    return {
+      applicationStore: this.props.applicationStore
+    };
+  }
+
+  render(): JSX.Element {
+    return React.Children.only(this.props.children) as any; //type error, fix when possible
+  }
+}
+
+export default connect;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/flux/middleware.ts b/sdnr/wt/odlux/framework/src/flux/middleware.ts
new file mode 100644
index 0000000..de6505c
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/flux/middleware.ts
@@ -0,0 +1,107 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action, IActionHandler } from './action';
+import { Store, Dispatch, Enhancer } from './store';
+
+export interface MiddlewareArg<T> {
+  dispatch: Dispatch;
+  getState: () => T;
+}
+
+export interface Middleware<T> {
+  (obj: MiddlewareArg<T>): Function;
+}
+
+class InitialisationAction extends Action { };
+const initialisationAction = new InitialisationAction();
+
+export type ActionHandlerMapObject<S extends { [key: string]: any }, A extends Action = Action> = {
+  [K in keyof S]: IActionHandler<S[K], A>
+}
+
+export const combineActionHandler = <TState extends { [key: string]: any }, TAction extends Action = Action>(actionHandlers: ActionHandlerMapObject<TState, TAction>) : IActionHandler<TState, TAction> => {
+  const finalActionHandlers = {} as { [key: string]: any }; // https://github.com/microsoft/TypeScript/issues/31808
+  Object.keys(actionHandlers).forEach(actionHandlerKey => {
+    const handler = actionHandlers[actionHandlerKey];
+    if (typeof handler === 'function') {
+      finalActionHandlers[actionHandlerKey] = handler;
+    }
+  });
+
+  // ensure initialisation
+  Object.keys(finalActionHandlers).forEach(key => {
+    const actionHandler = finalActionHandlers[key];
+    const initialState = actionHandler(undefined, initialisationAction);
+    if (typeof initialState === 'undefined') {
+      const errorMessage = `Action handler ${ key } returned undefiend during initialization.`;
+      throw new Error(errorMessage);
+    }
+  });
+
+  return function combination<TAction extends Action>(state: TState = ({} as TState), action: TAction) {
+    let hasChanged = false;
+    const nextState = {} as { [key: string]: any }; // https://github.com/microsoft/TypeScript/issues/31808
+    Object.keys(finalActionHandlers).forEach(key => {
+      const actionHandler = finalActionHandlers[key];
+      const previousState = state[key];
+      const nextStateKey = actionHandler(previousState, action);
+      if (typeof nextStateKey === 'undefined') {
+        const errorMessage = `Given ${ action.constructor } and action handler ${ key } returned undefiend.`;
+        throw new Error(errorMessage);
+      }
+      nextState[key] = nextStateKey;
+      hasChanged = hasChanged || nextStateKey !== previousState;
+    });
+    return (hasChanged ? nextState : state) as TState;
+  };
+};
+
+export const chainMiddleware = <TStoreState>(...middlewares: Middleware<TStoreState>[]): Enhancer<TStoreState> => {
+  return (store: Store<TStoreState>) => {
+    const middlewareAPI = {
+      getState() { return store.state },
+      dispatch: <TAction extends Action>(action: TAction) => store.dispatch(action) // we want to use the combinded dispatch
+      // we should NOT use the flux dispatcher here, since the action would affect ALL stores
+    };
+    const chain = middlewares.map(middleware => middleware(middlewareAPI));
+    return compose(...chain)(store.dispatch) as Dispatch;
+  }
+};
+
+/**
+ * Composes single-argument functions from right to left. The rightmost
+ * function can take multiple arguments as it provides the signature for
+ * the resulting composite function.
+ *
+ * @param {...Function} funcs The functions to compose.
+ * @returns {Function} A function obtained by composing the argument functions
+ * from right to left. For example, compose(f, g, h) is identical to doing
+ * (...args) => f(g(h(...args))).
+ */
+const compose = (...funcs: Function[]) => {
+  if (funcs.length === 0) {
+    return (arg: any) => arg
+  }
+
+  if (funcs.length === 1) {
+    return funcs[0]
+  }
+
+  return funcs.reduce((a, b) => (...args: any[]) => a(b(...args)));
+};
+
diff --git a/sdnr/wt/odlux/framework/src/flux/store.ts b/sdnr/wt/odlux/framework/src/flux/store.ts
new file mode 100644
index 0000000..dd80ce7
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/flux/store.ts
@@ -0,0 +1,98 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Event } from "../common/event"
+
+import { Action } from './action';
+import { IActionHandler } from './action';
+
+export interface Dispatch {
+  <TAction extends Action>(action: TAction): TAction;
+}
+
+export interface Enhancer<TStoreState> {
+  (store: Store<TStoreState>): Dispatch;
+}
+
+class InitialisationAction extends Action { };
+const initialisationAction = new InitialisationAction();
+
+export class Store<TStoreState> {
+
+  constructor(actionHandler: IActionHandler<TStoreState>, enhancer?: Enhancer<TStoreState>)
+  constructor(actionHandler: IActionHandler<TStoreState>, initialState: TStoreState, enhancer?: Enhancer<TStoreState>)
+  constructor(actionHandler: IActionHandler<TStoreState>, initialState?: TStoreState | Enhancer<TStoreState>, enhancer?: Enhancer<TStoreState>) {
+    if (typeof initialState === 'function') {
+      enhancer = initialState as Enhancer<TStoreState>;
+      initialState = undefined;
+    }
+
+    this._isDispatching = false;
+     
+    this.changed = new Event<void>(); // sollten wir hier eventuell sogar den state mit übergeben ?
+
+    this._actionHandler = actionHandler;
+    
+    this._state = initialState as TStoreState;
+    if (enhancer) this._dispatch = enhancer(this);
+
+    this._dispatch(initialisationAction);
+  }
+
+  public changed: Event<void>;
+
+  private _dispatch: Dispatch = <TAction extends Action>(payload: TAction): TAction => {
+    if (payload == null || !(payload instanceof Action)) {
+      throw new Error(
+        'Actions must inherit from type Action. ' +
+        'Use a custom middleware for async actions.'
+      );
+    }
+    
+    if (this._isDispatching) {
+      throw new Error('ActionHandler may not dispatch actions.');
+    }
+
+    const oldState = this._state;
+    try {
+      this._isDispatching = true;
+      this._state = this._actionHandler(oldState, payload);
+    } finally {
+      this._isDispatching = false;
+    }
+
+    if (this._state !== oldState) {
+      this.changed.invoke();
+    }
+
+    return payload;
+  }
+
+  public get dispatch(): Dispatch {
+    return this._dispatch;
+  }
+
+  public get state() {
+    return this._state
+  }
+
+  private _state: TStoreState;
+  private _isDispatching: boolean;
+  private _actionHandler: IActionHandler<TStoreState>;
+
+}
+
diff --git a/sdnr/wt/odlux/framework/src/handlers/applicationRegistryHandler.ts b/sdnr/wt/odlux/framework/src/handlers/applicationRegistryHandler.ts
new file mode 100644
index 0000000..ec7b0a0
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/handlers/applicationRegistryHandler.ts
@@ -0,0 +1,31 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { IActionHandler } from '../flux/action';
+
+import { ApplicationInfo } from '../models/applicationInfo';
+import { applicationManager } from '../services/applicationManager';
+
+export interface IApplicationRegistration {
+  [name: string]: ApplicationInfo;
+}
+
+const applicationRegistrationInit: IApplicationRegistration = applicationManager.applications;
+
+export const applicationRegistryHandler: IActionHandler<IApplicationRegistration> = (state = applicationRegistrationInit, action) => {
+  return state;
+};
diff --git a/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts b/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts
new file mode 100644
index 0000000..a93f96a
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts
@@ -0,0 +1,108 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { IActionHandler } from '../flux/action';
+import { SetTitleAction } from '../actions/titleActions';
+
+import { AddSnackbarNotification, RemoveSnackbarNotification } from '../actions/snackbarActions';
+import { AddErrorInfoAction, RemoveErrorInfoAction, ClearErrorInfoAction } from '../actions/errorActions';
+import { MenuAction, MenuClosedByUser } from '../actions/menuAction'
+import { IconType } from '../models/iconDefinition';
+
+import { ErrorInfo } from '../models/errorInfo';
+import { SnackbarItem } from '../models/snackbarItem';
+import { SetWebsocketAction } from '../actions/websocketAction';
+
+export interface IApplicationState {
+  title: string;
+  appId?: string;
+  icon?: IconType;
+  isMenuOpen: boolean;
+  isMenuClosedByUser: boolean;
+  errors: ErrorInfo[];
+  snackBars: SnackbarItem[];
+  isWebsocketAvailable: boolean | undefined;
+}
+
+const applicationStateInit: IApplicationState = { title: "Loading ...", errors: [], snackBars: [], isMenuOpen: true, isMenuClosedByUser: false, isWebsocketAvailable: undefined };
+
+export const applicationStateHandler: IActionHandler<IApplicationState> = (state = applicationStateInit, action) => {
+  if (action instanceof SetTitleAction) {
+    state = {
+      ...state,
+      title: action.title,
+      icon: action.icon,
+      appId: action.appId
+    };
+  } else if (action instanceof AddErrorInfoAction) {
+    state = {
+      ...state,
+      errors: [
+        ...state.errors,
+        action.errorInfo
+      ]
+    };
+  } else if (action instanceof RemoveErrorInfoAction) {
+    const index = state.errors.indexOf(action.errorInfo);
+    if (index > -1) {
+      state = {
+        ...state,
+        errors: [
+          ...state.errors.slice(0, index),
+          ...state.errors.slice(index + 1)
+        ]
+      };
+    }
+  } else if (action instanceof ClearErrorInfoAction) {
+    if (state.errors && state.errors.length) {
+      state = {
+        ...state,
+        errors: []
+      };
+    }
+  } else if (action instanceof AddSnackbarNotification) {
+    state = {
+      ...state,
+      snackBars: [
+        ...state.snackBars,
+        action.notification
+      ]
+    };
+  } else if (action instanceof RemoveSnackbarNotification) {
+    state = {
+      ...state,
+      snackBars: state.snackBars.filter(s => s.key !== action.key)
+    };
+  } else if (action instanceof MenuAction) {
+    state = {
+      ...state,
+      isMenuOpen: action.isOpen
+    }
+  } else if (action instanceof MenuClosedByUser) {
+    state = {
+      ...state,
+      isMenuClosedByUser: action.isClosed
+    }
+  }
+  else if (action instanceof SetWebsocketAction) {
+    state = {
+      ...state,
+      isWebsocketAvailable: action.isConnected
+    }
+  }
+  return state;
+};
diff --git a/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts b/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts
new file mode 100644
index 0000000..82b228d
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/handlers/authenticationHandler.ts
@@ -0,0 +1,61 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { IActionHandler } from '../flux/action';
+import { UpdateAuthentication } from '../actions/authentication';
+
+import { User } from '../models/authentication';
+
+import { onLogin, onLogout } from '../services/applicationApi';
+import { startWebsocketSession, endWebsocketSession } from '../services/notificationService';
+
+export interface IAuthenticationState {
+  user?: User;
+}
+
+const initialToken = localStorage.getItem("userToken");
+
+if (initialToken !== null) {
+  startWebsocketSession();
+}
+
+const authenticationStateInit: IAuthenticationState = {
+  user: initialToken && User.fromString(initialToken) || undefined
+};
+
+export const authenticationStateHandler: IActionHandler<IAuthenticationState> = (state = authenticationStateInit, action) => {
+  if (action instanceof UpdateAuthentication) {
+
+    const user = action.bearerToken && new User(action.bearerToken) || undefined;
+    if (user) {
+      localStorage.setItem("userToken", user.toString());
+      startWebsocketSession();
+      onLogin();
+    } else {
+      localStorage.removeItem("userToken");
+      endWebsocketSession();
+      onLogout();
+    }
+
+    state = {
+      ...state,
+      user
+    };
+  }
+
+  return state;
+};
diff --git a/sdnr/wt/odlux/framework/src/handlers/navigationStateHandler.ts b/sdnr/wt/odlux/framework/src/handlers/navigationStateHandler.ts
new file mode 100644
index 0000000..6ecdf2f
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/handlers/navigationStateHandler.ts
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { IActionHandler } from '../flux/action';
+import { LocationChanged } from '../actions/navigationActions';
+
+
+export interface INavigationState {
+  pathname: string;
+  search: string;
+  hash: string;
+}
+
+const navigationStateInit: INavigationState = {
+  pathname: '/',
+  search: '',
+  hash: '',
+};
+
+
+export const navigationStateHandler: IActionHandler<INavigationState> = (state = navigationStateInit, action) => {
+  if (action instanceof LocationChanged) { 
+    state = {
+      ...state,
+      pathname: action.pathname,
+      search: action.search,
+      hash: action.hash
+    }
+  }
+  return state;
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/index.dev.html b/sdnr/wt/odlux/framework/src/index.dev.html
new file mode 100644
index 0000000..71cb740
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/index.dev.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta http-equiv="X-UA-Compatible" content="ie=edge">
+  <!-- <link rel="stylesheet" href="./vendor.css" > -->
+  <title>O D L UX</title>
+</head>
+
+<body>
+  <div id="app"></div>
+  <script type="text/javascript" src="./require.js"></script>
+  <script type="text/javascript" src="./config.js"></script>
+  <script>
+    // run the application
+    require(["app" /*,"connectApp","inventoryApp","faultApp","helpApp"*/], function (app,connectApp,inventoryApp,faultApp,helpApp) {
+      // connectApp.register();
+      // inventoryApp.register();
+      // faultApp.register();
+      // helpApp.register();
+      app("./app.tsx").runApplication();
+    });
+  </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/index.html b/sdnr/wt/odlux/framework/src/index.html
new file mode 100644
index 0000000..1a37339
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/index.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta http-equiv="X-UA-Compatible" content="ie=edge">
+  <!-- <link rel="stylesheet" href="./vendor.css" > -->
+  <title>O D L UX</title>
+</head>
+
+<body>
+  <div id="app"></div>
+  <script type="text/javascript" src="./require.js"></script>
+  <script type="text/javascript" src="./config.js"></script>
+  <script>
+    // run the application
+    require(["run"], function (run) {
+      run.runApplication();
+    });
+  </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/middleware/api.ts b/sdnr/wt/odlux/framework/src/middleware/api.ts
new file mode 100644
index 0000000..8e9bc64
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/middleware/api.ts
@@ -0,0 +1,72 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Action, IActionHandler } from '../flux/action';
+import { MiddlewareArg } from '../flux/middleware';
+import { Dispatch } from '../flux/store';
+
+import { IApplicationStoreState } from '../store/applicationStore';
+import { AddErrorInfoAction, ErrorInfo } from '../actions/errorActions';
+
+const baseUrl = `${ window.location.origin }${ window.location.pathname }`;
+
+export class ApiAction<TResult, TSuccessAction extends Action & { result: TResult }> extends Action {
+  constructor(public endpoint: string, public successAction: { new(result: TResult): TSuccessAction }, public authenticate: boolean = false) {
+    super();
+  }
+}
+
+export const apiMiddleware = (store: MiddlewareArg<IApplicationStoreState>) => (next: Dispatch) => <A extends Action>(action: A) => {
+
+  // So the middleware doesn't get applied to every single action
+  if (action instanceof ApiAction) {
+    const user = store && store.getState().framework.authenticationState.user;
+    const token = user && user.token || null;
+    let config = { headers: {} };
+
+    if (action.authenticate) {
+      if (token) {
+        config = {
+          ...config,
+          headers: {
+            ...config.headers,
+            // 'Authorization': `Bearer ${ token }`
+            authorization: "Basic YWRtaW46YWRtaW4="
+          }
+        }
+      } else {
+        return next(new AddErrorInfoAction({ message: 'Please login to continue.' }));
+      }
+    }
+
+    fetch(baseUrl + action.endpoint.replace(/\/{2,}/, '/'), config)
+      .then(response =>
+        response.json().then(data => ({ data, response }))
+      )
+      .then(result => {
+        next(new action.successAction(result.data));
+      })
+      .catch((error: any) => {
+        next(new AddErrorInfoAction((error instanceof Error) ? { error: error } : { message: error.toString() }));
+      });
+  }
+
+  // let all actions pass
+  return next(action);
+}
+
+export default apiMiddleware;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/middleware/logger.ts b/sdnr/wt/odlux/framework/src/middleware/logger.ts
new file mode 100644
index 0000000..47725e6
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/middleware/logger.ts
@@ -0,0 +1,34 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Dispatch } from '../flux/store';
+import { MiddlewareApi } from '../store/applicationStore';
+
+
+function createLoggerMiddleware() {
+  return function logger({ getState }: MiddlewareApi) {
+    return (next: Dispatch): Dispatch => action => {
+      console.log('will dispatch', action);
+      const returnValue = next(action);
+      console.log('state after dispatch', getState());
+      return returnValue;
+    };
+  }
+}
+
+export const logger = createLoggerMiddleware();
+export default logger;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/middleware/navigation.ts b/sdnr/wt/odlux/framework/src/middleware/navigation.ts
new file mode 100644
index 0000000..d5cdcd4
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/middleware/navigation.ts
@@ -0,0 +1,79 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Location, History, createHashHistory } from "history";
+
+import { ApplicationStore } from "../store/applicationStore";
+import { Dispatch } from '../flux/store';
+
+import { LocationChanged, NavigateToApplication } from "../actions/navigationActions";
+import { PushAction, ReplaceAction, GoAction, GoBackAction, GoForwardeAction } from '../actions/navigationActions';
+
+import { applicationManager } from "../services/applicationManager";
+
+const routerMiddlewareCreator = (history: History) => () => (next: Dispatch): Dispatch => (action) => {
+
+  if (action instanceof NavigateToApplication) {
+    const application = applicationManager.applications && applicationManager.applications[action.applicationName];
+    if (application) {
+      const href = `/${application.path || application.name}${action.href ? '/' + action.href : ''}`.replace(/\/{2,}/i, '/');
+      if (action.replace) {
+        history.replace(href, action.state);
+      } else {
+        history.push(href, action.state);
+      }
+    }
+  } else if (action instanceof PushAction) {
+    history.push(action.href, action.state);
+  } else if (action instanceof ReplaceAction) {
+    history.replace(action.href, action.state);
+  } else if (action instanceof GoAction) {
+    history.go(action.index);
+  } else if (action instanceof GoBackAction) {
+    history.goBack();
+  } else if (action instanceof GoForwardeAction) {
+    history.goForward();
+  } else if (action instanceof LocationChanged) {
+    // ensure user is logged in and token is valid
+    if (!action.pathname.startsWith("/login") && applicationStore && (!applicationStore.state.framework.authenticationState.user || !applicationStore.state.framework.authenticationState.user.isValid)) {
+      history.replace(`/login?returnTo=${action.pathname}`);
+    } else {
+      return next(action);
+    }
+  } else {
+    return next(action);
+  }
+  return action;
+};
+
+function startListener(history: History, store: ApplicationStore) {
+  store.dispatch(new LocationChanged(history.location.pathname, history.location.search, history.location.hash));
+  history.listen((location: Location) => {
+    store.dispatch(new LocationChanged(location.pathname, location.search, location.hash));
+  });
+}
+
+const history = createHashHistory();
+let applicationStore: ApplicationStore | null = null;
+
+export function startHistoryListener(store: ApplicationStore) {
+  applicationStore = store;
+  startListener(history, store);
+}
+
+export const routerMiddleware = routerMiddlewareCreator(history);
+export default routerMiddleware;
diff --git a/sdnr/wt/odlux/framework/src/middleware/thunk.ts b/sdnr/wt/odlux/framework/src/middleware/thunk.ts
new file mode 100644
index 0000000..18f40c4
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/middleware/thunk.ts
@@ -0,0 +1,35 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { Dispatch } from '../flux/store';
+import { MiddlewareApi } from '../store/applicationStore';
+
+function createThunkMiddleware() {
+  return ({ dispatch, getState }: MiddlewareApi) =>
+    (next : Dispatch) : Dispatch =>
+      action => {
+        if (typeof action === 'function') {
+          return action(dispatch, getState);
+        }
+
+        return next(action);
+      };
+}
+
+export const thunk = createThunkMiddleware();
+export default thunk;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/models/applicationInfo.ts b/sdnr/wt/odlux/framework/src/models/applicationInfo.ts
new file mode 100644
index 0000000..0b33777
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/models/applicationInfo.ts
@@ -0,0 +1,52 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { ComponentType } from 'react';
+import { IconType } from './iconDefinition';
+
+import { IActionHandler } from '../flux/action';
+import { Middleware } from '../flux/middleware';
+
+/** Represents the information needed about an application to integrate. */
+export class ApplicationInfo {
+  /** The name of the application. */
+  name: string;
+  /** Optional: The title of the application, if null ot undefined the name will be used. */
+  title?: string;
+  /** Optional: The icon of the application for the navigation and title bar. */
+  icon?: IconType;
+  /** Optional: The description of the application. */
+  description?: string;
+  /** The root component of the application. */
+  rootComponent: ComponentType;
+  /** Optional: The root action handler of the application. */
+  rootActionHandler?: IActionHandler<{ [key: string]: any }>;
+  /** Optional: Application speciffic middlewares. */
+  middlewares?: Middleware<{ [key: string]: any }>[];
+  /** Optional: A mapping object with the exported components. */
+  exportedComponents?: { [key: string]: ComponentType }
+  /** Optional: The entry to be shown in the menu. If undefiened the name will be used. */
+  menuEntry?: string | React.ComponentType;
+  /** Optional: A component to be shown in the menu when this app is active below the main entry. If undefiened the name will be used. */
+  subMenuEntry?: React.ComponentType;
+  /** Optional: A component to be shown in the applications status bar. If undefiened the name will be used. */
+  statusBarElement?: React.ComponentType;
+  /** Optional: A component to be shown in the dashboardview. If undefiened the name will be used. */
+  dashbaordElement?: React.ComponentType;
+  /** Optional: The pasth for this application. If undefined the name will be use as path. */
+  path?: string;
+}
diff --git a/sdnr/wt/odlux/framework/src/models/authentication.ts b/sdnr/wt/odlux/framework/src/models/authentication.ts
new file mode 100644
index 0000000..a50c5de
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/models/authentication.ts
@@ -0,0 +1,58 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+export type AuthToken = {
+  username: string;
+  access_token: string;
+  token_type: string;
+  expires: number;
+}
+
+
+export class User {
+
+  constructor (private _bearerToken: AuthToken) {
+
+  }
+
+  public get user(): string | null {
+    return this._bearerToken && this._bearerToken.username;
+  };
+
+  public get token(): string | null {
+    return this._bearerToken && this._bearerToken.access_token;
+  }
+
+  public get tokenType(): string | null {
+    return this._bearerToken && this._bearerToken.token_type;
+  }
+
+  public get isValid(): boolean {
+    return (this._bearerToken && (new Date().valueOf()) < this._bearerToken.expires) || false;
+  }
+
+  public toString() {
+    return JSON.stringify(this._bearerToken);
+  }
+
+  public static fromString(data: string) {
+    return new User(JSON.parse(data));
+  }
+
+
+}
diff --git a/sdnr/wt/odlux/framework/src/models/elasticSearch.ts b/sdnr/wt/odlux/framework/src/models/elasticSearch.ts
new file mode 100644
index 0000000..12cfd7d
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/models/elasticSearch.ts
@@ -0,0 +1,56 @@
+/**

+ * ============LICENSE_START========================================================================

+ * ONAP : ccsdk feature sdnr wt odlux

+ * =================================================================================================

+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.

+ * =================================================================================================

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

+ * in compliance with the License. You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License

+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

+ * or implied. See the License for the specific language governing permissions and limitations under

+ * the License.

+ * ============LICENSE_END==========================================================================

+ */

+export type Result<TSource extends {}> = {

+  output: {

+    pagination?: {

+      size: number,

+      page: number,

+      total: number

+    },

+    data: TSource[];

+  }

+}

+

+export type HitEntry<TSource extends {}> = {

+  _index: string;

+  _type: string;

+  _id: string;

+  _score: number;

+  _source: TSource;

+}

+

+type ActionResponse ={

+  _index: string;

+  _type: string;

+  _id: string;

+  _shards: {

+    total: number,

+    successful: number,

+    failed: number

+    },

+

+}

+

+export type PostResponse = ActionResponse & {

+  created: boolean

+}

+

+export type DeleteResponse = ActionResponse & {

+  found: boolean

+}

+

diff --git a/sdnr/wt/odlux/framework/src/models/errorInfo.ts b/sdnr/wt/odlux/framework/src/models/errorInfo.ts
new file mode 100644
index 0000000..21217a1
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/models/errorInfo.ts
@@ -0,0 +1,29 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+export type ErrorInfo = {
+  title?: string,
+  error?: Error | null,
+  url?: string,
+  line?: number,
+  col?: number,
+  info?: {
+    extra?: string,
+    componentStack?: string
+  },
+  message?: string
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/models/iconDefinition.ts b/sdnr/wt/odlux/framework/src/models/iconDefinition.ts
new file mode 100644
index 0000000..e93d20e
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/models/iconDefinition.ts
@@ -0,0 +1,21 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { IconDefinition } from '@fortawesome/free-solid-svg-icons';
+
+export type IconType = IconDefinition;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/models/index.ts b/sdnr/wt/odlux/framework/src/models/index.ts
new file mode 100644
index 0000000..4b8dc20
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/models/index.ts
@@ -0,0 +1,18 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+export * from './elasticSearch'; 
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/models/restService.ts b/sdnr/wt/odlux/framework/src/models/restService.ts
new file mode 100644
index 0000000..03f580b
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/models/restService.ts
@@ -0,0 +1,48 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+/**
+  * The PlainObject type is a JavaScript object containing zero or more key-value pairs.
+  */
+export interface PlainObject<T = any> {
+  [key: string]: T;
+}
+
+export interface AjaxParameter {
+  /**
+    * The HTTP method to use for the request (e.g. "POST", "GET", "PUT").
+    */
+  method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'PATCH';
+  /**
+    * An object of additional header key/value pairs to send along with requests using the XMLHttpRequest
+    * transport. The header X-Requested-With: XMLHttpRequest is always added, but its default
+    * XMLHttpRequest value can be changed here. Values in the headers setting can also be overwritten from
+    * within the beforeSend function.
+    */
+  headers?: PlainObject<string | null | undefined>;
+  /**
+    * Data to be sent to the server. It is converted to a query string, if not already a string. It's
+    * appended to the url for GET-requests. See processData option to prevent this automatic processing.
+    * Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same
+    * key based on the value of the traditional setting (described below).
+    */
+  data?: PlainObject | string;
+}
+
+
+
diff --git a/sdnr/wt/odlux/framework/src/models/snackbarItem.ts b/sdnr/wt/odlux/framework/src/models/snackbarItem.ts
new file mode 100644
index 0000000..c10d7ef
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/models/snackbarItem.ts
@@ -0,0 +1,20 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { OptionsObject } from "notistack";
+
+export type SnackbarItem = { key: number, message: string, options?: OptionsObject };
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/run.ts b/sdnr/wt/odlux/framework/src/run.ts
new file mode 100644
index 0000000..10692e8
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/run.ts
@@ -0,0 +1,18 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+export { runApplication } from './app'; 
diff --git a/sdnr/wt/odlux/framework/src/services/applicationApi.ts b/sdnr/wt/odlux/framework/src/services/applicationApi.ts
new file mode 100644
index 0000000..77287f4
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/services/applicationApi.ts
@@ -0,0 +1,61 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { Event } from '../common/event';
+import { ApplicationStore } from '../store/applicationStore';
+
+let resolveApplicationStoreInitialized: (store: ApplicationStore) => void;
+let applicationStore: ApplicationStore | null = null;
+const applicationStoreInitialized: Promise<ApplicationStore> = new Promise((resolve) => resolveApplicationStoreInitialized = resolve);
+
+const loginEvent = new Event();
+const logoutEvent = new Event();
+
+export const onLogin = () => {
+  loginEvent.invoke();
+}
+
+export const onLogout = () => {
+  logoutEvent.invoke();
+}
+
+export const setApplicationStore = (store: ApplicationStore) => {
+  if (!applicationStore && store) {
+    applicationStore = store;
+    resolveApplicationStoreInitialized(store);
+  }
+}
+
+export const applicationApi = {
+  get applicationStore(): ApplicationStore | null {
+    return applicationStore;
+  },
+
+  get applicationStoreInitialized(): Promise<ApplicationStore> {
+    return applicationStoreInitialized;
+  },
+
+  get loginEvent() {
+    return loginEvent;
+  },
+
+  get logoutEvent() {
+    return logoutEvent;
+  }
+};
+
+export default applicationApi;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/services/applicationManager.ts b/sdnr/wt/odlux/framework/src/services/applicationManager.ts
new file mode 100644
index 0000000..14e3ed0
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/services/applicationManager.ts
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { ApplicationInfo } from '../models/applicationInfo';
+import { Event } from '../common/event';
+
+import { applicationApi } from './applicationApi';
+
+/** Represents registry to manage all applications. */
+class ApplicationManager {
+    
+  /** Stores all registerd applications.  */
+  private _applications: { [key: string]: ApplicationInfo }; 
+  
+  /** Initializes a new instance of this class. */
+  constructor() {
+    this._applications = {};
+    this.changed = new Event<void>(); 
+  }
+
+  /** The chaged event will fire if the registration has changed. */
+  public changed: Event<void>;
+
+  /** Registers a new application. */
+  public registerApplication(applicationInfo: ApplicationInfo) {
+    this._applications[applicationInfo.name] = applicationInfo;
+    this.changed.invoke();
+    return applicationApi;
+  }
+
+  /** Gets all registered applications. */
+  public get applications() {
+    return this._applications;
+  }
+}
+
+/** A singleton instance of the application manager. */
+export const applicationManager = new ApplicationManager();
+export default applicationManager;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/services/authenticationService.ts b/sdnr/wt/odlux/framework/src/services/authenticationService.ts
new file mode 100644
index 0000000..d3d62c5
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/services/authenticationService.ts
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { requestRest, formEncode } from "./restService";
+import { AuthToken } from "../models/authentication";
+
+type AuthTokenResponse = {
+  access_token: string;
+  token_type: string;
+  expires_in: number;
+}
+
+
+class AuthenticationService {
+  public async authenticateUser(email: string, password: string, scope: string): Promise<AuthToken | null> {
+    const result = await requestRest<string>(`oauth2/token`, {
+      method: "POST",
+      headers: {
+        'Content-Type': 'application/x-www-form-urlencoded'
+      },
+      body: formEncode({
+        grant_type: "password",
+        username: email,
+        password: password,
+        scope: scope
+      })
+    }, false);
+    const resultObj: AuthTokenResponse| null = result && JSON.parse(result);
+    return resultObj && {
+      username: email,
+      access_token: resultObj.access_token,
+      token_type: resultObj.token_type,
+      expires: (new Date().valueOf()) + (resultObj.expires_in * 1000)
+    } || null;
+  }
+}
+
+export const authenticationService = new AuthenticationService();
+export default authenticationService;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/services/forceLogoutService.ts b/sdnr/wt/odlux/framework/src/services/forceLogoutService.ts
new file mode 100644
index 0000000..ce4faab
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/services/forceLogoutService.ts
@@ -0,0 +1,52 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { ApplicationStore } from "../store/applicationStore";
+import { UpdateAuthentication } from "../actions/authentication";
+import { ReplaceAction } from "../actions/navigationActions";
+
+const maxMinutesTillLogout = 15;
+let applicationStore: ApplicationStore | null;
+let tickTimer = 15;
+
+
+export const startForceLogoutService = (store: ApplicationStore) => {
+    applicationStore = store;
+    createForceLogoutInterval();
+};
+
+const createForceLogoutInterval = () => {
+    console.log("logout timer running...")
+
+    return setInterval(function () {
+        if (applicationStore && applicationStore.state.framework.authenticationState.user) {
+            tickTimer--;
+
+            if (tickTimer === 0) {
+                console.log("got logged out by timer")
+                if (applicationStore) {
+                    applicationStore.dispatch(new UpdateAuthentication(null));
+                    applicationStore.dispatch(new ReplaceAction("/login"));
+                }
+            }
+        }
+
+    }, 1 * 60000)
+}
+
+document.addEventListener("mousemove", function () { tickTimer = maxMinutesTillLogout; }, false)
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/services/index.ts b/sdnr/wt/odlux/framework/src/services/index.ts
new file mode 100644
index 0000000..c6071e7
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/services/index.ts
@@ -0,0 +1,21 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+export { applicationManager } from './applicationManager';

+export { subscribe, unsubscribe } from './notificationService';

+export { requestRest } from './restService';

+

diff --git a/sdnr/wt/odlux/framework/src/services/notificationService.ts b/sdnr/wt/odlux/framework/src/services/notificationService.ts
new file mode 100644
index 0000000..85d3f71
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/services/notificationService.ts
@@ -0,0 +1,190 @@
+/**

+ * ============LICENSE_START========================================================================

+ * ONAP : ccsdk feature sdnr wt odlux

+ * =================================================================================================

+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.

+ * =================================================================================================

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

+ * in compliance with the License. You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License

+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

+ * or implied. See the License for the specific language governing permissions and limitations under

+ * the License.

+ * ============LICENSE_END==========================================================================

+ */

+import * as X2JS from 'x2js';

+import { ApplicationStore } from '../store/applicationStore';

+import { SetWebsocketAction } from '../actions/websocketAction';

+

+const socketUrl = [location.protocol === 'https:' ? 'wss://' : 'ws://', 'admin', ':', 'admin', '@', location.hostname, ':', location.port, '/websocket'].join('');

+const subscriptions: { [scope: string]: SubscriptionCallback[] } = {};

+let socketReady: Promise<WebSocket>;

+let userLoggedOut = false;

+let wasWebsocketConnectionEstablished: undefined | boolean;

+let applicationStore: ApplicationStore | null;

+

+

+export interface IFormatedMessage {

+  notifType: string | null;

+  time: string;

+}

+

+export type SubscriptionCallback<TMessage extends IFormatedMessage = IFormatedMessage> = (msg: TMessage) => void;

+

+function formatData(event: MessageEvent): IFormatedMessage | undefined {

+

+  var x2js = new X2JS();

+  var jsonObj: { [key: string]: IFormatedMessage } = x2js.xml2js(event.data);

+  if (jsonObj && typeof (jsonObj) === 'object') {

+

+    const notifType = Object.keys(jsonObj)[0];

+    const formated = jsonObj[notifType];

+    formated.notifType = notifType;

+    formated.time = new Date().toISOString();

+    return formated;

+  }

+  return undefined;

+

+}

+

+export function subscribe<TMessage extends IFormatedMessage = IFormatedMessage>(scope: string | string[], callback: SubscriptionCallback<TMessage>): boolean {

+  const scopes = scope instanceof Array ? scope : [scope];

+

+  // send all new scopes to subscribe

+  const newScopesToSubscribe: string[] = scopes.reduce((acc: string[], cur: string) => {

+    const currentCallbacks = subscriptions[cur];

+    if (currentCallbacks) {

+      if (!currentCallbacks.some(c => c === callback)) {

+        currentCallbacks.push(callback);

+      }

+    } else {

+      subscriptions[cur] = [callback];

+      acc.push(cur);

+    }

+    return acc;

+  }, []);

+

+  if (newScopesToSubscribe.length === 0) {

+    return true;

+  }

+

+  return true;

+}

+

+

+export function unsubscribe<TMessage extends IFormatedMessage = IFormatedMessage>(scope: string | string[], callback: SubscriptionCallback<TMessage>): Promise<boolean> {

+  return socketReady.then((notificationSocket) => {

+    const scopes = scope instanceof Array ? scope : [scope];

+    scopes.forEach(s => {

+      const callbacks = subscriptions[s];

+      const index = callbacks && callbacks.indexOf(callback);

+      if (index > -1) {

+        callbacks.splice(index, 1);

+      }

+      if (callbacks.length === 0) {

+        subscriptions[s] === undefined;

+      }

+    });

+

+    // send a subscription to all active scopes

+    const scopesToSubscribe = Object.keys(subscriptions);

+    if (notificationSocket.readyState === notificationSocket.OPEN) {

+      const data = {

+        'data': 'scopes',

+        'scopes': scopesToSubscribe

+      };

+      notificationSocket.send(JSON.stringify(data));

+      return true;

+    }

+    return false;

+  });

+}

+

+export const startNotificationService = (store: ApplicationStore) => {

+  applicationStore = store;

+}

+

+const connect = (): Promise<WebSocket> => {

+  return new Promise((resolve, reject) => {

+    const notificationSocket = new WebSocket(socketUrl);

+

+    notificationSocket.onmessage = (event) => {

+      // process received event

+      if (typeof event.data === 'string') {

+        const formated = formatData(event);

+        if (formated && formated.notifType) {

+          const callbacks = subscriptions[formated.notifType];

+          if (callbacks) {

+            callbacks.forEach(cb => {

+              // ensure all callbacks will be called

+              try {

+                return cb(formated);

+              } catch (reason) {

+                console.error(reason);

+              }

+            });

+          }

+        }

+      }

+    };

+

+    notificationSocket.onerror = function (error) {

+      console.log("Socket error:");

+      console.log(error);

+      reject("Socket error: " + error);

+      if (applicationStore) {

+        applicationStore.dispatch(new SetWebsocketAction(false));

+      }

+    };

+

+    notificationSocket.onopen = function (event) {

+      if (applicationStore) {

+        applicationStore.dispatch(new SetWebsocketAction(true));

+      }

+      console.log("Socket connection opened.");

+      resolve(notificationSocket);

+

+      // send a subscription to all active scopes

+      const scopesToSubscribe = Object.keys(subscriptions);

+      if (notificationSocket.readyState === notificationSocket.OPEN) {

+        const data = {

+          'data': 'scopes',

+          'scopes': scopesToSubscribe

+        };

+        notificationSocket.send(JSON.stringify(data));

+      };

+    };

+

+    notificationSocket.onclose = function (event) {

+      console.log("socket connection closed");

+      if (applicationStore) {

+        applicationStore.dispatch(new SetWebsocketAction(false));

+      }

+      if (!userLoggedOut) {

+        socketReady = connect();

+      }

+    };

+  });

+}

+

+

+

+

+export const startWebsocketSession = () => {

+  socketReady = connect();

+  userLoggedOut = false;

+}

+

+export const endWebsocketSession = () => {

+  socketReady.then(websocket => {

+    websocket.close();

+    userLoggedOut = true;

+  })

+}

+

+

+

+

diff --git a/sdnr/wt/odlux/framework/src/services/restAccessorService.ts b/sdnr/wt/odlux/framework/src/services/restAccessorService.ts
new file mode 100644
index 0000000..ca95ebc
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/services/restAccessorService.ts
@@ -0,0 +1,93 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as $ from 'jquery'; 
+import { Action, IActionHandler } from '../flux/action';
+import { MiddlewareArg } from '../flux/middleware';
+import { Dispatch } from '../flux/store';
+
+import { IApplicationStoreState } from '../store/applicationStore';
+import { AddErrorInfoAction, ErrorInfo } from '../actions/errorActions';
+import { PlainObject, AjaxParameter } from 'models/restService';
+
+export const absoluteUri = /^(https?:\/\/|blob:)/i;
+export const baseUrl = `${ window.location.origin }${ window.location.pathname }`;
+
+class RestBaseAction extends Action { }
+
+export const createRestApiAccessor = <TResult extends PlainObject>(urlOrPath: string, initialValue: TResult) => {
+  const isLocalRequest = !absoluteUri.test(urlOrPath);
+  const uri = isLocalRequest ? `${ baseUrl }/${ urlOrPath }`.replace(/\/{2,}/, '/') : urlOrPath ;
+ 
+  class RestRequestAction extends RestBaseAction { constructor(public settings?: AjaxParameter) { super(); } }
+
+  class RestResponseAction extends RestBaseAction { constructor(public result: TResult) { super(); } }
+
+  class RestErrorAction extends RestBaseAction { constructor(public error?: Error | string) { super(); } }
+  
+  type RestAction = RestRequestAction | RestResponseAction | RestErrorAction;
+
+  /** Represents our middleware to handle rest backend requests */
+  const restMiddleware = (api: MiddlewareArg<IApplicationStoreState>) =>
+    (next: Dispatch) => (action: RestAction): RestAction => {
+      
+      // pass all actions through by default
+      next(action);
+      // handle the RestRequestAction
+      if (action instanceof RestRequestAction) {
+        const state = api.getState();
+        const authHeader = isLocalRequest && state && state.framework.authenticationState.user && state.framework.authenticationState.user.token
+          ? { "Authentication": "Bearer " + state.framework.authenticationState.user.token } : { };
+        $.ajax({
+          url: uri,
+          method: (action.settings && action.settings.method) || "GET",
+          headers: { ...authHeader, ...action.settings && action.settings.headers ? action.settings.headers : { } },
+        }).then((data: TResult) => {
+           next(new RestResponseAction(data));
+        }).catch((err: any) => {
+          next(new RestErrorAction());
+          next(new AddErrorInfoAction((err instanceof Error) ? { error: err } : { message: err.toString() }));
+        });
+      }
+      // allways return action
+      return action;
+  };
+  
+  /** Represents our action handler to handle our actions */
+  const restActionHandler: IActionHandler<TResult> = (state = initialValue, action) => {
+    if (action instanceof RestRequestAction) {
+      return {
+        ...(state as any),
+        busy: true
+      };
+    } else if (action instanceof RestResponseAction) {
+      return action.result;
+    } else if (action instanceof RestErrorAction) {
+      return initialValue;
+    }
+    return state;
+  };
+
+  return {
+    requestAction: RestRequestAction,
+    actionHandler: restActionHandler,
+    middleware: restMiddleware,
+  };
+}
+
+
+
diff --git a/sdnr/wt/odlux/framework/src/services/restService.ts b/sdnr/wt/odlux/framework/src/services/restService.ts
new file mode 100644
index 0000000..b02d7d1
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/services/restService.ts
@@ -0,0 +1,105 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { ApplicationStore } from "../store/applicationStore";
+import { ReplaceAction } from "../actions/navigationActions";
+
+const baseUri = `${ window.location.origin }`;
+const absUrlPattern = /^https?:\/\//;
+let applicationStore: ApplicationStore | null = null;
+
+export const startRestService = (store: ApplicationStore) => {
+  applicationStore = store;
+};
+
+export const formEncode = (params: { [key: string]: string | number }) => Object.keys(params).map((key) => {
+  return encodeURIComponent(key) + '=' + encodeURIComponent(params[key].toString());
+}).join('&');
+
+/** Sends a rest request to the given path. 
+ * @returns The data, or null it there was any error
+ */
+export async function requestRest<TData>(path: string = '', init: RequestInit = {}, authenticate: boolean = true, isResource: boolean = false): Promise<TData | null> {
+  const res = await requestRestExt<TData>(path, init, authenticate, isResource);
+  if (res && res.status >= 200 && res.status < 300) {
+    return res.data;
+  }
+  return null;
+}
+
+/** Sends a rest request to the given path and reports the server state. 
+ *  @returns An object with the server state, a message and the data.
+ */
+export async function requestRestExt<TData>(path: string = '', init: RequestInit = {}, authenticate: boolean = true, isResource: boolean = false): Promise<{ status: number, message?: string, data: TData | null }> {
+  const result: { status: number, message?: string, data: TData | null } = {
+    status: -1,
+    data: null,
+  };
+  const isAbsUrl = absUrlPattern.test(path);
+  const uri = isAbsUrl ? path : isResource ? path.replace(/\/{2,}/i, '/') : (baseUri) + ('/' + path).replace(/\/{2,}/i, '/');
+  init = {
+    'method': 'GET',
+    ...init,
+    headers: {
+      'Content-Type': 'application/json',
+      'Accept': 'application/json',
+      ...init.headers
+    }
+  };
+  if (!isAbsUrl && authenticate && applicationStore) {
+    const { state: { framework: { authenticationState: { user } } } } = applicationStore;
+    // do not request if the user is not valid
+    if (!user || !user.isValid) {
+      return {
+        ...result,
+        message: "User is not valid or not logged in."
+      };
+    }
+    (init.headers = {
+      ...init.headers,
+      'Authorization': `${user.tokenType} ${user.token}`
+      //'Authorization': 'Basic YWRtaW46YWRtaW4='
+    });
+  }
+  const fetchResult = await fetch(uri, init);
+  if (fetchResult.status === 401 || fetchResult.status === 403) {
+    applicationStore && applicationStore.dispatch(new ReplaceAction(`/login?returnTo=${applicationStore.state.framework.navigationState.pathname}`));
+    return {
+      ...result,
+      status: 403,
+      message: "Authentication requested by server."
+    };
+  }
+  const contentType = fetchResult.headers.get("Content-Type") || fetchResult.headers.get("content-type");
+  const isJson = contentType && contentType.toLowerCase().startsWith("application/json");
+  try {
+    const data = (isJson ? await fetchResult.json() : await fetchResult.text()) as TData;
+    return {
+      ...result,
+      status: fetchResult.status,
+      message: fetchResult.statusText,
+      data: data
+    };
+  } catch (error) {
+    return {
+      ...result,
+      status: fetchResult.status,
+      message: error && error.message || String(error),
+      data: null
+    };
+  }
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/services/snackbarService.ts b/sdnr/wt/odlux/framework/src/services/snackbarService.ts
new file mode 100644
index 0000000..50e279c
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/services/snackbarService.ts
@@ -0,0 +1,22 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import { OptionsObject } from "notistack";
+
+export const snackbarService = {
+  enqueueSnackbar: (message: string, options?: OptionsObject) =>{ }
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/store/applicationStore.ts b/sdnr/wt/odlux/framework/src/store/applicationStore.ts
new file mode 100644
index 0000000..287eba3
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/store/applicationStore.ts
@@ -0,0 +1,73 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { Store } from '../flux/store';
+import { combineActionHandler, MiddlewareArg, Middleware, chainMiddleware } from '../flux/middleware';
+
+import applicationService from '../services/applicationManager';
+
+import { applicationRegistryHandler, IApplicationRegistration } from '../handlers/applicationRegistryHandler';
+import { authenticationStateHandler, IAuthenticationState } from '../handlers/authenticationHandler';
+import { applicationStateHandler, IApplicationState } from '../handlers/applicationStateHandler';
+import { navigationStateHandler, INavigationState } from '../handlers/navigationStateHandler';
+
+import { setApplicationStore } from '../services/applicationApi';
+
+import apiMiddleware from '../middleware/api';
+import thunkMiddleware from '../middleware/thunk';
+import loggerMiddleware from '../middleware/logger';
+import routerMiddleware from '../middleware/navigation';
+
+export type MiddlewareApi = MiddlewareArg<IApplicationStoreState>;
+
+export interface IFrameworkStoreState {
+  applicationRegistraion: IApplicationRegistration;
+  applicationState: IApplicationState;
+  authenticationState: IAuthenticationState;
+  navigationState: INavigationState;
+}
+
+export interface IApplicationStoreState {
+  framework: IFrameworkStoreState;
+}
+
+const frameworkHandlers = combineActionHandler({
+  applicationRegistraion: applicationRegistryHandler,
+  applicationState: applicationStateHandler,
+  authenticationState: authenticationStateHandler,
+  navigationState: navigationStateHandler
+});
+
+export class ApplicationStore extends Store<IApplicationStoreState> { }
+
+/** This function will create the application store considering the currently registered application ans their middlewares. */
+export const applicationStoreCreator = (): ApplicationStore => {
+  const middlewares: Middleware<IApplicationStoreState>[] = [];
+  const actionHandlers = Object.keys(applicationService.applications).reduce((acc, cur) => {
+    const reg = applicationService.applications[cur];
+    reg && typeof reg.rootActionHandler === 'function' && (acc[cur] = reg.rootActionHandler);
+    reg && +(reg.middlewares || 0) && middlewares.push(...(reg.middlewares as Middleware<IApplicationStoreState>[]));
+    return acc;
+  }, { framework: frameworkHandlers } as any);
+
+  const applicationStore = new ApplicationStore(combineActionHandler(actionHandlers), chainMiddleware(loggerMiddleware, thunkMiddleware, routerMiddleware, apiMiddleware, ...middlewares));
+  setApplicationStore(applicationStore);
+  return applicationStore;
+}
+
+export default applicationStoreCreator;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/styles/att.ts b/sdnr/wt/odlux/framework/src/styles/att.ts
new file mode 100644
index 0000000..cfd743d
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/styles/att.ts
@@ -0,0 +1,46 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { createMuiTheme } from '@material-ui/core/styles';
+
+const theme = createMuiTheme({
+  design: {
+    id: "att",
+    name: "AT&T",
+    url: "https://pmcvariety.files.wordpress.com/2016/04/att_logo.jpg?w=1000&h=563&crop=1",
+    height: 70,
+    width: 150,
+    logoHeight: 60,
+  },
+  palette: {
+    primary: {
+      light: "#f2f2f29c",
+      main: "#f2f2f2",
+      dark: "#d5d5d5",
+      contrastText: "#0094d3"
+    },
+    secondary: {
+      light: "#f2f2f2",
+      main: "rgba(51, 171, 226, 1)",
+      dark: "rgba(41, 159, 213, 1)",
+      contrastText: "#0094d3"
+    }
+  },
+});
+
+export default theme;
diff --git a/sdnr/wt/odlux/framework/src/utilities/elasticSearch.ts b/sdnr/wt/odlux/framework/src/utilities/elasticSearch.ts
new file mode 100644
index 0000000..c18a40b
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/utilities/elasticSearch.ts
@@ -0,0 +1,78 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { Result } from '../models';
+import { DataCallback } from '../components/material-table';
+
+import { requestRest } from '../services/restService';
+
+import { convertPropertyNames, convertPropertyValues, replaceUpperCase, replaceHyphen } from './yangHelper';
+
+type propType = string | number | null | undefined | (string | number)[];
+type dataType = { [prop: string]: propType };
+
+/** Represents a fabric for the searchDataHandler used by the internal data api.
+ *  @param typeName The name of the entry type to create a searchDataHandler for.
+ *  @param additionalFilters Filterproperties and their values to add permanently.
+ *  @returns The searchDataHandler callback to be used with the material table.
+*/
+export function createSearchDataHandler<TResult>(typeName: (() => string) | string, additionalFilters?: {} | null | undefined): DataCallback<(TResult)> {
+  const fetchData: DataCallback<(TResult)> = async (pageIndex, rowsPerPage, orderBy, order, filter) => {
+    const url = `/restconf/operations/data-provider:read-${typeof typeName === "function" ? typeName(): typeName}-list`;
+
+    filter = { ...filter, ...additionalFilters };
+
+    const filterKeys = filter && Object.keys(filter) || [];
+
+    const query = {
+      input: {
+        filter: filterKeys.filter(f => filter![f] != null && filter![f] !== "").map(property => ({ property, filtervalue: filter![property]})),
+        sortorder: orderBy ? [{ property: orderBy, sortorder: order === "desc" ? "descending" : "ascending" }] : [],
+        pagination: { size: rowsPerPage, page: (pageIndex != null && pageIndex > 0 && pageIndex || 0) +1 }
+      }
+    };
+    const result = await requestRest<Result<TResult>>(url, {
+      method: "POST",       // *GET, POST, PUT, DELETE, etc.
+      mode: "same-origin",  // no-cors, cors, *same-origin
+      cache: "no-cache",    // *default, no-cache, reload, force-cache, only-if-cached
+      headers: {
+        "Content-Type": "application/json",
+        // "Content-Type": "application/x-www-form-urlencoded",
+      },
+      body: JSON.stringify(convertPropertyValues(query, replaceUpperCase)), // body data type must match "Content-Type" header
+    });
+
+    if (result) {
+      let rows: TResult[] = [];
+
+      if (result && result.output && result.output.data) {
+        rows = result.output.data.map(obj => convertPropertyNames(obj, replaceHyphen)) || []
+      }
+
+      const data = {
+        page: result.output.pagination && result.output.pagination.page != null && result.output.pagination.page - 1  || 0 , total: result.output.pagination && result.output.pagination.total || 0, rows: rows
+      };
+      return data;
+    }
+
+    return { page: 1, total: 0, rows: [] };
+  };
+
+  return fetchData;
+}
+
diff --git a/sdnr/wt/odlux/framework/src/utilities/withComponents.ts b/sdnr/wt/odlux/framework/src/utilities/withComponents.ts
new file mode 100644
index 0000000..8e460ad
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/utilities/withComponents.ts
@@ -0,0 +1,37 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+import applicationService from '../services/applicationManager';
+export type WithComponents<T extends { [name: string]: string }> = {
+  components: { [prop in keyof T]: React.ComponentType }
+};
+
+export function withComponents<TProps,TMap extends { [name: string]: string }>(mapping: TMap) {
+  return (component: React.ComponentType<TProps & WithComponents<TMap>>): React.ComponentType<TProps> => {
+    const components = {} as any;
+    Object.keys(mapping).forEach(name => {
+      const [appKey, componentKey] = mapping[name].split('.');
+      const reg = applicationService.applications[appKey];
+      components[name] = reg && reg.exportedComponents && reg.exportedComponents[componentKey] || (() => null);
+    });
+    return (props: TProps) => (
+      React.createElement(component, Object.assign({ components }, props))
+    );
+  }
+}
+export default withComponents;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/utilities/yangHelper.ts b/sdnr/wt/odlux/framework/src/utilities/yangHelper.ts
new file mode 100644
index 0000000..127f3e0
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/utilities/yangHelper.ts
@@ -0,0 +1,39 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+
+export const replaceHyphen = (name: string) => name.replace(/-([a-z])/g, (g) => (g[1].toUpperCase()));
+export const replaceUpperCase = (name: string) => name.replace(/([a-z][A-Z])/g, (g) => g[0] + '-' + g[1].toLowerCase());
+
+export const convertPropertyNames = <T extends { [prop: string]: any }>(obj: T, conv: (name: string) => string): T => {
+  return Object.keys(obj).reduce<{ [prop: string]: any }>((acc, cur) => {
+    acc[conv(cur)] = typeof obj[cur] === "object" ? convertPropertyNames(obj[cur], conv) : obj[cur];
+    return acc;
+  }, obj instanceof Array ? [] : {}) as T;
+}
+
+export const convertPropertyValues = <T extends { [prop: string]: any }>(obj: T, conv: (name: string) => string): T => {
+  return Object.keys(obj).reduce<{ [prop: string]: any }>((acc, cur) => {
+    acc[cur] = typeof obj[cur] === "object"
+      ? convertPropertyValues(obj[cur], conv)
+      : cur === "property"
+        ? conv(obj[cur])
+        : obj[cur];
+    return acc;
+  }, obj instanceof Array ? [] : {}) as T;
+}
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/views/about.tsx b/sdnr/wt/odlux/framework/src/views/about.tsx
new file mode 100644
index 0000000..d47e09c
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/views/about.tsx
@@ -0,0 +1,31 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';

+

+const AboutComponent = () => {

+

+  return (

+    <div>

+      <h2>About</h2>

+      <div style={{ margin: "0 auto" }}>##odlux.version##</div>

+    </div>

+  );

+};

+

+export const About = AboutComponent;

+export default About;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/views/frame.tsx b/sdnr/wt/odlux/framework/src/views/frame.tsx
new file mode 100644
index 0000000..b93b7ee
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/views/frame.tsx
@@ -0,0 +1,118 @@
+/**

+ * ============LICENSE_START========================================================================

+ * ONAP : ccsdk feature sdnr wt odlux

+ * =================================================================================================

+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.

+ * =================================================================================================

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

+ * in compliance with the License. You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License

+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

+ * or implied. See the License for the specific language governing permissions and limitations under

+ * the License.

+ * ============LICENSE_END==========================================================================

+ */

+import * as React from 'react';

+import { HashRouter as Router, Route, Redirect, Switch } from 'react-router-dom';

+

+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';

+import { faHome, faAddressBook, faSignInAlt } from '@fortawesome/free-solid-svg-icons';

+

+import AppFrame from '../components/routing/appFrame';

+import TitleBar from '../components/titleBar';

+import Menu from '../components/navigationMenu';

+import ErrorDisplay from '../components/errorDisplay';

+import SnackDisplay from '../components/material-ui/snackDisplay';

+

+import Home from '../views/home';

+import Login from '../views/login';

+import About from '../views/about';

+import Test from '../views/test';

+

+import applicationService from '../services/applicationManager';

+import { SnackbarProvider } from 'notistack';

+

+const styles = (theme: Theme) => createStyles({

+  root: {

+    flexGrow: 1,

+    height: '100%',

+    zIndex: 1,

+    overflow: 'hidden',

+    position: 'relative',

+    display: 'flex',

+  },

+  content: {

+    flexGrow: 1,

+    display: "flex",

+    flexDirection: "column",

+    backgroundColor: theme.palette.background.default,

+    padding: theme.spacing(3),

+    minWidth: 0, // So the Typography noWrap works

+  },

+  toolbar: theme.mixins.toolbar

+});

+

+type FrameProps = WithStyles<typeof styles>;

+

+class FrameComponent extends React.Component<FrameProps>{

+

+  render() {

+    const registrations = applicationService.applications;

+    const { classes } = this.props;

+    return (

+      <SnackbarProvider maxSnack={3}>

+        <Router>

+          <div className={classes.root}>

+            <SnackDisplay />

+            <ErrorDisplay />

+            <TitleBar />

+            <Menu />

+            <main className={classes.content}>

+              {

+                <div className={classes.toolbar} /> //needed for margins, don't remove!

+              }

+              <Switch>

+                <Route exact path="/" component={() => (

+                  <AppFrame title={"Home"} icon={faHome} >

+                    <Home />

+                  </AppFrame>

+                )} />

+                <Route path="/about" component={() => (

+                  <AppFrame title={"About"} icon={faAddressBook} >

+                    <About />

+                  </AppFrame>

+                )} />

+                {process.env.NODE_ENV === "development" ? <Route path="/test" component={() => (

+                  <AppFrame title={"Test"} icon={faAddressBook} >

+                    <Test />

+                  </AppFrame>

+                )} /> : null}

+                <Route path="/login" component={() => (

+                  <AppFrame title={"Login"} icon={faSignInAlt} >

+                    <Login />

+                  </AppFrame>

+                )} />

+                {Object.keys(registrations).map(p => {

+                  const application = registrations[p];

+                  return (<Route key={application.name} path={application.path || `/${application.name}`} component={() => (

+                    <AppFrame title={application.title || (typeof application.menuEntry === 'string' && application.menuEntry) || application.name} icon={application.icon} appId={application.name} >

+                      <application.rootComponent />

+                    </AppFrame>

+                  )} />)

+                })}

+                <Redirect to="/" />

+              </Switch>

+            </main>

+          </div>

+        </Router>

+      </SnackbarProvider>

+    );

+  }

+}

+

+export const Frame = withStyles(styles)(FrameComponent);

+

+export default Frame;

diff --git a/sdnr/wt/odlux/framework/src/views/home.tsx b/sdnr/wt/odlux/framework/src/views/home.tsx
new file mode 100644
index 0000000..4a4084e
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/views/home.tsx
@@ -0,0 +1,27 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+
+export const Home = (props: React.Props<any>) => {
+  return (
+    <div>
+      <h1>Welcome to ODLUX.</h1>
+    </div>
+  )
+}
+export default Home;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/views/login.tsx b/sdnr/wt/odlux/framework/src/views/login.tsx
new file mode 100644
index 0000000..3f6ef61
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/views/login.tsx
@@ -0,0 +1,210 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+import { withRouter, RouteComponentProps } from 'react-router-dom';
+
+import Avatar from '@material-ui/core/Avatar';
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+import CssBaseline from '@material-ui/core/CssBaseline';
+import FormControl from '@material-ui/core/FormControl';
+import FormControlLabel from '@material-ui/core/FormControlLabel';
+import Checkbox from '@material-ui/core/Checkbox';
+import Input from '@material-ui/core/Input';
+import InputLabel from '@material-ui/core/InputLabel';
+import LockIcon from '@material-ui/icons/LockOutlined';
+import Paper from '@material-ui/core/Paper';
+import Typography from '@material-ui/core/Typography';
+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
+
+import connect, { Connect } from '../flux/connect';
+import authenticationService from '../services/authenticationService';
+
+import { UpdateAuthentication } from '../actions/authentication';
+
+const styles = (theme: Theme) => createStyles({
+  layout: {
+    width: 'auto',
+    display: 'block', // Fix IE11 issue.
+    marginLeft: theme.spacing(3),
+    marginRight: theme.spacing(3),
+    [theme.breakpoints.up(400 + theme.spacing(3) * 2)]: {
+      width: 400,
+      marginLeft: 'auto',
+      marginRight: 'auto',
+    },
+  },
+  paper: {
+    marginTop: theme.spacing(8),
+    display: 'flex',
+    flexDirection: 'column',
+    alignItems: 'center',
+    padding: `${theme.spacing(2)}px ${theme.spacing(3)}px ${theme.spacing(3)}px`,
+  },
+  avatar: {
+    margin: theme.spacing(1),
+    backgroundColor: theme.palette.secondary.main,
+  },
+  form: {
+    width: '100%', // Fix IE11 issue.
+    marginTop: theme.spacing(1),
+  },
+  submit: {
+    marginTop: theme.spacing(3),
+  },
+});
+
+type LoginProps = RouteComponentProps<{}> & WithStyles<typeof styles> & Connect;
+
+interface ILoginState {
+  busy: boolean;
+  username: string;
+  password: string;
+  scope: string;
+  message: string;
+}
+
+
+// todo: ggf. redirect to einbauen
+class LoginComponent extends React.Component<LoginProps, ILoginState> {
+
+  constructor(props: LoginProps) {
+    super(props);
+
+    this.state = {
+      busy: false,
+      username: '',
+      password: '',
+      scope: 'sdn',
+      message: ''
+    };
+  }
+
+  render(): JSX.Element {
+    const { classes } = this.props;
+    return (
+      <React.Fragment>
+        <CssBaseline />
+        <main className={classes.layout}>
+          <Paper className={classes.paper}>
+            <Avatar className={classes.avatar}>
+              <LockIcon />
+            </Avatar>
+            <Typography variant="caption">Sign in</Typography>
+            <form className={classes.form}>
+              <FormControl margin="normal" required fullWidth>
+                <InputLabel htmlFor="username">Username</InputLabel>
+                <Input id="username" name="username" autoComplete="username" autoFocus
+                  disabled={this.state.busy}
+                  value={this.state.username}
+                  onChange={event => { this.setState({ username: event.target.value }) }} />
+              </FormControl>
+              <FormControl margin="normal" required fullWidth>
+                <InputLabel htmlFor="password">Password</InputLabel>
+                <Input
+                  name="password"
+                  type="password"
+                  id="password"
+                  autoComplete="current-password"
+                  disabled={this.state.busy}
+                  value={this.state.password}
+                  onChange={event => { this.setState({ password: event.target.value }) }}
+                />
+              </FormControl>
+              <FormControl margin="normal" required fullWidth>
+                <InputLabel htmlFor="password">Domain</InputLabel>
+                <Input
+                  name="scope"
+                  type="scope"
+                  id="scope"
+                  disabled={this.state.busy}
+                  value={this.state.scope}
+                  onChange={event => { this.setState({ scope: event.target.value }) }}
+                />
+              </FormControl>
+              <FormControlLabel
+                control={<Checkbox value="remember" color="secondary" />}
+                label="Remember me"
+              />
+              <Button
+                type="submit"
+                fullWidth
+                variant="contained"
+                color="primary"
+                disabled={this.state.busy}
+                className={classes.submit}
+                onClick={this.onSignIn}
+              >
+                Sign in
+            </Button>
+            </form>
+          </Paper>
+        </main>
+        <Dialog
+          open={!!this.state.message}
+          onClose={() => { this.setState({ message: '' }) }}
+          aria-labelledby="alert-dialog-title"
+          aria-describedby="alert-dialog-description"
+        >
+          <DialogTitle id="alert-dialog-title">{"Error"}</DialogTitle>
+          <DialogContent>
+            <DialogContentText id="alert-dialog-description">
+              {this.state.message}
+            </DialogContentText>
+          </DialogContent>
+          <DialogActions>
+            <Button onClick={() => { this.setState({ message: '' }) }} color="secondary" autoFocus>
+              OK
+            </Button>
+          </DialogActions>
+        </Dialog>
+      </React.Fragment>
+    );
+  }
+
+  private onSignIn = async (event: React.MouseEvent<HTMLButtonElement>) => {
+    event.preventDefault();
+
+    this.setState({ busy: true });
+    const token = await authenticationService.authenticateUser(this.state.username, this.state.password, this.state.scope);
+    this.props.dispatch(new UpdateAuthentication(token));
+    this.setState({ busy: false });
+
+    if (token) {
+      const query =
+        this.props.state.framework.navigationState.search &&
+        this.props.state.framework.navigationState.search.replace(/^\?/, "")
+          .split('&').map(e => e.split("="));
+      const returnTo = query && query.find(e => e[0] === "returnTo");
+      this.props.history.replace(returnTo && returnTo[1] || "/");
+    }
+    else {
+      this.setState({
+        message: "Could not log in. Please check your credentials or ask your administrator for assistence.",
+        password: ""
+      })
+    }
+  }
+}
+
+export const Login = withStyles(styles)(withRouter(connect()(LoginComponent)));
+export default Login;
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/src/views/test.tsx b/sdnr/wt/odlux/framework/src/views/test.tsx
new file mode 100644
index 0000000..68b1893
--- /dev/null
+++ b/sdnr/wt/odlux/framework/src/views/test.tsx
@@ -0,0 +1,878 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+import * as React from 'react';
+
+import { withComponents, WithComponents } from '../utilities/withComponents';
+import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
+
+import ExpansionPanel from '@material-ui/core/ExpansionPanel';
+import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
+import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
+import Typography from '@material-ui/core/Typography';
+import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
+
+import { MaterialTable, MaterialTableCtorType, ColumnType } from '../components/material-table';
+import { TreeView, ITreeItem, TreeViewCtorType } from '../components/material-ui/treeView';
+import { SvgIconProps } from '@material-ui/core/SvgIcon';
+
+const styles = (theme: Theme) => createStyles({
+  root: {
+    width: '100%',
+  },
+  heading: {
+    fontSize: theme.typography.pxToRem(15),
+    fontWeight: theme.typography.fontWeightRegular,
+  },
+});
+
+class SampleData {
+  _id: string;
+  index: number;
+  guid: string;
+  isActive: boolean;
+  balance: string;
+  age: number;
+  firstName: string;
+  lastName: string;
+  company: string;
+  email: string;
+  registered: string;
+  latitude: string;
+  longitude: string;
+}
+
+// https://next.json-generator.com/NJ5Bv-v1I
+const tableData: SampleData[] = [
+  {
+    "_id": "5c0e18399919a5c43636fdf2",
+    "index": 0,
+    "guid": "48728d8e-8300-4d0f-b967-e2166d023066",
+    "isActive": false,
+    "balance": "$3,480.16",
+    "age": 33,
+    "firstName": "Brooke",
+    "lastName": "Morris",
+    "company": "ZORROMOP",
+    "email": "brooke.morris@zorromop.de",
+    "registered": "Sunday, February 11, 2018 2:55 PM",
+    "latitude": "-69.109379",
+    "longitude": "113.735639"
+  },
+  {
+    "_id": "5c0e1839b61e3eeaf164259d",
+    "index": 1,
+    "guid": "28723570-1507-422e-b78c-924402371fb1",
+    "isActive": false,
+    "balance": "$1,305.01",
+    "age": 28,
+    "firstName": "Jolene",
+    "lastName": "Everett",
+    "company": "ZENCO",
+    "email": "jolene.everett@zenco.de",
+    "registered": "Saturday, December 8, 2018 5:17 PM",
+    "latitude": "13.683025",
+    "longitude": "85.101421"
+  },
+  {
+    "_id": "5c0e1839e81f57913c5d2147",
+    "index": 2,
+    "guid": "e914dc5d-91a3-405d-ac48-aee6f0cd391a",
+    "isActive": true,
+    "balance": "$1,418.37",
+    "age": 28,
+    "firstName": "Elva",
+    "lastName": "Travis",
+    "company": "ZYTREK",
+    "email": "elva.travis@zytrek.de",
+    "registered": "Thursday, March 10, 2016 5:13 PM",
+    "latitude": "53.75862",
+    "longitude": "-67.784532"
+  },
+  {
+    "_id": "5c0e1839bc9224a2b54c0f69",
+    "index": 3,
+    "guid": "88cbdce0-0bcc-4d16-83c3-3017690503c4",
+    "isActive": true,
+    "balance": "$1,709.60",
+    "age": 21,
+    "firstName": "Ellis",
+    "lastName": "Mcpherson",
+    "company": "DIGIPRINT",
+    "email": "ellis.mcpherson@digiprint.de",
+    "registered": "Sunday, December 21, 2014 5:25 AM",
+    "latitude": "46.486149",
+    "longitude": "-66.657067"
+  },
+  {
+    "_id": "5c0e183951b51475db0f35d1",
+    "index": 4,
+    "guid": "c887ac86-7ba1-4eb6-9b47-e88a1bcb3713",
+    "isActive": true,
+    "balance": "$3,578.54",
+    "age": 25,
+    "firstName": "Marcia",
+    "lastName": "Rocha",
+    "company": "ZAPPIX",
+    "email": "marcia.rocha@zappix.de",
+    "registered": "Tuesday, June 16, 2015 11:21 AM",
+    "latitude": "-39.905461",
+    "longitude": "150.873895"
+  },
+  {
+    "_id": "5c0e18398c5be8d362a578eb",
+    "index": 5,
+    "guid": "0d160697-9b5b-4941-9b5f-4ba3a7f97b49",
+    "isActive": true,
+    "balance": "$414.98",
+    "age": 32,
+    "firstName": "Lavonne",
+    "lastName": "Wilkins",
+    "company": "FARMAGE",
+    "email": "lavonne.wilkins@farmage.de",
+    "registered": "Monday, February 1, 2016 5:27 PM",
+    "latitude": "-16.839256",
+    "longitude": "-105.824746"
+  },
+  {
+    "_id": "5c0e18399804086c836d7d56",
+    "index": 6,
+    "guid": "715a5f63-35b6-4903-a46e-ba584b005e64",
+    "isActive": false,
+    "balance": "$1,755.78",
+    "age": 32,
+    "firstName": "Wise",
+    "lastName": "Berg",
+    "company": "ZIZZLE",
+    "email": "wise.berg@zizzle.de",
+    "registered": "Saturday, March 28, 2015 1:40 AM",
+    "latitude": "51.15269",
+    "longitude": "65.795093"
+  },
+  {
+    "_id": "5c0e18399c4d13538bcaf8c9",
+    "index": 7,
+    "guid": "7ee50269-23e8-499e-9a16-09f393d7600c",
+    "isActive": false,
+    "balance": "$342.52",
+    "age": 27,
+    "firstName": "Isabel",
+    "lastName": "Battle",
+    "company": "EZENTIA",
+    "email": "isabel.battle@ezentia.de",
+    "registered": "Thursday, June 7, 2018 12:16 AM",
+    "latitude": "-53.318152",
+    "longitude": "-153.516824"
+  },
+  {
+    "_id": "5c0e18398d7fb9a4eceeffa2",
+    "index": 8,
+    "guid": "1e30c9ac-2297-4f16-83e6-9559b1ebe92c",
+    "isActive": true,
+    "balance": "$3,184.71",
+    "age": 36,
+    "firstName": "Lenora",
+    "lastName": "Crawford",
+    "company": "KIDGREASE",
+    "email": "lenora.crawford@kidgrease.de",
+    "registered": "Saturday, January 7, 2017 6:17 PM",
+    "latitude": "-72.431496",
+    "longitude": "9.413359"
+  },
+  {
+    "_id": "5c0e18395837069ab6b79d00",
+    "index": 9,
+    "guid": "d04a02ed-5899-4729-a7e5-2d85b5d03973",
+    "isActive": true,
+    "balance": "$1,553.28",
+    "age": 35,
+    "firstName": "Sasha",
+    "lastName": "Bridges",
+    "company": "IDEALIS",
+    "email": "sasha.bridges@idealis.de",
+    "registered": "Sunday, February 4, 2018 7:02 PM",
+    "latitude": "8.095691",
+    "longitude": "-105.758195"
+  },
+  {
+    "_id": "5c0e18390be19bf65acad180",
+    "index": 10,
+    "guid": "3a1a77e6-ef15-4598-8274-c68ac3bb922a",
+    "isActive": false,
+    "balance": "$3,587.96",
+    "age": 20,
+    "firstName": "Wilkins",
+    "lastName": "Beasley",
+    "company": "DIGIFAD",
+    "email": "wilkins.beasley@digifad.de",
+    "registered": "Monday, March 5, 2018 1:27 PM",
+    "latitude": "-88.062704",
+    "longitude": "149.95661"
+  },
+  {
+    "_id": "5c0e1839ffbbad5c9954e49f",
+    "index": 11,
+    "guid": "97a56950-a08c-4e00-8002-ba2d5de4da5d",
+    "isActive": false,
+    "balance": "$1,997.80",
+    "age": 31,
+    "firstName": "Sullivan",
+    "lastName": "Mcclain",
+    "company": "EARTHMARK",
+    "email": "sullivan.mcclain@earthmark.de",
+    "registered": "Saturday, October 27, 2018 2:51 PM",
+    "latitude": "-81.86349",
+    "longitude": "-79.596991"
+  },
+  {
+    "_id": "5c0e183914bd464d55e7325f",
+    "index": 12,
+    "guid": "294f6485-d0f9-4b25-b998-325ae90fa769",
+    "isActive": true,
+    "balance": "$1,405.46",
+    "age": 24,
+    "firstName": "Herminia",
+    "lastName": "Fischer",
+    "company": "ECOLIGHT",
+    "email": "herminia.fischer@ecolight.de",
+    "registered": "Thursday, January 16, 2014 4:48 PM",
+    "latitude": "48.224363",
+    "longitude": "11.08339"
+  },
+  {
+    "_id": "5c0e183968ec2556d8f6566c",
+    "index": 13,
+    "guid": "16edfea4-7b37-4e54-868c-c369b413dd78",
+    "isActive": false,
+    "balance": "$3,440.67",
+    "age": 39,
+    "firstName": "Blanchard",
+    "lastName": "Blackwell",
+    "company": "GEOFORMA",
+    "email": "blanchard.blackwell@geoforma.de",
+    "registered": "Wednesday, July 30, 2014 4:07 AM",
+    "latitude": "-52.169297",
+    "longitude": "10.415879"
+  },
+  {
+    "_id": "5c0e183939a0fc955f2d94da",
+    "index": 14,
+    "guid": "4ed454e2-dde1-4ab5-a434-4a82205ced2d",
+    "isActive": true,
+    "balance": "$1,883.27",
+    "age": 35,
+    "firstName": "Gayle",
+    "lastName": "Little",
+    "company": "AQUAZURE",
+    "email": "gayle.little@aquazure.de",
+    "registered": "Tuesday, December 12, 2017 5:08 PM",
+    "latitude": "-58.473236",
+    "longitude": "38.022269"
+  },
+  {
+    "_id": "5c0e1839099f9221ccd968ac",
+    "index": 15,
+    "guid": "1d052fd4-7c54-45fb-b0db-7de1acc4262a",
+    "isActive": false,
+    "balance": "$2,601.94",
+    "age": 31,
+    "firstName": "Jocelyn",
+    "lastName": "Richards",
+    "company": "GINK",
+    "email": "jocelyn.richards@gink.de",
+    "registered": "Sunday, October 30, 2016 9:12 PM",
+    "latitude": "-43.489676",
+    "longitude": "2.557869"
+  },
+  {
+    "_id": "5c0e183970f320f377321c3f",
+    "index": 16,
+    "guid": "45bca125-8831-48c3-b22b-29ae318e7096",
+    "isActive": false,
+    "balance": "$3,441.74",
+    "age": 34,
+    "firstName": "Berta",
+    "lastName": "Valentine",
+    "company": "ISOSPHERE",
+    "email": "berta.valentine@isosphere.de",
+    "registered": "Sunday, March 19, 2017 8:22 PM",
+    "latitude": "-40.188039",
+    "longitude": "-170.085092"
+  },
+  {
+    "_id": "5c0e1839ab960bb0a9f4f392",
+    "index": 17,
+    "guid": "d7b5122a-94c9-423c-b799-1a8f8314b152",
+    "isActive": false,
+    "balance": "$56.39",
+    "age": 21,
+    "firstName": "Russell",
+    "lastName": "Powers",
+    "company": "TETAK",
+    "email": "russell.powers@tetak.de",
+    "registered": "Thursday, November 3, 2016 9:23 PM",
+    "latitude": "-51.610519",
+    "longitude": "-133.280363"
+  },
+  {
+    "_id": "5c0e183998f0195404b9aaa4",
+    "index": 18,
+    "guid": "a043ba97-ea7e-48ce-bb15-18ee09fb393d",
+    "isActive": true,
+    "balance": "$1,503.57",
+    "age": 37,
+    "firstName": "Rosario",
+    "lastName": "Brennan",
+    "company": "VIAGRAND",
+    "email": "rosario.brennan@viagrand.de",
+    "registered": "Saturday, March 17, 2018 10:32 PM",
+    "latitude": "-43.773365",
+    "longitude": "47.58682"
+  },
+  {
+    "_id": "5c0e1839bcb2a5cc567129ac",
+    "index": 19,
+    "guid": "de6d5d36-201e-4f87-9976-ed31f3160e42",
+    "isActive": false,
+    "balance": "$1,160.18",
+    "age": 29,
+    "firstName": "Anita",
+    "lastName": "Hodges",
+    "company": "TUBALUM",
+    "email": "anita.hodges@tubalum.de",
+    "registered": "Sunday, November 26, 2017 11:54 AM",
+    "latitude": "7.080244",
+    "longitude": "-9.970715"
+  },
+  {
+    "_id": "5c0e18394b37e854a1ef371c",
+    "index": 20,
+    "guid": "9407113b-896a-4699-ac1b-363bc3c6f8ad",
+    "isActive": false,
+    "balance": "$34.81",
+    "age": 31,
+    "firstName": "Barrett",
+    "lastName": "Weaver",
+    "company": "DUOFLEX",
+    "email": "barrett.weaver@duoflex.de",
+    "registered": "Tuesday, November 3, 2015 9:31 AM",
+    "latitude": "40.30558",
+    "longitude": "-69.986664"
+  },
+  {
+    "_id": "5c0e1839b5658f90e16a86e0",
+    "index": 21,
+    "guid": "81f894c4-c931-422d-a30e-593824d95bf9",
+    "isActive": true,
+    "balance": "$2,808.63",
+    "age": 26,
+    "firstName": "Baxter",
+    "lastName": "Chase",
+    "company": "BUNGA",
+    "email": "baxter.chase@bunga.de",
+    "registered": "Friday, October 28, 2016 7:10 AM",
+    "latitude": "-49.05652",
+    "longitude": "63.123535"
+  },
+  {
+    "_id": "5c0e1839cb9462c9ecbb59af",
+    "index": 22,
+    "guid": "92e67862-4fdf-43af-a3ef-ef3edb8d6706",
+    "isActive": true,
+    "balance": "$3,552.71",
+    "age": 29,
+    "firstName": "Olga",
+    "lastName": "Kemp",
+    "company": "OHMNET",
+    "email": "olga.kemp@ohmnet.de",
+    "registered": "Saturday, March 26, 2016 11:51 AM",
+    "latitude": "-17.450481",
+    "longitude": "-13.945794"
+  },
+  {
+    "_id": "5c0e18396f999c2b8ac731a9",
+    "index": 23,
+    "guid": "a682eaae-34f0-4973-b8a0-30972de0732b",
+    "isActive": false,
+    "balance": "$1,999.20",
+    "age": 21,
+    "firstName": "Ebony",
+    "lastName": "Le",
+    "company": "MULTRON",
+    "email": "ebony.le@multron.de",
+    "registered": "Friday, March 27, 2015 9:23 AM",
+    "latitude": "-70.380014",
+    "longitude": "173.20685"
+  },
+  {
+    "_id": "5c0e18391cfb28263eb42db7",
+    "index": 24,
+    "guid": "f1cddb5f-0b89-453e-b0c9-8193a56cc610",
+    "isActive": true,
+    "balance": "$2,950.91",
+    "age": 30,
+    "firstName": "Norman",
+    "lastName": "Price",
+    "company": "COMVEX",
+    "email": "norman.price@comvex.de",
+    "registered": "Tuesday, August 21, 2018 11:17 PM",
+    "latitude": "86.501469",
+    "longitude": "159.545352"
+  },
+  {
+    "_id": "5c0e18394a6be11128c7e5ca",
+    "index": 25,
+    "guid": "dadb738a-40fd-45b6-abac-023a803d95c2",
+    "isActive": true,
+    "balance": "$2,767.09",
+    "age": 25,
+    "firstName": "Sara",
+    "lastName": "Ruiz",
+    "company": "AUSTECH",
+    "email": "sara.ruiz@austech.de",
+    "registered": "Wednesday, June 20, 2018 6:34 AM",
+    "latitude": "86.784904",
+    "longitude": "-120.331325"
+  },
+  {
+    "_id": "5c0e183974631549eda97cea",
+    "index": 26,
+    "guid": "b5c43ee5-14ed-4ab5-b3db-b31a8bb65ceb",
+    "isActive": true,
+    "balance": "$3,235.42",
+    "age": 32,
+    "firstName": "Holly",
+    "lastName": "Santos",
+    "company": "LOVEPAD",
+    "email": "holly.santos@lovepad.de",
+    "registered": "Thursday, November 22, 2018 9:26 PM",
+    "latitude": "-19.640066",
+    "longitude": "50.410992"
+  },
+  {
+    "_id": "5c0e1839ab9b933881429d78",
+    "index": 27,
+    "guid": "94961092-65ca-41b9-bc69-3e40ce2cafc9",
+    "isActive": true,
+    "balance": "$2,106.34",
+    "age": 39,
+    "firstName": "Rachel",
+    "lastName": "Douglas",
+    "company": "DEMINIMUM",
+    "email": "rachel.douglas@deminimum.de",
+    "registered": "Sunday, April 9, 2017 3:55 AM",
+    "latitude": "31.395281",
+    "longitude": "-1.899514"
+  },
+  {
+    "_id": "5c0e183937f743155859c5a9",
+    "index": 28,
+    "guid": "07d7ef18-bcef-483d-999e-0b3da4a7098b",
+    "isActive": true,
+    "balance": "$2,260.65",
+    "age": 40,
+    "firstName": "Reed",
+    "lastName": "Workman",
+    "company": "BUZZMAKER",
+    "email": "reed.workman@buzzmaker.de",
+    "registered": "Wednesday, May 28, 2014 3:44 PM",
+    "latitude": "23.789646",
+    "longitude": "106.938375"
+  },
+  {
+    "_id": "5c0e1839f8f4b60beb28b7ed",
+    "index": 29,
+    "guid": "9b4952e5-aa0e-4919-9e17-7c357a297394",
+    "isActive": false,
+    "balance": "$702.99",
+    "age": 27,
+    "firstName": "Cochran",
+    "lastName": "Ware",
+    "company": "HIVEDOM",
+    "email": "cochran.ware@hivedom.de",
+    "registered": "Monday, October 16, 2017 5:51 AM",
+    "latitude": "85.953108",
+    "longitude": "124.590037"
+  },
+  {
+    "_id": "5c0e1839342fbd54a88269df",
+    "index": 30,
+    "guid": "30937d5b-9514-4ebd-b628-2cfb5017fe41",
+    "isActive": false,
+    "balance": "$385.88",
+    "age": 35,
+    "firstName": "Cote",
+    "lastName": "Hess",
+    "company": "TERAPRENE",
+    "email": "cote.hess@teraprene.de",
+    "registered": "Thursday, March 15, 2018 4:42 PM",
+    "latitude": "81.38211",
+    "longitude": "64.516797"
+  },
+  {
+    "_id": "5c0e18395b6dc85d73ce1fb3",
+    "index": 31,
+    "guid": "f34847da-7f96-4cd8-8d8a-b06c0eb0a8f2",
+    "isActive": true,
+    "balance": "$3,494.56",
+    "age": 27,
+    "firstName": "Daniels",
+    "lastName": "Ayala",
+    "company": "BESTO",
+    "email": "daniels.ayala@besto.de",
+    "registered": "Sunday, December 18, 2016 10:52 AM",
+    "latitude": "47.704227",
+    "longitude": "41.674767"
+  },
+  {
+    "_id": "5c0e183974587cdccf30b13f",
+    "index": 32,
+    "guid": "fdbb6d83-0e47-4453-b8a7-b47f44e4164b",
+    "isActive": false,
+    "balance": "$2,087.38",
+    "age": 26,
+    "firstName": "Powers",
+    "lastName": "Drake",
+    "company": "GENESYNK",
+    "email": "powers.drake@genesynk.de",
+    "registered": "Saturday, September 29, 2018 12:24 AM",
+    "latitude": "40.580432",
+    "longitude": "110.940759"
+  },
+  {
+    "_id": "5c0e18397b51245e971c58b8",
+    "index": 33,
+    "guid": "6adfe544-238b-4001-b2a6-f50ea3094da3",
+    "isActive": true,
+    "balance": "$3,566.22",
+    "age": 34,
+    "firstName": "Pacheco",
+    "lastName": "Ramsey",
+    "company": "ENVIRE",
+    "email": "pacheco.ramsey@envire.de",
+    "registered": "Friday, September 11, 2015 12:14 AM",
+    "latitude": "-30.691235",
+    "longitude": "69.343692"
+  },
+  {
+    "_id": "5c0e18391ede9c0996fd09e7",
+    "index": 34,
+    "guid": "d190b32f-d33b-4c17-a18a-bb2f57e79ba7",
+    "isActive": false,
+    "balance": "$1,671.63",
+    "age": 32,
+    "firstName": "Mcintyre",
+    "lastName": "Chan",
+    "company": "ORBAXTER",
+    "email": "mcintyre.chan@orbaxter.de",
+    "registered": "Wednesday, May 7, 2014 7:11 PM",
+    "latitude": "7.380435",
+    "longitude": "70.955103"
+  },
+  {
+    "_id": "5c0e1839fe48069c9c260fa9",
+    "index": 35,
+    "guid": "a41c064b-6bf4-4ba5-b229-9b657d286936",
+    "isActive": false,
+    "balance": "$24.02",
+    "age": 27,
+    "firstName": "Genevieve",
+    "lastName": "Sparks",
+    "company": "ZBOO",
+    "email": "genevieve.sparks@zboo.de",
+    "registered": "Saturday, December 16, 2017 2:51 PM",
+    "latitude": "-63.406337",
+    "longitude": "118.662621"
+  },
+  {
+    "_id": "5c0e1839a7e8e76accf0803e",
+    "index": 36,
+    "guid": "3e71864d-4be5-418e-ace8-346c3d7a9c5f",
+    "isActive": true,
+    "balance": "$3,261.01",
+    "age": 30,
+    "firstName": "Powell",
+    "lastName": "Patterson",
+    "company": "GAZAK",
+    "email": "powell.patterson@gazak.de",
+    "registered": "Thursday, May 18, 2017 10:10 AM",
+    "latitude": "-10.428548",
+    "longitude": "64.979192"
+  },
+  {
+    "_id": "5c0e183984b0320f1118a8b0",
+    "index": 37,
+    "guid": "ec5b292c-6efb-471b-9bf5-a47286e03515",
+    "isActive": false,
+    "balance": "$918.71",
+    "age": 37,
+    "firstName": "Tara",
+    "lastName": "Mcmillan",
+    "company": "GRAINSPOT",
+    "email": "tara.mcmillan@grainspot.de",
+    "registered": "Sunday, May 17, 2015 1:01 PM",
+    "latitude": "-13.519031",
+    "longitude": "67.931062"
+  },
+  {
+    "_id": "5c0e183965875876835ccd79",
+    "index": 38,
+    "guid": "b7e97ffb-439a-4454-90af-7f5ebd565ebc",
+    "isActive": true,
+    "balance": "$574.99",
+    "age": 28,
+    "firstName": "Pennington",
+    "lastName": "Gallegos",
+    "company": "CEDWARD",
+    "email": "pennington.gallegos@cedward.de",
+    "registered": "Wednesday, September 26, 2018 6:01 AM",
+    "latitude": "-63.693261",
+    "longitude": "-38.352153"
+  },
+  {
+    "_id": "5c0e183922505dd21be49009",
+    "index": 39,
+    "guid": "5187aa39-4357-462b-9508-3c537d26d70d",
+    "isActive": false,
+    "balance": "$2,447.08",
+    "age": 26,
+    "firstName": "Meagan",
+    "lastName": "Irwin",
+    "company": "SENTIA",
+    "email": "meagan.irwin@sentia.de",
+    "registered": "Saturday, April 2, 2016 4:39 PM",
+    "latitude": "1.051313",
+    "longitude": "-86.168315"
+  },
+  {
+    "_id": "5c0e183900a9f7f896e5b3b1",
+    "index": 40,
+    "guid": "31889843-79e7-4636-9ca1-4eb5cbcb0ae3",
+    "isActive": true,
+    "balance": "$1,992.25",
+    "age": 22,
+    "firstName": "Kelly",
+    "lastName": "Cobb",
+    "company": "BOVIS",
+    "email": "kelly.cobb@bovis.de",
+    "registered": "Tuesday, August 9, 2016 5:36 PM",
+    "latitude": "-85.547579",
+    "longitude": "-89.794104"
+  },
+  {
+    "_id": "5c0e18393b25b8552ff950e2",
+    "index": 41,
+    "guid": "0bf02edc-ca1b-4cfe-8356-b65881bdca11",
+    "isActive": true,
+    "balance": "$465.96",
+    "age": 27,
+    "firstName": "Angela",
+    "lastName": "Booker",
+    "company": "EQUICOM",
+    "email": "angela.booker@equicom.de",
+    "registered": "Thursday, July 30, 2015 1:39 AM",
+    "latitude": "-9.345395",
+    "longitude": "107.070665"
+  },
+  {
+    "_id": "5c0e183955d747ebbe25437b",
+    "index": 42,
+    "guid": "6405e559-5849-4d12-ae4e-520f13b4dffe",
+    "isActive": true,
+    "balance": "$15.63",
+    "age": 28,
+    "firstName": "Carrie",
+    "lastName": "Mclean",
+    "company": "BOINK",
+    "email": "carrie.mclean@boink.de",
+    "registered": "Wednesday, February 1, 2017 1:50 PM",
+    "latitude": "72.287519",
+    "longitude": "-135.436286"
+  },
+  {
+    "_id": "5c0e1839e9cfe1b28e31e7e6",
+    "index": 43,
+    "guid": "e49e7ca7-a6cc-4cdb-bebe-5a3b6ba931eb",
+    "isActive": true,
+    "balance": "$3,127.94",
+    "age": 33,
+    "firstName": "Callie",
+    "lastName": "Cooley",
+    "company": "MUSIX",
+    "email": "callie.cooley@musix.de",
+    "registered": "Wednesday, August 30, 2017 4:58 PM",
+    "latitude": "-38.954739",
+    "longitude": "-152.706424"
+  },
+  {
+    "_id": "5c0e18391bafa0750ff4f280",
+    "index": 44,
+    "guid": "c245ffd3-4924-4dce-ae4a-f4cabf057b54",
+    "isActive": false,
+    "balance": "$1,320.36",
+    "age": 35,
+    "firstName": "Terry",
+    "lastName": "Bennett",
+    "company": "EXOTECHNO",
+    "email": "terry.bennett@exotechno.de",
+    "registered": "Friday, June 17, 2016 11:54 PM",
+    "latitude": "-48.946183",
+    "longitude": "32.53167"
+  },
+  {
+    "_id": "5c0e1839e91b27fcce34b70f",
+    "index": 45,
+    "guid": "0860cb66-de4c-410e-8233-aeef5ee9d64e",
+    "isActive": false,
+    "balance": "$1,187.75",
+    "age": 30,
+    "firstName": "Phoebe",
+    "lastName": "Bartlett",
+    "company": "VORATAK",
+    "email": "phoebe.bartlett@voratak.de",
+    "registered": "Tuesday, July 25, 2017 2:57 AM",
+    "latitude": "-63.208957",
+    "longitude": "-91.209743"
+  },
+  {
+    "_id": "5c0e183987e8a4e98415c8dd",
+    "index": 46,
+    "guid": "49219833-172c-4659-9192-d1116a5ca833",
+    "isActive": false,
+    "balance": "$3,225.24",
+    "age": 38,
+    "firstName": "Jordan",
+    "lastName": "Evans",
+    "company": "PHARMACON",
+    "email": "jordan.evans@pharmacon.de",
+    "registered": "Sunday, April 23, 2017 6:27 PM",
+    "latitude": "-59.454678",
+    "longitude": "67.251185"
+  },
+  {
+    "_id": "5c0e183944979692cc1a3e48",
+    "index": 47,
+    "guid": "680c4d15-d539-4db9-8793-a2f6d3f354aa",
+    "isActive": false,
+    "balance": "$2,913.14",
+    "age": 28,
+    "firstName": "Goodman",
+    "lastName": "Cain",
+    "company": "CAXT",
+    "email": "goodman.cain@caxt.de",
+    "registered": "Tuesday, November 1, 2016 6:11 PM",
+    "latitude": "-30.187547",
+    "longitude": "-164.313273"
+  },
+  {
+    "_id": "5c0e1839ef5312ac08e3cbc3",
+    "index": 48,
+    "guid": "85f5fa5d-b6b3-47c6-ad1b-faee10a4e1bd",
+    "isActive": true,
+    "balance": "$544.97",
+    "age": 27,
+    "firstName": "Aisha",
+    "lastName": "Oliver",
+    "company": "MINGA",
+    "email": "aisha.oliver@minga.de",
+    "registered": "Sunday, July 3, 2016 8:18 AM",
+    "latitude": "-21.527536",
+    "longitude": "141.029691"
+  },
+  {
+    "_id": "5c0e1839c2e58f5da04f29fd",
+    "index": 49,
+    "guid": "e2ee9b25-5887-49a9-a1c6-17432154d266",
+    "isActive": true,
+    "balance": "$3,621.65",
+    "age": 31,
+    "firstName": "Erin",
+    "lastName": "Lester",
+    "company": "SLOFAST",
+    "email": "erin.lester@slofast.de",
+    "registered": "Saturday, February 20, 2016 5:13 AM",
+    "latitude": "-30.080798",
+    "longitude": "-1.291093"
+  }
+];
+
+const components = {
+  'counter': 'demoApp.counter'
+};
+
+class TreeDemoItem implements ITreeItem {
+  title: string;
+  children?: TreeDemoItem[];
+  disabled?: boolean;
+  icon?: React.ComponentType<SvgIconProps>;
+}
+
+const treeData: TreeDemoItem[] = [
+  {
+    title: "Erste Ebene", children: [
+      {
+        title: "Zweite Ebene", children: [
+          { title: "Dritte Ebene" },
+        ]
+      },
+      { title: "Zweite Ebene 2" },
+    ]
+  },
+  { title: "Erste Ebene 3" },
+];
+
+const SampleDataMaterialTable = MaterialTable as MaterialTableCtorType<SampleData>;
+
+const SampleTree = TreeView as any as TreeViewCtorType<TreeDemoItem>;
+
+const TestComponent = (props: WithComponents<typeof components> & WithStyles<typeof styles>) => {
+
+  return (
+    <div>
+      <h2>About</h2>
+      <ExpansionPanel>
+        <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
+          <Typography className={props.classes.heading}>Client Side Table Demo</Typography>
+        </ExpansionPanelSummary>
+        <ExpansionPanelDetails>
+          <SampleDataMaterialTable rows={tableData} columns={
+            [
+              { property: "index", type: ColumnType.text, title: "Index", width: "80px", disableFilter: true, disableSorting: true },
+              { property: "firstName", type: ColumnType.text, title: "First Name" },
+              { property: "lastName", type: ColumnType.text, title: "Last Name" },
+              { property: "age", type: ColumnType.numeric, title: "Age", width: "60px" },
+              { property: "email", type: ColumnType.text, title: "eMail" },
+              { property: "actions", type: ColumnType.custom, title: "Actions", customControl: ({ rowData }) => (<div>Button</div>) },
+            ]
+          } idProperty={"_id"} title={"Customers 2018"} >
+          </SampleDataMaterialTable>
+        </ExpansionPanelDetails>
+      </ExpansionPanel>
+      <ExpansionPanel>
+        <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
+          <Typography className={props.classes.heading}>Tree Demo</Typography>
+        </ExpansionPanelSummary>
+        <ExpansionPanelDetails>
+          <SampleTree items={treeData} contentProperty={"title"} childrenProperty={"children"} useFolderIcons enableSearchBar />
+        </ExpansionPanelDetails>
+      </ExpansionPanel>
+    </div>
+  )
+};
+
+export const Test = withComponents(components)(withStyles(styles)(TestComponent));
+export default Test;
diff --git a/sdnr/wt/odlux/framework/tsconfig.json b/sdnr/wt/odlux/framework/tsconfig.json
new file mode 100644
index 0000000..d801f7c
--- /dev/null
+++ b/sdnr/wt/odlux/framework/tsconfig.json
@@ -0,0 +1,39 @@
+{
+  "compilerOptions": {
+    "baseUrl": "./src",
+    "outDir": "./dist",
+    "sourceMap": true,
+    "forceConsistentCasingInFileNames": true,
+    "allowSyntheticDefaultImports": false,
+    "allowUnreachableCode": false,
+    "allowUnusedLabels": false,
+    "noFallthroughCasesInSwitch": true,
+    "noImplicitAny": true,
+    "noImplicitReturns": true,
+    "noImplicitThis": true,
+    "strictNullChecks": true,
+    "pretty": true,
+    "newLine": "LF",
+    "module": "es2015",
+    "target": "es2016",
+    "moduleResolution": "node",
+    "experimentalDecorators": true,
+    "jsx": "preserve",
+    "lib": [
+      "dom",
+      "es2015",
+      "es2016"
+    ],
+    "types": [
+      "node",
+      "prop-types",
+      "react",
+      "react-dom",
+      "jest"
+    ]
+  },
+  "exclude": [
+    "dist",
+    "node_modules"
+  ]
+}
diff --git a/sdnr/wt/odlux/framework/webpack.config.js b/sdnr/wt/odlux/framework/webpack.config.js
new file mode 100644
index 0000000..578a0ae
--- /dev/null
+++ b/sdnr/wt/odlux/framework/webpack.config.js
@@ -0,0 +1,203 @@
+/**

+ * ============LICENSE_START========================================================================

+ * ONAP : ccsdk feature sdnr wt odlux

+ * =================================================================================================

+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.

+ * =================================================================================================

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

+ * in compliance with the License. You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License

+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express

+ * or implied. See the License for the specific language governing permissions and limitations under

+ * the License.

+ * ============LICENSE_END==========================================================================

+ */

+/**

+ * Webpack 4 configuration file

+ * see https://webpack.js.org/configuration/

+ * see https://webpack.js.org/configuration/dev-server/

+ */

+

+"use strict";

+

+const path = require("path");

+const webpack = require("webpack");

+const CopyWebpackPlugin = require("copy-webpack-plugin");

+const requirejsPlugin = require('requirejs-webpack-plugin');

+const TerserPlugin = require('terser-webpack-plugin');

+

+// const __dirname = (path => path.replace(/^([a-z]\:)/, c => c.toUpperCase()))(process.__dirname());

+

+module.exports = (env) => {

+  const distPath = path.resolve(__dirname, env === "release" ? "." : "..", "dist");

+  const frameworkPath = path.resolve(__dirname, env === "release" ? "." : "..", "dist");

+  return [{

+    name: "Client",

+    mode: "none", //disable default behavior

+    target: "web",

+

+    context: path.resolve(__dirname, "src"),

+

+    entry: {

+      app: [

+        "./app.tsx",

+        "./services",

+        "./components/material-table",

+        "./components/material-ui",

+        "./utilities/elasticSearch",

+        "./models"],

+    },

+

+    devtool: env === "release" ? false : "source-map",

+

+    resolve: {

+      extensions: [".ts", ".tsx", ".js", ".jsx"]

+    },

+

+    output: {

+      path: distPath,

+      library: "[name]", // related to webpack.DllPlugin::name

+      libraryTarget: "umd2",

+      filename: "[name].js",

+      chunkFilename: "[name].js"

+    },

+

+    module: {

+      rules: [{

+        test: /\.tsx?$/,

+        exclude: /node_modules/,

+        use: [{

+          loader: "babel-loader"

+        }, {

+          loader: "ts-loader"

+        }]

+      }, {

+        test: /\.jsx?$/,

+        exclude: /node_modules/,

+        use: [{

+          loader: "babel-loader"

+        }]

+      }, {

+        test: /\.(png|gif|jpg|svg)$/,

+        use: [{

+          loader: 'url-loader',

+          options: {

+            limit: 10000,

+            name: './images/[hash].[ext]'

+          }

+        }]

+      }]

+    },

+

+    optimization: {

+      noEmitOnErrors: true,

+      namedModules: env !== "release",

+      minimize: env === "release",

+      minimizer: env !== "release" ? [] : [new TerserPlugin({

+        terserOptions: {

+          mangle: {

+            reserved: ["./app.tsx"]

+          },

+          warnings: false, // false, true, "verbose"

+          compress: {

+            drop_console: true,

+            drop_debugger: true,

+          }

+        }

+      })],

+    },

+

+    plugins: [

+      new CopyWebpackPlugin([{

+        from: '../../node_modules/requirejs/require.js',

+        to: '.'

+      }, {

+        from: './favicon.ico',

+        to: '.'

+      }, {

+        from: env === "release" ? './index.html' : 'index.dev.html',

+        to: './index.html'

+      }]),

+      new requirejsPlugin({

+        path: distPath,

+        filename: 'config.js',

+        baseUrl: '',

+        pathUrl: '',

+        processOutput: function (assets) {

+          return 'require.config(' + JSON.stringify(assets, null, 2) + ')';

+        }

+      }),

+      // new HtmlWebpackPlugin({

+      //   filename: "index.html",

+      //   template: "./index.html",

+      //   inject: "head"

+      // }),

+      // new HtmlWebpackIncludeAssetsPlugin({

+      //    assets: ['vendor.js'],

+      //    append: false

+      // }),

+      new webpack.DllReferencePlugin({

+        context: path.resolve(__dirname, "src"),

+        manifest: require(path.resolve(frameworkPath, "vendor-manifest.json")),

+        sourceType: "umd2"

+      }),

+      new webpack.DllPlugin({

+        context: path.resolve(__dirname, "src"),

+        name: "[name]",

+        path: path.resolve(distPath, "[name]-manifest.json")

+      }),

+      ...(env === "release") ? [

+        new webpack.DefinePlugin({

+          "process.env": {

+            NODE_ENV: "'production'",

+            VERSION: JSON.stringify(require("./package.json").version)

+          }

+        }),

+      ] : [

+          new webpack.HotModuleReplacementPlugin(),

+          new webpack.DefinePlugin({

+            "process.env": {

+              NODE_ENV: "'development'",

+              VERSION: JSON.stringify(require("./package.json").version)

+            }

+          }),

+          new webpack.WatchIgnorePlugin([

+            /css\.d\.ts$/,

+            /less\.d\.ts$/

+          ])

+        ]

+    ],

+

+    devServer: {

+      public: "http://localhost:3100",

+      contentBase: distPath,

+

+      compress: true,

+      headers: {

+        "Access-Control-Allow-Origin": "*"

+      },

+      host: "0.0.0.0",

+      port: 3100,

+      disableHostCheck: true,

+      historyApiFallback: true,

+      inline: true,

+      hot: false,

+      quiet: false,

+      stats: {

+        colors: true

+      },

+      proxy: {

+        "/oauth2/**/*": {

+          target: "http://10.20.6.29:48181",

+          secure: false

+        }

+      }

+    }

+

+  }];

+}

+

+

diff --git a/sdnr/wt/odlux/framework/webpack.runner.js b/sdnr/wt/odlux/framework/webpack.runner.js
new file mode 100644
index 0000000..c07721f
--- /dev/null
+++ b/sdnr/wt/odlux/framework/webpack.runner.js
@@ -0,0 +1,85 @@
+/**
+ * Webpack 4 configuration file
+ * see https://webpack.js.org/configuration/
+ * see https://webpack.js.org/configuration/dev-server/
+ */
+
+"use strict";
+
+const path = require("path");
+const webpack = require("webpack");
+const TerserPlugin = require('terser-webpack-plugin');
+
+// const __dirname = (path => path.replace(/^([a-z]\:)/, c => c.toUpperCase()))(process.__dirname());
+
+module.exports = (env) => {
+  const distPath = path.resolve(__dirname, env === "release" ? "." : "..", "dist");
+  const frameworkPath = path.resolve(__dirname, env === "release" ? "." : "..", "dist");
+  return [{
+    name: "App",
+
+    mode: "none", //disable default behavior
+
+    target: "web",
+
+    context: path.resolve(__dirname, "src"),
+
+    entry: {
+      run: ["./run.ts"]
+    },
+
+    devtool: env === "release" ? false : "source-map",
+
+    resolve: {
+      extensions: [".ts", ".tsx", ".js", ".jsx"]
+    },
+
+    output: {
+      path: distPath,
+      filename: "[name].js",
+      library: "[name]",
+      libraryTarget: "umd2",
+      chunkFilename: "[name].js"
+    },
+    module: {
+      rules: [{
+        test: /\.tsx?$/,
+        exclude: /node_modules/,
+        use: [{
+          loader: "babel-loader"
+        }, {
+          loader: "ts-loader"
+        }]
+      }, {
+        test: /\.jsx?$/,
+        exclude: /node_modules/,
+        use: [{
+          loader: "babel-loader"
+        }]
+      }]
+    },
+    optimization: {
+      noEmitOnErrors: true,
+      namedModules: env !== "release",
+      minimize: env === "release",
+      minimizer: env !== "release" ? [] : [new TerserPlugin({
+        terserOptions: {
+          warnings: false, // false, true, "verbose"
+          compress: {
+            drop_console: true,
+            drop_debugger: true,
+          }
+        }
+      })],
+    },
+    plugins: [
+      new webpack.DllReferencePlugin({
+        context: path.resolve(__dirname, "./src"),
+        manifest: require(path.resolve(frameworkPath, "app-manifest.json")),
+        sourceType: "umd2"
+      }),
+
+    ]
+  }
+  ]
+};
\ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/webpack.vendor.js b/sdnr/wt/odlux/framework/webpack.vendor.js
new file mode 100644
index 0000000..649c9b9
--- /dev/null
+++ b/sdnr/wt/odlux/framework/webpack.vendor.js
@@ -0,0 +1,130 @@
+/**
+ * Webpack 4 configuration file
+ * see https://webpack.js.org/configuration/
+ * see https://webpack.js.org/configuration/dev-server/
+ */
+
+"use strict";
+
+const path = require("path");
+const webpack = require("webpack");
+
+const TerserPlugin = require('terser-webpack-plugin');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const extractCSS = new ExtractTextPlugin('vendor.css');
+
+// const __dirname = (path => path.replace(/^([a-z]\:)/, c => c.toUpperCase()))(process.__dirname());
+
+module.exports = (env) => {
+  const distPath = path.resolve(__dirname, env === "release" ? "." : "..", "dist");
+  const frameworkPath = path.resolve(__dirname, env === "release" ? "." : "..", "dist");
+  return [{
+    name: "Vendor",
+    mode: "none", //disable default behavior
+    target: "web",
+
+    context: path.resolve(__dirname, "src"),
+
+    entry: {
+      vendor: [
+        "@babel/polyfill",
+        "@fortawesome/fontawesome-svg-core",
+        "@fortawesome/free-solid-svg-icons",
+        "@fortawesome/react-fontawesome",
+        "jquery",
+        "react",
+        "react-dom",
+        "react-router-dom",
+        "@material-ui/core"
+      ]
+    },
+
+    devtool: env === "release" ? false : "source-map",
+
+    resolve: {
+      extensions: [".ts", ".tsx", ".js", ".jsx"]
+    },
+
+    output: {
+      path: distPath,
+      library: "[name]", // related to webpack.DllPlugin::name
+      libraryTarget: "umd2",
+      filename: "[name].js",
+      chunkFilename: "[name].js"
+    },
+
+    module: {
+      rules: [{
+        test: /\.tsx?$/,
+        exclude: /node_modules/,
+        use: [{
+          loader: "babel-loader"
+        }, {
+          loader: "ts-loader"
+        }]
+      },
+      {
+        test: /\.jsx?$/,
+        exclude: /node_modules/,
+        use: [{
+          loader: "babel-loader"
+        }]
+      },
+      {
+        test: /\.(png|woff|woff2|eot|ttf|svg)$/,
+        loader: 'url-loader?limit=100000&name=assets/[name].[ext]'
+      }, {
+        test: /\.s?css$/i,
+        loader: extractCSS.extract(['css-loader?minimize', 'sass-loader'])
+      }, {
+        test: /\.json$/,
+        loader: 'json-loader'
+      },
+      ]
+    },
+
+    optimization: {
+      noEmitOnErrors: true,
+      namedModules: env !== "release",
+      minimize: env === "release",
+      minimizer: env !== "release" ? [] : [new TerserPlugin({
+        terserOptions: {
+          warnings: false, // false, true, "verbose"
+          compress: {
+            drop_console: true,
+            drop_debugger: true,
+          }
+        }
+      })],
+    },
+
+    plugins: [
+      extractCSS,
+      new webpack.DllPlugin({
+        context: path.resolve(__dirname, "src"),
+        name: "[name]",
+        path: path.resolve(distPath, "[name]-manifest.json")
+      }),
+      ...(env === "release") ? [
+        new webpack.DefinePlugin({
+          "process.env": {
+            NODE_ENV: "'production'",
+            VERSION: JSON.stringify(require("./package.json").version)
+          }
+        })
+      ] : [
+          new webpack.HotModuleReplacementPlugin(),
+          new webpack.DefinePlugin({
+            "process.env": {
+              NODE_ENV: "'development'",
+              VERSION: JSON.stringify(require("./package.json").version)
+            }
+          }),
+          new webpack.WatchIgnorePlugin([
+            /s?css\.d\.ts$/,
+            /less\.d\.ts$/
+          ])
+        ]
+    ]
+  }];
+}