@telus-uds/components-base 1.50.0 → 1.51.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 (70) hide show
  1. package/CHANGELOG.md +22 -2
  2. package/component-docs.json +160 -46
  3. package/lib/A11yText/index.js +8 -0
  4. package/lib/Divider/Divider.js +4 -0
  5. package/lib/IconButton/IconButton.js +16 -0
  6. package/lib/Link/ChevronLink.js +4 -0
  7. package/lib/Link/LinkBase.js +1 -1
  8. package/lib/Modal/Modal.js +16 -0
  9. package/lib/MultiSelectFilter/ModalOverlay.js +24 -8
  10. package/lib/MultiSelectFilter/MultiSelectFilter.js +154 -21
  11. package/lib/Pagination/PageButton.js +12 -0
  12. package/lib/Pagination/Pagination.js +12 -0
  13. package/lib/QuickLinks/QuickLinks.js +12 -0
  14. package/lib/QuickLinksFeature/QuickLinksFeatureItem.js +62 -41
  15. package/lib/Responsive/Responsive.js +7 -0
  16. package/lib/Select/Group.js +4 -0
  17. package/lib/Select/Group.native.js +4 -0
  18. package/lib/Select/Item.js +4 -0
  19. package/lib/SideNav/ItemsGroup.js +4 -0
  20. package/lib/SideNav/SideNav.js +8 -0
  21. package/lib/StepTracker/Step.js +35 -14
  22. package/lib/StepTracker/StepTracker.js +21 -2
  23. package/lib/StepTracker/dictionary.js +24 -4
  24. package/lib/Tabs/Tabs.js +20 -0
  25. package/lib-module/A11yText/index.js +8 -0
  26. package/lib-module/Divider/Divider.js +4 -0
  27. package/lib-module/IconButton/IconButton.js +16 -0
  28. package/lib-module/Link/ChevronLink.js +4 -0
  29. package/lib-module/Link/LinkBase.js +1 -1
  30. package/lib-module/Modal/Modal.js +16 -0
  31. package/lib-module/MultiSelectFilter/ModalOverlay.js +25 -9
  32. package/lib-module/MultiSelectFilter/MultiSelectFilter.js +154 -23
  33. package/lib-module/Pagination/PageButton.js +12 -0
  34. package/lib-module/Pagination/Pagination.js +12 -0
  35. package/lib-module/QuickLinks/QuickLinks.js +12 -0
  36. package/lib-module/QuickLinksFeature/QuickLinksFeatureItem.js +64 -43
  37. package/lib-module/Responsive/Responsive.js +7 -0
  38. package/lib-module/Select/Group.js +4 -0
  39. package/lib-module/Select/Group.native.js +4 -0
  40. package/lib-module/Select/Item.js +4 -0
  41. package/lib-module/SideNav/ItemsGroup.js +4 -0
  42. package/lib-module/SideNav/SideNav.js +8 -0
  43. package/lib-module/StepTracker/Step.js +35 -14
  44. package/lib-module/StepTracker/StepTracker.js +21 -2
  45. package/lib-module/StepTracker/dictionary.js +24 -4
  46. package/lib-module/Tabs/Tabs.js +20 -0
  47. package/package.json +2 -2
  48. package/src/A11yText/index.jsx +6 -0
  49. package/src/Divider/Divider.jsx +3 -0
  50. package/src/IconButton/IconButton.jsx +12 -0
  51. package/src/Link/ChevronLink.jsx +3 -0
  52. package/src/Link/LinkBase.jsx +3 -1
  53. package/src/Modal/Modal.jsx +12 -0
  54. package/src/MultiSelectFilter/ModalOverlay.jsx +30 -6
  55. package/src/MultiSelectFilter/MultiSelectFilter.jsx +142 -20
  56. package/src/Pagination/PageButton.jsx +9 -0
  57. package/src/Pagination/Pagination.jsx +9 -0
  58. package/src/QuickLinks/QuickLinks.jsx +9 -0
  59. package/src/QuickLinksFeature/QuickLinksFeatureItem.jsx +42 -35
  60. package/src/Responsive/Responsive.jsx +6 -0
  61. package/src/Select/Group.jsx +3 -0
  62. package/src/Select/Group.native.jsx +3 -0
  63. package/src/Select/Item.jsx +3 -0
  64. package/src/SideNav/ItemsGroup.jsx +3 -0
  65. package/src/SideNav/SideNav.jsx +6 -0
  66. package/src/StepTracker/Step.jsx +34 -10
  67. package/src/StepTracker/StepTracker.jsx +23 -2
  68. package/src/StepTracker/dictionary.js +24 -4
  69. package/src/Tabs/Tabs.jsx +15 -0
  70. package/src/Typography/Typography.jsx +1 -0
@@ -96,17 +96,18 @@ const selectKnobStyles = (_ref4, isCompleted, isCurrent) => {
96
96
  height: knobSize,
97
97
  width: knobSize,
98
98
  ...(isCompleted && {
99
- backgroundColor: knobCompletedBackgroundColor,
100
- borderColor: knobCompletedBorderColor,
101
- paddingLeft: knobCompletedPaddingLeft,
102
- paddingTop: knobCompletedPaddingTop
103
- }),
104
- ...(isCurrent && {
105
99
  backgroundColor: knobCurrentBackgroundColor,
106
100
  borderColor: knobCurrentBorderColor,
107
101
  borderWidth: knobCurrentBorderWidth,
108
102
  paddingLeft: knobCurrentPaddingLeft,
109
103
  paddingTop: knobCurrentPaddingTop
104
+ }),
105
+ ...(isCurrent && {
106
+ backgroundColor: knobCompletedBackgroundColor,
107
+ borderColor: knobCompletedBorderColor,
108
+ borderWidth: knobCurrentBorderWidth,
109
+ paddingLeft: knobCompletedPaddingLeft,
110
+ paddingTop: knobCompletedPaddingTop
110
111
  })
111
112
  };
112
113
  };
@@ -128,7 +129,26 @@ const selectLabelContainerStyles = _ref5 => {
128
129
  };
129
130
  };
130
131
 
131
- const selectLabelStyles = (_ref6, themeOptions, isCurrent) => {
132
+ const selectStepLabelStyles = (_ref6, themeOptions, isCurrent) => {
133
+ let {
134
+ stepLabelColor,
135
+ labelCurrentColor,
136
+ stepLabelFontWeight,
137
+ stepLabelFontSize,
138
+ stepLabelFontName,
139
+ stepLabelLineHeight
140
+ } = _ref6;
141
+ return (0, _ThemeProvider.applyTextStyles)({
142
+ color: isCurrent ? labelCurrentColor : stepLabelColor,
143
+ fontSize: stepLabelFontSize,
144
+ lineHeight: stepLabelLineHeight,
145
+ fontWeight: stepLabelFontWeight,
146
+ fontName: stepLabelFontName,
147
+ themeOptions
148
+ });
149
+ };
150
+
151
+ const selectLabelStyles = (_ref7, themeOptions, isCurrent) => {
132
152
  let {
133
153
  labelColor,
134
154
  labelCurrentColor,
@@ -137,7 +157,7 @@ const selectLabelStyles = (_ref6, themeOptions, isCurrent) => {
137
157
  labelFontWeight,
138
158
  labelFontName,
139
159
  labelLineHeight
140
- } = _ref6;
160
+ } = _ref7;
141
161
  return (0, _ThemeProvider.applyTextStyles)({
142
162
  color: isCurrent ? labelCurrentColor : labelColor,
143
163
  fontSize: labelFontSize,
@@ -164,7 +184,7 @@ const getStepTestID = (isCompleted, isCurrent) => {
164
184
  */
165
185
 
166
186
 
167
- const Step = _ref7 => {
187
+ const Step = _ref8 => {
168
188
  let {
169
189
  label,
170
190
  name,
@@ -173,11 +193,12 @@ const Step = _ref7 => {
173
193
  stepIndex = 0,
174
194
  tokens,
175
195
  ...rest
176
- } = _ref7;
196
+ } = _ref8;
177
197
  const {
178
198
  completedIcon,
179
199
  showStepLabel,
180
200
  showStepName,
201
+ textStepTrackerLabel,
181
202
  ...themeTokens
182
203
  } = tokens;
183
204
  const isFirst = stepIndex === 0;
@@ -211,11 +232,11 @@ const Step = _ref7 => {
211
232
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
212
233
  style: [staticStyles.knob, selectKnobStyles(themeTokens, isCompleted, isCurrent)],
213
234
  testID: getStepTestID(isCompleted, isCurrent),
214
- children: [isCompleted && completedIcon && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
235
+ children: [(isCompleted && completedIcon || isCurrent && !completedIcon) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
236
+ style: selectCurrentInnerStyles(themeTokens)
237
+ }), isCurrent && completedIcon && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
215
238
  icon: completedIcon,
216
239
  tokens: selectCompletedIconTokens(themeTokens)
217
- }), isCurrent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
218
- style: selectCurrentInnerStyles(themeTokens)
219
240
  })]
220
241
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
221
242
  style: [staticStyles.connector, !isLast && selectConnectorStyles(themeTokens, isCompleted)]
@@ -223,7 +244,7 @@ const Step = _ref7 => {
223
244
  }), showStepLabel && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
224
245
  style: [staticStyles.stepLabelContainer, selectLabelContainerStyles(tokens)],
225
246
  children: [showStepName && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.default, {
226
- style: [staticStyles.centeredText, selectLabelStyles(tokens, themeOptions, isCurrent)],
247
+ style: [staticStyles.centeredText, selectStepLabelStyles(tokens, themeOptions, isCurrent)],
227
248
  children: name
228
249
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.default, {
229
250
  direction: "row",
@@ -131,13 +131,16 @@ const StepTracker = /*#__PURE__*/(0, _react.forwardRef)((_ref4, ref) => {
131
131
  } = (0, _ThemeProvider.useThemeTokens)('StepTracker', tokens, variant, {
132
132
  viewport
133
133
  });
134
+ const {
135
+ textStepTrackerLabel
136
+ } = themeTokens;
134
137
  const getCopy = (0, _useCopy.default)({
135
138
  dictionary,
136
139
  copy
137
140
  });
138
- const stepTrackerLabel = showStepTrackerLabel ? getCopy('stepTrackerLabel').replace('%{stepNumber}', current < steps.length ? current + 1 : steps.length).replace('%{stepCount}', steps.length).replace('%{stepLabel}', current < steps.length ? steps[current] : steps[steps.length - 1]) : '';
141
+ const stepTrackerLabel = showStepTrackerLabel ? (typeof copy === 'string' ? getCopy(textStepTrackerLabel ?? 1).stepTrackerLabel : getCopy('stepTrackerLabel')).replace('%{stepNumber}', current < steps.length ? current + 1 : steps.length).replace('%{stepCount}', steps.length).replace('%{stepLabel}', current < steps.length ? steps[current] : steps[steps.length - 1]) : '';
139
142
 
140
- const getStepLabel = index => themeTokens.showStepLabel ? getCopy('stepLabel').replace('%{stepNumber}', index + 1) : '';
143
+ const getStepLabel = index => themeTokens.showStepLabel ? (typeof copy === 'string' ? getCopy(textStepTrackerLabel ?? 1).stepLabel : getCopy('stepLabel')).replace('%{stepNumber}', index + 1) : '';
141
144
 
142
145
  const {
143
146
  themeOptions
@@ -191,12 +194,28 @@ const dictionaryContentShape = _propTypes.default.shape({
191
194
  });
192
195
 
193
196
  StepTracker.propTypes = { ...selectedSystemPropTypes,
197
+
198
+ /**
199
+ * The current step, 0-based number
200
+ */
194
201
  current: _propTypes.default.number,
202
+
203
+ /**
204
+ * The language to use for the labels
205
+ */
195
206
  copy: _propTypes.default.oneOfType([_propTypes.default.oneOf(['en', 'fr']), dictionaryContentShape]),
207
+
208
+ /**
209
+ * Custom dictionary containing the labels to use for the steps
210
+ */
196
211
  dictionary: _propTypes.default.shape({
197
212
  en: dictionaryContentShape,
198
213
  fr: dictionaryContentShape
199
214
  }),
215
+
216
+ /**
217
+ * An array of strings defining the step titles
218
+ */
200
219
  steps: _propTypes.default.arrayOf(_propTypes.default.string),
201
220
  tokens: (0, _utils.getTokensPropType)('StepTracker'),
202
221
  variant: _utils.variantProp.propType
@@ -6,12 +6,32 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _default = {
8
8
  en: {
9
- stepLabel: 'Step %{stepNumber}',
10
- stepTrackerLabel: 'Step %{stepNumber} of %{stepCount}: %{stepLabel}'
9
+ 1: {
10
+ stepLabel: 'Step %{stepNumber}',
11
+ stepTrackerLabel: 'Step %{stepNumber} of %{stepCount}: %{stepLabel}'
12
+ },
13
+ 2: {
14
+ stepLabel: '%{stepNumber}.',
15
+ stepTrackerLabel: 'Step %{stepNumber} of %{stepCount}: %{stepLabel}'
16
+ },
17
+ 3: {
18
+ stepLabel: 'Step %{stepNumber}',
19
+ stepTrackerLabel: 'Step %{stepNumber} of %{stepCount}: %{stepLabel}'
20
+ }
11
21
  },
12
22
  fr: {
13
- stepLabel: 'Étape %{stepNumber}',
14
- stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
23
+ 1: {
24
+ stepLabel: 'Étape %{stepNumber}',
25
+ stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
26
+ },
27
+ 2: {
28
+ stepLabel: '%{stepNumber}.',
29
+ stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
30
+ },
31
+ 3: {
32
+ stepLabel: 'Étape %{stepNumber}',
33
+ stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
34
+ }
15
35
  }
16
36
  };
17
37
  exports.default = _default;
package/lib/Tabs/Tabs.js CHANGED
@@ -154,6 +154,10 @@ const Tabs = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
154
154
  Tabs.displayName = 'Tabs';
155
155
  Tabs.propTypes = { ...selectedSystemPropTypes,
156
156
  ..._utils.withLinkRouter.PropTypes,
157
+
158
+ /**
159
+ * Array of `TabsItem`s
160
+ */
157
161
  items: _propTypes.default.arrayOf(_propTypes.default.shape({ ...selectedItemPropTypes,
158
162
  ..._utils.withLinkRouter.PropTypes,
159
163
  href: _propTypes.default.string,
@@ -161,11 +165,27 @@ Tabs.propTypes = { ...selectedSystemPropTypes,
161
165
  id: _propTypes.default.string,
162
166
  ref: _airbnbPropTypes.default.ref()
163
167
  })),
168
+
169
+ /**
170
+ * `id` property of the current tab in the items array
171
+ */
164
172
  value: _propTypes.default.string,
165
173
  initialValue: _propTypes.default.string,
174
+
175
+ /**
176
+ * Callback for when the selected tab changes
177
+ */
166
178
  onChange: _propTypes.default.func,
167
179
  tokens: (0, _utils.getTokensPropType)('Tabs'),
180
+
181
+ /**
182
+ * Custom tokens for `TabsItem`
183
+ */
168
184
  itemTokens: (0, _utils.getTokensPropType)('TabsItem'),
185
+
186
+ /**
187
+ * Custom tokens for `HorizontalScrollButton`
188
+ */
169
189
  scrollButtonTokens: (0, _utils.getTokensPropType)('HorizontalScrollButton'),
170
190
  variant: _utils.variantProp.propType
171
191
  };
@@ -37,7 +37,15 @@ const A11yText = /*#__PURE__*/forwardRef((_ref, ref) => {
37
37
  });
38
38
  A11yText.displayName = 'A11yText';
39
39
  A11yText.propTypes = { ...selectedSystemPropTypes,
40
+
41
+ /**
42
+ * Text to be read by screen readers
43
+ */
40
44
  text: PropTypes.string.isRequired,
45
+
46
+ /**
47
+ * Whether text should be rendered as a heading
48
+ */
41
49
  heading: PropTypes.bool
42
50
  };
43
51
  const styles = StyleSheet.create({
@@ -110,6 +110,10 @@ const Divider = /*#__PURE__*/forwardRef((_ref, ref) => {
110
110
  Divider.displayName = 'Divider';
111
111
  Divider.propTypes = { ...selectedSystemPropTypes,
112
112
  tokens: getTokensPropType('Divider'),
113
+
114
+ /**
115
+ * A number referring to a position on the space scale to create space on either side of the divider
116
+ */
113
117
  space: spacingProps.types.spacingValue,
114
118
  variant: variantProp.propType,
115
119
 
@@ -120,9 +120,25 @@ IconButton.displayName = 'IconButton';
120
120
  IconButton.propTypes = { ...selectedSystemPropTypes,
121
121
  variant: variantProp.propType,
122
122
  tokens: getTokensPropType('IconButton'),
123
+
124
+ /**
125
+ * Defines the icon to be rendered
126
+ */
123
127
  icon: PropTypes.elementType.isRequired,
128
+
129
+ /**
130
+ * URL to navigate to when the `Iconbutton` is pressed
131
+ */
124
132
  href: PropTypes.string,
133
+
134
+ /**
135
+ * URL options to navigate to when the `Iconbutton` is pressed
136
+ */
125
137
  hrefAttrs: PropTypes.shape(hrefAttrsProp.types),
138
+
139
+ /**
140
+ * Function to execute when the `Iconbutton` is pressed
141
+ */
126
142
  onPress: PropTypes.func
127
143
  };
128
144
  const staticStyles = StyleSheet.create({
@@ -52,6 +52,10 @@ const ChevronLink = /*#__PURE__*/forwardRef((_ref, ref) => {
52
52
  ChevronLink.displayName = 'ChevronLink';
53
53
  ChevronLink.propTypes = { ...LinkBase.propTypes,
54
54
  tokens: getTokensPropType('ChevronLink', 'Link'),
55
+
56
+ /**
57
+ * Changes direction of chevron icon
58
+ */
55
59
  direction: PropTypes.oneOf(['left', 'right'])
56
60
  };
57
61
  export default ChevronLink;
@@ -201,7 +201,7 @@ const LinkBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
201
201
  },
202
202
  children: /*#__PURE__*/_jsx(Text, {
203
203
  style: [textStyles, blockTextStyles, staticStyles.baseline],
204
- children: children
204
+ children: typeof children === 'function' ? children(linkState) : children
205
205
  })
206
206
  });
207
207
  }
@@ -174,9 +174,25 @@ const Modal = /*#__PURE__*/forwardRef((_ref5, ref) => {
174
174
  Modal.displayName = 'Modal';
175
175
  Modal.propTypes = { ...selectedSystemPropTypes,
176
176
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
177
+
178
+ /**
179
+ * To define the locale of the copy
180
+ */
177
181
  copy: copyPropTypes,
182
+
183
+ /**
184
+ * Setting this to `true` will open the `Modal`
185
+ */
178
186
  isOpen: PropTypes.bool,
187
+
188
+ /**
189
+ * This function is triggered when the `Modal` is closed
190
+ */
179
191
  onClose: PropTypes.func,
192
+
193
+ /**
194
+ * `max-width` is applied to the `Modal` container
195
+ */
180
196
  maxWidth: PropTypes.bool,
181
197
  tokens: getTokensPropType('Modal'),
182
198
  variant: variantProp.propType,
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import View from "react-native-web/dist/exports/View";
4
4
  import StyleSheet from "react-native-web/dist/exports/StyleSheet";
5
5
  import { Portal } from '@gorhom/portal';
6
- import { selectTokens, useCopy, copyPropTypes, getTokensPropType, variantProp } from '../utils';
6
+ import { useCopy, copyPropTypes, getTokensPropType, variantProp } from '../utils';
7
7
  import { useViewport } from '../ViewportProvider';
8
8
  import { useThemeTokens } from '../ThemeProvider';
9
9
  import dictionary from './dictionary';
@@ -16,7 +16,6 @@ const staticStyles = StyleSheet.create({
16
16
  flex: 1,
17
17
  // Grow to maxWidth when possible, shrink when not possible
18
18
  position: 'absolute',
19
- height: 330,
20
19
  zIndex: 10000 // Position on top of all the other overlays, including backdrops and modals
21
20
 
22
21
  },
@@ -62,6 +61,11 @@ const ModalOverlay = /*#__PURE__*/forwardRef((_ref3, ref) => {
62
61
  let {
63
62
  children,
64
63
  isReady = false,
64
+ maxHeight,
65
+ maxHeightSize,
66
+ maxWidthSize,
67
+ minHeight,
68
+ minWidth,
65
69
  overlaidPosition,
66
70
  onLayout,
67
71
  variant,
@@ -74,9 +78,18 @@ const ModalOverlay = /*#__PURE__*/forwardRef((_ref3, ref) => {
74
78
  viewport,
75
79
  maxWidth: false
76
80
  });
81
+ const containerWidthHeight = {
82
+ minWidth,
83
+ minHeight,
84
+ ...(tokens.maxWidth && maxWidthSize && {
85
+ maxWidth: maxWidthSize
86
+ }),
87
+ ...(maxHeight && maxHeightSize && {
88
+ maxHeight: maxHeightSize
89
+ })
90
+ };
77
91
  const {
78
- closeIcon: CloseIconComponent,
79
- maxWidth
92
+ closeIcon: CloseIconComponent
80
93
  } = themeTokens;
81
94
  const getCopy = useCopy({
82
95
  dictionary,
@@ -87,9 +100,7 @@ const ModalOverlay = /*#__PURE__*/forwardRef((_ref3, ref) => {
87
100
  children: /*#__PURE__*/_jsx(View, {
88
101
  ref: ref,
89
102
  onLayout: onLayout,
90
- style: [overlaidPosition, {
91
- minWidth: maxWidth
92
- }, staticStyles.positioner, !isReady && staticStyles.hidden],
103
+ style: [overlaidPosition, containerWidthHeight, staticStyles.positioner, !isReady && staticStyles.hidden],
93
104
  children: /*#__PURE__*/_jsxs(Card, {
94
105
  tokens: selectPaddingContainerStyles(themeTokens),
95
106
  children: [/*#__PURE__*/_jsx(View, {
@@ -98,8 +109,7 @@ const ModalOverlay = /*#__PURE__*/forwardRef((_ref3, ref) => {
98
109
  onPress: onClose,
99
110
  icon: CloseIconComponent,
100
111
  accessibilityRole: "button",
101
- accessibilityLabel: closeLabel,
102
- tokens: selectTokens('IconButton', themeTokens, 'close')
112
+ accessibilityLabel: closeLabel
103
113
  })
104
114
  }), children]
105
115
  })
@@ -115,6 +125,12 @@ ModalOverlay.propTypes = {
115
125
  left: PropTypes.number,
116
126
  width: PropTypes.number
117
127
  }),
128
+ minWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
129
+ minHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
130
+ maxHeightSize: PropTypes.number,
131
+ maxWidthSize: PropTypes.number,
132
+ maxHeight: PropTypes.bool,
133
+ maxWidth: PropTypes.bool,
118
134
  onLayout: PropTypes.func,
119
135
  variant: variantProp.propType,
120
136
  tokens: getTokensPropType('Modal'),