@abi-software/flatmapvuer 0.4.0 → 0.4.1-beta.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.
package/package-lock.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@abi-software/flatmapvuer",
3
- "version": "0.4.0",
3
+ "version": "0.4.1-beta.0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
7
7
  "@abi-software/flatmap-viewer": {
8
- "version": "2.2.13",
9
- "resolved": "https://registry.npmjs.org/@abi-software/flatmap-viewer/-/flatmap-viewer-2.2.13.tgz",
10
- "integrity": "sha512-5t6jlHPHFQyvx53tHY8OM8j8Abs0oii4jXCSCNPOZAh7mRvrN1sWafXt4kVlgFeUV4IcDBan6Ihh7mx+ejHyNw==",
8
+ "version": "2.2.14-b.1",
9
+ "resolved": "https://registry.npmjs.org/@abi-software/flatmap-viewer/-/flatmap-viewer-2.2.14-b.1.tgz",
10
+ "integrity": "sha512-OZ1VAf8K7DU/EO4UYlzQHAOA0NLnGXHtSl3KZTesAbWW7JiwDf+iVpKFx0yXOrKGwkeHkgLFf8V3QdwLWiY/1Q==",
11
11
  "requires": {
12
12
  "@babel/runtime": "^7.10.4",
13
13
  "@turf/area": "^6.0.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/flatmapvuer",
3
- "version": "0.4.0",
3
+ "version": "0.4.1-beta.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/flatmapvuer.common.js",
6
6
  "files": [
@@ -22,7 +22,7 @@
22
22
  "lint": "vue-cli-service lint"
23
23
  },
24
24
  "dependencies": {
25
- "@abi-software/flatmap-viewer": "^2.2.13",
25
+ "@abi-software/flatmap-viewer": "^2.2.14-b.1",
26
26
  "@abi-software/svg-sprite": "^0.1.14",
27
27
  "core-js": "^3.3.2",
28
28
  "css-element-queries": "^1.2.2",
package/src/App.vue CHANGED
@@ -20,9 +20,10 @@
20
20
  <MultiFlatmapVuer ref="multi" :availableSpecies="availableSpecies"
21
21
  @resource-selected="FlatmapSelected" :minZoom="minZoom"
22
22
  @pan-zoom-callback="panZoomcallback"
23
- @ready="FlatmapReady" :featureInfo="featureInfo" :searchable="searchable"
23
+ @ready="FlatmapReady" :featureInfo="featureInfo" :searchable="searchable"
24
+ :layerControl="layerControl"
24
25
  :initial="initial" :pathControls="pathControls" :helpMode="helpMode"
25
- :displayMinimap=true :flatmapAPI="flatmapAPI"/>
26
+ :displayMinimap="true" :flatmapAPI="flatmapAPI"/>
26
27
  </div>
27
28
  </template>
28
29
 
@@ -53,10 +54,12 @@ export default {
53
54
  this.$refs.multi.setState(this.mapSettings.pop());
54
55
  },
55
56
  FlatmapSelected: function(resource) {
56
- if (resource.eventType === "click")
57
+ if (resource.eventType === "click") {
57
58
  console.log('resource', resource);
59
+ }
58
60
  },
59
61
  FlatmapReady: function(component) {
62
+ console.log(component);
60
63
  let taxon = component.mapImp.describes;
61
64
  let id = component.mapImp.addMarker("UBERON:0000948");
62
65
  component.enablePanZoomEvents(true);
@@ -73,6 +76,7 @@ export default {
73
76
  featureInfo: true,
74
77
  searchable: true,
75
78
  pathControls: true,
79
+ layerControl: true,
76
80
  minZoom: 4,
77
81
  availableSpecies : {
78
82
  "Human Female":{taxo: "NCBITaxon:9606", biologicalSex: "PATO:0000383", iconClass:"mapicon-icon_human", displayWarning:true},
@@ -92,13 +96,13 @@ export default {
92
96
  position: "absolute"
93
97
  },
94
98
  displayCloseButton: false,
95
- initial: "Rat",
99
+ initial: "Functional Connectivity",
96
100
  helpMode: false,
97
101
  mapSettings: [],
98
102
  //flatmapAPI: "https://mapcore-demo.org/current/flatmap/v2/"
99
103
  //flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v3/"
100
- flatmapAPI: "https://mapcore-demo.org/current/flatmap/v3/"
101
- //flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v4/"
104
+ //flatmapAPI: "https://mapcore-demo.org/current/flatmap/v3/"
105
+ flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v4/"
102
106
  //flatmapAPI: "https://mapcore-demo.org/staging/flatmap/v1/"
103
107
  // flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v1/"
104
108
  }
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <div class="resource-container">
3
+ <template v-for="resource in resources">
4
+ <div class="resource" :key="resource.id">
5
+ <el-button v-if="resource.id === 'pubmed'" class="button" icon="el-icon-notebook-2" @click="openUrl(resource.url)">
6
+ Open publications in pubmed
7
+ </el-button>
8
+ </div>
9
+ </template>
10
+ </div>
11
+ </template>
12
+
13
+
14
+
15
+ <script>
16
+ /* eslint-disable no-alert, no-console */
17
+ import Vue from "vue";
18
+ import { Button } from "element-ui";
19
+ Vue.use(Button);
20
+
21
+ export default {
22
+ name: "ExternalResourceCard",
23
+ props: {
24
+ resources: {
25
+ type: Array,
26
+ default: () => []
27
+ },
28
+ },
29
+ data: function() {
30
+ return {
31
+ pubmeds: [],
32
+ pubmedIds: [],
33
+ };
34
+ },
35
+ methods: {
36
+ capitalise: function(string) {
37
+ return string.charAt(0).toUpperCase() + string.slice(1);
38
+ },
39
+ openUrl: function(url){
40
+ window.open(url, '_blank')
41
+ },
42
+ }
43
+ };
44
+ </script>
45
+
46
+ <style scoped lang="scss">
47
+ @import "~element-ui/packages/theme-chalk/src/button";
48
+
49
+ .attribute-title{
50
+ font-size: 16px;
51
+ font-weight: 600;
52
+ /* font-weight: bold; */
53
+ text-transform: uppercase;
54
+ }
55
+
56
+ .attribute-content{
57
+ font-size: 14px;
58
+ font-weight: 400;
59
+ }
60
+
61
+ .el-link {
62
+ color: $app-primary-color;
63
+ text-decoration: none;
64
+ word-wrap: break-word;
65
+ &:hover, &:focus{
66
+ color: $app-primary-color;
67
+ }
68
+ }
69
+
70
+ ::v-deep .el-carousel__button {
71
+ background-color: $app-primary-color;
72
+ }
73
+
74
+ .attribute-title{
75
+ font-size: 16px;
76
+ font-weight: 600;
77
+ /* font-weight: bold; */
78
+ text-transform: uppercase;
79
+ }
80
+
81
+ .button {
82
+ margin-left: 0px !important;
83
+ margin-top: 0px !important;
84
+ font-size: 14px !important;
85
+ background-color: $app-primary-color;
86
+ color: #fff;
87
+ &:hover{
88
+ color: #fff !important;
89
+ background: #ac76c5 !important;
90
+ border: 1px solid #ac76c5 !important;
91
+ }
92
+ &+.button {
93
+ margin-top: 10px !important;
94
+ background-color: $app-primary-color;
95
+ color: #fff;
96
+ }
97
+ }
98
+
99
+ </style>
@@ -151,14 +151,18 @@
151
151
  v-html="flatmapMarker"
152
152
  v-popover:markerPopover
153
153
  ></div>
154
- <dynamic-legends
154
+ <selections-group
155
155
  v-if="isFC && systems && systems.length > 0"
156
156
  title="Systems"
157
+ labelKey="name"
157
158
  identifierKey="name"
158
- :lists="systems"
159
- key="systemslegends"
159
+ :selections="systems"
160
+ colourStyle="background"
161
+ @changed="systemSelected"
162
+ @checkAll="checkAllSystems"
163
+ ref="systemsSelection"
164
+ key="systemsSelection"
160
165
  />
161
- <!--
162
166
  <selections-group
163
167
  v-if="!isFC && centreLines && centreLines.length > 0"
164
168
  title="Nerves"
@@ -169,7 +173,6 @@
169
173
  ref="centrelinesSelection"
170
174
  key="centrelinesSelection"
171
175
  />
172
- -->
173
176
  <selections-group
174
177
  v-if="isFC && sckanDisplay && sckanDisplay.length > 0"
175
178
  title="SCKAN"
@@ -197,6 +200,7 @@
197
200
  title="Pathways"
198
201
  labelKey="label"
199
202
  identifierKey="type"
203
+ colourStyle="line"
200
204
  :selections="pathways"
201
205
  @changed="pathwaysSelected"
202
206
  @checkAll="checkAllPathways"
@@ -268,7 +272,7 @@
268
272
  <Tooltip
269
273
  ref="tooltip"
270
274
  class="tooltip"
271
- :content="tooltipContent"
275
+ :entry="tooltipEntry"
272
276
  @resource-selected="resourceSelected"
273
277
  />
274
278
  </div>
@@ -281,7 +285,6 @@ import Vue from "vue";
281
285
  import Tooltip from "./Tooltip";
282
286
  import SelectionsGroup from "./SelectionsGroup.vue";
283
287
  import { MapSvgIcon, MapSvgSpriteColor } from "@abi-software/svg-sprite";
284
- import DynamicLegends from "./legends/DynamicLegends.vue";
285
288
  import SvgLegends from "./legends/SvgLegends";
286
289
  import {
287
290
  Col,
@@ -293,6 +296,7 @@ import {
293
296
  import lang from "element-ui/lib/locale/lang/en";
294
297
  import locale from "element-ui/lib/locale";
295
298
  import flatmapMarker from "../icons/flatmap-marker";
299
+ import {FlatmapQueries} from "../services/flatmapQueries";
296
300
 
297
301
  locale.use(lang);
298
302
  Vue.use(Col);
@@ -302,10 +306,21 @@ Vue.use(RadioGroup);
302
306
  Vue.use(Row);
303
307
  const ResizeSensor = require("css-element-queries/src/ResizeSensor");
304
308
 
309
+ const createUnfilledTooltipData = function (){
310
+ return {
311
+ destinations: [],
312
+ origins: [],
313
+ components: [],
314
+ destinationsWithDatasets: [],
315
+ originsWithDatasets: [],
316
+ componentsWithDatasets: [],
317
+ resource: undefined
318
+ }
319
+ }
320
+
305
321
  export default {
306
322
  name: "FlatmapVuer",
307
323
  components: {
308
- DynamicLegends,
309
324
  MapSvgIcon,
310
325
  MapSvgSpriteColor,
311
326
  Tooltip,
@@ -373,6 +388,9 @@ export default {
373
388
  if (this.$refs.layersSelection) {
374
389
  this.$refs.layersSelection.reset();
375
390
  }
391
+ if (this.$refs.systemsSelection) {
392
+ this.$refs.pathwaysSelection.reset();
393
+ }
376
394
  if (this.$refs.pathwaysSelection) {
377
395
  this.$refs.pathwaysSelection.reset();
378
396
  }
@@ -398,7 +416,6 @@ export default {
398
416
  },
399
417
  centreLinesSelected: function(payload) {
400
418
  if (this.mapImp) {
401
- console.log(payload.value)
402
419
  this.mapImp.enableCentrelines(payload.value);
403
420
  }
404
421
  },
@@ -412,6 +429,16 @@ export default {
412
429
  payload.keys.forEach(key => this.mapImp.enableSckanPath(key, payload.value));
413
430
  }
414
431
  },
432
+ systemSelected: function(payload) {
433
+ if (this.mapImp) {
434
+ this.mapImp.enableSystem(payload.key, payload.value);
435
+ }
436
+ },
437
+ checkAllSystems: function(payload) {
438
+ if (this.mapImp) {
439
+ payload.keys.forEach(key => this.mapImp.enableSystem(key, payload.value));
440
+ }
441
+ },
415
442
  layersSelected: function(payload) {
416
443
  if (this.mapImp) {
417
444
  this.mapImp.enableLayer(payload.key, payload.value);
@@ -452,9 +479,9 @@ export default {
452
479
  userData: args,
453
480
  eventType: eventType
454
481
  };
455
- // Disable the nueron pop up for now.
456
- if (data && data.type !== "marker")
482
+ if (data && data.type !== "marker" && eventType === "click"){
457
483
  this.checkAndCreatePopups(payload);
484
+ }
458
485
  this.$emit("resource-selected", payload);
459
486
  } else {
460
487
  this.$emit("pan-zoom-callback", data);
@@ -462,18 +489,17 @@ export default {
462
489
  };
463
490
  },
464
491
  // checkNeuronClicked shows a neuron path pop up if a path was recently clicked
465
- checkAndCreatePopups: function(data) {
466
- if (
467
- data.eventType == "click" &&
468
- this.hasNeuronTooltip(data)
469
- ) {
492
+ checkAndCreatePopups: async function(data) {
493
+ // Call flatmap database to get the connection data
494
+ let connections = await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(data)
495
+ if(!connections){
496
+ if(data.feature.hyperlinks){
497
+ this.resourceForTooltip = data.resource[0];
498
+ this.createTooltipFromNeuronCuration(data);
499
+ }
500
+ } else {
501
+ this.resourceForTooltip = data.resource[0];
470
502
  this.createTooltipFromNeuronCuration(data);
471
- this.mapImp.showPopup(
472
- this.mapImp.modelFeatureIds(data.resource[0])[0],
473
- this.$refs.tooltip.$el,
474
- { className: "flatmapvuer-popover", positionAtLastClick: true }
475
- );
476
- this.popUpCssHacks();
477
503
  }
478
504
  },
479
505
  popUpCssHacks: function() {
@@ -491,69 +517,9 @@ export default {
491
517
  resourceSelected: function(action) {
492
518
  this.$emit("resource-selected", action);
493
519
  },
494
- hasNeuronTooltip: function(data) {
495
-
496
- // neural data check
497
- if (data.resource[0]){
498
- if (data.resource[0].includes('ilxtr:neuron')){
499
- return true
500
- }
501
- }
502
- // annotated with datset check
503
- if (data.dataset) {
504
- return true
505
- }
506
-
507
- // if there is no cuff, neural data, or dataset we do not display neuron tooltip
508
- return false
509
-
510
- },
511
520
  createTooltipFromNeuronCuration: function(data) {
512
- const feature = data.resource[0];
513
- let content = {
514
- title: undefined,
515
- components: undefined,
516
- start: undefined,
517
- distribution: undefined,
518
- actions: []
519
- };
520
-
521
- this.tooltipVisible = false;
522
-
523
- // neural data check
524
- if (feature){
525
- if (feature.includes('ilxtr:neuron')){
526
- this.tooltipVisible = true;
527
- this.tooltipContent = content;
528
- this.tooltipContent.uberon = feature;
529
- this.tooltipContent.source = data.feature.source;
530
- this.tooltipContent.title = data.label;
531
- this.tooltipContent.featureIds = [feature];
532
- this.tooltipContent.actions.push({
533
- title: "Search for datasets",
534
- label: "Neuron Datasets",
535
- resource: feature.split(":")[1],
536
- type: "Neuron Search",
537
- feature: feature,
538
- nervePath: true
539
- });
540
- }
541
- }
542
- // annotated with datset check
543
- if (data.dataset) {
544
- this.tooltipVisible = true;
545
- this.tooltipContent = content;
546
- this.tooltipContent.uberon = feature;
547
- this.tooltipContent.source = data.feature.source;
548
- this.tooltipContent.title = data.label;
549
- this.tooltipContent.actions.push({
550
- title: "View dataset",
551
- resource: data.dataset,
552
- type: "URL",
553
- feature: feature,
554
- nervePath: false
555
- });
556
- }
521
+ this.tooltipEntry = this.flatmapQueries.createTooltipData(data);
522
+ this.displayTooltip();
557
523
  },
558
524
  // Keeping this as an API
559
525
  showPopup: function(featureId, node, options) {
@@ -585,9 +551,11 @@ export default {
585
551
  },
586
552
  addResizeButtonToMinimap: function(){
587
553
  let minimapEl = this.$refs.flatmapContainer.querySelector('.maplibregl-ctrl-minimap');
588
- this.$refs.minimapResize.parentNode.removeChild(this.$refs.minimapResize);
589
- minimapEl.appendChild(this.$refs.minimapResize);
590
- this.minimapResizeShow = true;
554
+ if (minimapEl){
555
+ this.$refs.minimapResize.parentNode.removeChild(this.$refs.minimapResize);
556
+ minimapEl.appendChild(this.$refs.minimapResize);
557
+ this.minimapResizeShow = true;
558
+ }
591
559
  },
592
560
  setHelpMode: function(helpMode) {
593
561
  if (helpMode) {
@@ -617,6 +585,14 @@ export default {
617
585
  clearTimeout(this.tooltipWait);
618
586
  }
619
587
  },
588
+ displayTooltip: function() {
589
+ this.mapImp.showPopup(
590
+ this.mapImp.modelFeatureIds(this.resourceForTooltip)[0],
591
+ this.$refs.tooltip.$el,
592
+ { className: "flatmapvuer-popover", positionAtLastClick: true }
593
+ );
594
+ this.popUpCssHacks();
595
+ },
620
596
  openFlatmapHelpPopup: function() {
621
597
  if (this.mapImp) {
622
598
  let heartId = this.mapImp.featureIdsForModel("UBERON:0000948")[0];
@@ -789,8 +765,8 @@ export default {
789
765
  this.backgroundChangeCallback(this.currentBackground);
790
766
  this.pathways = this.mapImp.pathTypes();
791
767
  this.mapImp.enableCentrelines(false);
792
- //this.layers = this.mapImp.getLayers();
793
- //this.systems = this.mapImp.getSystems();
768
+ this.layers = this.mapImp.getLayers();
769
+ this.systems = this.mapImp.getSystems();
794
770
  this.addResizeButtonToMinimap();
795
771
  this.loading = false;
796
772
  this.computePathControlsMaximumHeight();
@@ -860,12 +836,16 @@ export default {
860
836
  },
861
837
  pathControls: {
862
838
  type: Boolean,
863
- default: true
839
+ default: false
864
840
  },
865
841
  searchable: {
866
842
  type: Boolean,
867
843
  default: false
868
844
  },
845
+ layerControl: {
846
+ type: Boolean,
847
+ default: false
848
+ },
869
849
  tooltips: {
870
850
  type: Boolean,
871
851
  default: true
@@ -943,6 +923,7 @@ export default {
943
923
  key: "centrelines"
944
924
  }
945
925
  ],
926
+ systems: [],
946
927
  pathwaysMaxHeight: 1000,
947
928
  hoverVisibilities: [
948
929
  { value: false },
@@ -960,12 +941,14 @@ export default {
960
941
  availableBackground: ["white", "lightskyblue", "black"],
961
942
  loading: false,
962
943
  flatmapMarker: flatmapMarker,
944
+ tooltipEntry: createUnfilledTooltipData(),
945
+ connectivityTooltipVisible: false,
946
+ resourceForTooltip: undefined,
963
947
  drawerOpen: false,
964
- tooltipContent: { featureIds: []},
965
948
  colourRadio: true,
966
949
  outlinesRadio: true,
967
950
  minimapResizeShow: false,
968
- minimapSmall: false
951
+ minimapSmall: false,
969
952
  };
970
953
  },
971
954
  watch: {
@@ -987,6 +970,7 @@ export default {
987
970
  const flatmap = require("@abi-software/flatmap-viewer");
988
971
  this.mapManager = new flatmap.MapManager(this.flatmapAPI);
989
972
  if (this.renderAtMounted) this.createFlatmap();
973
+ this.flatmapQueries = new FlatmapQueries(this.sparcAPI, this.flatmapAPI);
990
974
  }
991
975
  };
992
976
  </script>
@@ -46,6 +46,7 @@
46
46
  :minZoom="minZoom"
47
47
  :pathControls="pathControls"
48
48
  :searchable="searchable"
49
+ :layerControl="layerControl"
49
50
  :helpMode="helpMode"
50
51
  :renderAtMounted="renderAtMounted"
51
52
  :displayMinimap="displayMinimap"
@@ -349,6 +350,10 @@ export default {
349
350
  type: Boolean,
350
351
  default: false
351
352
  },
353
+ layerControl: {
354
+ type: Boolean,
355
+ default: false
356
+ },
352
357
  /**
353
358
  * Initial species for the flatmap.
354
359
  * This value will be ignored if a valid state object is provided.
@@ -28,8 +28,16 @@
28
28
  :label="item[identifierKey]"
29
29
  @change="visibilityToggle(item[identifierKey], $event)"
30
30
  :checked="!(('enable' in item) && item.enable === false)">
31
- <div class="path-visual" :style="getVisualStyles(item)"></div>
32
- {{item[labelKey]}}
31
+ <el-row class="checkbox-row">
32
+ <el-col :span="4">
33
+ <div class="path-visual" :style="getLineStyles(item)"></div>
34
+ </el-col>
35
+ <el-col :span="20">
36
+ <div class="label-text" :style="getBackgroundStyles(item)">
37
+ {{item[labelKey]}}
38
+ </div>
39
+ </el-col>
40
+ </el-row>
33
41
  </el-checkbox>
34
42
  </div>
35
43
  </el-row>
@@ -82,7 +90,7 @@ export default {
82
90
  let checkedCount = value.length;
83
91
  this.checkAll = checkedCount === this.selections.length;
84
92
  },
85
- handleCheckAllChange(val) {
93
+ handleCheckAllChange: function(val) {
86
94
  this.checkedItems = val ? this.selections.map(a => a[this.identifierKey]) : [];
87
95
  this.$emit("checkAll",
88
96
  {
@@ -90,21 +98,30 @@ export default {
90
98
  value: val
91
99
  });
92
100
  },
93
- getVisualStyles(item) {
94
- if ('colour' in item) {
101
+ getBackgroundStyles: function(item) {
102
+ if ('colour' in item && this.colourStyle === "background") {
103
+ return { background: item.colour };
104
+ }
105
+ return {};
106
+ },
107
+ getLineStyles: function(item) {
108
+ if ('colour' in item && this.colourStyle === "line") {
95
109
  if (('dashed' in item) && (item.dashed === true)) {
96
110
  const background = `repeating-linear-gradient(90deg,${item.colour},${item.colour} 6px,transparent 0,transparent 9px)`;
97
- return {'background':background};
111
+ return { background };
98
112
  }
99
113
  else {
100
- const background = item.colour;
101
- return {background};
114
+ return { background: item.colour };
102
115
  }
103
116
  }
104
- return {};
117
+ return { display: "None"};
105
118
  }
106
119
  },
107
120
  props: {
121
+ colourStyle: {
122
+ type: String,
123
+ default: "line"
124
+ },
108
125
  identifierKey: {
109
126
  type: String,
110
127
  default: "id"
@@ -151,10 +168,6 @@ export default {
151
168
  @import "~element-ui/packages/theme-chalk/src/checkbox-group";
152
169
  @import "~element-ui/packages/theme-chalk/src/row";
153
170
 
154
- .selection-container {
155
- margin-top:5px;
156
- }
157
-
158
171
  .path-visual {
159
172
  margin: 3px 0;
160
173
  height: 3px;
@@ -163,6 +176,10 @@ export default {
163
176
  display: inline-block;
164
177
  }
165
178
 
179
+ .selections-container {
180
+ padding-top: 5px;
181
+ }
182
+
166
183
  .checkall-display-text {
167
184
  width: 59px;
168
185
  height: 20px;
@@ -205,6 +222,7 @@ export default {
205
222
  font-weight: 500;
206
223
  letter-spacing: 0px;
207
224
  line-height: 14px;
225
+ width: 100%;
208
226
  }
209
227
 
210
228
  ::v-deep .el-checkbox__input {
@@ -221,5 +239,10 @@ export default {
221
239
  color: $app-primary-color !important;
222
240
  }
223
241
 
242
+ .checkbox-row {
243
+ width: 100%;
244
+ top: 2px;
245
+ }
246
+
224
247
  </style>
225
248