@panneau/core 1.0.0-alpha.19 → 1.0.0-alpha.193

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/lib/hooks.js CHANGED
@@ -15,6 +15,8 @@ var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
15
15
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
16
16
  var fetch = require('@folklore/fetch');
17
17
  var isObject = require('lodash/isObject');
18
+ var isArray = require('lodash/isArray');
19
+ var get = require('lodash/get');
18
20
  var contexts = require('@panneau/core/contexts');
19
21
  var cssMediaquery = require('css-mediaquery');
20
22
 
@@ -48,6 +50,8 @@ var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray)
48
50
  var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
49
51
  var _objectWithoutProperties__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutProperties);
50
52
  var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
53
+ var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
54
+ var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
51
55
 
52
56
  var useAnimationFrame = function useAnimationFrame(onFrame) {
53
57
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
@@ -149,6 +153,7 @@ var getFieldsPropsFromFields = function getFieldsPropsFromFields(fields, _ref) {
149
153
  _onChange = _ref.onChange,
150
154
  props = _objectWithoutProperties__default['default'](_ref, ["value", "errors", "onChange"]);
151
155
 
156
+ var locales = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
152
157
  return fields.reduce(function (allFields, field) {
153
158
  var _ref2 = isObject__default['default'](field) ? field : {},
154
159
  _ref2$name = _ref2.name,
@@ -156,12 +161,18 @@ var getFieldsPropsFromFields = function getFieldsPropsFromFields(fields, _ref) {
156
161
  _ref2$component = _ref2.component,
157
162
  component = _ref2$component === void 0 ? null : _ref2$component;
158
163
 
159
- console.log('f', field);
164
+ var fieldErrors = errors !== null ? errors[name] || [] : [];
165
+ var localizedErrors = component === 'localized' ? (locales || []).reduce(function (previousErrors, locale) {
166
+ var items = errors !== null ? get__default['default'](errors, "".concat(name, ".").concat(locale), []) || [] : [];
167
+ var finalItems = isArray__default['default'](items) ? items : [items];
168
+ var finalPrevious = isArray__default['default'](previousErrors) ? previousErrors : [];
169
+ return [].concat(_toConsumableArray__default['default'](finalPrevious), _toConsumableArray__default['default'](finalItems));
170
+ }, fieldErrors) : fieldErrors;
160
171
  return [].concat(_toConsumableArray__default['default'](allFields), [_objectSpread__default['default'](_objectSpread__default['default']({}, isObject__default['default'](field) ? field : null), {}, {
161
172
  name: name,
162
173
  component: component,
163
174
  value: value !== null ? value[name] || null : null,
164
- errors: errors !== null ? errors[name] || null : null,
175
+ errors: localizedErrors.length > 0 ? localizedErrors : null,
165
176
  onChange: function onChange(fieldValue) {
166
177
  return _onChange(name, fieldValue);
167
178
  }
@@ -196,7 +207,9 @@ var useForm = function useForm() {
196
207
  _opts$setValue = opts.setValue,
197
208
  setProvidedValue = _opts$setValue === void 0 ? null : _opts$setValue,
198
209
  _opts$onComplete = opts.onComplete,
199
- onComplete = _opts$onComplete === void 0 ? null : _opts$onComplete;
210
+ onComplete = _opts$onComplete === void 0 ? null : _opts$onComplete,
211
+ _opts$locales = opts.locales,
212
+ locales = _opts$locales === void 0 ? [] : _opts$locales;
200
213
 
201
214
  var _useState = react.useState(initialValue || providedValue),
202
215
  _useState2 = _slicedToArray__default['default'](_useState, 2),
@@ -236,7 +249,7 @@ var useForm = function useForm() {
236
249
  var hasProvidedGeneralError = setProvidedGeneralError !== null;
237
250
  var generalError = hasProvidedGeneralError ? providedGeneralError : stateGeneralError;
238
251
  var setGeneralError = hasProvidedGeneralError ? setProvidedGeneralError : setStateGeneralError;
239
- var fieldsKey = [value, errors].concat(fields);
252
+ var fieldsKey = [value, errors, locales].concat(fields);
240
253
  var onFieldChange = react.useCallback(function (fieldName, fieldValue) {
241
254
  var fieldErrors = errors !== null ? errors[fieldName] || null : null;
242
255
 
@@ -251,7 +264,7 @@ var useForm = function useForm() {
251
264
  value: value,
252
265
  errors: errors,
253
266
  onChange: onFieldChange
254
- });
267
+ }, locales);
255
268
  }, fieldsKey);
256
269
  var csrfToken = react.useMemo(function () {
257
270
  return fetch.getCsrfToken();
@@ -986,21 +999,27 @@ var getResource = function getResource(resources, resourceId) {
986
999
  var useResourceUrlGenerator = function useResourceUrlGenerator() {
987
1000
  var resourceId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
988
1001
  var resources = contexts.usePanneauResources();
989
- var resource = getResource(resources, resourceId);
1002
+ var contextResource = contexts.useResource();
1003
+ var resource = getResource(resources, resourceId) || contextResource;
990
1004
  var route = contexts.useUrlGenerator();
991
1005
  return function (routeResourceId) {
992
1006
  var routeName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
993
1007
  var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
994
1008
  var finalRouteName = resourceId !== null ? routeResourceId : routeName;
995
1009
  var finalParams = resourceId !== null ? routeName : params;
996
- var finalResource = resource || getResource(resources, routeResourceId);
997
- var id = finalResource.id,
998
- _finalResource$has_ro = finalResource.has_routes,
999
- hasRoutes = _finalResource$has_ro === void 0 ? false : _finalResource$has_ro;
1000
- var routePrefix = hasRoutes ? "resources.".concat(id) : 'resources';
1001
- return route("".concat(routePrefix, ".").concat(finalRouteName), _objectSpread__default['default'](_objectSpread__default['default']({}, finalParams), {}, {
1010
+ var finalResource = getResource(resources, routeResourceId) || resource;
1011
+
1012
+ var _ref = finalResource || {},
1013
+ _ref$id = _ref.id,
1014
+ id = _ref$id === void 0 ? null : _ref$id; // console.log('gen', finalRouteName, route(`resources.${finalRouteName}`, {
1015
+ // ...finalParams,
1016
+ // resource: id,
1017
+ // }));
1018
+
1019
+
1020
+ return id !== null ? route("resources.".concat(finalRouteName), _objectSpread__default['default'](_objectSpread__default['default']({}, finalParams), {}, {
1002
1021
  resource: id
1003
- }));
1022
+ })) : null;
1004
1023
  };
1005
1024
  };
1006
1025
 
package/lib/index.js CHANGED
@@ -15,10 +15,12 @@ require('snake-case');
15
15
  var isObject = require('lodash/isObject');
16
16
  require('react');
17
17
  var changeCase = require('change-case');
18
- require('lodash/isString');
18
+ var ReactIs = require('react-is');
19
19
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
20
+ require('lodash/isString');
20
21
  var isArray = require('lodash/isArray');
21
22
  var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
23
+ require('lodash/capitalize');
22
24
  require('slugify');
23
25
  var uniqBy = require('lodash/uniqBy');
24
26
  var uniq = require('lodash/uniq');
@@ -35,6 +37,7 @@ var _inherits__default = /*#__PURE__*/_interopDefaultLegacy(_inherits);
35
37
  var _createSuper__default = /*#__PURE__*/_interopDefaultLegacy(_createSuper);
36
38
  var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
37
39
  var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
40
+ var ReactIs__default = /*#__PURE__*/_interopDefaultLegacy(ReactIs);
38
41
  var _objectWithoutProperties__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutProperties);
39
42
  var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
40
43
  var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
@@ -92,6 +95,7 @@ var routes = PropTypes__default['default'].shape({
92
95
  'resources.show': PropTypes__default['default'].string.isRequired,
93
96
  'resources.edit': PropTypes__default['default'].string.isRequired,
94
97
  'resources.update': PropTypes__default['default'].string.isRequired,
98
+ 'resources.delete': PropTypes__default['default'].string.isRequired,
95
99
  'resources.destroy': PropTypes__default['default'].string.isRequired
96
100
  });
97
101
  var intl = PropTypes__default['default'].shape({
@@ -106,8 +110,9 @@ var pages = PropTypes__default['default'].objectOf(page);
106
110
  var field = PropTypes__default['default'].shape({
107
111
  // type: PropTypes.string.isRequired,
108
112
  name: PropTypes__default['default'].isRequired,
109
- component: PropTypes__default['default'].string.isRequired,
110
- label: PropTypes__default['default'].isRequired
113
+ type: PropTypes__default['default'].string,
114
+ component: PropTypes__default['default'].string,
115
+ label: PropTypes__default['default'].node
111
116
  });
112
117
  var fields = PropTypes__default['default'].arrayOf(field);
113
118
  var form = PropTypes__default['default'].shape({
@@ -118,11 +123,10 @@ var form = PropTypes__default['default'].shape({
118
123
  var forms = PropTypes__default['default'].arrayOf(form);
119
124
  var resource = PropTypes__default['default'].shape({
120
125
  id: PropTypes__default['default'].string.isRequired,
121
- label: PropTypes__default['default'].string.isRequired,
126
+ name: PropTypes__default['default'].string.isRequired,
122
127
  intl: intl,
123
128
  fields: fields,
124
129
  forms: PropTypes__default['default'].shape({}),
125
- has_routes: PropTypes__default['default'].bool,
126
130
  shows_in_navbar: PropTypes__default['default'].bool
127
131
  });
128
132
  var resources = PropTypes__default['default'].arrayOf(resource);
@@ -159,6 +163,11 @@ var formError = PropTypes__default['default'].shape({
159
163
  message: PropTypes__default['default'].string
160
164
  });
161
165
  var formErrors = PropTypes__default['default'].arrayOf(formError);
166
+ var uppy = PropTypes__default['default'].shape({
167
+ tus: PropTypes__default['default'].object
168
+ }); // eslint-disable-line
169
+
170
+ var triggerUpdate = PropTypes__default['default'].string;
162
171
 
163
172
  var PropTypes = /*#__PURE__*/Object.freeze({
164
173
  __proto__: null,
@@ -199,9 +208,23 @@ var PropTypes = /*#__PURE__*/Object.freeze({
199
208
  selectOptions: selectOptions,
200
209
  feedback: feedback,
201
210
  formError: formError,
202
- formErrors: formErrors
211
+ formErrors: formErrors,
212
+ uppy: uppy,
213
+ triggerUpdate: triggerUpdate
203
214
  });
204
215
 
216
+ var flattenComponents = function flattenComponents(components) {
217
+ var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
218
+
219
+ if (components === null) {
220
+ return null;
221
+ }
222
+
223
+ return Object.keys(components).reduce(function (newMap, key) {
224
+ return ReactIs__default['default'].isValidElementType(components[key]) ? _objectSpread__default['default'](_objectSpread__default['default']({}, newMap), {}, _defineProperty__default['default']({}, prefix !== null ? "".concat(prefix, ".").concat(key) : key, components[key])) : _objectSpread__default['default'](_objectSpread__default['default']({}, newMap), flattenComponents(components[key], key));
225
+ }, {});
226
+ };
227
+
205
228
  var getComponentFromName = function getComponentFromName() {
206
229
  var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
207
230
  var components = arguments.length > 1 ? arguments[1] : undefined;
@@ -234,7 +257,7 @@ var ComponentsManager = /*#__PURE__*/function (_EventEmitter) {
234
257
  _classCallCheck__default['default'](this, ComponentsManager);
235
258
 
236
259
  _this = _super.call(this);
237
- _this.components = components;
260
+ _this.components = flattenComponents(components);
238
261
  return _this;
239
262
  }
240
263
 
package/lib/utils.js CHANGED
@@ -7,24 +7,28 @@ var snakeCase = require('snake-case');
7
7
  var isObject = require('lodash/isObject');
8
8
  var react = require('react');
9
9
  var changeCase = require('change-case');
10
- var isString = require('lodash/isString');
10
+ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
11
+ var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
12
+ var ReactIs = require('react-is');
11
13
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
14
+ var isString = require('lodash/isString');
12
15
  var isArray = require('lodash/isArray');
13
16
  var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
14
- var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
15
- var _defineProperty = require('@babel/runtime/helpers/defineProperty');
17
+ var capitalize = require('lodash/capitalize');
16
18
  var slugify = require('slugify');
17
19
 
18
20
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
19
21
 
20
22
  var isNumber__default = /*#__PURE__*/_interopDefaultLegacy(isNumber);
21
23
  var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
22
- var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
24
+ var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
25
+ var _objectSpread__default = /*#__PURE__*/_interopDefaultLegacy(_objectSpread);
26
+ var ReactIs__default = /*#__PURE__*/_interopDefaultLegacy(ReactIs);
23
27
  var _objectWithoutProperties__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutProperties);
28
+ var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
24
29
  var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
25
30
  var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
26
- var _objectSpread__default = /*#__PURE__*/_interopDefaultLegacy(_objectSpread);
27
- var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
31
+ var capitalize__default = /*#__PURE__*/_interopDefaultLegacy(capitalize);
28
32
  var slugify__default = /*#__PURE__*/_interopDefaultLegacy(slugify);
29
33
 
30
34
  var convertStyleToString = function convertStyleToString(style) {
@@ -71,6 +75,31 @@ var createUseEvent = function createUseEvent(eventsManager) {
71
75
  };
72
76
  };
73
77
 
78
+ var flattenComponents = function flattenComponents(components) {
79
+ var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
80
+
81
+ if (components === null) {
82
+ return null;
83
+ }
84
+
85
+ return Object.keys(components).reduce(function (newMap, key) {
86
+ return ReactIs__default['default'].isValidElementType(components[key]) ? _objectSpread__default['default'](_objectSpread__default['default']({}, newMap), {}, _defineProperty__default['default']({}, prefix !== null ? "".concat(prefix, ".").concat(key) : key, components[key])) : _objectSpread__default['default'](_objectSpread__default['default']({}, newMap), flattenComponents(components[key], key));
87
+ }, {});
88
+ };
89
+
90
+ var getComponent = function getComponent(component) {
91
+ var _ref = isObject__default['default'](component) ? component : {
92
+ component: component
93
+ };
94
+ _ref.component;
95
+ var props = _objectWithoutProperties__default['default'](_ref, ["component"]);
96
+
97
+ return {
98
+ name: component,
99
+ props: props
100
+ };
101
+ };
102
+
74
103
  var getColumnFromField = function getColumnFromField(field) {
75
104
  if (field === null) {
76
105
  return null;
@@ -78,82 +107,43 @@ var getColumnFromField = function getColumnFromField(field) {
78
107
 
79
108
 
80
109
  var name = field.name,
81
- _field$components = field.components,
82
- components = _field$components === void 0 ? null : _field$components,
83
- _field$settings = field.settings;
84
- _field$settings = _field$settings === void 0 ? {} : _field$settings;
85
- var order = _field$settings.orderInIndex,
110
+ _field$components = field.components;
111
+ _field$components = _field$components === void 0 ? {} : _field$components;
112
+ var _field$components$dis = _field$components.display,
113
+ display = _field$components$dis === void 0 ? null : _field$components$dis,
86
114
  label = field.label;
87
- return {
115
+
116
+ var _getComponent = getComponent(display),
117
+ _getComponent$name = _getComponent.name,
118
+ componentName = _getComponent$name === void 0 ? null : _getComponent$name,
119
+ _getComponent$props = _getComponent.props,
120
+ componentProps = _getComponent$props === void 0 ? null : _getComponent$props;
121
+
122
+ return _objectSpread__default['default'](_objectSpread__default['default']({}, componentProps), {}, {
88
123
  id: name,
89
124
  label: label,
90
125
  valueKey: name,
91
- order: order,
92
- component: components !== null ? components.index_column || components.index || null : null,
126
+ component: componentName,
93
127
  field: field
94
- };
95
- };
96
- var sortColumns = function sortColumns(columns) {
97
- return columns.sort(function (_ref, _ref2) {
98
- var _ref$order = _ref.order,
99
- aOrder = _ref$order === void 0 ? null : _ref$order;
100
- var _ref2$order = _ref2.order,
101
- bOrder = _ref2$order === void 0 ? null : _ref2$order;
102
-
103
- if (aOrder === bOrder) {
104
- return 0;
105
- }
106
-
107
- if (aOrder === null) {
108
- return 1;
109
- }
110
-
111
- if (bOrder === null) {
112
- return -1;
113
- }
114
-
115
- return aOrder > bOrder ? 1 : -1;
116
128
  });
117
129
  };
118
- var getColumnsFromResource = function getColumnsFromResource(resource) {
119
- var fields = resource.fields,
120
- _resource$columns = resource.columns,
121
- resourceColumns = _resource$columns === void 0 ? null : _resource$columns;
122
- var newColumns = resourceColumns !== null ? resourceColumns.map(function (column) {
123
- var _ref3 = isString__default['default'](column) ? {
130
+ var getColumnsWithFields = function getColumnsWithFields(resource, columns) {
131
+ var fields = resource.fields;
132
+ var newColumns = columns !== null ? columns.map(function (column) {
133
+ var _ref = isString__default['default'](column) ? {
124
134
  field: column
125
135
  } : column,
126
- _ref3$field = _ref3.field,
127
- fieldName = _ref3$field === void 0 ? null : _ref3$field;
136
+ _ref$field = _ref.field,
137
+ fieldName = _ref$field === void 0 ? null : _ref$field,
138
+ otherProps = _objectWithoutProperties__default['default'](_ref, ["field"]);
128
139
 
129
- return fieldName !== null ? getColumnFromField(fields.find(function (it) {
140
+ return _objectSpread__default['default'](_objectSpread__default['default']({}, fieldName !== null ? getColumnFromField(fields.find(function (it) {
130
141
  return it.name === fieldName;
131
- }) || null) : column;
142
+ }) || null) : null), otherProps);
132
143
  }).filter(function (it) {
133
144
  return it !== null;
134
- }) : fields.filter(function (_ref4) {
135
- var _ref4$settings = _ref4.settings;
136
- _ref4$settings = _ref4$settings === void 0 ? {} : _ref4$settings;
137
- var _ref4$settings$hidden = _ref4$settings.hiddenInIndex,
138
- hiddenInIndex = _ref4$settings$hidden === void 0 ? false : _ref4$settings$hidden;
139
- return !hiddenInIndex;
140
- }).map(function (field) {
141
- return getColumnFromField(field);
142
- });
143
- return sortColumns(newColumns);
144
- };
145
-
146
- var getComponent = function getComponent(component) {
147
- var _ref = isObject__default['default'](component) ? component : {
148
- component: component
149
- };
150
- _ref.component;
151
- var props = _objectWithoutProperties__default['default'](_ref, ["component"]);
152
-
153
- return {
154
- name: component,
155
- props: props
156
- };
145
+ }) : [];
146
+ return newColumns;
157
147
  };
158
148
 
159
149
  var getComponentFromName = function getComponentFromName() {
@@ -266,9 +256,27 @@ var getFileName = function getFileName() {
266
256
 
267
257
  var getSelectOptions = function getSelectOptions(options) {
268
258
  return options.map(function (it) {
269
- return isObject__default['default'](it) ? it : {
259
+ if (isObject__default['default'](it)) {
260
+ var _it$label = it.label,
261
+ label = _it$label === void 0 ? null : _it$label,
262
+ value = it.value;
263
+
264
+ if (label === null) {
265
+ return {
266
+ value: value,
267
+ label: capitalize__default['default']("".concat(value))
268
+ };
269
+ }
270
+
271
+ return {
272
+ value: value,
273
+ label: "".concat(label)
274
+ };
275
+ }
276
+
277
+ return {
270
278
  value: it,
271
- label: it
279
+ label: capitalize__default['default']("".concat(it))
272
280
  };
273
281
  });
274
282
  };
@@ -345,7 +353,8 @@ Object.defineProperty(exports, 'snakeCase', {
345
353
  exports.convertStyleToString = convertStyleToString;
346
354
  exports.createNullableOnChange = createNullableOnChange;
347
355
  exports.createUseEvent = createUseEvent;
348
- exports.getColumnsFromResource = getColumnsFromResource;
356
+ exports.flattenComponents = flattenComponents;
357
+ exports.getColumnsWithFields = getColumnsWithFields;
349
358
  exports.getComponent = getComponent;
350
359
  exports.getComponentFromName = getComponentFromName;
351
360
  exports.getDefinitionFromId = getDefinitionFromId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panneau/core",
3
- "version": "1.0.0-alpha.19",
3
+ "version": "1.0.0-alpha.193",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "javascript"
@@ -88,7 +88,7 @@
88
88
  "@uppy/tus": "^1.8.2",
89
89
  "@uppy/webcam": "^1.8.1",
90
90
  "@uppy/xhr-upload": "^1.6.8",
91
- "bootstrap": "next",
91
+ "bootstrap": "^5.0.2",
92
92
  "change-case": "^4.1.2",
93
93
  "classnames": "^2.2.6",
94
94
  "css-mediaquery": "^0.1.2",
@@ -100,6 +100,7 @@
100
100
  "prop-types": "^15.7.2",
101
101
  "react-helmet": "^6.1.0",
102
102
  "react-intl": "^5.15.8",
103
+ "react-is": "^17.0.2",
103
104
  "react-router": "^5.2.0",
104
105
  "react-router-dom": "^5.2.0",
105
106
  "react-use-gesture": "^9.0.0",
@@ -113,5 +114,5 @@
113
114
  "publishConfig": {
114
115
  "access": "public"
115
116
  },
116
- "gitHead": "a15404f113a7c59ea6e5b946b366c3768b6a9db6"
117
+ "gitHead": "d2ca466ff6c7d5a8cacf0fe7a5c01a10590661cd"
117
118
  }