instantsearch.js 4.73.4 → 4.74.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.
Files changed (55) hide show
  1. package/cjs/connectors/answers/connectAnswers.js +3 -2
  2. package/cjs/connectors/configure-related-items/connectConfigureRelatedItems.js +2 -0
  3. package/cjs/connectors/index.js +7 -10
  4. package/cjs/connectors/voice-search/connectVoiceSearch.js +2 -1
  5. package/cjs/index.js +2 -0
  6. package/cjs/lib/version.js +1 -1
  7. package/cjs/templates/carousel/carousel.js +62 -0
  8. package/cjs/templates/index.js +16 -0
  9. package/cjs/widgets/configure-related-items/configure-related-items.js +2 -0
  10. package/cjs/widgets/frequently-bought-together/frequently-bought-together.js +36 -12
  11. package/cjs/widgets/index.js +7 -10
  12. package/cjs/widgets/looking-similar/looking-similar.js +37 -13
  13. package/cjs/widgets/related-products/related-products.js +37 -13
  14. package/cjs/widgets/trending-items/trending-items.js +38 -14
  15. package/dist/instantsearch.development.d.ts +119 -51
  16. package/dist/instantsearch.development.js +10284 -9961
  17. package/dist/instantsearch.development.js.map +1 -1
  18. package/dist/instantsearch.production.d.ts +119 -51
  19. package/dist/instantsearch.production.min.d.ts +119 -51
  20. package/dist/instantsearch.production.min.js +2 -2
  21. package/dist/instantsearch.production.min.js.map +1 -1
  22. package/es/connectors/answers/connectAnswers.js +3 -2
  23. package/es/connectors/configure-related-items/connectConfigureRelatedItems.d.ts +1 -0
  24. package/es/connectors/configure-related-items/connectConfigureRelatedItems.js +2 -0
  25. package/es/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.d.ts +7 -7
  26. package/es/connectors/index.d.ts +2 -1
  27. package/es/connectors/index.js +4 -1
  28. package/es/connectors/looking-similar/connectLookingSimilar.d.ts +7 -7
  29. package/es/connectors/related-products/connectRelatedProducts.d.ts +7 -7
  30. package/es/connectors/trending-items/connectTrendingItems.d.ts +7 -7
  31. package/es/connectors/voice-search/connectVoiceSearch.js +2 -1
  32. package/es/index.js +5 -0
  33. package/es/lib/utils/render-args.d.ts +2 -2
  34. package/es/lib/version.d.ts +1 -1
  35. package/es/lib/version.js +1 -1
  36. package/es/templates/carousel/carousel.d.ts +22 -0
  37. package/es/templates/carousel/carousel.js +56 -0
  38. package/es/templates/index.d.ts +1 -0
  39. package/es/templates/index.js +1 -0
  40. package/es/types/widget.d.ts +3 -2
  41. package/es/widgets/configure-related-items/configure-related-items.d.ts +1 -0
  42. package/es/widgets/configure-related-items/configure-related-items.js +2 -0
  43. package/es/widgets/frequently-bought-together/frequently-bought-together.d.ts +15 -7
  44. package/es/widgets/frequently-bought-together/frequently-bought-together.js +36 -12
  45. package/es/widgets/geo-search/geo-search.d.ts +1 -1
  46. package/es/widgets/index/index.d.ts +3 -3
  47. package/es/widgets/index.d.ts +2 -1
  48. package/es/widgets/index.js +4 -1
  49. package/es/widgets/looking-similar/looking-similar.d.ts +15 -7
  50. package/es/widgets/looking-similar/looking-similar.js +37 -13
  51. package/es/widgets/related-products/related-products.d.ts +15 -7
  52. package/es/widgets/related-products/related-products.js +37 -13
  53. package/es/widgets/trending-items/trending-items.d.ts +15 -7
  54. package/es/widgets/trending-items/trending-items.js +38 -14
  55. package/package.json +8 -8
@@ -1,24 +1,32 @@
1
1
 
2
2
  import type { LookingSimilarWidgetDescription, LookingSimilarConnectorParams } from '../../connectors/looking-similar/connectLookingSimilar';
3
- import type { Template, WidgetFactory, Hit, BaseHit } from '../../types';
4
- import type { RecommendResultItem } from 'algoliasearch-helper';
3
+ import type { Template, WidgetFactory, AlgoliaHit, BaseHit, RecommendResponse } from '../../types';
5
4
  import type { RecommendClassNames, LookingSimilarProps as LookingSimilarUiProps } from 'instantsearch-ui-components';
6
5
  export type LookingSimilarCSSClasses = Partial<RecommendClassNames>;
7
6
  export type LookingSimilarTemplates<THit extends NonNullable<object> = BaseHit> = Partial<{
8
7
  /**
9
8
  * Template to use when there are no results.
10
9
  */
11
- empty: Template<RecommendResultItem<Hit<THit>>>;
10
+ empty: Template<RecommendResponse<AlgoliaHit<THit>>>;
12
11
  /**
13
12
  * Template to use for the header of the widget.
14
13
  */
15
- header: Template<Pick<Parameters<NonNullable<LookingSimilarUiProps<Hit<THit>>['headerComponent']>>[0], 'items'> & {
14
+ header: Template<Pick<Parameters<NonNullable<LookingSimilarUiProps<AlgoliaHit<THit>>['headerComponent']>>[0], 'items'> & {
16
15
  cssClasses: RecommendClassNames;
17
16
  }>;
18
17
  /**
19
18
  * Template to use for each result. This template will receive an object containing a single record.
20
19
  */
21
- item: Template<Hit<THit>>;
20
+ item: Template<AlgoliaHit<THit>>;
21
+ /**
22
+ * Template to use to wrap all items.
23
+ */
24
+ layout: Template<Pick<Parameters<NonNullable<LookingSimilarUiProps<AlgoliaHit<THit>>['layout']>>[0], 'items'> & {
25
+ templates: {
26
+ item: LookingSimilarUiProps<AlgoliaHit<THit>>['itemComponent'];
27
+ };
28
+ cssClasses: Pick<LookingSimilarCSSClasses, 'list' | 'item'>;
29
+ }>;
22
30
  }>;
23
31
  type LookingSimilarWidgetParams<THit extends NonNullable<object> = BaseHit> = {
24
32
  /**
@@ -217,9 +225,9 @@ declare const _default: <THit extends NonNullable<object> = BaseHit>(widgetParam
217
225
  error: import("../../types").InstantSearch["error"];
218
226
  createURL: (nextState: import("algoliasearch-helper").SearchParameters | ((state: import("../../types").IndexUiState) => import("../../types").IndexUiState)) => string;
219
227
  } & {
220
- results: RecommendResultItem;
228
+ results: RecommendResponse<any>;
221
229
  })): {
222
- items: Hit<THit>[];
230
+ items: AlgoliaHit<THit>[];
223
231
  widgetParams: Partial<LookingSimilarWidgetParams<BaseHit>> & LookingSimilarConnectorParams<THit>;
224
232
  };
225
233
  dispose({ recommendState }: import("../../types").DisposeOptions): import("algoliasearch-helper").RecommendParameters;
@@ -60,6 +60,29 @@ function createRenderer(_ref) {
60
60
  data: results
61
61
  }));
62
62
  } : undefined;
63
+ var layoutComponent = templates.layout ? function (data) {
64
+ return h(TemplateComponent, _extends({}, renderState.templateProps, {
65
+ templateKey: "layout",
66
+ rootTagName: "fragment",
67
+ data: {
68
+ items: data.items,
69
+ templates: {
70
+ item: templates.item ? function (_ref4) {
71
+ var item = _ref4.item;
72
+ return h(TemplateComponent, _extends({}, renderState.templateProps, {
73
+ templateKey: "item",
74
+ rootTagName: "fragment",
75
+ data: item
76
+ }));
77
+ } : undefined
78
+ },
79
+ cssClasses: {
80
+ list: data.classNames.list,
81
+ item: data.classNames.item
82
+ }
83
+ }
84
+ }));
85
+ } : undefined;
63
86
  render(h(LookingSimilar, {
64
87
  items: items,
65
88
  headerComponent: headerComponent,
@@ -67,24 +90,25 @@ function createRenderer(_ref) {
67
90
  sendEvent: function sendEvent() {},
68
91
  classNames: cssClasses,
69
92
  emptyComponent: emptyComponent,
93
+ layout: layoutComponent,
70
94
  status: instantSearchInstance.status
71
95
  }), containerNode);
72
96
  };
73
97
  }
74
98
  export default (function lookingSimilar(widgetParams) {
75
- var _ref4 = widgetParams || {},
76
- container = _ref4.container,
77
- objectIDs = _ref4.objectIDs,
78
- limit = _ref4.limit,
79
- queryParameters = _ref4.queryParameters,
80
- fallbackParameters = _ref4.fallbackParameters,
81
- threshold = _ref4.threshold,
82
- escapeHTML = _ref4.escapeHTML,
83
- transformItems = _ref4.transformItems,
84
- _ref4$templates = _ref4.templates,
85
- templates = _ref4$templates === void 0 ? {} : _ref4$templates,
86
- _ref4$cssClasses = _ref4.cssClasses,
87
- cssClasses = _ref4$cssClasses === void 0 ? {} : _ref4$cssClasses;
99
+ var _ref5 = widgetParams || {},
100
+ container = _ref5.container,
101
+ objectIDs = _ref5.objectIDs,
102
+ limit = _ref5.limit,
103
+ queryParameters = _ref5.queryParameters,
104
+ fallbackParameters = _ref5.fallbackParameters,
105
+ threshold = _ref5.threshold,
106
+ escapeHTML = _ref5.escapeHTML,
107
+ transformItems = _ref5.transformItems,
108
+ _ref5$templates = _ref5.templates,
109
+ templates = _ref5$templates === void 0 ? {} : _ref5$templates,
110
+ _ref5$cssClasses = _ref5.cssClasses,
111
+ cssClasses = _ref5$cssClasses === void 0 ? {} : _ref5$cssClasses;
88
112
  if (!container) {
89
113
  throw new Error(withUsage('The `container` option is required.'));
90
114
  }
@@ -1,24 +1,32 @@
1
1
 
2
2
  import type { RelatedProductsWidgetDescription, RelatedProductsConnectorParams } from '../../connectors/related-products/connectRelatedProducts';
3
- import type { Template, WidgetFactory, Hit, BaseHit } from '../../types';
4
- import type { RecommendResultItem } from 'algoliasearch-helper';
3
+ import type { Template, WidgetFactory, AlgoliaHit, BaseHit, RecommendResponse } from '../../types';
5
4
  import type { RecommendClassNames, RelatedProductsProps as RelatedProductsUiProps } from 'instantsearch-ui-components';
6
5
  export type RelatedProductsCSSClasses = Partial<RecommendClassNames>;
7
6
  export type RelatedProductsTemplates<THit extends NonNullable<object> = BaseHit> = Partial<{
8
7
  /**
9
8
  * Template to use when there are no results.
10
9
  */
11
- empty: Template<RecommendResultItem<Hit<THit>>>;
10
+ empty: Template<RecommendResponse<AlgoliaHit<THit>>>;
12
11
  /**
13
12
  * Template to use for the header of the widget.
14
13
  */
15
- header: Template<Pick<Parameters<NonNullable<RelatedProductsUiProps<Hit<THit>>['headerComponent']>>[0], 'items'> & {
14
+ header: Template<Pick<Parameters<NonNullable<RelatedProductsUiProps<AlgoliaHit<THit>>['headerComponent']>>[0], 'items'> & {
16
15
  cssClasses: RecommendClassNames;
17
16
  }>;
18
17
  /**
19
18
  * Template to use for each result. This template will receive an object containing a single record.
20
19
  */
21
- item: Template<Hit<THit>>;
20
+ item: Template<AlgoliaHit<THit>>;
21
+ /**
22
+ * Template to use to wrap all items.
23
+ */
24
+ layout: Template<Pick<Parameters<NonNullable<RelatedProductsUiProps<AlgoliaHit<THit>>['layout']>>[0], 'items'> & {
25
+ templates: {
26
+ item: RelatedProductsUiProps<AlgoliaHit<THit>>['itemComponent'];
27
+ };
28
+ cssClasses: Pick<RelatedProductsCSSClasses, 'list' | 'item'>;
29
+ }>;
22
30
  }>;
23
31
  type RelatedProductsWidgetParams<THit extends NonNullable<object> = BaseHit> = {
24
32
  /**
@@ -217,9 +225,9 @@ declare const _default: <THit extends NonNullable<object> = BaseHit>(widgetParam
217
225
  error: import("../../types").InstantSearch["error"];
218
226
  createURL: (nextState: import("algoliasearch-helper").SearchParameters | ((state: import("../../types").IndexUiState) => import("../../types").IndexUiState)) => string;
219
227
  } & {
220
- results: RecommendResultItem;
228
+ results: RecommendResponse<any>;
221
229
  })): {
222
- items: Hit<BaseHit>[] | Hit<THit>[];
230
+ items: AlgoliaHit<BaseHit>[] | AlgoliaHit<THit>[];
223
231
  widgetParams: Partial<RelatedProductsWidgetParams<BaseHit>> & RelatedProductsConnectorParams<THit>;
224
232
  };
225
233
  dispose({ recommendState }: import("../../types").DisposeOptions): import("algoliasearch-helper").RecommendParameters;
@@ -60,6 +60,29 @@ function createRenderer(_ref) {
60
60
  data: results
61
61
  }));
62
62
  } : undefined;
63
+ var layoutComponent = templates.layout ? function (data) {
64
+ return h(TemplateComponent, _extends({}, renderState.templateProps, {
65
+ templateKey: "layout",
66
+ rootTagName: "fragment",
67
+ data: {
68
+ items: data.items,
69
+ templates: {
70
+ item: templates.item ? function (_ref4) {
71
+ var item = _ref4.item;
72
+ return h(TemplateComponent, _extends({}, renderState.templateProps, {
73
+ templateKey: "item",
74
+ rootTagName: "fragment",
75
+ data: item
76
+ }));
77
+ } : undefined
78
+ },
79
+ cssClasses: {
80
+ list: data.classNames.list,
81
+ item: data.classNames.item
82
+ }
83
+ }
84
+ }));
85
+ } : undefined;
63
86
  render(h(RelatedProducts, {
64
87
  items: items,
65
88
  sendEvent: function sendEvent() {},
@@ -67,24 +90,25 @@ function createRenderer(_ref) {
67
90
  headerComponent: headerComponent,
68
91
  itemComponent: itemComponent,
69
92
  emptyComponent: emptyComponent,
93
+ layout: layoutComponent,
70
94
  status: instantSearchInstance.status
71
95
  }), containerNode);
72
96
  };
73
97
  }
74
98
  export default (function relatedProducts(widgetParams) {
75
- var _ref4 = widgetParams || {},
76
- container = _ref4.container,
77
- objectIDs = _ref4.objectIDs,
78
- limit = _ref4.limit,
79
- queryParameters = _ref4.queryParameters,
80
- fallbackParameters = _ref4.fallbackParameters,
81
- threshold = _ref4.threshold,
82
- escapeHTML = _ref4.escapeHTML,
83
- transformItems = _ref4.transformItems,
84
- _ref4$templates = _ref4.templates,
85
- templates = _ref4$templates === void 0 ? {} : _ref4$templates,
86
- _ref4$cssClasses = _ref4.cssClasses,
87
- cssClasses = _ref4$cssClasses === void 0 ? {} : _ref4$cssClasses;
99
+ var _ref5 = widgetParams || {},
100
+ container = _ref5.container,
101
+ objectIDs = _ref5.objectIDs,
102
+ limit = _ref5.limit,
103
+ queryParameters = _ref5.queryParameters,
104
+ fallbackParameters = _ref5.fallbackParameters,
105
+ threshold = _ref5.threshold,
106
+ escapeHTML = _ref5.escapeHTML,
107
+ transformItems = _ref5.transformItems,
108
+ _ref5$templates = _ref5.templates,
109
+ templates = _ref5$templates === void 0 ? {} : _ref5$templates,
110
+ _ref5$cssClasses = _ref5.cssClasses,
111
+ cssClasses = _ref5$cssClasses === void 0 ? {} : _ref5$cssClasses;
88
112
  if (!container) {
89
113
  throw new Error(withUsage('The `container` option is required.'));
90
114
  }
@@ -1,24 +1,32 @@
1
1
 
2
2
  import type { TrendingItemsWidgetDescription, TrendingItemsConnectorParams } from '../../connectors/trending-items/connectTrendingItems';
3
- import type { Template, WidgetFactory, Hit, BaseHit } from '../../types';
4
- import type { RecommendResultItem } from 'algoliasearch-helper';
3
+ import type { Template, WidgetFactory, AlgoliaHit, BaseHit, RecommendResponse } from '../../types';
5
4
  import type { RecommendClassNames, TrendingItemsProps as TrendingItemsUiProps } from 'instantsearch-ui-components';
6
5
  export type TrendingItemsCSSClasses = Partial<RecommendClassNames>;
7
6
  export type TrendingItemsTemplates<THit extends NonNullable<object> = BaseHit> = Partial<{
8
7
  /**
9
8
  * Template to use when there are no results.
10
9
  */
11
- empty: Template<RecommendResultItem<Hit<THit>>>;
10
+ empty: Template<RecommendResponse<AlgoliaHit<THit>>>;
12
11
  /**
13
12
  * Template to use for the header of the widget.
14
13
  */
15
- header: Template<Pick<Parameters<NonNullable<TrendingItemsUiProps<Hit<THit>>['headerComponent']>>[0], 'items'> & {
14
+ header: Template<Pick<Parameters<NonNullable<TrendingItemsUiProps<AlgoliaHit<THit>>['headerComponent']>>[0], 'items'> & {
16
15
  cssClasses: RecommendClassNames;
17
16
  }>;
18
17
  /**
19
18
  * Template to use for each result. This template will receive an object containing a single record.
20
19
  */
21
- item: Template<Hit<THit>>;
20
+ item: Template<AlgoliaHit<THit>>;
21
+ /**
22
+ * Template to use to wrap all items.
23
+ */
24
+ layout: Template<Pick<Parameters<NonNullable<TrendingItemsUiProps<AlgoliaHit<THit>>['layout']>>[0], 'items'> & {
25
+ templates: {
26
+ item: TrendingItemsUiProps<AlgoliaHit<THit>>['itemComponent'];
27
+ };
28
+ cssClasses: Pick<TrendingItemsCSSClasses, 'list' | 'item'>;
29
+ }>;
22
30
  }>;
23
31
  type TrendingItemsWidgetParams<THit extends NonNullable<object> = BaseHit> = {
24
32
  /**
@@ -217,9 +225,9 @@ declare const _default: <THit extends NonNullable<object> = BaseHit>(widgetParam
217
225
  error: import("../../types").InstantSearch["error"];
218
226
  createURL: (nextState: import("algoliasearch-helper").SearchParameters | ((state: import("../../types").IndexUiState) => import("../../types").IndexUiState)) => string;
219
227
  } & {
220
- results: RecommendResultItem;
228
+ results: RecommendResponse<any>;
221
229
  })): {
222
- items: Hit<THit>[];
230
+ items: AlgoliaHit<THit>[];
223
231
  widgetParams: Partial<TrendingItemsWidgetParams<BaseHit>> & TrendingItemsConnectorParams<THit>;
224
232
  };
225
233
  dispose({ recommendState }: import("../../types").DisposeOptions): import("algoliasearch-helper").RecommendParameters;
@@ -60,6 +60,29 @@ function createRenderer(_ref) {
60
60
  data: results
61
61
  }));
62
62
  } : undefined;
63
+ var layoutComponent = templates.layout ? function (data) {
64
+ return h(TemplateComponent, _extends({}, renderState.templateProps, {
65
+ templateKey: "layout",
66
+ rootTagName: "fragment",
67
+ data: {
68
+ items: data.items,
69
+ templates: {
70
+ item: templates.item ? function (_ref4) {
71
+ var item = _ref4.item;
72
+ return h(TemplateComponent, _extends({}, renderState.templateProps, {
73
+ templateKey: "item",
74
+ rootTagName: "fragment",
75
+ data: item
76
+ }));
77
+ } : undefined
78
+ },
79
+ cssClasses: {
80
+ list: data.classNames.list,
81
+ item: data.classNames.item
82
+ }
83
+ }
84
+ }));
85
+ } : undefined;
63
86
  render(h(TrendingItems, {
64
87
  items: items,
65
88
  sendEvent: function sendEvent() {},
@@ -67,25 +90,26 @@ function createRenderer(_ref) {
67
90
  headerComponent: headerComponent,
68
91
  itemComponent: itemComponent,
69
92
  emptyComponent: emptyComponent,
93
+ layout: layoutComponent,
70
94
  status: instantSearchInstance.status
71
95
  }), containerNode);
72
96
  };
73
97
  }
74
98
  export default (function trendingItems(widgetParams) {
75
- var _ref4 = widgetParams || {},
76
- container = _ref4.container,
77
- facetName = _ref4.facetName,
78
- facetValue = _ref4.facetValue,
79
- limit = _ref4.limit,
80
- queryParameters = _ref4.queryParameters,
81
- fallbackParameters = _ref4.fallbackParameters,
82
- threshold = _ref4.threshold,
83
- escapeHTML = _ref4.escapeHTML,
84
- transformItems = _ref4.transformItems,
85
- _ref4$templates = _ref4.templates,
86
- templates = _ref4$templates === void 0 ? {} : _ref4$templates,
87
- _ref4$cssClasses = _ref4.cssClasses,
88
- cssClasses = _ref4$cssClasses === void 0 ? {} : _ref4$cssClasses;
99
+ var _ref5 = widgetParams || {},
100
+ container = _ref5.container,
101
+ facetName = _ref5.facetName,
102
+ facetValue = _ref5.facetValue,
103
+ limit = _ref5.limit,
104
+ queryParameters = _ref5.queryParameters,
105
+ fallbackParameters = _ref5.fallbackParameters,
106
+ threshold = _ref5.threshold,
107
+ escapeHTML = _ref5.escapeHTML,
108
+ transformItems = _ref5.transformItems,
109
+ _ref5$templates = _ref5.templates,
110
+ templates = _ref5$templates === void 0 ? {} : _ref5$templates,
111
+ _ref5$cssClasses = _ref5.cssClasses,
112
+ cssClasses = _ref5$cssClasses === void 0 ? {} : _ref5$cssClasses;
89
113
  if (!container) {
90
114
  throw new Error(withUsage('The `container` option is required.'));
91
115
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instantsearch.js",
3
- "version": "4.73.4",
3
+ "version": "4.74.0",
4
4
  "description": "InstantSearch.js is a JavaScript library for building performant and instant search experiences with Algolia.",
5
5
  "homepage": "https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/",
6
6
  "types": "es/index.d.ts",
@@ -28,13 +28,13 @@
28
28
  "dependencies": {
29
29
  "@algolia/events": "^4.0.1",
30
30
  "@types/dom-speech-recognition": "^0.0.1",
31
- "@types/google.maps": "^3.45.3",
31
+ "@types/google.maps": "^3.55.12",
32
32
  "@types/hogan.js": "^3.0.0",
33
33
  "@types/qs": "^6.5.3",
34
- "algoliasearch-helper": "3.22.3",
34
+ "algoliasearch-helper": "3.22.4",
35
35
  "hogan.js": "^3.0.2",
36
36
  "htm": "^3.0.0",
37
- "instantsearch-ui-components": "0.8.0",
37
+ "instantsearch-ui-components": "0.9.0",
38
38
  "preact": "^10.10.0",
39
39
  "qs": "^6.5.1 < 6.10",
40
40
  "search-insights": "^2.15.0"
@@ -56,9 +56,9 @@
56
56
  "watch:es": "yarn --silent build:es:base --watch"
57
57
  },
58
58
  "devDependencies": {
59
- "@instantsearch/mocks": "1.54.0",
60
- "@instantsearch/tests": "1.54.0",
61
- "@instantsearch/testutils": "1.43.0",
59
+ "@instantsearch/mocks": "1.55.0",
60
+ "@instantsearch/tests": "1.55.0",
61
+ "@instantsearch/testutils": "1.44.0",
62
62
  "@storybook/html": "5.3.9",
63
63
  "@types/scriptjs": "0.0.2",
64
64
  "algoliasearch": "4.23.2",
@@ -66,5 +66,5 @@
66
66
  "scriptjs": "2.5.9",
67
67
  "webpack": "4.47.0"
68
68
  },
69
- "gitHead": "b602bbe90e1f3f6db6e64f70eed5297001742dd4"
69
+ "gitHead": "1583f2bc8e74ccccc59a0bd0193f69f9c77bf636"
70
70
  }