bfg-common 1.4.16 → 1.4.17

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.
Files changed (40) hide show
  1. package/assets/localization/local_be.json +6 -0
  2. package/assets/localization/local_en.json +6 -0
  3. package/assets/localization/local_hy.json +6 -0
  4. package/assets/localization/local_kk.json +6 -0
  5. package/assets/localization/local_ru.json +6 -0
  6. package/assets/localization/local_zh.json +6 -0
  7. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/form/Form.vue +4 -4
  8. package/components/common/monitor/advanced/tools/chartOptionsModal/counters/timespan/form/lib/config/dateForm.ts +1 -1
  9. package/components/common/pages/hardwareHealth/HardwareHealth.vue +43 -61
  10. package/components/common/pages/hardwareHealth/historyTestimony/Graph.vue +331 -0
  11. package/components/common/pages/hardwareHealth/historyTestimony/lib/models/interfaces.ts +9 -0
  12. package/components/common/pages/hardwareHealth/historyTestimony/tools/Tools.vue +375 -0
  13. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/ChartOptionsModal.vue +469 -0
  14. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/Notification.vue +30 -0
  15. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/actions/Actions.vue +157 -0
  16. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/actions/SaveOptionsModal.vue +81 -0
  17. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/actions/lib/utils/optionsActions.ts +25 -0
  18. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/counters/Counters.vue +89 -0
  19. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/counters/table/Table.vue +174 -0
  20. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/counters/table/lib/config/tableConfig.ts +89 -0
  21. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/counters/table/lib/models/types.ts +5 -0
  22. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/counters/timespan/Timespan.vue +64 -0
  23. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/counters/timespan/form/Form.vue +539 -0
  24. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/counters/timespan/form/lib/config/dateForm.ts +115 -0
  25. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/lib/config/optionsMetrics.ts +17 -0
  26. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/lib/models/interfaces.ts +15 -0
  27. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/lib/models/types.ts +1 -0
  28. package/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/metrics/Metrics.vue +31 -0
  29. package/components/common/pages/hardwareHealth/historyTestimony/tools/lib/config/toolbar.ts +78 -0
  30. package/components/common/pages/hardwareHealth/historyTestimony/tools/lib/models/interfaces.ts +9 -0
  31. package/components/common/pages/hardwareHealth/tableView/TableView.vue +4 -10
  32. package/components/common/pages/hardwareHealth/tableView/lib/config/historyTestimonyTable.ts +128 -0
  33. package/components/common/pages/hardwareHealth/tableView/lib/config/sensorTable.ts +7 -11
  34. package/components/common/pages/hardwareHealth/tableView/lib/config/tableKeys.ts +6 -7
  35. package/components/common/pages/hardwareHealth/tableView/lib/models/interfaces.ts +2 -0
  36. package/components/common/pages/hardwareHealth/tableView/lib/models/types.ts +9 -4
  37. package/lib/models/interfaces.ts +1 -0
  38. package/lib/models/types.ts +1 -0
  39. package/package.json +1 -1
  40. package/components/common/pages/hardwareHealth/Graph.vue +0 -84
@@ -0,0 +1,81 @@
1
+ <template>
2
+ <atoms-modal
3
+ width="575px"
4
+ :show="true"
5
+ :title="localization.common.saveOptionsAs"
6
+ @hide="onHide"
7
+ @submit="onSave"
8
+ >
9
+ <template #modalBody>
10
+ <common-monitor-advanced-tools-chart-options-modal-notification
11
+ v-show="isShowAlerts"
12
+ :alerts="alerts"
13
+ @remove="onRemoveAlerts"
14
+ />
15
+ <div class="form-control">
16
+ <label class="save-option-name-label" for="chartOptionsName"
17
+ >{{ localization.common.chartOptionsName }}:</label
18
+ >
19
+ <input
20
+ id="chartOptionsName"
21
+ v-model="name"
22
+ data-id="chart-options-name"
23
+ type="text"
24
+ />
25
+ </div>
26
+ </template>
27
+ </atoms-modal>
28
+ </template>
29
+
30
+ <script setup lang="ts">
31
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
32
+
33
+ const emits = defineEmits<{
34
+ (event: 'hide'): void
35
+ (event: 'save', value: string): void
36
+ }>()
37
+
38
+ const localization = computed<UI_I_Localization>(() => useLocal())
39
+
40
+ const name = ref<string>('')
41
+ const isShowAlerts = ref<boolean>(false)
42
+ const alerts = ref<string[]>([])
43
+
44
+ const onHide = (): void => {
45
+ emits('hide')
46
+ }
47
+ const onSave = (): void => {
48
+ if (!name.value) {
49
+ alerts.value = [localization.value.settingsNameErrorDesc]
50
+ isShowAlerts.value = true
51
+
52
+ return
53
+ }
54
+
55
+ emits('save', name.value)
56
+ }
57
+
58
+ const onRemoveAlerts = (): void => {
59
+ isShowAlerts.value = false
60
+ alerts.value = []
61
+ }
62
+ </script>
63
+
64
+ <style scoped lang="scss">
65
+ :deep(.modal-dialog) {
66
+ .alert {
67
+ margin-bottom: 20px;
68
+ }
69
+
70
+ .form-control {
71
+ display: flex;
72
+
73
+ .save-option-name-label {
74
+ white-space: nowrap;
75
+ }
76
+ #chartOptionsName {
77
+ width: 100%;
78
+ }
79
+ }
80
+ }
81
+ </style>
@@ -0,0 +1,25 @@
1
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
2
+ import type { UI_I_OptionItem } from '~/components/atoms/lib/models/interfaces'
3
+
4
+ export const chartOptionItems = (
5
+ localization: UI_I_Localization,
6
+ names: string[]
7
+ ): UI_I_OptionItem[] => {
8
+ const mainOptionsNames = [
9
+ {
10
+ text: `--${localization.common.selectOption}--`,
11
+ value: 'select_options',
12
+ },
13
+ {
14
+ text: localization.common.default,
15
+ value: 'default',
16
+ },
17
+ ]
18
+ names.forEach((name) => {
19
+ mainOptionsNames.push({
20
+ text: name,
21
+ value: name,
22
+ })
23
+ })
24
+ return mainOptionsNames
25
+ }
@@ -0,0 +1,89 @@
1
+ <template>
2
+ <div class="vertical-flex-container chart-option-counters-container">
3
+ <common-pages-hardware-health-history-testimony-tools-chart-options-modal-counters-table
4
+ :chart="props.chart"
5
+ :selected-power-keys="props.selectedPowerKeys"
6
+ :selected-temperature-keys="props.selectedTemperatureKeys"
7
+ :power-counters-table-data="props.powerCountersTableData"
8
+ :temperature-counters-table-data="props.temperatureCountersTableData"
9
+ @select-power-row="emits('select-power-row', $event)"
10
+ @select-temperature-row="emits('select-temperature-row', $event)"
11
+ @total-items="totalMetricItems = $event"
12
+ />
13
+ <common-pages-hardware-health-history-testimony-tools-chart-options-modal-counters-timespan
14
+ :language="props.language"
15
+ :selected-chart-type="props.selectedChartType"
16
+ :selected-timespan-type="props.selectedTimespanType"
17
+ :units-count="props.unitsCount"
18
+ :period-type="props.periodType"
19
+ :selected-custom-time="props.selectedCustomTime"
20
+ :custom-date-from="props.customDateFrom"
21
+ :custom-date-to="props.customDateTo"
22
+ :custom-time-from="props.customTimeFrom"
23
+ :custom-time-to="props.customTimeTo"
24
+ @update-chart-type="emits('update-chart-type', $event)"
25
+ @update-custom-time="emits('update-custom-time', $event)"
26
+ @update-timespan-type="emits('update-timespan-type', $event)"
27
+ @update-unit-count="emits('update-unit-count', $event)"
28
+ @update-period-type="emits('update-period-type', $event)"
29
+ @update-custom-date-from="emits('update-custom-date-from', $event)"
30
+ @update-custom-date-to="emits('update-custom-date-to', $event)"
31
+ @update-custom-time-from="emits('update-custom-time-from', $event)"
32
+ @update-custom-time-to="emits('update-custom-time-to', $event)"
33
+ />
34
+ </div>
35
+ </template>
36
+
37
+ <script setup lang="ts">
38
+ import type { UI_I_HardwareHealthSensorsGraph } from '~/components/common/pages/hardwareHealth/historyTestimony/lib/models/interfaces'
39
+ import type { UI_T_Chart } from '~/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/lib/models/types'
40
+
41
+ const props = defineProps<{
42
+ chart: UI_T_Chart
43
+ selectedPowerKeys: number[]
44
+ selectedTemperatureKeys: number[]
45
+ powerCountersTableData: UI_I_HardwareHealthSensorsGraph[]
46
+ temperatureCountersTableData: UI_I_HardwareHealthSensorsGraph[]
47
+ language: string
48
+ selectedChartType: string
49
+ selectedTimespanType: string
50
+ unitsCount: number
51
+ periodType: string
52
+ selectedCustomTime: string
53
+ customDateFrom: string
54
+ customDateTo: string
55
+ customTimeFrom: string
56
+ customTimeTo: string
57
+ }>()
58
+
59
+ const emits = defineEmits<{
60
+ (event: 'select-power-row', value: UI_I_HardwareHealthSensorsGraph[]): void
61
+ (event: 'select-temperature-row', value: UI_I_HardwareHealthSensorsGraph[]): void
62
+ (event: 'update-chart-type', value: string): void
63
+ (event: 'update-custom-time', value: string): void
64
+ (event: 'update-timespan-type', value: string): void
65
+ (event: 'update-unit-count', value: number): void
66
+ (event: 'update-period-type', value: string): void
67
+ (event: 'update-custom-date-from', value: string): void
68
+ (event: 'update-custom-date-to', value: string): void
69
+ (event: 'update-custom-time-from', value: string): void
70
+ (event: 'update-custom-time-to', value: string): void
71
+ }>()
72
+
73
+ const totalMetricItems = ref<number>(0)
74
+ </script>
75
+
76
+ <style scoped lang="scss">
77
+ .chart-option-counters-container {
78
+ margin-top: 20px;
79
+ flex-basis: 80%;
80
+ padding-left: 15px;
81
+ max-width: 80%;
82
+ }
83
+ @media (max-width: 1024px) {
84
+ .chart-option-counters-container {
85
+ max-width: unset;
86
+ padding-left: 0;
87
+ }
88
+ }
89
+ </style>
@@ -0,0 +1,174 @@
1
+ <template>
2
+ <div class="vertical-flex-container chart-option-counters-vertical-split">
3
+ <span class="chart-options-grid-title">{{
4
+ localization.common.selectCountersForThisChart
5
+ }}</span>
6
+
7
+ <atoms-table-data-grid
8
+ v-model:selected-row="selectedCounters"
9
+ v-model:column-keys="columnItems"
10
+ v-model:page-size="pagination.pageSize"
11
+ v-model:page="pagination.page"
12
+ type="checkbox"
13
+ class="data-table"
14
+ test-id="chart-options-table"
15
+ :head-items="headItems"
16
+ :body-items="bodyItems"
17
+ :total-items="totalItems"
18
+ :total-pages="totalPages"
19
+ hide-footer
20
+ server-off
21
+ @change="onChangeRow"
22
+ />
23
+ </div>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
28
+ import type { UI_I_Pagination } from '~/lib/models/table/interfaces'
29
+ import type {
30
+ UI_I_BodyItem,
31
+ UI_I_ColumnKey,
32
+ UI_I_HeadItem,
33
+ } from '~/components/atoms/table/dataGrid/lib/models/interfaces'
34
+ import type { UI_I_HardwareHealthSensorsGraph } from '~/components/common/pages/hardwareHealth/historyTestimony/lib/models/interfaces'
35
+ import type { UI_T_Chart } from '~/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/lib/models/types'
36
+ import * as table from '~/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/counters/table/lib/config/tableConfig'
37
+
38
+ const props = defineProps<{
39
+ chart: UI_T_Chart
40
+ selectedPowerKeys: number[]
41
+ selectedTemperatureKeys: number[]
42
+ powerCountersTableData: UI_I_HardwareHealthSensorsGraph[]
43
+ temperatureCountersTableData: UI_I_HardwareHealthSensorsGraph[]
44
+ }>()
45
+
46
+ const emits = defineEmits<{
47
+ (event: 'select-power-row', value: UI_I_HardwareHealthSensorsGraph[]): void
48
+ (
49
+ event: 'select-temperature-row',
50
+ value: UI_I_HardwareHealthSensorsGraph[]
51
+ ): void
52
+ (event: 'total-items', value: number): void
53
+ }>()
54
+
55
+ const localization = computed<UI_I_Localization>(() => useLocal())
56
+
57
+ const totalItems = computed<number>(() => props.powerCountersTableData.length)
58
+ const totalPages = computed<number>(() => 1)
59
+
60
+ watch(
61
+ totalItems,
62
+ (newValue) => {
63
+ emits('total-items', newValue)
64
+ },
65
+ { immediate: true }
66
+ )
67
+
68
+ const selectedCounters = ref<number[]>([])
69
+ watch(
70
+ () => props.chart,
71
+ (newValue) => {
72
+ switch (newValue) {
73
+ case 'power':
74
+ selectedCounters.value = props.selectedPowerKeys
75
+ break
76
+ case 'temperature':
77
+ selectedCounters.value = props.selectedTemperatureKeys
78
+ break
79
+ }
80
+ }
81
+ )
82
+ watch(
83
+ () => props.selectedPowerKeys,
84
+ (newValue) => {
85
+ props.chart === 'power' && (selectedCounters.value = newValue)
86
+ },
87
+ { immediate: true, deep: true }
88
+ )
89
+ watch(
90
+ () => props.selectedTemperatureKeys,
91
+ (newValue) => {
92
+ props.chart === 'temperature' && (selectedCounters.value = newValue)
93
+ },
94
+ { immediate: true, deep: true }
95
+ )
96
+ const pagination = ref<UI_I_Pagination>({
97
+ page: 1,
98
+ pageSize: 35,
99
+ })
100
+
101
+ const columnItems = computed<UI_I_ColumnKey[]>(() =>
102
+ table.columnKeys(localization.value)
103
+ )
104
+ const headItems = computed<UI_I_HeadItem[]>(() =>
105
+ table.headItems(localization.value)
106
+ )
107
+ const bodyItems = ref<UI_I_BodyItem[][]>([])
108
+
109
+ watch(
110
+ () => [
111
+ props.powerCountersTableData,
112
+ props.temperatureCountersTableData,
113
+ props.chart,
114
+ ],
115
+ (newValue) => {
116
+ if (
117
+ (!newValue[0].length && newValue[2] === 'power') ||
118
+ (!newValue[1].length && newValue[2] === 'temperature')
119
+ )
120
+ return
121
+
122
+ let currentBody: UI_I_HardwareHealthSensorsGraph[] = []
123
+ switch (newValue[2]) {
124
+ case 'power':
125
+ currentBody = newValue[0]
126
+ break
127
+ case 'temperature':
128
+ currentBody = newValue[1]
129
+ break
130
+ }
131
+
132
+ bodyItems.value = table.bodyItems(currentBody)
133
+ },
134
+ { deep: true, immediate: true }
135
+ )
136
+
137
+ const onChangeRow = (value: number[]): void => {
138
+ const result: UI_I_HardwareHealthSensorsGraph[] = []
139
+
140
+ const allData = [
141
+ ...props.powerCountersTableData,
142
+ ...props.temperatureCountersTableData,
143
+ ]
144
+
145
+ allData.forEach((item) => {
146
+ if (value.includes(item.id)) result.push(item)
147
+ })
148
+
149
+ if (props.chart === 'power') emits('select-power-row', result)
150
+ else if (props.chart === 'temperature')
151
+ emits('select-temperature-row', result)
152
+ }
153
+
154
+ watch(
155
+ selectedCounters,
156
+ (newValue) => {
157
+ onChangeRow(newValue)
158
+ },
159
+ { immediate: true }
160
+ )
161
+ </script>
162
+
163
+ <style scoped lang="scss">
164
+ .chart-option-counters-vertical-split {
165
+ .chart-options-grid-title {
166
+ display: block;
167
+ margin-bottom: -20px;
168
+ }
169
+
170
+ :deep(.datagrid-table-wrapper) {
171
+ max-height: 176px;
172
+ }
173
+ }
174
+ </style>
@@ -0,0 +1,89 @@
1
+ import type { UI_I_Localization } from '~/lib/models/interfaces'
2
+ import type {
3
+ UI_I_BodyItem,
4
+ UI_I_ColumnKey,
5
+ UI_I_HeadItem,
6
+ } from '~/components/atoms/table/dataGrid/lib/models/interfaces'
7
+ import type { UI_I_HardwareHealthSensorsGraph } from '~/components/common/pages/hardwareHealth/historyTestimony/lib/models/interfaces'
8
+ import type { UI_T_SensorsGraphCountersColumnKey } from '~/components/common/pages/hardwareHealth/historyTestimony/tools/chartOptionsModal/counters/table/lib/models/types'
9
+ import {
10
+ constructColumnKey,
11
+ constructHeadItem,
12
+ } from '~/components/atoms/table/dataGrid/lib/utils/constructDataTable'
13
+
14
+ export const countersTableKey: UI_T_SensorsGraphCountersColumnKey[] = [
15
+ 'name',
16
+ 'description',
17
+ 'measurement',
18
+ 'units',
19
+ ]
20
+
21
+ const getItems = (
22
+ localization: UI_I_Localization
23
+ ): [string, boolean, string, string][] => {
24
+ return [
25
+ [localization.common.name, true, '140px', countersTableKey[0]],
26
+ [localization.common.description, true, '140px', countersTableKey[1]],
27
+ [localization.common.measurement, true, '140px', countersTableKey[2]],
28
+ [localization.common.units, true, '140px', countersTableKey[3]],
29
+ ]
30
+ }
31
+
32
+ export const columnKeys = (
33
+ localization: UI_I_Localization
34
+ ): UI_I_ColumnKey[] => {
35
+ const result: UI_I_ColumnKey[] = []
36
+ getItems(localization).forEach((item, i) => {
37
+ const col = `col${i + 1}`
38
+ result.push(constructColumnKey(col, item[0], item[1]))
39
+ })
40
+
41
+ return result
42
+ }
43
+
44
+ export const headItems = (localization: UI_I_Localization): UI_I_HeadItem[] => {
45
+ const result: UI_I_HeadItem[] = []
46
+ getItems(localization).forEach((item, i) => {
47
+ const col = `col${i + 1}`
48
+ result.push(
49
+ constructHeadItem(col, item[0], item[3], false, item[2], '', item[3])
50
+ )
51
+ })
52
+ return result
53
+ }
54
+
55
+ export const bodyItems = (
56
+ counter: UI_I_HardwareHealthSensorsGraph[]
57
+ ): UI_I_BodyItem[][] => {
58
+ const bodyItems: UI_I_BodyItem[][] = []
59
+
60
+ counter.forEach((counters: UI_I_HardwareHealthSensorsGraph) => {
61
+ bodyItems.push([
62
+ {
63
+ key: 'col1',
64
+ text: counters[countersTableKey[0]],
65
+ id: counters.id,
66
+ testId: `counters-item-${countersTableKey[0]}-${counters.id}`,
67
+ },
68
+ {
69
+ key: 'col2',
70
+ text: counters[countersTableKey[1]],
71
+ id: counters.id,
72
+ testId: `counters-item-${countersTableKey[1]}-${counters.id}`,
73
+ },
74
+ {
75
+ key: 'col3',
76
+ text: counters[countersTableKey[2]],
77
+ id: counters.id,
78
+ testId: `counters-item-${countersTableKey[2]}-${counters.id}`,
79
+ },
80
+ {
81
+ key: 'col4',
82
+ text: counters[countersTableKey[3]],
83
+ id: counters.id,
84
+ testId: `counters-item-${countersTableKey[3]}-${counters.id}`,
85
+ },
86
+ ])
87
+ })
88
+ return bodyItems
89
+ }
@@ -0,0 +1,5 @@
1
+ export type UI_T_SensorsGraphCountersColumnKey =
2
+ | 'name'
3
+ | 'description'
4
+ | 'measurement'
5
+ | 'units'
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="timespan-objects-section-direction">
3
+ <common-pages-hardware-health-history-testimony-tools-chart-options-modal-counters-timespan-form
4
+ :language="props.language"
5
+ :selected-chart-type="props.selectedChartType"
6
+ :selected-timespan-type="props.selectedTimespanType"
7
+ :units-count="props.unitsCount"
8
+ :period-type="props.periodType"
9
+ :selected-custom-time="props.selectedCustomTime"
10
+ :custom-date-from="props.customDateFrom"
11
+ :custom-date-to="props.customDateTo"
12
+ :custom-time-from="props.customTimeFrom"
13
+ :custom-time-to="props.customTimeTo"
14
+ @update-chart-type="emits('update-chart-type', $event)"
15
+ @update-custom-time="emits('update-custom-time', $event)"
16
+ @update-timespan-type="emits('update-timespan-type', $event)"
17
+ @update-unit-count="emits('update-unit-count', $event)"
18
+ @update-period-type="emits('update-period-type', $event)"
19
+ @update-custom-date-from="emits('update-custom-date-from', $event)"
20
+ @update-custom-date-to="emits('update-custom-date-to', $event)"
21
+ @update-custom-time-from="emits('update-custom-time-from', $event)"
22
+ @update-custom-time-to="emits('update-custom-time-to', $event)"
23
+ />
24
+ </div>
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ const props = defineProps<{
29
+ language: string
30
+ selectedChartType: string
31
+ selectedTimespanType: string
32
+ unitsCount: number
33
+ periodType: string
34
+ selectedCustomTime: string
35
+ customDateFrom: string
36
+ customDateTo: string
37
+ customTimeFrom: string
38
+ customTimeTo: string
39
+ }>()
40
+
41
+ const emits = defineEmits<{
42
+ (event: 'update-chart-type', value: string): void
43
+ (event: 'update-custom-time', value: string): void
44
+ (event: 'update-timespan-type', value: string): void
45
+ (event: 'update-unit-count', value: number): void
46
+ (event: 'update-period-type', value: string): void
47
+ (event: 'update-custom-date-from', value: string): void
48
+ (event: 'update-custom-date-to', value: string): void
49
+ (event: 'update-custom-time-from', value: string): void
50
+ (event: 'update-custom-time-to', value: string): void
51
+ }>()
52
+ </script>
53
+
54
+ <style scoped lang="scss">
55
+ .timespan-objects-section-direction {
56
+ display: flex;
57
+ flex-direction: row;
58
+ }
59
+ @media (max-width: 1024px) {
60
+ .timespan-objects-section-direction {
61
+ flex-direction: column;
62
+ }
63
+ }
64
+ </style>