@ouestfrance/sipa-bms-ui 8.18.0 → 8.20.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/dist/components/form/BmsInputText.vue.d.ts +1 -0
- package/dist/components/form/BmsSearch.vue.d.ts +3 -1
- package/dist/components/layout/BmsSplitWindow.vue.d.ts +1 -0
- package/dist/components/navigation/UiTenantSwitcher.vue.d.ts +3 -1
- package/dist/components/table/BmsTableFilters.vue.d.ts +3 -1
- package/dist/sipa-bms-ui.css +23 -9
- package/dist/sipa-bms-ui.es.js +19 -11
- package/dist/sipa-bms-ui.es.js.map +1 -1
- package/dist/sipa-bms-ui.umd.js +19 -11
- package/dist/sipa-bms-ui.umd.js.map +1 -1
- package/package.json +2 -1
- package/src/components/button/BmsButton.stories.js +14 -22
- package/src/components/button/BmsIconButton.stories.js +14 -8
- package/src/components/button/UiButton.stories.js +31 -0
- package/src/components/feedback/BmsCircularProgress.stories.js +0 -7
- package/src/components/feedback/BmsLoader.stories.js +0 -6
- package/src/components/feedback/BmsTooltip.stories.js +1 -0
- package/src/components/feedback/UiTooltip.stories.js +1 -0
- package/src/components/form/BmsAutocomplete.stories.js +11 -1
- package/src/components/form/BmsBetweenInput.stories.js +17 -1
- package/src/components/form/BmsFilePicker.stories.js +3 -1
- package/src/components/form/BmsInputBooleanCheckbox.stories.js +9 -0
- package/src/components/form/BmsInputCheckboxCaption.stories.js +16 -0
- package/src/components/form/BmsInputCheckboxCaptionGroup.stories.js +21 -1
- package/src/components/form/BmsInputText.vue +1 -0
- package/src/components/form/UiBmsInputCheckbox.stories.js +1 -0
- package/src/components/form/UiBmsSwitch.stories.js +1 -5
- package/src/components/layout/BmsForm_retrocompat.stories.js +1 -0
- package/src/components/layout/BmsSplitWindow.vue +38 -10
- package/src/components/navigation/BmsBreadcrumb.stories.js +0 -18
- package/src/components/navigation/BmsMenu.stories.js +4 -4
- package/src/components/navigation/BmsMenuNav.stories.js +4 -3
- package/src/components/navigation/UiMenuItem.stories.js +53 -2
- package/src/components/navigation/UiTab.stories.js +1 -0
- package/src/components/navigation/UiTenantSwitcher.stories.js +1 -0
- package/src/components/table/BmsEmptyScreen.stories.js +0 -7
- package/src/components/table/UiBmsTable.stories.js +1 -0
- package/src/components/table/UiFilterButton.stories.js +3 -8
- package/src/components/utils/BmsRelativeTime.stories.js +0 -6
- package/src/components/feedback/Notification.stories.js +0 -37
- package/src/components/navigation/UiMenuItemStatus.stories.js +0 -64
|
@@ -55,6 +55,7 @@ const collapsedLocal = ref(props.collapsed ?? false);
|
|
|
55
55
|
watch(
|
|
56
56
|
() => props.collapsed,
|
|
57
57
|
(val) => {
|
|
58
|
+
console.log('watch:collapsed', val);
|
|
58
59
|
collapsedLocal.value = val ?? false;
|
|
59
60
|
},
|
|
60
61
|
);
|
|
@@ -110,7 +111,9 @@ onBeforeUnmount(() => {
|
|
|
110
111
|
|
|
111
112
|
function onPointerDown(evt: PointerEvent) {
|
|
112
113
|
isDragging.value = true;
|
|
113
|
-
|
|
114
|
+
if (collapsedLocal.value) {
|
|
115
|
+
setCollapsed(false);
|
|
116
|
+
}
|
|
114
117
|
startSplit.value = clampSplit.value;
|
|
115
118
|
startPosition.value =
|
|
116
119
|
props.splitOrientation === 'vertical' ? evt.clientX : evt.clientY;
|
|
@@ -146,14 +149,14 @@ function onKeyDown(evt: KeyboardEvent) {
|
|
|
146
149
|
switch (evt.key) {
|
|
147
150
|
case 'ArrowLeft':
|
|
148
151
|
case 'ArrowUp':
|
|
149
|
-
if (collapsedLocal.value
|
|
152
|
+
if (collapsedLocal.value) {
|
|
150
153
|
setCollapsed(false);
|
|
151
154
|
}
|
|
152
155
|
split.value = Math.max(min.value, clampSplit.value - 1);
|
|
153
156
|
break;
|
|
154
157
|
case 'ArrowRight':
|
|
155
158
|
case 'ArrowDown':
|
|
156
|
-
if (collapsedLocal.value
|
|
159
|
+
if (collapsedLocal.value) {
|
|
157
160
|
setCollapsed(false);
|
|
158
161
|
}
|
|
159
162
|
split.value = Math.min(max.value, clampSplit.value + 1);
|
|
@@ -162,13 +165,13 @@ function onKeyDown(evt: KeyboardEvent) {
|
|
|
162
165
|
setCollapsed(!collapsedLocal.value);
|
|
163
166
|
break;
|
|
164
167
|
case 'Home':
|
|
165
|
-
if (collapsedLocal.value
|
|
168
|
+
if (collapsedLocal.value) {
|
|
166
169
|
setCollapsed(false);
|
|
167
170
|
}
|
|
168
171
|
split.value = props.primary === 'first' ? min.value : max.value;
|
|
169
172
|
break;
|
|
170
173
|
case 'End':
|
|
171
|
-
if (collapsedLocal.value
|
|
174
|
+
if (collapsedLocal.value) {
|
|
172
175
|
setCollapsed(false);
|
|
173
176
|
}
|
|
174
177
|
split.value = props.primary === 'first' ? max.value : min.value;
|
|
@@ -202,11 +205,14 @@ function clamp(value: number, minValue: number, maxValue: number) {
|
|
|
202
205
|
<div
|
|
203
206
|
ref="split-window"
|
|
204
207
|
class="split-window"
|
|
205
|
-
:class="
|
|
208
|
+
:class="[
|
|
209
|
+
`split-window--${splitOrientation}`,
|
|
210
|
+
{ 'split-window--dragging': isDragging },
|
|
211
|
+
]"
|
|
206
212
|
:style="gridStyle"
|
|
207
213
|
>
|
|
208
214
|
<div
|
|
209
|
-
class="split-window__first-pane"
|
|
215
|
+
class="split-window__pane split-window__first-pane"
|
|
210
216
|
:id="primary === 'first' ? primaryId : undefined"
|
|
211
217
|
>
|
|
212
218
|
<slot name="first" />
|
|
@@ -223,9 +229,11 @@ function clamp(value: number, minValue: number, maxValue: number) {
|
|
|
223
229
|
:aria-controls="primaryId"
|
|
224
230
|
@pointerdown.prevent.stop="onPointerDown"
|
|
225
231
|
@keydown="onKeyDown"
|
|
226
|
-
|
|
232
|
+
>
|
|
233
|
+
<slot name="separator" />
|
|
234
|
+
</div>
|
|
227
235
|
<div
|
|
228
|
-
class="split-window__second-pane"
|
|
236
|
+
class="split-window__pane split-window__second-pane"
|
|
229
237
|
:id="primary === 'second' ? primaryId : undefined"
|
|
230
238
|
>
|
|
231
239
|
<slot name="second" />
|
|
@@ -238,10 +246,17 @@ function clamp(value: number, minValue: number, maxValue: number) {
|
|
|
238
246
|
display: grid;
|
|
239
247
|
width: 100%;
|
|
240
248
|
height: 100%;
|
|
249
|
+
overflow: hidden;
|
|
250
|
+
|
|
251
|
+
&__pane {
|
|
252
|
+
display: flex;
|
|
253
|
+
max-height: 100%;
|
|
254
|
+
overflow: hidden;
|
|
255
|
+
}
|
|
241
256
|
|
|
242
257
|
&__separator {
|
|
243
258
|
position: relative;
|
|
244
|
-
z-index:
|
|
259
|
+
z-index: var(--bms-z-index-fixed);
|
|
245
260
|
|
|
246
261
|
&:before {
|
|
247
262
|
content: '';
|
|
@@ -286,5 +301,18 @@ function clamp(value: number, minValue: number, maxValue: number) {
|
|
|
286
301
|
}
|
|
287
302
|
}
|
|
288
303
|
}
|
|
304
|
+
|
|
305
|
+
&--dragging {
|
|
306
|
+
.split-window__separator {
|
|
307
|
+
&:before {
|
|
308
|
+
position: fixed;
|
|
309
|
+
top: 0;
|
|
310
|
+
left: 0;
|
|
311
|
+
width: 100%;
|
|
312
|
+
height: 100%;
|
|
313
|
+
transform: unset;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
289
317
|
}
|
|
290
318
|
</style>
|
|
@@ -60,21 +60,3 @@ Default.args = {
|
|
|
60
60
|
},
|
|
61
61
|
],
|
|
62
62
|
};
|
|
63
|
-
|
|
64
|
-
export const WithCustomSeparator = Template.bind({});
|
|
65
|
-
WithCustomSeparator.args = {
|
|
66
|
-
separator: '❤️',
|
|
67
|
-
breadcrumbs: [
|
|
68
|
-
{
|
|
69
|
-
to: { name: 'firstRoute' },
|
|
70
|
-
label: 'First route',
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
to: { name: 'secondRoute' },
|
|
74
|
-
label: 'Second route',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
label: 'Third and final route',
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
};
|
|
@@ -18,8 +18,8 @@ const Template = (args) => ({
|
|
|
18
18
|
},
|
|
19
19
|
template: `
|
|
20
20
|
<BmsMenu v-bind="args">
|
|
21
|
-
<template v-if="args.
|
|
22
|
-
<template v-if="args.
|
|
21
|
+
<template v-if="args.additional" #additional>{{args.additional}}</template>
|
|
22
|
+
<template v-if="args.footer" #footer>{{args.footer}}</template>
|
|
23
23
|
</BmsMenu>
|
|
24
24
|
`,
|
|
25
25
|
});
|
|
@@ -80,6 +80,6 @@ WithFooterSlot.args = {
|
|
|
80
80
|
},
|
|
81
81
|
],
|
|
82
82
|
activeLink: '/tutu',
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
additional: 'Additional',
|
|
84
|
+
footer: 'Footer',
|
|
85
85
|
};
|
|
@@ -21,8 +21,8 @@ const Template = (args) => ({
|
|
|
21
21
|
},
|
|
22
22
|
template: `
|
|
23
23
|
<BmsMenuNav v-bind="args">
|
|
24
|
-
<template v-if="args.
|
|
25
|
-
<template v-if="args.
|
|
24
|
+
<template v-if="args.additional" #additional>{{args.additional}}</template>
|
|
25
|
+
<template v-if="args.iconEndCustomSlot" #icon-end="{ item }" >
|
|
26
26
|
<BmsBadge :pending="item.badgeCount"></BmsBadge>
|
|
27
27
|
</template>
|
|
28
28
|
</BmsMenuNav>
|
|
@@ -189,5 +189,6 @@ WithAdditionalSlot.args = {
|
|
|
189
189
|
},
|
|
190
190
|
],
|
|
191
191
|
activeLink: { path: '/tutu' },
|
|
192
|
-
|
|
192
|
+
additional: 'Additional',
|
|
193
|
+
iconEndCustomSlot: true,
|
|
193
194
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import UiMenuItem from '@/components/navigation/UiMenuItem.vue';
|
|
2
|
-
import { Activity } from 'lucide-vue-next';
|
|
2
|
+
import { Activity, ShieldAlert, ShieldCheck, ShieldOff } from 'lucide-vue-next';
|
|
3
3
|
import { vueRouter } from 'storybook-vue3-router';
|
|
4
4
|
import template from '@/documentation/template_internal_component.mdx';
|
|
5
|
+
import { StatusType } from '@/models';
|
|
5
6
|
|
|
6
7
|
export default {
|
|
7
8
|
parameters: {
|
|
@@ -9,7 +10,8 @@ export default {
|
|
|
9
10
|
page: template,
|
|
10
11
|
},
|
|
11
12
|
},
|
|
12
|
-
|
|
13
|
+
tags: ['code-only'],
|
|
14
|
+
title: 'Composants/navigation/UiMenuItem',
|
|
13
15
|
component: UiMenuItem,
|
|
14
16
|
decorators: [
|
|
15
17
|
vueRouter([
|
|
@@ -77,3 +79,52 @@ Active.args = {
|
|
|
77
79
|
},
|
|
78
80
|
active: true,
|
|
79
81
|
};
|
|
82
|
+
|
|
83
|
+
const TemplateStatus = (args) => ({
|
|
84
|
+
components: {
|
|
85
|
+
UiMenuItem,
|
|
86
|
+
},
|
|
87
|
+
setup() {
|
|
88
|
+
return { args };
|
|
89
|
+
},
|
|
90
|
+
template: `
|
|
91
|
+
<UiMenuItem :item="args.items[0]"/>
|
|
92
|
+
<UiMenuItem :item="args.items[0]" :active="true"/>
|
|
93
|
+
<UiMenuItem :item="args.items[1]"/>
|
|
94
|
+
<UiMenuItem :item="args.items[1]" :active="true"/>
|
|
95
|
+
<UiMenuItem :item="args.items[2]"/>
|
|
96
|
+
<UiMenuItem :item="args.items[2]" :active="true"/>
|
|
97
|
+
<UiMenuItem :item="args.items[3]"/>
|
|
98
|
+
<UiMenuItem :item="args.items[3]" :active="true"/>
|
|
99
|
+
`,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export const WithStatusType = TemplateStatus.bind({});
|
|
103
|
+
WithStatusType.args = {
|
|
104
|
+
items: [
|
|
105
|
+
{
|
|
106
|
+
label: 'Item label',
|
|
107
|
+
link: 'http://google.fr',
|
|
108
|
+
icon: ShieldAlert,
|
|
109
|
+
status: StatusType.Danger,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
label: 'Item label',
|
|
113
|
+
link: 'http://google.fr',
|
|
114
|
+
icon: ShieldAlert,
|
|
115
|
+
status: StatusType.Warning,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
label: 'Item label',
|
|
119
|
+
link: 'http://google.fr',
|
|
120
|
+
icon: ShieldCheck,
|
|
121
|
+
status: StatusType.Success,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
label: 'Item label',
|
|
125
|
+
link: 'http://google.fr',
|
|
126
|
+
icon: ShieldOff,
|
|
127
|
+
status: StatusType.Information,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
};
|
|
@@ -1,31 +1,24 @@
|
|
|
1
1
|
import BmsEmptyScreen from '@/components/table/BmsEmptyScreen.vue';
|
|
2
2
|
|
|
3
|
-
// More on default export: https://storybook.js.org/docs/vue/writing-stories/introduction#default-export
|
|
4
3
|
export default {
|
|
5
4
|
title: 'Composants/table/EmptyScreen',
|
|
6
5
|
component: BmsEmptyScreen,
|
|
7
|
-
// More on argTypes: https://storybook.js.org/docs/vue/api/argtypes
|
|
8
6
|
argTypes: {},
|
|
9
7
|
};
|
|
10
8
|
|
|
11
|
-
// More on component templates: https://storybook.js.org/docs/vue/writing-stories/introduction#using-args
|
|
12
9
|
const Template = (args) => ({
|
|
13
|
-
// Components used in your story `template` are defined in the `components` object
|
|
14
10
|
components: {
|
|
15
11
|
BmsEmptyScreen,
|
|
16
12
|
},
|
|
17
|
-
// The story's `args` need to be mapped into the template through the `setup()` method
|
|
18
13
|
setup() {
|
|
19
14
|
return { args };
|
|
20
15
|
},
|
|
21
|
-
// And then the `args` are bound to your component with `v-bind="args"`
|
|
22
16
|
template: `
|
|
23
17
|
<BmsEmptyScreen v-bind="args" />
|
|
24
18
|
`,
|
|
25
19
|
});
|
|
26
20
|
|
|
27
21
|
export const Default = Template.bind({});
|
|
28
|
-
// More on args: https://storybook.js.org/docs/vue/writing-stories/args
|
|
29
22
|
Default.args = {
|
|
30
23
|
title: 'Not found',
|
|
31
24
|
description: "The requested data haven't been found",
|
|
@@ -7,7 +7,8 @@ export default {
|
|
|
7
7
|
page: template,
|
|
8
8
|
},
|
|
9
9
|
},
|
|
10
|
-
|
|
10
|
+
tags: ['code-only'],
|
|
11
|
+
title: 'Composants/table/UiFilterButton',
|
|
11
12
|
component: UiFilterButton,
|
|
12
13
|
argTypes: {},
|
|
13
14
|
};
|
|
@@ -19,16 +20,10 @@ const Template = (args) => ({
|
|
|
19
20
|
setup() {
|
|
20
21
|
return { args };
|
|
21
22
|
},
|
|
22
|
-
|
|
23
|
-
template: `
|
|
24
|
-
<div style="display:flex">
|
|
25
|
-
<UiFilterButton v-bind="args" />
|
|
26
|
-
</div>
|
|
27
|
-
`,
|
|
23
|
+
template: `<UiFilterButton v-bind="args" />`,
|
|
28
24
|
});
|
|
29
25
|
|
|
30
26
|
export const Default = Template.bind({});
|
|
31
|
-
// More on args: https://storybook.js.org/docs/vue/writing-stories/args
|
|
32
27
|
Default.args = {};
|
|
33
28
|
|
|
34
29
|
export const activeFilters = Template.bind({});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import BmsRelativeTime from '@/components/utils/BmsRelativeTime.vue';
|
|
2
2
|
|
|
3
|
-
// More on default export: https://storybook.js.org/docs/vue/writing-stories/introduction#default-export
|
|
4
3
|
export default {
|
|
5
4
|
title: 'Composants/utils/RelativeTime',
|
|
6
5
|
component: BmsRelativeTime,
|
|
@@ -11,17 +10,13 @@ export default {
|
|
|
11
10
|
},
|
|
12
11
|
};
|
|
13
12
|
|
|
14
|
-
// More on component templates: https://storybook.js.org/docs/vue/writing-stories/introduction#using-args
|
|
15
13
|
const Template = (args) => ({
|
|
16
|
-
// Components used in your story `template` are defined in the `components` object
|
|
17
14
|
components: {
|
|
18
15
|
BmsRelativeTime,
|
|
19
16
|
},
|
|
20
|
-
// The story's `args` need to be mapped into the template through the `setup()` method
|
|
21
17
|
setup() {
|
|
22
18
|
return { args };
|
|
23
19
|
},
|
|
24
|
-
// And then the `args` are bound to your component with `v-bind="args"`
|
|
25
20
|
template: `
|
|
26
21
|
<div style="width: 400px; text-align: center;">
|
|
27
22
|
<p>
|
|
@@ -44,5 +39,4 @@ const Template = (args) => ({
|
|
|
44
39
|
});
|
|
45
40
|
|
|
46
41
|
export const Primary = Template.bind({});
|
|
47
|
-
// More on args: https://storybook.js.org/docs/vue/writing-stories/args
|
|
48
42
|
Primary.args = {};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import NotificationItem from '../../plugins/notifications/NotificationItem.vue';
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
title: 'Composants/feedback/Notifications',
|
|
5
|
-
component: NotificationItem,
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const Template = (args) => ({
|
|
9
|
-
components: {
|
|
10
|
-
NotificationItem,
|
|
11
|
-
},
|
|
12
|
-
setup() {
|
|
13
|
-
return { args };
|
|
14
|
-
},
|
|
15
|
-
template: `
|
|
16
|
-
<NotificationItem v-bind="args">
|
|
17
|
-
</NotificationItem>
|
|
18
|
-
`,
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
export const Sucess = Template.bind({});
|
|
22
|
-
Sucess.args = {
|
|
23
|
-
notification: {
|
|
24
|
-
id: 1,
|
|
25
|
-
type: 'success',
|
|
26
|
-
text: 'Sucess',
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const Error = Template.bind({});
|
|
31
|
-
Error.args = {
|
|
32
|
-
notification: {
|
|
33
|
-
id: 1,
|
|
34
|
-
type: 'error',
|
|
35
|
-
text: 'Error',
|
|
36
|
-
},
|
|
37
|
-
};
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import UiMenuItem from '@/components/navigation/UiMenuItem.vue';
|
|
2
|
-
import { ShieldAlert, ShieldCheck, ShieldOff } from 'lucide-vue-next';
|
|
3
|
-
import { StatusType } from '../../models';
|
|
4
|
-
import template from '@/documentation/template_internal_component.mdx';
|
|
5
|
-
|
|
6
|
-
export default {
|
|
7
|
-
parameters: {
|
|
8
|
-
docs: {
|
|
9
|
-
page: template,
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
title: 'Composants/navigation/MenuItem',
|
|
13
|
-
component: UiMenuItem,
|
|
14
|
-
argTypes: {},
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const Template = (args) => ({
|
|
18
|
-
components: {
|
|
19
|
-
UiMenuItem,
|
|
20
|
-
},
|
|
21
|
-
setup() {
|
|
22
|
-
return { args };
|
|
23
|
-
},
|
|
24
|
-
template: `
|
|
25
|
-
<UiMenuItem :item="args.items[0]"/>
|
|
26
|
-
<UiMenuItem :item="args.items[0]" :active="true"/>
|
|
27
|
-
<UiMenuItem :item="args.items[1]"/>
|
|
28
|
-
<UiMenuItem :item="args.items[1]" :active="true"/>
|
|
29
|
-
<UiMenuItem :item="args.items[2]"/>
|
|
30
|
-
<UiMenuItem :item="args.items[2]" :active="true"/>
|
|
31
|
-
<UiMenuItem :item="args.items[3]"/>
|
|
32
|
-
<UiMenuItem :item="args.items[3]" :active="true"/>
|
|
33
|
-
`,
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
export const WithStatusType = Template.bind({});
|
|
37
|
-
WithStatusType.args = {
|
|
38
|
-
items: [
|
|
39
|
-
{
|
|
40
|
-
label: 'Item label',
|
|
41
|
-
link: 'http://google.fr',
|
|
42
|
-
icon: ShieldAlert,
|
|
43
|
-
status: StatusType.Danger,
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
label: 'Item label',
|
|
47
|
-
link: 'http://google.fr',
|
|
48
|
-
icon: ShieldAlert,
|
|
49
|
-
status: StatusType.Warning,
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
label: 'Item label',
|
|
53
|
-
link: 'http://google.fr',
|
|
54
|
-
icon: ShieldCheck,
|
|
55
|
-
status: StatusType.Success,
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
label: 'Item label',
|
|
59
|
-
link: 'http://google.fr',
|
|
60
|
-
icon: ShieldOff,
|
|
61
|
-
status: StatusType.Information,
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
};
|