@abi-software/map-side-bar 2.19.1-demo.0 → 2.20.0-acuppoints.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -92,6 +92,7 @@
92
92
  </el-cascader>
93
93
  <div v-if="showFiltersText" class="filter-default-value">Filters</div>
94
94
  <el-popover
95
+ v-if="entry.helper"
95
96
  title="How do filters work?"
96
97
  width="250"
97
98
  trigger="hover"
@@ -143,7 +144,10 @@ import '@abi-software/svg-sprite/dist/style.css';
143
144
  import { AlgoliaClient } from '../algolia/algolia.js';
144
145
  import { facetPropPathMapping } from '../algolia/utils.js';
145
146
  import EventBus from './EventBus.js';
146
- import { capitalise } from '../utils/common.js';
147
+
148
+ const capitalise = function (txt) {
149
+ return txt.charAt(0).toUpperCase() + txt.slice(1);
150
+ };
147
151
 
148
152
  const convertReadableLabel = function (original) {
149
153
  const name = original.toLowerCase();
@@ -270,22 +274,16 @@ export default {
270
274
  return value;
271
275
  },
272
276
  createChildrenCascaderValue: function (children, facet, facets) {
273
- const parentKey = facet.key;
274
-
275
277
  if (children?.length) {
276
278
  for (let i = 0; i < children.length; i++) {
277
279
  const facetItem = children[i];
278
280
  //copy the facets into
279
281
  if (children[i].facetPropPath !== 'supportingAwards.consortium.name') {
280
- // `sourceNomenclatureLabel` is from cell card explorer filters
281
- if (parentKey === 'sourceNomenclatureLabel') {
282
- children[i].label = facetItem.label;
283
- } else {
284
- children[i].label = convertReadableLabel(facetItem.label);
285
- }
282
+ children[i].label = convertReadableLabel(facetItem.label);
286
283
  }
287
- if (facetItem.key && parentKey.includes('flatmap.connectivity.source.')) {
284
+ if (facetItem.key && facet.key.includes('flatmap.connectivity.source.')) {
288
285
  const childKey = facetItem.key;
286
+ const parentKey = facet.key;
289
287
  const key = childKey.replace(`${parentKey}.`, '');
290
288
  children[i].value = this.createCascaderItemValue([facet.label, key]);
291
289
  } else {
@@ -343,7 +341,7 @@ export default {
343
341
  });
344
342
 
345
343
  // trigger reactivity only once
346
- Object.assign(this.options, processedOptions);
344
+ Object.assign(this.options, processedOptions)
347
345
  },
348
346
  populateCascader: function () {
349
347
  if (this.entry.options) {
@@ -523,7 +521,14 @@ export default {
523
521
  });
524
522
  return count;
525
523
  }
526
- return facet.children.length;
524
+ const found = facet.children.find((item) => {
525
+ return item.label === "Show all"
526
+ })
527
+ if (found) {
528
+ return facet.children.length - 1
529
+ }
530
+
531
+ return facet.children.length
527
532
  },
528
533
  /**
529
534
  * When check/uncheck all child items, automatically check "Show all"
@@ -125,10 +125,23 @@
125
125
 
126
126
  <script>
127
127
  import EventBus from './EventBus.js';
128
- import { generateUUID } from '../utils/common.js';
129
128
 
130
129
  const MAX_SEARCH_HISTORY = 12;
131
130
 
131
+ function generateUUID() {
132
+ const arr = new Uint8Array(16);
133
+ window.crypto.getRandomValues(arr);
134
+
135
+ arr[6] = (arr[6] & 0x0f) | 0x40;
136
+ arr[8] = (arr[8] & 0x3f) | 0x80;
137
+
138
+ const hex = Array.from(arr)
139
+ .map((byte) => byte.toString(16).padStart(2, '0'))
140
+ .join('');
141
+
142
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
143
+ }
144
+
132
145
  export default {
133
146
  name: 'SearchHistory',
134
147
  props: {
@@ -304,14 +317,7 @@ export default {
304
317
  getParentComponentName: function () {
305
318
  const isConnectivity = this.localStorageKey?.indexOf('connectivity') !== -1;
306
319
  const isDataset = this.localStorageKey?.indexOf('dataset') !== -1;
307
- const isCellCard = this.localStorageKey?.indexOf('cell-card') !== -1;
308
- const location = isConnectivity
309
- ? 'connectivity'
310
- : isDataset
311
- ? 'dataset'
312
- : isCellCard
313
- ? 'cell_card'
314
- : '';
320
+ const location = isConnectivity ? 'connectivity' : isDataset ? 'dataset' : '';
315
321
  return location;
316
322
  },
317
323
  search: function (item) {
@@ -65,18 +65,13 @@
65
65
  @connectivity-item-close="onConnectivityItemClose"
66
66
  />
67
67
  </template>
68
- <template v-else-if="tab.type === 'cellCardExplorer' && showCellCards">
69
- <CellCardExplorer
70
- :ref="'cellCardExplorerTab_' + tab.id"
71
- class="sidebar-content-container"
68
+ <template v-else-if="tab.type === 'acupoints' && acupointsInfoList">
69
+ <acupoints-info-search
70
+ :ref="'acupointsTab_' + tab.id"
71
+ :entry="acupointsInfoList"
72
+ @on-acupoints-click="acupointsClicked"
73
+ @acupoints-result="acupointsResult"
72
74
  v-show="tab.id === activeTabId"
73
- :envVars="envVars"
74
- :activeSpecies="activeSpeciesForEntries"
75
- @search-changed="searchChanged(tab.id, $event)"
76
- @dataset-search="openDatasetSearchFromCellCard($event)"
77
- @connectivity-search="openConnectivitySearch($event.facets, $event.query)"
78
- @soma-location-hovered="showSomaLocation"
79
- @soma-locations-ready="onSomaLocationsReady"
80
75
  />
81
76
  </template>
82
77
  <template v-else>
@@ -101,14 +96,16 @@
101
96
  import {
102
97
  ArrowLeft as ElIconArrowLeft,
103
98
  ArrowRight as ElIconArrowRight,
104
- } from '@element-plus/icons-vue';
105
- import DatasetExplorer from './DatasetExplorer.vue';
106
- import EventBus from './EventBus.js';
107
- import Tabs from './Tabs.vue';
108
- import AnnotationTool from './AnnotationTool.vue';
109
- import ConnectivityExplorer from './ConnectivityExplorer.vue';
110
- import CellCardExplorer from './CellCardExplorer.vue';
111
- import { removeShowAllFacets } from '../algolia/utils.js';
99
+ } from '@element-plus/icons-vue'
100
+ /* eslint-disable no-alert, no-console */
101
+ import { ElDrawer as Drawer, ElIcon as Icon } from 'element-plus'
102
+ import DatasetExplorer from './DatasetExplorer.vue'
103
+ import EventBus from './EventBus.js'
104
+ import Tabs from './Tabs.vue'
105
+ import AcupointsInfoSearch from './AcupointsInfoSearch.vue'
106
+ import AnnotationTool from './AnnotationTool.vue'
107
+ import ConnectivityExplorer from './ConnectivityExplorer.vue'
108
+ import { removeShowAllFacets } from '../algolia/utils.js'
112
109
 
113
110
  /**
114
111
  * Aims to provide a sidebar for searching capability for SPARC portal.
@@ -121,7 +118,6 @@ export default {
121
118
  ElIconArrowRight,
122
119
  AnnotationTool,
123
120
  ConnectivityExplorer,
124
- CellCardExplorer,
125
121
  },
126
122
  name: 'SideBar',
127
123
  props: {
@@ -131,7 +127,6 @@ export default {
131
127
  { title: 'Dataset Explorer', id: 1, type: 'datasetExplorer', closable: false },
132
128
  { title: 'Connectivity Explorer', id: 2, type: 'connectivityExplorer', closable: false },
133
129
  { title: 'Annotation', id: 3, type: 'annotation', closable: true },
134
- { title: 'Cell Card Explorer', id: 4, type: 'cellCardExplorer', closable: false },
135
130
  ],
136
131
  },
137
132
  /**
@@ -164,6 +159,13 @@ export default {
164
159
  type: Array,
165
160
  default: () => [],
166
161
  },
162
+ /**
163
+ * The acupoints info to show in sidebar.
164
+ */
165
+ acupointsInfoList: {
166
+ type: Object,
167
+ default: null,
168
+ },
167
169
  /**
168
170
  * The annotation data to show in sidebar.
169
171
  */
@@ -197,10 +199,6 @@ export default {
197
199
  type: Boolean,
198
200
  default: false,
199
201
  },
200
- showCellCards: {
201
- type: Boolean,
202
- default: false,
203
- },
204
202
  },
205
203
  data: function () {
206
204
  return {
@@ -209,7 +207,6 @@ export default {
209
207
  activeTabId: 1,
210
208
  activeAnnotationData: { tabType: 'annotation' },
211
209
  activeConnectivityData: { tabType: 'connectivity' },
212
- activeSpeciesForEntries: [],
213
210
  state: {
214
211
  dataset: {
215
212
  search: '',
@@ -219,10 +216,6 @@ export default {
219
216
  search: '',
220
217
  filters: [],
221
218
  },
222
- cellCards: {
223
- search: '',
224
- filters: [],
225
- },
226
219
  connectivityEntries: [],
227
220
  annotationEntries: [],
228
221
  activeTabId: this.activeTabId,
@@ -230,6 +223,16 @@ export default {
230
223
  };
231
224
  },
232
225
  methods: {
226
+ /**
227
+ * This event is emitted with a mouse click on acupoint card
228
+ * @arg data
229
+ */
230
+ acupointsClicked: function (data) {
231
+ this.$emit('acupoints-clicked', data)
232
+ },
233
+ acupointsResult: function (data) {
234
+ this.$emit('acupoints-result', data)
235
+ },
233
236
  onConnectivityCollapseChange: function (data) {
234
237
  this.$emit('connectivity-collapse-change', data);
235
238
  },
@@ -257,16 +260,6 @@ export default {
257
260
  this.activeAnnotationData = data;
258
261
  }
259
262
  },
260
- /**
261
- * This event is emitted when the mouse hover on or off a soma location in cell card explorer.
262
- * @param name Soma location
263
- */
264
- showSomaLocation: function (name) {
265
- this.$emit('soma-location-hovered', name);
266
- },
267
- onSomaLocationsReady: function (somaLocations) {
268
- this.$emit('soma-locations-ready', somaLocations);
269
- },
270
263
  /**
271
264
  * This event is emitted when the show connectivity button is clicked.
272
265
  * @arg featureIds
@@ -309,6 +302,14 @@ export default {
309
302
  toggleDrawer: function () {
310
303
  this.drawerOpen = !this.drawerOpen;
311
304
  },
305
+ openAcupointsSearch: function (facets, query) {
306
+ this.drawerOpen = true
307
+ // Because refs are in v-for, nextTick is needed here
308
+ this.$nextTick(() => {
309
+ const acupointTabRef = this.getTabRef(undefined, 'acupoints', true);
310
+ acupointTabRef.openSearch(facets, query)
311
+ })
312
+ },
312
313
  openConnectivitySearch: function (facets, query) {
313
314
  this.drawerOpen = true;
314
315
  // Because refs are in v-for, nextTick is needed here
@@ -331,45 +332,6 @@ export default {
331
332
  datasetExplorerTabRef.openSearch(facets, query);
332
333
  });
333
334
  },
334
- openCellCardExplorerSearch: function (filters, query) {
335
- this.drawerOpen = true;
336
- // Because refs are in v-for, nextTick is needed here
337
- this.$nextTick(() => {
338
- const cellCardExplorerTabRef = this.getTabRef(undefined, 'cellCardExplorer', true);
339
- if (cellCardExplorerTabRef && typeof cellCardExplorerTabRef.openSearch === 'function') {
340
- cellCardExplorerTabRef.openSearch(filters, query);
341
- }
342
- });
343
- },
344
- openDatasetSearchFromCellCard: function (payload) {
345
- if (!payload || typeof payload !== 'object') {
346
- this.openSearch([], payload);
347
- return;
348
- }
349
-
350
- const facets = [];
351
- if (payload.species) {
352
- facets.push({
353
- facet: payload.species,
354
- term: 'Species',
355
- facetPropPath: 'organisms.primary.species.name',
356
- });
357
- }
358
-
359
- if (payload.location) {
360
- facets.push({
361
- facet: payload.location,
362
- term: 'Anatomical structure',
363
- facetPropPath: 'anatomy.organ.category.name',
364
- AND: true,
365
- });
366
- }
367
-
368
- this.openSearch(facets, '');
369
- },
370
- /**
371
- * Get the ref id of the tab by id and type.
372
- */
373
335
  getTabRef: function (id, type, switchTab = false) {
374
336
  const matchedTab = this.tabEntries.filter((tabEntry) => {
375
337
  return (
@@ -504,13 +466,6 @@ export default {
504
466
  this.state.connectivity.filters = connectivityExplorerTabRef.getFilters();
505
467
  }
506
468
 
507
- // Update cell card explorer state if available
508
- const cellCardExplorerTabRef = this.getTabRef(undefined, 'cellCardExplorer');
509
- if (cellCardExplorerTabRef) {
510
- this.state.cellCards.search = cellCardExplorerTabRef.getSearch();
511
- this.state.cellCards.filters = cellCardExplorerTabRef.getFilters();
512
- }
513
-
514
469
  // Update connectivity entries if available
515
470
  if (this.connectivityEntry && this.connectivityEntry.length > 0) {
516
471
  this.state.connectivityEntries = this.connectivityEntry.map((entry) => entry.id);
@@ -540,15 +495,11 @@ export default {
540
495
  setState: function (state) {
541
496
  // if state is not provided or formatted incorrectly, do nothing
542
497
  if (!state || !state.dataset || !state.connectivity) return;
543
- // Create a deep copy while preserving the original state structure for future extensibility
544
- const newState = JSON.parse(JSON.stringify(state));
545
- this.state = { ...this.state, ...newState };
546
- const datasetFilters = this.state.dataset.filters;
547
- const connectivityFilters = this.state.connectivity.filters;
548
- const datasetSearch = this.state.dataset.search;
549
- const connectivitySearch = this.state.connectivity.search;
550
- const cellCardFilters = this.state.cellCards.filters || [];
551
- const cellCardSearch = this.state.cellCards.search || '';
498
+ this.state = JSON.parse(JSON.stringify(state)); // deep copy to avoid reference issues
499
+ const datasetFilters = state.dataset.filters;
500
+ const connectivityFilters = state.connectivity.filters;
501
+ const datasetSearch = state.dataset.search;
502
+ const connectivitySearch = state.connectivity.search;
552
503
 
553
504
  if (datasetFilters.length || datasetSearch) {
554
505
  this.openSearch(datasetFilters, datasetSearch);
@@ -558,10 +509,6 @@ export default {
558
509
  this.openConnectivitySearch(connectivityFilters, connectivitySearch);
559
510
  }
560
511
 
561
- if (cellCardFilters.length || cellCardSearch) {
562
- this.openCellCardExplorerSearch(cellCardFilters, cellCardSearch);
563
- }
564
-
565
512
  if (state.activeTabId) {
566
513
  this.$nextTick(() => {
567
514
  const hasTab = this.tabEntries.find((t) => t.id === state.activeTabId);
@@ -584,26 +531,23 @@ export default {
584
531
  };
585
532
  this.$emit('trackEvent', taggingData);
586
533
  },
587
- /**
588
- * @public
589
- * Update the active species to use in filters.
590
- * Used by SplitFlow component.
591
- * @param activeSpecies
592
- */
593
- updateActiveSpeciesForEntries: function (activeSpecies) {
594
- const speciesEntries = Array.isArray(activeSpecies) ? activeSpecies : [activeSpecies];
595
- this.activeSpeciesForEntries = [...new Set(speciesEntries.filter(Boolean))];
596
- },
597
534
  },
598
535
  computed: {
599
536
  // This should respect the information provided by the property
600
537
  tabEntries: function () {
601
- return this.tabs.filter(
602
- (tab) =>
603
- tab.type === 'datasetExplorer' ||
604
- tab.type === 'connectivityExplorer' ||
605
- (tab.type === 'annotation' && this.annotationEntry && this.annotationEntry.length > 0) ||
606
- (tab.type === 'cellCardExplorer' && this.showCellCards),
538
+ return this.tabs.filter((tab) =>
539
+ (tab.type === "acupoints" &&
540
+ (
541
+ this.acupointsInfoList &&
542
+ Object.keys(this.acupointsInfoList).length > 0
543
+ )) ||
544
+ tab.type === "datasetExplorer" ||
545
+ tab.type === "connectivityExplorer" ||
546
+ (
547
+ tab.type === "annotation" &&
548
+ this.annotationEntry &&
549
+ this.annotationEntry.length > 0
550
+ )
607
551
  );
608
552
  },
609
553
  },
@@ -662,6 +606,16 @@ export default {
662
606
  this.$emit('show-connectivity-graph', payLoad);
663
607
  });
664
608
 
609
+ // Emit acupoints clicked event
610
+ EventBus.on('acupoints-clicked', (payLoad) => {
611
+ this.$emit('acupoints-clicked', payLoad);
612
+ })
613
+
614
+ // Emit acupoints hovered event
615
+ EventBus.on('acupoints-hovered', (payLoad) => {
616
+ this.$emit('acupoints-hovered', payLoad);
617
+ })
618
+
665
619
  // Get available anatomy facets for the connectivity info
666
620
  EventBus.on('available-facets', (payLoad) => {
667
621
  this.availableAnatomyFacets = payLoad.find(
@@ -4,7 +4,7 @@
4
4
  class="tab"
5
5
  v-for="tab in tabs"
6
6
  :key="tab.id"
7
- :class="{ 'active-tab': tab.id == activeId, 'closable-tab': tab.closable }"
7
+ :class="{ 'active-tab': tab.id == activeId }"
8
8
  @click="tabClicked(tab)"
9
9
  >
10
10
  <span class="tab-title">{{ tab.title }}</span>
@@ -98,23 +98,14 @@ export default {
98
98
  .tab-title {
99
99
  text-align: center;
100
100
  font-size: 14px;
101
- padding: 0 0.75rem;
102
-
103
- .closable-tab & {
104
- padding-right: 0.25rem;
105
- }
101
+ padding: 0 1rem;
106
102
  }
107
103
 
108
104
  .tab-close-icon {
109
- width: 18px !important;
110
- height: 18px !important;
111
- font-size: 18px !important;
112
- margin-right: 4px !important;
105
+ width: 20px !important;
106
+ height: 20px !important;
107
+ font-size: 20px !important;
108
+ padding-right: 4px !important;
113
109
  color: $app-primary-color !important;
114
- border-radius: 2px;
115
-
116
- &:hover {
117
- background-color: rgba($app-primary-color, 0.15) !important;
118
- }
119
110
  }
120
111
  </style>
@@ -11,10 +11,10 @@ export {}
11
11
  /* prettier-ignore */
12
12
  declare module 'vue' {
13
13
  export interface GlobalComponents {
14
+ AcupointsCard: typeof import('./components/AcupointsCard.vue')['default']
15
+ AcupointsInfoSearch: typeof import('./components/AcupointsInfoSearch.vue')['default']
14
16
  AnnotationTool: typeof import('./components/AnnotationTool.vue')['default']
15
17
  BadgesGroup: typeof import('./components/BadgesGroup.vue')['default']
16
- CellCard: typeof import('./components/CellCard.vue')['default']
17
- CellCardExplorer: typeof import('./components/CellCardExplorer.vue')['default']
18
18
  ConnectivityCard: typeof import('./components/ConnectivityCard.vue')['default']
19
19
  ConnectivityExplorer: typeof import('./components/ConnectivityExplorer.vue')['default']
20
20
  ConnectivityInfo: typeof import('./components/ConnectivityInfo.vue')['default']
@@ -26,6 +26,8 @@ declare module 'vue' {
26
26
  ElCascader: typeof import('element-plus/es')['ElCascader']
27
27
  ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
28
28
  ElCol: typeof import('element-plus/es')['ElCol']
29
+ ElCollapse: typeof import('element-plus/es')['ElCollapse']
30
+ ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
29
31
  ElDrawer: typeof import('element-plus/es')['ElDrawer']
30
32
  ElDropdown: typeof import('element-plus/es')['ElDropdown']
31
33
  ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
@@ -50,7 +52,6 @@ declare module 'vue' {
50
52
  ElRow: typeof import('element-plus/es')['ElRow']
51
53
  ElSelect: typeof import('element-plus/es')['ElSelect']
52
54
  ElTag: typeof import('element-plus/es')['ElTag']
53
- IconOpenExternal: typeof import('./components/icons/IconOpenExternal.vue')['default']
54
55
  ImageGallery: typeof import('./components/ImageGallery.vue')['default']
55
56
  SearchFilters: typeof import('./components/SearchFilters.vue')['default']
56
57
  SearchHistory: typeof import('./components/SearchHistory.vue')['default']
@@ -0,0 +1,94 @@
1
+ async function getReferenceConnectivitiesFromStorage(resource) {
2
+ const flatmapKnowledgeRaw = sessionStorage.getItem('flatmap-knowledge');
3
+
4
+ if (flatmapKnowledgeRaw) {
5
+ const flatmapKnowledge = JSON.parse(flatmapKnowledgeRaw);
6
+ const dataWithRefs = flatmapKnowledge.filter((x) => x.references && x.references.length);
7
+ const foundData = dataWithRefs.filter((x) => x.references.includes(resource));
8
+
9
+ if (foundData.length) {
10
+ const featureIds = foundData.map((x) => x.id);
11
+ return featureIds;
12
+ }
13
+ }
14
+ return [];
15
+ }
16
+
17
+ async function getReferenceConnectivitiesByAPI(mapImp, resource, flatmapQueries) {
18
+ const knowledgeSource = getKnowledgeSource(mapImp);
19
+ const sql = `select knowledge from knowledge
20
+ where source="${knowledgeSource}" and
21
+ knowledge like "%${resource}%" order by source desc`;
22
+ console.log(sql)
23
+ const response = await flatmapQueries.flatmapQuery(sql);
24
+ const mappedData = response.values.map((x) => x[0]);
25
+ const parsedData = mappedData.map((x) => JSON.parse(x));
26
+ const featureIds = parsedData.map((x) => x.id);
27
+ return featureIds;
28
+ }
29
+
30
+ function getKnowledgeSource(mapImp) {
31
+ let mapKnowledgeSource = '';
32
+ if (mapImp.provenance?.connectivity) {
33
+ const sckanProvenance = mapImp.provenance.connectivity;
34
+ if ('knowledge-source' in sckanProvenance) {
35
+ mapKnowledgeSource = sckanProvenance['knowledge-source'];
36
+ } else if ('npo' in sckanProvenance) {
37
+ mapKnowledgeSource = `${sckanProvenance.npo.release}-npo`;
38
+ }
39
+ }
40
+
41
+ return mapKnowledgeSource;
42
+ }
43
+
44
+ function loadAndStoreKnowledge(mapImp, flatmapQueries) {
45
+ const knowledgeSource = getKnowledgeSource(mapImp);
46
+ const sql = `select knowledge from knowledge
47
+ where source="${knowledgeSource}"
48
+ order by source desc`;
49
+ const flatmapKnowledge = sessionStorage.getItem('flatmap-knowledge');
50
+
51
+ if (!flatmapKnowledge) {
52
+ flatmapQueries.flatmapQuery(sql).then((response) => {
53
+ const mappedData = response.values.map(x => x[0]);
54
+ const parsedData = mappedData.map(x => JSON.parse(x));
55
+ sessionStorage.setItem('flatmap-knowledge', JSON.stringify(parsedData));
56
+ updateFlatmapKnowledgeCache();
57
+ });
58
+ }
59
+ }
60
+
61
+ function updateFlatmapKnowledgeCache() {
62
+ const CACHE_LIFETIME = 24 * 60 * 60 * 1000; // One day
63
+ const now = new Date();
64
+ const expiry = now.getTime() + CACHE_LIFETIME;
65
+
66
+ sessionStorage.setItem('flatmap-knowledge-expiry', expiry);
67
+ }
68
+
69
+ function removeFlatmapKnowledgeCache() {
70
+ const keys = [
71
+ 'flatmap-knowledge',
72
+ 'flatmap-knowledge-expiry',
73
+ ];
74
+ keys.forEach((key) => {
75
+ sessionStorage.removeItem(key);
76
+ });
77
+ }
78
+
79
+ function refreshFlatmapKnowledgeCache() {
80
+ const expiry = sessionStorage.getItem('flatmap-knowledge-expiry');
81
+ const now = new Date();
82
+
83
+ if (now.getTime() > expiry) {
84
+ removeFlatmapKnowledgeCache();
85
+ }
86
+ }
87
+
88
+ export {
89
+ getReferenceConnectivitiesFromStorage,
90
+ getReferenceConnectivitiesByAPI,
91
+ loadAndStoreKnowledge,
92
+ getKnowledgeSource,
93
+ refreshFlatmapKnowledgeCache,
94
+ }