@megafon/ui-core 4.4.0 → 4.5.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/CHANGELOG.md +12 -0
- package/dist/es/colors/colorsData.js +1 -1
- package/dist/es/components/Search/Search.d.ts +2 -0
- package/dist/es/components/Search/Search.js +4 -2
- package/dist/es/components/TextField/TextField.d.ts +9 -0
- package/dist/es/components/TextField/TextField.js +20 -11
- package/dist/lib/colors/colorsData.js +1 -1
- package/dist/lib/components/Search/Search.d.ts +2 -0
- package/dist/lib/components/Search/Search.js +4 -2
- package/dist/lib/components/TextField/TextField.d.ts +9 -0
- package/dist/lib/components/TextField/TextField.js +22 -12
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [4.5.0](https://github.com/MegafonWebLab/megafon-ui/compare/@megafon/ui-core@4.4.0...@megafon/ui-core@4.5.0) (2022-10-17)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **search:** add new keys for prop classes ([552741b](https://github.com/MegafonWebLab/megafon-ui/commit/552741be627cce59b4ba221645b569ce57e72bd2))
|
|
12
|
+
* **textfield:** add minTextareaHeight and hideResizeButton props for textarea ([088d219](https://github.com/MegafonWebLab/megafon-ui/commit/088d21971b69233522bb5cf7d642cffbc2571ca4))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
6
18
|
# [4.4.0](https://github.com/MegafonWebLab/megafon-ui/compare/@megafon/ui-core@4.3.0...@megafon/ui-core@4.4.0) (2022-10-10)
|
|
7
19
|
|
|
8
20
|
|
|
@@ -122,7 +122,7 @@ var colors = {
|
|
|
122
122
|
staticOpacity: {
|
|
123
123
|
title: 'Static Opacity',
|
|
124
124
|
colorsList: {
|
|
125
|
-
description: 'Цвета
|
|
125
|
+
description: 'Цвета с прозрачностью не зависящие от темы',
|
|
126
126
|
colors: [{
|
|
127
127
|
name: 'STC White 5%',
|
|
128
128
|
code: 'stcWhite5',
|
|
@@ -199,7 +199,7 @@ var Search = function Search(_ref) {
|
|
|
199
199
|
id: searchId,
|
|
200
200
|
className: cn('search-field', {
|
|
201
201
|
filled: !!searchQuery
|
|
202
|
-
}),
|
|
202
|
+
}, [classes === null || classes === void 0 ? void 0 : classes.input]),
|
|
203
203
|
placeholder: placeholder,
|
|
204
204
|
value: searchQuery,
|
|
205
205
|
onChange: handleChange,
|
|
@@ -211,7 +211,7 @@ var Search = function Search(_ref) {
|
|
|
211
211
|
type: "text",
|
|
212
212
|
autoComplete: "off"
|
|
213
213
|
})), label && /*#__PURE__*/React.createElement("div", {
|
|
214
|
-
className: cn('label')
|
|
214
|
+
className: cn('label', [classes === null || classes === void 0 ? void 0 : classes.label])
|
|
215
215
|
}, label, required && /*#__PURE__*/React.createElement("span", {
|
|
216
216
|
className: cn('require-mark')
|
|
217
217
|
}, "*"))), !hideIcon && /*#__PURE__*/React.createElement("div", _extends({}, filterDataAttrs(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.submit), {
|
|
@@ -272,6 +272,8 @@ Search.propTypes = {
|
|
|
272
272
|
required: PropTypes.bool,
|
|
273
273
|
className: PropTypes.string,
|
|
274
274
|
classes: PropTypes.shape({
|
|
275
|
+
label: PropTypes.string,
|
|
276
|
+
input: PropTypes.string,
|
|
275
277
|
listItemTitle: PropTypes.string,
|
|
276
278
|
control: PropTypes.string,
|
|
277
279
|
icon: PropTypes.string
|
|
@@ -8,6 +8,11 @@ export declare const TextareaTypes: {
|
|
|
8
8
|
readonly FIXED: "fixed";
|
|
9
9
|
readonly FLEXIBLE: "flexible";
|
|
10
10
|
};
|
|
11
|
+
export declare const MinTextareaHeight: {
|
|
12
|
+
readonly ONE_ROW: 24;
|
|
13
|
+
readonly THREE_ROWS: number;
|
|
14
|
+
};
|
|
15
|
+
declare type MinTextareaHeightType = typeof MinTextareaHeight[keyof typeof MinTextareaHeight];
|
|
11
16
|
interface IMaskSelection {
|
|
12
17
|
start: number;
|
|
13
18
|
end: number;
|
|
@@ -79,6 +84,10 @@ export declare type TextFieldProps = {
|
|
|
79
84
|
autoComplete?: string;
|
|
80
85
|
/** Переводит компонент в контролируемое состояние */
|
|
81
86
|
isControlled?: boolean;
|
|
87
|
+
/** Минимальная высота textarea, px */
|
|
88
|
+
minTextareaHeight?: MinTextareaHeightType;
|
|
89
|
+
/** Скрывает кнопку ресайза для textarea="flexible" */
|
|
90
|
+
hideResizeButton?: boolean;
|
|
82
91
|
/** Обработчик изменения значения */
|
|
83
92
|
onChange?: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
84
93
|
/** Обработчик изменения значения маскированного инпута до обработки маской */
|
|
@@ -59,6 +59,10 @@ var ResizeIcon = function ResizeIcon(props) {
|
|
|
59
59
|
}));
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
var TEXTAREA_MAX_HEIGHT = 144;
|
|
63
|
+
var DEFAULT_LABEL_TOP_POSITION = 16;
|
|
64
|
+
var DEFAULT_ROW_COUNT = 3;
|
|
65
|
+
var ROW_HEIGHT = 24;
|
|
62
66
|
var DEFAULT_PLACEHOLDERS = {
|
|
63
67
|
email: 'E-mail',
|
|
64
68
|
tel: 'Номер телефона',
|
|
@@ -73,11 +77,10 @@ export var TextareaTypes = {
|
|
|
73
77
|
FIXED: 'fixed',
|
|
74
78
|
FLEXIBLE: 'flexible'
|
|
75
79
|
};
|
|
76
|
-
var
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
var ROW_HEIGHT = 24;
|
|
80
|
+
export var MinTextareaHeight = {
|
|
81
|
+
ONE_ROW: ROW_HEIGHT,
|
|
82
|
+
THREE_ROWS: ROW_HEIGHT * 3
|
|
83
|
+
};
|
|
81
84
|
var cn = cnCreate('mfui-text-field');
|
|
82
85
|
|
|
83
86
|
var TextField = function TextField(_ref) {
|
|
@@ -101,6 +104,10 @@ var TextField = function TextField(_ref) {
|
|
|
101
104
|
required = _ref.required,
|
|
102
105
|
_ref$isControlled = _ref.isControlled,
|
|
103
106
|
isControlled = _ref$isControlled === void 0 ? false : _ref$isControlled,
|
|
107
|
+
_ref$minTextareaHeigh = _ref.minTextareaHeight,
|
|
108
|
+
minTextareaHeight = _ref$minTextareaHeigh === void 0 ? MinTextareaHeight.THREE_ROWS : _ref$minTextareaHeigh,
|
|
109
|
+
_ref$hideResizeButton = _ref.hideResizeButton,
|
|
110
|
+
hideResizeButton = _ref$hideResizeButton === void 0 ? false : _ref$hideResizeButton,
|
|
104
111
|
onBlur = _ref.onBlur,
|
|
105
112
|
onChange = _ref.onChange,
|
|
106
113
|
onBeforeMaskChange = _ref.onBeforeMaskChange,
|
|
@@ -133,7 +140,7 @@ var TextField = function TextField(_ref) {
|
|
|
133
140
|
inputValue = _useState4[0],
|
|
134
141
|
setInputValue = _useState4[1];
|
|
135
142
|
|
|
136
|
-
var _useState5 = useState(
|
|
143
|
+
var _useState5 = useState(minTextareaHeight),
|
|
137
144
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
138
145
|
initialTextareaHeight = _useState6[0],
|
|
139
146
|
setInitialTextareaHeight = _useState6[1];
|
|
@@ -206,7 +213,7 @@ var TextField = function TextField(_ref) {
|
|
|
206
213
|
var handleResize = throttle(function (moveEvent) {
|
|
207
214
|
var currentCoordinateY = moveEvent.clientY || moveEvent.touches[0].clientY;
|
|
208
215
|
var resizeHeight = originalHeight + (currentCoordinateY - originalCoordinateY);
|
|
209
|
-
var updatedHeight = resizeHeight <
|
|
216
|
+
var updatedHeight = resizeHeight < minTextareaHeight ? minTextareaHeight : resizeHeight;
|
|
210
217
|
setInitialTextareaHeight(updatedHeight);
|
|
211
218
|
setIsTextareaResized(true);
|
|
212
219
|
}, throttleTime.resizeTextarea);
|
|
@@ -227,7 +234,7 @@ var TextField = function TextField(_ref) {
|
|
|
227
234
|
|
|
228
235
|
resizerRef.current.addEventListener('mousedown', handleStartResize);
|
|
229
236
|
resizerRef.current.addEventListener('touchstart', handleStartResize);
|
|
230
|
-
}, [textarea]);
|
|
237
|
+
}, [textarea, minTextareaHeight]);
|
|
231
238
|
var togglePasswordHiding = useCallback(function () {
|
|
232
239
|
return setPasswordHidden(function (prevPassState) {
|
|
233
240
|
return !prevPassState;
|
|
@@ -240,8 +247,8 @@ var TextField = function TextField(_ref) {
|
|
|
240
247
|
}
|
|
241
248
|
|
|
242
249
|
var scrollHeight = fieldNode.current.scrollHeight;
|
|
243
|
-
var extraRowCount = Math.round((scrollHeight - 28 -
|
|
244
|
-
var newHeight = extraRowCount <= DEFAULT_ROW_COUNT ?
|
|
250
|
+
var extraRowCount = Math.round((scrollHeight - 28 - minTextareaHeight) / ROW_HEIGHT);
|
|
251
|
+
var newHeight = extraRowCount <= DEFAULT_ROW_COUNT ? minTextareaHeight + ROW_HEIGHT * extraRowCount : TEXTAREA_MAX_HEIGHT;
|
|
245
252
|
setInitialTextareaHeight(newHeight);
|
|
246
253
|
};
|
|
247
254
|
|
|
@@ -442,7 +449,7 @@ var TextField = function TextField(_ref) {
|
|
|
442
449
|
className: cn('field-wrapper', {
|
|
443
450
|
textarea: textarea && textareaType
|
|
444
451
|
})
|
|
445
|
-
}, renderField(), textareaType === TextareaTypes.FLEXIBLE && /*#__PURE__*/React.createElement("div", {
|
|
452
|
+
}, renderField(), textareaType === TextareaTypes.FLEXIBLE && !hideResizeButton && /*#__PURE__*/React.createElement("div", {
|
|
446
453
|
className: cn('resizer'),
|
|
447
454
|
ref: resizerRef
|
|
448
455
|
}, /*#__PURE__*/React.createElement(ResizeIcon, null))), /*#__PURE__*/React.createElement("div", {
|
|
@@ -485,6 +492,8 @@ TextField.propTypes = {
|
|
|
485
492
|
maskChar: PropTypes.string,
|
|
486
493
|
noticeText: PropTypes.string,
|
|
487
494
|
className: PropTypes.string,
|
|
495
|
+
minTextareaHeight: PropTypes.oneOf([24, 72]),
|
|
496
|
+
hideResizeButton: PropTypes.bool,
|
|
488
497
|
onChange: PropTypes.func,
|
|
489
498
|
onBeforeMaskChange: PropTypes.func,
|
|
490
499
|
onBlur: PropTypes.func,
|
|
@@ -128,7 +128,7 @@ var colors = {
|
|
|
128
128
|
staticOpacity: {
|
|
129
129
|
title: 'Static Opacity',
|
|
130
130
|
colorsList: {
|
|
131
|
-
description: 'Цвета
|
|
131
|
+
description: 'Цвета с прозрачностью не зависящие от темы',
|
|
132
132
|
colors: [{
|
|
133
133
|
name: 'STC White 5%',
|
|
134
134
|
code: 'stcWhite5',
|
|
@@ -241,7 +241,7 @@ var Search = function Search(_ref) {
|
|
|
241
241
|
id: searchId,
|
|
242
242
|
className: cn('search-field', {
|
|
243
243
|
filled: !!searchQuery
|
|
244
|
-
}),
|
|
244
|
+
}, [classes === null || classes === void 0 ? void 0 : classes.input]),
|
|
245
245
|
placeholder: placeholder,
|
|
246
246
|
value: searchQuery,
|
|
247
247
|
onChange: handleChange,
|
|
@@ -253,7 +253,7 @@ var Search = function Search(_ref) {
|
|
|
253
253
|
type: "text",
|
|
254
254
|
autoComplete: "off"
|
|
255
255
|
})), label && /*#__PURE__*/_react["default"].createElement("div", {
|
|
256
|
-
className: cn('label')
|
|
256
|
+
className: cn('label', [classes === null || classes === void 0 ? void 0 : classes.label])
|
|
257
257
|
}, label, required && /*#__PURE__*/_react["default"].createElement("span", {
|
|
258
258
|
className: cn('require-mark')
|
|
259
259
|
}, "*"))), !hideIcon && /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, (0, _uiHelpers.filterDataAttrs)(dataAttrs === null || dataAttrs === void 0 ? void 0 : dataAttrs.submit), {
|
|
@@ -314,6 +314,8 @@ Search.propTypes = {
|
|
|
314
314
|
required: PropTypes.bool,
|
|
315
315
|
className: PropTypes.string,
|
|
316
316
|
classes: PropTypes.shape({
|
|
317
|
+
label: PropTypes.string,
|
|
318
|
+
input: PropTypes.string,
|
|
317
319
|
listItemTitle: PropTypes.string,
|
|
318
320
|
control: PropTypes.string,
|
|
319
321
|
icon: PropTypes.string
|
|
@@ -8,6 +8,11 @@ export declare const TextareaTypes: {
|
|
|
8
8
|
readonly FIXED: "fixed";
|
|
9
9
|
readonly FLEXIBLE: "flexible";
|
|
10
10
|
};
|
|
11
|
+
export declare const MinTextareaHeight: {
|
|
12
|
+
readonly ONE_ROW: 24;
|
|
13
|
+
readonly THREE_ROWS: number;
|
|
14
|
+
};
|
|
15
|
+
declare type MinTextareaHeightType = typeof MinTextareaHeight[keyof typeof MinTextareaHeight];
|
|
11
16
|
interface IMaskSelection {
|
|
12
17
|
start: number;
|
|
13
18
|
end: number;
|
|
@@ -79,6 +84,10 @@ export declare type TextFieldProps = {
|
|
|
79
84
|
autoComplete?: string;
|
|
80
85
|
/** Переводит компонент в контролируемое состояние */
|
|
81
86
|
isControlled?: boolean;
|
|
87
|
+
/** Минимальная высота textarea, px */
|
|
88
|
+
minTextareaHeight?: MinTextareaHeightType;
|
|
89
|
+
/** Скрывает кнопку ресайза для textarea="flexible" */
|
|
90
|
+
hideResizeButton?: boolean;
|
|
82
91
|
/** Обработчик изменения значения */
|
|
83
92
|
onChange?: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
84
93
|
/** Обработчик изменения значения маскированного инпута до обработки маской */
|
|
@@ -5,7 +5,7 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "functi
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports["default"] = exports.TextareaTypes = exports.Verification = void 0;
|
|
8
|
+
exports["default"] = exports.MinTextareaHeight = exports.TextareaTypes = exports.Verification = void 0;
|
|
9
9
|
|
|
10
10
|
require("core-js/modules/es.array.concat");
|
|
11
11
|
|
|
@@ -85,6 +85,10 @@ var ResizeIcon = function ResizeIcon(props) {
|
|
|
85
85
|
}));
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
+
var TEXTAREA_MAX_HEIGHT = 144;
|
|
89
|
+
var DEFAULT_LABEL_TOP_POSITION = 16;
|
|
90
|
+
var DEFAULT_ROW_COUNT = 3;
|
|
91
|
+
var ROW_HEIGHT = 24;
|
|
88
92
|
var DEFAULT_PLACEHOLDERS = {
|
|
89
93
|
email: 'E-mail',
|
|
90
94
|
tel: 'Номер телефона',
|
|
@@ -101,11 +105,11 @@ var TextareaTypes = {
|
|
|
101
105
|
FLEXIBLE: 'flexible'
|
|
102
106
|
};
|
|
103
107
|
exports.TextareaTypes = TextareaTypes;
|
|
104
|
-
var
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
var MinTextareaHeight = {
|
|
109
|
+
ONE_ROW: ROW_HEIGHT,
|
|
110
|
+
THREE_ROWS: ROW_HEIGHT * 3
|
|
111
|
+
};
|
|
112
|
+
exports.MinTextareaHeight = MinTextareaHeight;
|
|
109
113
|
var cn = (0, _uiHelpers.cnCreate)('mfui-text-field');
|
|
110
114
|
|
|
111
115
|
var TextField = function TextField(_ref) {
|
|
@@ -129,6 +133,10 @@ var TextField = function TextField(_ref) {
|
|
|
129
133
|
required = _ref.required,
|
|
130
134
|
_ref$isControlled = _ref.isControlled,
|
|
131
135
|
isControlled = _ref$isControlled === void 0 ? false : _ref$isControlled,
|
|
136
|
+
_ref$minTextareaHeigh = _ref.minTextareaHeight,
|
|
137
|
+
minTextareaHeight = _ref$minTextareaHeigh === void 0 ? MinTextareaHeight.THREE_ROWS : _ref$minTextareaHeigh,
|
|
138
|
+
_ref$hideResizeButton = _ref.hideResizeButton,
|
|
139
|
+
hideResizeButton = _ref$hideResizeButton === void 0 ? false : _ref$hideResizeButton,
|
|
132
140
|
onBlur = _ref.onBlur,
|
|
133
141
|
onChange = _ref.onChange,
|
|
134
142
|
onBeforeMaskChange = _ref.onBeforeMaskChange,
|
|
@@ -161,7 +169,7 @@ var TextField = function TextField(_ref) {
|
|
|
161
169
|
inputValue = _useState4[0],
|
|
162
170
|
setInputValue = _useState4[1];
|
|
163
171
|
|
|
164
|
-
var _useState5 = (0, React.useState)(
|
|
172
|
+
var _useState5 = (0, React.useState)(minTextareaHeight),
|
|
165
173
|
_useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
|
|
166
174
|
initialTextareaHeight = _useState6[0],
|
|
167
175
|
setInitialTextareaHeight = _useState6[1];
|
|
@@ -234,7 +242,7 @@ var TextField = function TextField(_ref) {
|
|
|
234
242
|
var handleResize = (0, _lodash["default"])(function (moveEvent) {
|
|
235
243
|
var currentCoordinateY = moveEvent.clientY || moveEvent.touches[0].clientY;
|
|
236
244
|
var resizeHeight = originalHeight + (currentCoordinateY - originalCoordinateY);
|
|
237
|
-
var updatedHeight = resizeHeight <
|
|
245
|
+
var updatedHeight = resizeHeight < minTextareaHeight ? minTextareaHeight : resizeHeight;
|
|
238
246
|
setInitialTextareaHeight(updatedHeight);
|
|
239
247
|
setIsTextareaResized(true);
|
|
240
248
|
}, _throttleTime["default"].resizeTextarea);
|
|
@@ -255,7 +263,7 @@ var TextField = function TextField(_ref) {
|
|
|
255
263
|
|
|
256
264
|
resizerRef.current.addEventListener('mousedown', handleStartResize);
|
|
257
265
|
resizerRef.current.addEventListener('touchstart', handleStartResize);
|
|
258
|
-
}, [textarea]);
|
|
266
|
+
}, [textarea, minTextareaHeight]);
|
|
259
267
|
var togglePasswordHiding = (0, React.useCallback)(function () {
|
|
260
268
|
return setPasswordHidden(function (prevPassState) {
|
|
261
269
|
return !prevPassState;
|
|
@@ -268,8 +276,8 @@ var TextField = function TextField(_ref) {
|
|
|
268
276
|
}
|
|
269
277
|
|
|
270
278
|
var scrollHeight = fieldNode.current.scrollHeight;
|
|
271
|
-
var extraRowCount = Math.round((scrollHeight - 28 -
|
|
272
|
-
var newHeight = extraRowCount <= DEFAULT_ROW_COUNT ?
|
|
279
|
+
var extraRowCount = Math.round((scrollHeight - 28 - minTextareaHeight) / ROW_HEIGHT);
|
|
280
|
+
var newHeight = extraRowCount <= DEFAULT_ROW_COUNT ? minTextareaHeight + ROW_HEIGHT * extraRowCount : TEXTAREA_MAX_HEIGHT;
|
|
273
281
|
setInitialTextareaHeight(newHeight);
|
|
274
282
|
};
|
|
275
283
|
|
|
@@ -466,7 +474,7 @@ var TextField = function TextField(_ref) {
|
|
|
466
474
|
className: cn('field-wrapper', {
|
|
467
475
|
textarea: textarea && textareaType
|
|
468
476
|
})
|
|
469
|
-
}, renderField(), textareaType === TextareaTypes.FLEXIBLE && /*#__PURE__*/React.createElement("div", {
|
|
477
|
+
}, renderField(), textareaType === TextareaTypes.FLEXIBLE && !hideResizeButton && /*#__PURE__*/React.createElement("div", {
|
|
470
478
|
className: cn('resizer'),
|
|
471
479
|
ref: resizerRef
|
|
472
480
|
}, /*#__PURE__*/React.createElement(ResizeIcon, null))), /*#__PURE__*/React.createElement("div", {
|
|
@@ -509,6 +517,8 @@ TextField.propTypes = {
|
|
|
509
517
|
maskChar: PropTypes.string,
|
|
510
518
|
noticeText: PropTypes.string,
|
|
511
519
|
className: PropTypes.string,
|
|
520
|
+
minTextareaHeight: PropTypes.oneOf([24, 72]),
|
|
521
|
+
hideResizeButton: PropTypes.bool,
|
|
512
522
|
onChange: PropTypes.func,
|
|
513
523
|
onBeforeMaskChange: PropTypes.func,
|
|
514
524
|
onBlur: PropTypes.func,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@megafon/ui-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist",
|
|
6
6
|
"styles"
|
|
@@ -97,5 +97,5 @@
|
|
|
97
97
|
"react-popper": "^2.2.3",
|
|
98
98
|
"swiper": "^6.5.6"
|
|
99
99
|
},
|
|
100
|
-
"gitHead": "
|
|
100
|
+
"gitHead": "1767b434f1650a100aa2aca6f5c795f8b549a184"
|
|
101
101
|
}
|