From 83b7609bfa772968e846c0c4377365dabd6e1ca0 Mon Sep 17 00:00:00 2001
From: Xiao Gui <xgui3783@gmail.com>
Date: Thu, 10 Mar 2022 14:38:55 +0100
Subject: [PATCH] wip: migrate to sapiview/core wip: migrate/remove
 src/service/

---
 src/atlasComponents/parcellation/module.ts    |   4 +-
 .../regionSearch/regionSearch.component.ts    |  20 +-
 .../regionSearch/regionSearch.template.html   |   9 +-
 .../parcellationRegion/TODO.md                |   3 -
 .../parcellationRegion/index.ts               |   7 -
 .../parcellationRegion/module.ts              |  42 ---
 .../parcellationRegion/region.base.spec.ts    | 333 -----------------
 .../parcellationRegion/region.base.ts         | 158 --------
 .../parcellationRegion/region.directive.ts    |  14 -
 .../regionAccordionTooltipText.pipe.ts        |  18 -
 .../regionInOtherTmpl.pipe.ts                 |  14 -
 .../regionSimple/regionSimple.component.ts    |  21 --
 .../regionSimple/regionSimple.template.html   |  26 --
 .../parcellationRegion/type.ts                |  24 --
 src/atlasComponents/sapi/schema.ts            |  27 +-
 src/atlasComponents/sapi/type.ts              |  21 +-
 .../dropdownAtlasSelector.component.ts        |   1 -
 .../tmplParcSelector.style.css                |   9 +-
 .../tmplParcSelector.template.html            |  99 ++---
 .../core/datasets/dataset/dataset.stories.ts  |   2 +-
 .../chip/parcellation.chip.component.ts       |  26 ++
 .../chip/parcellation.chip.stories.ts         | 118 ++++++
 .../chip/parcellation.chip.style.css}         |   0
 .../chip/parcellation.chip.template.html      |  16 +
 .../filterUnsupportedParc.pipe.ts             |   2 +-
 .../sapiViews/core/parcellation/module.ts     |  33 +-
 .../parcellationIsBaseLayer.pipe.ts           |  22 ++
 .../parcellation/parcellationVis.service.ts   |  21 ++
 .../parcellation.smartChip.component.ts       |  99 +++++
 .../parcellation.smartChip.stories.ts         | 108 ++++++
 .../parcellation.smartChip.style.css}         |   0
 .../parcellation.smartChip.template.html      |  49 +++
 .../tile/parcellation.tile.template.html      |   1 +
 .../region/rich/region.rich.component.ts      |   4 +-
 .../entryListItem/entryListItem.component.ts  |  22 +-
 .../entryListItem/entryListItem.template.html |   4 +-
 .../features/featureBadgeColor.pipe.ts        |   2 +-
 .../features/featureBadgeName.pipe.ts         |   2 +-
 .../autoradiography/autoradiograph.stories.ts |   2 +-
 .../sapiViews/features/receptors/base.ts      |   4 +-
 .../features/receptors/entry/entry.stories.ts |   2 +-
 .../fingerprint/fingerprint.stories.ts        |   2 +-
 .../receptors/profile/profile.stories.ts      |   2 +-
 .../atlasViewer.apiService.service.ts         |  13 +-
 src/atlasViewer/atlasViewer.component.ts      |  31 +-
 src/extra_styles.css                          |   7 +-
 .../currentLayout/currentLayout.component.ts  |  21 +-
 .../currentLayout/currentLayout.template.html |  18 +-
 src/main.module.ts                            |  68 +---
 src/mouseoverModule/mouseover.directive.ts    |  41 ++-
 src/overwrite.scss                            |  52 ++-
 src/plugin/pluginCsp/pluginCsp.component.ts   |   4 +-
 src/routerModule/util.ts                      |  34 --
 .../state/ngViewerState.store.helper.ts       |   4 +-
 .../state/ngViewerState.store.spec.ts         | 100 -----
 src/services/state/ngViewerState.store.ts     | 341 ------------------
 src/services/state/ngViewerState/actions.ts   |   5 -
 src/services/state/ngViewerState/selectors.ts |   9 -
 src/services/state/uiState.store.helper.ts    |   4 -
 src/services/state/uiState.store.ts           | 223 ------------
 src/services/state/uiState/selectors.ts       |  17 -
 src/services/state/uiState/ui.effects.ts      |  32 --
 src/services/state/userConfigState.store.ts   | 143 --------
 src/services/state/viewerConfig.store.ts      |  79 ----
 src/services/state/viewerConfig/selectors.ts  |   6 -
 src/services/stateStore.service.ts            | 131 -------
 src/state/atlasAppearance/action.ts           |  14 +
 src/state/atlasAppearance/index.ts            |   1 +
 src/state/atlasAppearance/selector.ts         |  10 +
 src/state/atlasAppearance/store.ts            |  26 +-
 src/state/effects/TODO.md                     |   3 +
 src/state/index.ts                            |  55 ++-
 src/state/userInterface/actions.ts            |  34 +-
 src/state/userInterface/const.ts              |   6 +-
 src/state/userInterface/effects.ts            |  75 +++-
 src/state/userInterface/index.ts              |   5 +-
 src/state/userInterface/selectors.ts          |   9 +-
 src/state/userInterface/store.ts              |  26 +-
 src/state/userPreference/actions.ts           |  39 ++
 src/state/userPreference/const.ts             |   9 +
 src/state/userPreference/effects.ts           |  48 +++
 src/state/userPreference/index.ts             |   4 +
 src/state/userPreference/selectors.ts         |  35 ++
 src/state/userPreference/store.ts             |  93 +++++
 src/ui/config/configCmp/config.component.ts   |  82 ++---
 src/ui/config/configCmp/config.stories.ts     |  46 +++
 src/ui/config/configCmp/config.style.css      |  12 +
 src/ui/config/configCmp/config.template.html  | 233 ++++++------
 src/ui/config/module.ts                       |   2 +-
 src/ui/ui.module.ts                           |   2 -
 src/util/constants.ts                         |   2 +-
 src/util/pureConstant.service.ts              |   4 +-
 src/viewerModule/module.ts                    |   2 -
 .../layerCtrl.service.spec.ts                 | 289 +--------------
 .../layerCtrl.service/layerCtrl.service.ts    |  23 +-
 .../layerCtrl.service/layerCtrl.util.ts       |   2 +-
 .../maximisePanelButton.component.ts          |  26 +-
 .../navigation.service.spec.ts                |   9 +-
 .../navigation.service/navigation.service.ts  |   8 +-
 .../nehubaViewer/nehubaViewer.component.ts    |   3 +-
 .../nehubaViewerGlue.component.spec.ts        |  16 +-
 .../nehubaViewerGlue.component.ts             |   7 +-
 .../nehubaViewerGlue.template.html            |   2 +-
 .../nehubaViewerInterface.directive.spec.ts   |  13 +-
 .../nehubaViewerInterface.directive.ts        |  44 +--
 src/viewerModule/nehuba/store/actions.ts      |   4 +-
 .../nehuba/touchSideClass.directive.ts        |  22 +-
 .../viewerCtrlCmp.component.spec.ts           |   6 +-
 .../viewerCtrlCmp/viewerCtrlCmp.component.ts  |  86 ++---
 .../viewerCtrlCmp/viewerCtrlCmp.template.html |  15 -
 .../viewerCmp/viewerCmp.component.ts          |  15 +-
 .../viewerCmp/viewerCmp.template.html         | 164 ++++-----
 .../breadcrumb/breadcrumb.template.html       |  25 +-
 .../viewerStateBreadCrumb/module.ts           |   2 -
 114 files changed, 1639 insertions(+), 2795 deletions(-)
 delete mode 100644 src/atlasComponents/parcellationRegion/TODO.md
 delete mode 100644 src/atlasComponents/parcellationRegion/index.ts
 delete mode 100644 src/atlasComponents/parcellationRegion/module.ts
 delete mode 100644 src/atlasComponents/parcellationRegion/region.base.spec.ts
 delete mode 100644 src/atlasComponents/parcellationRegion/region.base.ts
 delete mode 100644 src/atlasComponents/parcellationRegion/region.directive.ts
 delete mode 100644 src/atlasComponents/parcellationRegion/regionAccordionTooltipText.pipe.ts
 delete mode 100644 src/atlasComponents/parcellationRegion/regionInOtherTmpl.pipe.ts
 delete mode 100644 src/atlasComponents/parcellationRegion/regionSimple/regionSimple.component.ts
 delete mode 100644 src/atlasComponents/parcellationRegion/regionSimple/regionSimple.template.html
 delete mode 100644 src/atlasComponents/parcellationRegion/type.ts
 create mode 100644 src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.component.ts
 create mode 100644 src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.stories.ts
 rename src/atlasComponents/{parcellationRegion/regionSimple/regionSimple.style.css => sapiViews/core/parcellation/chip/parcellation.chip.style.css} (100%)
 create mode 100644 src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.template.html
 create mode 100644 src/atlasComponents/sapiViews/core/parcellation/parcellationIsBaseLayer.pipe.ts
 create mode 100644 src/atlasComponents/sapiViews/core/parcellation/parcellationVis.service.ts
 create mode 100644 src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts
 create mode 100644 src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.stories.ts
 rename src/{services/state/uiState.store.spec.ts => atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.style.css} (100%)
 create mode 100644 src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
 delete mode 100644 src/services/state/ngViewerState.store.spec.ts
 delete mode 100644 src/services/state/ngViewerState.store.ts
 delete mode 100644 src/services/state/uiState.store.ts
 delete mode 100644 src/services/state/uiState/selectors.ts
 delete mode 100644 src/services/state/uiState/ui.effects.ts
 delete mode 100644 src/services/state/userConfigState.store.ts
 delete mode 100644 src/services/state/viewerConfig.store.ts
 delete mode 100644 src/services/state/viewerConfig/selectors.ts
 create mode 100644 src/state/effects/TODO.md
 create mode 100644 src/state/userPreference/actions.ts
 create mode 100644 src/state/userPreference/const.ts
 create mode 100644 src/state/userPreference/effects.ts
 create mode 100644 src/state/userPreference/index.ts
 create mode 100644 src/state/userPreference/selectors.ts
 create mode 100644 src/state/userPreference/store.ts
 create mode 100644 src/ui/config/configCmp/config.stories.ts

diff --git a/src/atlasComponents/parcellation/module.ts b/src/atlasComponents/parcellation/module.ts
index 7763c155a..5941ce7af 100644
--- a/src/atlasComponents/parcellation/module.ts
+++ b/src/atlasComponents/parcellation/module.ts
@@ -1,7 +1,6 @@
 import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
 import { AngularMaterialModule } from "src/sharedModules";
-import { ParcellationRegionModule } from "src/atlasComponents/parcellationRegion";
 import { RegionHierarchy } from "./regionHierachy/regionHierarchy.component";
 import { RegionTextSearchAutocomplete } from "./regionSearch/regionSearch.component";
 import { FilterNameBySearch } from "./regionHierachy/filterNameBySearch.pipe";
@@ -16,7 +15,6 @@ import { ComponentsModule } from "src/components";
     FormsModule,
     ReactiveFormsModule,
     AngularMaterialModule,
-    ParcellationRegionModule,
     ComponentsModule,
   ],
   declarations: [
@@ -29,6 +27,8 @@ import { ComponentsModule } from "src/components";
     RegionHierarchy,
     RegionTextSearchAutocomplete,
     FilterNameBySearch,
+  ],
+  providers: [
   ]
 })
 export class AtlasCmpParcellationModule{}
\ No newline at end of file
diff --git a/src/atlasComponents/parcellation/regionSearch/regionSearch.component.ts b/src/atlasComponents/parcellation/regionSearch/regionSearch.component.ts
index 7f98db57d..45b7314c6 100644
--- a/src/atlasComponents/parcellation/regionSearch/regionSearch.component.ts
+++ b/src/atlasComponents/parcellation/regionSearch/regionSearch.component.ts
@@ -3,7 +3,6 @@ import { FormControl } from "@angular/forms";
 import { select, Store } from "@ngrx/store";
 import { combineLatest, Observable, Subject, merge } from "rxjs";
 import { debounceTime, distinctUntilChanged, filter, map, shareReplay, startWith, take, tap, withLatestFrom } from "rxjs/operators";
-import { getMultiNgIdsRegionsLabelIndexMap } from "src/services/stateStore.service";
 import { LoggingService } from "src/logging";
 import { MatDialog } from "@angular/material/dialog";
 import { MatAutocompleteSelectedEvent } from "@angular/material/autocomplete";
@@ -72,24 +71,7 @@ export class RegionTextSearchAutocomplete {
       distinctUntilChanged(),
       filter(p => !!p && p.regions),
       map(parcellationSelected => {
-        try {
-          const returnArray = []
-          const ngIdMap = getMultiNgIdsRegionsLabelIndexMap(parcellationSelected, { ngId: 'root', relatedAreas: [], fullId: null })
-          for (const [ngId, labelIndexMap] of ngIdMap) {
-            for (const [labelIndex, region] of labelIndexMap) {
-              returnArray.push({
-                ...region,
-                ngId,
-                labelIndex,
-                labelIndexId: serializeSegment(ngId, labelIndex),
-              })
-            }
-          }
-          return returnArray
-        } catch (e) {
-          this.log.warn(`getMultiNgIdsRegionsLabelIndexMap error`, e)
-          return []
-        }
+        return []
       }),
       shareReplay(1),
     )
diff --git a/src/atlasComponents/parcellation/regionSearch/regionSearch.template.html b/src/atlasComponents/parcellation/regionSearch/regionSearch.template.html
index a5db58d62..e7f60fc7a 100644
--- a/src/atlasComponents/parcellation/regionSearch/regionSearch.template.html
+++ b/src/atlasComponents/parcellation/regionSearch/regionSearch.template.html
@@ -36,11 +36,12 @@
         *ngFor="let region of autocompleteList$ | async"
         [value]="region.labelIndexId">
 
-        <simple-region
-          [region-base-region]="region">
-          <!-- [isSelected]="regionsSelected$ | async | includes : region : compareFn"> -->
+        <!-- TODO replace with sapiViews/core/region/simple -->
+        <!-- <simple-region
+          [region-base-region]="region"
+          [isSelected]="regionsSelected$ | async | includes : region : compareFn">
 
-        </simple-region>
+        </simple-region> -->
       </mat-option>
     </mat-autocomplete>
   </form>
diff --git a/src/atlasComponents/parcellationRegion/TODO.md b/src/atlasComponents/parcellationRegion/TODO.md
deleted file mode 100644
index fbf02893d..000000000
--- a/src/atlasComponents/parcellationRegion/TODO.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# TODO
-
-migrate src/atlasComponents/parcellationRegion -> src/sapiViews/core/region
\ No newline at end of file
diff --git a/src/atlasComponents/parcellationRegion/index.ts b/src/atlasComponents/parcellationRegion/index.ts
deleted file mode 100644
index d5869daaa..000000000
--- a/src/atlasComponents/parcellationRegion/index.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export {
-  ParcellationRegionModule,
-} from "./module"
-
-export { RegionDirective } from "./region.directive";
-export { SimpleRegionComponent } from "./regionSimple/regionSimple.component";
-export { RenderViewOriginDatasetLabelPipe } from "./region.base";
\ No newline at end of file
diff --git a/src/atlasComponents/parcellationRegion/module.ts b/src/atlasComponents/parcellationRegion/module.ts
deleted file mode 100644
index 20f1f4fb3..000000000
--- a/src/atlasComponents/parcellationRegion/module.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { NgModule } from "@angular/core";
-import { ComponentsModule } from "src/components";
-import { AngularMaterialModule } from "src/sharedModules";
-import { UtilModule } from "src/util";
-import { RenderViewOriginDatasetLabelPipe } from "./region.base";
-import { RegionDirective } from "./region.directive";
-import { SimpleRegionComponent } from "./regionSimple/regionSimple.component";
-import { RegionAccordionTooltipTextPipe } from "./regionAccordionTooltipText.pipe";
-import { AtlasCmptConnModule } from "../connectivity";
-import { HttpClientModule } from "@angular/common/http";
-import { RegionInOtherTmplPipe } from "./regionInOtherTmpl.pipe";
-import { SiibraExplorerTemplateModule } from "../template";
-
-@NgModule({
-  imports: [
-    CommonModule,
-    UtilModule,
-    AngularMaterialModule,
-    ComponentsModule,
-    AtlasCmptConnModule,
-    HttpClientModule,
-    SiibraExplorerTemplateModule,
-
-  ],
-  declarations: [
-    SimpleRegionComponent,
-
-    RegionDirective,
-    RenderViewOriginDatasetLabelPipe,
-    RegionAccordionTooltipTextPipe,
-    RegionInOtherTmplPipe,
-  ],
-  exports: [
-    SimpleRegionComponent,
-
-    RegionDirective,
-    RenderViewOriginDatasetLabelPipe,
-  ]
-})
-
-export class ParcellationRegionModule{}
\ No newline at end of file
diff --git a/src/atlasComponents/parcellationRegion/region.base.spec.ts b/src/atlasComponents/parcellationRegion/region.base.spec.ts
deleted file mode 100644
index d3ead88e5..000000000
--- a/src/atlasComponents/parcellationRegion/region.base.spec.ts
+++ /dev/null
@@ -1,333 +0,0 @@
-import { TestBed } from '@angular/core/testing'
-import { MockStore, provideMockStore } from '@ngrx/store/testing'
-import { viewerStateSelectTemplateWithId } from 'src/services/state/viewerState/actions'
-import { RegionBase } from './region.base'
-import { TSiibraExRegion } from './type'
-
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const util = require('common/util')
-
-/**
- * regions
- */
-
-const mr0 = {
-  labelIndex: 1,
-  name: 'mr0',
-  availableIn: [{id: 'fzj/mock/rs/v0.0.0/aaa-bbb'}, {id: 'fzj/mock/rs/v0.0.0/bbb-bbb'}, {id: 'fzj/mock/rs/v0.0.0/ccc-bbb'}],
-  id: {
-    kg: {
-      kgSchema: 'fzj/mock/pr',
-      kgId: 'aaa-bbb'
-    }
-  }
-}
-
-enum EnumParcRegVersion{
-  V1_18 = 'V1_18',
-  V2_4 = "V2_4"
-}
-
-describe('> region.base.ts', () => {
-  describe('> RegionBase', () => {
-    let regionBase: RegionBase
-    let mockStore: MockStore
-    beforeEach(() => {
-      TestBed.configureTestingModule({
-        providers: [
-          provideMockStore()
-        ]
-      })
-      mockStore = TestBed.inject(MockStore)
-    })
-    describe('> position', () => {
-      beforeEach(() => {
-        regionBase = new RegionBase(mockStore)
-      })
-      it('> does not populate if position property is absent', () => {
-        regionBase.region = {
-          ...mr0
-        } as any
-        expect(regionBase.position).toBeFalsy()
-      })
-
-      describe('> does not populate if position property is malformed', () => {
-        it('> if region is falsy', () => {
-          regionBase.region = null
-          expect(regionBase.position).toBeFalsy()
-        })
-        it('> if props is falsy', () => {
-          regionBase.region = {
-            ...mr0,
-            props: null
-          } as any
-          expect(regionBase.position).toBeFalsy()
-        })
-        it('> if props.components is falsy', () => {
-          regionBase.region = {
-            ...mr0,
-            props: {
-              components: null
-            }
-          } as any
-          expect(regionBase.position).toBeFalsy()
-        })
-        it('> if props.components[0] is falsy', () => {
-          regionBase.region = {
-            ...mr0,
-            props: {
-              components: []
-            }
-          } as any
-          expect(regionBase.position).toBeFalsy()
-        })
-
-        it('> if props.components[0].centroid is falsy', () => {
-
-          regionBase.region = {
-            ...mr0,
-            props: {
-              components: [{
-                centroid: null
-              }]
-            }
-          } as any
-          expect(regionBase.position).toBeFalsy()
-        })
-      })
-
-      it('> populates if position property is array with length 3 and non NaN element', () => {
-        regionBase.region = {
-          ...mr0,
-          props: {
-            components: [{
-              centroid: [1, 2, 3]
-            }]
-          },
-        } as any
-        expect(regionBase.position).toBeTruthy()
-      })
-    })
-
-    describe('> rgb', () => {
-      let strToRgbSpy: jasmine.Spy
-      let mockStore: MockStore
-      beforeEach(() => {
-        strToRgbSpy = spyOn(util, 'strToRgb')
-        mockStore = TestBed.inject(MockStore)
-      })
-
-      afterEach(() => {
-        strToRgbSpy.calls.reset()
-      })
-
-      it('> will take region.rgb if exists', () => {
-        const regionBase = new RegionBase(mockStore)
-        regionBase.region = {
-          rgb: [100, 120, 140]
-        } as any
-        expect(
-          regionBase.rgbString
-        ).toEqual(`rgb(100,120,140)`)
-      })
-
-      it('> if rgb not provided, and labelIndex > 65500, set to white', () => {
-
-        const regionBase = new RegionBase(mockStore)
-        regionBase.region = {
-          labelIndex: 65535
-        } as any
-        expect(
-          regionBase.rgbString
-        ).toEqual(`rgb(255,255,255)`)
-      })
-
-      describe('> if rgb not provided, labelIndex < 65500', () => {
-
-        describe('> arguments for strToRgb', () => {
-          it('> if ngId is defined, use ngId', () => {
-
-            const regionBase = new RegionBase(mockStore)
-            regionBase.region = {
-              ngId: 'foo',
-              name: 'bar',
-              labelIndex: 152
-            } as any
-            expect(strToRgbSpy).toHaveBeenCalledWith(`foo152`)
-          })
-          it('> if ngId is not defined, use name', () => {
-
-            const regionBase = new RegionBase(mockStore)
-            regionBase.region = {
-              name: 'bar',
-              labelIndex: 152
-            } as any
-            expect(strToRgbSpy).toHaveBeenCalledWith(`bar152`)
-          })
-        })
-
-        it('> calls strToRgb, and use return value for rgb', () => {
-          const getRandomNum = () => Math.floor(255*Math.random())
-          const arr = [
-            getRandomNum(),
-            getRandomNum(),
-            getRandomNum()
-          ]
-          strToRgbSpy.and.returnValue(arr)
-          const regionBase = new RegionBase(mockStore)
-          regionBase.region = {
-            foo: 'bar'
-          } as any
-          expect(
-            regionBase.rgbString
-          ).toEqual(`rgb(${arr.join(',')})`)
-        })
-
-        it('> if strToRgb returns falsy, uses fallback', () => {
-
-          strToRgbSpy.and.returnValue(null)
-          const regionBase = new RegionBase(mockStore)
-          regionBase.region = {
-            foo: 'bar'
-          } as any
-          expect(
-            regionBase.rgbString
-          ).toEqual(`rgb(255,200,200)`)
-        })
-      })
-    })
-    describe('> changeView', () => {
-      const fakeTmpl = {
-        '@id': 'faketmplid',
-        name: 'fakeTmpl'
-      }
-      const fakeParc = {
-        '@id': 'fakeparcid',
-        name: 'fakeParc'
-      }
-      beforeEach(() => {
-        regionBase = new RegionBase(mockStore)
-      })
-
-      describe('> [tmp] sameRegion to use transform backend', () => {
-        let dispatchSpy: jasmine.Spy
-
-        beforeEach(() => {
-          dispatchSpy = spyOn(mockStore, 'dispatch')
-        })
-        afterEach(() => {
-          dispatchSpy.calls.reset()
-        })
-
-        it('> calls viewerStateSelectTemplateWithId', () => {
-
-          const partialRegion = {
-            context: {
-              parcellation: fakeParc,
-              atlas: {
-                "@id": '',
-                name: '',
-                parcellations: [],
-                templateSpaces: [fakeTmpl]
-              },
-              template: null
-            }
-          } as Partial<TSiibraExRegion>
-          regionBase.region = partialRegion as any
-          regionBase.changeView(fakeTmpl)
-
-          expect(dispatchSpy).toHaveBeenCalledWith(
-            viewerStateSelectTemplateWithId({
-              payload: {
-                '@id': fakeTmpl['@id']
-              },
-              config: {
-                selectParcellation: {
-                  "@id": fakeParc['@id']
-                }
-              }
-            })
-          )
-        })
-      })
-
-      /**
-       * currently, without position metadata, the navigation is broken
-       * fix changeView to fetch position metadata. If cannot, fallback to spatial backend
-       */
-
-      // describe('> if sameRegion has position attribute', () => {
-      //   let dispatchSpy: jasmine.Spy
-
-      //   beforeEach(() => {
-      //     dispatchSpy = spyOn(mockStore, 'dispatch')
-      //   })
-      //   afterEach(() => {
-      //     dispatchSpy.calls.reset()
-      //   })
-      //   it('> malformed position is not an array > do not pass position', () => {
-
-      //     regionBase.changeView({
-      //       template: fakeTmpl,
-      //       parcellation: fakeParc,
-      //       region: {
-      //         position: 'hello wolrd'
-      //       }
-      //     })
-
-      //     expect(dispatchSpy).toHaveBeenCalledWith(
-      //       actionViewerStateNewViewer({
-      //         selectTemplate: fakeTmpl,
-      //         selectParcellation: fakeParc,
-      //         navigation: {}
-      //       })
-      //     )
-      //   })
-
-      //   it('> malformed position is an array of incorrect size > do not pass position', () => {
-
-      //     regionBase.changeView({
-      //       template: fakeTmpl,
-      //       parcellation: fakeParc,
-      //       region: {
-      //         position: []
-      //       }
-      //     })
-
-      //     expect(dispatchSpy).toHaveBeenCalledWith(
-      //       viewerStateSelectTemplateWithId({
-      //         payload: {
-      //           '@id': fakeTmpl['@id']
-      //         },
-      //         config: {
-      //           selectParcellation: {
-      //             "@id": fakeParc['@id']
-      //           }
-      //         }
-      //       })
-      //     )
-      //   })
-
-      //   it('> correct position > pass position', () => {
-      //     regionBase.changeView({
-      //       template: fakeTmpl,
-      //       parcellation: fakeParc,
-      //       region: {
-      //         position: [1,2,3]
-      //       }
-      //     })
-
-      //     expect(dispatchSpy).toHaveBeenCalledWith(
-      //       actionViewerStateNewViewer({
-      //         selectTemplate: fakeTmpl,
-      //         selectParcellation: fakeParc,
-      //         navigation: {
-      //           position: [1,2,3]
-      //         }
-      //       })
-      //     )
-      //   })
-      // })
-    })
-  })
-})
diff --git a/src/atlasComponents/parcellationRegion/region.base.ts b/src/atlasComponents/parcellationRegion/region.base.ts
deleted file mode 100644
index 561ed2ac4..000000000
--- a/src/atlasComponents/parcellationRegion/region.base.ts
+++ /dev/null
@@ -1,158 +0,0 @@
-import { Directive, EventEmitter, Input, Output, Pipe, PipeTransform } from "@angular/core";
-import { select, Store } from "@ngrx/store";
-import { Observable, BehaviorSubject } from "rxjs";
-import { rgbToHsl, hexToRgb } from 'common/util'
-import { strToRgb, verifyPositionArg } from 'common/util'
-import { actions } from "src/state/atlasSelection";
-import { SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "../sapi";
-import { atlasSelection } from "src/state";
-
-@Directive()
-export class RegionBase {
-
-  public rgbString: string
-  public rgbDarkmode: boolean
-
-  private _region: SapiRegionModel
-
-  private _position: number[]
-  set position(val){
-    if (verifyPositionArg(val)) {
-      this._position = val
-    } else {
-      this._position = null
-    }
-  }
-
-  get position(){
-    return this._position
-  }
-
-  public dois: string[] = []
-
-  @Input('region-base-atlas')
-  atlas: SapiAtlasModel
-
-  @Input('region-base-parcellation')
-  parcellation: SapiParcellationModel
-
-  @Input('region-base-template')
-  template: SapiSpaceModel
-
-  @Input('region-base-region')
-  set region(val) {
-    this._region = val
-    this.region$.next(this._region)
-    this.hasContext$.next(false)
-
-    this.position = null
-    // bug the centroid returned is currently nonsense
-    // this.position = val?.props?.centroid_mm
-    if (!val) return
-    const pos = val?.hasAnnotation?.bestViewPoint?.coordinates?.map(v => v.value * 1e6)
-    if (pos) {
-      this.position = pos
-    }
-
-    let rgb = [255, 200, 200]
-    if (val.hasAnnotation?.displayColor) {
-      rgb = hexToRgb(val?.hasAnnotation?.displayColor)
-    } else {
-      rgb = strToRgb(JSON.stringify(val))
-    }
-    this.rgbString = `rgb(${rgb.join(',')})`
-    const [_h, _s, l] = rgbToHsl(...rgb)
-    this.rgbDarkmode = l < 0.4
-
-    this.dois = (val.hasAnnotation?.inspiredBy || [])
-      .map(insp => insp["@id"] as string)
-      .filter(id => /^https?:\/\/doi\.org/.test(id))
-  }
-
-  get region(){
-    return this._region
-  }
-
-
-  public hasContext$: BehaviorSubject<boolean> = new BehaviorSubject(false)
-  public region$: BehaviorSubject<any> = new BehaviorSubject(null)
-
-  @Input()
-  public isSelected: boolean = false
-
-  @Input() public hasConnectivity: boolean
-
-  @Output() public closeRegionMenu: EventEmitter<boolean> = new EventEmitter()
-
-  public selectedAtlas$: Observable<any> = this.store$.pipe(
-    select(atlasSelection.selectors.selectedAtlas)
-  )
-
-
-  constructor(
-    private store$: Store<any>,
-  ) {
-
-  }
-
-  public selectedTemplate$ = this.store$.pipe(
-    select(atlasSelection.selectors.selectedTemplate),
-  )
-
-  public navigateToRegion() {
-    this.closeRegionMenu.emit()
-    const { region } = this
-    this.store$.dispatch(
-      atlasSelection.actions.navigateToRegion({
-        region
-      })
-    )
-  }
-
-  public toggleRegionSelected() {
-    this.closeRegionMenu.emit()
-    const { region } = this
-    this.store$.dispatch(
-      actions.toggleRegionSelect({
-        region
-      })
-    )
-  }
-
-  public showConnectivity(regionName) {
-    this.closeRegionMenu.emit()
-    // ToDo trigger side panel opening with effect
-    // this.store$.dispatch(uiStateOpenSidePanel())
-    // this.store$.dispatch(uiStateExpandSidePanel())
-    // this.store$.dispatch(uiActionShowSidePanelConnectivity())
-
-    // I think we can use viewerMode for this??
-    // this.store$.dispatch(
-    //   viewerStateSetConnectivityRegion({ connectivityRegion: regionName })
-    // )
-  }
-
-  changeView(template: SapiSpaceModel) {
-
-    this.closeRegionMenu.emit()
-    this.store$.dispatch(
-      atlasSelection.actions.viewSelRegionInNewSpace({
-        region: this._region,
-        template,
-      })
-    )
-  }
-}
-
-@Pipe({
-  name: 'renderViewOriginDatasetlabel'
-})
-
-export class RenderViewOriginDatasetLabelPipe implements PipeTransform{
-  public transform(originDatasetlabels: { name: string }[], index: string|number){
-    if (!!originDatasetlabels && !!originDatasetlabels[index] && !!originDatasetlabels[index].name) {
-      return `${originDatasetlabels[index]['name']}`
-    }
-    return `origin dataset`
-  }
-}
diff --git a/src/atlasComponents/parcellationRegion/region.directive.ts b/src/atlasComponents/parcellationRegion/region.directive.ts
deleted file mode 100644
index fb66743eb..000000000
--- a/src/atlasComponents/parcellationRegion/region.directive.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { Directive } from "@angular/core";
-import { RegionBase } from "./region.base";
-import { Store } from "@ngrx/store";
-
-@Directive({
-  selector: '[iav-region]',
-  exportAs: 'iavRegion'
-})
-
-export class RegionDirective extends RegionBase{
-  constructor(store: Store<any>){
-    super(store)
-  }
-}
diff --git a/src/atlasComponents/parcellationRegion/regionAccordionTooltipText.pipe.ts b/src/atlasComponents/parcellationRegion/regionAccordionTooltipText.pipe.ts
deleted file mode 100644
index c2a92b83d..000000000
--- a/src/atlasComponents/parcellationRegion/regionAccordionTooltipText.pipe.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core"
-
-@Pipe({
-  name: 'regionAccordionTooltipTextPipe',
-  pure: true
-})
-
-export class RegionAccordionTooltipTextPipe implements PipeTransform{
-
-  public transform(length: number, type: string): string{
-    switch (type) {
-    case 'regionInOtherTmpl': return `Region available in ${length} other reference space${length > 1 ? 's' : ''}`
-    case 'regionalFeatures': return `${length} regional feature${length > 1 ? 's' : ''} found`
-    case 'connectivity': return `${length} connections found`
-    default: return `${length} items found`
-    }
-  }
-}
diff --git a/src/atlasComponents/parcellationRegion/regionInOtherTmpl.pipe.ts b/src/atlasComponents/parcellationRegion/regionInOtherTmpl.pipe.ts
deleted file mode 100644
index 3a0e81dc8..000000000
--- a/src/atlasComponents/parcellationRegion/regionInOtherTmpl.pipe.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { TSiibraExRegion } from "./type";
-
-@Pipe({
-  name: 'regionInOtherTmpl',
-  pure: true
-})
-
-export class RegionInOtherTmplPipe implements PipeTransform{
-  public transform(region: TSiibraExRegion){
-    const { templateSpaces: allTmpl = [] } = region?.context?.atlas || {}
-    return allTmpl.filter(t => (region?.availableIn || []).find(availTmpl => availTmpl['id'] === t["@id"]))
-  }
-}
diff --git a/src/atlasComponents/parcellationRegion/regionSimple/regionSimple.component.ts b/src/atlasComponents/parcellationRegion/regionSimple/regionSimple.component.ts
deleted file mode 100644
index 76859b9e5..000000000
--- a/src/atlasComponents/parcellationRegion/regionSimple/regionSimple.component.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Component } from '@angular/core'
-
-import { Store } from '@ngrx/store'
-import { IavRootStoreInterface } from 'src/services/stateStore.service'
-import { RegionBase } from '../region.base'
-
-@Component({
-  selector: 'simple-region',
-  templateUrl: './regionSimple.template.html',
-  styleUrls: [
-    './regionSimple.style.css',
-  ],
-})
-
-export class SimpleRegionComponent extends RegionBase {
-  constructor(
-    store$: Store<IavRootStoreInterface>,
-  ) {
-    super(store$)
-  }
-}
diff --git a/src/atlasComponents/parcellationRegion/regionSimple/regionSimple.template.html b/src/atlasComponents/parcellationRegion/regionSimple/regionSimple.template.html
deleted file mode 100644
index b724ab6f2..000000000
--- a/src/atlasComponents/parcellationRegion/regionSimple/regionSimple.template.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<div class="d-flex flex-row">
-
-  <small class="text-truncate flex-shrink-1 flex-grow-1">
-    {{ region.name }}
-  </small>
-
-  <div class="flex-grow-0 flex-shrink-0 d-flex flex-row">
-
-    <!-- if has position defined -->
-    <button *ngIf="position"
-      iav-stop="click"
-      (click)="navigateToRegion()"
-      mat-icon-button>
-      <i class="fas fa-map-marked-alt"></i>
-    </button>
-
-    <!-- region selected  -->
-    <button mat-icon-button
-      [color]="isSelected ? 'primary' : 'basic'">
-      <i class="far"
-        [ngClass]="{'fa-check-square': isSelected, 'fa-square': !isSelected}">
-      </i>
-    </button>
-  </div>
-
-</div>
\ No newline at end of file
diff --git a/src/atlasComponents/parcellationRegion/type.ts b/src/atlasComponents/parcellationRegion/type.ts
deleted file mode 100644
index e5c40a75f..000000000
--- a/src/atlasComponents/parcellationRegion/type.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { IHasId } from "src/util/interfaces";
-import { TRegionSummary } from "src/util/siibraApiConstants/types";
-
-type TAny = {
-  [key: string]: any
-}
-
-export type TSiibraExTemplate = IHasId & TAny
-export type TSiibraExParcelation = IHasId & TAny
-
-export type TSiibraExAtlas = {
-  name: string
-  '@id': string
-  parcellations: TSiibraExParcelation[]
-  templateSpaces: TSiibraExTemplate[]
-}
-
-export type TSiibraExRegion = TRegionSummary & {
-  context: {
-    atlas: TSiibraExAtlas
-    template: TSiibraExTemplate
-    parcellation: TSiibraExParcelation
-  }
-}
diff --git a/src/atlasComponents/sapi/schema.ts b/src/atlasComponents/sapi/schema.ts
index 1b807d7d3..5ba071c50 100644
--- a/src/atlasComponents/sapi/schema.ts
+++ b/src/atlasComponents/sapi/schema.ts
@@ -156,7 +156,7 @@ export interface components {
        * Type
        * @constant
        */
-      type?: "siibra/base-dataset";
+      type?: "siibra/core/dataset";
       metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
       /** Urls */
       urls: components["schemas"]["Url"][];
@@ -199,7 +199,7 @@ export interface components {
        * Type
        * @constant
        */
-      type?: "siibra/connectivity";
+      type?: "siibra/features/connectivity";
       /** Name */
       name: string;
       /** Parcellations */
@@ -216,7 +216,7 @@ export interface components {
        * Type
        * @constant
        */
-      type?: "siibra/base-dataset";
+      type?: "siibra/core/dataset";
       metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
       /** Urls */
       urls: components["schemas"]["Url"][];
@@ -327,6 +327,11 @@ export interface components {
     IEEGSessionModel: {
       /** @Id */
       "@id": string;
+      /**
+       * Type
+       * @constant
+       */
+      type?: "siibra/features/ieegSession";
       dataset: components["schemas"]["DatasetJsonModel"];
       /** Sub Id */
       sub_id: string;
@@ -457,7 +462,7 @@ export interface components {
        * Type
        * @constant
        */
-      type?: "siibra/receptor";
+      type?: "siibra/features/receptor";
       metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
       /** Urls */
       urls: components["schemas"]["Url"][];
@@ -556,6 +561,7 @@ export interface components {
       datasets: components["schemas"]["DatasetJsonModel"][];
       /** Brainatlasversions */
       brainAtlasVersions: components["schemas"]["siibra__openminds__SANDS__v3__atlas__brainAtlasVersion__Model"][];
+      version?: components["schemas"]["SiibraParcellationVersionModel"];
     };
     /** SapiSpaceModel */
     SapiSpaceModel: {
@@ -650,6 +656,15 @@ export interface components {
       /** @Id */
       "@id": string;
     };
+    /** SiibraParcellationVersionModel */
+    SiibraParcellationVersionModel: {
+      /** Name */
+      name: string;
+      /** Deprecated */
+      deprecated?: boolean;
+      prev?: components["schemas"]["SiibraAtIdModel"];
+      next?: components["schemas"]["SiibraAtIdModel"];
+    };
     /** SpeciesModel */
     SpeciesModel: {
       /**
@@ -722,7 +737,7 @@ export interface components {
        * Type
        * @constant
        */
-      type?: "siibra/base-dataset";
+      type?: "siibra/features/voi";
       metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
       /** Urls */
       urls: components["schemas"]["Url"][];
@@ -772,7 +787,7 @@ export interface components {
        * Type
        * @constant
        */
-      type?: "siibra/base-dataset";
+      type?: "siibra/core/dataset";
       metadata: components["schemas"]["siibra__openminds__core__v4__products__datasetVersion__Model"];
       /** Urls */
       urls: components["schemas"]["Url"][];
diff --git a/src/atlasComponents/sapi/type.ts b/src/atlasComponents/sapi/type.ts
index 42a8047ae..8e645b34e 100644
--- a/src/atlasComponents/sapi/type.ts
+++ b/src/atlasComponents/sapi/type.ts
@@ -24,9 +24,24 @@ export type SapiDatasetModel = components["schemas"]["DatasetJsonModel"]
 
 export type SpyNpArrayDataModel = components["schemas"]["NpArrayDataModel"]
 
-export const guards = {
-  isSapiVolumeModel: (val: SapiVolumeModel) => val.type === "siibra/base-dataset"
-    && val.data.detail["neuroglancer/precomputed"]
+
+export function FeatureTypeGuard(input: SapiFeatureModel) {
+  if (input.type === "siibra/core/dataset") {
+    return input as SapiDatasetModel
+  }
+  if (input.type === "siibra/features/connectivity") {
+    return input as SapiParcellationFeatureMatrixModel
+  }
+  if (input.type === "siibra/features/receptor") {
+    return input as SapiRegionalFeatureReceptorModel
+  }
+  if (input.type === "siibra/features/voi") {
+    return input as SapiVOIDataResponse
+  }
+  if (input.type === "spy/serialization-error") {
+    return input as SapiSerializationErrorModel
+  }
+  throw new Error(`cannot parse type: ${input}`)
 }
 
 /**
diff --git a/src/atlasComponents/sapiViews/core/atlas/dropdownAtlasSelector/dropdownAtlasSelector.component.ts b/src/atlasComponents/sapiViews/core/atlas/dropdownAtlasSelector/dropdownAtlasSelector.component.ts
index ec13b3064..0da41ae9d 100644
--- a/src/atlasComponents/sapiViews/core/atlas/dropdownAtlasSelector/dropdownAtlasSelector.component.ts
+++ b/src/atlasComponents/sapiViews/core/atlas/dropdownAtlasSelector/dropdownAtlasSelector.component.ts
@@ -26,7 +26,6 @@ export class SapiViewsCoreAtlasAtlasDropdownSelector{
     private store$: Store<any>,
     private sapi: SAPI,
   ){
-    this.selectedAtlas$.subscribe(val => console.log('sel atlas changed', val))
   }
 
   handleChangeAtlas({ value }) {
diff --git a/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.style.css b/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.style.css
index 0d8c1e199..49568298b 100644
--- a/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.style.css
+++ b/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.style.css
@@ -13,7 +13,7 @@
 
 .loading-overlay
 {
-    position: absolute;
+    position: fixed;
     width: 100%;
     height: 100%;
     top: 0;
@@ -32,3 +32,10 @@
     grid-column: 2;
     grid-row: 2;
 }
+
+/* necessary to align the tiles to the start of grid tile */
+sxplr-sapiviews-core-space-tile,
+sxplr-sapiviews-core-parcellation-tile
+{
+    height: 100%;
+}
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.template.html b/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.template.html
index f98de1d0b..944f2bc95 100644
--- a/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.template.html
+++ b/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.template.html
@@ -5,61 +5,68 @@
   [@toggleAtlasLayerSelector]="selectorExpanded"
   (@toggleAtlasLayerSelector.done)="atlasSelectorTour?.attachTo(selectorExpanded ? selectorPanelTemplateRef : null)"
   #selectorPanelTmpl>
+
   <mat-card-content>
 
-  <!-- templates -->
-  <mat-card-subtitle>
-    {{ CONST.ATLAS_SELECTOR_LABEL_SPACES }}
-  </mat-card-subtitle>
-
-  <!-- template grid and tiles -->
-  <mat-grid-list cols="3"
-    rowHeight="2:3"
-    gutterSize="16">
-
-    <mat-grid-tile *ngFor="let template of availableTemplates$ | async; trackBy: trackbyAtId"
-      [attr.aria-checked]="(selectedTemplate$ | async)?.['@id']  === template['@id']">
-      <sxplr-sapiviews-core-space-tile
-        [sxplr-sapiviews-core-space-tile-space]="template"
-        [sxplr-sapiviews-core-space-tile-selected]="(selectedTemplate$ | async)?.['@id'] === template['@id']"
-        (click)="selectTemplate(template)">
-      </sxplr-sapiviews-core-space-tile>
-    </mat-grid-tile>
-  </mat-grid-list>
-
-  <mat-divider></mat-divider>
-
-  <!-- parcellations -->
-  <mat-card-subtitle class="mt-2">
-    {{ CONST.ATLAS_SELECTOR_LABEL_PARC_MAPS }}
-  </mat-card-subtitle>
-
-  <mat-grid-list cols="3"
+    <!-- templates -->
+    <mat-card-subtitle>
+      {{ CONST.ATLAS_SELECTOR_LABEL_SPACES }}
+    </mat-card-subtitle>
+
+    <!-- template grid and tiles -->
+    <mat-grid-list cols="3"
       rowHeight="2:3"
       gutterSize="16">
 
-      <mat-grid-tile *ngFor="let parc of availableParcellations$ | async | filterUnsupportedParc | filterGroupedParcs">
-        <sxplr-sapiviews-core-parcellation-tile
-          [sxplr-sapiviews-core-parcellation-tile-parcellation]="parc"
-          (sxplr-sapiviews-core-parcellation-tile-onclick-parc)="selectParcellation($event)">
-
-        </sxplr-sapiviews-core-parcellation-tile>
+      <mat-grid-tile *ngFor="let template of availableTemplates$ | async; trackBy: trackbyAtId"
+        [attr.aria-checked]="(selectedTemplate$ | async)?.['@id']  === template['@id']">
+        
+        <sxplr-sapiviews-core-space-tile
+          [sxplr-sapiviews-core-space-tile-space]="template"
+          [sxplr-sapiviews-core-space-tile-selected]="(selectedTemplate$ | async)?.['@id'] === template['@id']"
+          (click)="selectTemplate(template)">
+        </sxplr-sapiviews-core-space-tile>
       </mat-grid-tile>
+    </mat-grid-list>
 
-      <mat-grid-tile *ngFor="let group of availableParcellations$ | async | filterUnsupportedParc | filterGroupedParcs : true | filterUnsupportedParc">
-        <sxplr-sapiviews-core-parcellation-tile
-          [sxplr-sapiviews-core-parcellation-tile-parcellation]="group"
-          (sxplr-sapiviews-core-parcellation-tile-onclick-parc)="selectParcellation($event)">
+    <mat-divider></mat-divider>
 
-        </sxplr-sapiviews-core-parcellation-tile>
-      </mat-grid-tile>
-  </mat-grid-list>
-</mat-card-content>
+    <!-- parcellations -->
+    <mat-card-subtitle class="mt-2">
+      {{ CONST.ATLAS_SELECTOR_LABEL_PARC_MAPS }}
+    </mat-card-subtitle>
+
+    <mat-grid-list cols="3"
+        rowHeight="2:3"
+        gutterSize="16">
+
+        <mat-grid-tile *ngFor="let parc of availableParcellations$ | async | filterUnsupportedParc | filterGroupedParcs">
+          <sxplr-sapiviews-core-parcellation-tile
+            [sxplr-sapiviews-core-parcellation-tile-parcellation]="parc"
+            (sxplr-sapiviews-core-parcellation-tile-onclick-parc)="selectParcellation($event)">
+
+          </sxplr-sapiviews-core-parcellation-tile>
+        </mat-grid-tile>
+
+        <mat-grid-tile *ngFor="let group of availableParcellations$ | async | filterUnsupportedParc | filterGroupedParcs : true | filterUnsupportedParc">
+          <sxplr-sapiviews-core-parcellation-tile
+            [sxplr-sapiviews-core-parcellation-tile-parcellation]="group"
+            (sxplr-sapiviews-core-parcellation-tile-onclick-parc)="selectParcellation($event)">
+
+          </sxplr-sapiviews-core-parcellation-tile>
+        </mat-grid-tile>
+    </mat-grid-list>
+
+  </mat-card-content>
+
+  <div [ngClass]="{
+    'sxplr-d-none': !(showLoadingOverlay$ | async)
+  }"
+    class="loading-overlay">
+    <spinner-cmp class="spinner"></spinner-cmp>
+  </div>
+  
 
-<div [hidden]="!(showLoadingOverlay$ | async)"
-  class="loading-overlay">
-  <spinner-cmp class="spinner"></spinner-cmp>
-</div>
 </mat-card>
 
 <!-- place holder when not expanded -->
diff --git a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.stories.ts b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.stories.ts
index 0a288e0f9..ff2a04062 100644
--- a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.stories.ts
+++ b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.stories.ts
@@ -36,7 +36,7 @@ const Template: Story<DatasetView> = (args: DatasetView, { loaded }) => {
 
 const loadFeat = async () => {
   const features = await getHoc1Features()
-  const receptorfeat = features.find(f => f.type === "siibra/receptor")
+  const receptorfeat = features.find(f => f.type === "siibra/core/dataset")
   const feature = await getHoc1FeatureDetail(receptorfeat["@id"])
   return {
     feature
diff --git a/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.component.ts b/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.component.ts
new file mode 100644
index 000000000..13358ff46
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.component.ts
@@ -0,0 +1,26 @@
+import { Component, Input, Output, EventEmitter } from "@angular/core";
+import { SapiParcellationModel } from "src/atlasComponents/sapi/type";
+
+@Component({
+  selector: `sxplr-sapiviews-core-parcellation-chip`,
+  templateUrl: './parcellation.chip.template.html',
+  styleUrls: [
+    `./parcellation.chip.style.css`
+  ],
+})
+
+export class SapiViewsCoreParcellationParcellationChip {
+
+  @Input('sxplr-sapiviews-core-parcellation-chip-parcellation')
+  parcellation: SapiParcellationModel
+
+  @Input('sxplr-sapiviews-core-parcellation-chip-color')
+  color: 'default' | 'primary' | 'accent' | 'warn' = "default"
+
+  @Output('sxplr-sapiviews-core-parcellation-chip-onclick')
+  onClick = new EventEmitter<MouseEvent>()
+
+  click(event: MouseEvent) {
+    this.onClick.emit(event)
+  }
+}
diff --git a/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.stories.ts b/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.stories.ts
new file mode 100644
index 000000000..3210779ec
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.stories.ts
@@ -0,0 +1,118 @@
+import { CommonModule } from "@angular/common"
+import { HttpClientModule } from "@angular/common/http"
+import { Meta, moduleMetadata, Story } from "@storybook/angular"
+import { SAPI, SapiParcellationModel } from "src/atlasComponents/sapi"
+import { atlasId, getAtlas, provideDarkTheme, getParc } from "src/atlasComponents/sapi/stories.base"
+import { AngularMaterialModule } from "src/sharedModules"
+import { SapiViewsCoreParcellationModule } from "../module"
+import { SapiViewsCoreParcellationParcellationChip } from "./parcellation.chip.component"
+
+
+export default {
+  component: SapiViewsCoreParcellationParcellationChip,
+  decorators: [
+    moduleMetadata({
+      imports: [
+        CommonModule,
+        HttpClientModule,
+        SapiViewsCoreParcellationModule,
+        AngularMaterialModule,
+      ],
+      providers: [
+        SAPI,
+        ...provideDarkTheme,
+      ],
+      declarations: []
+    })
+  ],
+} as Meta
+
+const Template: Story<SapiViewsCoreParcellationParcellationChip> = (args: SapiViewsCoreParcellationParcellationChip, { loaded, parameters }) => {
+  const { 
+    parcellation
+  } = loaded
+  const {
+    contentProjection
+  } = parameters
+
+  return ({
+    props: {
+      ...args,
+      parcellation
+    },
+    template: `
+    <sxplr-sapiviews-core-parcellation-chip>
+      ${contentProjection || ''}
+    </sxplr-sapiviews-core-parcellation-chip>
+    `
+  })
+}
+Template.loaders = []
+
+const asyncLoader = async (_atlasId: string) => {
+  const parcs: SapiParcellationModel[] = []
+  const atlasDetail = await getAtlas(_atlasId)
+  
+  for (const parc of atlasDetail.parcellations) {
+    const parcDetail = await getParc(atlasDetail['@id'], parc['@id'])
+    parcs.push(parcDetail)
+  }
+  return {
+    parcs
+  }
+}
+
+const getContentProjection = ({ prefix = null, suffix = null }) => {
+  let returnVal = ``
+  if (prefix) {
+    returnVal += `<div prefix>${prefix}</div>`
+  }
+  if (suffix) {
+    returnVal += `<div suffix>${suffix}</div>`
+  }
+  return returnVal
+}
+
+export const Default = Template.bind({})
+Default.loaders = [
+  async () => {
+    const {
+      parcs
+    } = await asyncLoader(atlasId.human)
+    return {
+      parcellation: parcs[0]
+    }
+  }
+]
+
+export const Prefix = Template.bind({})
+Prefix.loaders = [
+  ...Default.loaders
+]
+Prefix.parameters = {
+  contentProjection: getContentProjection({
+    prefix: `PREFIX`,
+  })
+}
+
+export const Suffix = Template.bind({})
+Suffix.loaders = [
+  ...Default.loaders
+]
+Suffix.parameters = {
+  contentProjection: getContentProjection({
+    suffix: `SUFFIX`,
+  })
+}
+
+
+export const PrefixSuffix = Template.bind({})
+PrefixSuffix.loaders = [
+  ...Default.loaders
+]
+PrefixSuffix.parameters = {
+  contentProjection: getContentProjection({
+    prefix: `PREFIX`,
+    suffix: `SUFFIX`,
+  })
+}
diff --git a/src/atlasComponents/parcellationRegion/regionSimple/regionSimple.style.css b/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.style.css
similarity index 100%
rename from src/atlasComponents/parcellationRegion/regionSimple/regionSimple.style.css
rename to src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.style.css
diff --git a/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.template.html b/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.template.html
new file mode 100644
index 000000000..417575bf6
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/parcellation/chip/parcellation.chip.template.html
@@ -0,0 +1,16 @@
+<mat-chip-list *ngIf="parcellation">
+  <mat-chip [selected]="color !== 'default'"
+    (click)="click($event)"
+    [color]="color">
+
+    <ng-content select="[prefix]">
+    </ng-content>
+
+    <span class="mat-body sxplr-white-space-nowrap">
+      {{ parcellation.name }}
+    </span>
+
+    <ng-content select="[suffix]">
+    </ng-content>
+  </mat-chip>
+</mat-chip-list>
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/core/parcellation/filterUnsupportedParc.pipe.ts b/src/atlasComponents/sapiViews/core/parcellation/filterUnsupportedParc.pipe.ts
index 188a83b0a..5d2412cdd 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/filterUnsupportedParc.pipe.ts
+++ b/src/atlasComponents/sapiViews/core/parcellation/filterUnsupportedParc.pipe.ts
@@ -20,7 +20,7 @@ const hideGroup = [
 
 export class FilterUnsupportedParcPipe implements PipeTransform{
   public transform<T extends Filterables>(parcs: T[]): T[] {
-    return parcs.filter(p => {
+    return (parcs || []).filter(p => {
       if (p instanceof GroupedParcellation) {
         return hideGroup.indexOf(p.name) < 0
       }
diff --git a/src/atlasComponents/sapiViews/core/parcellation/module.ts b/src/atlasComponents/sapiViews/core/parcellation/module.ts
index 2ef93bef5..fca236799 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/module.ts
+++ b/src/atlasComponents/sapiViews/core/parcellation/module.ts
@@ -1,10 +1,17 @@
 import { CommonModule } from "@angular/common";
-import { NgModule } from "@angular/core";
+import { APP_INITIALIZER, NgModule } from "@angular/core";
+import { Store } from "@ngrx/store";
 import { ComponentsModule } from "src/components";
 import { AngularMaterialModule } from "src/sharedModules";
+import { atlasAppearance } from "src/state";
+import { UtilModule } from "src/util";
+import { SapiViewsCoreParcellationParcellationChip } from "./chip/parcellation.chip.component";
 import { FilterGroupedParcellationPipe } from "./filterGroupedParcellations.pipe";
 import { FilterUnsupportedParcPipe } from "./filterUnsupportedParc.pipe";
+import { ParcellationIsBaseLayer } from "./parcellationIsBaseLayer.pipe";
+import { ParcellationVisibilityService } from "./parcellationVis.service";
 import { PreviewParcellationUrlPipe } from "./previewParcellationUrl.pipe";
+import { SapiViewsCoreParcellationParcellationSmartChip } from "./smartChip/parcellation.smartChip.component";
 import { SapiViewsCoreParcellationParcellationTile } from "./tile/parcellation.tile.component";
 
 @NgModule({
@@ -12,17 +19,41 @@ import { SapiViewsCoreParcellationParcellationTile } from "./tile/parcellation.t
     CommonModule,
     ComponentsModule,
     AngularMaterialModule,
+    UtilModule,
   ],
   declarations: [
     SapiViewsCoreParcellationParcellationTile,
+    SapiViewsCoreParcellationParcellationChip,
+    SapiViewsCoreParcellationParcellationSmartChip,
     PreviewParcellationUrlPipe,
     FilterGroupedParcellationPipe,
     FilterUnsupportedParcPipe,
+    ParcellationIsBaseLayer,
   ],
   exports: [
     SapiViewsCoreParcellationParcellationTile,
+    SapiViewsCoreParcellationParcellationChip,
+    SapiViewsCoreParcellationParcellationSmartChip,
     FilterGroupedParcellationPipe,
     FilterUnsupportedParcPipe,
+  ],
+  providers: [
+    ParcellationVisibilityService,
+    {
+      provide: APP_INITIALIZER,
+      useFactory: (store: Store, svc: ParcellationVisibilityService) => {
+        svc.visibility$.subscribe(val => {
+          store.dispatch(
+            atlasAppearance.actions.setShowDelineation({
+              flag: val
+            })
+          )
+        })
+        return () => Promise.resolve()
+      },
+      multi: true,
+      deps: [ Store, ParcellationVisibilityService ]
+    }
   ]
 })
 
diff --git a/src/atlasComponents/sapiViews/core/parcellation/parcellationIsBaseLayer.pipe.ts b/src/atlasComponents/sapiViews/core/parcellation/parcellationIsBaseLayer.pipe.ts
new file mode 100644
index 000000000..7bd6f31f1
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/parcellation/parcellationIsBaseLayer.pipe.ts
@@ -0,0 +1,22 @@
+import { Pipe, PipeTransform } from "@angular/core";
+import { SapiParcellationModel } from "src/atlasComponents/sapi/type";
+
+const baseLayerIds = [
+  "minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-290",
+  "minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-25",
+  "minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579",
+]
+
+@Pipe({
+  name: 'parcellationIsBaseLayer',
+  pure: true
+})
+
+export class ParcellationIsBaseLayer implements PipeTransform{
+  public transform(parc: SapiParcellationModel): boolean {
+    /**
+     * currently, the only base layer is cyto maps
+     */
+    return baseLayerIds.includes(parc["@id"])
+  }
+}
diff --git a/src/atlasComponents/sapiViews/core/parcellation/parcellationVis.service.ts b/src/atlasComponents/sapiViews/core/parcellation/parcellationVis.service.ts
new file mode 100644
index 000000000..3eb329a9b
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/parcellation/parcellationVis.service.ts
@@ -0,0 +1,21 @@
+import { Injectable } from "@angular/core";
+import { BehaviorSubject } from "rxjs";
+
+@Injectable({
+  providedIn: 'root'
+})
+
+export class ParcellationVisibilityService {
+  private _visibility$ = new BehaviorSubject<boolean>(true)
+  public readonly visibility$ = this._visibility$.asObservable()
+
+  setVisibility(flag: boolean) {
+    this._visibility$.next(flag)
+  }
+
+  toggleVisibility(){
+    this.setVisibility(
+      !this._visibility$.getValue()
+    )
+  }
+}
diff --git a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts
new file mode 100644
index 000000000..e28c7bec0
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts
@@ -0,0 +1,99 @@
+import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from "@angular/core";
+import { Observable } from "rxjs";
+import { SapiParcellationModel } from "src/atlasComponents/sapi/type";
+import { ParcellationVisibilityService } from "../parcellationVis.service";
+
+@Component({
+  selector: `sxplr-sapiviews-core-parcellation-smartchip`,
+  templateUrl: `./parcellation.smartChip.template.html`,
+  styleUrls: [
+    `./parcellation.smartChip.style.css`
+  ]
+})
+
+export class SapiViewsCoreParcellationParcellationSmartChip implements OnChanges{
+
+  @Input('sxplr-sapiviews-core-parcellation-smartchip-parcellation')
+  parcellation: SapiParcellationModel
+
+  @Input('sxplr-sapiviews-core-parcellation-smartchip-all-parcellations')
+  parcellations: SapiParcellationModel[]
+
+  @Output('sxplr-sapiviews-core-parcellation-smartchip-dismiss-nonbase-layer')
+  onDismiss = new EventEmitter<SapiParcellationModel>()
+
+  @Output('sxplr-sapiviews-core-parcellation-smartchip-select-parcellation')
+  onSelectParcellation = new EventEmitter<SapiParcellationModel>()
+
+  constructor(
+    private svc: ParcellationVisibilityService
+  ){
+
+  }
+
+  otherVersions: SapiParcellationModel[]
+
+  ngOnChanges() {
+    this.otherVersions = []
+    if (!this.parcellation) {
+      return
+    }
+    this.otherVersions = [ this.parcellation ]
+    if (!this.parcellations || this.parcellations.length === 0) {
+      return 
+    }
+    if (!this.parcellation.version) {
+      return 
+    }
+
+    this.otherVersions = []
+    const getTraverse = (key: 'prev' | 'next') => (parc: SapiParcellationModel) => {
+      if (!parc.version) {
+        throw new Error(`parcellation ${parc.name} does not have version defined!`)
+      }
+      if (!parc.version[key]) {
+        return null
+      }
+      const found = this.parcellations.find(p => p["@id"] === parc.version[key]["@id"])
+      if (!found) {
+        throw new Error(`parcellation ${parc.name} references ${parc.version[key]['@id']} as ${key} version, but it cannot be found.`)
+      }
+      return found
+    }
+
+    const findNewer = getTraverse('next')
+    const findOlder = getTraverse('prev')
+
+    const newest = (() => {
+      let cursor = this.parcellation
+      let newest: SapiParcellationModel
+      while (cursor) {
+        newest = cursor
+        cursor = findNewer(cursor)
+      }
+      return newest
+    })()
+
+    let cursor: SapiParcellationModel = newest
+    while (cursor) {
+      this.otherVersions.push(cursor)
+      cursor = findOlder(cursor)
+    }
+  }
+
+  parcellationVisibility$: Observable<boolean> = this.svc.visibility$
+
+  toggleParcellationVisibility(){
+    this.svc.toggleVisibility()
+  }
+
+  dismiss(){
+    this.onDismiss.emit(this.parcellation)
+  }
+
+  selectParcellation(parc: SapiParcellationModel){
+    if (parc === this.parcellation) return
+
+    console.log('select parcellation', parc)
+  }
+}
diff --git a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.stories.ts b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.stories.ts
new file mode 100644
index 000000000..7f3338a6a
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.stories.ts
@@ -0,0 +1,108 @@
+import { CommonModule } from "@angular/common"
+import { HttpClientModule } from "@angular/common/http"
+import { Component, EventEmitter, Input, Output } from "@angular/core"
+import { Meta, moduleMetadata, Story } from "@storybook/angular"
+import { action } from "@storybook/addon-actions"
+import { SAPI, SapiParcellationModel } from "src/atlasComponents/sapi"
+import { atlasId, getAtlas, provideDarkTheme, getParc, getAtlases } from "src/atlasComponents/sapi/stories.base"
+import { AngularMaterialModule } from "src/sharedModules"
+import { SapiViewsCoreParcellationModule } from "../module"
+
+@Component({
+  selector: `parc-smart-chip-wrapper`,
+  template: `
+  <mat-accordion>
+    <mat-expansion-panel *ngFor="let item of parcRecords | keyvalue">
+      <mat-expansion-panel-header>
+        {{ item.key }}
+      </mat-expansion-panel-header>
+
+      <div class="sxplr-of-x-scroll sxplr-white-space-nowrap">
+        <sxplr-sapiviews-core-parcellation-smartchip *ngFor="let parc of item.value | filterUnsupportedParc"
+          [sxplr-sapiviews-core-parcellation-smartchip-parcellation]="parc"
+          [sxplr-sapiviews-core-parcellation-smartchip-all-parcellations]="item.value"
+          (sxplr-sapiviews-core-parcellation-smartchip-select-parcellation)="selectParcellation($event)">
+        </sxplr-sapiviews-core-parcellation-smartchip>
+      </div>
+
+    </mat-expansion-panel>
+  </mat-accordion>
+  `,
+  styles: [
+    `sxplr-sapiviews-core-parcellation-chip { display: block;  }`
+  ]
+})
+
+class ParcSmartChipWrapper{
+  @Input()
+  parcRecords: Record<string, SapiParcellationModel[]> = {}
+
+  selectParcellation(parc: SapiParcellationModel){
+
+  }
+}
+
+
+export default {
+  component: ParcSmartChipWrapper,
+  decorators: [
+    moduleMetadata({
+      imports: [
+        CommonModule,
+        HttpClientModule,
+        SapiViewsCoreParcellationModule,
+        AngularMaterialModule,
+      ],
+      providers: [
+        SAPI,
+        ...provideDarkTheme,
+      ],
+      declarations: []
+    })
+  ],
+} as Meta
+
+const Template: Story<ParcSmartChipWrapper> = (args: ParcSmartChipWrapper, { loaded, parameters }) => {
+  const { 
+    parcRecords
+  } = loaded
+
+  return ({
+    props: {
+      ...args,
+      selectParcellation: action("selectParcellation"),
+      parcRecords
+    },
+  })
+}
+Template.loaders = []
+
+const asyncLoader = async () => {
+  const parcRecords: Record<string, SapiParcellationModel[]> = {}
+
+  for (const species in atlasId) {
+
+    const atlasDetail = await getAtlas(atlasId[species])
+    parcRecords[species] = []
+    for (const parc of atlasDetail.parcellations) {
+      const parcDetail = await getParc(atlasDetail['@id'], parc['@id'])
+      parcRecords[species].push(parcDetail)
+    }
+  }
+  
+  return {
+    parcRecords
+  }
+}
+
+export const Default = Template.bind({})
+Default.loaders = [
+  async () => {
+    const {
+      parcRecords
+    } = await asyncLoader()
+    return {
+      parcRecords
+    }
+  }
+]
diff --git a/src/services/state/uiState.store.spec.ts b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.style.css
similarity index 100%
rename from src/services/state/uiState.store.spec.ts
rename to src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.style.css
diff --git a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
new file mode 100644
index 000000000..0473218f9
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
@@ -0,0 +1,49 @@
+<mat-menu #otherParcMenu="matMenu"
+  [hasBackdrop]="false"
+  class="sxplr-bg-none sxplr-of-x-hidden sxplr-box-shadow-none overwrite-max-width-80vw">
+  <div (iav-outsideClick)="menuTrigger.closeMenu()">
+
+    <sxplr-sapiviews-core-parcellation-chip *ngFor="let parc of otherVersions"
+      [sxplr-sapiviews-core-parcellation-chip-parcellation]="parc"
+      [sxplr-sapiviews-core-parcellation-chip-color]="parcellation === parc ? 'primary' : 'default'"
+      (click)="selectParcellation(parc)">
+
+    </sxplr-sapiviews-core-parcellation-chip>
+  </div>
+  
+</mat-menu>
+
+<sxplr-sapiviews-core-parcellation-chip
+  [ngClass]="{
+    'sxplr-muted': !(parcellationVisibility$ | async)
+  }"
+  class="sxplr-d-inline-block"
+  [sxplr-sapiviews-core-parcellation-chip-parcellation]="parcellation"
+  [sxplr-sapiviews-core-parcellation-chip-color]="(parcellation | parcellationIsBaseLayer) ? 'default' : 'primary'"
+  (sxplr-sapiviews-core-parcellation-chip-onclick)="menuTrigger.toggleMenu()"
+  [matMenuTriggerFor]="otherParcMenu"
+  #menuTrigger="matMenuTrigger"
+  >
+
+  <div prefix class="sxplr-scale-70">
+    <button mat-mini-fab
+      [color]="(parcellationVisibility$ | async) ? 'primary' : 'default'"
+      iav-stop="mousedown click"
+      (click)="toggleParcellationVisibility()">
+      <i class="fas"
+        [ngClass]="(parcellationVisibility$ | async) ? 'fa-eye': 'fa-eye-slash'">
+      </i>
+    </button>
+  </div>
+
+  <div *ngIf="!(parcellation | parcellationIsBaseLayer)"
+    class="sxplr-scale-70"
+    suffix>
+    <button mat-mini-fab
+      color="primary"
+      iav-stop="mousedown click"
+      (click)="dismiss()">
+      <i class="fas fa-times"></i>
+    </button>
+  </div>
+</sxplr-sapiviews-core-parcellation-chip>
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/core/parcellation/tile/parcellation.tile.template.html b/src/atlasComponents/sapiViews/core/parcellation/tile/parcellation.tile.template.html
index 774814d73..10a48ac5e 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/tile/parcellation.tile.template.html
+++ b/src/atlasComponents/sapiViews/core/parcellation/tile/parcellation.tile.template.html
@@ -11,6 +11,7 @@
           *ngFor="let parc of subParcellations">
 
           <tile-cmp *ngIf="parc"
+            class="iv-custom-comp text"
             [tile-text]="parc.name"
             [tile-image-src]="parc | previewParcellationUrl"
             [tile-selected]="selected"
diff --git a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts
index 60eb0e497..1d44db4e8 100644
--- a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts
+++ b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts
@@ -37,11 +37,11 @@ export class SapiViewsCoreRegionRegionRich extends SapiViewsCoreRegionRegionBase
   }
 
   handleExpansionPanelClosedEv(title: string){
-    console.log("title", title)
+    
   }
 
   handleExpansionPanelAfterExpandEv(title: string) {
-    console.log("title", title)
+    
   }
 
   activePanelTitles$: Observable<string[]> = new Subject()
diff --git a/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.component.ts b/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.component.ts
index a7c5f4a84..d7fcb6758 100644
--- a/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.component.ts
+++ b/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.component.ts
@@ -1,6 +1,6 @@
 import { Component, Input } from "@angular/core";
 import { SapiFeatureModel, SapiRegionalFeatureModel, SapiSpatialFeatureModel, SapiParcellationFeatureModel } from "src/atlasComponents/sapi";
-import { SapiParcellationFeatureMatrixModel } from "src/atlasComponents/sapi/type";
+import { SapiDatasetModel, SapiParcellationFeatureMatrixModel, SapiRegionalFeatureReceptorModel, SapiSerializationErrorModel, SapiVOIDataResponse } from "src/atlasComponents/sapi/type";
 
 @Component({
   selector: `sxplr-sapiviews-features-entry-list-item`,
@@ -19,11 +19,21 @@ export class SapiViewsFeaturesEntryListItem{
 
   get label(): string{
     if (!this.feature) return null
-    if (this.feature.type === "siibra/base-dataset" || this.feature.type === "siibra/receptor") {
-      return (this.feature as (SapiRegionalFeatureModel | SapiSpatialFeatureModel)).metadata.fullName
+    const { type } = this.feature
+    if (
+      type === "siibra/core/dataset" ||
+      type === "siibra/features/receptor" ||
+      type === "siibra/features/voi"
+    ) {
+      return (this.feature as (SapiDatasetModel | SapiRegionalFeatureReceptorModel | SapiVOIDataResponse) ).metadata.fullName
     }
-    return (this.feature as SapiParcellationFeatureMatrixModel).name
-  }
-  constructor(){
+
+    if (type === "siibra/features/connectivity") {
+      return (this.feature as SapiParcellationFeatureMatrixModel).name
+    }
+    if (type === "spy/serialization-error") {
+      return (this.feature as SapiSerializationErrorModel).message
+    }
+    return "Unknown type"
   }
 }
diff --git a/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.template.html b/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.template.html
index b6cfc81d0..5bbc24ee2 100644
--- a/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.template.html
+++ b/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.template.html
@@ -1,8 +1,8 @@
 <div matRipple [matRippleDisabled]="!ripple"
   class="sxplr-p-2">
 
-  <mat-chip-list [ngSwitch]="feature.type" class="scale-80 transform-origin-left-center">
-    <mat-chip *ngSwitchCase="'siibra/receptor'"
+  <mat-chip-list [ngSwitch]="feature.type" class="sxplr-scale-80 transform-origin-left-center">
+    <mat-chip *ngSwitchCase="'siibra/features/receptor'"
       [color]="feature | featureBadgeColour"
       selected>
       {{ feature | featureBadgeName }}
diff --git a/src/atlasComponents/sapiViews/features/featureBadgeColor.pipe.ts b/src/atlasComponents/sapiViews/features/featureBadgeColor.pipe.ts
index 9d8be8736..d3caf6b13 100644
--- a/src/atlasComponents/sapiViews/features/featureBadgeColor.pipe.ts
+++ b/src/atlasComponents/sapiViews/features/featureBadgeColor.pipe.ts
@@ -8,7 +8,7 @@ import { SapiFeatureModel } from "src/atlasComponents/sapi";
 
 export class FeatureBadgeColourPipe implements PipeTransform{
   public transform(regionalFeature: SapiFeatureModel) {
-      if (regionalFeature.type === "siibra/receptor") {
+      if (regionalFeature.type === "siibra/features/receptor") {
         return "accent"
       }
       return "default"
diff --git a/src/atlasComponents/sapiViews/features/featureBadgeName.pipe.ts b/src/atlasComponents/sapiViews/features/featureBadgeName.pipe.ts
index 3b0faa80c..34e4f7dc6 100644
--- a/src/atlasComponents/sapiViews/features/featureBadgeName.pipe.ts
+++ b/src/atlasComponents/sapiViews/features/featureBadgeName.pipe.ts
@@ -8,7 +8,7 @@ import { SapiFeatureModel } from "src/atlasComponents/sapi";
 
 export class FeatureBadgeNamePipe implements PipeTransform{
   public transform(regionalFeature: SapiFeatureModel) {
-      if (regionalFeature.type === "siibra/receptor") {
+      if (regionalFeature.type === "siibra/features/receptor") {
         return "receptor density"
       }
       return null
diff --git a/src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiograph.stories.ts b/src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiograph.stories.ts
index 281d26289..5ebfdce98 100644
--- a/src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiograph.stories.ts
+++ b/src/atlasComponents/sapiViews/features/receptors/autoradiography/autoradiograph.stories.ts
@@ -109,7 +109,7 @@ const loadFeat = async () => {
   const region = await getHoc1Left()
   const space = await getMni152()
   const features = await getHoc1Features()
-  const receptorfeat = features.find(f => f.type === "siibra/receptor")
+  const receptorfeat = features.find(f => f.type === "siibra/features/receptor")
   const feature = await getHoc1FeatureDetail(receptorfeat["@id"])
   return {
     atlas,
diff --git a/src/atlasComponents/sapiViews/features/receptors/base.ts b/src/atlasComponents/sapiViews/features/receptors/base.ts
index bfb7b9413..b393969c2 100644
--- a/src/atlasComponents/sapiViews/features/receptors/base.ts
+++ b/src/atlasComponents/sapiViews/features/receptors/base.ts
@@ -75,8 +75,8 @@ export abstract class BaseReceptor{
       return
     }
     const result = await this.sapi.getRegion(this.atlas["@id"], this.parcellation["@id"], this.region.name).getFeatureInstance(this.featureId, this.template["@id"])
-    if (result.type !== "siibra/receptor") {
-      throw new Error(`BaseReceptor Error. Expected .type to be "siibra/receptor", but was "${result.type}"`)
+    if (result.type !== "siibra/features/receptor") {
+      throw new Error(`BaseReceptor Error. Expected .type to be "siibra/features/receptor", but was "${result.type}"`)
     }
     return result
   }
diff --git a/src/atlasComponents/sapiViews/features/receptors/entry/entry.stories.ts b/src/atlasComponents/sapiViews/features/receptors/entry/entry.stories.ts
index 3adb01e1d..0c69f8216 100644
--- a/src/atlasComponents/sapiViews/features/receptors/entry/entry.stories.ts
+++ b/src/atlasComponents/sapiViews/features/receptors/entry/entry.stories.ts
@@ -92,7 +92,7 @@ const loadFeat = async () => {
   const region = await getHoc1Left()
   const space = await getMni152()
   const features = await getHoc1Features()
-  const receptorfeat = features.find(f => f.type === "siibra/receptor")
+  const receptorfeat = features.find(f => f.type === "siibra/features/receptor")
   const feature = await getHoc1FeatureDetail(receptorfeat["@id"])
   return {
     atlas,
diff --git a/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.stories.ts b/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.stories.ts
index ae8a161cf..7c5da4f82 100644
--- a/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.stories.ts
+++ b/src/atlasComponents/sapiViews/features/receptors/fingerprint/fingerprint.stories.ts
@@ -91,7 +91,7 @@ const loadFeat = async () => {
   const region = await getHoc1Left()
   const space = await getMni152()
   const features = await getHoc1Features()
-  const receptorfeat = features.find(f => f.type === "siibra/receptor")
+  const receptorfeat = features.find(f => f.type === "siibra/features/receptor")
   const feature = await getHoc1FeatureDetail(receptorfeat["@id"])
   return {
     atlas,
diff --git a/src/atlasComponents/sapiViews/features/receptors/profile/profile.stories.ts b/src/atlasComponents/sapiViews/features/receptors/profile/profile.stories.ts
index 39b199ef3..f4dc8b4bd 100644
--- a/src/atlasComponents/sapiViews/features/receptors/profile/profile.stories.ts
+++ b/src/atlasComponents/sapiViews/features/receptors/profile/profile.stories.ts
@@ -118,7 +118,7 @@ const loadFeat = async () => {
   const region = await getHoc1Left()
   const space = await getMni152()
   const features = await getHoc1Features()
-  const receptorfeat = features.find(f => f.type === "siibra/receptor")
+  const receptorfeat = features.find(f => f.type === "siibra/features/receptor")
   const feature = await getHoc1FeatureDetail(receptorfeat["@id"])
   return {
     atlas,
diff --git a/src/atlasViewer/atlasViewer.apiService.service.ts b/src/atlasViewer/atlasViewer.apiService.service.ts
index f4529026d..eae9a9c68 100644
--- a/src/atlasViewer/atlasViewer.apiService.service.ts
+++ b/src/atlasViewer/atlasViewer.apiService.service.ts
@@ -5,11 +5,7 @@ import { select, Store } from "@ngrx/store";
 import { Observable, Subject, Subscription, from, race, of, } from "rxjs";
 import { distinctUntilChanged, map, filter, startWith, switchMap, catchError, mapTo, take, shareReplay } from "rxjs/operators";
 import { DialogService } from "src/services/dialogService.service";
-import {
-  getLabelIndexMap,
-  getMultiNgIdsRegionsLabelIndexMap,
-  IavRootStoreInterface,
-} from "src/services/stateStore.service";
+
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
 import { FRAGMENT_EMIT_RED } from "src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component";
 import { IPluginManifest, PluginServices } from "src/plugin";
@@ -149,7 +145,7 @@ export class AtlasViewerAPIServices implements OnDestroy{
   }
 
   constructor(
-    private store: Store<IavRootStoreInterface>,
+    private store: Store<any>,
     private dialogService: DialogService,
     private snackbar: MatSnackBar,
     private zone: NgZone,
@@ -327,8 +323,9 @@ export class AtlasViewerAPIServices implements OnDestroy{
       filter(p => !!p && p.regions),
       distinctUntilChanged()
     ).subscribe(parcellation => {
-      this.interactiveViewer.metadata.regionsLabelIndexMap = getLabelIndexMap(parcellation.regions)
-      this.interactiveViewer.metadata.layersRegionLabelIndexMap = getMultiNgIdsRegionsLabelIndexMap(parcellation)
+      // TODO rework plugin metadata
+      // this.interactiveViewer.metadata.regionsLabelIndexMap = getLabelIndexMap(parcellation.regions)
+      // this.interactiveViewer.metadata.layersRegionLabelIndexMap = getMultiNgIdsRegionsLabelIndexMap(parcellation)
     })
 
     this.s.push(
diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts
index 341b6c268..cca817c6b 100644
--- a/src/atlasViewer/atlasViewer.component.ts
+++ b/src/atlasViewer/atlasViewer.component.ts
@@ -12,14 +12,8 @@ import {
 } from "@angular/core";
 import { Store, select } from "@ngrx/store";
 import { Observable, Subscription, merge, timer, fromEvent } from "rxjs";
-import { map, filter, delay, switchMapTo, take, startWith } from "rxjs/operators";
+import { filter, delay, switchMapTo, take, startWith } from "rxjs/operators";
 
-import {
-  IavRootStoreInterface,
-  isDefined,
-} from "../services/stateStore.service";
-
-import { AGREE_COOKIE } from "src/services/state/uiState.store";
 import { colorAnimation } from "./atlasViewer.animation"
 import { MouseHoverDirective } from "src/mouseoverModule";
 import {MatSnackBar, MatSnackBarRef} from "@angular/material/snack-bar";
@@ -31,6 +25,7 @@ import { PureContantService } from "src/util";
 import { ClickInterceptorService } from "src/glue";
 import { environment } from 'src/environments/environment'
 import { DOCUMENT } from "@angular/common";
+import { userPreference } from "src/state"
 
 /**
  * TODO
@@ -66,8 +61,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   public ismobile: boolean = false
   public meetsRequirement: boolean = true
 
-  public sidePanelView$: Observable<string|null>
-
   private snackbarRef: MatSnackBarRef<any>
 
   public onhoverLandmark$: Observable<{landmarkName: string, datasets: any} | null>
@@ -79,7 +72,7 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   private cookieDialogRef: MatDialogRef<any>
 
   constructor(
-    private store: Store<IavRootStoreInterface>,
+    private store: Store<any>,
     private pureConstantService: PureContantService,
     private matDialog: MatDialog,
     private rd: Renderer2,
@@ -90,13 +83,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
     @Inject(DOCUMENT) private document,
   ) {
 
-    this.sidePanelView$ = this.store.pipe(
-      select('uiState'),
-      filter(state => isDefined(state)),
-      map(state => state.focusedSidePanel),
-    )
-
-
     const error = this.el.nativeElement.getAttribute('data-error')
 
     if (error) {
@@ -163,9 +149,8 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
      * TODO avoid creating new views in lifecycle hooks in general
      */
     this.store.pipe(
-      select('uiState'),
-      select('agreedCookies'),
-      filter(agreed => !agreed),
+      select(userPreference.selectors.agreedToCookie),
+      filter(val => !val),
       delay(0),
     ).subscribe(() => {
       this.cookieDialogRef = this.matDialog.open(this.cookieAgreementComponent)
@@ -207,9 +192,9 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
 
   public cookieClickedOk() {
     if (this.cookieDialogRef) { this.cookieDialogRef.close() }
-    this.store.dispatch({
-      type: AGREE_COOKIE,
-    })
+    this.store.dispatch(
+      userPreference.actions.agreeCookie()
+    )
   }
 
   public quickTourFinale = {
diff --git a/src/extra_styles.css b/src/extra_styles.css
index 8b18c626e..3c9598b3f 100644
--- a/src/extra_styles.css
+++ b/src/extra_styles.css
@@ -874,4 +874,9 @@ quick-tour-unit svg
   stroke: rgb(255, 255, 255);
   stroke-linecap: round;
   stroke-linejoin: round;
-}
\ No newline at end of file
+}
+
+.overwrite-max-width-80vw
+{
+  max-width: 80vw!important;
+}
diff --git a/src/layouts/currentLayout/currentLayout.component.ts b/src/layouts/currentLayout/currentLayout.component.ts
index be31bf003..c5445d2cd 100644
--- a/src/layouts/currentLayout/currentLayout.component.ts
+++ b/src/layouts/currentLayout/currentLayout.component.ts
@@ -1,9 +1,7 @@
 import { Component } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { Observable } from "rxjs";
-import { startWith } from "rxjs/operators";
-import { SUPPORTED_PANEL_MODES } from "src/services/state/ngViewerState.store";
-import { ngViewerSelectorPanelMode } from "src/services/state/ngViewerState/selectors";
+import { userInterface } from "src/state"
 
 @Component({
   selector: 'current-layout',
@@ -15,15 +13,20 @@ import { ngViewerSelectorPanelMode } from "src/services/state/ngViewerState/sele
 
 export class CurrentLayout {
 
-  public supportedPanelModes = SUPPORTED_PANEL_MODES
-  public panelMode$: Observable<string>
+  public FOUR_PANEL: userInterface.PanelMode = "FOUR_PANEL"
+  
+  public panelModes: Record<string, userInterface.PanelMode> = {
+    FOUR_PANEL: "FOUR_PANEL",
+    H_ONE_THREE: "H_ONE_THREE",
+    SINGLE_PANEL: "SINGLE_PANEL",
+    V_ONE_THREE: "V_ONE_THREE"
+  }
+  public panelMode$: Observable<userInterface.PanelMode> = this.store$.pipe(
+    select(userInterface.selectors.panelMode)
+  )
 
   constructor(
     private store$: Store<any>,
   ) {
-    this.panelMode$ = this.store$.pipe(
-      select(ngViewerSelectorPanelMode),
-      startWith(SUPPORTED_PANEL_MODES[0]),
-    )
   }
 }
diff --git a/src/layouts/currentLayout/currentLayout.template.html b/src/layouts/currentLayout/currentLayout.template.html
index 9575932ed..9b52769e2 100644
--- a/src/layouts/currentLayout/currentLayout.template.html
+++ b/src/layouts/currentLayout/currentLayout.template.html
@@ -1,7 +1,7 @@
 <ng-container [ngSwitch]="panelMode$ | async">
   <layout-four-panel
-    *ngSwitchCase="supportedPanelModes[0]"
-    class="d-block w-100 h-100">
+    *ngSwitchCase="panelModes.FOUR_PANEL"
+    class="d-block sxplr-w-100 sxplr-h-100">
     <ng-container cell-i>
       <ng-content *ngTemplateOutlet="celli"></ng-content>
     </ng-container>
@@ -16,8 +16,8 @@
     </ng-container>
   </layout-four-panel>
   <layout-horizontal-one-three
-    *ngSwitchCase="supportedPanelModes[1]"
-    class="d-block w-100 h-100">
+    *ngSwitchCase="panelModes.H_ONE_THREE"
+    class="d-block sxplr-w-100 sxplr-h-100">
     <ng-container cell-i>
       <ng-content *ngTemplateOutlet="celli"></ng-content>
     </ng-container>
@@ -32,8 +32,8 @@
     </ng-container>
   </layout-horizontal-one-three>
   <layout-vertical-one-three
-    *ngSwitchCase="supportedPanelModes[2]"
-    class="d-block w-100 h-100">
+    *ngSwitchCase="panelModes.V_ONE_THREE"
+    class="d-block sxplr-w-100 sxplr-h-100">
     <ng-container cell-i>
       <ng-content *ngTemplateOutlet="celli"></ng-content>
     </ng-container>
@@ -48,8 +48,8 @@
     </ng-container>
   </layout-vertical-one-three>
   <layout-single-panel
-    *ngSwitchCase="supportedPanelModes[3]"
-    class="d-block w-100 h-100">
+    *ngSwitchCase="panelModes.SINGLE_PANEL"
+    class="d-block sxplr-w-100 sxplr-h-100">
     <ng-container cell-i>
       <ng-content *ngTemplateOutlet="celli"></ng-content>
     </ng-container>
@@ -64,7 +64,7 @@
     </ng-container>
   </layout-single-panel>
   <div *ngSwitchDefault>
-    A panel mode which I have never seen before ...
+    A panel mode which I have never seen before ... {{ panelMode$ | async }}
   </div>
 </ng-container>
 
diff --git a/src/main.module.ts b/src/main.module.ts
index 99766310f..329b27c1f 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -1,31 +1,27 @@
 import { DragDropModule } from '@angular/cdk/drag-drop'
 import { CommonModule } from "@angular/common";
-import { NgModule } from "@angular/core";
+import { APP_INITIALIZER, NgModule } from "@angular/core";
 import { FormsModule } from "@angular/forms";
-import { StoreModule, ActionReducer, Store, select } from "@ngrx/store";
+import { Store, select } from "@ngrx/store";
 import { AngularMaterialModule } from 'src/sharedModules'
 import { AtlasViewer } from "./atlasViewer/atlasViewer.component";
 import { ComponentsModule } from "./components/components.module";
 import { LayoutModule } from "./layouts/layout.module";
-import { ngViewerState, uiState, userConfigState, UserConfigStateUseEffect, viewerConfigState } from "./services/stateStore.service";
 import { UIModule } from "./ui/ui.module";
 
 import { HttpClientModule } from "@angular/common/http";
-import { EffectsModule } from "@ngrx/effects";
 import { AtlasWorkerService } from "./atlasViewer/atlasViewer.workerService.service";
 import { WINDOW_MESSAGING_HANDLER_TOKEN } from 'src/messaging/types'
 
 import { ConfirmDialogComponent } from "./components/confirmDialog/confirmDialog.component";
 import { DialogComponent } from "./components/dialog/dialog.component";
 import { DialogService } from "./services/dialogService.service";
-import { NgViewerUseEffect } from "./services/state/ngViewerState.store";
 import { UIService } from "./services/uiService.service";
 import { FloatingContainerDirective } from "./util/directives/floatingContainer.directive";
 import { FloatingMouseContextualContainerDirective } from "./util/directives/floatingMouseContextualContainer.directive";
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR, PureContantService, UtilModule } from "src/util";
 import { SpotLightModule } from 'src/spotlight/spot-light.module'
 import { TryMeComponent } from "./ui/tryme/tryme.component";
-import { UiStateUseEffect } from "src/services/state/uiState.store";
 import { TemplateCoordinatesTransformation } from "src/services/templateCoordinatesTransformation.service";
 import { WidgetModule } from 'src/widget';
 import { PluginModule } from './plugin/plugin.module';
@@ -35,9 +31,7 @@ import { AuthService } from './auth'
 import 'src/theme.scss'
 import { ClickInterceptorService } from './glue';
 import { TOS_OBS_INJECTION_TOKEN } from './ui/kgtos';
-import { UiEffects } from './services/state/uiState/ui.effects';
 import { MesssagingModule } from './messaging/module';
-import { ParcellationRegionModule } from './atlasComponents/parcellationRegion';
 import { ViewerModule, VIEWERMODULE_DARKTHEME } from './viewerModule';
 import { CookieModule } from './ui/cookieAgreement/module';
 import { KgTosModule } from './ui/kgtos/module';
@@ -54,22 +48,12 @@ import { NotSupportedCmp } from './notSupportedCmp/notSupported.component';
 
 import {
   atlasSelection,
-  annotation,
-  userInterface,
-  userInteraction,
-  plugins,
+  RootEffecsModule,
+  RootStoreModule,
 } from "./state"
 import { DARKTHEME } from './util/injectionTokens';
 import { map } from 'rxjs/operators';
 
-export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
-  return function(state, action) {
-    console.log('state', state);
-    console.log('action', action);
- 
-    return reducer(state, action);
-  };
-}
 
 @NgModule({
   imports : [
@@ -88,36 +72,14 @@ export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
     MesssagingModule,
     ViewerModule,
     SpotLightModule,
-    ParcellationRegionModule,
     CookieModule,
     KgTosModule,
     MouseoverModule,
     AtlasViewerRouterModule,
     QuickTourModule,
     
-    EffectsModule.forRoot([
-      UserConfigStateUseEffect,
-      NgViewerUseEffect,
-      plugins.Effects,
-      UiStateUseEffect,
-      UiEffects,
-      atlasSelection.Effect,
-    ]),
-    StoreModule.forRoot({
-      viewerConfigState,
-      ngViewerState,
-      uiState,
-      userConfigState,
-      [atlasSelection.nameSpace]: atlasSelection.reducer,
-      [userInterface.nameSpace]: userInterface.reducer,
-      [userInteraction.nameSpace]: userInteraction.reducer,
-      [annotation.nameSpace]: annotation.reducer,
-      [plugins.nameSpace]: plugins.reducer,
-    },{
-      metaReducers: [ 
-        // debug,
-      ]
-    }),
+    RootEffecsModule,
+    RootStoreModule,
     HttpClientModule,
   ],
   declarations : [
@@ -224,6 +186,15 @@ export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
         map(tmpl => !!(tmpl && tmpl["@id"] !== 'minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588')),
       ),
       deps: [ Store ]
+    },
+    {
+      provide: APP_INITIALIZER,
+      useFactory: (authSvc: AuthService) => {
+        authSvc.authReloadState()
+        return () => Promise.resolve()
+      },
+      multi: true,
+      deps: [ AuthService ]
     }
   ],
   bootstrap : [
@@ -231,11 +202,4 @@ export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
   ],
 })
 
-export class MainModule {
-
-  constructor(
-    authServce: AuthService,
-  ) {
-    authServce.authReloadState()
-  }
-}
+export class MainModule {}
diff --git a/src/mouseoverModule/mouseover.directive.ts b/src/mouseoverModule/mouseover.directive.ts
index b05625a94..9e0055301 100644
--- a/src/mouseoverModule/mouseover.directive.ts
+++ b/src/mouseoverModule/mouseover.directive.ts
@@ -1,9 +1,8 @@
 import { Directive } from "@angular/core"
 import { select, Store } from "@ngrx/store"
-import { merge, Observable } from "rxjs"
+import { merge, NEVER, Observable, of } from "rxjs"
 import { distinctUntilChanged, map, scan, shareReplay } from "rxjs/operators"
 import { LoggingService } from "src/logging"
-import { uiStateMouseOverLandmarkSelector, uiStateMouseoverUserLandmark } from "src/services/state/uiState/selectors"
 import { TOnHoverObj, temporalPositveScanFn } from "./util"
 import { ModularUserAnnotationToolService } from "src/atlasComponents/userAnnotations/tools/service";
 import { userInteraction } from "src/state"
@@ -26,24 +25,26 @@ export class MouseHoverDirective {
     // TODO consider moving these into a single obs serviced by a DI service
     // can potentially net better performance
 
-    const onHoverUserLandmark$ = this.store$.pipe(
-      select(uiStateMouseoverUserLandmark)
-    )
-
-    const onHoverLandmark$ = this.store$.pipe(
-      select(uiStateMouseOverLandmarkSelector)
-    ).pipe(
-      map(landmark => {
-        if (landmark === null) { return null }
-        const idx = Number(landmark.replace('label=', ''))
-        if (isNaN(idx)) {
-          this.log.warn(`Landmark index could not be parsed as a number: ${landmark}`)
-          return {
-            landmarkName: idx,
-          }
-        } 
-      }),
-    )
+    const onHoverUserLandmark$ = NEVER
+    // this.store$.pipe(
+    //   select(uiStateMouseoverUserLandmark)
+    // )
+
+    const onHoverLandmark$ = NEVER
+    // this.store$.pipe(
+    //   select(uiStateMouseOverLandmarkSelector)
+    // ).pipe(
+    //   map(landmark => {
+    //     if (landmark === null) { return null }
+    //     const idx = Number(landmark.replace('label=', ''))
+    //     if (isNaN(idx)) {
+    //       this.log.warn(`Landmark index could not be parsed as a number: ${landmark}`)
+    //       return {
+    //         landmarkName: idx,
+    //       }
+    //     } 
+    //   }),
+    // )
 
     const onHoverSegments$ = this.store$.pipe(
       select(userInteraction.selectors.mousingOverRegions),
diff --git a/src/overwrite.scss b/src/overwrite.scss
index c955e1032..7db898b3e 100644
--- a/src/overwrite.scss
+++ b/src/overwrite.scss
@@ -56,22 +56,21 @@ $media-map: (
 $overflow-directive: hidden, scroll, auto, visible;
 @each $directive in $overflow-directive {
   .#{$nsp}-of-x-#{$directive} {
-    overflow-x: $directive
+    overflow-x: $directive!important;
   }
   .#{$nsp}-of-y-#{$directive} {
-    overflow-y: $directive
+    overflow-y: $directive!important;
   }
   .#{$nsp}-of-#{$directive} {
-    overflow: $directive
+    overflow: $directive!important;
   }
 }
 
 @for $scale from 5 through 10 {
 
   $scale-var: $scale * 10;
-  .scale-#{$scale-var}
+  .#{$nsp}-scale-#{$scale-var}
   {
-    color: red;
     transform: scale($scale * 0.1);
   }
 }
@@ -135,7 +134,7 @@ $transform-origin-maps: (
   }
 }
 
-$display-vars: block, inline-block, flex, inline-flex;
+$display-vars: none, block, inline-block, flex, inline-flex;
 @each $display-var in $display-vars {
   .d-#{$display-var}
   {
@@ -147,7 +146,7 @@ $display-vars: block, inline-block, flex, inline-flex;
   }
 }
 
-$align-items-vars: center, stretch;
+$align-items-vars: center, stretch, start;
 @each $align-items-var in $align-items-vars {
   .align-items-#{$align-items-var} {
     align-items: $align-items-var;
@@ -179,3 +178,42 @@ $position-vars: relative, absolute;
     position: $position-var;
   }
 }
+
+.#{$nsp}-bg-none
+{
+  background: none!important;
+}
+
+.#{$nsp}-box-shadow-none
+{
+  box-shadow: none!important;
+}
+
+
+$white-space-vars: nowrap;
+@each $white-space-var in $white-space-vars {
+  .#{$nsp}-white-space-#{$white-space-var}
+  {
+    white-space: $white-space-var!important;
+  }
+}
+
+$pointer-events-vars: all, none;
+@each $pointer-events-var in $pointer-events-vars {
+  .#{$nsp}-pointer-events-#{$pointer-events-var}
+  {
+    pointer-events: $pointer-events-var!important;
+  }
+}
+
+$width-pc-vars: 100;
+@each $width-pc-var in $width-pc-vars {
+  .#{$nsp}-w-#{$width-pc-var} {
+    width: $width-pc-var * 1%;
+  }
+}
+
+.#{$nsp}-border
+{
+  border-width: 1px;
+}
diff --git a/src/plugin/pluginCsp/pluginCsp.component.ts b/src/plugin/pluginCsp/pluginCsp.component.ts
index 7ff3c8a1f..ff1026172 100644
--- a/src/plugin/pluginCsp/pluginCsp.component.ts
+++ b/src/plugin/pluginCsp/pluginCsp.component.ts
@@ -2,7 +2,7 @@ import { Component } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { map } from "rxjs/operators";
 import { PluginServices } from "../atlasViewer.pluginService.service";
-import { selectorAllPluginsCspPermission } from "src/services/state/userConfigState.store";
+import { userPreference } from "src/state"
 
 @Component({
   selector: 'plugin-csp-controller',
@@ -15,7 +15,7 @@ import { selectorAllPluginsCspPermission } from "src/services/state/userConfigSt
 export class PluginCspCtrlCmp{
 
   public pluginCsp$ = this.store$.pipe(
-    select(selectorAllPluginsCspPermission),
+    select(userPreference.selectors.userCsp),
     map(pluginCsp => Object.keys(pluginCsp).map(key => ({ pluginKey: key, pluginCsp: pluginCsp[key] }))),
   )
 
diff --git a/src/routerModule/util.ts b/src/routerModule/util.ts
index 127c59347..ad87e1fd8 100644
--- a/src/routerModule/util.ts
+++ b/src/routerModule/util.ts
@@ -1,8 +1,6 @@
 import { encodeNumber, decodeToNumber, separator, encodeURIFull } from './cipher'
 import { UrlSegment, UrlTree } from "@angular/router"
 import { getShader, PMAP_DEFAULT_CONFIG } from "src/util/constants"
-import { mixNgLayers } from "src/services/state/ngViewerState.store"
-import { uiStatePreviewingDatasetFilesSelector } from "src/services/state/uiState/selectors"
 import { Component } from "@angular/core"
 import { atlasSelection, plugins } from "src/state"
 
@@ -61,25 +59,6 @@ export const cvtFullRouteToState = (fullPath: UrlTree, state: any, _warnCb?: (ar
     returnObj[key] = val
   }
 
-  // TODO deprecate
-  // but ensure bkwd compat?
-  const niftiLayers = fullPath.queryParams['niftiLayers']
-  if (niftiLayers) {
-    const layers = niftiLayers
-      .split('__')
-      .map(layer => {
-        return {
-          name : layer,
-          source : `nifti://${layer}`,
-          mixability : 'nonmixable',
-          shader : getShader(PMAP_DEFAULT_CONFIG),
-        } as any
-      })
-    const { ngViewerState } = returnState
-    ngViewerState.layers = mixNgLayers(ngViewerState.layers, layers)
-  }
-  // -- end deprecate
-
   // logical assignment. Use instead of above after typescript > v4.0.0
   // returnState['viewerState'] ||= {}
   if (!returnState['viewerState']) {
@@ -214,22 +193,9 @@ export const cvtStateToHashedRoutes = (state): string => {
   const standaloneVolumes = atlasSelection.selectors.standaloneVolumes(state)
   const navigation = atlasSelection.selectors.navigation(state)
 
-  const previewingDatasetFiles = uiStatePreviewingDatasetFilesSelector(state)
   let dsPrvString: string
   const searchParam = new URLSearchParams()
 
-  if (previewingDatasetFiles && Array.isArray(previewingDatasetFiles)) {
-    const dsPrvArr = []
-    const datasetPreviews = (previewingDatasetFiles as {datasetId: string, filename: string}[])
-    for (const preview of datasetPreviews) {
-      dsPrvArr.push(preview)
-    }
-
-    if (dsPrvArr.length === 1) {
-      dsPrvString = `${dsPrvArr[0].datasetId}::${dsPrvArr[0].filename}`
-    }
-  }
-
   let cNavString: string
   if (navigation) {
     const { orientation, perspectiveOrientation, perspectiveZoom, position, zoom } = navigation
diff --git a/src/services/state/ngViewerState.store.helper.ts b/src/services/state/ngViewerState.store.helper.ts
index 6f23c74d1..2898db9c7 100644
--- a/src/services/state/ngViewerState.store.helper.ts
+++ b/src/services/state/ngViewerState.store.helper.ts
@@ -4,7 +4,7 @@ export { INgLayerInterface, PANELS } from './ngViewerState/constants'
 export {
   ngViewerActionAddNgLayer,
   ngViewerActionRemoveNgLayer,
-  ngViewerActionSetPerspOctantRemoval,
+  
   ngViewerActionToggleMax,
   ngViewerActionClearView,
   ngViewerActionSetPanelOrder,
@@ -15,8 +15,6 @@ export {
   ngViewerSelectorClearView,
   ngViewerSelectorClearViewEntries,
   ngViewerSelectorNehubaReady,
-  ngViewerSelectorOctantRemoval,
-  ngViewerSelectorPanelMode,
   ngViewerSelectorPanelOrder,
   ngViewerSelectorLayers,
 } from './ngViewerState/selectors'
diff --git a/src/services/state/ngViewerState.store.spec.ts b/src/services/state/ngViewerState.store.spec.ts
deleted file mode 100644
index 21173833c..000000000
--- a/src/services/state/ngViewerState.store.spec.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing"
-import { TestBed } from "@angular/core/testing"
-import { provideMockActions } from "@ngrx/effects/testing"
-import { Action } from "@ngrx/store"
-import { provideMockStore } from "@ngrx/store/testing"
-import { Observable, of } from "rxjs"
-import { PureContantService } from "src/util"
-import { generalApplyState } from "../stateStore.helper"
-import { NgViewerUseEffect } from "./ngViewerState.store"
-
-const action$: Observable<Action> = of({ type: 'TEST'})
-const initState = {}
-describe('> ngViewerState.store.ts', () => {
-  describe('> NgViewerUseEffect', () => {
-    let ef: NgViewerUseEffect
-    beforeEach(() => {
-
-      TestBed.configureTestingModule({
-        imports: [
-          HttpClientTestingModule,
-        ],
-        providers: [
-          provideMockActions(() => action$),
-          provideMockStore({ initialState: initState }),
-          {
-            provide: PureContantService,
-            useValue: {
-              useTouchUI$: of(false),
-              backendUrl: `http://localhost:3000/`
-            }
-          }
-        ]
-      })
-    })
-
-    it('> shoudl be insable', () => {
-      ef = TestBed.inject(NgViewerUseEffect)
-      expect(ef).toBeTruthy()
-    })
-
-    describe('> applySavedUserConfig$', () => {
-
-      let ctrl: HttpTestingController
-      beforeEach(() => {
-        ctrl = TestBed.inject(HttpTestingController)
-        ef = TestBed.inject(NgViewerUseEffect)
-      })
-
-      afterEach(() => {
-        ctrl.verify()
-      })
-      
-      it('> if http response errors, user$ should be stream of null', () => {
-        
-        ef.applySavedUserConfig$.subscribe(_action => {
-          // should not emit
-          expect(false).toEqual(true)
-        })
-        const resp1 = ctrl.expectOne('http://localhost:3000/user/config')
-        resp1.error(null, {
-          status: 404,
-        })
-      })
-
-      it('> if http response contains truthy error key, user should return stream of null', () => {
-
-        ef.applySavedUserConfig$.subscribe(_action => {
-          // should not emit
-          expect(false).toEqual(true)
-        })
-        const resp = ctrl.expectOne('http://localhost:3000/user/config')
-        resp.flush({
-          error: true
-        })
-      })
-
-      it('> if http response does not contain error key, should return the resp', () => {
-        
-        const mUserState = {
-          foo: 'baz',
-          baz: 'pineablle'
-        }
-        ef.applySavedUserConfig$.subscribe(action => {
-          expect(action).toEqual(generalApplyState({
-            state: {
-              ...initState,
-              ngViewerState: {
-                ...(initState['ngViewerState'] || {}),
-                ...mUserState,
-              }
-            }
-          }))
-        })
-        const resp = ctrl.expectOne('http://localhost:3000/user/config')
-        resp.flush({ ngViewerState: mUserState})
-
-      })
-    })
-  })
-})
diff --git a/src/services/state/ngViewerState.store.ts b/src/services/state/ngViewerState.store.ts
deleted file mode 100644
index a27495313..000000000
--- a/src/services/state/ngViewerState.store.ts
+++ /dev/null
@@ -1,341 +0,0 @@
-import { Injectable, OnDestroy } from '@angular/core';
-import { Observable, combineLatest, fromEvent, Subscription, of } from 'rxjs';
-import { Effect, Actions, ofType } from '@ngrx/effects';
-import { withLatestFrom, map, distinctUntilChanged, scan, shareReplay, filter, mapTo, debounceTime, catchError, skip, throttleTime } from 'rxjs/operators';
-import { getNgIds } from 'src/util/fn';
-import { Action, select, Store, createReducer, on } from '@ngrx/store'
-import { CYCLE_PANEL_MESSAGE } from 'src/util/constants';
-import { HttpClient } from '@angular/common/http';
-import { INgLayerInterface, ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer, ngViewerActionSetPerspOctantRemoval } from './ngViewerState.store.helper'
-import { PureContantService } from 'src/util';
-import { PANELS } from './ngViewerState.store.helper'
-import { ngViewerActionToggleMax, ngViewerActionClearView, ngViewerActionSetPanelOrder, ngViewerActionSwitchPanelMode, ngViewerActionForceShowSegment, ngViewerActionNehubaReady, ngViewerActionCycleViews } from './ngViewerState/actions';
-import { generalApplyState } from '../stateStore.helper';
-import { ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from './ngViewerState/selectors';
-import { uiActionSnackbarMessage } from './uiState/actions';
-import { TUserRouteError } from 'src/auth/auth.service';
-
-export function mixNgLayers(oldLayers: INgLayerInterface[], newLayers: INgLayerInterface|INgLayerInterface[]): INgLayerInterface[] {
-  if (newLayers instanceof Array) {
-    return oldLayers.concat(newLayers)
-  } else {
-    return oldLayers.concat({
-      ...newLayers,
-    })
-  }
-}
-
-export interface StateInterface {
-  layers: INgLayerInterface[]
-  forceShowSegment: boolean | null
-  nehubaReady: boolean
-  panelMode: string
-  panelOrder: string
-
-  octantRemoval: boolean
-  showSubstrate: boolean
-  showZoomlevel: boolean
-
-  clearViewQueue: {
-    [key: string]: boolean
-  }
-}
-
-export interface ActionInterface extends Action {
-  layer: INgLayerInterface
-  layers: INgLayerInterface[]
-  forceShowSegment: boolean
-  nehubaReady: boolean
-  payload: any
-}
-
-export const defaultState: StateInterface = {
-  layers: [],
-  forceShowSegment: null,
-  nehubaReady: false,
-  panelMode: PANELS.FOUR_PANEL,
-  panelOrder: `0123`,
-
-  octantRemoval: true,
-  showSubstrate: null,
-  showZoomlevel: null,
-
-  clearViewQueue: {}
-}
-
-export const ngViewerStateReducer = createReducer(
-  defaultState,
-  on(ngViewerActionClearView, (state, { payload }) => {
-    const { clearViewQueue } = state
-    const clearViewQueueUpdated = {...clearViewQueue}
-    for (const key in payload) {
-      clearViewQueueUpdated[key] = payload[key]
-    }
-    return {
-      ...state,
-      clearViewQueue: clearViewQueueUpdated
-    }
-  }),
-  on(ngViewerActionSetPerspOctantRemoval, (state, { octantRemovalFlag }) => {
-    return {
-      ...state,
-      octantRemoval: octantRemovalFlag
-    }
-  }),
-  on(ngViewerActionAddNgLayer, (state, { layer }) => {
-    return {
-      ...state,
-      layers: mixNgLayers(state.layers, layer)
-    }
-  }),
-  on(ngViewerActionSetPanelOrder, (state, { payload }) => {
-    const { panelOrder } = payload
-    return {
-      ...state,
-      panelOrder
-    }
-  }),
-  on(ngViewerActionSwitchPanelMode, (state, { payload }) => {
-    const { panelMode } = payload
-    if (SUPPORTED_PANEL_MODES.indexOf(panelMode as any) < 0) { return state }
-    return {
-      ...state,
-      panelMode
-    }
-  }),
-  on(ngViewerActionRemoveNgLayer, (state, { layer }) => {
-    
-    const newLayers = Array.isArray(layer)
-      ? (() => {
-        const layerNameSet = new Set(layer.map(l => l.name))
-        return state.layers.filter(l => !layerNameSet.has(l.name))
-      })()
-      : state.layers.filter(l => l.name !== layer.name)
-    return {
-      ...state,
-      layers: newLayers
-    }
-  }),
-  on(ngViewerActionForceShowSegment, (state, { forceShowSegment }) => {
-    return {
-      ...state,
-      forceShowSegment
-    }
-  }),
-  on(ngViewerActionNehubaReady, (state, { nehubaReady }) => {
-    return {
-      ...state,
-      nehubaReady
-    }
-  }),
-  on(generalApplyState, (_, { state }) => {
-    const { ngViewerState } = state
-    return ngViewerState
-  })
-)
-
-
-// must export a named function for aot compilation
-// see https://github.com/angular/angular/issues/15587
-// https://github.com/amcdnl/ngrx-actions/issues/23
-// or just google for:
-//
-// angular function expressions are not supported in decorators
-
-export function stateStore(state, action) {
-  return ngViewerStateReducer(state, action)
-}
-
-type TUserConfig = {
-
-}
-
-type TUserConfigResp = TUserConfig & TUserRouteError
-
-@Injectable({
-  providedIn: 'root',
-})
-
-export class NgViewerUseEffect implements OnDestroy {
-  @Effect()
-  public toggleMaximiseMode$: Observable<any>
-
-  @Effect()
-  public unmaximiseOrder$: Observable<any>
-
-  @Effect()
-  public maximiseOrder$: Observable<any>
-
-  @Effect()
-  public toggleMaximiseCycleMessage$: Observable<any>
-
-  @Effect()
-  public cycleViews$: Observable<any>
-
-  private panelOrder$: Observable<string>
-  private panelMode$: Observable<string>
-
-  private subscriptions: Subscription[] = []
-
-  @Effect()
-  public applySavedUserConfig$: Observable<any>
-
-  constructor(
-    private actions: Actions,
-    private store$: Store<any>,
-    private pureConstantService: PureContantService,
-    private http: HttpClient,
-  ){
-
-    this.applySavedUserConfig$ = this.http.get<TUserConfigResp>(`${this.pureConstantService.backendUrl}user/config`).pipe(
-      map(json => {
-        if (json.error) {
-          throw new Error(json.message || 'User not loggedin.')
-        }
-        return json
-      }),
-      catchError((err,caught) => of(null)),
-      filter(v => !!v),
-      withLatestFrom(this.store$),
-      map(([{ ngViewerState: fetchedNgViewerState }, state]) => {
-        const { ngViewerState } = state
-        return generalApplyState({
-          state: {
-            ...state,
-            ngViewerState: {
-              ...ngViewerState,
-              ...fetchedNgViewerState
-            }}
-        })
-      })
-    )
-
-    const toggleMaxmimise$ = this.actions.pipe(
-      ofType(ngViewerActionToggleMax.type),
-      shareReplay(1),
-    )
-
-    this.panelOrder$ = this.store$.pipe(
-      select(ngViewerSelectorPanelOrder),
-      distinctUntilChanged(),
-    )
-
-    this.panelMode$ = this.store$.pipe(
-      select(ngViewerSelectorPanelMode),
-      distinctUntilChanged(),
-    )
-
-    this.cycleViews$ = this.actions.pipe(
-      ofType(ngViewerActionCycleViews.type),
-      withLatestFrom(this.panelOrder$),
-      map(([_, panelOrder]) => {
-        return ngViewerActionSetPanelOrder({
-          payload: {
-            panelOrder: [...panelOrder.slice(1), ...panelOrder.slice(0, 1)].join(''),
-          }
-        })
-      }),
-    )
-
-    this.maximiseOrder$ = toggleMaxmimise$.pipe(
-      withLatestFrom(
-        combineLatest([
-          this.panelOrder$,
-          this.panelMode$,
-        ]),
-      ),
-      filter(([_action, [_panelOrder, panelMode]]) => panelMode !== PANELS.SINGLE_PANEL),
-      map(([ action, [ oldPanelOrder ] ]) => {
-        const { payload } = action as ActionInterface
-        const { index = 0 } = payload
-
-        const panelOrder = [...oldPanelOrder.slice(index), ...oldPanelOrder.slice(0, index)].join('')
-        return ngViewerActionSetPanelOrder({
-          payload: { panelOrder },
-        })
-      }),
-    )
-
-    this.unmaximiseOrder$ = toggleMaxmimise$.pipe(
-      withLatestFrom(
-        combineLatest([
-          this.panelOrder$,
-          this.panelMode$,
-        ]),
-      ),
-      scan((acc, curr) => {
-        const [action, [panelOrders, panelMode]] = curr
-        return [{
-          action,
-          panelOrders,
-          panelMode,
-        }, ...acc.slice(0, 1)]
-      }, [] as any[]),
-      filter(([ { panelMode } ]) => panelMode === PANELS.SINGLE_PANEL),
-      map(arr => {
-        const {
-          action,
-          panelOrders,
-        } = arr[0]
-
-        const {
-          panelOrders: panelOrdersPrev = null,
-        } = arr[1] || {}
-
-        const { payload } = action as ActionInterface
-        const { index = 0 } = payload
-
-        const panelOrder = panelOrdersPrev || [...panelOrders.slice(index), ...panelOrders.slice(0, index)].join('')
-
-        return ngViewerActionSetPanelOrder({
-          payload: { panelOrder }
-        })
-      }),
-    )
-
-    const scanFn = (acc: string[], curr: string): string[] => [curr, ...acc.slice(0, 1)]
-
-    this.toggleMaximiseMode$ = toggleMaxmimise$.pipe(
-      withLatestFrom(this.panelMode$.pipe(
-        scan(scanFn, []),
-      )),
-      map(([ _, panelModes ]) => {
-        return ngViewerActionSwitchPanelMode({
-          payload: {
-            panelMode: panelModes[0] === PANELS.SINGLE_PANEL
-              ? (panelModes[1] || PANELS.FOUR_PANEL)
-              : PANELS.SINGLE_PANEL,
-          },
-        })
-      }),
-    )
-
-    this.toggleMaximiseCycleMessage$ = combineLatest([
-      this.toggleMaximiseMode$,
-      this.pureConstantService.useTouchUI$,
-    ]).pipe(
-      filter(([_, useMobileUI]) => !useMobileUI),
-      map(([toggleMaximiseMode, _]) => toggleMaximiseMode),
-      filter(({ payload }) => payload.panelMode && payload.panelMode === PANELS.SINGLE_PANEL),
-      mapTo(uiActionSnackbarMessage({
-        snackbarMessage: CYCLE_PANEL_MESSAGE
-      })),
-    )
-  }
-
-  public ngOnDestroy() {
-    while (this.subscriptions.length > 0) {
-      this.subscriptions.pop().unsubscribe()
-    }
-  }
-}
-
-export { INgLayerInterface } 
-
-export const SUPPORTED_PANEL_MODES = [
-  PANELS.FOUR_PANEL,
-  PANELS.H_ONE_THREE,
-  PANELS.V_ONE_THREE,
-  PANELS.SINGLE_PANEL,
-]
-
diff --git a/src/services/state/ngViewerState/actions.ts b/src/services/state/ngViewerState/actions.ts
index c504a085a..858602e07 100644
--- a/src/services/state/ngViewerState/actions.ts
+++ b/src/services/state/ngViewerState/actions.ts
@@ -11,11 +11,6 @@ export const ngViewerActionRemoveNgLayer = createAction(
   props<{ layer: Partial<INgLayerInterface>|Partial<INgLayerInterface>[] }>()
 )
 
-export const ngViewerActionSetPerspOctantRemoval = createAction(
-  `[ngViewerAction] setPerspectiveOctant`,
-  props<{ octantRemovalFlag: boolean }>()
-)
-
 export const ngViewerActionToggleMax = createAction(
   `[ngViewerAction] toggleMax`,
   props<{ payload: { index: number } }>()
diff --git a/src/services/state/ngViewerState/selectors.ts b/src/services/state/ngViewerState/selectors.ts
index 7222296d4..e5940a77d 100644
--- a/src/services/state/ngViewerState/selectors.ts
+++ b/src/services/state/ngViewerState/selectors.ts
@@ -21,15 +21,6 @@ export const ngViewerSelectorPanelOrder = createSelector(
   ngViewerState => ngViewerState.panelOrder
 )
 
-export const ngViewerSelectorPanelMode = createSelector(
-  state => state['ngViewerState'],
-  ngViewerState => ngViewerState.panelMode
-)
-
-export const ngViewerSelectorOctantRemoval = createSelector(
-  state => state['ngViewerState'],
-  ngViewerState => ngViewerState.octantRemoval
-)
 
 export const ngViewerSelectorNehubaReady = createSelector(
   state => state['ngViewerState'],
diff --git a/src/services/state/uiState.store.helper.ts b/src/services/state/uiState.store.helper.ts
index 2a89567a3..b2201ef0b 100644
--- a/src/services/state/uiState.store.helper.ts
+++ b/src/services/state/uiState.store.helper.ts
@@ -13,10 +13,6 @@ export {
   uiActionMouseoverSegments,
 } from './uiState/actions'
 
-export {
-  uiStatePreviewingDatasetFilesSelector,
-  uiStateMouseoverUserLandmark,
-} from './uiState/selectors'
 
 export enum EnumWidgetTypes{
   DATASET_PREVIEW,
diff --git a/src/services/state/uiState.store.ts b/src/services/state/uiState.store.ts
deleted file mode 100644
index 1df46f1de..000000000
--- a/src/services/state/uiState.store.ts
+++ /dev/null
@@ -1,223 +0,0 @@
-import { Injectable, TemplateRef, OnDestroy } from '@angular/core';
-import { Action, select, Store } from '@ngrx/store'
-
-import { Effect, Actions, ofType } from "@ngrx/effects";
-import { Observable, Subscription } from "rxjs";
-import { filter, map, mapTo, scan, startWith, take } from "rxjs/operators";
-import { COOKIE_VERSION, KG_TOS_VERSION, LOCAL_STORAGE_CONST } from 'src/util/constants'
-import { IavRootStoreInterface, GENERAL_ACTION_TYPES } from '../stateStore.service'
-import { MatBottomSheetRef, MatBottomSheet } from '@angular/material/bottom-sheet';
-import { uiStateCloseSidePanel, uiStateOpenSidePanel, uiStateCollapseSidePanel, uiStateExpandSidePanel, uiActionSetPreviewingDatasetFiles, uiStateShowBottomSheet, uiActionShowSidePanelConnectivity } from './uiState.store.helper';
-import { viewerStateMouseOverCustomLandmark } from './viewerState/actions';
-import { IUiState } from './uiState/common'
-import { uiActionMouseoverLandmark, uiActionMouseoverSegments, uiActionSnackbarMessage } from './uiState/actions';
-export const defaultState: IUiState = {
-
-  previewingDatasetFiles: [],
-
-  mouseOverSegments: [],
-  mouseOverSegment: null,
-
-  mouseOverLandmark: null,
-  mouseOverUserLandmark: null,
-
-  focusedSidePanel: null,
-  sidePanelIsOpen: false,
-  sidePanelExploreCurrentViewIsOpen: false,
-
-  snackbarMessage: null,
-
-  /**
-   * replace with server side logic (?)
-   */
-  agreedCookies: localStorage.getItem(LOCAL_STORAGE_CONST.AGREE_COOKIE) === COOKIE_VERSION,
-  agreedKgTos: localStorage.getItem(LOCAL_STORAGE_CONST.AGREE_KG_TOS) === KG_TOS_VERSION,
-}
-
-export { IUiState }
-
-export const getStateStore = ({ state = defaultState } = {}) => (prevState: IUiState = state, action: ActionInterface) => {
-  switch (action.type) {
-
-  case uiActionSetPreviewingDatasetFiles.type: {
-    const { previewingDatasetFiles } = action as any
-    return {
-      ...prevState,
-      previewingDatasetFiles
-    }
-  }
-  case uiActionMouseoverSegments.type: {
-    const { segments } = action
-    return {
-      ...prevState,
-      mouseOverSegments: segments,
-    }
-  }
-  case MOUSE_OVER_SEGMENT: 
-    return {
-      ...prevState,
-      mouseOverSegment : action.segment,
-    }
-  case viewerStateMouseOverCustomLandmark.type: {
-    const { payload = {} } = action
-    const { userLandmark: mouseOverUserLandmark = null } = payload
-    return {
-      ...prevState,
-      mouseOverUserLandmark,
-    }
-  }
-  case uiActionMouseoverLandmark.type:
-    return {
-      ...prevState,
-      mouseOverLandmark : action.landmark,
-    }
-  case uiActionSnackbarMessage.type:
-  case SNACKBAR_MESSAGE: {
-    const { snackbarMessage } = action
-    /**
-       * Need to use symbol here, or repeated snackbarMessage will not trigger new event
-       */
-    return {
-      ...prevState,
-      snackbarMessage: Symbol(snackbarMessage),
-    }
-  }
-  case uiStateOpenSidePanel.type:
-  case OPEN_SIDE_PANEL:
-    return {
-      ...prevState,
-      sidePanelIsOpen: true,
-    }
-  // src/state/userInteraction/actions.closeSidePanel
-  case uiStateCloseSidePanel.type:
-  case CLOSE_SIDE_PANEL:
-    return {
-      ...prevState,
-      sidePanelIsOpen: false,
-    }
-  case uiActionShowSidePanelConnectivity.type:
-  case uiStateExpandSidePanel.type:
-  case EXPAND_SIDE_PANEL_CURRENT_VIEW:
-    return {
-      ...prevState,
-      sidePanelExploreCurrentViewIsOpen: true,
-    }
-  case uiStateCollapseSidePanel.type:
-  case COLLAPSE_SIDE_PANEL_CURRENT_VIEW:
-    return {
-      ...prevState,
-      sidePanelExploreCurrentViewIsOpen: false,
-    }
-
-  case AGREE_COOKIE: {
-    /**
-       * TODO replace with server side logic
-       */
-    localStorage.setItem(LOCAL_STORAGE_CONST.AGREE_COOKIE, COOKIE_VERSION)
-    return {
-      ...prevState,
-      agreedCookies: true,
-    }
-  }
-  case AGREE_KG_TOS: {
-    /**
-       * TODO replace with server side logic
-       */
-    localStorage.setItem(LOCAL_STORAGE_CONST.AGREE_KG_TOS, KG_TOS_VERSION)
-    return {
-      ...prevState,
-      agreedKgTos: true,
-    }
-  }
-  case GENERAL_ACTION_TYPES.APPLY_STATE: {
-    const { uiState } = (action as any).state
-    return uiState
-  }
-  default: return prevState
-  }
-}
-
-// must export a named function for aot compilation
-// see https://github.com/angular/angular/issues/15587
-// https://github.com/amcdnl/ngrx-actions/issues/23
-// or just google for:
-//
-// angular function expressions are not supported in decorators
-
-const defaultStateStore = getStateStore()
-
-export function stateStore(state, action) {
-  return defaultStateStore(state, action)
-}
-
-export interface ActionInterface extends Action {
-  segment: any | number
-  landmark: any
-  focusedSidePanel?: string
-  segments?: Array<{
-    layer: {
-      name: string
-    }
-    segment: any | null
-  }>
-  snackbarMessage: string
-
-  bottomSheetTemplate: TemplateRef<any>
-
-  payload: any
-}
-
-@Injectable({
-  providedIn: 'root',
-})
-
-export class UiStateUseEffect implements OnDestroy{
-
-  private subscriptions: Subscription[] = []
-
-  private bottomSheetRef: MatBottomSheetRef
-
-  constructor(
-    store$: Store<IavRootStoreInterface>,
-    actions$: Actions,
-    bottomSheet: MatBottomSheet
-  ) {
-    
-    this.subscriptions.push(
-      actions$.pipe(
-        ofType(uiStateShowBottomSheet.type)
-      ).subscribe(({ bottomSheetTemplate, config }) => {
-        if (!bottomSheetTemplate) {
-          if (this.bottomSheetRef) {
-            this.bottomSheetRef.dismiss()
-            this.bottomSheetRef = null
-          }
-        } else {
-          this.bottomSheetRef = bottomSheet.open(bottomSheetTemplate, config)
-          this.bottomSheetRef.afterDismissed().subscribe(() => {
-            this.bottomSheetRef = null
-          })
-        }
-      })
-    )
-  }
-
-  ngOnDestroy(){
-    while(this.subscriptions.length > 0) {
-      this.subscriptions.pop().unsubscribe()
-    }
-  }
-}
-
-export const MOUSE_OVER_SEGMENT = `MOUSE_OVER_SEGMENT`
-
-export const CLOSE_SIDE_PANEL = `CLOSE_SIDE_PANEL`
-export const OPEN_SIDE_PANEL = `OPEN_SIDE_PANEL`
-export const COLLAPSE_SIDE_PANEL_CURRENT_VIEW = `COLLAPSE_SIDE_PANEL_CURRENT_VIEW`
-export const EXPAND_SIDE_PANEL_CURRENT_VIEW = `EXPAND_SIDE_PANEL_CURRENT_VIEW`
-
-export const AGREE_COOKIE = `AGREE_COOKIE`
-export const AGREE_KG_TOS = `AGREE_KG_TOS`
-
-export const SNACKBAR_MESSAGE = uiActionSnackbarMessage.type
-export const SHOW_BOTTOM_SHEET = `SHOW_BOTTOM_SHEET`
diff --git a/src/services/state/uiState/selectors.ts b/src/services/state/uiState/selectors.ts
deleted file mode 100644
index 9d48faded..000000000
--- a/src/services/state/uiState/selectors.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { createSelector } from "@ngrx/store";
-import { IUiState } from './common'
-
-export const uiStatePreviewingDatasetFilesSelector = createSelector(
-  state => state['uiState'],
-  (uiState: IUiState) => uiState['previewingDatasetFiles']
-)
-
-export const uiStateMouseOverLandmarkSelector = createSelector(
-  state => state['uiState'],
-  uiState => uiState['mouseOverLandmark'] as string
-)
-
-export const uiStateMouseoverUserLandmark = createSelector(
-  state => state['uiState'],
-  uiState => uiState['mouseOverUserLandmark']
-)
diff --git a/src/services/state/uiState/ui.effects.ts b/src/services/state/uiState/ui.effects.ts
deleted file mode 100644
index 128655ad5..000000000
--- a/src/services/state/uiState/ui.effects.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { Injectable, OnDestroy } from "@angular/core";
-import { MatSnackBar } from "@angular/material/snack-bar";
-import { Actions, ofType } from "@ngrx/effects";
-import { Subscription } from "rxjs";
-import { generalActionError } from "src/services/stateStore.helper";
-
-@Injectable({
-  providedIn: 'root'
-})
-
-export class UiEffects implements OnDestroy{
-
-  private subscriptions: Subscription[] = []
-
-  constructor(
-    private actions$: Actions,
-    snackBar: MatSnackBar
-  ){
-    this.subscriptions.push(
-      this.actions$.pipe(
-        ofType(generalActionError.type)
-      ).subscribe((payload: any) => {
-        if (!payload.message) console.log(payload)
-        snackBar.open(payload.message || `Error: cannot complete your action.`, 'Dismiss', { duration: 5000 })
-      })
-    )
-  }
-
-  ngOnDestroy(){
-    while (this.subscriptions.length > 0) this.subscriptions.pop().unsubscribe()
-  }
-}
diff --git a/src/services/state/userConfigState.store.ts b/src/services/state/userConfigState.store.ts
deleted file mode 100644
index f5906c02c..000000000
--- a/src/services/state/userConfigState.store.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-import { Injectable, OnDestroy } from "@angular/core";
-import { Actions, createEffect, Effect, ofType } from "@ngrx/effects";
-import { Action, createAction, createReducer, props, select, Store, on, createSelector } from "@ngrx/store";
-import { of, Subscription } from "rxjs";
-import { catchError, filter, map } from "rxjs/operators";
-import { LOCAL_STORAGE_CONST } from "src/util//constants";
-// Get around the problem of importing duplicated string (ACTION_TYPES), even using ES6 alias seems to trip up the compiler
-// TODO file bug and reverse
-import { HttpClient } from "@angular/common/http";
-import { PureContantService } from "src/util";
-import * as stateCtrl from "src/state"
-
-interface ICsp{
-  'connect-src'?: string[]
-  'script-src'?: string[]
-}
-
-export interface StateInterface {
-  savedRegionsSelection: RegionSelection[]
-  /**
-   * plugin csp - currently store in localStorage
-   * if user log in, store in user profile
-   */
-  pluginCsp: {
-    /**
-     * key === plugin version id 
-     */
-    [key: string]: ICsp
-  }
-}
-
-export interface RegionSelection {
-  templateSelected: any
-  parcellationSelected: any
-  regionsSelected: any[]
-  name: string
-  id: string
-}
-
-/**
- * for serialisation into local storage/database
- */
-interface SimpleRegionSelection {
-  id: string
-  name: string
-  tName: string
-  pName: string
-  rSelected: string[]
-}
-
-interface UserConfigAction extends Action {
-  config?: Partial<StateInterface>
-  payload?: any
-}
-
-export const defaultState: StateInterface = {
-  savedRegionsSelection: [],
-  pluginCsp: {}
-}
-
-export const selectorAllPluginsCspPermission = createSelector(
-  (state: any) => state.userConfigState,
-  userConfigState => userConfigState.pluginCsp
-)
-
-export const actionUpdatePluginCsp = createAction(
-  `[userConfig] updatePluginCspPermission`,
-  props<{
-    payload: {
-      [key: string]: ICsp
-    }
-  }>()
-)
-
-export const ACTION_TYPES = {
-  UPDATE_REGIONS_SELECTION: 'UPDATE_REGIONS_SELECTION',
-}
-
-
-export const userConfigReducer = createReducer(
-  defaultState,
-  on(actionUpdatePluginCsp, (state, { payload }) => {
-    return {
-      ...state,
-      pluginCsp: payload
-    }
-  })
-)
-
-@Injectable({
-  providedIn: 'root',
-})
-export class UserConfigStateUseEffect implements OnDestroy {
-
-  private subscriptions: Subscription[] = []
-
-  storeUseMobileInLocalStorage = createEffect(() => this.actions$.pipe(
-    ofType(stateCtrl.userInterface.actions.useModileUi),
-    map(({ flag }) => {
-      window.localStorage.setItem(LOCAL_STORAGE_CONST.MOBILE_UI, JSON.stringify(flag))
-    })
-  ), { dispatch: false })
-
-  constructor(
-    private actions$: Actions,
-    private store$: Store<any>,
-    private http: HttpClient,
-    private constantSvc: PureContantService,
-  ) {
-
-    this.subscriptions.push(
-      this.store$.pipe(
-        select('viewerConfigState'),
-      ).subscribe(({ gpuLimit, animation }) => {
-
-        if (gpuLimit) {
-          window.localStorage.setItem(LOCAL_STORAGE_CONST.GPU_LIMIT, gpuLimit.toString())
-        }
-        if (typeof animation !== 'undefined' && animation !== null) {
-          window.localStorage.setItem(LOCAL_STORAGE_CONST.ANIMATION, animation.toString())
-        }
-      }),
-    )
-  }
-
-  public ngOnDestroy() {
-    while (this.subscriptions.length > 0) {
-      this.subscriptions.pop().unsubscribe()
-    }
-  }
-
-
-  @Effect()
-  public setInitPluginPermission$ = this.http.get(`${this.constantSvc.backendUrl}user/pluginPermissions`, {
-    responseType: 'json'
-  }).pipe(
-    /**
-     * TODO show warning?
-     */
-    catchError(() => of({})),
-    map((json: any) => actionUpdatePluginCsp({ payload: json }))
-  )
-}
diff --git a/src/services/state/viewerConfig.store.ts b/src/services/state/viewerConfig.store.ts
deleted file mode 100644
index 650ba69c8..000000000
--- a/src/services/state/viewerConfig.store.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import { Action } from "@ngrx/store";
-import { LOCAL_STORAGE_CONST } from "src/util/constants";
-
-import { IViewerConfigState as StateInterface } from './viewerConfig.store.helper'
-export { StateInterface }
-
-interface ViewerConfigurationAction extends Action {
-  config: Partial<StateInterface>
-  payload: any
-}
-
-export const CONFIG_CONSTANTS = {
-  /**
-   * byets
-   */
-  gpuLimitMin: 1e8,
-  gpuLimitMax: 1e9,
-  defaultGpuLimit: 1e9,
-  defaultAnimation: true,
-}
-
-export const VIEWER_CONFIG_ACTION_TYPES = {
-  SET_ANIMATION: `SET_ANIMATION`,
-  UPDATE_CONFIG: `UPDATE_CONFIG`,
-}
-
-// get gpu limit
-const lsGpuLimit = localStorage.getItem(LOCAL_STORAGE_CONST.GPU_LIMIT)
-const lsAnimationFlag = localStorage.getItem(LOCAL_STORAGE_CONST.ANIMATION)
-const gpuLimit = lsGpuLimit && !isNaN(Number(lsGpuLimit))
-  ? Number(lsGpuLimit)
-  : CONFIG_CONSTANTS.defaultGpuLimit
-
-// get animation flag
-const animation = lsAnimationFlag && lsAnimationFlag === 'true'
-  ? true
-  : lsAnimationFlag === 'false'
-    ? false
-    : CONFIG_CONSTANTS.defaultAnimation
-
-// get mobile ui setting
-// UA sniff only if not useMobileUI not explicitly set
-const getIsMobile = () => {
-  // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/maxTouchPoints
-  // CC0 or MIT
-  // msMaxTouchPoints is not needed, since IE is not supported
-  return 'maxTouchPoints' in navigator && navigator.maxTouchPoints > 0
-}
-const useMobileUIStroageValue = window && window.localStorage && window.localStorage.getItem(LOCAL_STORAGE_CONST.MOBILE_UI)
-
-export const defaultState: StateInterface = {
-  animation,
-  gpuLimit,
-  useMobileUI: (useMobileUIStroageValue && useMobileUIStroageValue === 'true') || getIsMobile(),
-}
-
-export const getStateStore = ({ state = defaultState } = {}) => (prevState: StateInterface = state, action: ViewerConfigurationAction) => {
-  switch (action.type) {
-  case VIEWER_CONFIG_ACTION_TYPES.UPDATE_CONFIG:
-    return {
-      ...prevState,
-      ...action.config,
-    }
-  default: return prevState
-  }
-}
-
-// must export a named function for aot compilation
-// see https://github.com/angular/angular/issues/15587
-// https://github.com/amcdnl/ngrx-actions/issues/23
-// or just google for:
-//
-// angular function expressions are not supported in decorators
-
-const defaultStateStore = getStateStore()
-
-export function stateStore(state, action) {
-  return defaultStateStore(state, action)
-}
diff --git a/src/services/state/viewerConfig/selectors.ts b/src/services/state/viewerConfig/selectors.ts
deleted file mode 100644
index 4b69c0e58..000000000
--- a/src/services/state/viewerConfig/selectors.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { createSelector } from "@ngrx/store";
-
-export const selectViewerConfigAnimationFlag = createSelector(
-  state => state['viewerConfigState'],
-  viewerConfigState => viewerConfigState['animation']
-)
diff --git a/src/services/stateStore.service.ts b/src/services/stateStore.service.ts
index ceef16525..e69de29bb 100644
--- a/src/services/stateStore.service.ts
+++ b/src/services/stateStore.service.ts
@@ -1,131 +0,0 @@
-import { filter } from 'rxjs/operators';
-
-export { getNgIds } from 'src/util/fn'
-
-import {
-  ActionInterface as NgViewerActionInterface,
-  defaultState as ngViewerDefaultState,
-  StateInterface as NgViewerStateInterface,
-  stateStore as ngViewerState,
-} from './state/ngViewerState.store'
-import {
-  ActionInterface as UIActionInterface,
-  defaultState as uiDefaultState,
-  IUiState,
-  stateStore as uiState,
-} from './state/uiState.store'
-import {
-  ACTION_TYPES as USER_CONFIG_ACTION_TYPES,
-  defaultState as userConfigDefaultState,
-  StateInterface as UserConfigStateInterface,
-  userConfigReducer as userConfigState,
-} from './state/userConfigState.store'
-import {
-  defaultState as viewerConfigDefaultState,
-  StateInterface as ViewerConfigStateInterface,
-  stateStore as viewerConfigState,
-} from './state/viewerConfig.store'
-
-
-export { viewerConfigState }
-export { NgViewerStateInterface, NgViewerActionInterface, ngViewerState }
-export { IUiState, UIActionInterface, uiState }
-export { userConfigState,  USER_CONFIG_ACTION_TYPES}
-
-export { MOUSE_OVER_SEGMENT, OPEN_SIDE_PANEL, COLLAPSE_SIDE_PANEL_CURRENT_VIEW, EXPAND_SIDE_PANEL_CURRENT_VIEW } from './state/uiState.store'
-export { UserConfigStateUseEffect } from './state/userConfigState.store'
-
-export { GENERAL_ACTION_TYPES, generalActionError } from './stateStore.helper'
-
-// TODO deprecate
-export function safeFilter(key: string) {
-  return filter((state: any) =>
-    (typeof state !== 'undefined' && state !== null) &&
-    typeof state[key] !== 'undefined' && state[key] !== null)
-}
-
-export function getMultiNgIdsRegionsLabelIndexMap(parcellation: any = {}, inheritAttrsOpt: any = { ngId: 'root' }): Map<string, Map<number, any>> {
-  const map: Map<string, Map<number, any>> = new Map()
-  
-  const inheritAttrs = Object.keys(inheritAttrsOpt)
-  if (inheritAttrs.indexOf('children') >=0 ) throw new Error(`children attr cannot be inherited`)
-
-  const processRegion = (region: any) => {
-    const { ngId: rNgId } = region
-    const existingMap = map.get(rNgId)
-    const labelIndex = Number(region.labelIndex)
-    if (labelIndex) {
-      if (!existingMap) {
-        const newMap = new Map()
-        newMap.set(labelIndex, region)
-        map.set(rNgId, newMap)
-      } else {
-        existingMap.set(labelIndex, region)
-      }
-    }
-
-    if (region.children && Array.isArray(region.children)) {
-      for (const r of region.children) {
-        const copiedRegion = { ...r }
-        for (const attr of inheritAttrs){
-          copiedRegion[attr] = copiedRegion[attr] || region[attr] || parcellation[attr]
-        }
-        processRegion(copiedRegion)
-      }
-    }
-  }
-
-  if (!parcellation) throw new Error(`parcellation needs to be defined`)
-  if (!parcellation.regions) throw new Error(`parcellation.regions needs to be defined`)
-  if (!Array.isArray(parcellation.regions)) throw new Error(`parcellation.regions needs to be an array`)
-
-  for (const region of parcellation.regions){
-    const copiedregion = { ...region }
-    for (const attr of inheritAttrs){
-      copiedregion[attr] = copiedregion[attr] || parcellation[attr]
-    }
-    processRegion(copiedregion)
-  }
-
-  return map
-}
-
-/**
- * labelIndexMap maps label index to region
- * @TODO deprecate
- */
-export function getLabelIndexMap(regions: any[]): Map<number, any> {
-  const returnMap = new Map()
-
-  const reduceRegions = (rs: any[]) => {
-    rs.forEach(region => {
-      if ( region.labelIndex ) { returnMap.set(Number(region.labelIndex),
-        Object.assign({}, region, {labelIndex : Number(region.labelIndex)}))
-      }
-      if ( region.children && region.children.constructor === Array ) { reduceRegions(region.children) }
-    })
-  }
-
-  if (regions && regions.forEach) { reduceRegions(regions) }
-  return returnMap
-}
-
-
-// @TODO deprecate
-export function isDefined(obj) {
-  return typeof obj !== 'undefined' && obj !== null
-}
-
-export interface IavRootStoreInterface {
-  viewerConfigState: ViewerConfigStateInterface
-  ngViewerState: NgViewerStateInterface
-  uiState: IUiState
-  userConfigState: UserConfigStateInterface
-}
-
-export const defaultRootState: any = {
-  ngViewerState: ngViewerDefaultState,
-  uiState: uiDefaultState,
-  userConfigState: userConfigDefaultState,
-  viewerConfigState: viewerConfigDefaultState,
-}
diff --git a/src/state/atlasAppearance/action.ts b/src/state/atlasAppearance/action.ts
index d9065e07c..27461e622 100644
--- a/src/state/atlasAppearance/action.ts
+++ b/src/state/atlasAppearance/action.ts
@@ -7,3 +7,17 @@ export const overwriteColorMap = createAction(
     colormap: Record<string, number[]>
   }>()
 )
+
+export const setOctantRemoval = createAction(
+  `${nameSpace} setOctantRemoval`,
+  props<{
+    flag: boolean
+  }>()
+)
+
+export const setShowDelineation = createAction(
+  `${nameSpace} setShowDelineation`,
+  props<{
+    flag: boolean
+  }>()
+)
\ No newline at end of file
diff --git a/src/state/atlasAppearance/index.ts b/src/state/atlasAppearance/index.ts
index cf777e1fe..bbbe62696 100644
--- a/src/state/atlasAppearance/index.ts
+++ b/src/state/atlasAppearance/index.ts
@@ -1,3 +1,4 @@
 export * as actions from "./action"
 export * as selectors from "./selector"
+export { nameSpace } from "./const"
 export { reducer } from "./store"
\ No newline at end of file
diff --git a/src/state/atlasAppearance/selector.ts b/src/state/atlasAppearance/selector.ts
index c43c61978..842d2db0f 100644
--- a/src/state/atlasAppearance/selector.ts
+++ b/src/state/atlasAppearance/selector.ts
@@ -7,4 +7,14 @@ const selectStore = state => state[nameSpace] as AtlasAppearanceStore
 export const getOverwrittenColormap = createSelector(
   selectStore,
   state => state.overwrittenColormap
+)
+
+export const octantRemoval = createSelector(
+  selectStore,
+  state => state.octantRemoval
+)
+
+export const showDelineation = createSelector(
+  selectStore,
+  state => state.showDelineation
 )
\ No newline at end of file
diff --git a/src/state/atlasAppearance/store.ts b/src/state/atlasAppearance/store.ts
index 817603c93..476da0558 100644
--- a/src/state/atlasAppearance/store.ts
+++ b/src/state/atlasAppearance/store.ts
@@ -3,10 +3,14 @@ import * as actions from "./action"
 
 export type AtlasAppearanceStore = {
   overwrittenColormap: Record<string, number[]>
+  octantRemoval: boolean
+  showDelineation: boolean
 }
 
 const defaultState: AtlasAppearanceStore = {
-  overwrittenColormap: null
+  overwrittenColormap: null,
+  octantRemoval: true,
+  showDelineation: true,
 }
 
 export const reducer = createReducer(
@@ -19,5 +23,23 @@ export const reducer = createReducer(
         overwrittenColormap: colormap
       }
     }
-  )
+  ),
+  on(
+    actions.setOctantRemoval,
+    (state, { flag }) => {
+      return {
+        ...state,
+        octantRemoval: flag
+      }
+    }
+  ),
+  on(
+    actions.setShowDelineation,
+    (state, { flag }) => {
+      return {
+        ...state,
+        showDelineation: flag
+      }
+    }
+  ),
 )
diff --git a/src/state/effects/TODO.md b/src/state/effects/TODO.md
new file mode 100644
index 000000000..0fd8e3c71
--- /dev/null
+++ b/src/state/effects/TODO.md
@@ -0,0 +1,3 @@
+# TODO
+
+migrate ASAP
\ No newline at end of file
diff --git a/src/state/index.ts b/src/state/index.ts
index 856798548..b8523aff3 100644
--- a/src/state/index.ts
+++ b/src/state/index.ts
@@ -1,8 +1,51 @@
+import { ActionReducer, StoreModule } from "@ngrx/store"
+
 export { StateModule } from "./state.module"
 
-export * as atlasSelection from "./atlasSelection"
-export * as annotation from "./annotations"
-export * as userInterface from "./userInterface"
-export * as atlasAppearance from "./atlasAppearance"
-export * as plugins from "./plugins"
-export * as userInteraction from "./userInteraction"
+import * as atlasSelection from "./atlasSelection"
+import * as annotation from "./annotations"
+import * as userInterface from "./userInterface"
+import * as atlasAppearance from "./atlasAppearance"
+import * as plugins from "./plugins"
+import * as userInteraction from "./userInteraction"
+import * as userPreference from "./userPreference"
+import { EffectsModule } from "@ngrx/effects"
+
+export {
+  atlasSelection,
+  annotation,
+  userInterface,
+  atlasAppearance,
+  plugins,
+  userInteraction,
+  userPreference,
+}
+
+export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
+  return function(state, action) {
+    console.log('state', state);
+    console.log('action', action);
+ 
+    return reducer(state, action);
+  };
+}
+
+export const RootStoreModule = StoreModule.forRoot({
+  [userPreference.nameSpace]: userPreference.reducer,
+  [atlasSelection.nameSpace]: atlasSelection.reducer,
+  [userInterface.nameSpace]: userInterface.reducer,
+  [userInteraction.nameSpace]: userInteraction.reducer,
+  [annotation.nameSpace]: annotation.reducer,
+  [plugins.nameSpace]: plugins.reducer,
+  [atlasAppearance.nameSpace]: atlasAppearance.reducer,
+},{
+  metaReducers: [ 
+    // debug,
+  ]
+})
+
+export const RootEffecsModule = EffectsModule.forRoot([
+  plugins.Effects,
+  atlasSelection.Effect,
+  userInterface.Effects,
+])
\ No newline at end of file
diff --git a/src/state/userInterface/actions.ts b/src/state/userInterface/actions.ts
index 1e80ac94a..e423f261e 100644
--- a/src/state/userInterface/actions.ts
+++ b/src/state/userInterface/actions.ts
@@ -2,14 +2,8 @@ import { TemplateRef } from "@angular/core";
 import { MatBottomSheetConfig } from "@angular/material/bottom-sheet";
 import { MatSnackBarConfig } from "@angular/material/snack-bar";
 import { createAction, props } from "@ngrx/store";
-import { nameSpace } from "./const"
+import { nameSpace, PanelMode } from "./const"
 
-export const useModileUi = createAction(
-  `${nameSpace} useMobileUi`,
-  props<{
-    flag: boolean
-  }>()
-)
 
 export const openSidePanel = createAction(
   `${nameSpace} openSidePanel`
@@ -38,3 +32,29 @@ export const snackBarMessage = createAction(
     config?: MatSnackBarConfig
   }>()
 )
+
+
+export const setPanelMode = createAction(
+  `${nameSpace} setPanelMode`,
+  props<{
+    panelMode: PanelMode
+  }>()
+)
+
+export const cyclePanelMode = createAction(
+  `${nameSpace} cyclePanelMode`
+)
+
+export const toggleMaximiseView = createAction(
+  `${nameSpace} toggleMaximiseView`,
+  props<{
+    targetIndex: number
+  }>()
+)
+
+export const setPanelOrder = createAction(
+  `${nameSpace} setPanelOrder`,
+  props<{
+    order: string
+  }>()
+)
\ No newline at end of file
diff --git a/src/state/userInterface/const.ts b/src/state/userInterface/const.ts
index 1033ee368..929102239 100644
--- a/src/state/userInterface/const.ts
+++ b/src/state/userInterface/const.ts
@@ -1 +1,5 @@
-export const nameSpace = `[state.ui]`
\ No newline at end of file
+export const nameSpace = `[state.ui]`
+export type PanelMode = 'FOUR_PANEL'
+| 'V_ONE_THREE'
+| 'H_ONE_THREE'
+| 'SINGLE_PANEL'
\ No newline at end of file
diff --git a/src/state/userInterface/effects.ts b/src/state/userInterface/effects.ts
index 254cf22a4..d1472dc5d 100644
--- a/src/state/userInterface/effects.ts
+++ b/src/state/userInterface/effects.ts
@@ -3,7 +3,10 @@ import { MatBottomSheet, MatBottomSheetRef } from "@angular/material/bottom-shee
 import { MatSnackBar } from "@angular/material/snack-bar";
 import { Actions, createEffect, ofType } from "@ngrx/effects";
 import { select, Store } from "@ngrx/store";
-import { filter, map, mapTo, pairwise, startWith } from "rxjs/operators";
+import { of } from "rxjs";
+import { filter, map, mapTo, pairwise, startWith, switchMap, tap, withLatestFrom } from "rxjs/operators";
+import { generalActionError } from "src/services/stateStore.helper";
+import { userInterface } from "..";
 import { selectors } from "../atlasSelection"
 import * as actions from "./actions"
 
@@ -26,31 +29,71 @@ export class Effects{
     mapTo(actions.expandSidePanelDetailView())
   ))
 
-  private bottomSheetRef: MatBottomSheetRef
-  constructor(
-    private store: Store,
-    private action: Actions,
-    bottomsheet: MatBottomSheet,
-    snackbar: MatSnackBar,
-  ){
-    this.action.pipe(
-      ofType(actions.showBottomSheet)
-    ).subscribe(({ template, config }) => {
+  onGeneralError = createEffect(() => this.action.pipe(
+    ofType(generalActionError.type),
+    tap(payload => {
+      this.snackbar.open(
+        (payload as any)?.message || `Error: cannot complete your action`,
+        'Dismiss',
+        { duration: 5000 }
+      )
+    })
+  ), { dispatch: false })
+
+  onShowBottomSheet = createEffect(() => this.action.pipe(
+    ofType(actions.showBottomSheet),
+    tap(({ template, config }) => {
+
       if (this.bottomSheetRef) {
         this.bottomSheetRef.dismiss()
       }
-      this.bottomSheetRef = bottomsheet.open(
+      this.bottomSheetRef = this.bottomsheet.open(
         template,
         config
       )
       this.bottomSheetRef.afterDismissed().subscribe(() => this.bottomSheetRef = null)
     })
+  ), { dispatch: false })
 
-    this.action.pipe(
-      ofType(actions.snackBarMessage)
-    ).subscribe(({ message, config }) => {
+  onSnackbarMessage = createEffect(() => this.action.pipe(
+    ofType(actions.snackBarMessage),
+    tap(({ message, config }) => {
       const _config = config || { duration: 5000 }
-      snackbar.open(message, "Dismiss", _config)
+      this.snackbar.open(message, "Dismiss", _config)
+    })
+  ), { dispatch: false })
+
+  onMaximiseView = createEffect(() => this.action.pipe(
+    ofType(actions.toggleMaximiseView),
+    withLatestFrom(
+      this.store.pipe(
+        select(userInterface.selectors.panelMode),
+      )
+    ),
+    switchMap(([ { targetIndex }, panelMode ]) => {
+      const newMode: userInterface.PanelMode = panelMode === "FOUR_PANEL"
+        ? "SINGLE_PANEL"
+        : "FOUR_PANEL"
+      const newOrder = newMode === "FOUR_PANEL"
+        ? "0123"
+        : "0123".split("").map(v => ((Number(v) + targetIndex) % 4).toString()).join("")
+      return of(
+        userInterface.actions.setPanelMode({
+          panelMode: newMode
+        }),
+        userInterface.actions.setPanelOrder({
+          order: newOrder
+        })
+      )
     })
+  ))
+
+  private bottomSheetRef: MatBottomSheetRef
+  constructor(
+    private store: Store,
+    private action: Actions,
+    private bottomsheet: MatBottomSheet,
+    private snackbar: MatSnackBar,
+  ){
   }
 }
diff --git a/src/state/userInterface/index.ts b/src/state/userInterface/index.ts
index f0b980136..cff6971a4 100644
--- a/src/state/userInterface/index.ts
+++ b/src/state/userInterface/index.ts
@@ -1,4 +1,5 @@
 export * as actions from "./actions"
 export * as selectors from "./selectors"
-export { nameSpace } from "./const"
-export { reducer } from "./store"
\ No newline at end of file
+export { nameSpace, PanelMode } from "./const"
+export { reducer } from "./store"
+export { Effects } from "./effects"
diff --git a/src/state/userInterface/selectors.ts b/src/state/userInterface/selectors.ts
index 15705846f..b9b3001d1 100644
--- a/src/state/userInterface/selectors.ts
+++ b/src/state/userInterface/selectors.ts
@@ -4,7 +4,12 @@ import { UiStore } from "./store"
 
 const selectStore = state => state[nameSpace] as UiStore
 
-export const useMobileUi = createSelector(
+export const panelMode = createSelector(
   selectStore,
-  state => state.useMobileUi
+  state => state.panelMode
+)
+
+export const panelOrder = createSelector(
+  selectStore,
+  state => state.panelOrder
 )
diff --git a/src/state/userInterface/store.ts b/src/state/userInterface/store.ts
index aabe2f556..3fcea7d7e 100644
--- a/src/state/userInterface/store.ts
+++ b/src/state/userInterface/store.ts
@@ -1,23 +1,39 @@
 import { createReducer, on } from "@ngrx/store";
 import * as actions from "./actions"
+import { PanelMode } from "./const"
 
 export type UiStore = {
-  useMobileUi: boolean
+  panelMode: PanelMode
+  panelOrder: string // permutation of 0123
+  octantRemoval: boolean
+  showDelineation: boolean
 }
 
 const defaultStore: UiStore = {
-  useMobileUi: false
+  panelMode: 'FOUR_PANEL',
+  panelOrder: '0123',
+  octantRemoval: false,
+  showDelineation: true,
 }
 
 export const reducer = createReducer(
   defaultStore,
   on(
-    actions.useModileUi,
-    (state, { flag }) => {
+    actions.setPanelMode,
+    (state, { panelMode }) => {
       return {
         ...state,
-        useMobileUi: flag
+        panelMode
       }
     }
   ),
+  on(
+    actions.setPanelOrder,
+    (state, { order }) => {
+      return {
+        ...state,
+        panelOrder: order
+      }
+    }
+  )
 )
diff --git a/src/state/userPreference/actions.ts b/src/state/userPreference/actions.ts
new file mode 100644
index 000000000..ee6f8f306
--- /dev/null
+++ b/src/state/userPreference/actions.ts
@@ -0,0 +1,39 @@
+import { createAction, props } from "@ngrx/store"
+import { nameSpace, CSP } from "./const"
+
+export const setAnimationFlag = createAction(
+  `${nameSpace} setAnimationFlag`,
+  props<{
+    flag: boolean
+  }>()
+)
+
+export const setGpuLimit = createAction(
+  `${nameSpace} setGpuLimit`,
+  props<{
+    limit: number
+  }>()
+)
+
+export const useMobileUi = createAction(
+  `${nameSpace} setUseMobileUi`,
+  props<{
+    flag: boolean
+  }>()
+)
+
+export const agreeCookie = createAction(
+  `${nameSpace} agreeCookie`
+)
+
+export const agreeKgTos = createAction(
+  `${nameSpace} agreeKgTos`
+)
+
+export const updateCsp = createAction(
+  `${nameSpace} updateCsp`,
+  props<{
+    name: string
+    csp: CSP
+  }>()
+)
\ No newline at end of file
diff --git a/src/state/userPreference/const.ts b/src/state/userPreference/const.ts
new file mode 100644
index 000000000..c9a9daba8
--- /dev/null
+++ b/src/state/userPreference/const.ts
@@ -0,0 +1,9 @@
+export const nameSpace = `[userPreference]`
+
+export const maxGpuLimit = 1e9
+export const minGpuLimit = 1e8
+
+export interface CSP{
+  'connect-src'?: string[]
+  'script-src'?: string[]
+}
\ No newline at end of file
diff --git a/src/state/userPreference/effects.ts b/src/state/userPreference/effects.ts
new file mode 100644
index 000000000..29aaf3710
--- /dev/null
+++ b/src/state/userPreference/effects.ts
@@ -0,0 +1,48 @@
+import { HttpClient } from "@angular/common/http";
+import { Injectable } from "@angular/core";
+import { Actions, createEffect, ofType } from "@ngrx/effects";
+import { map } from "rxjs/operators";
+import { COOKIE_VERSION, KG_TOS_VERSION, LOCAL_STORAGE_CONST } from "src/util/constants";
+import * as actions from "./actions"
+
+@Injectable()
+export class Effects{
+
+  onUseMobileUi = createEffect(() => this.actions$.pipe(
+    ofType(actions.useMobileUi),
+    map(({ flag }) => {
+      window.localStorage.setItem(LOCAL_STORAGE_CONST.MOBILE_UI, JSON.stringify(flag))
+    })
+  ), { dispatch: false })
+  
+  onSetGpuLimit = createEffect(() => this.actions$.pipe(
+    ofType(actions.setGpuLimit),
+    map(({ limit }) => {
+      localStorage.setItem(LOCAL_STORAGE_CONST.GPU_LIMIT, limit.toString())
+    })
+  ), { dispatch: false })
+
+  onAgreeCookie = createEffect(() => this.actions$.pipe(
+    ofType(actions.agreeCookie),
+    map(() => {
+      localStorage.setItem(LOCAL_STORAGE_CONST.AGREE_COOKIE, COOKIE_VERSION)
+    })
+  ), { dispatch: false })
+
+  onAgreeKgTos = createEffect(() => this.actions$.pipe(
+    ofType(actions.agreeKgTos),
+    map(() => {
+      localStorage.setItem(LOCAL_STORAGE_CONST.AGREE_KG_TOS, KG_TOS_VERSION)
+    })
+  ), { dispatch: false })
+
+  // TODO setup on startup get user csp
+  // this.http.get(`${this.constantSvc.backendUrl}user/pluginPermissions`)
+  // onStartUpGetCsp
+
+  constructor(
+    private actions$: Actions,
+    private http: HttpClient,
+  ){
+  }
+}
diff --git a/src/state/userPreference/index.ts b/src/state/userPreference/index.ts
new file mode 100644
index 000000000..e8e485b4d
--- /dev/null
+++ b/src/state/userPreference/index.ts
@@ -0,0 +1,4 @@
+export { UserPreference, defaultUserPreferenceStore, reducer } from "./store"
+export { nameSpace } from "./const"
+export * as actions from "./actions"
+export * as selectors from "./selectors"
diff --git a/src/state/userPreference/selectors.ts b/src/state/userPreference/selectors.ts
new file mode 100644
index 000000000..608264fc6
--- /dev/null
+++ b/src/state/userPreference/selectors.ts
@@ -0,0 +1,35 @@
+import { createSelector } from "@ngrx/store"
+import { nameSpace } from "./const"
+import { UserPreference } from "./store"
+
+const storeSelector = store => store[nameSpace] as UserPreference
+
+export const useAnimation = createSelector(
+  storeSelector,
+  state => state.useAnimation
+)
+
+export const gpuLimit = createSelector(
+  storeSelector,
+  state => state.gpuLimit
+)
+
+export const useMobileUi = createSelector(
+  storeSelector,
+  state => state.useMobileUi
+)
+
+export const agreedToCookie = createSelector(
+  storeSelector,
+  store => store.agreeCookie
+)
+
+export const agreedToKgTos = createSelector(
+  storeSelector,
+  store => store.agreeKgTos
+)
+
+export const userCsp = createSelector(
+  storeSelector,
+  store => store.pluginCSP
+)
diff --git a/src/state/userPreference/store.ts b/src/state/userPreference/store.ts
new file mode 100644
index 000000000..b80d510d8
--- /dev/null
+++ b/src/state/userPreference/store.ts
@@ -0,0 +1,93 @@
+import { createReducer, on } from "@ngrx/store"
+import { COOKIE_VERSION, KG_TOS_VERSION, LOCAL_STORAGE_CONST } from "src/util/constants"
+import * as actions from "./actions"
+import { maxGpuLimit, CSP } from "./const"
+
+export const defaultGpuLimit = maxGpuLimit
+
+export type UserPreference = {
+  useMobileUi: boolean
+  gpuLimit: number
+  useAnimation: boolean
+  pluginCSP: Record<string, CSP>
+
+  agreeCookie: boolean
+  agreeKgTos: boolean
+}
+
+export const defaultUserPreferenceStore: UserPreference = {
+  useMobileUi: JSON.parse(localStorage.getItem(LOCAL_STORAGE_CONST.MOBILE_UI)),
+  gpuLimit: Number(localStorage.getItem(LOCAL_STORAGE_CONST.GPU_LIMIT)) || defaultGpuLimit,
+  useAnimation: !localStorage.getItem(LOCAL_STORAGE_CONST.ANIMATION),
+  pluginCSP: {},
+
+  agreeCookie: localStorage.getItem(LOCAL_STORAGE_CONST.AGREE_COOKIE) === COOKIE_VERSION,
+  agreeKgTos: localStorage.getItem(LOCAL_STORAGE_CONST.AGREE_KG_TOS) === KG_TOS_VERSION,
+}
+
+export const reducer = createReducer(
+  defaultUserPreferenceStore,
+  on(
+    actions.setAnimationFlag,
+    (state, { flag }) => {
+      if (flag) {
+        localStorage.removeItem(LOCAL_STORAGE_CONST.ANIMATION)
+      } else {
+        localStorage.setItem(LOCAL_STORAGE_CONST.ANIMATION, "false")
+      }
+      
+      return {
+        ...state,
+        useAnimation: flag
+      }
+    }
+  ),
+  on(
+    actions.setGpuLimit,
+    (state, { limit }) => {
+      return {
+        ...state,
+        gpuLimit: limit
+      }
+    }
+  ),
+  on(
+    actions.useMobileUi,
+    (state, { flag }) => {
+      return {
+        ...state,
+        useMobileUi: flag
+      }
+    }
+  ),
+  on(
+    actions.agreeCookie,
+    state => {
+      return {
+        ...state,
+        agreeCookie: true
+      }
+    }
+  ),
+  on(
+    actions.agreeKgTos,
+    state => {
+      return {
+        ...state,
+        agreeKgTos: true
+      }
+    }
+  ),
+  on(
+    actions.updateCsp,
+    (state, { name, csp }) => {
+      return {
+        ...state,
+        pluginCSP: {
+          ...state.pluginCSP,
+          [name]: csp
+        }
+      }
+    }
+  )
+)
diff --git a/src/ui/config/configCmp/config.component.ts b/src/ui/config/configCmp/config.component.ts
index ffc01128f..494403b61 100644
--- a/src/ui/config/configCmp/config.component.ts
+++ b/src/ui/config/configCmp/config.component.ts
@@ -2,18 +2,11 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
 import { select, Store } from '@ngrx/store';
 import { combineLatest, Observable, Subscription } from 'rxjs';
 import { debounceTime, distinctUntilChanged, map, startWith } from 'rxjs/operators';
-import { SUPPORTED_PANEL_MODES } from 'src/services/state/ngViewerState.store';
-import { ngViewerActionSetPanelOrder } from 'src/services/state/ngViewerState.store.helper';
-import { VIEWER_CONFIG_ACTION_TYPES, StateInterface as ViewerConfiguration } from 'src/services/state/viewerConfig.store'
-import { IavRootStoreInterface } from 'src/services/stateStore.service';
 import { isIdentityQuat } from 'src/viewerModule/nehuba/util';
-import {MatSlideToggleChange} from "@angular/material/slide-toggle";
-import {MatSliderChange} from "@angular/material/slider";
-import { PureContantService } from 'src/util';
-import { ngViewerActionSwitchPanelMode } from 'src/services/state/ngViewerState/actions';
-import { ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from 'src/services/state/ngViewerState/selectors';
-import { atlasSelection } from 'src/state';
-import * as stateCtrl from "src/state"
+import { MatSlideToggleChange } from "@angular/material/slide-toggle";
+import { MatSliderChange } from "@angular/material/slider";
+import { atlasSelection, userPreference, userInterface } from 'src/state';
+import { environment } from "src/environments/environment"
 
 const GPU_TOOLTIP = `Higher GPU usage can cause crashes on lower end machines`
 const ANIMATION_TOOLTIP = `Animation can cause slowdowns in lower end machines`
@@ -34,14 +27,25 @@ export class ConfigComponent implements OnInit, OnDestroy {
   public GPU_TOOLTIP = GPU_TOOLTIP
   public ANIMATION_TOOLTIP = ANIMATION_TOOLTIP
   public MOBILE_UI_TOOLTIP = MOBILE_UI_TOOLTIP
-  public supportedPanelModes = SUPPORTED_PANEL_MODES
+
+  public experimentalFlag = environment.EXPERIMENTAL_FEATURE_FLAG
+
+  public panelModes: Record<string, userInterface.PanelMode> = {
+    FOUR_PANEL: "FOUR_PANEL",
+    H_ONE_THREE: "H_ONE_THREE",
+    SINGLE_PANEL: "SINGLE_PANEL",
+    V_ONE_THREE: "V_ONE_THREE",
+  }
+
 
   /**
    * in MB
    */
   public gpuLimit$: Observable<number>
 
-  public useMobileUI$: Observable<boolean>
+  public useMobileUI$: Observable<boolean> = this.store.pipe(
+    select(userPreference.selectors.useMobileUi)
+  )
   public animationFlag$: Observable<boolean>
   private subscriptions: Subscription[] = []
 
@@ -57,31 +61,24 @@ export class ConfigComponent implements OnInit, OnDestroy {
   private viewerObliqueRotated$: Observable<boolean>
 
   constructor(
-    private store: Store<IavRootStoreInterface>,
-    private pureConstantService: PureContantService,
+    private store: Store<any>,
   ) {
 
-    this.useMobileUI$ = this.pureConstantService.useTouchUI$
-
     this.gpuLimit$ = this.store.pipe(
-      select('viewerConfigState'),
-      map((config: ViewerConfiguration) => config.gpuLimit),
-      distinctUntilChanged(),
+      select(userPreference.selectors.gpuLimit),
       map(v => v / 1e6),
     )
 
     this.animationFlag$ = this.store.pipe(
-      select('viewerConfigState'),
-      map((config: ViewerConfiguration) => config.animation),
+      select(userPreference.selectors.useAnimation)
     )
 
     this.panelMode$ = this.store.pipe(
-      select(ngViewerSelectorPanelMode),
-      startWith(SUPPORTED_PANEL_MODES[0]),
+      select(userInterface.selectors.panelMode)
     )
 
     this.panelOrder$ = this.store.pipe(
-      select(ngViewerSelectorPanelOrder),
+      select(userInterface.selectors.panelOrder),
     )
 
     this.viewerObliqueRotated$ = this.store.pipe(
@@ -117,7 +114,7 @@ export class ConfigComponent implements OnInit, OnDestroy {
   public toggleMobileUI(ev: MatSlideToggleChange) {
     const { checked } = ev
     this.store.dispatch(
-      stateCtrl.userInterface.actions.useModileUi({
+      userPreference.actions.useMobileUi({
         flag: checked
       })
     )
@@ -125,26 +122,25 @@ export class ConfigComponent implements OnInit, OnDestroy {
 
   public toggleAnimationFlag(ev: MatSlideToggleChange ) {
     const { checked } = ev
-    this.store.dispatch({
-      type: VIEWER_CONFIG_ACTION_TYPES.UPDATE_CONFIG,
-      config: {
-        animation: checked,
-      },
-    })
+    this.store.dispatch(
+      userPreference.actions.setAnimationFlag({
+        flag: checked
+      })
+    )
   }
 
   public handleMatSliderChange(ev: MatSliderChange) {
-    this.store.dispatch({
-      type: VIEWER_CONFIG_ACTION_TYPES.UPDATE_CONFIG,
-      config: {
-        gpuLimit: ev.value * 1e6,
-      },
-    })
+    this.store.dispatch(
+      userPreference.actions.setGpuLimit({
+        limit: ev.value * 1e6
+      })
+    )
   }
-  public usePanelMode(panelMode: string) {
+  public usePanelMode(panelMode: userInterface.PanelMode) {
+
     this.store.dispatch(
-      ngViewerActionSwitchPanelMode({
-        payload: { panelMode }
+      userInterface.actions.setPanelMode({
+        panelMode
       })
     )
   }
@@ -160,8 +156,8 @@ export class ConfigComponent implements OnInit, OnDestroy {
 
     [arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]]
     this.store.dispatch(
-      ngViewerActionSetPanelOrder({
-        payload: { panelOrder: arr.join('') }
+      userInterface.actions.setPanelOrder({
+        order: arr.join('')
       })
     )
   }
diff --git a/src/ui/config/configCmp/config.stories.ts b/src/ui/config/configCmp/config.stories.ts
new file mode 100644
index 000000000..f1aa0a63f
--- /dev/null
+++ b/src/ui/config/configCmp/config.stories.ts
@@ -0,0 +1,46 @@
+import { CommonModule } from "@angular/common"
+import { HttpClientModule } from "@angular/common/http"
+import { Meta, moduleMetadata, Story } from "@storybook/angular"
+import { provideDarkTheme } from "src/atlasComponents/sapi/stories.base"
+import { ConfigModule } from "../module"
+import { ConfigComponent } from "./config.component"
+import { userPreference, userInterface, atlasSelection } from "src/state"
+import { StoreModule } from "@ngrx/store"
+
+export default {
+  component: ConfigComponent,
+  decorators: [
+    moduleMetadata({
+      imports: [
+        CommonModule,
+        HttpClientModule,
+        ConfigModule,
+        StoreModule.forRoot({
+          [userPreference.nameSpace]: userPreference.reducer,
+          [userInterface.nameSpace]: userInterface.reducer,
+          [atlasSelection.nameSpace]: atlasSelection.reducer,
+        })
+      ],
+      providers: [
+        ...provideDarkTheme,
+      ],
+      declarations: []
+    })
+  ],
+} as Meta
+
+const Template: Story<ConfigComponent> = (args: ConfigComponent, { loaded }) => {
+  const { experimentalFlag } = args
+  return ({
+    props: {
+      experimentalFlag
+    },
+  })
+}
+
+export const Default = Template.bind({})
+Default.args = {
+  experimentalFlag: true
+}
+Default.loaders = [
+]
\ No newline at end of file
diff --git a/src/ui/config/configCmp/config.style.css b/src/ui/config/configCmp/config.style.css
index 907391412..9fccc534f 100644
--- a/src/ui/config/configCmp/config.style.css
+++ b/src/ui/config/configCmp/config.style.css
@@ -11,4 +11,16 @@
 .onDragOver
 {
   background-color: rgba(128,128,128,0.2);
+}
+
+.chunky
+{
+  width: 100%;
+  height: 100%;
+}
+
+.uncollapsable
+{
+  width: 10em;
+  height: 7em;
 }
\ No newline at end of file
diff --git a/src/ui/config/configCmp/config.template.html b/src/ui/config/configCmp/config.template.html
index 7241ef02a..1972951cd 100644
--- a/src/ui/config/configCmp/config.template.html
+++ b/src/ui/config/configCmp/config.template.html
@@ -1,8 +1,65 @@
 <mat-tab-group>
+
+  <!-- hard ware -->
+  <mat-tab label="Hardware">
+    <!-- wrapper + margin control -->
+    <div class="sxplr-m-4">
+
+      <!-- use mobile UI -->
+      <div class="d-flex mb-2 align-items-center">
+        <mat-slide-toggle
+          [checked]="useMobileUI$ | async"
+          (change)="toggleMobileUI($event)">
+          Enable Mobile UI
+        </mat-slide-toggle>
+        <small iav-stop="click mousedown mouseup" [matTooltip]="MOBILE_UI_TOOLTIP" class="ml-2 fas fa-question"></small>
+      </div>
+
+      <!-- animation toggle -->
+      <div class="d-flex mb-2 align-items-center">
+        <mat-slide-toggle
+          [checked]="animationFlag$ | async"
+          (change)="toggleAnimationFlag($event)">
+          Enable Animation
+        </mat-slide-toggle>
+        <small iav-stop="click mousedown mouseup" [matTooltip]="ANIMATION_TOOLTIP" class="ml-2 fas fa-question"></small>
+      </div>
+
+      <!-- GPU limit -->
+      <div class="d-flex flex-row align-items-center justify-content start">
+        <label
+          class="sxplr-m-0 d-inline-block flex-grow-0 flex-shrink-0"
+          for="gpuLimitSlider">
+          GPU Limit
+          <small iav-stop="click mousedown mouseup" [matTooltip]="GPU_TOOLTIP" class="ml-2 fas fa-question"></small>
+        </label>
+        <mat-slider
+          class="flex-grow-1 flex-shrink-1 ml-2 mr-2"
+          id="gpuLimitSlider"
+          name="gpuLimitSlider"
+          thumbLabel="true"
+          min="100"
+          max="1000"
+          [step]="stepSize"
+          (change)="handleMatSliderChange($event)"
+          [value]="gpuLimit$ | async">
+        </mat-slider>
+        <span class="d-inline-block flex-grow-0 flex-shrink-0 w-10em">
+          {{ gpuLimit$ | async }} MB
+        </span>
+      </div>
+    </div>
+  </mat-tab>
+
+  <!-- plugin csp -->
+  <!-- <mat-tab label="Plugin Permission">
+    <plugin-csp-controller></plugin-csp-controller>
+  </mat-tab> -->
+
   <!-- viewer preference -->
-  <mat-tab *ngIf="false" label="Viewer Preference">
-    
-    <div class="m-2">
+  <mat-tab *ngIf="experimentalFlag" label="Viewer Preference">
+
+    <div class="iv-custom-comp text sxplr-m-2">
       <div class="mat-h2">
         Rearrange Viewports
       </div>
@@ -17,11 +74,11 @@
           (dragleave)="handleDragLeave($event)"
           (dragend)="handleDragend($event)"
           (drop)="handleDrop($event)"
-          class="w-100 h-100 config-transition"
+          class="chunky config-transition"
           cell-i>
           <div
             [attr.panel-order]="0"
-            class="config-transition w-100 h-100 d-flex align-items-center justify-content-center border"
+            class="config-transition chunky d-flex align-items-center justify-content-center border"
             draggable="true">
             {{ (panelTexts$ | async)[0] }}
           </div>
@@ -33,11 +90,11 @@
           (dragleave)="handleDragLeave($event)"
           (dragend)="handleDragend($event)"
           (drop)="handleDrop($event)"
-          class="w-100 h-100 config-transition"
+          class="chunky config-transition"
           cell-ii>
           <div
             [attr.panel-order]="1"
-            class="config-transition w-100 h-100 d-flex align-items-center justify-content-center border"
+            class="config-transition chunky d-flex align-items-center justify-content-center border"
             draggable="true">
             {{ (panelTexts$ | async)[1] }}
           </div>
@@ -49,11 +106,11 @@
           (dragleave)="handleDragLeave($event)"
           (dragend)="handleDragend($event)"
           (drop)="handleDrop($event)"
-          class="w-100 h-100 config-transition"
+          class="chunky config-transition"
           cell-iii>
           <div
             [attr.panel-order]="2"
-            class="config-transition w-100 h-100 d-flex align-items-center justify-content-center border"
+            class="config-transition chunky d-flex align-items-center justify-content-center border"
             draggable="true">
             {{ (panelTexts$ | async)[2] }}
           </div>
@@ -65,146 +122,112 @@
           (dragleave)="handleDragLeave($event)"
           (dragend)="handleDragend($event)"
           (drop)="handleDrop($event)"
-          class="w-100 h-100 config-transition"
+          class="chunky config-transition"
           cell-iv>
           <div
             [attr.panel-order]="3"
-            class="config-transition w-100 h-100 d-flex align-items-center justify-content-center border"
+            class="config-transition chunky d-flex align-items-center justify-content-center border"
             draggable="true">
             {{ (panelTexts$ | async)[3] }}
           </div>
         </div>
       </current-layout>
 
-      <div class="mat-body text-muted font-italic">
+      <div class="iv-custom-comp text text-muted font-italic">
         Plane designation refers to default orientation (without oblique rotation).
       </div>
     </div>
 
     <!-- scroll window -->
 
-    <div class="m-2">
+    <div class="sxplr-m-2 iv-custom-comp text">
       <div class="mat-h2">
         Select a viewports configuration
       </div>
     </div>
 
     <div class="d-flex flex-row flex-nowrap sxplr-p-2">
+      BLA?
+      <!-- main template -->
+      <ng-template #panelModeBtnTmpl
+        let-panelMode="panelMode"
+        let-previewTmpl="previewTmpl">
+        <button
+          class="sxplr-m-2 sxplr-p-2"
+          mat-flat-button
+          (click)="usePanelMode(panelMode)"
+          [color]="(panelMode$ | async) === panelMode ? 'primary' : null">
+
+          <div class="uncollapsable">
+
+            <ng-template [ngTemplateOutlet]="previewTmpl">
+            </ng-template>
+          </div>
+        </button>
+      </ng-template>
 
       <!-- Four Panel Card -->
-      <button
-        class="m-2 sxplr-p-2"
-        mat-flat-button
-        (click)="usePanelMode(supportedPanelModes[0])"
-        [color]="(panelMode$ | async) === supportedPanelModes[0] ? 'primary' : null">
-        <layout-four-panel class="d-block w-10em h-7em">
-          <div class="border w-100 h-100" cell-i></div>
-          <div class="border w-100 h-100" cell-ii></div>
-          <div class="border w-100 h-100" cell-iii></div>
-          <div class="border w-100 h-100" cell-iv></div>
+      <ng-template #layoutFourPanelTmpl>
+        <layout-four-panel class="d-block chunky">
+          <div class="sxplr-border chunky" cell-i></div>
+          <div class="sxplr-border chunky" cell-ii></div>
+          <div class="sxplr-border chunky" cell-iii></div>
+          <div class="sxplr-border chunky" cell-iv></div>
         </layout-four-panel>
-      </button>
+      </ng-template>
+      <ng-template [ngTemplateOutlet]="panelModeBtnTmpl"
+        [ngTemplateOutletContext]="{
+          panelMode: panelModes.FOUR_PANEL,
+          previewTmpl: layoutFourPanelTmpl
+        }">
+      </ng-template>
 
       <!-- temporarily disabling 1-3 layout -->
 
       <!-- horizontal 1 3 card -->
       <!-- <button
-        class="m-2 sxplr-p-2"
+        class="sxplr-m-2 sxplr-p-2"
         mat-flat-button
-        (click)="usePanelMode(supportedPanelModes[1])"
-        [color]="(panelMode$ | async) === supportedPanelModes[1] ? 'primary' : null">
+        (click)="usePanelMode(panelModes.H_ONE_THREE)"
+        [color]="(panelMode$ | async) === panelModes.H_ONE_THREE ? 'primary' : null">
         <layout-horizontal-one-three class="d-block w-10em h-7em">
-          <div class="border w-100 h-100" cell-i></div>
-          <div class="border w-100 h-100" cell-ii></div>
-          <div class="border w-100 h-100" cell-iii></div>
-          <div class="border w-100 h-100" cell-iv></div>
+          <div class="border chunky" cell-i></div>
+          <div class="border chunky" cell-ii></div>
+          <div class="border chunky" cell-iii></div>
+          <div class="border chunky" cell-iv></div>
         </layout-horizontal-one-three>
       </button> -->
-  
+
       <!-- vertical 1 3 card -->
       <!-- <button
-        class="m-2 sxplr-p-2"
+        class="sxplr-m-2 sxplr-p-2"
         mat-flat-button
-        (click)="usePanelMode(supportedPanelModes[2])"
-        [color]="(panelMode$ | async) === supportedPanelModes[2] ? 'primary' : null">
+        (click)="usePanelMode(panelModes.V_ONE_THREE)"
+        [color]="(panelMode$ | async) === panelModes.V_ONE_THREE ? 'primary' : null">
         <layout-vertical-one-three class="d-block w-10em h-7em">
-          <div class="border w-100 h-100" cell-i></div>
-          <div class="border w-100 h-100" cell-ii></div>
-          <div class="border w-100 h-100" cell-iii></div>
-          <div class="border w-100 h-100" cell-iv></div>
+          <div class="border chunky" cell-i></div>
+          <div class="border chunky" cell-ii></div>
+          <div class="border chunky" cell-iii></div>
+          <div class="border chunky" cell-iv></div>
         </layout-vertical-one-three>
       </button> -->
 
       <!-- single -->
-      <button
-        class="m-2 sxplr-p-2"
-        mat-flat-button
-        (click)="usePanelMode(supportedPanelModes[3])"
-        [color]="(panelMode$ | async) === supportedPanelModes[3] ? 'primary' : null">
+      <ng-template #singlePanelTmpl>
         <layout-single-panel class="d-block w-10em h-7em">
-          <div class="border w-100 h-100" cell-i></div>
-          <div class="border w-100 h-100" cell-ii></div>
-          <div class="border w-100 h-100" cell-iii></div>
-          <div class="border w-100 h-100" cell-iv></div>
+          <div class="border chunky" cell-i></div>
+          <div class="border chunky" cell-ii></div>
+          <div class="border chunky" cell-iii></div>
+          <div class="border chunky" cell-iv></div>
         </layout-single-panel>
-      </button>
-    </div>
-  </mat-tab>
-
-  <!-- hard ware -->
-  <mat-tab label="Hardware">
-    <!-- wrapper + margin control -->
-    <div class="m-4">
-
-      <!-- use mobile UI -->
-      <div class="d-flex mb-2 align-items-center">
-        <mat-slide-toggle
-          [checked]="useMobileUI$ | async"
-          (change)="toggleMobileUI($event)">
-          Enable Mobile UI
-        </mat-slide-toggle>
-        <small iav-stop="click mousedown mouseup" [matTooltip]="MOBILE_UI_TOOLTIP" class="ml-2 fas fa-question"></small>
-      </div>
-
-      <!-- animation toggle -->
-      <div class="d-flex mb-2 align-items-center">
-        <mat-slide-toggle
-          [checked]="animationFlag$ | async"
-          (change)="toggleAnimationFlag($event)">
-          Enable Animation
-        </mat-slide-toggle>
-        <small iav-stop="click mousedown mouseup" [matTooltip]="ANIMATION_TOOLTIP" class="ml-2 fas fa-question"></small>
-      </div>
-
-      <!-- GPU limit -->
-      <div class="d-flex flex-row align-items-center justify-content start">
-        <label
-          class="m-0 d-inline-block flex-grow-0 flex-shrink-0"
-          for="gpuLimitSlider">
-          GPU Limit
-          <small iav-stop="click mousedown mouseup" [matTooltip]="GPU_TOOLTIP" class="ml-2 fas fa-question"></small>
-        </label>
-        <mat-slider
-          class="flex-grow-1 flex-shrink-1 ml-2 mr-2"
-          id="gpuLimitSlider"
-          name="gpuLimitSlider"
-          thumbLabel="true"
-          min="100"
-          max="1000"
-          [step]="stepSize"
-          (change)="handleMatSliderChange($event)"
-          [value]="gpuLimit$ | async">
-        </mat-slider>
-        <span class="d-inline-block flex-grow-0 flex-shrink-0 w-10em">
-          {{ gpuLimit$ | async }} MB
-        </span>
-      </div>
+      </ng-template>
+      <ng-template [ngTemplateOutlet]="panelModeBtnTmpl"
+        [ngTemplateOutletContext]="{
+          panelMode: panelModes.SINGLE_PANEL,
+          previewTmpl: singlePanelTmpl
+        }">
+      </ng-template>
     </div>
   </mat-tab>
-
-  <!-- plugin csp -->
-  <mat-tab label="Plugin Permission">
-    <plugin-csp-controller></plugin-csp-controller>
-  </mat-tab>
 </mat-tab-group>
 
diff --git a/src/ui/config/module.ts b/src/ui/config/module.ts
index f52b5ffb9..55fcded2c 100644
--- a/src/ui/config/module.ts
+++ b/src/ui/config/module.ts
@@ -9,7 +9,7 @@ import { ConfigComponent } from "./configCmp/config.component";
   imports: [
     CommonModule,
     AngularMaterialModule,
-    PluginModule,
+    // PluginModule,
     LayoutModule,
   ],
   declarations: [
diff --git a/src/ui/ui.module.ts b/src/ui/ui.module.ts
index 92ecdd79f..3e389e958 100644
--- a/src/ui/ui.module.ts
+++ b/src/ui/ui.module.ts
@@ -28,7 +28,6 @@ import { DOCUMENT } from "@angular/common";
 import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
 import { Landmark2DModule } from "./nehubaContainer/2dLandmarks/module";
 import { HANDLE_SCREENSHOT_PROMISE, TypeHandleScrnShotPromise } from "../screenshot";
-import { ParcellationRegionModule } from "src/atlasComponents/parcellationRegion";
 import { AtlasCmpParcellationModule } from "src/atlasComponents/parcellation";
 import { DialogInfoModule } from "./dialogInfo"
 
@@ -46,7 +45,6 @@ import { DialogInfoModule } from "./dialogInfo"
     ShareModule,
     AuthModule,
     Landmark2DModule,
-    ParcellationRegionModule,
     AtlasCmpParcellationModule,
     DialogInfoModule,
   ],
diff --git a/src/util/constants.ts b/src/util/constants.ts
index ee179b2d4..fadf58112 100644
--- a/src/util/constants.ts
+++ b/src/util/constants.ts
@@ -3,7 +3,7 @@ import { environment } from 'src/environments/environment'
 
 export const LOCAL_STORAGE_CONST = {
   GPU_LIMIT: 'fzj.xg.iv.GPU_LIMIT',
-  ANIMATION: 'fzj.xg.iv.ANIMATION_FLAG',
+  ANIMATION: 'fzj.xg.iv.DISABLE_ANIMATION_FLAG',
   MOBILE_UI: 'fzj.xg.iv.MOBILE_UI',
   AGREE_COOKIE: 'fzj.xg.iv.AGREE_COOKIE',
   AGREE_KG_TOS: 'fzj.xg.iv.AGREE_KG_TOS',
diff --git a/src/util/pureConstant.service.ts b/src/util/pureConstant.service.ts
index 34fa6e3bf..68360a593 100644
--- a/src/util/pureConstant.service.ts
+++ b/src/util/pureConstant.service.ts
@@ -9,7 +9,7 @@ import { TId, TParc, TRegionDetail, TRegionSummary, TSpaceFull, TSpaceSummary }
 import { MultiDimMap, recursiveMutate, mutateDeepMerge } from "./fn";
 import { patchRegions } from './patchPureConstants'
 import { MatSnackBar } from "@angular/material/snack-bar";
-import { atlasSelection, userInterface } from "src/state";
+import { atlasSelection, userPreference } from "src/state";
 
 const validVolumeType = new Set([
   'neuroglancer/precomputed',
@@ -305,7 +305,7 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
     )
 
     this.useTouchUI$ = this.store.pipe(
-      select(userInterface.selectors.useMobileUi),
+      select(userPreference.selectors.useMobileUi),
       shareReplay(1)
     )
 
diff --git a/src/viewerModule/module.ts b/src/viewerModule/module.ts
index 58cc6ae77..1e12da494 100644
--- a/src/viewerModule/module.ts
+++ b/src/viewerModule/module.ts
@@ -2,7 +2,6 @@ import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
 import { Observable } from "rxjs";
 import { AtlasCmpParcellationModule } from "src/atlasComponents/parcellation";
-import { ParcellationRegionModule } from "src/atlasComponents/parcellationRegion";
 import { SplashUiModule } from "src/atlasComponents/splashScreen";
 import { ComponentsModule } from "src/components";
 import { ContextMenuModule, ContextMenuService, TContextMenuReg } from "src/contextMenuModule";
@@ -38,7 +37,6 @@ import { SapiViewsModule, SapiViewsUtilModule } from "src/atlasComponents/sapiVi
     AngularMaterialModule,
     SplashUiModule,
     TopMenuModule,
-    ParcellationRegionModule,
     UtilModule,
     AtlasCmpParcellationModule,
     ComponentsModule,
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.spec.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.spec.ts
index 7e41087b1..5ef1deb33 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.spec.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.spec.ts
@@ -1,12 +1,14 @@
 import { fakeAsync, TestBed, tick } from "@angular/core/testing"
 import { MockStore, provideMockStore } from "@ngrx/store/testing"
-import { viewerStateCustomLandmarkSelector, viewerStateSelectedParcellationSelector, viewerStateSelectedRegionsSelector, viewerStateSelectedTemplateSelector } from "src/services/state/viewerState/selectors"
 import { NehubaLayerControlService } from "./layerCtrl.service"
 import * as layerCtrlUtil from '../constants'
 import { hot } from "jasmine-marbles"
 import { IColorMap } from "./layerCtrl.util"
 import { debounceTime } from "rxjs/operators"
 import { ngViewerSelectorClearView, ngViewerSelectorLayers } from "src/services/state/ngViewerState.store.helper"
+import {
+  atlasSelection
+} from "src/state"
 
 describe('> layerctrl.service.ts', () => {
   describe('> NehubaLayerControlService', () => {
@@ -27,10 +29,9 @@ describe('> layerctrl.service.ts', () => {
         layerCtrlUtil,
         'getMultiNgIdsRegionsLabelIndexMap'
       ).and.returnValue(() => getMultiNgIdsRegionsLabelIndexMapReturnVal)
-      mockStore.overrideSelector(viewerStateCustomLandmarkSelector, [])
-      mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [])
-      mockStore.overrideSelector(viewerStateSelectedTemplateSelector, {})
-      mockStore.overrideSelector(viewerStateSelectedParcellationSelector, {})
+      mockStore.overrideSelector(atlasSelection.selectors.selectedRegions, [])
+      mockStore.overrideSelector(atlasSelection.selectors.selectedTemplate, {} as any)
+      mockStore.overrideSelector(atlasSelection.selectors.selectedParcellation, {} as any)
     })
 
     it('> can be init', () => {
@@ -43,132 +44,27 @@ describe('> layerctrl.service.ts', () => {
         describe('> template/parc has no aux meshes', () => {
 
           it('> calls getMultiNgIdsRegionsLabelIndexMapReturn', () => {
-            const service = TestBed.inject(NehubaLayerControlService)
-            service.setColorMap$.subscribe()
-            expect(getMultiNgIdsRegionsLabelIndexMapSpy).toHaveBeenCalled()
+            
           })
 
           it('> emitted value is as expected', fakeAsync(() => {
-            const map = new Map<number, layerCtrlUtil.IRegion>()
-            getMultiNgIdsRegionsLabelIndexMapReturnVal.set(
-              'foo-bar',
-              map
-            )
-            map.set(1, {
-              ngId: 'foo-bar',
-              rgb: [100, 200, 255]
-            })
-            map.set(2, {
-              ngId: 'foo-bar',
-              rgb: [15, 15, 15]
-            })
-
-            const service = TestBed.inject(NehubaLayerControlService)
-            let v: any
-            service.setColorMap$.subscribe(val => {
-              v = val
-            })
-            tick(32)
-            const expectedVal = {
-              'foo-bar': {
-                1: { red: 100, green: 200, blue: 255 },
-                2: { red: 15, green: 15, blue: 15}
-              }
-            }
-            expect(v).toEqual(expectedVal)
+
           }))
 
         })
 
         describe('> template/parc has aux meshes', () => {
-          let tmplAuxMeshes = [{
-            name: 'foo-bar',
-            ngId: 'bazz',
-            labelIndicies: [1,2,3],
-            rgb: [100, 100, 100]
-          }, {
-            name: 'hello-world',
-            ngId: 'hello-world',
-            labelIndicies: [4,5,6],
-            rgb: [200, 200, 200]
-          }]
-          let parcAuxMeshes = [{
-            name: 'hello-world',
-            ngId: 'hello-world',
-            labelIndicies: [10,11,12],
-            rgb: [255, 255, 255]
-          }]
+
           beforeEach(() => {
-            mockStore.overrideSelector(viewerStateSelectedTemplateSelector, {
-              auxMeshes: tmplAuxMeshes
-            })
-            mockStore.overrideSelector(viewerStateSelectedParcellationSelector, {
-              auxMeshes: parcAuxMeshes
-            })
+
           })
 
           it('> should inherit values from tmpl and parc',  fakeAsync(() => {
 
-            const service = TestBed.inject(NehubaLayerControlService)
-            let val
-            service.setColorMap$.subscribe(v => {
-              val = v
-            })
-
-            tick(32)
-
-            expect(val).toEqual({
-              'bazz': {
-                1: { red: 100, green: 100, blue: 100 },
-                2: { red: 100, green: 100, blue: 100 },
-                3: { red: 100, green: 100, blue: 100 },
-              },
-              'hello-world': {
-                4: { red: 200, green: 200, blue: 200 },
-                5: { red: 200, green: 200, blue: 200 },
-                6: { red: 200, green: 200, blue: 200 },
-                10: { red: 255, green: 255, blue: 255 },
-                11: { red: 255, green: 255, blue: 255 },
-                12: { red: 255, green: 255, blue: 255 },
-              }
-            })
           }))
 
           it('> should overwrite any value if at all, from region', fakeAsync(() => {
-            const map = new Map<number, layerCtrlUtil.IRegion>()
-            map.set(10, {
-              ngId: 'hello-world',
-              rgb: [0, 0, 0]
-            })
-            map.set(15, {
-              ngId: 'hello-world',
-              rgb: [0, 0, 0]
-            })
-            getMultiNgIdsRegionsLabelIndexMapReturnVal.set('hello-world', map)
-
-            const service = TestBed.inject(NehubaLayerControlService)
-            let val
-            service.setColorMap$.subscribe(v => {
-              val = v
-            })
-
-            tick(32)
-            expect(val).toEqual({
-              'bazz': {
-                1: { red: 100, green: 100, blue: 100 },
-                2: { red: 100, green: 100, blue: 100 },
-                3: { red: 100, green: 100, blue: 100 },
-              },
-              'hello-world': {
-                4: { red: 200, green: 200, blue: 200 },
-                5: { red: 200, green: 200, blue: 200 },
-                6: { red: 200, green: 200, blue: 200 },
-                10: { red: 255, green: 255, blue: 255 },
-                11: { red: 255, green: 255, blue: 255 },
-                12: { red: 255, green: 255, blue: 255 },
-                15: { red: 0, green: 0, blue: 0 },
-              }
-            })
+
           }))
         })
       })
@@ -187,66 +83,13 @@ describe('> layerctrl.service.ts', () => {
     
       describe('> overwriteColorMap$ firing', () => {
         beforeEach(() => {
-          mockStore.overrideSelector(viewerStateSelectedTemplateSelector, {})
-          mockStore.overrideSelector(viewerStateSelectedParcellationSelector, {})
-          const map = new Map<number, layerCtrlUtil.IRegion>()
-          getMultiNgIdsRegionsLabelIndexMapReturnVal.set(
-            'foo-bar',
-            map
-          )
-          map.set(1, {
-            ngId: 'foo-bar',
-            rgb: [100, 200, 255]
-          })
-          map.set(2, {
-            ngId: 'foo-bar',
-            rgb: [15, 15, 15]
-          })
         })
 
         it('> should overwrite existing colormap', () => {
-          const service = TestBed.inject(NehubaLayerControlService)
-          service.overwriteColorMap$.next(foobar2)
-
-          expect(service.setColorMap$).toBeObservable(
-            hot('(b)', {
-              a: foobar1,
-              b: foobar2
-            })
-          )
+
         })
 
         it('> unsub/resub should not result in overwritecolormap last emitted value', fakeAsync(() => {
-          const service = TestBed.inject(NehubaLayerControlService)
-
-          let subscrbiedVal: IColorMap
-          const sub = service.setColorMap$.pipe(
-            debounceTime(16),
-          ).subscribe(val => {
-            subscrbiedVal = val
-          })
-
-          // see TODO this is a dirty fix
-          tick(32)
-          service.overwriteColorMap$.next(foobar2)
-          tick(32)
-          expect(subscrbiedVal).toEqual(foobar2)
-          tick(16)
-          sub.unsubscribe()
-          subscrbiedVal = null
-
-          // mock emit selectParc etc...
-          mockStore.overrideSelector(viewerStateSelectedParcellationSelector, {})
-          mockStore.setState({})
-          const sub2 = service.setColorMap$.pipe(
-            debounceTime(16),
-          ).subscribe(val => {
-            subscrbiedVal = val
-          })
-
-          tick(32)
-          expect(subscrbiedVal).toEqual(foobar1)
-          sub2.unsubscribe()
 
         }))
       })
@@ -255,48 +98,10 @@ describe('> layerctrl.service.ts', () => {
 
     describe('> visibleLayer$', () => {
       beforeEach(() => {
-        mockStore.overrideSelector(viewerStateSelectedTemplateSelector, {
-          ngId: 'tmplNgId',
-          auxMeshes: [{
-            ngId: 'tmplAuxId1',
-            labelIndicies: [1,2,3]
-          },{
-            ngId: 'tmplAuxId2',
-            labelIndicies: [1,2,3]
-          }]
-        })
-
-        mockStore.overrideSelector(viewerStateSelectedParcellationSelector, {
-          auxMeshes: [{
-            ngId: 'parcAuxId1',
-            labelIndicies: [1,2,3],
-          },{
-            ngId: 'parcAuxId2',
-            labelIndicies: [1,2,3]
-          }]
-        })
 
-        getMultiNgIdsRegionsLabelIndexMapReturnVal.set(
-          'regionsNgId1', null
-        )
-
-        getMultiNgIdsRegionsLabelIndexMapReturnVal.set(
-          'regionsNgId2', null
-        )
       })
       it('> combines ngId of template, aux mesh and regions', () => {
-        const service = TestBed.inject(NehubaLayerControlService)
-        expect(service.visibleLayer$).toBeObservable(hot('a', {
-          a: [
-            'tmplNgId',
-            'tmplAuxId1',
-            'tmplAuxId2',
-            'parcAuxId1',
-            'parcAuxId2',
-            'regionsNgId1',
-            'regionsNgId2',
-          ]
-        }))
+
       })
     })
 
@@ -310,106 +115,48 @@ describe('> layerctrl.service.ts', () => {
         labelIndex: 2
       }
       beforeEach(() => {
-        mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [])
-        mockStore.overrideSelector(ngViewerSelectorLayers, [])
-        mockStore.overrideSelector(ngViewerSelectorClearView, false)
-        mockStore.overrideSelector(viewerStateSelectedParcellationSelector, {})
       })
 
       it('> by default, should return []', () => {
-        const service = TestBed.inject(NehubaLayerControlService)
-        expect(service.segmentVis$).toBeObservable(
-          hot('a', {
-            a: []
-          })
-        )
+
       })
 
       describe('> if sel regions exist', () => {
         beforeEach(() => {
-          mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [
-            region1, region2
-          ])
+
         })
 
         it('> default, should return encoded strings', () => {
-          mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [
-            region1, region2
-          ])
-          const service = TestBed.inject(NehubaLayerControlService)
-          expect(service.segmentVis$).toBeObservable(
-            hot('a', {
-              a: [`ngid#1`, `ngid#2`]
-            })
-          )
+
         })
 
         it('> if clearflag is true, then return []', () => {
 
-          mockStore.overrideSelector(ngViewerSelectorClearView, true)
-          const service = TestBed.inject(NehubaLayerControlService)
-          expect(service.segmentVis$).toBeObservable(
-            hot('a', {
-              a: []
-            })
-          )
         })        
       })
 
       describe('> if non mixable layer exist', () => {
         beforeEach(() => {
-          mockStore.overrideSelector(ngViewerSelectorLayers, [{
-            mixability: 'nonmixable'
-          }])
         })
 
         it('> default, should return null', () => {
-          const service = TestBed.inject(NehubaLayerControlService)
-          expect(service.segmentVis$).toBeObservable(
-            hot('a', {
-              a: null
-            })
-          )
+
         })
 
         it('> if regions selected, should still return null', () => {
 
-          mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [
-            region1, region2
-          ])
-          const service = TestBed.inject(NehubaLayerControlService)
-          expect(service.segmentVis$).toBeObservable(
-            hot('a', {
-              a: null
-            })
-          )
         })
 
         describe('> if clear flag is set', () => {
           beforeEach(() => {
-            mockStore.overrideSelector(ngViewerSelectorClearView, true)
+            
           })
 
           it('> default, should return []', () => {
-            const service = TestBed.inject(NehubaLayerControlService)
-            expect(service.segmentVis$).toBeObservable(
-              hot('a', {
-                a: []
-              })
-            )
           })
 
           it('> if reg selected, should return []', () => {
 
-            mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [
-              region1, region2
-            ])
-            const service = TestBed.inject(NehubaLayerControlService)
-            expect(service.segmentVis$).toBeObservable(
-              hot('a', {
-                a: []
-              })
-            )
           })
         })
       })
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
index 156410ee6..8cb8fed1e 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
@@ -11,7 +11,7 @@ import { SAPI, SapiParcellationModel } from "src/atlasComponents/sapi";
 import { SAPISpace } from "src/atlasComponents/sapi/core";
 import { getParcNgId, fromRootStore as nehubaConfigSvcFromRootStore } from "../config.service"
 import { getRegionLabelIndex } from "../config.service/util";
-import { annotation, atlasSelection } from "src/state";
+import { annotation, atlasAppearance, atlasSelection } from "src/state";
 import { serializeSegment } from "../util";
 
 export const BACKUP_COLOR = {
@@ -160,6 +160,27 @@ export class NehubaLayerControlService implements OnDestroy{
   ){
 
     this.sub.push(
+
+      /**
+       * on store showdelin
+       * toggle parcnglayers visibility
+       */
+      this.store$.pipe(
+        select(atlasAppearance.selectors.showDelineation),
+        withLatestFrom(this.defaultNgLayers$)
+      ).subscribe(([flag, { parcNgLayers }]) => {
+        const layerObj = {}
+        for (const key in parcNgLayers) {
+          layerObj[key] = {
+            visible: flag
+          }
+        }
+
+        this.manualNgLayersControl$.next({
+          type: 'update',
+          payload: layerObj
+        })
+      }),
       this.store$.pipe(
         select(atlasSelection.selectors.selectedRegions)
       ).subscribe(() => {
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.util.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.util.ts
index f6fc08184..0b76bb270 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.util.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.util.ts
@@ -45,7 +45,7 @@ export interface INgLayerCtrl {
     [key: string]: INgLayerInterface
   }
   update: {
-    [key: string]: INgLayerInterface
+    [key: string]: Partial<INgLayerInterface>
   }
   setLayerTransparency: {
     [key: string]: number
diff --git a/src/viewerModule/nehuba/maximisePanelButton/maximisePanelButton.component.ts b/src/viewerModule/nehuba/maximisePanelButton/maximisePanelButton.component.ts
index 7aab44ac4..16cecc54b 100644
--- a/src/viewerModule/nehuba/maximisePanelButton/maximisePanelButton.component.ts
+++ b/src/viewerModule/nehuba/maximisePanelButton/maximisePanelButton.component.ts
@@ -4,7 +4,7 @@ import { Observable } from "rxjs";
 import { distinctUntilChanged, map } from "rxjs/operators";
 import { PANELS } from 'src/services/state/ngViewerState.store.helper'
 import { ARIA_LABELS } from 'common/constants'
-import { ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from "src/services/state/ngViewerState/selectors";
+import { userInterface } from "src/state"
 
 const {
   MAXIMISE_VIEW,
@@ -26,26 +26,18 @@ export class MaximisePanelButton {
 
   @Input() public panelIndex: number
 
-  private panelMode$: Observable<string>
-  private panelOrder$: Observable<string>
+  private panelMode$ = this.store$.pipe(
+    select(userInterface.selectors.panelMode),
+    distinctUntilChanged(),
+  )
 
-  public isMaximised$: Observable<boolean>
+  public isMaximised$ = this.panelMode$.pipe(
+    map(panelMode => panelMode === "SINGLE_PANEL"),
+  )
 
   constructor(
     private store$: Store<any>,
   ) {
-    this.panelMode$ = this.store$.pipe(
-      select(ngViewerSelectorPanelMode),
-      distinctUntilChanged(),
-    )
-
-    this.panelOrder$ = this.store$.pipe(
-      select(ngViewerSelectorPanelOrder),
-      distinctUntilChanged(),
-    )
-
-    this.isMaximised$ = this.panelMode$.pipe(
-      map(panelMode => panelMode === PANELS.SINGLE_PANEL),
-    )
+
   }
 }
diff --git a/src/viewerModule/nehuba/navigation.service/navigation.service.spec.ts b/src/viewerModule/nehuba/navigation.service/navigation.service.spec.ts
index 9fdde1ebb..9180048b0 100644
--- a/src/viewerModule/nehuba/navigation.service/navigation.service.spec.ts
+++ b/src/viewerModule/nehuba/navigation.service/navigation.service.spec.ts
@@ -1,12 +1,11 @@
 import { discardPeriodicTasks, fakeAsync, TestBed, tick } from '@angular/core/testing'
 import { MockStore, provideMockStore } from '@ngrx/store/testing'
 import { BehaviorSubject, of, Subject } from 'rxjs'
-import { selectViewerConfigAnimationFlag } from 'src/services/state/viewerConfig/selectors'
-import { viewerStateSelectorNavigation } from 'src/services/state/viewerState/selectors'
 import * as NavUtil from './navigation.util'
 import { NehubaViewerUnit } from '../nehubaViewer/nehubaViewer.component'
 import { NEHUBA_INSTANCE_INJTKN } from '../util'
 import { NehubaNavigationService } from './navigation.service'
+import { userPreference, atlasSelection } from "src/state"
 
 const nav1 = {
   position: [1,2,3],
@@ -63,11 +62,11 @@ describe('> navigation.service.ts', () => {
 
       const mockStore = TestBed.inject(MockStore)
       mockStore.overrideSelector(
-        viewerStateSelectorNavigation,
+        atlasSelection.selectors.navigation,
         nav1
       )
       mockStore.overrideSelector(
-        selectViewerConfigAnimationFlag,
+        userPreference.selectors.useAnimation,
         true
       )
     })
@@ -108,7 +107,7 @@ describe('> navigation.service.ts', () => {
         service['nehubaViewerInstance'] = nehubaInst as NehubaViewerUnit
 
         const mockStore = TestBed.inject(MockStore)
-        mockStore.overrideSelector(viewerStateSelectorNavigation, nav1)
+        mockStore.overrideSelector(atlasSelection.selectors.navigation, nav1)
         dispatchSpy = spyOn(mockStore, 'dispatch').and.callFake(() => {})
       })
 
diff --git a/src/viewerModule/nehuba/navigation.service/navigation.service.ts b/src/viewerModule/nehuba/navigation.service/navigation.service.ts
index 7836d2797..17dd91789 100644
--- a/src/viewerModule/nehuba/navigation.service/navigation.service.ts
+++ b/src/viewerModule/nehuba/navigation.service/navigation.service.ts
@@ -2,13 +2,11 @@ import { Inject, Injectable, OnDestroy, Optional } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { Observable, ReplaySubject, Subscription } from "rxjs";
 import { debounceTime } from "rxjs/operators";
-import { selectViewerConfigAnimationFlag } from "src/services/state/viewerConfig/selectors";
 import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component";
 import { NEHUBA_INSTANCE_INJTKN } from "../util";
-import { timedValues } from 'src/util/generator'
-import { INavObj, navAdd, navMul, navObjEqual } from './navigation.util'
+import { INavObj, navObjEqual } from './navigation.util'
 import { actions } from "src/state/atlasSelection";
-import { atlasSelection } from "src/state";
+import { atlasSelection, userPreference } from "src/state";
 
 @Injectable()
 export class NehubaNavigationService implements OnDestroy{
@@ -33,7 +31,7 @@ export class NehubaNavigationService implements OnDestroy{
   ){
     this.subscriptions.push(
       this.store$.pipe(
-        select(selectViewerConfigAnimationFlag)
+        select(userPreference.selectors.useAnimation)
       ).subscribe(flag => this.globalAnimationFlag = flag)
     )
 
diff --git a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
index c3b14f7b9..9627bd89b 100644
--- a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
@@ -2,7 +2,6 @@ import { Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, Inject,
 import { fromEvent, Subscription, ReplaySubject, BehaviorSubject, Observable, race, timer, Subject } from 'rxjs'
 import { debounceTime, filter, map, scan, startWith, mapTo, switchMap, take, skip, tap, distinctUntilChanged } from "rxjs/operators";
 import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service";
-import { StateInterface as ViewerConfiguration } from "src/services/state/viewerConfig.store";
 import { LoggingService } from "src/logging";
 import { bufferUntil, getExportNehuba, getViewer, setNehubaViewer, switchMapWaitFor } from "src/util/fn";
 import { deserializeSegment, NEHUBA_INSTANCE_INJTKN, scanSliceViewRenderFn } from "../util";
@@ -370,7 +369,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
 
   public numMeshesToBeLoaded: number = 0
 
-  public applyPerformanceConfig({ gpuLimit }: Partial<ViewerConfiguration>) {
+  public applyGpuLimit(gpuLimit: number) {
     if (gpuLimit && this.nehubaViewer) {
       const limit = this.nehubaViewer.ngviewer.state.children.get('gpuMemoryLimit')
       if (limit && limit.restoreState) {
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts
index faa78cb3d..c3882f02f 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts
@@ -7,9 +7,6 @@ import { NEVER, Subject } from "rxjs"
 import { ComponentsModule } from "src/components"
 import { ClickInterceptorService } from "src/glue"
 import { LayoutModule } from "src/layouts/layout.module"
-import { PANELS } from "src/services/state/ngViewerState/constants"
-import { ngViewerSelectorOctantRemoval, ngViewerSelectorPanelMode, ngViewerSelectorPanelOrder } from "src/services/state/ngViewerState/selectors"
-import { viewerStateCustomLandmarkSelector, viewerStateNavigationStateSelector, viewerStateSelectedRegionsSelector } from "src/services/state/viewerState/selectors"
 import { Landmark2DModule } from "src/ui/nehubaContainer/2dLandmarks/module"
 import { QuickTourModule } from "src/ui/quickTour"
 import { AngularMaterialModule } from "src/sharedModules/angularMaterial.module"
@@ -24,7 +21,7 @@ import { TouchSideClass } from "../touchSideClass.directive"
 import { NehubaGlueCmp } from "./nehubaViewerGlue.component"
 import { HarnessLoader } from "@angular/cdk/testing"
 import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service"
-
+import { userInterface, atlasSelection, userPreference, atlasAppearance } from "src/state"
 
 @Component({
   selector: 'viewer-ctrl-component',
@@ -132,12 +129,11 @@ describe('> nehubaViewerGlue.component.ts', () => {
 
   beforeEach(() => {
     mockStore = TestBed.inject(MockStore)
-    mockStore.overrideSelector(ngViewerSelectorPanelMode, PANELS.FOUR_PANEL)
-    mockStore.overrideSelector(ngViewerSelectorPanelOrder, '0123')
-    mockStore.overrideSelector(ngViewerSelectorOctantRemoval, true)
-    mockStore.overrideSelector(viewerStateCustomLandmarkSelector, [])
-    mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [])
-    mockStore.overrideSelector(viewerStateNavigationStateSelector, null)
+    mockStore.overrideSelector(userInterface.selectors.panelMode, "FOUR_PANEL")
+    mockStore.overrideSelector(userInterface.selectors.panelOrder, '0123')
+    mockStore.overrideSelector(atlasAppearance.selectors.octantRemoval, true)
+    mockStore.overrideSelector(atlasSelection.selectors.selectedRegions, [])
+    mockStore.overrideSelector(atlasSelection.selectors.navigation, null)
 
     mockStore.overrideSelector(selectorAuxMeshes, [])
   })
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
index 55ae60bb3..66d4e77a7 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
@@ -5,7 +5,6 @@ import { ngViewerActionCycleViews, ngViewerActionToggleMax } from "src/services/
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
 import { debounceTime, distinctUntilChanged, filter, map, mapTo, scan, shareReplay, startWith, switchMap, switchMapTo, take, tap, throttleTime } from "rxjs/operators";
 import { viewerStateAddUserLandmarks, viewerStateMouseOverCustomLandmark } from "src/services/state/viewerState/actions";
-import { ngViewerSelectorPanelOrder, ngViewerSelectorPanelMode } from "src/services/state/ngViewerState/selectors";
 import { ARIA_LABELS, IDS, QUICKTOUR_DESC } from 'common/constants'
 import { PANELS } from "src/services/state/ngViewerState/constants";
 import { LoggingService } from "src/logging";
@@ -31,7 +30,7 @@ import { NehubaConfig, getNehubaConfig, fromRootStore, NgLayerSpec, NgPrecompMes
 import { generalActionError } from "src/services/stateStore.helper";
 import { SET_MESHES_TO_LOAD } from "../constants";
 import { actions } from "src/state/atlasSelection";
-import { annotation, atlasSelection, userInteraction } from "src/state";
+import { annotation, atlasSelection, userInteraction, userInterface } from "src/state";
 
 export const INVALID_FILE_INPUT = `Exactly one (1) nifti file is required!`
 
@@ -169,7 +168,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
   }
 
   public panelOrder$ = this.store$.pipe(
-    select(ngViewerSelectorPanelOrder),
+    select(userInterface.selectors.panelOrder),
     distinctUntilChanged(),
     shareReplay(1),
   )
@@ -392,7 +391,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
      */
     const redrawLayoutSub = combineLatest([
       this.store$.pipe(
-        select(ngViewerSelectorPanelMode),
+        select(userInterface.selectors.panelMode),
         distinctUntilChanged(),
         shareReplay(1),
       ),
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
index 6c544745f..3f9b846f7 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
@@ -99,7 +99,7 @@
     </layout-floating-container>
 
     <!-- panel controller -->
-    <div iavLayoutFourCornersBottomRight class="position-relative">
+    <div iavLayoutFourCornersBottomRight class="position-relative honing">
 
       <ng-container *ngTemplateOutlet="panelCtrlTmpl; context: {
         panelIndex: panelIndex,
diff --git a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts
index 84a54b7e2..baab9f9d2 100644
--- a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts
+++ b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts
@@ -1,16 +1,13 @@
 import { Component } from "@angular/core"
 import { TestBed, async, ComponentFixture, fakeAsync, tick } from "@angular/core/testing"
 import { By } from "@angular/platform-browser"
-import { BrowserDynamicTestingModule } from "@angular/platform-browser-dynamic/testing"
 import { MockStore, provideMockStore } from "@ngrx/store/testing"
-import { ngViewerSelectorOctantRemoval } from "src/services/state/ngViewerState/selectors"
 import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component"
 import { NehubaViewerContainerDirective } from "./nehubaViewerInterface.directive"
-import { viewerStateSelectorNavigation, viewerStateStandAloneVolumes } from "src/services/state/viewerState/selectors";
 import { Subject } from "rxjs"
 import { ngViewerActionNehubaReady } from "src/services/state/ngViewerState/actions"
 import { viewerStateMouseOverCustomLandmarkInPerspectiveView } from "src/services/state/viewerState/actions"
-import { selectViewerConfigAnimationFlag } from "src/services/state/viewerConfig/selectors"
+import { userPreference, atlasSelection, atlasAppearance } from "src/state"
 
 describe('> nehubaViewerInterface.directive.ts', () => {
   describe('> NehubaViewerContainerDirective', () => {
@@ -46,10 +43,10 @@ describe('> nehubaViewerInterface.directive.ts', () => {
 
     beforeEach(() => {
       const mockStore = TestBed.inject(MockStore)
-      mockStore.overrideSelector(ngViewerSelectorOctantRemoval, true)
-      mockStore.overrideSelector(viewerStateStandAloneVolumes, [])
-      mockStore.overrideSelector(viewerStateSelectorNavigation, null)
-      mockStore.overrideSelector(selectViewerConfigAnimationFlag, false)
+      mockStore.overrideSelector(atlasAppearance.selectors.octantRemoval, true)
+      mockStore.overrideSelector(atlasSelection.selectors.standaloneVolumes, [])
+      mockStore.overrideSelector(atlasSelection.selectors.navigation, null)
+      mockStore.overrideSelector(userPreference.selectors.useAnimation, false)
     })
 
     it('> can be inited', () => {
diff --git a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
index 59062511f..e476b8055 100644
--- a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
+++ b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
@@ -5,14 +5,12 @@ import { Subscription, Observable, fromEvent, asyncScheduler, combineLatest } fr
 import { distinctUntilChanged, filter, debounceTime, scan, map, throttleTime, switchMapTo } from "rxjs/operators";
 import { serializeSegment, takeOnePipe } from "../util";
 import { ngViewerActionNehubaReady } from "src/services/state/ngViewerState/actions";
-import { ngViewerSelectorOctantRemoval } from "src/services/state/ngViewerState/selectors";
 import { LoggingService } from "src/logging";
-import { uiActionMouseoverLandmark, uiActionMouseoverSegments } from "src/services/state/uiState/actions";
-import { IViewerConfigState } from "src/services/state/viewerConfig.store.helper";
+import { uiActionMouseoverLandmark } from "src/services/state/uiState/actions";
 import { arrayOfPrimitiveEqual } from 'src/util/fn'
 import { INavObj, NehubaNavigationService } from "../navigation.service";
 import { NehubaConfig, defaultNehubaConfig } from "../config.service";
-import { atlasSelection } from "src/state";
+import { atlasAppearance, atlasSelection, userPreference } from "src/state";
 
 
 const determineProtocol = (url: string) => {
@@ -162,25 +160,16 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
     @Optional() private log: LoggingService,
   ){
     this.nehubaViewerFactory = this.cfr.resolveComponentFactory(NehubaViewerUnit)
-
-    this.viewerPerformanceConfig$ = this.store$.pipe(
-      select('viewerConfigState'),
-      /**
-       * TODO: this is only a bandaid fix. Technically, we should also implement
-       * logic to take the previously set config to apply oninit
-       */
-      distinctUntilChanged(),
-    )
-
-    this.nehubaViewerPerspectiveOctantRemoval$ = this.store$.pipe(
-      select(ngViewerSelectorOctantRemoval),
-    )
   }
 
-  private nehubaViewerPerspectiveOctantRemoval$: Observable<boolean>
+  private nehubaViewerPerspectiveOctantRemoval$ = this.store$.pipe(
+    select(atlasAppearance.selectors.octantRemoval),
+  )
 
-  private viewerPerformanceConfig$: Observable<IViewerConfigState>
-  private viewerConfig: Partial<IViewerConfigState> = {}
+  private gpuLimit$: Observable<number> = this.store$.pipe(
+    select(userPreference.selectors.gpuLimit)
+  )
+  private gpuLimit: number = null
 
   private nehubaViewerSubscriptions: Subscription[] = []
   private subscriptions: Subscription[] = []
@@ -218,12 +207,12 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
         this.createNehubaInstance(copiedNehubaConfig, { onInit })
       }),
 
-      this.viewerPerformanceConfig$.pipe(
-        debounceTime(200)
-      ).subscribe(config => {
-        this.viewerConfig = config
+      this.gpuLimit$.pipe(
+        debounceTime(200),
+      ).subscribe(limit => {
+        this.gpuLimit = limit
         if (this.nehubaViewerInstance && this.nehubaViewerInstance.nehubaViewer) {
-          this.nehubaViewerInstance.applyPerformanceConfig(config)
+          this.nehubaViewerInstance.applyGpuLimit(limit)
         }
       }),
       this.navService.viewerNav$.subscribe(v => {
@@ -261,15 +250,14 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
     /**
      * apply viewer config such as gpu limit
      */
-    const { gpuLimit = null } = this.viewerConfig
 
     this.nehubaViewerInstance.config = nehubaConfig
     this.nehubaViewerInstance.lifecycle = lifeCycle
 
-    if (gpuLimit) {
+    if (this.gpuLimit) {
       const initialNgState = nehubaConfig && nehubaConfig.dataset && nehubaConfig.dataset.initialNgState
       // the correct key is gpuMemoryLimit
-      initialNgState.gpuMemoryLimit = gpuLimit
+      initialNgState.gpuMemoryLimit = this.gpuLimit
     }
 
     this.nehubaViewerSubscriptions.push(
diff --git a/src/viewerModule/nehuba/store/actions.ts b/src/viewerModule/nehuba/store/actions.ts
index 38c6572e1..03e4821f5 100644
--- a/src/viewerModule/nehuba/store/actions.ts
+++ b/src/viewerModule/nehuba/store/actions.ts
@@ -1,12 +1,12 @@
 import { createAction, props } from "@ngrx/store";
-import { INgLayerInterface } from "src/services/state/ngViewerState.store";
+
 import { NEHUBA_VIEWER_FEATURE_KEY } from "../constants";
 import { IAuxMesh } from "./type";
 
 export const actionAddNgLayer = createAction(
   `[${NEHUBA_VIEWER_FEATURE_KEY}] [addNgLayer]`,
   props<{
-    layers: INgLayerInterface[]
+    layers: any[]
   }>()
 )
 
diff --git a/src/viewerModule/nehuba/touchSideClass.directive.ts b/src/viewerModule/nehuba/touchSideClass.directive.ts
index 44cdac937..eee66a8a1 100644
--- a/src/viewerModule/nehuba/touchSideClass.directive.ts
+++ b/src/viewerModule/nehuba/touchSideClass.directive.ts
@@ -1,11 +1,9 @@
 import { Directive, ElementRef, Input, OnDestroy, OnInit } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { Observable, Subscription } from "rxjs";
-import { distinctUntilChanged, tap } from "rxjs/operators";
-import { ngViewerSelectorPanelMode } from "src/services/state/ngViewerState/selectors";
-import { IavRootStoreInterface } from "src/services/stateStore.service";
+import { distinctUntilChanged } from "rxjs/operators";
 import { addTouchSideClasses, removeTouchSideClasses } from "src/viewerModule/nehuba/util";
-
+import { userInterface } from "src/state"
 
 @Directive({
   selector: '[touch-side-class]',
@@ -16,25 +14,23 @@ export class TouchSideClass implements OnDestroy, OnInit {
   @Input('touch-side-class')
   public panelNativeIndex: number
 
-  public panelMode: string
-  private panelMode$: Observable<string>
+  public panelMode: userInterface.PanelMode
+  private panelMode$: Observable<userInterface.PanelMode> = this.store$.pipe(
+    select(userInterface.selectors.panelMode),
+    distinctUntilChanged(),
+  )
 
   private subscriptions: Subscription[] = []
 
   constructor(
-    private store$: Store<IavRootStoreInterface>,
+    private store$: Store<any>,
     private el: ElementRef,
   ) {
-
-    this.panelMode$ = this.store$.pipe(
-      select(ngViewerSelectorPanelMode),
-      distinctUntilChanged(),
-      tap(mode => this.panelMode = mode),
-    )
   }
 
   public ngOnInit() {
     this.subscriptions.push(
+      this.panelMode$.subscribe(panelMode => this.panelMode = panelMode),
 
       this.panelMode$.subscribe(panelMode => {
         removeTouchSideClasses(this.el.nativeElement)
diff --git a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts
index 54b6e08fa..b9476bf4f 100644
--- a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts
+++ b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts
@@ -4,8 +4,6 @@ import { FormsModule, ReactiveFormsModule } from "@angular/forms"
 import { MockStore, provideMockStore } from "@ngrx/store/testing"
 import { BehaviorSubject, of } from "rxjs"
 import { ComponentsModule } from "src/components"
-import { ngViewerSelectorOctantRemoval } from "src/services/state/ngViewerState.store.helper"
-import { viewerStateCustomLandmarkSelector, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors"
 import { AngularMaterialModule } from "src/sharedModules"
 import {PureContantService, UtilModule} from "src/util"
 import { actionSetAuxMeshes, selectorAuxMeshes } from "../../store"
@@ -14,6 +12,8 @@ import { ViewerCtrlCmp } from "./viewerCtrlCmp.component"
 import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'
 import { HarnessLoader } from "@angular/cdk/testing"
 import { MatSlideToggleHarness } from '@angular/material/slide-toggle/testing'
+import { atlasAppearance } from "src/state"
+
 
 describe('> viewerCtrlCmp.component.ts', () => {
   describe('> ViewerCtrlCmp', () => {
@@ -81,7 +81,7 @@ describe('> viewerCtrlCmp.component.ts', () => {
     beforeEach(() => {
       mockStore = TestBed.inject(MockStore)
       mockStore.overrideSelector(viewerStateSelectedTemplatePureSelector, {})
-      mockStore.overrideSelector(ngViewerSelectorOctantRemoval, true)
+      mockStore.overrideSelector(atlasAppearance.selectors.octantRemoval, true)
       mockStore.overrideSelector(viewerStateCustomLandmarkSelector, [])
       mockStore.overrideSelector(selectorAuxMeshes, [])
     })
diff --git a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
index cd4385139..6df4e2704 100644
--- a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
+++ b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
@@ -1,16 +1,14 @@
 import { Component, HostBinding, Inject, Optional } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { combineLatest, merge, Observable, of, Subscription } from "rxjs";
-import {filter, map, pairwise, withLatestFrom} from "rxjs/operators";
-import { ngViewerActionSetPerspOctantRemoval } from "src/services/state/ngViewerState/actions";
-import { ngViewerSelectorOctantRemoval } from "src/services/state/ngViewerState/selectors";
+import { merge, Observable, of, Subscription } from "rxjs";
+import { pairwise, withLatestFrom} from "rxjs/operators";
 import { NehubaViewerUnit } from "src/viewerModule/nehuba";
 import { NEHUBA_INSTANCE_INJTKN } from "src/viewerModule/nehuba/util";
 import { ARIA_LABELS } from 'common/constants'
 import { actionSetAuxMeshes, selectorAuxMeshes } from "../../store";
 import { FormBuilder, FormControl, FormGroup } from "@angular/forms";
-import {PureContantService} from "src/util";
-import { atlasSelection } from "src/state";
+import { PureContantService } from "src/util";
+import { atlasSelection, atlasAppearance } from "src/state";
 
 @Component({
   selector: 'viewer-ctrl-component',
@@ -31,14 +29,6 @@ export class ViewerCtrlCmp{
   private selectedAtlasId: string
   private selectedTemplateId: string
 
-  private _flagDelin = true
-  get flagDelin(){
-    return this._flagDelin
-  }
-  set flagDelin(flag){
-    this._flagDelin = flag
-    this.toggleParcVsbl()
-  }
 
   private sub: Subscription[] = []
   private hiddenLayerNames: string[] = []
@@ -54,7 +44,7 @@ export class ViewerCtrlCmp{
   }
 
   public nehubaViewerPerspectiveOctantRemoval$ = this.store$.pipe(
-    select(ngViewerSelectorOctantRemoval),
+    select(atlasAppearance.selectors.octantRemoval),
   )
 
   public auxMeshFormGroup: FormGroup
@@ -80,24 +70,25 @@ export class ViewerCtrlCmp{
   
 
     // TODO move this to... nehubadirective?
-    // if (this.nehubaInst$) {
-    //   this.sub.push(
-    //     combineLatest([
-    //       this.customLandmarks$,
-    //       this.nehubaInst$,
-    //     ]).pipe(
-    //       filter(([_, nehubaInst]) => !!nehubaInst),
-    //     ).subscribe(([landmarks, nehubainst]) => {
-    //       this.setOctantRemoval(landmarks.length === 0)
-    //       nehubainst.updateUserLandmarks(landmarks)
-    //     }),
-    //     this.nehubaInst$.subscribe(nehubaInst => this.nehubaInst = nehubaInst)
-    //   )
-    // } else {
-    //   console.warn(`NEHUBA_INSTANCE_INJTKN not provided`)
-    // }
+    if (this.nehubaInst$) {
+      this.sub.push(
+        // combineLatest([
+        //   this.customLandmarks$,
+        //   this.nehubaInst$,
+        // ]).pipe(
+        //   filter(([_, nehubaInst]) => !!nehubaInst),
+        // ).subscribe(([landmarks, nehubainst]) => {
+        //   this.setOctantRemoval(landmarks.length === 0)
+        //   nehubainst.updateUserLandmarks(landmarks)
+        // }),
+        this.nehubaInst$.subscribe(nehubaInst => this.nehubaInst = nehubaInst)
+      )
+    } else {
+      console.warn(`NEHUBA_INSTANCE_INJTKN not provided`)
+    }
 
     this.sub.push(
+
       this.store$.pipe(
         select(atlasSelection.selectors.selectedATP)
       ).subscribe(({ atlas, parcellation, template }) => {
@@ -158,39 +149,10 @@ export class ViewerCtrlCmp{
     )
   }
 
-  private async toggleParcVsbl(){
-    const viewerConfig = await this.pureConstantService.getViewerConfig(this.selectedAtlasId, this.selectedTemplateId, null)
-
-    if (this.flagDelin) {
-      for (const name of this.hiddenLayerNames) {
-        const l = this.ngViewer.layerManager.getLayerByName(name)
-        l && l.setVisible(true)
-      }
-      this.hiddenLayerNames = []
-    } else {
-      this.hiddenLayerNames = []
-      const segLayerNames: string[] = []
-      for (const layer of this.ngViewer.layerManager.managedLayers) {
-        if (layer.visible && layer.name in viewerConfig) {
-          segLayerNames.push(layer.name)
-        }
-      }
-      for (const name of segLayerNames) {
-        const l = this.ngViewer.layerManager.getLayerByName(name)
-        l && l.setVisible(false)
-        this.hiddenLayerNames.push( name )
-      }
-    }
-
-    requestAnimationFrame(() => {
-      this.ngViewer.display.scheduleRedraw()
-    })
-  }
-
   public setOctantRemoval(octantRemovalFlag: boolean) {
     this.store$.dispatch(
-      ngViewerActionSetPerspOctantRemoval({
-        octantRemovalFlag
+      atlasAppearance.actions.setOctantRemoval({
+        flag: octantRemovalFlag
       })
     )
   }
diff --git a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html
index 76aa348a8..f029408a9 100644
--- a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html
+++ b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html
@@ -1,18 +1,3 @@
-<h3 class="iv-custom-comp text mat-h3">
-  Volumes
-</h3>
-
-<mat-slide-toggle [(ngModel)]="flagDelin"
-  #delinToggle="matSlideToggle"
-  [iav-key-listener]="[{ type: 'keydown', key: 'q', target: 'document', capture: true }]"
-  (iav-key-event)="delinToggle.toggle()"
-  name="toggle-delineation">
-
-  <markdown-dom class="d-inline-block iv-custom-comp text"
-    markdown="Show delineations `[q]`">
-  </markdown-dom>
-</mat-slide-toggle>
-
 <mat-divider class="mt-2 mb-2"></mat-divider>
 
 <h3 class="iv-custom-comp text mat-h3">
diff --git a/src/viewerModule/viewerCmp/viewerCmp.component.ts b/src/viewerModule/viewerCmp/viewerCmp.component.ts
index edbdcda41..14ae775e5 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.component.ts
+++ b/src/viewerModule/viewerCmp/viewerCmp.component.ts
@@ -11,9 +11,9 @@ import { ContextMenuService, TContextMenuReg } from "src/contextMenuModule";
 import { ComponentStore } from "../componentStore";
 import { DialogService } from "src/services/dialogService.service";
 import { SAPI, SapiRegionModel } from "src/atlasComponents/sapi";
-import { actions } from "src/state/atlasSelection";
+import { actions, fromRootStore } from "src/state/atlasSelection";
 import { atlasSelection, userInteraction } from "src/state";
-import { SapiSpatialFeatureModel, SapiFeatureModel } from "src/atlasComponents/sapi/type";
+import { SapiSpatialFeatureModel, SapiFeatureModel, SapiParcellationModel } from "src/atlasComponents/sapi/type";
 
 type TCStoreViewerCmp = {
   overlaySideNav: any
@@ -116,6 +116,10 @@ export class ViewerCmp implements OnDestroy {
     map(({ parcellation }) => parcellation)
   )
 
+  public allAvailableParcellations$ = this.store$.pipe(
+    fromRootStore.allAvailParcs(this.sapi)
+  )
+
   public selectedRegions$ = this.store$.pipe(
     select(atlasSelection.selectors.selectedRegions),
   )
@@ -383,4 +387,11 @@ export class ViewerCmp implements OnDestroy {
       userInteraction.actions.clearShownFeature()
     )
   }
+
+  onDismissNonbaseLayer(){
+    
+  }
+  onSelectParcellation(parc: SapiParcellationModel){
+
+  }
 }
diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html
index dc657df12..103d28ebc 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.template.html
+++ b/src/viewerModule/viewerCmp/viewerCmp.template.html
@@ -205,25 +205,21 @@
     <!-- such a gross implementation -->
     <!-- TODO fix this -->
     <div class="mt-1-n w-100 sxplr-pl-2 sxplr-pr-2 m-1px">
+
+      <!-- TODO use sapiViews/core/region/base and fix the rest -->
       <button mat-raised-button
         *ngIf="!(onlyShowMiniTray$ | async)"
         [attr.aria-label]="ARIA_LABELS.EXPAND"
         (click)="showFullSidenav()"
         class="explore-btn pe-all w-100"
         [ngClass]="{
-          'darktheme': iavRegion.rgbDarkmode === true,
-          'lighttheme': iavRegion.rgbDarkmode === false
+          'darktheme': true,
+          'lighttheme': false
         }"
-        [style.backgroundColor]="iavRegion?.rgbString || 'accent'">
+        [style.backgroundColor]="'accent'">
         <span class="text iv-custom-comp">
           Explore
         </span>
-
-        <div class="hidden"
-          iav-region
-          [region-base-region]="(selectedRegions$ | async) && (selectedRegions$ | async)[0]"
-          #iavRegion="iavRegion">
-        </div>
       </button>
     </div>
   
@@ -362,19 +358,23 @@
   <sxplr-sapiviews-core-atlas-tmplparcselector *ngIf="viewerLoaded && !(isStandaloneVolumes$ | async)">
   </sxplr-sapiviews-core-atlas-tmplparcselector>
 
-  <!-- <atlas-layer-selector *ngIf="viewerLoaded && !(isStandaloneVolumes$ | async)"
-    #alSelector="atlasLayerSelector"
-    class="d-inline-block flex-grow-0 flex-shrink-0 pe-all"
-    (iav-outsideClick)="alSelector.selectorExpanded = false">
-  </atlas-layer-selector> -->
+  <!-- selected parcellation chip -->
+  <sxplr-sapiviews-core-parcellation-smartchip
+    class="sxplr-pointer-events-all"
+    [sxplr-sapiviews-core-parcellation-smartchip-parcellation]="parcellationSelected$ | async"
+    [sxplr-sapiviews-core-parcellation-smartchip-all-parcellations]="allAvailableParcellations$ | async"
+    (sxplr-sapiviews-core-parcellation-smartchip-dismiss-nonbase-layer)="onDismissNonbaseLayer()"
+    (sxplr-sapiviews-core-parcellation-smartchip-select-parcellation)="onSelectParcellation($event)"
+    >
+  </sxplr-sapiviews-core-parcellation-smartchip>
 
   <!-- chips -->
-  <div *ngIf="parcellationSelected$ | async"
+  <!-- <div *ngIf="parcellationSelected$ | async"
     class="d-inline-block flex-grow-1 flex-shrink-1 pe-none overflow-x-auto overflow-y-hidden">
 
     <viewer-state-breadcrumb class="d-inline-block pe-all" (on-item-click)="showFullSideNav()">
     </viewer-state-breadcrumb>
-  </div>
+  </div> -->
 
 </ng-template>
 
@@ -471,13 +471,10 @@
 
       <!-- if region selected > 0 -->
       <ng-template [ngIf]="regionSelected?.length > 0" [ngIfElse]="tabTmpl_nothingSelected">
-        <div class="hidden"
-          iav-region
-          [region-base-region]="regionSelected[0]"
-          #tabTmpl_iavRegion="iavRegion">
-        </div>
 
-        <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
+
+        <!-- TODO fix with sapiView/core/region directive -->
+        <!-- <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
           matColor: 'accent',
           customColor: tabTmpl_iavRegion.rgbString,
           customColorDarkmode: tabTmpl_iavRegion.rgbDarkmode,
@@ -486,7 +483,7 @@
           click: click
         }">
 
-        </ng-container>
+        </ng-container> -->
       </ng-template>
 
       <!-- nothing is selected -->
@@ -558,8 +555,16 @@
       <ng-template [ngIf]="selectedRegions.length === 1" [ngIfElse]="multiRegionWrapperTmpl">
         <!-- a series of bugs result in requiring this hacky -->
         <!-- see https://github.com/HumanBrainProject/interactive-viewer/issues/698 -->
-        <ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: selectedRegions[0] }">
-        </ng-container>
+
+        <sxplr-sapiviews-core-region-region-rich
+          [sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async"
+          [sxplr-sapiviews-core-region-template]="templateSelected$ | async"
+          [sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
+          [sxplr-sapiviews-core-region-region]="selectedRegions[0]"
+          (sxplr-sapiviews-core-region-region-rich-feature-clicked)="showDataset($event)"
+        >
+          <div class="sapi-container" header></div>
+        </sxplr-sapiviews-core-region-region-rich>
       </ng-template>
 
       <!-- multi region wrapper -->
@@ -573,8 +578,7 @@
 
       <!-- place holder if length === 0 -->
       <ng-container *ngIf="selectedRegions.length === 0">
-        <ng-container *ngTemplateOutlet="singleRegionTmpl; context: { region: false }">
-        </ng-container>
+        no region selected
       </ng-container>
     </ng-container>
 
@@ -591,21 +595,6 @@
 </ng-template>
 
 
-<!-- single region tmpl -->
-<ng-template #singleRegionTmpl let-region="region">
-  <!-- region detail -->
-  <sxplr-sapiviews-core-region-region-rich
-    [sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async"
-    [sxplr-sapiviews-core-region-template]="templateSelected$ | async"
-    [sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
-    [sxplr-sapiviews-core-region-region]="region"
-    (sxplr-sapiviews-core-region-region-rich-feature-clicked)="showDataset($event)"
-  >
-    <div class="sapi-container" header></div>
-  </sxplr-sapiviews-core-region-region-rich>
-</ng-template>
-
-
 <!-- expansion tmpl -->
 <ng-template #ngMatAccordionTmpl
   let-title="title"
@@ -614,37 +603,6 @@
   let-iconTooltip="iconTooltip"
   let-iavNgIf="iavNgIf"
   let-content="content">
-  <mat-expansion-panel
-    [attr.data-opened]="expansionPanel.expanded"
-    [attr.data-mat-expansion-title]="title"
-    hideToggle
-    *ngIf="iavNgIf"
-    #expansionPanel="matExpansionPanel">
-
-    <mat-expansion-panel-header>
-
-      <!-- title -->
-      <mat-panel-title>
-        {{ title }}
-      </mat-panel-title>
-
-      <!-- desc + icon -->
-      <mat-panel-description class="d-flex align-items-center justify-content-end"
-        [matTooltip]="iconTooltip">
-        <span class="mr-3">{{ desc }}</span>
-        <span class="accordion-icon d-inline-flex justify-content-center">
-          <i [class]="iconClass"></i>
-        </span>
-      </mat-panel-description>
-
-    </mat-expansion-panel-header>
-
-    <!-- content -->
-    <ng-template matExpansionPanelContent>
-      <ng-container *ngTemplateOutlet="content; context: { expansionPanel: expansionPanel }">
-      </ng-container>
-    </ng-template>
-  </mat-expansion-panel>
 </ng-template>
 
 <!-- select region error... for whatever reason -->
@@ -656,42 +614,42 @@
 <!-- multi region tmpl -->
 <ng-template #multiRegionTmpl let-regions="regions">
   <ng-template [ngIf]="regions.length > 0" [ngIfElse]="regionPlaceholderTmpl">
-    <!-- <region-menu
-      [region-base-region]="{ name: CONST.MULTI_REGION_SELECTION }"
-      class="bs-border-box ml-15px-n mr-15px-n mat-elevation-z4">
-    </region-menu> -->
-    MULTI_REGION_SELECTION
 
     <!-- other regions detail accordion -->
     <mat-accordion class="bs-border-box ml-15px-n mr-15px-n mt-2">
 
       <!-- Multi regions include -->
-      <ng-template #multiRegionInclTmpl>
-
-        <mat-chip *ngFor="let r of regions"
-          iav-region
-          [region-base-region]="r"
-          class="m-1"
-          [ngClass]="{
-            'darktheme':regionDirective.rgbDarkmode === true,
-            'lighttheme': regionDirective.rgbDarkmode === false
-          }"
-          [style.backgroundColor]="regionDirective.rgbString"
-          #regionDirective="iavRegion">
-          <span class="iv-custom-comp text text-truncate d-inline">
-            {{ r.name }}
-          </span>
-        </mat-chip>
-      </ng-template>
 
-      <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
-        title: 'Brain regions',
-        desc: regions.length,
-        iconClass: 'fas fa-brain',
-        iavNgIf: true,
-        content: multiRegionInclTmpl
-      }">
-      </ng-container>
+      <mat-expansion-panel
+        [attr.data-opened]="expansionPanel.expanded"
+        [attr.data-mat-expansion-title]="'Brain regions'"
+        hideToggle
+        #expansionPanel="matExpansionPanel">
+
+        <mat-expansion-panel-header>
+
+          <!-- title -->
+          <mat-panel-title>
+            Brain regions
+          </mat-panel-title>
+
+          <!-- desc + icon -->
+          <mat-panel-description class="d-flex align-items-center justify-content-end">
+            <span class="mr-3">{{ regions.length }}</span>
+            <span class="accordion-icon d-inline-flex justify-content-center">
+              <i class="fas fa-brain"></i>
+            </span>
+          </mat-panel-description>
+
+        </mat-expansion-panel-header>
+
+        <!-- content -->
+        <ng-template matExpansionPanelContent>
+          
+          <!-- TODO use actual region chip in sapiViews/core/region/chip -->
+          SOMETHING
+        </ng-template>
+      </mat-expansion-panel>
 
     </mat-accordion>
   </ng-template>
diff --git a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html b/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html
index 89dc12e40..d1338f81b 100644
--- a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html
+++ b/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html
@@ -86,28 +86,9 @@
       <ng-container *ngFor="let r of selectedRegions">
 
         <!-- region chip for discrete map -->
-        <mat-chip
-          (click)="handleChipClick()"
-          [region-base-region]="r"
-          class="pe-all position-relative z-index-1 ml-8-n"
-          [ngClass]="{
-            'darktheme':regionDirective.rgbDarkmode === true,
-            'lighttheme': regionDirective.rgbDarkmode === false
-          }"
-          [style.backgroundColor]="regionDirective.rgbString"
-          iav-region
-          #regionDirective="iavRegion">
-          <span class="iv-custom-comp text text-truncate d-inline sxplr-pl-4">
-            {{ r.name }}
-          </span>
-          <mat-icon
-            class="iv-custom-comp text"
-            (click)="clearSelectedRegions()"
-            fontSet="fas"
-            iav-stop="click"
-            fontIcon="fa-times">
-          </mat-icon>
-        </mat-chip>
+
+        <!-- TODO use actual region chip -->
+        <mat-chip>REGION PLACE HOLDER</mat-chip>
 
         <!-- chips for previewing origin datasets/continous map -->
         <ng-container *ngFor="let originDataset of (r.originDatasets || []); let index = index">
diff --git a/src/viewerModule/viewerStateBreadCrumb/module.ts b/src/viewerModule/viewerStateBreadCrumb/module.ts
index 28de784c3..c331dbbae 100644
--- a/src/viewerModule/viewerStateBreadCrumb/module.ts
+++ b/src/viewerModule/viewerStateBreadCrumb/module.ts
@@ -1,6 +1,5 @@
 import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
-import { ParcellationRegionModule } from "src/atlasComponents/parcellationRegion";
 import { QuickTourModule } from "src/ui/quickTour";
 import { AngularMaterialModule } from "src/sharedModules";
 import { UtilModule } from "src/util";
@@ -13,7 +12,6 @@ import { DialogInfoModule } from "src/ui/dialogInfo";
     CommonModule,
     AngularMaterialModule,
     QuickTourModule,
-    ParcellationRegionModule,
     UtilModule,
     DialogInfoModule,
   ],
-- 
GitLab