@bethinkpl/design-system 19.0.3 → 20.0.1

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 (64) hide show
  1. package/.eslintrc.js +1 -0
  2. package/dist/design-system.umd.js +1009 -476
  3. package/dist/design-system.umd.js.map +1 -1
  4. package/dist/lib/js/components/Drawer/DrawerContent/DrawerContent.vue.d.ts +4 -3
  5. package/dist/lib/js/components/Drawer/DrawerDivider/DrawerDivider.vue.d.ts +20 -3
  6. package/dist/lib/js/components/Drawer/DrawerHeader/DrawerHeader.vue.d.ts +282 -3
  7. package/dist/lib/js/components/Drawer/DrawerListItem/DrawerListItem.vue.d.ts +228 -3
  8. package/dist/lib/js/components/Drawer/DrawerListItemGroup/DrawerListItemGroup.vue.d.ts +4 -3
  9. package/dist/lib/js/components/Drawer/DrawerSection/DrawerSection.vue.d.ts +283 -3
  10. package/dist/lib/js/components/Drawer/DrawerTile/DrawerTile.vue.d.ts +63 -3
  11. package/dist/lib/js/components/Headers/SectionHeader/SectionHeader.consts.d.ts +18 -0
  12. package/dist/lib/js/components/Headers/SectionHeader/SectionHeader.vue.d.ts +19 -1
  13. package/dist/lib/js/components/Icons/Icon/Icon.consts.d.ts +16 -0
  14. package/dist/lib/js/components/SelectList/SelectList.vue.d.ts +4 -3
  15. package/dist/lib/js/components/SelectList/SelectListItem/SelectListItem.vue.d.ts +258 -3
  16. package/dist/lib/js/components/SelectList/SelectListItemDivider/SelectListItemDivider.vue.d.ts +8 -3
  17. package/dist/lib/js/components/SelectList/SelectListItemTile/SelectListItemTile.vue.d.ts +62 -3
  18. package/dist/lib/js/components/SelectList/SelectListItemToggle/SelectListItemToggle.vue.d.ts +58 -3
  19. package/dist/lib/js/components/SelectList/SelectListSectionTitle/SelectListSectionTitle.vue.d.ts +14 -3
  20. package/dist/lib/js/components/Switch/Switch.consts.d.ts +21 -0
  21. package/dist/lib/js/components/Switch/Switch.stories.d.ts +5 -0
  22. package/dist/lib/js/components/Switch/Switch.vue.d.ts +280 -0
  23. package/dist/lib/js/components/Switch/index.d.ts +3 -0
  24. package/dist/lib/js/index.d.ts +2 -0
  25. package/docs/iframe.html +1 -1
  26. package/docs/main.d1b90503.iframe.bundle.js +1 -0
  27. package/docs/project.json +1 -1
  28. package/lib/js/components/Banner/Banner.vue +2 -0
  29. package/lib/js/components/Cards/CardExpandable/CardExpandable.vue +2 -0
  30. package/lib/js/components/Chip/Chip.vue +2 -0
  31. package/lib/js/components/Drawer/DrawerHeader/DrawerHeader.vue +2 -0
  32. package/lib/js/components/Drawer/DrawerSection/DrawerSection.stories.ts +75 -6
  33. package/lib/js/components/Drawer/DrawerSection/DrawerSection.vue +99 -68
  34. package/lib/js/components/Drawer/DrawerTile/DrawerTile.vue +2 -0
  35. package/lib/js/components/Dropdown/Dropdown.vue +2 -0
  36. package/lib/js/components/Form/Checkbox/Checkbox.vue +2 -0
  37. package/lib/js/components/Form/RadioButton/RadioButton.vue +2 -0
  38. package/lib/js/components/Form/SelectionControl/SelectionControl.vue +2 -0
  39. package/lib/js/components/Headers/OverlayHeader/OverlayHeader.vue +2 -0
  40. package/lib/js/components/Headers/SectionHeader/SectionHeader.consts.ts +22 -0
  41. package/lib/js/components/Headers/SectionHeader/SectionHeader.stories.ts +20 -4
  42. package/lib/js/components/Headers/SectionHeader/SectionHeader.vue +94 -12
  43. package/lib/js/components/Icons/Icon/Icon.consts.ts +18 -0
  44. package/lib/js/components/Layouts/ThreeColumnLayout/ThreeColumnLayout.vue +2 -0
  45. package/lib/js/components/Modal/Modal.vue +2 -0
  46. package/lib/js/components/Modals/Modal/Modal.vue +5 -3
  47. package/lib/js/components/Modals/ModalDialog/ModalDialog.vue +2 -0
  48. package/lib/js/components/Pagination/Pagination.vue +2 -0
  49. package/lib/js/components/PopOver/PopOver.vue +2 -0
  50. package/lib/js/components/RichList/RichListItem/RichListItem.vue +2 -0
  51. package/lib/js/components/SelectionTile/SelectionTile.vue +2 -0
  52. package/lib/js/components/SurveyQuestions/SurveyQuestionOpenEnded/SurveyQuestionOpenEnded.vue +2 -0
  53. package/lib/js/components/SurveyQuestions/SurveyQuestionScale/SurveyQuestionScale.vue +2 -0
  54. package/lib/js/components/SurveyQuestions/SurveyQuestionTextarea.vue +2 -0
  55. package/lib/js/components/Switch/Switch.consts.ts +29 -0
  56. package/lib/js/components/Switch/Switch.stories.ts +98 -0
  57. package/lib/js/components/Switch/Switch.vue +341 -0
  58. package/lib/js/components/Switch/index.ts +4 -0
  59. package/lib/js/components/TabItem/TabItem.vue +2 -0
  60. package/lib/js/components/Toggles/ToggleButton/ToggleButton.vue +2 -0
  61. package/lib/js/index.ts +2 -0
  62. package/lib/styles/settings/_icons.scss +78 -0
  63. package/package.json +1 -1
  64. package/docs/main.eb803853.iframe.bundle.js +0 -1
@@ -14,6 +14,9 @@
14
14
  <ds-icon
15
15
  v-if="iconLeft"
16
16
  class="sectionHeader__icon"
17
+ :class="{
18
+ [`-${iconLeftColor}`]: iconLeftColor,
19
+ }"
17
20
  :icon="iconLeft"
18
21
  :size="iconSize"
19
22
  />
@@ -24,6 +27,9 @@
24
27
  <ds-icon
25
28
  v-if="iconRight"
26
29
  class="sectionHeader__icon"
30
+ :class="{
31
+ [`-${iconRightColor}`]: iconRightColor,
32
+ }"
27
33
  :icon="iconRight"
28
34
  :size="iconSize"
29
35
  />
@@ -55,8 +61,8 @@
55
61
  class="sectionHeader__supportingText"
56
62
  :class="{
57
63
  '-withoutPadding':
58
- !divider ||
59
- (!divider && mobileLayout === SECTION_HEADER_MOBILE_LAYOUTS.HORIZONTAL),
64
+ !hasDivider ||
65
+ (!hasDivider && mobileLayout === SECTION_HEADER_MOBILE_LAYOUTS.HORIZONTAL),
60
66
  }"
61
67
  >{{ supportingText }}
62
68
  </div>
@@ -64,20 +70,21 @@
64
70
  <div
65
71
  v-if="$slots.default && showSlot"
66
72
  class="sectionHeader__slotVertical"
67
- :class="{ '-withoutPadding': !divider }"
73
+ :class="{ '-withoutPadding': !hasDivider }"
68
74
  >
69
75
  <slot />
70
76
  </div>
71
77
  </div>
72
- <ds-divider v-if="divider" />
78
+ <ds-divider v-if="hasDivider" />
73
79
  </div>
74
80
  </template>
75
81
 
76
82
  <style scoped lang="scss">
77
83
  @import '../../../../styles/settings/colors/tokens';
78
- @import '../../../../styles/settings/typography/tokens';
84
+ @import '../../../../styles/settings/icons';
79
85
  @import '../../../../styles/settings/media-queries';
80
86
  @import '../../../../styles/settings/spacings';
87
+ @import '../../../../styles/settings/typography/tokens';
81
88
 
82
89
  .sectionHeader {
83
90
  $root: &;
@@ -121,6 +128,10 @@
121
128
  }
122
129
  }
123
130
 
131
+ &__icon {
132
+ color: $color-neutral-icon;
133
+ }
134
+
124
135
  &.-expandable &__header {
125
136
  cursor: pointer;
126
137
 
@@ -135,15 +146,21 @@
135
146
  }
136
147
  }
137
148
 
149
+ &__icon,
150
+ &.-size-xx-small &__icon {
151
+ @include coloredIcon();
152
+ }
153
+
154
+ &.-expandable &__header:hover &__icon,
155
+ &.-expandable.-size-xx-small &__header:hover &__icon {
156
+ @include coloredIcon('hovered');
157
+ }
158
+
138
159
  &__titleWrapper {
139
160
  align-items: center;
140
161
  display: flex;
141
162
  }
142
163
 
143
- &__icon {
144
- color: $color-neutral-icon;
145
- }
146
-
147
164
  &__titleContainer {
148
165
  display: flex;
149
166
  flex-direction: column;
@@ -238,6 +255,38 @@
238
255
  }
239
256
  }
240
257
 
258
+ &.-size-xx-small {
259
+ #{$root}__main {
260
+ padding: $space-xxxxxs 0;
261
+ }
262
+
263
+ #{$root}__titleWrapper {
264
+ gap: $space-xxxs;
265
+ }
266
+
267
+ #{$root}__header {
268
+ @include info-s-extensive-bold-uppercase;
269
+ }
270
+
271
+ #{$root}__icon {
272
+ color: $color-neutral-icon-weak;
273
+ }
274
+
275
+ #{$root}__title {
276
+ color: $color-neutral-text-weak;
277
+ }
278
+
279
+ &.-expandable #{$root}__header:hover {
280
+ #{$root}__icon {
281
+ color: $color-neutral-icon-weak-hovered;
282
+ }
283
+
284
+ #{$root}__title {
285
+ color: $color-neutral-text-weak-hovered;
286
+ }
287
+ }
288
+ }
289
+
241
290
  &__slotHorizontal {
242
291
  display: none;
243
292
  flex-shrink: 0;
@@ -273,7 +322,12 @@
273
322
  </style>
274
323
 
275
324
  <script lang="ts">
276
- import { SECTION_HEADER_MOBILE_LAYOUTS, SECTION_HEADER_SIZES } from './SectionHeader.consts';
325
+ import {
326
+ SECTION_HEADER_MOBILE_LAYOUTS,
327
+ SECTION_HEADER_SIZES,
328
+ SECTION_HEADER_ICON_COLORS,
329
+ SectionHeaderIconColor,
330
+ } from './SectionHeader.consts';
277
331
  import DsIcon, { ICON_SIZES, IconItem, ICONS } from '../../Icons/Icon';
278
332
  import DsIconButton, { ICON_BUTTON_COLORS, ICON_BUTTON_SIZES } from '../../Buttons/IconButton';
279
333
  import DsDivider from '../../Divider';
@@ -302,6 +356,13 @@ export default {
302
356
  return Object.values(ICONS).includes(toRaw(iconLeft));
303
357
  },
304
358
  },
359
+ iconLeftColor: {
360
+ type: String as () => SectionHeaderIconColor,
361
+ default: null,
362
+ validator(iconLeftColor: SectionHeaderIconColor) {
363
+ return Object.values(SECTION_HEADER_ICON_COLORS).includes(toRaw(iconLeftColor));
364
+ },
365
+ },
305
366
  iconRight: {
306
367
  type: Object as () => IconItem,
307
368
  default: null,
@@ -309,6 +370,13 @@ export default {
309
370
  return Object.values(ICONS).includes(toRaw(iconRight));
310
371
  },
311
372
  },
373
+ iconRightColor: {
374
+ type: String as () => SectionHeaderIconColor,
375
+ default: null,
376
+ validator(iconRightColor: SectionHeaderIconColor) {
377
+ return Object.values(SECTION_HEADER_ICON_COLORS).includes(toRaw(iconRightColor));
378
+ },
379
+ },
312
380
  isExpanded: {
313
381
  type: Boolean,
314
382
  default: false,
@@ -336,7 +404,7 @@ export default {
336
404
  type: String,
337
405
  default: null,
338
406
  },
339
- divider: {
407
+ hasDivider: {
340
408
  type: Boolean,
341
409
  default: true,
342
410
  },
@@ -346,6 +414,8 @@ export default {
346
414
  validator: (value) => Object.values(SECTION_HEADER_MOBILE_LAYOUTS).includes(value),
347
415
  },
348
416
  },
417
+ // TODO fix me when touching this file
418
+ // eslint-disable-next-line vue/require-emit-validator
349
419
  emits: ['info-click', 'update:isExpanded'],
350
420
  data() {
351
421
  return {
@@ -354,6 +424,7 @@ export default {
354
424
  ICON_BUTTON_SIZES: Object.freeze(ICON_BUTTON_SIZES),
355
425
  ICON_BUTTON_COLORS: Object.freeze(ICON_BUTTON_COLORS),
356
426
  SECTION_HEADER_MOBILE_LAYOUTS: Object.freeze(SECTION_HEADER_MOBILE_LAYOUTS),
427
+ isExpandedInternal: false,
357
428
  };
358
429
  },
359
430
  computed: {
@@ -377,6 +448,16 @@ export default {
377
448
  return ICON_SIZES.XX_SMALL;
378
449
  },
379
450
  },
451
+ watch: {
452
+ isExpanded: {
453
+ handler(isExpanded) {
454
+ if (isExpanded !== this.isExpandedInternal) {
455
+ this.isExpandedInternal = isExpanded;
456
+ }
457
+ },
458
+ immediate: true,
459
+ },
460
+ },
380
461
  methods: {
381
462
  onInfoClicked(): void {
382
463
  this.$emit('info-click');
@@ -385,7 +466,8 @@ export default {
385
466
  if (!this.isExpandable) {
386
467
  return;
387
468
  }
388
- this.$emit('update:isExpanded', !this.isExpanded);
469
+ this.isExpandedInternal = !this.isExpandedInternal;
470
+ this.$emit('update:isExpanded', this.isExpandedInternal);
389
471
  },
390
472
  },
391
473
  };
@@ -5,6 +5,24 @@ import CommentsCheck from '../../../../images/icons/comments-check.svg';
5
5
  import { FONTAWESOME_ICONS } from '../../../icons/fontawesome';
6
6
  import { Value } from '../../../utils/type.utils';
7
7
 
8
+ export const ICON_COLORS = {
9
+ ACCENT: 'accent',
10
+ DANGER: 'danger',
11
+ DEFAULT: 'default',
12
+ FAIL: 'fail',
13
+ INFO: 'info',
14
+ INVERTED: 'inverted',
15
+ NEUTRAL: 'neutral',
16
+ NEUTRAL_STRONG: 'neutralStrong',
17
+ NEUTRAL_WEAK: 'neutralWeak',
18
+ PRIMARY: 'primary',
19
+ PRIMARY_WEAK: 'primaryWeak',
20
+ SUCCESS: 'success',
21
+ WARNING: 'warning',
22
+ };
23
+
24
+ export type IconColor = Value<typeof ICON_COLORS>;
25
+
8
26
  export const ICON_SIZES = {
9
27
  XXX_SMALL: 'xxx-small',
10
28
  XX_SMALL: 'xx-small',
@@ -235,6 +235,8 @@ export default {
235
235
  default: false,
236
236
  },
237
237
  },
238
+ // TODO fix me when touching this file
239
+ // eslint-disable-next-line vue/require-emit-validator
238
240
  emits: ['overlay-clicked'],
239
241
  data() {
240
242
  return {
@@ -117,6 +117,8 @@ export default {
117
117
  default: false,
118
118
  },
119
119
  },
120
+ // TODO fix me when touching this file
121
+ // eslint-disable-next-line vue/require-emit-validator
120
122
  emits: ['close-modal'],
121
123
  data() {
122
124
  return {
@@ -312,10 +312,10 @@ $image-height-small: 140px;
312
312
 
313
313
  <script lang="ts">
314
314
  import FeatureIcon from '../../Icons/FeatureIcon/FeatureIcon.vue';
315
- import { MODAL_SIZES, MODAL_HEADER_TITLE_SIZES } from './Modal.consts';
316
- import { ICONS, ICON_SIZES } from '../../Icons/Icon';
315
+ import { MODAL_HEADER_TITLE_SIZES, MODAL_SIZES } from './Modal.consts';
316
+ import { ICON_SIZES, ICONS } from '../../Icons/Icon';
317
317
  import { FEATURE_ICON_COLOR, FEATURE_ICON_SIZES } from '../../Icons/FeatureIcon';
318
- import WnlButton, { BUTTON_COLORS, BUTTON_TYPES, BUTTON_ELEVATIONS } from '../../Buttons/Button';
318
+ import WnlButton, { BUTTON_COLORS, BUTTON_ELEVATIONS, BUTTON_TYPES } from '../../Buttons/Button';
319
319
  import WnlIconButton, { ICON_BUTTON_COLORS } from '../../Buttons/IconButton';
320
320
  import { toRaw } from 'vue';
321
321
 
@@ -405,6 +405,8 @@ export default {
405
405
  default: null,
406
406
  },
407
407
  },
408
+ // TODO fix me when touching this file
409
+ /* eslint vue/require-emit-validator: 0 */
408
410
  emits: [
409
411
  'tertiary-button-click',
410
412
  'checkbox-change',
@@ -86,6 +86,8 @@ export default {
86
86
  },
87
87
  },
88
88
  },
89
+ // TODO fix me when touching this file
90
+ // eslint-disable-next-line vue/require-emit-validator
89
91
  emits: ['close-modal', 'primary-button-click', 'secondary-button-click'],
90
92
  data() {
91
93
  return {
@@ -306,6 +306,8 @@ export default {
306
306
  required: true,
307
307
  },
308
308
  },
309
+ // TODO fix me when touching this file
310
+ // eslint-disable-next-line vue/require-emit-validator
309
311
  emits: ['change-page'],
310
312
  data() {
311
313
  return {
@@ -273,6 +273,8 @@ export default {
273
273
  default: '',
274
274
  },
275
275
  },
276
+ // TODO fix me when touching this file
277
+ // eslint-disable-next-line vue/require-emit-validator
276
278
  emits: ['button-click'],
277
279
  data() {
278
280
  return {
@@ -392,6 +392,8 @@ export default {
392
392
  default: null,
393
393
  },
394
394
  },
395
+ // TODO fix me when touching this file
396
+ // eslint-disable-next-line vue/require-emit-validator
395
397
  emits: ['icon-click', 'click'],
396
398
  data() {
397
399
  return {
@@ -217,6 +217,8 @@ export default defineComponent({
217
217
  },
218
218
  },
219
219
  },
220
+ // TODO fix me when touching this file
221
+ // eslint-disable-next-line vue/require-emit-validator
220
222
  emits: ['update:isSelected', 'icon-click'],
221
223
  data() {
222
224
  return {
@@ -121,6 +121,8 @@ export default {
121
121
  },
122
122
  },
123
123
  },
124
+ // TODO fix me when touching this file
125
+ // eslint-disable-next-line vue/require-emit-validator
124
126
  emits: ['input'],
125
127
  data() {
126
128
  return {
@@ -297,6 +297,8 @@ export default {
297
297
  },
298
298
  },
299
299
  },
300
+ // TODO fix me when touching this file
301
+ // eslint-disable-next-line vue/require-emit-validator
300
302
  emits: ['elaboration-change', 'select-change'],
301
303
  data() {
302
304
  return {
@@ -50,6 +50,8 @@ export default {
50
50
  default: false,
51
51
  },
52
52
  },
53
+ // TODO fix me when touching this file
54
+ // eslint-disable-next-line vue/require-emit-validator
53
55
  emits: ['input'],
54
56
  watch: {
55
57
  value() {
@@ -0,0 +1,29 @@
1
+ import { Value } from '../../utils/type.utils';
2
+
3
+ export const SWITCH_SIZES = {
4
+ SMALL: 'small',
5
+ MEDIUM: 'medium',
6
+ } as const;
7
+
8
+ export type SwitchSize = Value<typeof SWITCH_SIZES>;
9
+
10
+ export const SWITCH_RADIUSES = {
11
+ CAPSULE: 'capsule',
12
+ ROUNDED: 'rounded',
13
+ } as const;
14
+
15
+ export type SwitchRadius = Value<typeof SWITCH_RADIUSES>;
16
+
17
+ export const SWITCH_STATE = {
18
+ DEFAULT: 'default',
19
+ DISABLED: 'disabled',
20
+ } as const;
21
+
22
+ export type SwitchState = typeof SWITCH_STATE[keyof typeof SWITCH_STATE];
23
+
24
+ export const SWITCH_SIDE = {
25
+ LEFT: 'left',
26
+ RIGHT: 'right',
27
+ } as const;
28
+
29
+ export type SwitchSelection = typeof SWITCH_SIDE[keyof typeof SWITCH_SIDE];
@@ -0,0 +1,98 @@
1
+ import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue3';
2
+ import DsSwitch from './Switch.vue';
3
+ import Icon, { ICONS } from '../Icons/Icon';
4
+ import { SWITCH_RADIUSES, SWITCH_SIDE, SWITCH_SIZES, SWITCH_STATE } from './Switch.consts';
5
+
6
+ export default {
7
+ title: 'Components/Switch',
8
+ component: DsSwitch,
9
+ } as Meta<typeof DsSwitch>;
10
+
11
+ const StoryTemplate: StoryFn<typeof DsSwitch> = (args, { updateArgs }) => ({
12
+ components: {
13
+ DsSwitch,
14
+ Icon,
15
+ },
16
+ setup() {
17
+ return { ...args };
18
+ },
19
+ methods: {
20
+ onSelectedUpdated(side) {
21
+ console.log(side);
22
+ },
23
+ },
24
+ data() {
25
+ return {
26
+ ICONS: Object.freeze(ICONS),
27
+ };
28
+ },
29
+ template: `
30
+ <div style="width: 500px; height: 300px; padding: 10px; border: 1px solid var(--raw-gray-100); position:relative">
31
+ <ds-switch
32
+ :size="size"
33
+ :radius="radius"
34
+ :icon-left="ICONS[iconLeft]"
35
+ :icon-right="ICONS[iconRight]"
36
+ :label-left="labelLeft"
37
+ :label-right="labelRight"
38
+ :state="state"
39
+ :selectedSide="selectedSide"
40
+ @update:selectedSide="onSelectedUpdated"
41
+ />
42
+ </div>
43
+ `,
44
+ });
45
+
46
+ export const Interactive = StoryTemplate.bind({});
47
+
48
+ const args = {
49
+ size: SWITCH_SIZES.MEDIUM,
50
+ radius: SWITCH_RADIUSES.CAPSULE,
51
+ iconLeft: null,
52
+ iconRight: null,
53
+ labelLeft: 'Left option',
54
+ labelRight: 'Right option',
55
+ state: SWITCH_STATE.DEFAULT,
56
+ selectedSide: SWITCH_SIDE.LEFT,
57
+ } as Args;
58
+
59
+ const argTypes = {
60
+ size: {
61
+ control: { type: 'select', options: Object.values(SWITCH_SIZES) },
62
+ defaultValue: SWITCH_SIZES.MEDIUM,
63
+ },
64
+ radius: {
65
+ control: { type: 'select', options: Object.values(SWITCH_RADIUSES) },
66
+ defaultValue: SWITCH_RADIUSES.CAPSULE,
67
+ },
68
+ iconLeft: {
69
+ control: { type: 'select', options: [null, ...Object.keys(ICONS)] },
70
+ defaultValue: null,
71
+ },
72
+ iconRight: {
73
+ control: { type: 'select', options: [null, ...Object.keys(ICONS)] },
74
+ defaultValue: null,
75
+ },
76
+ state: {
77
+ control: { type: 'select', options: Object.values(SWITCH_STATE) },
78
+ defaultValue: SWITCH_STATE.DEFAULT,
79
+ },
80
+ selectedSide: {
81
+ control: { type: 'select', options: Object.values(SWITCH_SIDE) },
82
+ defaultValue: SWITCH_SIDE.LEFT,
83
+ },
84
+ } as ArgTypes;
85
+
86
+ Interactive.argTypes = argTypes;
87
+
88
+ Interactive.args = args;
89
+
90
+ Interactive.parameters = {
91
+ actions: {
92
+ handles: ['updated:selectedSide'],
93
+ },
94
+ design: {
95
+ type: 'figma',
96
+ url: 'https://www.figma.com/file/izQdYyiBR1GQgFkaOIfIJI/LMS---DS-Components?type=design&node-id=7270-124052&mode=design&t=cVof0yT3M88A1z0U-0',
97
+ },
98
+ };